+ #Init blacklist
+ my %blacklist = ('tcp' => [], 'udp' => []);
+ #Set ssh proto and port tuple
+ if ($3 eq 'ssh') {
+ #Set blacklist for 22 dest port on tcp
+ #$blacklist{'tcp'}[$#{$blacklist{'tcp'}}+1] = 22;
+ %blacklist = ('tcp' => [ 22 ]);
+ #Set dovecot proto and port tuples
+ } elsif ($3 eq 'dovecot') {
+ #Set blacklist for 25, 143, 587, 993 dest ports on tcp and udp
+ %blacklist = ('tcp' => [ 25, 143, 587, 993 ], 'udp' => [ 25, 143, 587, 993 ]);
+ #Set other proto and port tuples
+ } else {
+ }
+
+ #Check if v4 ip and not in whitelist
+ if (is_ipv4($ip) && not scalar map { my $network = new_ipv4($_); my $netip = new_ipv4($ip); unless ($network->contains($netip)) { (); } } @{$iplist{ipv4}}) {
+ if (!defined $ip4s{$ip}) {
+ %{$ip4s{$ip}} = ('tcp' => {}, 'udp' => {});
+ }
+ #Add ip tuples in v4 blacklist
+ map { my $proto = $_; map { $ip4s{$ip}{$proto}{$_}=1; } @{$blacklist{$proto}}; } keys %blacklist;
+ #Check if v6 ip
+ } elsif (is_ipv6($ip) && not scalar map { my $network = NetAddr::IP->new($_); my $netip = NetAddr::IP->new($ip); unless ($network->contains($netip)) { (); } } @{$iplist{ipv6}}) {
+ if (!defined $ip6s{$ip}) {
+ %{$ip6s{$ip}} = ('tcp' => {}, 'udp' => {});
+ }
+ #Add ip tuples in v6 blacklist
+ map { my $proto = $_; map { $ip6s{$ip}{$proto}{$_}=1; } @{$blacklist{$proto}}; } keys %blacklist;
+ }
+ #nov. 30 15:30:07 aurae.aoihime.eu kernel: audit: type=1100 audit(1575124207.371:38129): pid=685 uid=985 auid=4294967295 ses=4294967295 msg='op=PAM:authentication grantors=? acct="toto" exe="/usr/bin/pwauth" hostname=? addr=? terminal=? res=failed'
+ #XXX: Until mod_authnz pass to pwauth the (SERVER_NAME|SERVER_ADDR) + REMOTE_ADDR+REMOTE_PORT in env it's impossible to know who did a failed auth
+ #XXX: see https://github.com/phokz/mod-auth-external/blob/master/mod_authnz_external/TODO
+ #} elsif (/op=PAM:authentication grantors=\? acct="(.+)" exe="\/usr\/bin\/pwauth" hostname=.+ addr=(.+) terminal=\? res=failed/ && grep($_ ne $1, @userlist)) {
+ # ...
+ }
+} capturex('journalctl', '-m', '-t', 'kernel', '-o', 'cat', '--no-hostname');
+
+#With spamlist
+if ($spamlist) {
+ #Extract originating ip in spam
+ map {
+ #Open spam file for reading
+ open (my $fh, '<', $_) or die "Can't open < $_: $!";
+
+ #Lookup for X-Originating-IP header
+ while (<$fh>) {
+ if (/X-Originating-IP: (.+)$/) {
+ #Set ip
+ my $ip = ${1};
+
+ #Set blacklist for 80 and 443 dest ports on tcp
+ my %blacklist = ('tcp' => [ 80, 443, 8000, 8080, 8443 ]);
+
+ #Check if v4 ip and not in whitelist
+ #if (is_ipv4($ip) && not scalar map { my $network = NetAddr::IP->new($_); my $netip = NetAddr::IP->new($ip); unless ($network->contains($netip)) { (); } } @{$iplist{ipv4}}) {
+ if (is_ipv4($ip) && not scalar map { my $network = new_ipv4($_); my $netip = new_ipv4($ip); unless ($network->contains($netip)) { (); } } @{$iplist{ipv4}}) {
+ if (!defined $ip4s{$ip}) {
+ %{$ip4s{$ip}} = ('tcp' => {}, 'udp' => {});
+ }
+ #Add ip tuples in v4 blacklist
+ map { my $proto = $_; map { $ip4s{$ip}{$proto}{$_}=1; } @{$blacklist{$proto}}; } keys %blacklist;
+ } elsif (is_ipv6($ip) && not scalar map { my $network = NetAddr::IP->new($_); my $netip = NetAddr::IP->new($ip); unless ($network->contains($netip)) { (); } } @{$iplist{ipv6}}) {
+ if (!defined $ip6s{$ip}) {
+ %{$ip6s{$ip}} = ('tcp' => {}, 'udp' => {});
+ }
+ #Add ip tuples in v6 blacklist
+ map { my $proto = $_; map { $ip6s{$ip}{$proto}{$_}=1; } @{$blacklist{$proto}}; } keys %blacklist;
+ }
+ }
+ }
+
+ #Close spam file
+ close $fh or die "Can't close fh: $!";
+ } glob('/var/spool/mail/*/.Junk/{new,cur,tmp}/*');
+}
+
+#Process each ipv4s keys
+map {
+ #Set proto as either tcp or udp
+ for my $proto (('tcp', 'udp')) {
+ #Check if branch is empty
+ if (!scalar keys %{$ip4s{$_}{$proto}}) {
+ #Prune it
+ delete $ip4s{$_}{$proto};
+ }
+ }
+} keys %ip4s;
+
+#Process each ipv6s keys
+map {
+ #Set proto as either tcp or udp
+ for my $proto (('tcp', 'udp')) {
+ #Check if branch is empty
+ if (!scalar keys %{$ip6s{$_}{$proto}}) {
+ #Prune it
+ delete $ip6s{$_}{$proto};