Installation behind nginx rev. proxy fails

I installed passbolt on a debian 9 running with apache 2.4 and php 7.3.
Connection from the public is realized through a reverse proxy with nginx.
The healthcheck fails with the following result:

[PASS] Full base url is set to https://passbolt.freifunk-stuttgart.de
[PASS] App.fullBaseUrl validation OK.
[FAIL] Could not reach the /healthcheck/status with the url specified in App.fullBaseUrl
[HELP] Check that the domain name is correct in config/passbolt.php
[HELP] Check the network settings

SSL Certificate

[FAIL] SSL peer certificate does not validate
[FAIL] Hostname does not match when validating certificates.
[WARN] Using a self-signed certificate
[HELP] cURL Error (7) Failed to connect to passbolt.freifunk-stuttgart.de port 443: Connection refused

Some of the checks are misleading: The LE cert for https has the correct hostname and P. 443 is available. Although I am shure I have a correct apache *.conf , the main url answers with “the requested URL was not found on this server.” Hmmmm …

The only similar topic I can find is at Install passbolt behind an existing Nginx Reverse Proxy but its not really helpful.

I would appreciate if someone can give me an idea where to search for the error. I believe it has to do with the reverse proxy or the cert which is provided there…

Thanks, Thommie

Hi @Thommie, I run my install on Ubuntu behind an Nginx reverse proxy.

What does your /etc/hosts file look like? Does it include “127.0.0.1 passbolt.freifunk-stuttgart.de”?

Can you share the reverse proxy nginx configuration and the apache configuration?

Here is the rev proxy config (nginx), the apache config of the passbolt container is “just standard” (virtual host on p. 80) as both containers communicate in the same local network:

server {
        listen 80;
        listen [::]:80;
        server_name passbolt.freifunk-stuttgart.de *.passbolt.freifunk-stuttgart.de;

    include /etc/nginx/snippets/serve-letsencrypt-challenges.conf;

    location / {
        return 301 https://passbolt.freifunk-stuttgart.de$request_uri;
    }


server {
        listen 80;
        listen [::]:80;
        server_name passbolt.freifunk-stuttgart.de *.passbolt.freifunk-stuttgart.de;

    include /etc/nginx/snippets/serve-letsencrypt-challenges.conf;

    location / {
        return 301 https://passbolt.freifunk-stuttgart.de$request_uri;
    }



    client_max_body_size 1M;
}

    client_max_body_size 1M;
}


server {
        #Listen SSL+HTTP/2
        listen 443 ssl http2;
        listen [::]:443 ssl http2;

        #Server Name
        server_name passbolt.freifunk-stuttgart.de;

        #Security Stuff comes later
        # include /etc/nginx/snippets/security.conf;

        #Forward all
        location / {

        proxy_pass http://10.0.3.235/;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $remote_addr;

        }

    client_max_body_size 1M;

        #SSL
        ssl_certificate /etc/letsencrypt/live/passbolt.freifunk-stuttgart.de/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/passbolt.freifunk-stuttgart.de/privkey.pem;
        ssl_trusted_certificate /etc/letsencrypt/live/passbolt.freifunk-stuttgart.de/chain.pem;

@Thommie I think you need to change the config file to show http and not https, based on your reverse proxy settings. No cert is used or needed with backend.

Or, if you intend for a cert to be used, change the nginx proxy_pass to https instead.

Hmmm, I tried with p. 443 on the passbolt backend and a change of the proxy-pass, but no success.

I am not familiar with nginx. I understand that we present both p. 80 and 443 on the nginx config. nginx adds the cert and proxy-pass redirects incoming requests to p. 80 of the passbolt backend container. But why do I get the 404 not found there? That makes no sense …

I have a similar setup in another environment, but wth haproxy as ssl terminator/rev-proxy and it works fine. ???

@Thommie The Nginx config you pasted appears to have duplicates…not sure if you intended for this or if you pasted twice by accident. There are two server sections for port 80, listening for the same domain.

Run nginx -t to test the configuration after changes, and then service nginx restart to make live.

I have an example config to show you, and you might notice a difference regarding how http is redirected to https on the reverse proxy…Nginx can be finicky in this regard. Consider how you want the final domain to appear (www.domain.com or domain.com) and return appropriately.

server {
        listen 80;
        server_name     www.domain.com domain.com; # list both, redirecting to https
        return 301 https://www.domain.com;
}

server {
        listen 443 ssl http2;
        server_name     domain.com; # list the one in https that you do not want in the end
        return 301 https://www.domain.com; # list the one you want

       # certs sent to the client in SERVER HELLO are concatenated in ssl_cert$
        ssl_certificate             /path/to/fullchain.cer;
        ssl_certificate_key     /path/to/domain.com.key;

}

server {
        listen 443 ssl http2;
        server_name     www.domain.com; # list the one you want in the end

        # logging settings
        access_log      /var/log/nginx/www.domain.com/access.log;
        error_log       /var/log/nginx/www.domain.com/error.log error;

        # modern configuration https://mozilla.github.io/server-side-tls/ssl-config-generator/
?server=nginx-1.14.0&openssl=1.1.0e&hsts=no&profile=modern
        ssl_protocols TLSv1.2 TLSv1.3;
        ssl_prefer_server_ciphers on;
        ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256';
        ssl_dhparam /etc/nginx/ssl/dhparam.pem;
        ssl_ecdh_curve prime256v1:secp384r1:secp521r1;
        ssl_stapling on;
        ssl_stapling_verify on;


        # certs
        ssl_certificate             /path/to/fullchain.cer;
        ssl_certificate_key     /path/to/domain.com.key;
        ssl_session_timeout     1d;
        ssl_session_cache       shared:SSL:50m;
        ssl_session_tickets     off;


        location / {

                proxy_set_header        Host $host;
                proxy_set_header        X-Real-IP $remote_addr;
                proxy_pass              https://10.10.3.3; # notice no forward slash on end
        }
}

Also, can you provide error logs with more specifics?

And, did you confirm /etc/hosts?

image
This shows that Nginx is sending to port 80

I may have been unclear here - the config file I was referring to was the passbolt config. Setting the App.fullBaseUrl to http://passbolt.freifunk-stuttgart.de would no longer ask for a secure connection…and if you are not intending to use a cert to the backend, then the backend itself should request the http version, and not https.

Thanks garret, I understand. I now changed the rev. proxy setting according to your recommendations. But I think the root cause is at an earlier point of installation: I am not shure if the resolution of all package dependencies was solved correctly with composer. The output is:

$ composer install --no-dev
Loading composer repositories with package information
Installing dependencies from lock file
Nothing to install or update
Generating optimized autoload files
> Cake\Composer\Installer\PluginInstaller::postAutoloadDump
thadafinser/package-info:  Generating class...
thadafinser/package-info: ...generating class
> App\Console\Installer::postInstall
Set Folder Permissions ? (Default to Y) [Y,n]? Y
No Security.salt placeholder to replace.

The 404 code comes from the Location Header after the initial reply with “302 Found”. So we have a problem inside the passbolt app, not at the rev-proxy level …

Agreed.

And you have confirmed that /etc/hosts on the backend passbolt server includes passbolt.freifunk-stuttgart.de?

Hi garrett,

127.0.0.1 passbolt.freifunk-stuttgart.de
::1 localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
# — BEGIN PVE —
10.0.3.235 passbolt.freifunk-stuttgart.de passbolt
# — END PVE —
10.0.3.3 salt

The healthcheck only has errors coming from the certs check which, I think, is unavoidable for this kind of setup where the app is behind a rev. proxy providing the ssl stuff:

[PASS] Full base url is set to https://passbolt.freifunk-stuttgart.de
[PASS] App.fullBaseUrl validation OK.
[FAIL] Could not reach the /healthcheck/status with the url specified in App.fullBaseUrl
[HELP] Check that the domain name is correct in config/passbolt.php
[HELP] Check the network settings

SSL Certificate

[FAIL] SSL peer certificate does not validate
[FAIL] Hostname does not match when validating certificates.
[WARN] Using a self-signed certificate
[HELP] cURL Error (35) error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol

If you change the full base url to http instead, try accessing the backend directly with http and not through the reverse proxy, and see if it works to confirm your suspicion.

If it comes down to a cert issue, then at least we know there are no problems otherwise.

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.