Учитывая, что у меня есть 2 поддомена, настроенных в DNS (так что пинг оба ответа для обоих с IP-адресом моего сервера), и для этих поддоменов у меня есть 2 разных сертификата TLS.
Я настроил nginx так:
# If we receive X-Forwarded-Proto, pass it through; otherwise, pass along the
# scheme used to connect to this server
map $http_x_forwarded_proto $proxy_x_forwarded_proto {
default $http_x_forwarded_proto;
'' $scheme;
}
# If we receive Upgrade, set Connection to "upgrade"; otherwise, delete any
# Connection header that may have been passed to this server
map $http_upgrade $proxy_connection {
default upgrade;
'' '';
}
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
access_log /var/log/nginx.log;
error_log /var/log/nginx_errors.log;
# HTTP 1.1 support
proxy_http_version 1.1;
proxy_buffering off;
proxy_set_header Host $http_host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $proxy_connection;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto;
server {
listen 80 default_server;
server_name _; # This is just an invalid value which will never trigger on a real hostname.
return 503;
server_tokens off; # Hide the nginx version
}
upstream sub1.domain.tld {
server 172.17.0.27:5000;
}
server {
server_name sub1.domain.tld;
server_tokens off; # Hide the nginx version
listen 443 ssl;
ssl_certificate /etc/nginx/ssl/sub1.domain.tld.crt;
ssl_certificate_key /etc/nginx/ssl/sub1.domain.tld.key;
location / {
auth_basic "Restricted";
auth_basic_user_file /etc/nginx/htpasswd/sub1.htpasswd;
proxy_pass http://sub1.domain.tld;
}
}
На этом этапе, если я перейду к https://sub1.domain.tld
все работает нормально. Теперь, если я попытаюсь получить доступ https://sub2.domain.tld
который еще не настроен и поэтому не должен отвечать, он принимает соединение и показывает мне проблему с сертификатом, поскольку он не соответствует имени сервера, поэтому кажется, что с этой конфигурацией Nginx отправляет сертификат для всех запросов на 443 порт.
Как мне изменить мою конфигурацию, чтобы доступ https://sub2.domain.tld
сбой (например, с ошибкой 503), пока я не настрою его, добавив новый server
инструкция?
Если вы слушаете TCP-порт 443 на определенном IP-адресе, он будет принимать новые TCP-соединения на этом порте, даже если у вас настроен SSL только для некоторых доменов, разрешающих этот IP-адрес. И как только TCP-соединение будет установлено, оно выполнит квитирование SSL и выберет наиболее подходящий сертификат, то есть либо соответствующий сертификат, если используется SNI (т.е. клиент отправляет ожидаемое имя хоста в подтверждении SSL), либо просто другой сертификат, если он не может определить запрошенное имя хоста или если для этого имени не настроен сертификат.
Это означает, что вам либо нужно иметь сертификаты для всех доменов, доступных на этом IP-адресе, либо принять, что доступ к доменам без надлежащих сертификатов вызовет такие ошибки, как недействительные сертификаты. Это не относится к nginx, но связано с тем, что SSL - это уровень поверх TCP, и информация о запрошенном хосте передается только в установленном TCP-соединении.
Вы можете добавить еще один серверный блок следующим образом:
server {
listen 443 ssl default_server;
server_name _;
ssl_certificate /etc/nginx/ssl/default.crt;
ssl_certificate_key /etc/nginx/ssl/default.key;
return 503;
}
Для сертификата по умолчанию вы можете сделать самозаверяющий сертификат. Это вызовет ошибку неверного сертификата на клиенте, как упоминал Штеффен. Если пользователь примет сертификат, он получит код состояния 503.