"remoteAddr" logged as SWAG container's IP with SWAG/fail2ban/Nextcloud setup

Hi,

I created the fail2ban filter: /config/fail2ban/filter.d/nextcloud.local

[Definition]_groupsre = (?:(?:,?\s*"\w+":(?:"[^"]+"|\w+)))failregex = ^{%(_groupsre)s,?\s"remoteAddr":""%(_groupsre)s,?\s*“message”:“Login failed: ^{%(_groupsre)s,?\s*“remoteAddr”:”"%(_groupsre)s,?\s*“message”:“Trusted domain error.datepattern = ,?\s*“time”\s*:\s*”%%Y-%%m-%%d[T ]%%H:%%M:%%S(%%z)?"

Then added the Nextcloud jail config in /config/fail2ban/jail.local

[nextcloud]
backend = auto
enabled = true
port = 80,443
protocol = tcp
filter = nextcloud
maxretry = 3
bantime = 86400
findtime = 43200
logpath = /config/log/nextcloud/nextcloud.log

Added the Netxcloud’s log location as a volume within the SWAG compose file.

volumes:
`- /var/lib/docker/volumes/nextcloud_nextcloud/_data/log/nextcloud:/config/log/nextcloud

Proxy header settings is included in the location block of the Nextcloud subdomain setup.

/nginx/proxy-confs/nextcloud.subdomain.conf

location / {
    include /config/nginx/proxy.conf;
    resolver 127.0.0.11 valid=30s;
    set $upstream_app nextcloud;
    set $upstream_port 80;
    set $upstream_proto http;
    proxy_pass $upstream_proto://$upstream_app:$upstream_port;
   proxy_max_temp_file_size 2048m;
}

Fail2ban successfully reads the Nextcloud log and rejects further connections after 3 failed attempts.

Problem being, the IP being banned is that of the SWAG container - “172.20.0.5” and not the “remoteAddr IP” as expected.

I’m going stir crazy try to make sense of this. Any advise regardless, will be greatly appreciated.

Do you see normal IP’s within the docker log or is it all that same IP?

@j0nnymoe, would you mind elaborating on the docker log you’re referring to ?

Sorry my brain hasn’t fully engaged yet this morning. I mean in your nextcloud log.file in your /data mount.

In log /config/log/fail2ban/fail2ban.log it’s always the SWAG container’s IP, 172.20.0.5 referenced as “[nextcloud] Found 172.20.0.5 - 2021-06-06 17:35

In log /config/log/nextcloud/nextcloud.log it’s also always the SWAG container’s IP, 172.20.0.5 referenced as
““remoteAddr":“172.20.0.5”,"user””

Your’s is waking … mine is dead tired … going into shutdown. :woozy_face:

My basic HTTP header understanding is that one sets the header in the server block of the proxy server and then advise the main server to use the header that was set.

Could it thus be that I’m missing some config in Nextcloud nginx’s config …

What platform is this all running on btw? Hardware/OS?

A single debian 4.19.0-16 virtual machine on xcp-ng (Intel i5, 32GB DDR4, 512GB NvME) hosting both the linuxserver.io nextcloud, mariadb, redis & swag containers in a docker-compose config.

Everything is currently up to date.

OK, reason I asked was I’ve seen this behavour happen on retail nas units like syno/qnap as they have the docker userland proxy enabled. I can only assume that is also enabled for you or it’s something to how you’ve got your reverse proxy configured (NATHairpin maybe).

Nothing of the sorts had been configured previously.

I have though followed the SWAG documentation as provided by Linuxserver.io to get the reverse proxy operational.

Would you accept me posting my configs ? (…and if so, which would you wanna see ?)

Which source (URL) would or could you advise to follow in setting up fail2ban with swag and nextcloud based on LinuxServer.io containers ?

You probably need to investigate further back in your stack. In the nginx access logs within SWAG, do the IP’s show correctly there? or are they showing the same IP for everything?

I’m only seeing the IP assigned to the docker host IP ( 172.20.0.1) being referenced in the SWAG’s nginx access.log and then the SWAG container’s IP ( 172.20.0.5) referenced in the nextcloud log.

I’m still hoping it’s only a config issue, with my gut feeling still towards the “x-real-IP $remote_addr” and/or “proxy_set_header x-forwarded-for” having to be added/configured at the nextcloud nginx config as to accept the “real IP” from the header than from the connection.

…or am I just too lost in the code woods to make any sense ?

After some sleep and 2x strong coffees this morning, I noticed that I stated “docker host” at times, when it was suppose to be “SWAG container”. I’ve fixed it up so it would read correctly for anyone following later on. Apologies about that and I hope it clears up the situation should it have caused any possible confusion.

My confusion was from seeing 172.20.0.5 (SWAG container) and 172.20.0.1 (Docker host|network gateway) being recognized by fail2ban when I add tried options with

set_real_ip_from 172.20.0.0/16;
real_ip_header X-Forwarded-For;

resulting in:

2021-06-08 10:14:05,934 fail2ban.filter [451]: INFO [nextcloud] Found 172.20.0.1 - 2021-06-08 10:14:05
2021-06-08 10:14:32,183 fail2ban.filter [451]: INFO [nextcloud] Found 172.20.0.1 - 2021-06-08 10:14:32
2021-06-08 10:14:38,199 fail2ban.filter [451]: INFO [nextcloud] Found 172.20.0.1 - 2021-06-08 10:14:37
2021-06-08 10:14:38,285 fail2ban.actions [451]: NOTICE [nextcloud] Ban 172.20.0.1
2021-06-08 10:18:13,524 fail2ban.actions [451]: NOTICE [nextcloud] Unban 172.20.0.1
2021-06-08 10:18:29,088 fail2ban.filter [451]: INFO [nextcloud] Found 172.20.0.1 - 2021-06-08 10:18:28
2021-06-08 10:19:23,400 fail2ban.filter [451]: INFO [nextcloud] Ignore 172.20.0.5 by ignoreself rule
2021-06-08 10:19:48,646 fail2ban.filter [451]: INFO [nextcloud] Ignore 172.20.0.5 by ignoreself rule
2021-06-08 10:20:13,921 fail2ban.filter [451]: INFO [nextcloud] Ignore 172.20.0.5 by ignoreself rule
2021-06-08 10:21:45,090 fail2ban.filter [451]: INFO [nextcloud] Found 172.20.0.1 - 2021-06-08 10:21:44
2021-06-08 10:36:42,359 fail2ban.filter [451]: INFO [nextcloud] Ignore 172.20.0.5 by ignoreself rule
2021-06-08 10:37:30,053 fail2ban.filter [451]: INFO [nextcloud] Ignore 172.20.0.5 by ignoreself rule
2021-06-08 10:47:24,264 fail2ban.filter [451]: INFO [nextcloud] Ignore 172.20.0.5 by ignoreself rule
2021-06-08 10:47:55,731 fail2ban.filter [451]: INFO [nextcloud] Ignore 172.20.0.5 by ignoreself rule
2021-06-08 10:48:21,376 fail2ban.filter [451]: INFO [nextcloud] Ignore 172.20.0.5 by ignoreself rule

Something within your configuration is stopping the containers from passing on your true IP to your containers. Our containers are already designed to pass to pass this information so I’m not sure what other factors there could be causing this.

I’ve experienced this on retail Nas units but not a Debian install.

How have you installed docker?

I’ve seen that blog, but need to get a bit more acquainted on the PREROUTING he’s referring to.

The IP tables on the Docker Host being:

Chain INPUT (policy ACCEPT)
target prot opt source destination

Chain FORWARD (policy DROP)
target prot opt source destination
DOCKER-USER all – anywhere anywhere
DOCKER-ISOLATION-STAGE-1 all – anywhere anywhere
ACCEPT all – anywhere anywhere ctstate RELATED,ESTABLISHED
DOCKER all – anywhere anywhere
ACCEPT all – anywhere anywhere
ACCEPT all – anywhere anywhere

Chain OUTPUT (policy ACCEPT)
target prot opt source destination

Chain DOCKER (10 references)
target prot opt source destination
ACCEPT tcp – anywhere 172.20.0.3 tcp dpt:https
ACCEPT tcp – anywhere 172.20.0.3 tcp dpt:http

Chain DOCKER-ISOLATION-STAGE-1 (1 references)
target prot opt source destination
DOCKER-ISOLATION-STAGE-2 all – anywhere anywhere
DOCKER-ISOLATION-STAGE-2 all – anywhere anywhere
RETURN all – anywhere anywhere

Chain DOCKER-ISOLATION-STAGE-2 (10 references)
target prot opt source destination
DROP all – anywhere anywhere
DROP all – anywhere anywhere
RETURN all – anywhere anywhere

Chain DOCKER-USER (1 references)
target prot opt source destination
RETURN all – anywhere anywhere

Warning: iptables-legacy tables present, use iptables-legacy to see them

iptables-legacy -L

Chain INPUT (policy ACCEPT)
target prot opt source destination

Chain FORWARD (policy ACCEPT)
target prot opt source destination

Chain OUTPUT (policy ACCEPT)
target prot opt source destination

Docker’s installation was et minimal most basic:

sudo apt-get -y install docker-ce docker-ce-cli containerd.io

Hmm, so you didn’t use the get.docker.com script?
More often than not, the supplied binaries of docker by distro’s is outdated. I would advise switching.

Could you though elaborate on the configuration/implementation on how the client_ip info is expected/configured to pass between the host and containers ?