External Proxy to kopano-docker



  • Hi,

    i’m trying to setup an external nginx as reverse proxy to get to the kopano running on docker.

    As per this hint in the project documentation, i’ve set TLS_MODE to tls_off in the kopano_ssl.env file and set about to implement nginx as reverse proxy as follows:

    upstream kopano {
        server 127.0.0.1:2015;
    }
    
    
    server {
    
        listen 80 default_server;
        listen [::]:80 default_server;
        server_tokens off;
        return 301 https://$host$request_uri;
    }
    
    server {
        listen 443 ssl http2;
        listen [::]:443 ssl http2;
        server_name mail.example.com autodiscover.example.com;
        server_tokens off;
    
        #ssl_protocols TLSv1.2 TLSv1.3;
        #ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
        #ssl_prefer_server_ciphers off;
    
        ssl_protocols TLSv1.2 TLSv1.3;# Requires nginx >= 1.13.0 else use TLSv1.2
        ssl_prefer_server_ciphers on;
        ssl_ciphers EECDH+AESGCM:EDH+AESGCM;
        ssl_ecdh_curve secp384r1; # Requires nginx >= 1.1.0
        ssl_session_timeout  10m;
        ssl_session_cache shared:SSL:10m;
        ssl_session_tickets off; # Requires nginx >= 1.5.9
        ssl_stapling on; # Requires nginx >= 1.3.7
        ssl_stapling_verify on; # Requires nginx => 1.3.7
    #    resolver $DNS-IP-1 $DNS-IP-2 valid=300s;
    #    resolver_timeout 5s;
        add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload; always;";
        #add_header X-Frame-Options DENY;
        #add_header X-Content-Type-Options nosniff;
        #add_header X-XSS-Protection "1; mode=block";
    
        add_header Referrer-Policy "no-referrer" always;
        add_header X-Content-Type-Options "nosniff" always;
        add_header X-Download-Options "noopen" always;
        add_header X-Frame-Options "SAMEORIGIN" always;
        add_header X-Permitted-Cross-Domain-Policies "none" always;
        add_header X-Robots-Tag "none" always;
        add_header X-XSS-Protection "1; mode=block" always;
    
    
        ssl_certificate /etc/ssl/example.com/fullchain.pem;
        ssl_certificate_key /etc/ssl/example.com/privkey.pem;
    
        # curl https://ssl-config.mozilla.org/ffdhe2048.txt > /path/to/dhparam.pem
        ssl_dhparam /etc/ssl/certs/dhparam.pem;
    
    
        # verify chain of trust of OCSP response using Root CA and Intermediate certs
        ssl_trusted_certificate /etc/ssl/example.com/fullchain.pem;
    
        location / {
          proxy_pass http://kopano;
    #      proxy_http_version 1.1;
          proxy_set_header Upgrade $http_upgrade;
          proxy_set_header Connection $connection_upgrade;
          proxy_set_header X-Forwarded-Proto $scheme;
          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;
        }
    }
    map $http_upgrade $connection_upgrade {
            default upgrade;
            '' close;
    }
    proxy_ssl_session_reuse off;
    proxy_buffering on;
    proxy_ignore_client_abort off;
    proxy_redirect off;
    proxy_connect_timeout 90;
    

    SSL settings are according to the great Mozilla SSL Configuration Generator.

    My .env file contains the follwing (relevant) settings:

    FQDN=mail.strnad.io
    FQDNCLEANED=10.0.50.5
    DEFAULTREDIRECT=/webapp
    EMAIL=off
    #self_signed
    CADDY=2015
    
    INSECURE=yes
    

    Nginx serves the SSL fortified connection to my client (Firefox, but Chrome does just the same), but spits out an HTTP error 400 - Bad Request.

    The logs from nginx are clean, so are those from the web container, but the kopano_webapp container reports:

    [ERROR 0 /webapp/] PHP message: Rejected insecure request as configuration for 'INSECURE_COOKIES' is false.
    

    It does not matter if i change the INSECURE variable to no, that just seems to change the connection to the kopano_server container.

    Can someone share some insight what’s happening here?

    Cheers!


  • Kopano

    Hi @demerzel999,

    I have not tried to reproduce this, but the INSECURE setting only concerns components such as kopano-server, konnect, kwmserver and grapi/kapi as it disables ssl certificate validation (which should only be done in testing scenarios and should not be set for production deployments).

    WebApp has had for a while already a feature that only allowed setting cookies for https connections. The “cure” for this is already what is logged. You need to switch the setting of INSECURE_COOKIES in WebApps config.php to to true.



  • Hi @fbartels,

    is there any other way apart from setting INSECURE_COOKIES to true?

    Apart from that, how would one go ahead on this in a docker setting? The build process seems to download and install the .deb packages from the community server, there is no local source in the git tree.
    Using a COPY statement in the Dockerfile would surely achieve that, but would als splice my environment from the repositories.
    Having said that, i would like to keep it as close to your environment as possible for future updates.

    Cheers!


  • Kopano

    @demerzel999 said in External Proxy to kopano-docker:

    Apart from that, how would one go ahead on this in a docker setting?

    All settings in kopano-docker can be done through environment variables. In this case it should be something like KCCONF_WEBAPP_INSECURE_COOKIES=true.

    Relevant code: https://github.com/zokradonh/kopano-docker/blob/93b4964f200dd6e0322ea9cabe69c53654fbbd9e/webapp/start.sh#L60-L63

    @demerzel999 said in External Proxy to kopano-docker:

    is there any other way apart from setting INSECURE_COOKIES to true?

    Setting this is certainly not needed when using kweb directly. If you must use Nginx, then you could also proxy from Nginx directly to the individual containers.



  • @fbartels said in External Proxy to kopano-docker:

    All settings in kopano-docker can be done through environment variables. In this case it should be something like KCCONF_WEBAPP_INSECURE_COOKIES=true.

    Relevant code: https://github.com/zokradonh/kopano-docker/blob/93b4964f200dd6e0322ea9cabe69c53654fbbd9e/webapp/start.sh#L60-L63

    That’s a neat trick indeed, thank you for pointing this out, i haven’t looked through the .sh files yet.

    Setting this is certainly not needed when using kweb directly. If you must use Nginx, then you could also proxy from Nginx directly to the individual containers.

    Just turned everything back to caddy (setting TLS_MODE to tls_custom and supplying the same certificates as for nginx), going for https://mail.example.com/webapp yields PR_END_OF_FILE_ERROR on the browserside, nothing in the logs.

    curl -k -L https://mail.example.com/webapp just returns curl: (35) error:1408F10B:SSL routines:ssl3_get_record:wrong version number.

    Does Caddy need the certificates in a different format than nginx?


  • Kopano

    @demerzel999 said in External Proxy to kopano-docker:

    i haven’t looked through the .sh files yet.

    Its also documented in the readme of the php base image. Maybe I should move it into the readme of the WebApp image instead? https://github.com/zokradonh/kopano-docker/tree/master/php#configuration-through-environment-variables

    @demerzel999 said in External Proxy to kopano-docker:

    Does Caddy need the certificates in a different format than nginx?

    No, normally not. I am using the same pair of certificates in my lab for both Nginx and kweb (generated through mkcert). Has the certificate mail.example.com in either the cn or one of the san?



  • @fbartels

    Its also documented in the readme of the php base image. Maybe I should move it into the readme of the WebApp image instead? https://github.com/zokradonh/kopano-docker/tree/master/php#configuration-through-environment-variables

    I agree, that would be helpful - maybe make a consolidated documentation-link-section in the main README on github?

    No, normally not. I am using the same pair of certificates in my lab for both Nginx and kweb (generated through mkcert). Has the certificate mail.example.com in either the cn or one of the san?

    I’m actually using the letsencrypt certificate internally by creating a DNS entry for my external domain (or more precise: the FQDN of my mailserver, mail.example.com). That way, my clients will be able to use ActiveSync on my internal WLAN too.

    As per documentation, i set the following:

    FQDN=mail.example.com
    FQDNCLEANED=10.0.50.5
    

    so Caddy would need to route all requests.
    Would it be more benefitial to use an internal domain name (say mail.internal.local, which would yield a valid DNS-resolution to the internal IP) for FQDNCLEANED?


  • Kopano

    @demerzel999 said in External Proxy to kopano-docker:

    maybe make a consolidated documentation-link-section in the main README on github?

    That is how it was before, people did not read that either ;-)

    @demerzel999 said in External Proxy to kopano-docker:

    Would it be more benefitial to use an internal domain name for FQDNCLEANED?

    No, that would not make a difference. The only place this variable is used is
    https://github.com/zokradonh/kopano-docker/blob/1d80122e51fa2b034c8607e902215228a4d2e792/docker-compose.yml#L20 and that only to make sure that internal internal traffic is routed through the web container and not to outside of the docker network (if you use kweb as your proxy). But thinking about this I will add a small tweak to the compose file to simply use a fake domain, when the environment variable was not set.


Log in to reply