How to get the real IPs in logs

I run Nextcloud in a docker container (:latest, currently 18.0.4). I access it via a reverse proxy.

When looking at the logs, I see one single IP address as the source (the docker network gateway). It seems that the logs display the IP address of the proxy and not the one from the header X-Forwarded-For, which is the real one (and the only one interesting).

Per the documentation, I updated my configuration file with

'trusted_proxies' => array('172.18.0.0/16'),
'forwarded_for_headers' => array('HTTP_X_FORWARDED_FOR'),

but there are no changes (trusted_proxies is the whole range of the docker network because the proxy (itself a container - but with directly exposed ports) can be anywhere)

Just to be complete with the question, the proxy server specifically sets the X-Forwarded-For header:

By default, Caddy passes thru incoming headers to the backend—including the Host header—without modifications, with two exceptions:

Thanks a lot - but unfortunately none of the settings helped.

I removed my config above and added the environment variables to the docker-compose file, no change in the IP.

environment:
      - APACHE_DISABLE_REWRITE_IP=1
      - TRUSTED_PROXIES='172.18.0.0/16'

The logs show an extra line (Conf remoteip disabled) but it seems that this configuration is not applied (?)

 → docker-compose -f /etc/docker/docker-compose.d/nextcloud.yaml down
 → docker-compose -f /etc/docker/docker-compose.d/nextcloud.yaml up -d
Conf remoteip disabled.
To activate the new configuration, you need to run:
  service apache2 reload
AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 172.18.0.15. Set the 'ServerName' directive globally to suppress this message
AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 172.18.0.15. Set the 'ServerName' directive globally to suppress this message
[Fri May 29 13:58:52.958141 2020] [mpm_prefork:notice] [pid 1] AH00163: Apache/2.4.38 (Debian) PHP/7.3.18 configured -- resuming normal operations
[Fri May 29 13:58:52.958192 2020] [core:notice] [pid 1] AH00094: Command line: 'apache2 -D FOREGROUND'
172.18.0.1 - wi [29/May/2020:13:58:56 +0000] "MKCOL /remote.php/webdav/Joplin/.sync/ HTTP/1.1" 405 1526 "-" "Joplin/1.0"
172.18.0.1 - wi [29/May/2020:13:58:56 +0000] "MKCOL /remote.php/webdav/Joplin/.lock/ HTTP/1.1" 405 1516 "-" "Joplin/1.0"
(...)

Looks good to me. The IP should be correct with nexcloud (and nextcloud.log / brute force detection) now. If you need the real ip also with the apache2 log (without enabled remoteip again because that will break brute force detection and the ip with nextcloud.log) modify the log format used by apache2. I usually enable the access log with the reverse proxy.

@kesselb Sorry but I do not understand (I am not sure which configuration you are talking about). To set up some context:

client (192.168.10.3) → reverse proxy (192.168.10.2 / 172.18.0.1) → [ apache → nextcloud ]
                                                                     nextcloud container (172.18.0.5)                              

The IP I see in the logs above (from docker logs nextcloud) is from the reverse proxy. This is the incoming IP the nextcloud container sees.

What I would like to see is the IP of the client, added to X-Forwarded-For by the reverse proxy. To take the example above, I would like to have in the logs

192.168.10.3 - wi [29/May/2020:13:58:56 +0000] "MKCOL /remote.php/webdav/Joplin/.sync/ HTTP/1.1" 405 1526 "-" "Joplin/1.0"
192.168.10.3 - wi [29/May/2020:13:58:56 +0000] "MKCOL /remote.php/webdav/Joplin/.lock/ HTTP/1.1" 405 1516 "-" "Joplin/1.0"

Or enable remoteip again and tell caddy to send x-forwarded-for as x-real-ip. But overwritehost and overwriteprotcol are mandatory then.

My constellation is a Nextcloud docker container behind an Apache Server, set up as a Proxy.

I really searched a lot and tried a lot. The only thing that helped, was editing the enabled-site in the Docker Container to use the remote-ip directives, like it is described here:
https://www.loadbalancer.org/blog/apache-and-x-forwarded-for-headers/
It then looks like this:

SetEnvIf X-Forwarded-For "^.*\..*\..*\..*" forwarded
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" forwarded
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined env=!forwarded
CustomLog ${APACHE_LOG_DIR}/access.log forwarded env=forwarded

I changed the configuration of the Nextclod config.php File like this:

   'trusted_proxies' => array('172.17.0.1','ip.from.apache.proxy',),
   'overwritecondaddr' => '^172\.17\.0\.1$',
   'forwarded_for_headers' => array('HTTP_X_FORWARDED',), 

The 172.17.0.1 is the gateway from the Docker container.

In Apache Proxy Config, it was sufficient to switch on the “ProxyPreserve host on”

Now I get the real IPs in the docker logs nextcloud.

Hope that helps someone. Don’t know if everything is really needed, but it works for me so far.

Perhaps this would be super to integrate it already in the Docker image … that would save lots of time.

Thanks @dora71 for the detailed answer. I will try this out as I almost abandoned the idea to have the right IP (I was getting the proxy one no matter which combinaison of parameters I tried).

I agree that this should be the default - there is no real interest to have the proxy IP (or maybe as a secondary information)

I have a question regarding your setup: where did you configure the Apache part (= where is the Apache configuration file)?

By default mod remoteip is configured to read x-real-ip from a trusted network. Tell caddy to send the forward to as x-real-ip and you are good.

I put it inside the Docker container in /etc/apache2/sites-available/000-default.conf inside the VirtualHost Configuration and commented out the predefined ErrorLog and CustomLog directives.

@kesselb - first of all, thanks a lot for following up, I am quite lost in the settings to be frank.

I set this on caddy and these are the headers which are forwarded to each container (including nextcloud). I removed the non-X ones:

X-Forwarded-For: 192.168.10.72
X-Forwarded-Proto: http
X-Real-Ip: 192.168.10.72

So X-Real-Ip is there, it is the IP of the client calling nextcloud.

I also set in the docker-compose file for nextcloud TRUSTED_PROXIES='172.18.0.0/16' (this is the internal docker network, on which all containers are, including the reverse proxy)

I tried to set and unset (again, in the docker-compose file for nextcloud) APACHE_DISABLE_REWRITE_IP=1.

None of this changed the logging, this is still the IP of the proxy that is displayed.

I then recalled that you wrote (emphasis mine)

Or enable remoteip again and tell caddy to send x-forwarded-for as x-real-ip. But overwritehost and overwriteprotcol are mandatory then.

I am not sure what they mean - the documentation says that these “set the protocol and hostname of the proxy”. I do not know what “the hostname of the proxy” is supposed to be.

My proxy (caddy) has a CNAME nextcloud.example.com (and many others, one for each service behind the proxy). I tried to set this as overwritehost (and https as overwriteprotcol because the full URI is https://nextcloud.example.com - but this did not change anything.

All this was done with a clean nextcloud configuration, the only things I changed there are

'trusted_domains' => 
  array (
    0 => 'nextcloud.example.com',
  ),
  'overwrite.cli.url' => 'https://nextcloud.example.com',
  'overwriteprotocol' => 'https',
  'overwritehost' => 'nextcloud.example.com',

(the actual domain name is mine of course)

Maybe the overwritehost refers to the IP the call comes from (the IP of the proxy, as seen within nextcloud network), so I tried

'overwriteprotocol' => 'http',
'overwritehost' => '172.18.0.1',

Same thing: the IP of the proxy is logged

@Wpq
Did you ever get this figured out?

I am having a similar issue. I’ve tried damn near everything, but it seems Nextcloud does not want to respect the X-Real-Ip or X-Forwarded-For at all. No matter what I do I get the IP address of my reverse proxy (traefik).

@scottdfedorov No, I also tried everything.

I am not very happy with that but I think this is actually a bug (in Nextcloud probably, as the problem exists with several reverse proxies)

Finally, I figured the proper configuration to get the client remote ip logged by Nextcloud. It isn’t a bug. Actually, all is mentioned in the official Nextcloud documentation.

So, I added in the sites-available/nextcloud.conf this additional line:

RemoteIPHeader X-Forwarded-For

Not to mention, you have to enable all belonging modules like remoteip and headers. I run Nextcloud on ubuntu server 20.04, installed through snap. Nextcloud is hidden behind a reverse proxy. The reverse proxy runs Apache 2.4

These two sites appeared as quite helpful:

https://docs.nextcloud.com/server/19/admin_manual/configuration_server/reverse_proxy_configuration.html

https://github.com/nextcloud/nextcloud-snap

‘trusted_proxies’ => [’111.222.333.444’],
‘forwarded_for_headers’ => [‘HTTP_X_FORWARDED_FOR’],
‘overwritehost’ => ‘cloud.example.com’,
‘overwriteprotocol’ => ‘https’,
‘overwrite.cli.url’ => ‘https://cloud.example.com’,
‘trusted_domains’ =>
array (
0 => ‘localhost’,
1 => ‘cloud.example.com’,
),

111.222.333.444 is the ip address of my Apache reverse proxy.

Also, in the settings of Nextcloud the result of the internal security check now is all well. Before, I got the error message that either the reverse proxy header is wrongly configured, or I run Nextcloud behind a trusted reverse proxy. As mentioned, now I only get a green okay confirmation.