How to get the real IPs in logs

@Wpq were you able to figure this out? I just followed a similar path. I’m using docker-compose, my reverse proxy is Traefik. I’m using the nextcloud:apache Docker image. I’m seeing correct and expected IP addresses in log lines in nextcloud.log (remoteAddr represents actual client IP addresses), but the Apache log (viewed via docker-compose logs) still shows the proxy IP address. I thought the issue was in the apache config, my proxy’s IP address is not in any of the ranges listed for RemoteIPTrustedProxy. However, I tried customizing /etc/apache2/conf-enabled/remoteip.conf with my proxy IP but the Apache logs still show the proxy IP address, not the real client IP address. It’s not a dealbreaker for me (I can, for example, train fail2ban to watch the nextcloud log) but it is annoying.

@meonkeys No, I did not. There is a fundamental problem with logging in Netxcloud, simply due to the fact that half of the people claim “it works” and the other half “it does not work”.

I tried every combination of parameters and did not manage to get the right IP. At the same time in the various 20+ services I run I do not have this problem. I work in hardcore IT for more years I would like to believe I do, so if that can be an indication that something is wrong there, it is.

Do you have ProxyPreserveHost set on the proxy?

Ugh, bummer. Just to be clear, which log files are you examining? Apache or Nextcloud? Or both?

1 Like

The reverse proxy (Traefik) is properly passing on X-Real-Ip and Nextcloud is using it: client IPs show up as expected in the Nextcloud log. I’m pretty sure there’s just something odd going on with the in-container Apache config.

1 Like

I had a similar issue that I couldn’t nail down for a bit. In the end I found a vague reference in documentation elsewhere that recommends modifying the apache2.conf LogFormat entries, replacing %h with %a like my example below.

LogFormat "%v:%p %a %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" vhost_combined
LogFormat "%a %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%a %l %u %t \"%r\" %>s %O" common
LogFormat "%{Referer}i -> %U" referer
LogFormat "%{User-agent}i" agent

Doing this and restarting the apache2 service seemed to fix the issue, although being a Docker container this won’t fix the issue for me longer term. Interested to know if this helps solve the issue for anyone else though!

1 Like

I was just trying to solve this problem for a non-docker install on a server behind an nginx reverse proxy, and came across this thread. I played around with the suggestions here and this is what worked for me:

NGINX on gateway/proxy:

server {
listen 443;
listen [::]:443;
server_name cloud.blah.com;
proxy_connect_timeout 600;
proxy_send_timeout 600;
proxy_read_timeout 600;
send_timeout 600;
location / {
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_pass https://192.168.1.6:443;
  }
ssl_certificate /etc/letsencrypt/live/cloud.blah.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/cloud.blah.com/privkey.pem; # managed by Certbot
}

I basically had to fully fit out the nextcloud’s nginx config, with its own SSL certificate, in order to get it working properly. There were endless http <-> https problems until I did this.
NGINX on nextcloud server:

server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name cloud.blah.com 

ssl_certificate /etc/letsencrypt/live/cloud.blah.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/cloud.blah.com/privkey.pem; # managed by Certbot

#... rest of the full config as if this was in a DMZ

config/config.php:

...
'trusted_domains' =>
array (
  0 => 'cloud.blah.com',
  1 => '192.168.1.6',
),
'trusted_proxies' =>
array (
  0 => '192.168.1.8',  /* the proxy IP */
),
'forwarded_for_headers' => array('HTTP_X_REAL_IP'),
'overwrite.cli.url' => 'https://cloud.blah.com',
'overwriteprotocol' => 'https',
'overwritecondaddr' => '^192.168.1.8$',
...

After I restarted php/nginx on the nextcloud server, it just worked. The nextcloud.log started showing the correct IP whether it was from a local networked machine, or an external one.

@dmartin: you withdrew the post because there was problem with what you provided as a solution?

I am asking because I use Caddy as the reverse proxy to nextcloud living in its own container as well. So your information was wonderful news :slight_smile:

One thing though, you mentioned

(…) in the caddy inside the container (…)

Does this mean that you have to rebuild the container every time there is a new version (I update nextcloud though watchtower)

I just tried this and it actually works. I wonder what you have to change in the settings to make it work permanently though.

So, for other who search for a solution, here is how I solved it:

I’m using reverse proxy with HAproxy, with ssl offloading, running nextcloud in docker
Also using nat reflection so that I can use my external host on my internal network

First added my haproxy to config.php trusted_proxies (nextcloud_config dir)

By enabling X-Forwarded-For header in HA proxy, I did get my client IP’s in nextcloud.log, also verified headers with tcpdump (also easily testet with something like containous/whoami),
apache logs didn’t care about that, first of all, I had to change %h to %a in LogFormat (in apache2.conf), which is the variable that mod_remoteip uses, then I had to add the X-Real-IP header to HAproxy as it doesn’t seem to listen to X-Forwarded-For in this configuration, now I can see the client IP’s of external clients
Clients originates from my local network still just shows the proxy as ip

After some investigation, I did some changes in /etc/apache2/conf-enabled/remoteip.conf
Commented out all RemoteIPTrustedProxy lines and added:
RemoteIPInternalProxy

By doing so, IP’s of clients originating from my local network also hits the apache log

Further I noticed that mod_remoteip only had “RemoteIPHeader X-Real-IP” configured, by changing that to:
RemoteIPHeader X-Forwarded-For
in remoteip.conf, it was unnecessary to add the X-Real-IP header in HAproxy config

I would like to see a persistent solution to this

This is the changes I did from within the container:

sed -i -e 's/RemoteIPHeader X-Real-IP/RemoteIPHeader X-Forwarded-For/g' /etc/apache2/conf-enabled/remoteip.conf
sed -i -e 's/RemoteIPTrustedProxy/#RemoteIPTrustedProxy/g' /etc/apache2/conf-enabled/remoteip.conf
echo "RemoteIPInternalProxy $(env | grep TRUSTED_PROXIES | cut -d= -f2)" >> /etc/apache2/conf-enabled/remoteip.conf
sed -i -e '/LogFormat/s/%h/%a/g' /etc/apache2/apache2.conf

note that TRUSTED_PROXIES env variable has to be set to the reverse proxy ip

Feel free to correct me if I made some mistakes

1 Like

I would like to see a persistent solution to this

I think that this is the key point, I have a docker container that is replaced at each update and while I can imagine persisting some files (the ones @linus.nordin mentioned), this will not help if there are some changes that must be done from within the container (i.e. changes that are dynamic and cannot be persisted)

3 Likes

I also agree with @Wpq

+1 for this

1 Like

I was following a fail2ban nextcloud guide and I can’t get the real IP from the logs too. Using the docker nextcloud:21 which is apache. :confused:

I’m not sure about changing the proxy IP inside the apache config manually in case Traefik changes it… that would cause problems I imagine.

Hi, I was trying to get this working for a few days so when it finally worked I decided to left here my configuration. Maybe it’ll help someone.

Docker-compose.yml:

  app:
    image: nextcloud
    network_mode: bridge
    restart: always
    ports:
      - "172.17.0.1:8080:80"
    links:
      - db
    volumes:
      - /usr/docker/cloud/www:/var/www/html
      - /mnt/nfs/Cloud/data:/var/www/html/data 
      - /usr/docker/cloud/apache2:/etc/apache2

nginx.conf:

    location / {
        proxy_pass http://172.17.0.1:8080;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

remoteip.conf (must be inside apache2\conf-enabled !):

RemoteIPHeader X-Forwarded-For
RemoteIPTrustedProxy 172.17.0.1

Apache2.conf (only changes):

LogFormat "%v:%p %h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" vhost_combined
LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %O" common
LogFormat "%{Referer}i -> %U" referer
LogFormat "%{User-agent}i" agent

config.php (changes only):

'forwarded_for_headers' => array('HTTP_X_FORWARDED_FOR'),
  'trusted_domains' => 
  array (
    0 => '172.17.0.1:8080',
  ),
1 Like

Stubled upon this in my own quest to get ip’s working in apache2. In the end it wasn’t all that hard:

  • Just don’t set APACHE_DISABLE_REWRITE_IP env var, its value doesn’t seem to matter. If it’s there remoteip in apache2 gets disabled by nextcloud. Without this it kind of just works for reverse proxies that provide the X-Real-Ip and are in the private ip range. Which is pretty much what you would expect in a docker based setup.
  • BUT: RemoteIPTrustedProxy does not work for internal ip’s, guess some people are ok with this and you’re done now. But there is also RemoteIPInternalProxy, because I use podman with a systemd config file all I needed to do was add:

ExecStartPost=/usr/bin/podman exec -it nextcloud_app /bin/bash -c ‘sleep 5 && rm -f /etc/apache2/conf-available/remoteip.conf && echo -e “RemoteIPHeader X-Real-IP\nRemoteIPInternalProxy 10.0.0.0/8” > /etc/apache2/conf-available/remoteip.conf && /usr/sbin/service apache2 reload’

To my nextcloud-app systemd Unit file.

I do realise this is not stricly the way to go on a docker container, but don’t see how this would change. Nevertheless, perhaps somebody @nextcloud could consider this?

PS I recall reading somewhere APACHE_DISABLE_REWRITE_IP was a security measure when using a reverse proxy. If this is the case I do agree with others in this thread: please fix this!!! nextcloud.log is for errors not for traffic logs :confused:

1 Like

the more elegant way to apply permanent changes to files inside of the container is to mount the files on the host as I described here:

Apache Docker behind reverse proxy

1 Like