0

I am running nginx and would like to ask you help in explaining how to set up a correct configuration. Im not expert of server maintenance and would like to avoid to misconfigure the running sites.

Below an extract of nginx configuration (the part I think relevant) :

server {

    server_name www.sub.example.com;
    return 301 $scheme://sub.example.com$request_uri;
}

server {

    listen 7000;
    server_name example.com;
...

    #listen 443 ssl; # managed by Certbot
    #ssl_certificate /etc/letsencrypt/live/nifty.works/fullchain.pem; # managed by Certbot
    #ssl_certificate_key /etc/letsencrypt/live/nifty.works/privkey.pem; # managed by Certbot
    #include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    #ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

}

and a proxy server like:


# Virtualhost/server configuration
server {
    listen  80;
    server_name sub.example.com;

..

}

I am using certbot, and I remember I tried to set up automatically the certificate, but had an issue, an I succeded to install correctly an SSL certificate for the main site, if I recall well, using a wildcard certificate.

Certificate expired yesterday, I renewed it helping myself with:

certbot renewal

https://certbot.eff.org/lets-encrypt/ubuntuxenial-nginx

and can see it works OK with the main site.

However, with sub sites, https://sub.example.com points will display the site of the main https://example.com (note, it is not a redirect), while with http http://sub.example.com displays the correct site.

With sudo certbot certonly --nginx I can see the list of subdomains to activate https for.

Before tampering, I would like to ask you:

Can you can help to brief me out in setting up a correct configuration for SSL also for subdomains?

Please note that all subdomains makes use of APIs (mostly GET, a few POST) : I am concerned about breaking the site (backend is in flask python, and possibly wish to avoid to set up users credentials - it is just an open site, with a few share plugins from socials).

1 Answer 1

4

This is entirely the fault of the NGINX configuration, and it is behaving As Configured by certbot / yourself.

When an NGINX server section listens on a port, if it is the only service listening on that port it will become the default server block to match on that port. This is By Design.

You will need a separate section in your configuration for your subdomain with a valid HTTPS configuration and certificate on it to make requests to https://sub.example.com/ to go to the correct docroot.

Example configuration of this (except both server blocks serve HTTP and HTTPS without needing to expand the number of server configurations):

server {
    listen 80 default_server;
    listen 443 default_server;

    server_name example.com;

    ssl_certificate /etc/nginx/ssl/example.com.crt;
    ssl_certificate_key /etc/nginx/ssl/example.com.key;

    root /var/www/example.com;

    if ($scheme = http) {
        return 301 https://$server_name$request_uri;
    }

    # ... other config here
}

server {
    listen 80;
    listen 443 ssl;

    server_name sub.example.com;

    ssl_certificate /etc/nginx/ssl/sub.example.com.crt;
    ssl_certificate_key /etc/nginx/ssl/sub.example.com.key;

    root /var/www/sub.example.com;

    if ($scheme = http) {
        return 301 https://$server_name$request_uri;
    }

    # other configuration for site here

}

When you request https://sub.example.com, it matches the configuration for the second site on HTTP and HTTPS because both HTTP and HTTPS listeners are configured for that server block. If you request https://foo.example.com however, it will fall back to the server with the default_server block for the 443 listener, which serves example.com and not the subdomain.

Essentially, you need to have a custom configuration that serves a certbot certificate for your subdomain on port 443 in order to work. Unfortunately, you cannot use the certbot nginx installer to do this, and will need to configure certbot to use standalone/webroot mode for your certificates and then configure NGINX yourself by hand for the proper paths to SSL certificates (and the .well-known handshakes that go on as well).

Certbot config on how to use standalone / webroot mode is here: https://certbot.eff.org/docs/using.html#webroot

You will need to utilize this method to configure two separate SSL docroots/domains per your nginx configuration and then configure your NGINX ssl_certificate paths to point at the Lets Encrypt paths on-disk. (This process is too long to fit into a single answer, but if you wish I can create a chat room to walk you through the process)

1
  • wow, thank you very much @Thomas Ward for your offer to set up a chat room. I would appreciate that. If you don't mind, I will show you the nginx configurations I have and take the opportunity to also learn a bit of good practices. I have different subdomain sites, each listening to its own port (python flask), and need to route each port on the nginx side properly. So far I managed, I will appreciate to listen to some suggestions to improve handling operations.
    – user305883
    Mar 31, 2020 at 19:28

You must log in to answer this question.

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