0

Premise

In the past days I setup a home server running Mastodon with Docker. I already have a Nextcloud instance running on a Raspberry so now I'm trying to make both available thru dedicated subdomains (I'm using free DDNS).

I set up the two subdomains (both obviously point to my home router) like theese:

  • mastodon.example.com
  • nextcloud.example.com

Then I set up port forwarding in my router to send TCP/UDP traffic on ports 80, 443 to the same ports of the Mastodon server, while TCP/UDP traffic on custom ports 3000, 3001 is mapped to ports 80, 443 of the Nexcloud server.

Until here no problem, if I type https://mastodon.example.com in the browser I get to the Mastodon server and with https://nextcloud.example.com:3001 I get to the Nextcloud one.

The problem

Now I'm trying to edit the configuration of the nginx-proxy container in the mastodon server in order to redirect every request for nextcloud.example.com to nextcloud.example.com:3001 to avoid having to specify the port.

I created a new file myadditions.conf in the folder mapped to the /etc/nginx/conf.d volume of the container, and after restarting the server I can confirm nginx has loaded it correctly with docker exec nginx-proxy nginx -T.

My problem is that everything I tryed to put in the file to make the redirect seems to be ignored, the result I get when I type nextcloud.example.com is always the same: error MOZILLA_PKIX_ERROR_SELF_SIGNED_CERT (I'm using Firefox). I suppose that error is because the server is not trying to redirect the call and so the certificate it provides does not match with the nextcloud subdomain. Is there something I'm missing?

Currently my myadditions.conf file looks like this:

server {
    server_name nextcloud.example.com;
    return 301 $scheme://nextcloud.example.com:3001$request_uri;
}

but I have tried a lot of settings without any change in the result, so I'm starting to think that the problem is not what I write in the file. By the way, also if I delete my file the error is the same.

2 Answers 2

0

You are connecting to an HTTPS URL, so the server that answers must be set up for HTTPS for that domain – it cannot just serve a plain-text redirect without fully establishing the TLS connection. (If browsers allowed this, it would make it trivial for an attacker to do the same.)

Your server block doesn't specify that it will be listening on a TLS port and doesn't define any certificate, so it's likely not even chosen for the request – Nginx ends up choosing the first server block that is marked as TLS-capable and uses whatever certificate was defined there.

Keep in mind that 30x redirects are client-side – the server just returns the new URL and the client visits that. You won't need to enter the nonstandard port but it will be visible in the address bar; the nginx-proxy container won't actually be doing any proxying.

If proxying is what you wanted, then you'd need to use proxy_pass instead of return. In that case Nginx would still need a working HTTPS setup.

The only other way Nginx could handle this without having access to a matching certificate for the domain is to proxy all data "blindly" (stream proxy mode) based on the hostname reported through TLS SNI, so that the browser would make the HTTPS handshake with the backend server instead. I'm not sure if Nginx has that function, though there are other proxies which do.

1

Here are the steps I took to solve the problem.

1. Get the additional certificate

I created a letsencrypt_user_data file and mapped it to the nginxproxy/acme-companion container in order to instruct it to request and keep updated the additional certificate for the nextcloud.example.com subdomain (see Standalone certificates in the container documentation). This is my file now:

LETSENCRYPT_STANDALONE_CERTS=('NextCloudCert')

LETSENCRYPT_NextCloudCert_HOST=('nextcloud.example.com')
LETSENCRYPT_NextCloudCert_EMAIL='[email protected]'
LETSENCRYPT_NextCloudCert_TEST=false

2. Correct the nginx redirect

I edited the myadditions.conf file i created in the Nginx configuration folder: I changed the redirect type from return 301 to proxy_pass and added a server context to redirect the traffic on the port 443 specifyng the new certificates. This is how the file looks now, please keep in mind that I just copied and edited it, it works but I dont really know the meaning of good part of what it contains so this could be a bad example to follow:

log_format logFormatNextcloud '$host $remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" "$upstream_addr"';

server {
    server_name nextcloud.example.com;
    listen 80 ;
    access_log /var/log/nginx/access.log logFormatNextcloud;
    # Do not HTTPS redirect Let's Encrypt ACME challenge
    location ^~ /.well-known/acme-challenge/ {
        auth_basic off;
        auth_request off;
        allow all;
        root /usr/share/nginx/html;
        try_files $uri =404;
        break;
    }
    location / {
        return 301 https://$host$request_uri;
    }
}
server {
    server_name nextcloud.example.com;
    access_log /var/log/nginx/access.log logFormatNextcloud;
    listen 443 ssl http2 ;
    ssl_session_timeout 5m;
    ssl_session_cache shared:SSL:50m;
    ssl_session_tickets off;
    ssl_certificate /etc/nginx/certs/nextcloud.example.com.crt;
    ssl_certificate_key /etc/nginx/certs/nextcloud.example.com.key;
    ssl_dhparam /etc/nginx/certs/nextcloud.example.com.dhparam.pem;
    ssl_stapling on;
    ssl_stapling_verify on;
    ssl_trusted_certificate /etc/nginx/certs/nextcloud.example.com.chain.pem;
    set $sts_header "";
    if ($https) {
        set $sts_header "max-age=31536000";
    }
    add_header Strict-Transport-Security $sts_header always;
    include /etc/nginx/vhost.d/default;
    location / {
        proxy_pass https://nextcloud.example.com:3001;
        set $upstream_keepalive false;
    }
}

Now both subdomains work. Thank you @u1686_grawity, your answer contained all the hints and explainations I needed.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .