spantaleev / matrix-docker-ansible-deploy

🐳 Matrix (An open network for secure, decentralized communication) server setup using Ansible and Docker
GNU Affero General Public License v3.0
4.89k stars 1.04k forks source link

Feature Request: Implement fail2ban optional activation for Synapse #1423

Open AnonyPla opened 2 years ago

AnonyPla commented 2 years ago

/etc/fail2ban/filter.d/matrix-synapse.conf

[Definition]
failregex = .*synapse.access.http.8008 - .* INFO - POST-[0-9]{1,10} - <HOST> - 8008 - {None} Processed request:.* 52B 403 "POST \/_matrix\/client\/r0\/login.*$

ignoreregex =

/etc/fail2ban/jail.d/matrix-synapse.conf

[matrix-synapse]
enabled = true
backend = systemd
journalmatch = _SYSTEMD_UNIT=matrix-synapse.service
bantime  = 1d
findtime  = 10m
maxretry = 1
maxmatches = %(maxretry)s
banaction = iptables-allports
chain = FORWARD

And finally in the matrix-synapse matrix.yourdomain.com.log.config

Change the following from WARNING to INFO:

loggers:
    synapse:
        level: INFO

This enables fail2ban to jail failed login attempts (bad password and/or user not existing) at the cost of switching logging from WARNING to INFO.

To mitigate this on small servers, a limit can be set on the logging within /etc/systemd/journald.conf

By adding the following line: MaxRetentionSec=1day and possibly also adding a cronjob to purge logs older than x, example: 0 6 * * * journalctl --vacuum-time=1d

Edit: As a bonus, this configuration will also protect Synapse Admin from same attempts.

shreyasajj commented 2 years ago

Does this only work on systemctl version of it or also the docker version

spantaleev commented 2 years ago

Looks nice! Thank you for the research and getting it organized like that, @AnonyPla!

At the very least, we should document this somewhere in docs/.

It would otherwise be great if we could optionally set it all (most) up automatically via a new role (matrix-fail2ban?). For this, in the spirit of this playbook ("all services running in containers"), we'd need to be able run fail2ban in a container, which is probably tricky.

altsalt commented 2 years ago

Brief research suggests it is doable.

TheLillo commented 2 years ago

synapse is not on 8448? The regex should be something like that: failregex = .::ffff: - 8448 - Received request: POST.\n.Got login request.\n.Attempted to login as. .::ffff: - 8448 - Received request: POST.\n.Got login request.\n.Failed password login.

If the implementation will be for both Synapse and Dendrite, will be great :)

ToeiRei commented 2 years ago

I tinkered a bit with that stuff and switched over to crowdsec reading from journald. Pattern writing was way easier using grok than regex.

juergen852 commented 1 year ago

Any Update about this?

altsalt commented 1 year ago

I was hoping to swing back to this but have not yet found the space. @ToeiRei I haven't messed with CrowdSec but it looks like a reasonable option. I used to use SSHGuard and there are probably other options. Really someone just needs to take the initiative and draft up a PR.

ToeiRei commented 1 year ago

All you need is the http scenarios and you are well protected for the most part.

altsalt commented 1 year ago

I appreciate that they have an active docker hub image. To make use of the journalctl stuff, we'd need to use the Debian image rather than Alpine. I'm not sure whether this image is already being pulled in by matrix-docker-ansible-deploy and would definitely like to keep changes to the minimum.

I'm not sure when I'll have time to really dig into this but would love for someone to take it on.

ToeiRei commented 1 year ago

crowdsec also comes as a go binary (?) that you just unpack. So even alpine would work.

What I could do is writing a crowdsec pattern for specific attacks against matrix servers, if I get some log messages of such incidents

altsalt commented 1 year ago

I think part of this feature request was adding fail2ban (or CrowdSec) as a service that can be deployed with the script. This would help secure the system as a whole, rather than just Matrix stuff.

ToeiRei commented 1 year ago

I wouldn't install it as a container then and just use the debian package via ansible then as it's system level (iptables!)