除非来自 nginx 上的私有网络,否则重定向到 https

除非来自 nginx 上的私有网络,否则重定向到 https

我想将来自网络外部的所有请求重定向到 https - 但将内部请求保留在 http 上。

现在我有两个.conf文件-一个以如下方式开头:

server {
        # listen [::]:443 ssl ipv6only=on; # managed by Certbot                                                                                                                                              
        listen 443 ssl; # managed by Certbot                                                                                                                                                                 
        server_name www.example.com , example.com;         
        # omitted stuff
}

并包含

server {
    listen 80;
    server_name www.example.com , example.com;         
    return 301 https://$host$request_uri;
}

另一个是这样开头的:

server {                                                                                                                                                                                                     
        listen 192.168.1.144:80;                                                                                                                                                                             
        listen 192.168.1.196:80;                                                                                                                                                                             
                                                                                                                                                                                                             
        server_name "";                                                                                                                                                                                      
        root /var/www/html;                                                                                                                                                                                  
        # omitted stuff
   }

但现在请求http://example.com不要重定向到 https。

这是为什么?我哪里做错了?我的目标是将所有不是来自家庭专用网络 ( 192.168.1.*) 的请求重定向到 https,而不影响内部请求。

答案1

server_name指令使用空格来分隔域名。您的配置中有逗号,这会让 nginx 感到困惑。

您需要使用:

server_name www.example.com example.com;

答案2

我假设您正在尝试创建一个不同的服务器块,用于监听本地网络上的两个接口:

server {
    listen 192.168.1.144:80;
    listen 192.168.1.196:80;
    # ...
}

为了使其正常工作,您的拓扑将类似于此:

Nginx 直连互联网的拓扑

但是,如果您的服务器与专用网络上的客户端位于相同的 NAT 后面192.168.1.0/24,则此server块也将用于外部连接。此拓扑将类似于此:

具有 NAT 和端口转发的拓扑

对于后者,你可以使用例如ngx_http_geo_模块根据客户端来分离本地网络:

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;
    }
}

但是,从安全角度来看,我不建议像这样信任您的内部网络,而是对每个客户端平等使用 TLS。这是因为只需访问本地网络,就很容易获得 MitM 位置。

答案3

尝试此重定向,对于内部,我个人更喜欢通过 IP 地址来创建服务器名称。

server {
    listen 80;
    server_name example.com www.example.com;
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl;
    listen [::]:443 ssl;

    ssl_certificate /etc/ssl/example.crt;
    ssl_certificate_key /etc/ssl/example.key;

    server_name example.com www.example.com;

    location{
       .......
    }
}

相关内容