[Solved] Caddy reverse proxy - Cannot get correct IP

Hi,
I’m finalizing my nextcloud installation with docker on my Pi4. Everything is running fine. The only problem is that the nextcloud log always displays the IP of the reverse proxy (172.18.0.4) instead of having the real IP.

I added the IP in config.php as a trusted proxy.

'trusted_proxies' => ['172.18.0.4'],

I also configured the following according to the manual:

php occ config:system:set overwriteprotocol --value="https"
php occ config:system:set overwritehost  --value="cloud.mydomain.com"
php occ config:system:set overwritewebroot --value="/"
php occ config:system:set overwrite.cli.url --value="https://cloud.mydomain.com"
php occ config:system:set htaccess.RewriteBase --value="/"

I use a custom network so I added a trusted IP in the apache remoteip.conf to match the IP range of the network (both nextcloud and caddy are in the same network).

RemoteIPTrustedProxy 172.18.0.0/12

In Caddy config I added entries for X-Real-IP and X-Forward-For. I have a doubt if it should be header_down or header_up. Anyway I tried both with no luck

   reverse_proxy http://nextcloud-srv {
      header_down Strict-Transport-Security "max-age=15552000;"
      header_down X-Real-IP {http.request.remote}
      header_down X-Forwarded-For {http.request.remote}
   }

I Caddy’s log I can see the header with the expected IP

"X-Real-Ip":["192.168.0.1:47280"]
"X-Forwarded-For":["192.168.0.1:47280"]

However after all this the nextcloud log keeps showing the reverse proxy IP when I do something in my browser.

Any idea what I’m doing wrong ? I spent the last 2 evening on this and I did not progress much.

Thanks

I switched to a reverse proxy based on ngnix instead (linuxserver/letsencrypt), but I still can’t get the real IP.

I found that I could enable the forensic module in apache to “dump” the header. In the log I can see that both X-Real-IP and X-Forwarded-For are set with the correct IP.

The header when I connect to my internet IPs (for some reason it shows the LAN IP)

+30:5e92d64c:4|GET /core/img/favicon.ico HTTP/1.1|Host:cloud.mydomain.com|X-Real-IP:192.168.0.1|X-Forwarded-For:192.168.0.1|
X-Forwarded-Proto:https|X-Forwarded-Host:cloud.mydomain.com|X-Forwarded-Ssl:on|
user-agent:Mozilla/5.0 (X11; Fedora; Linux x86_64; rv%3a75.0) Gecko/20100101 Firefox/75.0|accept:image/webp,*/*|

The same information when I connect using VPN. The IP is the one for my VPN connection

+30:5e92d80f:6|GET /core/img/background.png?v=0 HTTP/1.1|Host:cloud.mydomain.com|
X-Real-IP:192.40.57.229|X-Forwarded-For:192.40.57.229|X-Forwarded-Proto:https|
X-Forwarded-Host:cloud.mydomain.com|X-Forwarded-Ssl:on

Based on that it’s safe to say that the reverse proxy is setting the header properly, but it’s apache that does not use that information. I’ll check apache and I’ll post back if I find the solution.

I found the problem. In fact everything was fine. The problem was apache that was not logging the correct info.

By default the Apache log looks like the following:

LogFormat "%h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined

The apache documentation clearly indicate that in case of a reverse proxy %h will be the IP of the reverse proxy, not the client.

To fixed it I replaced %h with %{X-Forwarded-For}

LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined

I also made sure that the IP of my reverse proxy is trused (/etc/apache2/conf-enabled/remoteip.conf)

RemoteIPTrustedProxy 172.18.0.0/16

Here I’m using an IP range because I’m not using static IP for my docker container. It’s not a big problem for a home installation. The 172.18.0.0/16 subnet is dedicated to docker.

With the above changes I now have the correct IP in apache log file.

I was already using a Dockerfile to apply minor changes to the nextcloud image (e.g. create data folder with permission for www-data user). I used the same Docker file to add few lines to automatically apply these modifications:

# add/modify apache configuration for use behing a reverse proxy
# - add docker ip range in which the proxy is. using range because I don't use static IP
# - change log to use X-Forwarded-For instead of %h (shows reverse proxy ip). Only change in LogFormat lines
RUN echo "RemoteIPTrustedProxy 172.18.0.0/16" >> /etc/apache2/conf-enabled/remoteip.conf && \
    sed -i -e "/^LogFormat.*$/s/%h/%{X-Forwarded-For}i/g" /etc/apache2/apache2.conf