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
- single "REJECT"
to
- call to "ufw-user-logging-input" chain
- LOG per-IP
- RETURN per-IP
- "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!