Solving Real-IP issue running Kopano-Web behind reverse proxy in Docker
-
All,
I’d like to share my solution for getting the clients real-Ip exposed in log files when running Kopano in Docker, in my case Kopano4S.My proposal includes a feature request to the community respectively Kopano to make failed logins visible in error log other than nginx as Z-Push is doing so.
Problem Statement:
Web-Client requests are not traceable as IP address gets masked by Docker when running in default bridge mode to private IPs making fail2ban unusable.
Even simple Reverse-Proxy directives X-Forwarded-For appear not to work which seems to be linked to Dockers userland-proxy exposing ports.Solution(s):
Considering the sledgehammer solution approach running Docker in host mode should be used with caution here is a smarter solution maintaining containerized NW.- Front-End NGINX outside Docker passing Real-IP plus X-Forwarded-For:
On your Unix server outside Docker aka the Docker host have the following configuration (sample webapp location section as used on Synology for Kopano4S)
location ^~ /webapp/ {
proxy_pass https://127.0.0.1:9443;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_intercept_errors on;
proxy_http_version 1.1;
}- Back-End NGINX inside Docker passing Real-IP to PHP and custom access log:
In nginx.conf http basic section set custom log and in conf.d/ section ensure Real-IP is always set plus passed to PHP
http { .... # Logging Settings # we adjust log format to see the real_ip from clients instead of docker_host_ip log_format custom_combined '$http_x_real_ip - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent"'; access_log /var/log/kopano/nginx-access.log custom_combined; error_log /var/log/kopano/nginx-error.log info; ..... }
server { listen 0.0.0.0:9443 ssl; ..... # ensure http_x_real_ip is set so we use it in access log instead of remote_addr if ($http_x_real_ip = '') { set $http_x_real_ip $remote_addr; } ..... location ~ \.php$ { try_files $uri =404; include fastcgi.conf; include fastcgi_params; # we pass real_ip as remote address to php so we get the client instead of docker host ip fastcgi_param REMOTE_ADDR $http_x_real_ip; fastcgi_pass unix:/var/run/php/php7.0-fpm.sock; }
Hope that helps. -TosoBoso