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.

    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_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 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