diff --git a/config/example.jsonnet b/config/example.jsonnet index 1a9fc7d..c9e9abb 100644 --- a/config/example.jsonnet +++ b/config/example.jsonnet @@ -7,22 +7,38 @@ // strongly encouraged to take a look at the full documentation: https://reaction.ppom.me // JSONnet functions -local iptables(args) = ['ip46tables', '-w'] + args; -// ip46tables is a minimal C program (only POSIX dependencies) present in a -// subdirectory of this repo. -// it permits to handle both ipv4/iptables and ipv6/ip6tables commands +local ipBan(cmd) = [cmd, '-w', '-A', 'reaction', '-s', '', '-j', 'DROP']; +local ipUnban(cmd) = [cmd, '-w', '-D', 'reaction', '-s', '', '-j', 'DROP']; -// See meaning and usage of this function around L106 +// See meaning and usage of this function around L180 local banFor(time) = { - ban: { - cmd: iptables(['-A', 'reaction', '-s', '', '-j', 'DROP']), + ban4: { + cmd: ipBan('iptables'), + ipv4only: true, }, - unban: { + ban6: { + cmd: ipBan('ip6tables'), + ipv6only: true, + }, + unban4: { + cmd: ipUnban('iptables'), after: time, - cmd: iptables(['-D', 'reaction', '-s', '', '-j', 'DROP']), + ipv4only: true, + }, + unban6: { + cmd: ipUnban('ip6tables'), + after: time, + ipv6only: true, }, }; +// See usage of this function around L90 +// Generates a command for iptables and ip46tables +local ip46tables(arguments) = [ + ['iptables', '-w'] + arguments, + ['ip6tables', '-w'] + arguments, +]; + { // patterns are substitued in regexes. // when a filter performs an action, it replaces the found pattern @@ -74,24 +90,23 @@ local banFor(time) = { concurrency: 0, // Those commands will be executed in order at start, before everything else - start: [ + start: // Create an iptables chain for reaction - iptables(['-N', 'reaction']), + ip46tables(['-N', 'reaction']) + // Insert this chain as the first item of the INPUT & FORWARD chains (for incoming connections) - iptables(['-I', 'INPUT', '-p', 'all', '-j', 'reaction']), - iptables(['-I', 'FORWARD', '-p', 'all', '-j', 'reaction']), - ], + ip46tables(['-I', 'INPUT', '-p', 'all', '-j', 'reaction']) + + ip46tables(['-I', 'FORWARD', '-p', 'all', '-j', 'reaction']), // Those commands will be executed in order at stop, after everything else - stop: [ + stop: // Remove the chain from the INPUT & FORWARD chains - iptables(['-D', 'INPUT', '-p', 'all', '-j', 'reaction']), - iptables(['-D', 'FORWARD', '-p', 'all', '-j', 'reaction']), + ip46tables(['-D', 'INPUT', '-p', 'all', '-j', 'reaction']) + + ip46tables(['-D', 'FORWARD', '-p', 'all', '-j', 'reaction']) + // Empty the chain - iptables(['-F', 'reaction']), + ip46tables(['-F', 'reaction']) + // Delete the chain - iptables(['-X', 'reaction']), - ], + ip46tables(['-X', 'reaction']), + // streams are commands // they are run and their ouptut is captured @@ -145,12 +160,20 @@ local banFor(time) = { // actions are run by the filter when regexes are matched actions: { // actions have a user-defined name - ban: { - cmd: iptables(['-A', 'reaction', '-s', '', '-j', 'DROP']), + ban4: { + cmd: ['iptables', '-w', '-A', 'reaction', '-s', '', '-j', 'DROP'], + // this optional field permits to run an action only when a pattern of type ip contains an ipv4 + ipv4only: true, }, - unban: { - cmd: iptables(['-D', 'reaction', '-s', '', '-j', 'DROP']), + ban6: { + cmd: ['ip6tables', '-w', '-A', 'reaction', '-s', '', '-j', 'DROP'], + // this optional field permits to run an action only when a pattern of type ip contains an ipv6 + ipv6only: true, + }, + + unban4: { + cmd: ['iptables', '-w', '-D', 'reaction', '-s', '', '-j', 'DROP'], // if after is defined, the action will not take place immediately, but after a specified duration // same format as retryperiod after: '2 days', @@ -160,6 +183,13 @@ local banFor(time) = { // (defaults to false) // here it is not useful because we will flush and delete the chain containing the bans anyway // (with the stop commands) + ipv4only: true, + }, + + unban6: { + cmd: ['ip6tables', '-w', '-D', 'reaction', '-s', '', '-j', 'DROP'], + after: '2 days', + ipv6only: true, }, mail: { diff --git a/config/example.yml b/config/example.yml index 4169ecc..40f2764 100644 --- a/config/example.yml +++ b/config/example.yml @@ -10,8 +10,10 @@ # using YAML anchors `&name` and pointers `*name` # definitions are not readed by reaction definitions: - - &iptablesban [ 'ip46tables', '-w', '-A', 'reaction', '-s', '', '-j', 'DROP' ] - - &iptablesunban [ 'ip46tables', '-w', '-D', 'reaction', '-s', '', '-j', 'DROP' ] + - &ip4tablesban [ 'iptables', '-w', '-A', 'reaction', '-s', '', '-j', 'DROP' ] + - &ip6tablesban [ 'ip6tables', '-w', '-A', 'reaction', '-s', '', '-j', 'DROP' ] + - &ip4tablesunban [ 'iptables', '-w', '-D', 'reaction', '-s', '', '-j', 'DROP' ] + - &ip6tablesunban [ 'ip6tables', '-w', '-D', 'reaction', '-s', '', '-j', 'DROP' ] # ip46tables is a minimal C program (only POSIX dependencies) present as a subdirectory. # it permits to handle both ipv4/iptables and ipv6/ip6tables commands @@ -62,16 +64,23 @@ patterns: # Those commands will be executed in order at start, before everything else start: - - [ 'ip46tables', '-w', '-N', 'reaction' ] - - [ 'ip46tables', '-w', '-I', 'INPUT', '-p', 'all', '-j', 'reaction' ] - - [ 'ip46tables', '-w', '-I', 'FORWARD', '-p', 'all', '-j', 'reaction' ] + - [ 'iptables', '-w', '-N', 'reaction' ] + - [ 'ip6tables', '-w', '-N', 'reaction' ] + - [ 'iptables', '-w', '-I', 'INPUT', '-p', 'all', '-j', 'reaction' ] + - [ 'ip6tables', '-w', '-I', 'INPUT', '-p', 'all', '-j', 'reaction' ] + - [ 'iptables', '-w', '-I', 'FORWARD', '-p', 'all', '-j', 'reaction' ] + - [ 'ip6tables', '-w', '-I', 'FORWARD', '-p', 'all', '-j', 'reaction' ] # Those commands will be executed in order at stop, after everything else stop: - - [ 'ip46tables', '-w', '-D', 'INPUT', '-p', 'all', '-j', 'reaction' ] - - [ 'ip46tables', '-w', '-D', 'FORWARD', '-p', 'all', '-j', 'reaction' ] - - [ 'ip46tables', '-w', '-F', 'reaction' ] - - [ 'ip46tables', '-w', '-X', 'reaction' ] + - [ 'iptables', '-w', '-D', 'INPUT', '-p', 'all', '-j', 'reaction' ] + - [ 'ip6tables', '-w', '-D', 'INPUT', '-p', 'all', '-j', 'reaction' ] + - [ 'iptables', '-w', '-D', 'FORWARD', '-p', 'all', '-j', 'reaction' ] + - [ 'ip6tables', '-w', '-D', 'FORWARD', '-p', 'all', '-j', 'reaction' ] + - [ 'iptables', '-w', '-F', 'reaction' ] + - [ 'ip6tables', '-w', '-F', 'reaction' ] + - [ 'iptables', '-w', '-X', 'reaction' ] + - [ 'ip6tables', '-w', '-X', 'reaction' ] # streams are commands # they are run and their ouptut is captured @@ -124,12 +133,19 @@ streams: # actions are run by the filter when regexes are matched actions: # actions have a user-defined name - ban: + ban4: # YAML substitutes *reference by the value anchored at &reference - cmd: *iptablesban + cmd: *ip4tablesban + # this optional field permits to run an action only when a pattern of type ip contains an ipv4 + ipv4only: true - unban: - cmd: *iptablesunban + ban6: + cmd: *ip6tablesban + # this optional field permits to run an action only when a pattern of type ip contains an ipv6 + ipv6only: true + + unban4: + cmd: *ip4tablesunban # if after is defined, the action will not take place immediately, but after a specified duration # same format as retryperiod after: '2 days' @@ -139,6 +155,12 @@ streams: # (defaults to false) # here it is not useful because we will flush and delete the chain containing the bans anyway # (with the stop commands) + ipv4only: true + + unban6: + cmd: *ip6tablesunban + after: '2 days' + ipv6only: true mail: cmd: ['sendmail', '...', '']