You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何阻止直接IP访问Nginx SSL站点?现有配置遇访问问题

解决直接IP访问Nginx反向代理站点的问题

嘿,我来帮你捋捋这个问题哈~你的现有配置确实能搞定host.domain.com域名的SSL反向代理,但用服务器直接IP访问时出问题,核心原因有两个:一是你的Nginx配置里只有针对host.domain.com的server块,IP访问时Nginx找不到对应匹配的规则;二是你的SSL证书是绑定域名的,就算Nginx处理了IP请求,浏览器也会因为证书不匹配弹出安全警告,体验很差。

下面给你两种实用的解决方案,按需选就行:

方案1:禁止IP访问,跳转到正确域名(最推荐)

既然证书是给域名用的,不如直接引导用户用域名访问,还能避免证书警告。你只需要在现有配置前加一个默认server块,专门处理所有非域名的443请求(包括IP访问):

# 这个是默认server块,优先处理所有没匹配到host.domain.com的443请求
server {
    listen 443 ssl default_server;
    server_name _; # 下划线表示匹配任何域名或IP

    # 暂时复用你现有的证书就行(虽然浏览器会临时警告,但跳转后就正常了)
    ssl_certificate /etc/httpd/ssl/Sample_StarCert.crt;
    ssl_certificate_key /etc/httpd/ssl/Sample-NPW.key;

    # 直接301永久重定向到正确的域名,保留用户原本要访问的路径
    return 301 https://host.domain.com$request_uri;
}

# 保留你原来的server块,顺便加几个实用的proxy头部,避免反向代理时丢失客户端信息
server {
    listen 443 ssl;
    server_name host.domain.com;
    location / {
        proxy_pass http://host.domain.com;
        # 加上这些头部,后端服务器能拿到真实的客户端信息和请求协议
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
    ssl_certificate /etc/httpd/ssl/Sample_StarCert.crt;
    ssl_certificate_key /etc/httpd/ssl/Sample-NPW.key;
}

方案2:允许IP访问(不推荐,仅特殊场景用)

如果你确实需要支持IP访问,那得先解决证书问题——要么找CA签发绑定该服务器IP的证书(现在很多CA不提供这个服务,大概率得自签),要么接受浏览器的安全警告。然后修改你的server块,把IP加到server_name里,同时注意避免循环代理:

server {
    listen 443 ssl;
    server_name host.domain.com 192.168.1.100; # 把你的服务器实际IP填在这里
    location / {
        # 这里建议直接指向后端HTTP服务器的本地地址,比如http://127.0.0.1:80
        # 避免proxy_pass用域名导致请求又回到Nginx,形成循环代理
        proxy_pass http://127.0.0.1:80;
        # 同样加上必要的proxy头部
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
    # 如果有IP专属证书,就替换成下面的路径;没有的话还是用原来的证书
    ssl_certificate /etc/httpd/ssl/IP_Cert.crt;
    ssl_certificate_key /etc/httpd/ssl/IP_Key.key;
}

最后提醒一句:你原来的proxy_pass http://host.domain.com存在潜在的循环代理风险,如果后端的HTTP服务器也是通过这个Nginx实例处理请求的话,会导致请求无限循环,所以改成直接指向后端服务器的IP+端口会更稳妥~

内容的提问来源于stack exchange,提问作者user1197457

火山引擎 最新活动