Multiple certificates vs. 1

Hi,

I first generated a certificate with:
./letsencrypt-auto certonly -a webroot --webroot-path=/var/www/xxx -d test.domain.com

I configured Nginx and everything works like a charm.

Then I (stupidly) generated a new certificate with:
./letsencrypt-auto certonly -a webroot --webroot-path=/var/www/xxx -d domain.com -d www.domain.com

I thought it will be smart to have a separation between production and test environment.

So I configured everything for the second certificate.

And now, domain.com & www.domain.com are working with HTTPS but test.domain.com is not working anymore.

/etc/nginx/snippets/ssl-test.domain.com.conf
ssl_certificate /etc/letsencrypt/live/test.domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/test.domain.com/privkey.pem;

And

/etc/nginx/snippets/ssl-domain.com.conf
ssl_certificate /etc/letsencrypt/live/domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/domain.com/privkey.pem;

Then both config share:

/etc/nginx/snippets/ssl-params.conf

I followed How To Secure Nginx with Let's Encrypt on Ubuntu 16.04 | DigitalOcean

I would be very happy to understand WHY the first stopped to work when the second started to work.

  • Did I do a mistake by creating two certificates?
  • I was thinking of revoking one and updating the other by simply adding a domain but I feel stuck...

Thank you for your light and help

I know that to you it's probably very obvious that it's "not working anymore" but for anybody trying to help you we need to understand what this means precisely. For example - is there an error displayed if you try to visit the test.domain.com website with a web browser (what is the error?), is there anything interesting in the error logs for that site ?

1 Like

@tialaramex thank you! You are totally right!
When I open Chrome it output HTTPS in red overlined and outputs the following:

Your connection is not private

Attackers might be trying to steal your information from test.domain.com (for example, passwords, messages, or credit cards). NET::ERR_CERT_COMMON_NAME_INVALID

OK. This error says that test.domain.com is presenting a certificate for some other name. Given the other information it seems likely it’s presenting the new certificate, which is for domain.com and www.domain.com but of course not for test.domain.com

Chances are this is a mistake in your nginx configuration, either the new snippet is mistakenly included instead of the old one for the test.domain.com site, or the site configuration overall is wrong and only serving the www.domain.com site not the test.domain.com site to all visitors.

You might be able to get more detailed help by posting all the nginx configuration for people to examine, either here or on other relevant forums since Let’s Encrypt isn’t key to the problem. But I suggest first trying to diagnose it yourself, especially re-reading the configuration slowly to make sure it doesn’t have any obvious goofs in it.

1 Like

@tialaramex

Thank you so much for the help. So, I cleared my browser cache and now the message is a little bit more precise..

Your connection is not private

Attackers might be trying to steal your information from test.domain.com (for example, passwords, messages, or credit cards). NET::ERR_CERT_COMMON_NAME_INVALID

This server could not prove that it is test.domain.com; its security certificate is from domain.com. This may be caused by a misconfiguration or an attacker intercepting your connection.

Proceed to test.domain.com (unsafe)

And sometimes, it says:

test.domain.com normally uses encryption to protect your information. When Google Chrome tried to connect to test.domain.com this time, the website sent back unusual and incorrect credentials. This may happen when an attacker is trying to pretend to be test.domain.com, or a Wi-Fi sign-in screen has interrupted the connection. Your information is still secure because Google Chrome stopped the connection before any data was exchanged.

You cannot visit test.domain.com right now **because the website uses HSTS**. Network errors and attacks are usually temporary, so this page will probably work later.

its security certificate is from domain.com.

It means test.domain.com is now trying to use the certificate of domain.com.
It is weird because at the begining test.domain.com was working perfectly with it's generated certificate. Then I generated the domain.com + www.domain.com certificate and update NGINX conf. It stopped working at this time.

So as you suggested, it is a NGINX conf issue.
Let me share my conf.

// /etc/nginx/

- conf.d/
(empty)

- snippets/

fastcgi-php.conf

fastcgi_split_path_info ^(.+\.php)(/.+)$;
try_files $fastcgi_script_name =404;
set $path_info $fastcgi_path_info;
fastcgi_param PATH_INFO $path_info;
fastcgi_index index.php;
include fastcgi.conf;


ssl-params.conf

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
ssl_ecdh_curve secp384r1;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;


ssl-domain.com.conf

ssl_certificate /etc/letsencrypt/live/domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/domain.com/privkey.pem;


ssl-test.domain.com.conf

ssl_certificate /etc/letsencrypt/live/test.domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/test.domain.com/privkey.pem;


- nginx.conf

user www-data;
worker_processes auto;
pid /run/nginx.pid;

events {
worker_connections 768;
}

http {
server_tokens off;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
client_max_body_size 5M;
//# server_tokens off;

//# server_names_hash_bucket_size 64;
//# server_name_in_redirect off;

include /etc/nginx/mime.types;
default_type application/octet-stream;

//##
//# SSL Settings
//##

ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
ssl_prefer_server_ciphers on;

//##
//# Logging Settings
//##

access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;

//##
//# Gzip Settings
//##
gzip on;
gzip_disable "msie6";

//# gzip_vary on;
//# gzip_proxied any;
//# gzip_comp_level 6;
//# gzip_buffers 16 8k;
//# gzip_http_version 1.1;
//# gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
  
  //##
  //# Virtual Host Configs
  //##

include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;


- sites-available/

test.domain.com

server {
listen 80;
server_name test.domain.com;
return 301 https://test.domain.com$request_uri;
}

server {
//# SSL configuration

listen 443 ssl http2;
include snippets/ssl-test.domain.com.conf;
include snippets/ssl-params.conf;

root /var/www/test.domain.com/latest/public;
index index.php;

location / {
try_files $uri $uri/ /index.php?$query_string;

auth_basic "Restricted Content";
auth_basic_user_file /etc/nginx/.htpasswd;
}

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

location ~ /\.ht {
deny all;
}

location ~ /.well-known {
allow all;
}
}


domain.com

server {
listen 80;
server_name domain.com www.domain.com;
return 301 https://domain.com$request_uri;
}

server {

listen 443 ssl http2;
server_name domain.com;
include snippets/ssl-domain.com.conf;
include snippets/ssl-params.conf;

root /var/www/domain.com/latest/public;

index index.php;

location / {
try_files $uri $uri/ /index.php?$query_string;
}

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

location ~ /\.ht {
deny all;
}

location ~ /.well-known {
allow all;
}
}

server {
listen 443 ssl http2;
server_name www.domain.com;
return 301 https://domain.com$request_uri;
}

So this is pretty much what I have.
Thank you for the help.
Most important to me is to understand!

:slight_smile:

5 minutes after posting all the details I found the issue…
If you notice, for sites-available/ => test.domain.com
The second server block (for SSL) misses a server_name directive.

So I added that directive test.domain.com and now it works (like a charm).

I would be very happy if someone can give me some light on what happened so I understand.

Thank you again @tialaramex

You had the same problem as this thread. When a request comes in for a name that doesn't match any server_name directives a block is chosen by default. At first this would have been test.domain.com as it was the only one with SSL enabled, then when domain.com was created it became the default.

1 Like

Thank you for sharing the knowledge!

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