Nginx 및 https - IP 주소를 server_name으로 지정하면 올바른 웹사이트가 제공되지만 잘못된 인증서가 제공됩니다.

Nginx 및 https - IP 주소를 server_name으로 지정하면 올바른 웹사이트가 제공되지만 잘못된 인증서가 제공됩니다.

이 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가 분명히 허용하지 않는 방식과 관련이 있는 것 같습니다.a "HostName"으로서의 리터럴 IPv4 및 IPv6 주소. 하지만 정말 그런가요?

기본 서버 블록이 있습니다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 주소를 server_name에서 제거하면luci-https.conf다음 위치에 server_name으로 추가하세요.mysite.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인증서가 아닙니다.mysite.lan.crt~에서mysite.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가 server_name으로 지정되어 있는지 여부luci-https.conf또는mysite.lan.conf.

따라서 SNI는 IP 주소인 "호스트 이름"과 일치하는 것으로 보이지만 기본 서버 블록에서 인증서를 가져옵니다. 왜 그런 겁니까?

답변1

... SNI는 리터럴 IPv4 및 IPv6 주소를 "HostName"으로 허용하지 않는 것 같습니다. 하지만 정말 그런가요?

SNI의 기본 아이디어는 동일한 IP 주소의 여러 도메인을 구별하는 것입니다. IP 주소와 함께 SNI를 사용하는 것은 실제로 의미가 없습니다. 따라서 실제 호스트 이름으로도 제한됩니다. 인용하자면RFC 6066:

"HostName"에는 정규화된DNS 호스트 이름클라이언트가 이해하는 대로 서버의 정보입니다. ... "HostName"에서는 리터럴 IPv4 및 IPv6 주소가 허용되지 않습니다.

    server_name mysite.lan www.mysite.lan fun.mysite.lan 192.168.1.254;

...
따라서 SNI는 IP 주소인 "호스트 이름"과 일치하는 것으로 보이지만 기본 서버 블록에서 인증서를 가져옵니다.

SNI는 실제 호스트 이름에만 사용되므로 TLS 핸드셰이크 내부에는 SNI가 없으므로 기본 HTTPS 구성이 사용됩니다. HTTPS 내부에는 헤더 를 포함하는 HTTP 프로토콜이 있습니다 Host. 헤더는 IP 주소를 지정 하므로 Host(URL이 하기 때문에) 이 특정 가상 호스트와 일치합니다. 따라서 잘못된 인증서, 올바른 콘텐츠입니다.

관련 정보