Lan Ip of OpenWrt not using ssl cert from matched Nginx server block


I installed an OpenWrt snapshot image for Pi 4 and installed nginx instead of uhttpd like this:
opkg install luci-ssl-nginx

I made my own conf file in /etc/nginx/conf.d with a server block that points to a different document root than the OpenWrt LuCI web interface. I also made a new cert/key pair with a trusted CA I also made using openssl and added to my browser so I don't get any ssl errors or warnings.

My OpenWrt lan ip is I added this ip to the server_name field of my new server block. Now https://192168.1.254 brings up the test page from that server block however the page uses the _lan.crt and _lan.key certificates from the default _lan server block. The result is I get an ssl browser error because that cert/key pair always do that in Chrome.

When I copy/replace the _lan.crt and _lan.key certificates with my newly created cert/key pair that do not cause the ssl error then I don't get an ssl browser error anymore. So that's why I know that is somehow loading my test webpage (and not the LuCI web admin page) but is using the cert/key pair from the default server.

Why is this? How can I make a request for (the lan IP of OpenWrt on my Pi 4) use the cert/key pair in my new server block that points to a different doc root?



To make my problem more clear...

I installed OpenWrt with Nginx on a Pi 4 at I made my own server block in Nginx with self signed certs that do not produce any ssl browser error. I included that ip in the server_name list of that server block.

Here is my new server block in /etc/nginx/mysite.lan.conf:

server {
        listen 443;
        listen [::]:443;
        include '/var/lib/nginx/lan_ssl.listen';

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

        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;


Here is the default server block in /etc/nginx/_lan.conf

# default_server for the LAN addresses getting the IPs by:
# ifstatus lan | jsonfilter -e '@["ipv4-address","ipv6-address"].*.address'
server {
        server_name _lan;
        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 try to load a page using a local only domain name, the correct page is served and certificate is used in the browser:

When I try to load a page using the ip address of the OpenWrt. I get my page as expected but the wrong certificate?

Can someone help me understand why the default ssl cert is being used when I type the ip address into the browser?

After some more reading I think my issue is related to the design of the coupling between Nginx and OpenWrt for which there has been some controversy.

  1. Nginx is installed via opkg and part of that process installs a dependant module: nginx-utils.
  2. This hard codes in a default configuration, which cannot currently be modified, that makes Nginx listen on ports 80 and 443 (in case of nginx-ssl) on all IP addresses associated with the LAN adapter.
  3. Seemingly a new design of the Nginx-OpenWrt coupling will allow to restrict what ip addresses the default server listens to so another service that binds on a particular LAN addresses can have precedence.
  4. I suppose in my case this would mean I can have server_name in my own server block config and typing in the browser will make not only my own little page appear but the correct certificate key/pair combination be used also?

If I have any of this wrong please let me know? I still don't know why Nginx used my own server block to load the correct web page but uses the key/cert pair from the default server block.



Unless I'm misunderstanding you...a HTTPS server can only have once cert/key...or are you trying to run 2 instances of Nginx?

As far as I understand I am running one Nginx instance but two websites.

Here is my Nginx conf.d directory...

The default server _lan.conf has the self generated _lan.crt and _lan.key... I expect those to be used when I open the LuCI web admin page from something like

But I also made my own little test website called mysite.lan.conf and for that I have mysite.lan.crt and mysite.lan.key. I expect that key pair to be used in the browser when I open https://www.mysite.lan

That must be possible?

But I'm also playing around trying to understand it all. For example, I make point to mysite.lan.conf by adding as a server_name.. my little test webpage is loaded but the cert/key pair in the browser is from the _lan.conf server block instead of the mysite.lan.conf server block. Why?


What I was observing here was a consequence of Server Name Indication (SNI). I got an explanation in this Serverfault thread.

Basically SNI is not performed on a literal IP address so even if is specified as a server_name and I type into the browser, if a default server exists, then the certificate will come from the default_server.

But even though SNI cannot happen the host header contains the ip address (because the url does) and that's why the correct server block is matched and hence the correct webpage is served up but with the wrong certificate.


This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.