0

Running:

  • Ubuntu 18.04.4 LTS
  • Fail2Ban v0.10.2
  • ufw 0.36
  • iptables v1.6.1

I've successfully setup fail2ban to use ufw to block ip's based on ssh authentication failures. As we know, ufw is just a front-end for iptables. I've tested from another IP address and indeed have been blocked and receive the reject packets based on my ssh rules. So I know the whole thing is seemingly working.

What I would like to do (at least temporarily as i get familiar with all 3 components) is: turn on logging of rejects that are due to rules coming from fail2ban. I realize eventually this will just be all noise, but for now I want to be able to see positive confirmation of rules working.

UFW is logging normally to /var/log/ufw.log. I see tons of things like:

Feb 12 12:24:01 redis-test kernel: [14337092.381436] [UFW BLOCK] IN=eth0 OUT= MAC=1e:17....:08:00 SRC=123.456.789.10 DST=10.987.654.32 LEN=40 TOS=0x18 PREC=0x00 TTL=49 ID=59823 PROTO=TCP SPT=33169 DPT=23 WINDOW=2358 RES=0x00 SYN URGP=0

I do not fully understand where iptables logs and if it has its own logs separate from ufw's, but at a minimum, ufw's logs seems to be inclusive of everything iptables is doing behind the scenes.

From what I've read, it seems by default ufw will not log things that are expected (blocked by user specified rule). From the docs:

ufw supports per rule logging. By default, no logging is performed when a packet matches a rule. Specifying log will log all new connections matching the rule, and log-all will log all packets matching the rule. For example, to allow and log all new ssh connections, use: ufw allow log 22/tcp

So in my example above (from /var/log/ufw.log) I don't have any specifiec rules for port 23 (telnet), so that gets logged and blocked. But because I do have a rule specifically blocking my "other" test IP for ssh, it does not get logged.

iptables -L produces the following...

Chain INPUT (policy DROP)
target     prot opt source               destination
ufw-before-logging-input  all  --  anywhere             anywhere
ufw-before-input  all  --  anywhere             anywhere      ****** points to below (B) ******
ufw-after-input  all  --  anywhere             anywhere
ufw-after-logging-input  all  --  anywhere             anywhere  **** where first logging occurs ****
ufw-reject-input  all  --  anywhere             anywhere
ufw-track-input  all  --  anywhere             anywhere

Chain ufw-before-input (1 references)                                   ****** (B) referenced from above ******
target     prot opt source               destination
ACCEPT     all  --  anywhere             anywhere
ACCEPT     all  --  anywhere             anywhere             ctstate RELATED,ESTABLISHED
ufw-logging-deny  all  --  anywhere             anywhere             ctstate INVALID
DROP       all  --  anywhere             anywhere             ctstate INVALID
ACCEPT     icmp --  anywhere             anywhere             icmp destination-unreachable
ACCEPT     icmp --  anywhere             anywhere             icmp time-exceeded
ACCEPT     icmp --  anywhere             anywhere             icmp parameter-problem
ACCEPT     icmp --  anywhere             anywhere             icmp echo-request
ACCEPT     udp  --  anywhere             anywhere             udp spt:bootps dpt:bootpc
ufw-not-local  all  --  anywhere             anywhere
ACCEPT     udp  --  anywhere             224.0.0.251          udp dpt:mdns
ACCEPT     udp  --  anywhere             239.255.255.250      udp dpt:1900
ufw-user-input  all  --  anywhere             anywhere          ****** this is where my rules from fail2ban are going ******

Chain ufw-user-input (1 references)                                     ****** the IPs coming from fail2ban (any my allow SSH rule i added via UFW) ******
target     prot opt source               destination
REJECT     all  --  555.55.55.555        anywhere             reject-with icmp-port-unreachable
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:ssh

The first instance of logging I see is

Chain ufw-after-logging-input (1 references)    
target     prot opt source               destination
LOG        all  --  anywhere             anywhere             limit: avg 3/min burst 10 LOG level warning prefix "[UFW BLOCK] "

But since that doesn't get evaluated until after my fail2ban/ufw rules reject the connection, nothing is logged.

So my question is, how can i enable logging for the fail2ban IPs? Additionally, if I enable new jails in the future (for instance to target web scrapers/exploit scans), is there any way that I can have a different log message that indicates that it came from SSH ban or the WebScraper ban?

I tried to figure out if there was a configuration setting for which default "CHAIN" ufw inserted user rules into (thinking if i could get them into the bottom portion of ufw-after-logging-input, that might work), but i don't know if that is the best approach. i dont really like the idea of messing with how UFW interacts with iptables.

My actionban from ufw.conf is:

actionban = [ -n "<application>" ] && app="app <application>"
            ufw insert <insertpos> <blocktype> from <ip> to <destination> $app

actionunban = [ -n "<application>" ] && app="app <application>"
              ufw delete <blocktype> from <ip> to <destination> $app

maybe it's just as simple as adding "log" into the ufw insert statement? if so, is there a way that i can specify a custom log message so that i can differentiate between the jail types (ssh vs web scraper)?

note: logging is set to default (low). i temporarily turned it on high. I could see my "test" blocked IP in [UFW AUDIT] records in the log, but even then it did not mention it was rejected, just that it saw the incoming attempt. so changing the logging level will not do it (and is way too redundant for prod anyway).

thanks!

update 2/12/2020 9:46am:

adding "log" to the banaction in /etc/fail2ban/action.d/ufw.conf seems to do what i want. my iptables -L now looks like...

Chain ufw-user-input (1 references)
target     prot opt source               destination

ufw-user-logging-input  all  --  111.222.333.444       anywhere
REJECT     all  --  111.222.333.444       anywhere             reject-with icmp-port-unreachable
ufw-user-logging-input  all  --  555.666.777.888       anywhere
REJECT     all  --  555.666.777.888       anywhere             reject-with icmp-port-unreachable


Chain ufw-user-logging-input (163 references)
target     prot opt source               destination

LOG        all  --  111.222.333.444       anywhere             ctstate NEW limit: avg 3/min burst 10 LOG level warning prefix "[UFW BLOCK] "
RETURN     all  --  111.222.333.444       anywhere
LOG        all  --  555.666.777.888       anywhere             ctstate NEW limit: avg 3/min burst 10 LOG level warning prefix "[UFW BLOCK] "
RETURN     all  --  555.666.777.888       anywhere

i'm a bit worried at the additional records per-IP being added. per-IP, it went from

  1. single "REJECT"

to

  1. call to "ufw-user-logging-input" chain
  2. LOG per-IP
  3. RETURN per-IP
  4. "REJECT" in original "ufw-user-input"

so for each IP, there are now 4 steps. i'm not sure how much overhead that is and how bad it would get with 10's/100's/1000's of IPs. does this seem like it's going to get problematic quickly?

additionally, it still uses the generic [UFW BLOCK] in /var/log/ufw.log. i'd like to have it specifically reference the rule that caused the block (ssh/http scraper/http malware bot/etc). is there a way to get some type of reference from fail2ban -> ufw -> iptables? it seems ufw has a "comment" component to it's insert statement and iptables has "--log-prefix". any way to connect the two?

thanks!

user3249281
  • 185
  • 1
  • 10

0 Answers0