openwrt / packages

Community maintained packages for OpenWrt. Documentation for submitting pull requests is in CONTRIBUTING.md
GNU General Public License v2.0
3.93k stars 3.44k forks source link

nginx refuses to start if server _lan is disabled or not defined #11533

Open val-kulkov opened 4 years ago

val-kulkov commented 4 years ago

@heil @Ansuel @peter-stadler

Commit 2401fd6db5e582d1b1442e4832222a3fee50937a introduced sweeping changes to /etc/init.d/nginx and to the way Nginx configuration files have to be written.

  1. /etc/init.d/nginx now forces users to put Nginx configuration files into /etc/nginx/conf.d/. If you have a customized version of /etc/nginx/nginx.conf that uses the "include" directive to read configuration files from some other location, like the commonly-used /etc/nginx/sites or /etc/nginx/sites-enabled, you are out of luck. The new version of /etc/init.d/nginx hardcodes the location of the configuration files /etc/nginx/conf.d/ by way of using nginx-util.

  2. /etc/init.d/nginx now uses nginx-util to automatically create a default configuration for Nginx in /etc/nginx/conf.d/_lan.conf which loads "listen" and "default_server" directives from /var/lib/nginx/lan_ssl.listen and /var/lib/nginx/lan_ssl.listen.default. This default configuration makes Nginx listen on ports 80 and 443 (in case of nginx-ssl) on all IP addresses associated with the LAN adapter. Now if someone wants to change Nginx configuration so that there is no default server and there are only named virtual servers responding to specific domain names, one has to disable the "_lan" server. The updated OpenWrt Nginx Wiki page now says that "We can disable single configuration parts by giving them another extension, e.g., by adding .disabled." Renaming _lan.conf to _lan.conf.disabled and adding domain-specific configuration files into /etc/nginx/conf.d/ causes Nginx failure to start:

    root@OpenWrt:~# /etc/init.d/nginx start
    init_lan notice: no server named _lan

    To be clear, by mandating "_lan" server which uses directives from /var/lib/nginx/lan_ssl.listen and /var/lib/nginx/lan_ssl.listen.default it is no longer possible to configure Nginx in OpenWrt to drop requests without the "Host" header field, which is precisely the case when Nginx receives a "rogue" https request with no SNI specified.

Since /etc/init.d/nginx now relies on nginx-util to create a default configuration, nginx package now has an additional dependency: nginx-util. For users like me who already have a well-working Nginx configuration, nginx-util provides zero benefit while consuming ~130KB of space on an OpenWrt device.

While an attempt to provide a reasonable default configuration for a package in OpenWrt is laudable, in this particular case it has created more problems than it has solved. First, Nginx already comes with reasonably good default configuration. Second, it is completely unacceptable to force a particular configuration on users where it is not necessary. Mandating the "_lan" server and mandating the default servers listening on all IP addresses associated with the LAN interface are all unacceptable.

As a minimum:

As a maximum:

peter-stadler commented 4 years ago

I am working on a new version.

I see that the message init_lan notice: no server named _lan is misleading, I removed it in the new version. Beside that message, the root@OpenWrt:~# /etc/init.d/nginx start should not fail, this is just an information. Isn't Nginx running?

To be clear: You can remove _lan.conf and it should work (showing the notice message). But, be aware that it could be reinstalled on upgrades (opkg does not track user deleted files). So, for now it is better to comment or remove its content (leaving an empty file). In the new version this should be better, too.

For dropping request without Host header: Is server_name ""; not working? Please be aware that the server must also listen on LAN explicitly (if using _lan.conf):

server {
    server_name "";
    listen [::]:80; # or: listen [::]:443;
    listen 80; # or: listen 443;
    include /var/lib/nginx/lan.listen; # or: /var/lib/nginx/lan_ssl.listen;
    return 444;
}

The configuration should work with a custom /etc/nginx/nginx.conf. Beside nginx-util init_lan searches for _lan.conf in /etc/nginx/conf.d/ you do not have to use that directory.

You are right that the hard coded procd_set_param file /etc/nginx/conf.d/... is inflexible. But, it is tracking more than before. If you are not using the conf.d directory it should not behave differently than before. (This variable influences the service nginx reload behaviour. procd keeps track of the stated files and invokes reloading only if some of them changed its md5 value.) P.S.: I am not sure that the procd_set_param file … does this, when we use a custom reload function. So, I am thinking about removing these lines. But, this is not my priority now. Do you like to investigate it?

Note: Theoretically it would be possible to split off nginx-util with the default server respectively the uci configuration from the nginx packages. Then, it would be depended from other packages (like luci-ssl-nginx, luci-nginx or ariang-nginx). But, the problems will be introduced, when a user installs the first of these packages and it will become hard to track. Although, I do not think it would be a good idea, I would implement it if the maintainers want it.

Thank you very much for the feedback.

peter-stadler commented 4 years ago

I am not sure: Do you think it would be better for the default server to listen on all IPs instead of restricting to local IPs? I thought it is better if the user has to create servers that are reachable from WAN (including only specific locations): Especially LuCI will not be exposed to WAN by default …

peter-stadler commented 4 years ago

@val-kulkov: If I am wrong and it is not just the misleading message, can you give me some details such that I can investigate the problem(s)?

PussAzuki commented 4 years ago

As val-kulkov said, users using nginx should not be bound by the extra default settings, at least in this case, it is self-defeating. Today, when I tried to switch from running nginx on ubuntu to running nginx on openwrt, I was also fooled by these default value problems: First problem: you must have a server named _lan. The second problem, it doesn't seem to be able to disable it by adding a blank file named _lan.disabled to the conf.d folder. Third problem, you cannot delete the conf.d folder. What's even weirder is that it even throws out such a log: daemon.err nginx[9803]: 2020/04/02 17:51:11 [crit] 9803#0: pread() "/usr/" failed (21: Is a directory) I'm sure I don't have any /usr/ related in my configuration.

All of the above problems disappeared when I migrated the configuration on ubuntu directly and ran nginx directly instead of /etc/init.d/nginx start

So, are you helping users or not?

peter-stadler commented 4 years ago

I try to help: 1) I am working on a new version ... 2) For now try to create an empty file '_lan.conf', but the line init_lan notice: no server named _lan will be still there (it is removed in the new version). This line is just informational, it should not do any harm (beside be confusing). 3) Same for deleting the conf.d folder 4) I am not sure about /usr/ but I believe this comes from Nginx being compiled with --prefix=/usr/ and it will be installed by default to /usr/sbin/nginx. This was the case before my changes, too.

Edit: I cannot reproduce the /usr/ problem, can you give me any hint? Or maybe Nginx's configure helps ... The rest I tested in the old and new version. For both versions it should be working, although for the old one you will get the init_lan notice: … line. If this is not the case, can you give me some more infos?

PussAzuki commented 4 years ago
  1. Nginx is a software that needs to be highly customized and it should be a better way to let users decide whether to install the extra helper or not, even if your software will be of great help to beginners using openwrt. As long as this software is dependent on the installation of nginx, it will inevitably affect the users who have previously used nginx in other linux distributions. 4.But it works well by executing nginx instead of /etc/init.d/nginx start and now I think using the instructions that come with nginx is more efficient rather than read what you added.

To say something beside the point, the last software that had compilation options but was not "open" was the package dnsmasq-full.

PussAzuki commented 4 years ago

I don't know how to say. The same configuration worked normally last time, and then started after it was stopped by using /etc/init.d/nginx stop. I also think it's weird.

I used to compile nginx from the source code on ubuntu according to a tutorial, because the package in ubuntu 18.04 lts is too old, it is very old even with the precompiled package of nginx. So I tried the openwrt's nginx and it gave a kick.

peter-stadler commented 4 years ago
  1. We could add a configure option to disable the installation of the extra helper, would that help? In the new version, we plan already to use something like uci set nginx.global.uci_enable=false to disable the creation of the used uci.conf file. Then the user is expected to provide their own /etc/nginx/nginx.conf file that will be used then.

For the rest, I will look into it …

PussAzuki commented 4 years ago

Now you try to use uci,why not change the extra helper's name to luci-app-nginx and do something likewhat luci-app-uhttpd does to uhttpd ? That sounds great if stopping confusing the needs of some users.

peter-stadler commented 4 years ago

A luci-app would be definitely some separate package (not depended upon by nginx-*). This is far from that.

The reason for having this always: It contains the default server that can be used by other packages to provide their applications, e.g. luci-ssl-nginx (NB: This provides LuCI itself through Nginx not an LuCI app for Nginx). Beforehand it changed the existing nginx.conf for that.

We have three options (in my eyes):

(I think the last one is the way to go.)

PussAzuki commented 4 years ago

Is it okay to work like stubby ? That is if the package not installed, then try to use the file in /etc/nginx. If installed, convert /etc/config/nginx to configuration and put it under /var, then use this by default. So it can work as a part of luci-nginx/luci-ssl-nginx and never confuse users

peter-stadler commented 4 years ago

So changing the used configuration upon installation of luci-ssl-nginx (or other packages that want to use a default server to provide their locations, currently I want to do that for etesync-server)?

peter-stadler commented 4 years ago

Isn't that more confusing? Then, a user experiences problems with Nginx (as right now on the update), if they install another package and this would be intended behavior ... I am not sure if this is better. Sure there would be less users that have the problem (only those installing nginx and another package that wants the default server), but it splits the problems to different places making it harder to track down.

peter-stadler commented 4 years ago

Ah, I misunderstood: I thought you meant it to be off by default. Sorry.

Now I looked closer to stubby and actually the new version will be similar: When the global option uci_enable is false (default=true) it will try to use /etc/nginx/nginx.conf and ignore the rest of the UCI config. (stubby ignores the rest of its UCI config if manual is true with default=false) Thank you :-)

peter-stadler commented 4 years ago

For the /usr/ problem: I could get a the above error message by using include /usr/; or include ""; with the main conf being in /usr/. Does this help somehow?

Else: service nginx start is not working and afterwards /usr/sbin/nginx is working with the same /etc/nginx/nginx.conf file, right?

The init.d essentially uses the latter commandline with two variables, which it gets from the other two lines. (The command nginx-util init_lan sets some files /var/lib/nginx/*listen and in conf.d if possible. But if you do not delete them in between, it should be the same for service nginx start as for nginx alone).

PussAzuki commented 4 years ago

Yes, I just deleted nginx-util related lines, and it seemed to work, but it really failed once to start after using /etc/init.d/nginx stop, and I also using htop to see if there were master process es, there was not. Now I just leave the startup sequence in the startup script and generate the folder and nginx command. It works well now. I'm sorry I can't give you a log.

peter-stadler commented 4 years ago

No problem, thank you very much for explaining.

jkcapoeira commented 4 years ago

I have sslh running as multiplexer on port 443 and forward tls to nginx which is running as a reverse proxy on port 9443. So i can log for each virtual machine the real ip address. (https://forum.openwrt.org/t/nginx-and-openvpn-on-port-443/25004/5) but to get that working again i think i need to replace the /ect/init.d/nginx with an old version where there is no reference to nginx-util and all the LAN_stuff correct?

peter-stadler commented 4 years ago

Replacing the file /etc/init.d/nginx is not needed (and it would not be persistent as this file is not part of the configuration for opkg and thus would be reinstalled later). I write a suggestion for solving this at your issue #12776 …

richard-gravy commented 3 years ago

If I could chime in on this, I am similarly finding nginx-util an irritating dependency.

My use case:- I am running a web application server. The device has two interfaces, "lan" and "wan". I would like nginx to listen exclusively on the "wan" interface. The "lan" interface is reserved for admin work (e.g. changing config files over ssh).

Because nginx-util is hellbent on keeping nginx listening to both loopback and "lan", I have to write a complex script in /etc/uci-defaults/ to destroy it and replace it with a short shell script that performs an identical function for the "wan" interface.

I can understand the purpose of nginx-util, but the fact that it tags along every time nginx is installed and uses hardcoded values presents a "barrier to entry" to those who aren't using OpenWrt simply for routing.

peter-stadler commented 3 years ago

Thank you, I want to make it better and created a new version (This is the preparation for nginx-util; another PR for nginx that uses it would follow).

The new version will bind the default server to all addresses instead to the addresses of the local interfaces. So another service that binds on the LAN addresses will have precedence. (Instead of listening on local addresses, the default server '_lan' will be restrict to local addresses by allow/deny directives.)

For now it should be possible to disable the preinstalled servers by replacing _lan.conf and _redirect2ssl.conf in the directory /etc/nginx/conf.d/ with empty files. The new version will use UCI for the default server, then you can disable these servers by: uci set nginx._lan=disable and uci set nginx._redirect2ssl=disable. (You can also create your own /etc/nginx/nginx.conf and use it while disabling the UCI config for nginx by: uci set nginx.global.uci_enable=false)

So, the new version will be more flexible and allow the use of UCI for configuration (beside conf files). If you like to take a look at it, I appreciate the feedback :-)

FlexMcMurphy commented 3 years ago

@peter-stadler

I have a confusing situation which is somewhat related to this issue I think. Can you help me understand it please? I also posted about this on the OpenWrt forum but it's not getting any response.

I installed OpenWrt with Nginx on a Pi 4 at 192.168.1.254 using opkg install luci-ssl-nginx 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 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;
}

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: image

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

Can't understand why the default ssl cert is being used when I type the ip address into the browser but the webpage from my own server block is being loaded. It's like Nginx is half responding to my user defined server block and half responding to the default server block. Is that possible?

Cheers,

Flex

peter-stadler commented 3 years ago

I did a quick test (not using different certs but different locations): it should work. For half responding I have only in mind that Nginx has another config than on disk, maybe try service nginx reload ...

FlexMcMurphy commented 3 years ago

@peter-stadler

OK I actually rebooted my OpenWrt and now I see something different. Can you help me understand please?

I have these files in /etc/nginx/conf.d image

mysite.lan.conf is my own server block that points to a basic webpage for testing, but I also put 192.168.1.254 in the server_name list: image

_lan.conf is the default server block unchanged, aside from having ssl enabled: image

I cleared my browser cache and even deleted 192.158.1.254 from the domain security policy (HSTS and Expect-CT) in chrome://net-internals/#hsts

Now http://192.168.1.254 gives this: image

And https://192.168.1.254 gives this: image

Is this correct behavior? Can you explain it to me?

  1. In the first one.. why does the LuCI web page load? Does the default _lan.conf server listen on port 80 and port 443? It's still http so I guess it's not _redirect2ssl.conf getting involved?

  2. In the second one why don't I get my little test page from the mysite.lan.conf server block? 192.168.1.254 is listed in the server_name field?

  3. From reading through this thread I see that emptying the contents of _lan.conf and _redirect2ssl.conf will then make https://192.168.1.254 open my test page with the correct ssl cert/key pair. And it does: The cert is also correctly issued to mysite.lan and not OpenWrt from the default server image

  4. But why exactly is that? Is it because, if present, the default _lan.conf server gets a monopoly on web requests when the url is for an ip address even if the ip address is listed as a server_name in another server block?

  5. I go from having _lan.conf and _redirect2ssl.conf empty and then I restore their correct content. I find it is not enough to reload or restart Nginx I have to reboot OpenWrt altogether... otherwise https://192.168.1.254 will make my test page load but the cert/key pair from the _lan.conf will be used so I get a browser error. image

  6. Is this a bug or normal behavior? I have to reboot OpenWrt?

Sorry for this long post, I got fascinated by all this.

Cheers, Flex

peter-stadler commented 3 years ago

You should not need to reboot OpenWrt (although sometimes there is a problem getting the local IPs). Altogether this is a strange behavior. If you don´t mind: can you post the whole Nginx config printed by nginx -T (preferable as copyable text not as screen shot) edit: both when working and when failing?

I see only one problem in the mysite.lan.conf (missing ssl directives), but I cannot explain the described behaviour with it. The lines should be:

        listen 443 ssl;
        listen [::]:443 ssl;
FlexMcMurphy commented 3 years ago

@peter-stadler

Thanks for getting back to me peter. I added in ssl to mysite.lan .conf in those two places but I am still seeing the same behavior... I even freshly regenerated the _lan.conf, _lan.key and _lan.crt files.

When I put 192.168.1.254 in the mysite.lan.conf server block and put http://192.168.1.254 into the browser then it switches to https://192.168.1.254 (I guess that's _redirect2ssl.conf working) and I get my mysite.lan.conf test web page but the ssl error in the browser shows the cert being issued by and to OpenWrt. So it doesn't use the mysite.lan.conf cert. image

Is this result expected? Maybe that's what this whole Github thread above is about? That only the default server can really respond properly to a web browser request when the host is an actual ip address (e.g: https://192.168.1.254).

These are some observed behaviors that make me think this is so. With the default server in place I cannot run any site I want on a domain name: 192.168.1.254 Instead only the LuCI web admin page may respond properly to that "domain name".

  1. Emptying the contents of _lan.conf and _redirect2ssl.conf DO make https://192.168.1.254 open my test page with the correct ssl cert/key pair and 192.168.1.254 is a server_name in mysite.lan.conf.
  2. With _lan.conf and _redirect2ssl.conf NOT emptied out, if I type https://mysite.lan then I get my test page and the correct certificate is used... not the OpenWrt cert.

My main goal now is to simply understand why putting 192.168.1.254as a server_name in mysite.lan.confdoes load my test web page but does not load the correct cert.

Here is the output of nginx-T on my OpenWrt:

# configuration file /etc/nginx/nginx.conf:
# Please consider creating files in /etc/nginx/conf.d/ instead of editing this.
# For details see https://openwrt.org/docs/guide-user/services/webserver/nginx

worker_processes auto;

user root;

events {}

http {
    access_log off;
    log_format openwrt
        '$request_method $scheme://$host$request_uri => $status'
        ' (${body_bytes_sent}B in ${request_time}s) <- $http_referer';

    include mime.types;
    default_type application/octet-stream;
    sendfile on;

    client_max_body_size 128M;
    large_client_header_buffers 2 1k;

    gzip on;
    gzip_vary on;
    gzip_proxied any;

    root /www;

    include conf.d/*.conf;
}

# configuration file /etc/nginx/mime.types:

types {
    text/html                                        html htm shtml;
    text/css                                         css;
    text/xml                                         xml;
    image/gif                                        gif;
    image/jpeg                                       jpeg jpg;
    application/javascript                           js;
    application/atom+xml                             atom;
    application/rss+xml                              rss;

    text/mathml                                      mml;
    text/plain                                       txt;
    text/vnd.sun.j2me.app-descriptor                 jad;
    text/vnd.wap.wml                                 wml;
    text/x-component                                 htc;

    image/png                                        png;
    image/svg+xml                                    svg svgz;
    image/tiff                                       tif tiff;
    image/vnd.wap.wbmp                               wbmp;
    image/webp                                       webp;
    image/x-icon                                     ico;
    image/x-jng                                      jng;
    image/x-ms-bmp                                   bmp;

    font/woff                                        woff;
    font/woff2                                       woff2;

    application/java-archive                         jar war ear;
    application/json                                 json;
    application/mac-binhex40                         hqx;
    application/msword                               doc;
    application/pdf                                  pdf;
    application/postscript                           ps eps ai;
    application/rtf                                  rtf;
    application/vnd.apple.mpegurl                    m3u8;
    application/vnd.google-earth.kml+xml             kml;
    application/vnd.google-earth.kmz                 kmz;
    application/vnd.ms-excel                         xls;
    application/vnd.ms-fontobject                    eot;
    application/vnd.ms-powerpoint                    ppt;
    application/vnd.oasis.opendocument.graphics      odg;
    application/vnd.oasis.opendocument.presentation  odp;
    application/vnd.oasis.opendocument.spreadsheet   ods;
    application/vnd.oasis.opendocument.text          odt;
    application/vnd.openxmlformats-officedocument.presentationml.presentation
                                                     pptx;
    application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
                                                     xlsx;
    application/vnd.openxmlformats-officedocument.wordprocessingml.document
                                                     docx;
    application/vnd.wap.wmlc                         wmlc;
    application/x-7z-compressed                      7z;
    application/x-cocoa                              cco;
    application/x-java-archive-diff                  jardiff;
    application/x-java-jnlp-file                     jnlp;
    application/x-makeself                           run;
    application/x-perl                               pl pm;
    application/x-pilot                              prc pdb;
    application/x-rar-compressed                     rar;
    application/x-redhat-package-manager             rpm;
    application/x-sea                                sea;
    application/x-shockwave-flash                    swf;
    application/x-stuffit                            sit;
    application/x-tcl                                tcl tk;
    application/x-x509-ca-cert                       der pem crt;
    application/x-xpinstall                          xpi;
    application/xhtml+xml                            xhtml;
    application/xspf+xml                             xspf;
    application/zip                                  zip;

    application/octet-stream                         bin exe dll;
    application/octet-stream                         deb;
    application/octet-stream                         dmg;
    application/octet-stream                         iso img;
    application/octet-stream                         msi msp msm;

    audio/midi                                       mid midi kar;
    audio/mpeg                                       mp3;
    audio/ogg                                        ogg;
    audio/x-m4a                                      m4a;
    audio/x-realaudio                                ra;

    video/3gpp                                       3gpp 3gp;
    video/mp2t                                       ts;
    video/mp4                                        mp4;
    video/mpeg                                       mpeg mpg;
    video/quicktime                                  mov;
    video/webm                                       webm;
    video/x-flv                                      flv;
    video/x-m4v                                      m4v;
    video/x-mng                                      mng;
    video/x-ms-asf                                   asx asf;
    video/x-ms-wmv                                   wmv;
    video/x-msvideo                                  avi;
}

# configuration file /etc/nginx/conf.d/_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;
}

# configuration file /var/lib/nginx/lan_ssl.listen.default:
# This file is re-created if Nginx starts or a LAN address changes.
    listen 127.0.0.1:443 ssl default_server;
    listen 192.168.1.254:443 ssl default_server;

# configuration file /etc/nginx/conf.d/luci.locations:
location /cgi-bin/luci {
        index  index.html;
        include uwsgi_params;
        uwsgi_param SERVER_ADDR $server_addr;
        uwsgi_modifier1 9;
        uwsgi_pass unix:////var/run/luci-webui.socket;
}
location ~ /cgi-bin/cgi-(backup|download|upload|exec) {
        include uwsgi_params;
        uwsgi_param SERVER_ADDR $server_addr;
        uwsgi_modifier1 9;
        uwsgi_pass unix:////var/run/luci-cgi_io.socket;
}

location /luci-static {
        error_log stderr crit;
}

location /ubus {
        ubus_interpreter;
        ubus_socket_path /var/run/ubus/ubus.sock;
        ubus_parallel_req 2;
}

# configuration file /etc/nginx/uwsgi_params:

uwsgi_param  QUERY_STRING       $query_string;
uwsgi_param  REQUEST_METHOD     $request_method;
uwsgi_param  CONTENT_TYPE       $content_type;
uwsgi_param  CONTENT_LENGTH     $content_length;

uwsgi_param  REQUEST_URI        $request_uri;
uwsgi_param  PATH_INFO          $document_uri;
uwsgi_param  DOCUMENT_ROOT      $document_root;
uwsgi_param  SERVER_PROTOCOL    $server_protocol;
uwsgi_param  REQUEST_SCHEME     $scheme;
uwsgi_param  HTTPS              $https if_not_empty;

uwsgi_param  REMOTE_ADDR        $remote_addr;
uwsgi_param  REMOTE_PORT        $remote_port;
uwsgi_param  SERVER_PORT        $server_port;
uwsgi_param  SERVER_NAME        $server_name;

# configuration file /etc/nginx/conf.d/_redirect2ssl.conf:
# acts as default server if there is no other.
server {
    listen 80;
    listen [::]:80;
    server_name _redirect2ssl;
    return 302 https://$host$request_uri;
}

# configuration file /etc/nginx/conf.d/mysite.lan.conf:
server {
        listen 443 ssl;
        listen [::]:443 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;

}

# configuration file /var/lib/nginx/lan_ssl.listen:
# This file is re-created if Nginx starts or a LAN address changes.
    listen 127.0.0.1:443 ssl;
    listen 192.168.1.254:443 ssl;

Thank you for your time,

Flex

peter-stadler commented 3 years ago

Thank you for your patience, you are right that this a similar problem that val-kulkov pointed out already: I did oversee that the IP is not (allowed to be) sent as SNI, so Nginx will use the default server to setup https ...

In the current version I see no other way than to blank the _lan.conf. In the upcoming version you can install your server with an additional listen 192.168.1.254 ssl;. So it will handle all requests for this IP Edit: since a listen directive with a precise IP has precedence over a generic one (The '_lan' server will not listen on the local IPs but on all IPs and allow only local clients) .

But, for catching all https requests without SNI by another server, we would need to remove the default_server directive from the '_lan' server; I would consider this a rather special case and think it is bearable to remove it from the preinstalled config by the user then, but maybe it would be better to remove it upstream; what do you think?

FlexMcMurphy commented 3 years ago

Not at all Peter. I'm very grateful that you got back to me so now I finally understand that my issue here isn't related to how you are configuring Nginx on OpenWrt but rather my problem is a result of a feature of SNI. I got more explanation about it on ServerFault.

Basically even if 192.168.1.254 is specified as a server_name when I type https://192.168.1.254 into the browser the certificate will always come from the default_server because SNI is not performed on a literal IP address. 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. So that explains the behavior I found so confusing.

I have taken your advice and blanked out _lan.conf and _redirect2ssl.conf and now I can control things the way I like.

I think as others have suggested above it would be better to not hard code in a configuration that is intended to help those with less technical knowledge but which complicates things for those who might want to use OpenWrt as more than just a router. But then again blanking out those two files seemed to restore full control which wasn't hard to do..

Cheers,

Flex