0

I´m currently configuring my nginx server and I´ve ran into a problem where I can´t seem to find the problem I did, even after hours of research.
I´m running Debian 9 with PHP 7.2-fpm on NGINX.
So, I have setup following server blocks for different subdomains:

sites-enabled
- www.example.com    #this config covers both www.example.com and example.com
- pfa.example.com    #this config covers pfa.example.com

These are the contents of these files (I removed the default config from sites-enabled, I left a backup of it in sites-availible):
www.example.com

server {
    listen 80;
    listen [::]:80;
    server_name example.com www.example.com;
    return 301 https://www.example.com$request_uri;
}
server {
    listen 443 ssl http2; # managed by Certbot
    listen [::]:443 ssl http2; # managed by Certbot
    server_name www.example.com;

    ssl on;
    ssl_certificate /etc/letsencrypt/live/www.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/www.example.com/privkey.pem;
    ssl_session_timeout 1d;
    ssl_session_cache shared:SSL:50m;
    ssl_session_tickets off;
    ssl_dhparam /etc/letsencrypt/live/www.example.com/dh.pem;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS';
    ssl_prefer_server_ciphers on;
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
    ssl_stapling on;
    ssl_stapling_verify on;
    ssl_trusted_certificate /etc/letsencrypt/live/www.example.com/chain.pem;
    resolver 8.8.8.8;

    root /var/www/www.example.com/html/;
    index index.php index.html index.htm;

    add_header X-Frame-Options "SAMEORIGIN";
    add_header x-xss-protection "1; mode=block" always;
    add_header X-Content-Type-Options "nosniff" always;

    location ~ \.php$ {
            include snippets/fastcgi-php.conf;
            fastcgi_pass unix:/run/php/php7.2-fpm.sock;
    }
}

Calling both example.com and www.example.com works perfectly fine (it redirects to https and shows the content of /var/www/www.example.com/html/).
This is the config of pfa.example.com:

server {
    listen 80 http2;
    listen [::]:80 http2;
    server_name pfa.example.com;
    return 301 https://pfa.example.com$request_uri;
}
server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name pfa.example.com;

    ssl on;
    ssl_certificate /etc/letsencrypt/live/pfa.example.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/pfa.example.com/privkey.pem; # managed by Certbot
    ssl_session_timeout 1d;
    ssl_session_cache shared:SSL:50m;
    ssl_session_tickets off;
    ssl_dhparam /etc/letsencrypt/live/pfa.example.com/dh.pem;

    ssl_protocols TLSv1.2;
    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_prefer_server_ciphers on;

    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

    ssl_stapling on;
    ssl_stapling_verify on;
    ssl_trusted_certificate /etc/letsencrypt/live/pfa.example.com/chain.pem;
    resolver 8.8.8.8;

    root /var/www/html/;
    index index.php index.html index.htm;

    add_header X-Frame-Options "SAMEORIGIN";
    add_header x-xss-protection "1; mode=block" always;
    add_header X-Content-Type-Options "nosniff" always;
    location ~ \.php$ {
            include snippets/fastcgi-php.conf;
            fastcgi_pass unix:/run/php/php7.2-fpm.sock;
    }
}

I´ve configured the dh.pem 2048 bit keys via openssl for both domains.
Calling this page works as intended, too.

Here comes my problem: When calling a random page as abc.example.com, it will use the config of pfa.example.com as a "default" config. I´ve checked the server declarations a million times, I can´t figure out how the server block from pfa.example.com can be mistaken as a catch-all (It even works for sdfsdfjikdsfjsdfhjsd.example.com). This isn´t only annoying for potential visitors, but also for me, since, when calling a page as https://abc.example.com, it will attempt to use the ssl configuration for pfa.example.com, resulting in an error.
nginx -t returns no errors.
Where is the syntax error I´ve overseen?

EDIT: I´ve deleted the default vhost config because it would let 443 traffic pass to pfa.example.com anyways. Since I have a backup of the default config, I can easily add it back. I´d afterwards still need a solution for returning a 404 error on ssl traffic for not-existing subdomains. Any help is appreciated.

  • `pfa` **is** the default server. Nginx always has a default server. If you do not define one explicitly, then the first `server` block with a matching `listen` directive will be used. See [this document](http://nginx.org/en/docs/http/server_names.html#miscellaneous_names) for details. If you do not want that behaviour - define a catch-all `server` block. – Richard Smith Dec 13 '18 at 15:36
  • @RichardSmith as to be seen in my edit, when specifying a default catch-all (port 443) vhost server block, firefox will complain when I don´t enter any certificate AND when I enter a self-signed one. Since I don´t have access to letsencrypts wildcard SSL certificates (my dns provider doesn´t support such an extension) I also don´t know how to setup such a default block, just for returning a 404 error code. – SearchingSolutions Dec 13 '18 at 15:48
  • If you enter `foo.example.com` into a browser, it will attempt to connect to an SSL server with a valid certificate and complain when it cannot. There is nothing you can do about that (other than use a wildcard certificate) or drop the `includeSubDomains` security policy. And if you drop the `includeSubDomains` security policy, `https://foo.example.com` will still cause the browser to complain. – Richard Smith Dec 13 '18 at 15:57
  • @RichardSmith Sad :( I hoped there would be a workaround for this. Seems like only big companies with trusted wildcard self-signed certificates are allowed to do something like what I was dreaming of... thank you anyways :) – SearchingSolutions Dec 13 '18 at 16:55

1 Answers1

1

There's always a default vhost in nginx. It can be explicitely configured using the default option for listen directive. If omitted, nginx will use first declared vhost as it parses it's config as a default one. So looks like pfa.example.com occured first.

You can see the actual order in the final joined config by issuing nginx -T.

drookie
  • 8,051
  • 1
  • 17
  • 27
  • I removed the default vhost config since it would still use pfa.example.com for https (port 443) traffic. Adding another vhost listening to port 443 as a default-server in the default vhost config resulted in even more problems since I can´t specify a wildcard certificate without using a self-signed one (which will not be accepted by any browser). Is there any way I can add a default catch-all ssl vhost config? – SearchingSolutions Dec 13 '18 at 15:43
  • 1
    @SearchingSolutions There is always a default virtual host for port 443 traffic too. – Michael Hampton Dec 13 '18 at 16:06