1

I've been testing my various websites security at Qualsys. All my sites run off of one nginx host. The sites work fine and get an A+ on the Qualsys tests. The only issue that I really want to fix is the SNI setup. I've done a fair bit of researching on this so I understand how SNI works and the fact that you need to name your server blocks correctly to force SNI to work. All of my server blocks are named correctly and I've set up a default server block in sites-enabled/default that I thought would take care of forcing SNI. However, this doesn't appear to be the case. I'm almost certain that the issue is tied to the way I'm using my nginx server as a proxy for the various resources behind it but I'm struggling to pinpoint the issue. My conf files are as follows:

nginx.conf

user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;

events {
worker_connections 768;
# multi_accept on;
}

http {

##
# Basic Settings
##

sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
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.3;
ssl_dhparam /etc/nginx/dhparam.pem;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:50m;
ssl_session_timeout 5m;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

##
# Logging Settings
##

access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
log_format combined_ssl '$remote_addr - $remote_user [$time_local] '
                    '$ssl_protocol/$ssl_cipher '
                    '"$request" $status $http_x_forwarded_for $body_bytes_sent '
                    '"$http_referer" "$http_user_agent"';

##
# Gzip Settings
##

gzip on;
gzip_disable "msie6";
gzip_vary on;
gzip_comp_level 6;
gzip_min_length 1100;
gzip_buffers 16 8k;
gzip_proxied any;
gzip_types
text/plain
text/css
text/js
text/xml
text/javascript
application/javascript
application/x-javascript
application/json
application/xml
application/rss+xml
image/svg+xml;

##
# Virtual Host Configs
##

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

sites-enabled/default

# Default server configuration
server {
listen 80 default_server;
server_name _;
return 444;
}

server {
listen 443 ssl http2 default_server;
server_name _;

ssl_certificate /etc/letsencrypt/live/myserver.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/myserver.com/privkey.pem;
return 444;
}

Example site config

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

server {
listen 443 ssl http2;
server_name sub1.mydomain.com;
client_max_body_size 0;
underscores_in_headers on;
auth_basic "$site_authentication";
auth_basic_user_file /etc/nginx/.htpasswd;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
location / {
proxy_headers_hash_max_size 512;
proxy_headers_hash_bucket_size 64;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
add_header Front-End-Https on;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
proxy_pass http://192.168.1.22:6475;
proxy_read_timeout 90;
}

ssl_stapling on;
ssl_stapling_verify on;
access_log /var/log/nginx/sub1.mydomain.com.access.log;
error_log /var/log/nginx/sub1.mydomain.com.error.log;

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

The issue is that as SNI isn't working, it's exposing the names of my other hosts running on the same box. This is why I ended up temporarily adding a signed root cert and putting it in the default server block for 443. This way, NGINX returns a cert that it doesn't just alphabetically pick from it's know certs.

So can anyone tell me which piece of the puzzle I'm missing please? Spent almost all day on this before admitting defeat so I'd like to finally get a solution!

Thanks for any help you can offer.

EDIT* Unfortunately that doesn't help. This is what my http block now looks like:

server {
listen 80; server_name myserver.mydomain.com;
return 301 https://$server_name$request_uri;
ssl_certificate /etc/letsencrypt/live/myserver.mydomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/myserver.mydomain.com/privkey.pem;
}

The result is the same, the wrong cert is still issued on testing.

Callahan
  • 11
  • 2
  • Place the certificate you want as the default in the `http` block. This will be inherited by any `server` block that does not override it, so can be removed from your `default_server` block. – Richard Smith May 03 '20 at 07:09
  • You should edit your question rather than trying to format a large comment – Richard Smith May 03 '20 at 19:05

0 Answers0