I want to run this url: https://192.168.1.254 and get a website with the correct content and certificate in the address bar. I am getting the website but I get an invalid certificate error in the address bar because the cert is taken from a different server block: the default server block 000-default.conf.
Can someone explain this behavior to me please?
My client browser is Google Chrome Version 87.0.4280.88 (Official Build) (64-bit)
My Nginx server is:
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
I think the issue is related to how SNI apparently does not allow a Literal IPv4 and IPv6 addresses as a "HostName". But is that really the case?
I have a default server block 000-default.conf like this:
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
}
And another server called luci-http.conf like this:
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;
}
When I put http://192.168.1.254 in the address bar it serves me up the correct webpage.
I also have this https server: 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;
}
When I put https://192.168.1.254 in the address bar it serves me up the correct webpage and the certificate in _lan.crt. As you can see I have the same Cert/Key pair in this and the default server block.
However when I remove that ip address as a server_name from luci-https.conf and add it as a server_name in: mysite.lan.conf I don't see the same behavior.
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;
}
Now when I put https://192.168.1.254 in the address bar it serves me up the correct webpage but again the certificate in _lan.crt not the certificate: mysite.lan.crt from mysite.lan.conf as expected.
When I put..
ssl_certificate '/etc/nginx/conf.d/mysite.lan.crt';
ssl_certificate_key '/etc/nginx/conf.d/mysite.lan.key';
in the default server block 000-default.conf then I get that certificate instead when I put https://192.168.1.254 in the browser address bar whether 192.168.1.254 is specified as a server_name in luci-https.conf or mysite.lan.conf.
So it seems that SNI will match on a "hostname" that is an ip address but it takes the certificate from the default server block. Why is that?