Opened 3 years ago

Closed 3 years ago

Last modified 3 years ago

#2330 closed defect (invalid)

nginx does not choose the right certificate (with "IP" server block)

Reported by: kailifeforge@… Owned by:
Priority: minor Milestone:
Component: nginx-core Version:
Keywords: Cc:
uname -a: Linux a-test-server 3.10.0-1160.59.1.el7.x86_64 #1 SMP Wed Feb 23 16:47:03 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
nginx -V: nginx version: nginx/1.21.6
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC)
built with OpenSSL 1.0.2k-fips 26 Jan 2017
TLS SNI support enabled
configure arguments: --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -fPIC' --with-ld-opt='-Wl,-z,relro -Wl,-z,now -pie'

Description (last modified by kailifeforge@…)

I am bashed by a strange problem that nginx seems always choose the certificate in the "default_server" block when I connect to server with IP.

The config file to reproduce this problem is attached as "9443ssl.conf".
I test with the following commands:

curl -k -vvv https://127.0.0.1:9443
curl -k -vvv https://192.168.1.77:9443
curl -k -vvv https://example.com:9443

The results of each command are also attached.

Except the command to "example.com", the other 2 commands both returns with the certificate in "default_server" block. (The corresponding certificates of the 2 IPs and example.com are all from Let's Encrypt)

p.s.1 192.168.1.77 is the LAN IP of my test machine.
p.s.2 I register "example.com" as 127.0.0.1 in /etc/hosts
p.s.3 some fields in result file are marked.

Attachments (4)

9443ssl.conf (4.6 KB ) - added by kailifeforge@… 3 years ago.
configuration file to reproduce this problem
result.127.0.0.1-9443 (2.4 KB ) - added by kailifeforge@… 3 years ago.
result log for 127.0.0.1:9443
result.192.168.1.77-9443 (2.4 KB ) - added by kailifeforge@… 3 years ago.
result log for 192.168.1.77:9443
result.example.com-9443 (2.3 KB ) - added by kailifeforge@… 3 years ago.
result log for example.com:9443

Download all attachments as: .zip

Change History (7)

by kailifeforge@…, 3 years ago

Attachment: 9443ssl.conf added

configuration file to reproduce this problem

by kailifeforge@…, 3 years ago

Attachment: result.127.0.0.1-9443 added

result log for 127.0.0.1:9443

by kailifeforge@…, 3 years ago

Attachment: result.192.168.1.77-9443 added

result log for 192.168.1.77:9443

by kailifeforge@…, 3 years ago

Attachment: result.example.com-9443 added

result log for example.com:9443

comment:1 by kailifeforge@…, 3 years ago

Description: modified (diff)

in reply to:  description comment:2 by Maxim Dounin, 3 years ago

Resolution: invalid
Status: newclosed

I am bashed by a strange problem that nginx seems always choose the certificate in the "default_server" block when I connect to server with IP.

The TLS SNI extension is designed to distinguish multiple name-based virtual hosts running on the same IP/port. As such, it only makes it possible to use names to distinguish between multiple certificates, but not addresses. Further, the specification explicitly says:

Literal IPv4 and IPv6 addresses are not permitted in "HostName".

That is, any connection to an IP address will not provide a server name during the TLS handshake, so the certificate from the default server will be used. That's exactly what you observe in your tests and exactly what is expected to happen in your configuration.

If you want to provide different certificates for different IP addresses, consider using server blocks with listen directive configured for particular IP addresses, see here.

comment:3 by kailifeforge@…, 3 years ago

Oops, this is embarrassing...
Thank you for correcting my mis-understanding.

Note: See TracTickets for help on using tickets.