kael
kael

Reputation: 6735

nginx ssl_certificate directive doesn't work within server block, browser shows ERR_CONNECTION_CLOSED or ERR_CONNECTION_RESET

I'm trying to serve multiple TLS-secured domains out of a single VPS with Nginx v1.8.0, but for some reason it's just not taking the certificate configuration in the server block. When I put the ssl_certificate and ssl_certificate_key directives in the http block, it works fine. But when I try to put them into the server block instead, there are no errors at startup, nothing in the logs, but chrome gives me an ERR_CONNECTION_CLOSED message. This has to be easier than it seems....

Here's the setup that works:

nginx -V output:

nginx version: nginx/1.8.0
built by gcc 4.8.4 (Ubuntu 4.8.4-2ubuntu1~14.04) 
built with OpenSSL 1.0.1f 6 Jan 2014
TLS SNI support enabled

My main nginx.conf:

user  http;
worker_processes  3;
pid /var/run/nginx.pid;

error_log  /var/log/nginx_error.log error;

events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  text/plain;
    sendfile        on;
    keepalive_timeout  65;
    index index.php index.html;

    log_format  main  '$remote_addr - $remote_user [$time_local], "$scheme://$host$request_uri", '
                    'file: "$request_filename", http: $status, sent: $body_bytes_sent, ref: "$http_referer", '
                    '"$http_user_agent", "$http_x_forwarded_for"';

    access_log /var/log/nginx_access.log main;

    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

    server {
      listen 80;
      server_name "";
      return 410;
    }

    ssl_certificate /etc/letsencrypt/live/site1.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/site1.com/privkey.pem;
    include vhosts/*.conf;
}

My vhosts directory listing:

site1.conf
site2.conf

And finally, my site1.conf file (site2.conf is essentially the same):

# Server block that redirects www.site1.com requests to site1.com
server {
  listen 443;
  server_name www.site1.com;
  return 301 https://site1.com$request_uri;
}

# Server block that serves site1.com;
server {
  listen 443 ssl;
  server_name  site1.com;
  root /srv/www/site1/public_html;
  index index.php index.html index.htm;

  error_log /var/log/nginx_err_site1.log error;
  access_log /var/log/nginx_acc_site1.log main;

  include global_restrictions.conf;

  location / {
    try_files $uri /index.php?q=$uri&$args;
  }

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

As you can see, the ssl... directives are in the main configuration file http block. That configuration works fine. If I remove them from that location, however, and put them into the server block of the site1.conf vhost file, as indicated below, I get the ERR_CONNECTION_CLOSED error.

# Server block that redirects www.site1.com requests to site1.com
server {
  listen 443;
  server_name www.site1.com;
  return 301 https://site1.com$request_uri;
}

# Server block that serves site1.com;
server {
  listen 443 ssl;
  server_name  site1.com;
  root /srv/www/site1/public_html;
  index index.php index.html index.htm;

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

  error_log /var/log/nginx_err_site1.log error;
  access_log /var/log/nginx_acc_site1.log main;

  include global_restrictions.conf;

  location / {
    try_files $uri /index.php?q=$uri&$args;
  }

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

I just can't figure it out!

Thanks for any help you can offer.

Upvotes: 1

Views: 15968

Answers (1)

kael
kael

Reputation: 6735

Just got back to this after more than a month (ok, so my launch is a little delayed, whatever! ;) ).

Indeed, the answer was as easy as I supposed it had to be.

I had viewed those little "www." redirect blocks as simple bounces, and for some reason didn't feel I had to include information about the certificates in those blocks. However, because of the way secure connections work, the server has to fully establish a secured connection before issuing a response (i.e. redirect instruction), so because I wasn't including the certificate information in those little redirect blocks, it was giving me errors (and frustratingly, it wasn't telling me what those errors were).

So in the end, the solution was simply to add the valid ssl_certificate and ssl_certificate_key directives in each server block that listened on port 443. All works well now!

Just to fully illustrate the point, this is my updated and WORKING site1.conf (and site2.conf, which is virtually identical):

# Server block that redirects www.site1.com requests to site1.com
server {
  listen 443 ssl;
  server_name www.site1.com;
  ssl_certificate /etc/letsencrypt/live/site1.com/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/site1.com/privkey.pem;
  return 301 https://site1.com$request_uri;
}

# Server block that serves site1.com requests
server {
  listen 443 ssl;
  server_name  site1.com www.site1.com;
  root /srv/www/site1/public_html;
  ssl_certificate /etc/letsencrypt/live/site1.com/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/site1.com/privkey.pem;
  index index.php index.html index.htm;

  error_log /var/log/nginx_err_site1.log error;
  access_log /var/log/nginx_acc_site1.log main;

  include global_restrictions.conf;

  location / {
    try_files $uri /index.php?q=$uri&$args;
  }

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

And my nginx.conf file now no longer has the ssl_certificate lines in it.

Upvotes: 4

Related Questions