Certbot created a single nginx server block for two virtual hosts

Please fill out the fields below so we can help you better. Note: you must provide your domain name to get help. Domain names for issued certificates are all made public in Certificate Transparency logs (e.g. https://crt.sh/?q=example.com), so withholding your domain name here does not increase secrecy, but only makes it harder for us to provide help.

My domain is:
swanriver.dev AND swanriversystems.com

I ran this command: sudo certbot --nginx

It produced this output:

it worked great, no problems. I was prompted with a query asking if I had multiple domains, so provided both names: blog.swanriver.dev and www.swanriversystems.com

A single server block was created in the nginx.conf for both hosts.

I was hoping to manage these separately, giving each a different document root.

I tried to split these out, but nginx refused to bind them both to the same port. I realize this is partly an nginx config question, but since certbot wrote out the configuration file, it seems like it’s also a certbot question.

My web server is (include version): nginx/1.16.1

The operating system my web server runs on is (include version): CentOS 7

My hosting provider, if applicable, is: Kamatera

I can login to a root shell on my machine (yes or no, or I don’t know): yes

I’m using a control panel to manage my site (no, or provide the name and version of the control panel): no

The version of my client is (e.g. output of certbot --version or certbot-auto --version if you’re using Certbot): 0.39.0

1 Like

This seems like you may be issuing the wrong statements in that block.
[one or more statements that can only be issued once - and likely expected outside that block]

Please show the combined TLS block and we should be able to “split” it for you.

EDIT: LISTEN statements are allowed multiple times.

1 Like
    server {
	server_name blog.swanriver.dev www.swanriversystems.com; # managed by Certbot
    root         /usr/share/nginx/html;
    index        index.php index.html index.htm

    # Load configuration files for the default server block.
    include /etc/nginx/default.d/*.conf;

    location / {
        try_files $uri $uri/ =404;
    }

    error_page 404 /404.html;
        location = /40x.html {
    }

    error_page 500 502 503 504 /50x.html;
        location = /50x.html {
    }

    location ~ \.php$ {
       try_files $uri =404;
       fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
       fastcgi_index index.php;
       fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
       include fastcgi_params;
    }

listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/blog.swanriver.dev/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/blog.swanriver.dev/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

}

So far, I have this:

# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
#[moved out - server blocks/entire configs should NOT be loaded within another server block]

server { #1
    server_name blog.swanriver.dev; # managed by Certbot
    root         /usr/share/nginx/html;
    index        index.php index.html index.htm

    location / {
        try_files $uri $uri/ =404;
    }#location

    error_page 404 /404.html;
    location = /40x.html {
    }#location

    error_page 500 502 503 504 /50x.html;
    location = /50x.html {
    }#location

    location ~ \.php$ {
       try_files $uri =404;
       fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
       fastcgi_index index.php;
       fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
       include fastcgi_params;
    }#location

    ssl_certificate /etc/letsencrypt/live/blog.swanriver.dev/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/blog.swanriver.dev/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
}#server #1

server { #2
    server_name www.swanriversystems.com; # managed by Certbot
    root         /usr/share/nginx/html;
    index        index.php index.html index.htm

    location / {
        try_files $uri $uri/ =404;
    }#location

    error_page 404 /404.html;
    location = /40x.html {
    }#location

    error_page 500 502 503 504 /50x.html;
    location = /50x.html {
    }#location

    location ~ \.php$ {
       try_files $uri =404;
       fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
       fastcgi_index index.php;
       fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
       include fastcgi_params;
    }#location

    ssl_certificate /etc/letsencrypt/live/blog.swanriver.dev/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/blog.swanriver.dev/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
}#server #2

I’m pretty sure the problem was caused by including other complete configs within that server block.
If anything exists at /etc/nginx/default.d/*.conf it should be treated separately (sequentially).
Not nested like:

server {#start server block 1
   aaa

   include other.configs;
   #[which inserts immediately - right here:]

   server (#start server block 2
       xxx
   }#end server block 2

   server {#start server block 3
       zzz
   }#end server block 3
   #[included configs end]

   #[then we return to original server block 1 
   bbb
}#end server block 1

I hope that makes sense to you.
You can always check your config with:
nginx -t
and review the entire config with:
nginx -T

Thanks. Still not working though. No errors are reporting using “nginx -t”, and no errors in the access or error logs for the server. With the configuration in place however, the server refuses to connect: for either virtual host name.

server { # default server
    listen       80 default_server;
    listen       [::]:80 default_server;
    server_name  _;

    # Load configuration files for the default server block.
    include /etc/nginx/default.d/*.conf;

    if ($host = www.swanriversystems.com) {
        return 301 https://$host$request_uri;
    } # host

    if ($host = blog.swanriver.dev) {
        return 301 https://$host$request_uri;
    } # host

    return 404; 

} #  default server

server {  # server 1 
    server_name  blog.swanriver.dev; # managed by Certbot
    root         /usr/share/nginx/html;
    index        index.php index.html

    listen 443 ssl; # managed by Certbot
#   listen [::]:443 ssl ipv6only=on; # managed by Certbot

    location / {
        try_files $uri $uri/ =404;
    } # location

    error_page 404 /404.html;
        location = /40x.html {
    } # location

    error_page 500 502 503 504 /50x.html;
        location = /50x.html {
    } # location

    location ~ \.php$ {
       try_files $uri =404;
       fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
       fastcgi_index index.php;
       fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
       include fastcgi_params;
    } # location

    ssl_certificate /etc/letsencrypt/live/blog.swanriver.dev/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/blog.swanriver.dev/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
} # server 1

server { # server 2
    server_name  www.swanriversystems.com; # managed by Certbot
    root         /usr/share/nginx/html2;
    index        index.php index.html

    listen 443 ssl; # managed by Certbot
#   listen [::]:443 ssl ipv6only=on; # managed by Certbot

    location / {
        try_files $uri $uri/ =404;
    } # location

    error_page 404 /404.html;
        location = /40x.html {
    } # location

    error_page 500 502 503 504 /50x.html;
        location = /50x.html {
    } # location

    ssl_certificate /etc/letsencrypt/live/blog.swanriver.dev/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/blog.swanriver.dev/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
} # server 2

That looks a bit complicated…:
I would update the first SERVER section to simply redirect all HTTP connections to HTTPS (easy maintenance) and place the INCLUDE statement OUTSIDE any server block section:
[that would include entire server blocks inside that server block]
[in some cases ORDER may matter, so you might want to do the INCLUDE last]

# Load other configuration files
include /etc/nginx/default.d/*.conf;

server { # default server
 listen 80 default_server;
 listen [::]:80 default_server;
 server_name _; # DEFAULTs to ALL names
 #REDIRECT ALL HTTP to HTTPS
 return 301 https://$host$request_uri;
} # default server

Thanks again. I cut my teeth for managing virtual servers on Apache, way back in the day when you used to have to cut an expensive check to get support for SSL. A lot has changed since then.

In hindsight, I think my mistake was running certbot against what was essentially, an out-of-the-box nginx config file. I had tweaked it just enough that it supported php and would serve up web content.

Then I executed certbot, for both domains simultaneously. In all fairness, the certbot-written config works great. It’s just I was really wanting separate document roots for each. So the same certificate and key supports both domains.

I can’t help by wonder if should just somehow start over with certbot from the beginning. Not sure how much more of a mess I would make by doing so.

Anyway, thanks again, at this point, I’m guessing I should probably move this to an nginx-support forum.

2 Likes

Frustrated. I thought for sure that having certbot build new keys, one for each server would resolve this. That “include” by the way, doesn’t do anything: that directory is empty. So it’s been commented-out.

The real puzzler in my view, is that I’m not getting an error from nginx. I’m getting a “connection refused” response. Using Chrome: it’s a: ERR_CONNECTION_REFUSED

So that really has me scratching my head.

1 Like

Both return “Welcome to CentOS
Are you sure those are the correct roots?

1 Like

Got it working :slight_smile: Went back to the original certbot-authored config file and simply broke out the SSL server into two blocks, server1 and server2, with separate letsencrypt key files for each server. Also had to use the ipv6only option once.

Works great now! It’s a little more complicated, my attempts to simplify likely made it worse

2 Likes

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