feat: distributed systems
The implementation part is settled, I'll use the serf library.
However, I'm really open to suggestions about the configuration on the user side. I'd like to have the more versatile, easy to grasp configuration interface for cluster configuration.
Here are the changes to reaction I thought of to enable clustering:
Stream could accept a cmd []string
or a cluster type Cluster struct { Bootstrap [][]string, Key string }
Action could accept either a cmd []string
or cluster name string
Share bans:
{
streams: {
ssh: {
cmd: ['journalctl', '-n0', '-fu', 'sshd.service'],
filters: {
login: {
regex: [ 'authentication failed: <ip>' ],
retry: 3,
retryperiod: "6h",
actions: {
ban: "[...]",
send: {
cluster: "picasoft",
msg: "ban <ip>",
},
unban: "[...]",
send: {
cluster: "picasoft",
msg: "unban <ip>",
after: "3h"
},
},
},
},
},
picasoft: {
cluster: {
bootstrap: [
"pica01.picasoft.net:8484",
"pica02.picasoft.net:8484",
],
//key: "picasoft.keyring",
},
filters: {
// How do we set the formalism for message structure? string-only may be perfect for most use-cases.
ban: {
// Here we may need support for multiple patterns (feature not yet asked nor implemented)
regex: ['ban: <ip>'],
actions: {
ban: "[...]",
},
},
unban: {
// Here we may need support for multiple patterns (feature not yet asked nor implemented)
regex: ['unban: <ip>'],
actions: {
unban: "[...]",
},
},
},
},
},
}
Share matches:
{
streams: {
local sshregexes = [ 'authentication failed: <ip>' ];
ssh: {
cmd: ['journalctl', '-n0', '-fu', 'sshd.service'],
filters: {
loginsend: {
regex: sshregexes,
actions: {
send: {
cluster: "picasoft",
// self means this instance receives the message as well on the cluster stream below ↓
self: true,
msg: "ssh.match <ip>",
},
},
},
},
},
picasoft: {
cluster: {
bootstrap: [
"pica01.picasoft.net:8484",
"pica02.picasoft.net:8484",
],
// key: "picasoft.keyring",
},
filters: {
sshmatches: {
regex: ['ssh.match: <ip>'],
retry: 4,
retryperiod: "8h",
actions: {
ban: "[...]",
unban: "[...]",
},
},
},
},
},
}
Edited by ppom