
Я хочу запустить этот URL:https://192.168.1.254и получить веб-сайт с правильным содержанием и сертификатом в адресной строке. Я получаю веб-сайт, но получаю ошибку недействительного сертификата в адресной строке, потому что сертификат взят из другого блока сервера: блок сервера по умолчанию000-default.conf.
Может ли кто-нибудь объяснить мне такое поведение?
Мой клиентский браузер — Google Chrome версии 87.0.4280.88 (официальная сборка) (64-бит)
Мой сервер Nginx:
root@OpenWrt:/etc/nginx/conf.d# nginx -V
nginx version: nginx/1.19.4 (x86_64-pc-linux-gnu)
built with OpenSSL 1.1.1h 22 Sep 2020
TLS SNI support enabled
Я думаю, что проблема связана с тем, что SNI, по-видимому, не позволяетБуквальные адреса IPv4 и IPv6 как «HostName». Но так ли это на самом деле?
У меня есть блок сервера по умолчанию000-default.confтак:
server {
server_name _;
listen 80 default_server;
listen 443 ssl default_server;
## To also support IPv6, uncomment this block
# listen [::]:80 default_server;
# listen [::]:443 ssl default_server;
ssl_certificate '/etc/nginx/conf.d/_lan.crt';
ssl_certificate_key '/etc/nginx/conf.d/_lan.key';
return 404; # or whatever
}
И еще один сервер под названием luci-http.conf, вот такой:
server {
listen 80;
listen [::]:80;
server_name openwrt.lan 192.168.1.254;
# access_log /proc/self/fd/1 openwrt; # use logd (init forwards stdout).
include conf.d/*.locations;
}
Когда я ставлюhttp://192.168.1.254в адресной строке он открывает мне нужную веб-страницу.
У меня также есть этот https-сервер: luci-https.conf
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name openwrt.lan 192.168.1.254;
#include '/var/lib/nginx/lan_ssl.listen.default';
ssl_certificate '/etc/nginx/conf.d/_lan.crt';
ssl_certificate_key '/etc/nginx/conf.d/_lan.key';
ssl_session_cache 'shared:SSL:32k';
ssl_session_timeout '64m';
# access_log /proc/self/fd/1 openwrt; # use logd (init forwards stdout).
include conf.d/*.locations;
}
Когда я ставлюhttps://192.168.1.254в адресной строке он выдает мне правильную веб-страницу и сертификат в_lan.crt. Как вы видите, у меня в этом блоке и в блоке сервера по умолчанию одна и та же пара сертификат/ключ.
Однако когда я удаляю этот IP-адрес как имя_сервера изluci-https.confи добавьте его как имя_сервера в:мойсайт.lan.confЯ не вижу такого поведения.
server {
listen 443 ssl;
listen [::]:443 ssl;
#listen 192.168.1.254 ssl;
#include '/var/lib/nginx/lan_ssl.listen';
server_name mysite.lan www.mysite.lan fun.mysite.lan 192.168.1.254;
root /www/mysite;
index index.html index.htm index.nginx-debian.html;
ssl_certificate '/etc/nginx/conf.d/mysite.lan.crt';
ssl_certificate_key '/etc/nginx/conf.d/mysite.lan.key';
ssl_session_cache 'shared:SSL:32k';
ssl_session_timeout '64m';
location / {
try_files $uri $uri/ =404;
}
access_log /var/log/nginx/mysite.lan.access.log;
error_log /var/log/nginx/mysite.lan.error.log;
}
Теперь, когда я ставлюhttps://192.168.1.254в адресной строке он открывает мне правильную веб-страницу, но снова сертификат в_lan.crtне сертификат:мойсайт.lan.crtотмойсайт.lan.confкак и ожидалось.
Когда я ставлю..
ssl_certificate '/etc/nginx/conf.d/mysite.lan.crt';
ssl_certificate_key '/etc/nginx/conf.d/mysite.lan.key';
в блоке сервера по умолчанию000-default.confто я получаю этот сертификат вместо этого, когда я ставлюhttps://192.168.1.254в адресной строке браузера указано ли 192.168.1.254 как имя_сервера вluci-https.confилимойсайт.lan.conf.
Так что, похоже, SNI будет соответствовать "хосту", который является IP-адресом, но он берет сертификат из блока сервера по умолчанию. Почему так?
решение1
... SNI, по-видимому, не допускает использования адресов IPv4 и IPv6 в качестве "HostName". Но так ли это на самом деле?
Идея SNI заключается в различении нескольких доменов на одном IP-адресе. Использование SNI с IP-адресом не имеет смысла. Поэтому оно также ограничено реальными именами хостов. Цитата изRFC6066:
«HostName» содержит полностью определенноеDNS-имя хостасервера, как его понимает клиент. ... Буквальные адреса IPv4 и IPv6 не допускаются в «HostName».
server_name mysite.lan www.mysite.lan fun.mysite.lan 192.168.1.254;
...
Таким образом, похоже, что SNI будет соответствовать «имени хоста», которое является IP-адресом, но он берет сертификат из блока сервера по умолчанию.
Поскольку SNI используется только для реальных имен хостов, внутри рукопожатия TLS не будет SNI, и, таким образом, будет использована конфигурация HTTPS по умолчанию. Внутри HTTPS есть протокол HTTP, который включает заголовок Host
. Поскольку Host
заголовок указывает IP-адрес (потому что URL-адрес указывает), он будет соответствовать этому конкретному виртуальному хосту. Следовательно: неправильный сертификат, правильное содержимое.