SASL login brutforce mitigation
saikek opened this issue ยท 9 comments
Hello,
on my private hosting, i'm getting lots of hits on mail port with SASL authentication attempts
.
Could you please mention to the main page fail2ban SASL
mitigation? Otherwise we would end up with lots of mail-bots. (If this issue is valid with your server).
For example:
https://bobcares.com/blog/fail2ban-postfix-sasl/
It took me some time to make it work. Main issue - with correct regex - due to wrong timezone, date wasn't properly matched, so bans were not applied. Here are my solution:
/etc/fail2ban/jail.d/saslmail.conf
[DEFAULT]
sender = root@localhost
destemail = root@localhost
action = %(action_mwl)s
[saslmail]
enabled = true
port = 25
protocol = udp
filter = saslmail
logpath = /var/lib/docker/containers/<container>/<container>-json.log
maxretry = 2
bantime = 3600
[INCLUDES]
before = common.conf
`/etc/fail2ban/filter.d/saslmail.conf`
[Definition]
failregex = ^.*\[<HOST>\]: SASL (?:LOGIN|PLAIN|(?:CRAM|DIGEST)-MD5) authentication failed.*$
^.*reject: RCPT from \S+\[<HOST>\]:.*Relay access denied.*$
^.*lost connection after .*\[<HOST>\].*$
datepattern =%%b %%d %%H:%%M:%%S
Please update README with security issues.
@saikek Thanks for filing this issue.
Could you please help us to submit a PR to update the README for the project? Because I'm not very familiar with this problem.
Thank you very much.
@saikek Thank you very much for your ground work.
I now have this:
/ # fail2ban-client status saslmail
Status for the jail: saslmail
|- Filter
| |- Currently failed: 0
| |- Total failed: 0
| `- File list: /logs/simple_mail_forward.log
`- Actions
|- Currently banned: 0
|- Total banned: 0
`- Banned IP list:
/ # fail2ban-regex /logs/simple_mail_forward.log /data/filter.d/saslmail.conf
Running tests
=============
Use failregex filter file : saslmail, basedir: /data
Use datepattern : MON Day 24hour:Minute:Second
Use log file : /logs/simple_mail_forward.log
Use encoding : UTF-8
Results
=======
Failregex: 12314 total
|- #) [# of hits] regular expression
| 1) [8110] ^.*\[<HOST>\]: SASL (?:LOGIN|PLAIN|(?:CRAM|DIGEST)-MD5) authentication failed.*$
| 2) [2] ^.*reject: RCPT from \S+\[<HOST>\]:.*Relay access denied.*$
| 3) [4202] ^.*lost connection after .*\[<HOST>\].*$
`-
Ignoreregex: 0 total
Date template hits:
|- [# of hits] date format
| [33252] MON Day 24hour:Minute:Second
`-
Lines: 33636 lines, 0 ignored, 12314 matched, 21322 missed
[processed in 2.59 sec]
The filter is working, but somehow no bans are applied whatsoever when running the container. Any clues?
Many reasons why:
- Docker container timezone and time does not correspond to a system timezone. It can have UTC timezone and host machine can have anything else.
- Docker uses it's own IPTABLE rules. So fail2ban IPTABLE rules does not apply easily with docker. fail2ban solution
- Docker requests are coming from ip
172.17.0.1
- which is not internet IP but rather Docker Gateway. (Which is caused by IP masquerading)
I've ended up stopping service until I would have time to fix it. Better safe then sorry.
It's working for me now!
I've used a docker container with fail2ban ( https://github.com/crazy-max/docker-fail2ban )
compose file:
fail2ban:
image: crazymax/fail2ban:latest
container_name: fail2ban
network_mode: "host"
cap_add:
- NET_ADMIN
- NET_RAW
volumes:
- "${DOCKERDIR}/fail2ban/data:/data"
- "/var/log:/var/log:ro"
- "/var/lib/docker/containers/bf114b2df522e48cb486ad1db7cc1dae351c7c8539d64a5e111d6ef4cbfbabfd/bf114b2df522e48cb486ad1db7cc1dae351c7c8539d64a5e111d6ef4cbfbabfd-json.log:/logs/sim$
env_file:
- "${DOCKERDIR}/fail2ban/fail2ban.env"
restart: always
Notice the horrible path of the docker container for simple-mail-forwarder because there is no postfix log. This path is different for every installation. You can easily find the path by running
docker inspect --format="{{.Id}}" "simple-mail-forward" | xargs find /var/lib/docker/containers -name
Where "simple-mail-forward" is the name of your SMF docker container.
saslmail.conf (filter.d)
[Definition]
failregex = ^.*\[<HOST>\]: SASL (?:LOGIN|PLAIN|(?:CRAM|DIGEST)-MD5) authentication failed.*$
^.*reject: RCPT from \S+\[<HOST>\]:.*Relay access denied.*$
^.*lost connection after .*\[<HOST>\].*$
saslmail.conf (jail.d)
[saslmail]
enabled = true
findtime = 14400
bantime = 93600
port = 25
filter = saslmail
logpath = /logs/simple_mail_forward.log
Because the timezone is incorrect in the SMF container I have to account for 2 extra hours for findtime & bantime. This might differ according to your timezone.
Result:
fail2ban-client status saslmail
Status for the jail: saslmail
|- Filter
| |- Currently failed: 2
| |- Total failed: 4
| `- File list: /logs/simple_mail_forward.log
`- Actions
|- Currently banned: 5
|- Total banned: 5
`- Banned IP list: 45.13.39.140 185.137.111.129 185.137.111.136 185.137.111.96 185.137.111.125
Send to mail log files are finally silent after continuous hammering.
@me1299 - try this line in your jail.d
file:
[saslmail]
...
logtimezone = UTC
...
This should would work without docker-compose file.
Also you can use path for logs:
/var/lib/docker/containers/*/*-json.log
I don't think it would create big overhead even if you are running multiple containers.
Also Also:
Are you sure that all requests are now blocked - I had occasions with "IP already blocked" - which was actually not locking anything
@me1299 - try this line in your
jail.d
file:[saslmail] ... logtimezone = UTC ...
This should would work without docker-compose file.
Also you can use path for logs:
/var/lib/docker/containers/*/*-json.log
I don't think it would create big overhead even if you are running multiple containers.
Also Also:
Are you sure that all requests are now blocked - I had occasions with "IP already blocked" - which was actually not locking anything
Timezone is now fixed in the latest release, so that isn't an issue anymore. I like your idea of mapping all log files, but I'm not a fan of the overhead it creates.
And yes, I'm 100% sure the requests are blocked. My iptables on the host:
-A f2b-saslmail -s 45.13.39.140/32 -j REJECT --reject-with icmp-port-unreachable
-A f2b-saslmail -s 37.49.224.140/32 -j REJECT --reject-with icmp-port-unreachable
-A f2b-saslmail -s 185.234.219.66/32 -j REJECT --reject-with icmp-port-unreachable
-A f2b-saslmail -s 185.234.219.62/32 -j REJECT --reject-with icmp-port-unreachable
-A f2b-saslmail -s 185.234.219.61/32 -j REJECT --reject-with icmp-port-unreachable
-A f2b-saslmail -s 185.234.218.126/32 -j REJECT --reject-with icmp-port-unreachable
-A f2b-saslmail -s 185.234.216.206/32 -j REJECT --reject-with icmp-port-unreachable
-A f2b-saslmail -s 185.137.111.96/32 -j REJECT --reject-with icmp-port-unreachable
-A f2b-saslmail -s 185.137.111.136/32 -j REJECT --reject-with icmp-port-unreachable
-A f2b-saslmail -s 185.137.111.129/32 -j REJECT --reject-with icmp-port-unreachable
-A f2b-saslmail -s 185.137.111.125/32 -j REJECT --reject-with icmp-port-unreachable
-A f2b-saslmail -s 103.231.139.5/32 -j REJECT --reject-with icmp-port-unreachable
-A f2b-saslmail -s 103.231.139.3/32 -j REJECT --reject-with icmp-port-unreachable