Redirect to https unless from private network on nginx
I'd like to redirect all request coming from outside the network to https - but keep internal one s on http.
Right now I have two .conf
files - one that begins so:
server {
# listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
server_name www.example.com , example.com;
# omitted stuff
}
and contains
server {
listen 80;
server_name www.example.com , example.com;
return 301 https://$host$request_uri;
}
and another that begins like this:
server {
listen 192.168.1.144:80;
listen 192.168.1.196:80;
server_name "";
root /var/www/html;
# omitted stuff
}
But right now requests to http://example.com do not get redirected to https.
Why is that? what have I gotten wrong? my goal is to redirect all requests not coming from the home private network (192.168.1.*
) to https, and leave internal ones alone.
Solution 1:
server_name
directive uses spaces for separating domain names. Your configuration has commas, which confuses nginx.
You need to use:
server_name www.example.com example.com;
Solution 2:
I assume that with the following you are trying to make a different server block that listens on two interfaces on the local network:
server {
listen 192.168.1.144:80;
listen 192.168.1.196:80;
# ...
}
For this to work your topology would look similar to this:
However, if your server is behing the same NAT than the clients on the private network 192.168.1.0/24
, this server
block would be used for the external connections, too. This topology would be similar to this:
With the latter, you could use e.g. the ngx_http_geo_module to separate the local network based on its clients:
geo $external {
default 1;
192.168.1.0/24 0;
}
server {
listen 80;
server_name example.com www.example.com;
root /var/www/html;
if ($external) {
return 301 https://$server_name$request_uri;
}
}
However, from the security perspective I wouldn't recommend trusting your internal network like this, but using TLS equally for every client. That's because it's easy to get MitM position simply by having access to the local network.