You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Nginx配置问题:如何禁止通过服务器IP直接访问站点?

问题分析

你的配置里导致IP访问跳转到主域名的核心原因有两个:

  1. 80端口的默认服务器被主域名跳转逻辑接管:当前80端口的server块标记了default_server,且server_name是example.net www.example.net。当用IP访问80端口时,Nginx会命中这个默认服务器,执行最后的return 301 https://example.net$request_uri,直接跳转到主域名。
  2. 443端口无专属默认服务器:当用IP访问443端口时,Nginx会自动匹配第一个定义的443server块(即app.example.net的配置),虽然里面有if ($host !~ ^(app.example.net)$ )返回444,但如果浏览器缓存了之前的跳转记录,或者测试时未清除缓存,可能导致看起来没生效;更关键的是,没有专门的443默认服务器兜底,逻辑不严谨。

另外,你现有配置里的if ($http_host != $server_name)和重复的$host匹配判断属于冗余逻辑,且Nginx的if指令存在优先级问题,容易引发意外行为,建议移除。

解决步骤

1. 生成自签SSL证书(用于443默认服务器)

因为Nginx的443端口必须配置SSL证书才能启动,所以先生成一个自签证书用于兜底的默认服务器:

mkdir -p /etc/nginx/ssl
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/nginx/ssl/default.key -out /etc/nginx/ssl/default.crt

执行过程中按提示填写信息即可,无需严格匹配域名。

2. 修改Nginx配置

替换原有配置为以下内容,核心是新增80和443端口的专属默认服务器,专门处理IP访问:

# 80端口默认服务器:处理IP访问,直接返回444关闭连接
server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name _;
    return 444;
}

# 443端口默认服务器:处理IP访问,直接返回444关闭连接
server {
    listen 443 ssl default_server;
    listen [::]:443 ssl default_server;
    server_name _;

    ssl_certificate /etc/nginx/ssl/default.crt;
    ssl_certificate_key /etc/nginx/ssl/default.key;

    return 444;
}

# app server configuration
server {
    root /var/www/html;
    server_name app.example.net;

    location / {
        proxy_pass http://external_server_ip:8080; 
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_cache_bypass $http_upgrade;
    }

    if ($http_id = '') {
        return 401;
    }

    listen [::]:443 ssl http2; # managed by Certbot
    listen 443 ssl http2; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/app.example.net/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/app.example.net/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}

map $sent_http_content_type $expires {
    default                    off;
    ~text/css                   30d;
    ~application/javascript     30d;
    ~image/                    30d;
}

# Default server configuration
server {
    root /var/www/html;
    server_name example.net www.example.net;

    location / {
        proxy_pass http://localhost:5000; 
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_cache_bypass $http_upgrade;
        limit_except GET HEAD POST { deny all; }
    }

    ## Block download agents ##
    if ($http_user_agent ~* LWP::Simple|BBBike|wget|zgrab|WebSucker01h4x.com|360Spider|404checker|404enemy|80legs|ADmantX|AIBOT|ALittle\ Client|ASPSeek|Go-Ahead-Got-It|GoZilla|Gotit|GrabNet|Grabber|Grafula|Niki-bot|Nikto|NimbleCrawler|Nimbostratus|Ninja|Nmap|Xaldon_WebSpider|Xenu|YoudaoBot|Zade|Zauba|Zermelo|Zeus|Zitebot|ZmEu|seocompany.store|seoscanners|seostar|serpstatbot|sexsearcher|sitechecker.pro|siteripz|sogouspider|sp_auditbot|spyfu|sysscan|tAkeOut|trendiction.com|trendiction.de|ubermetrics-technologies.com|voyagerx.com|webgains-bot|webmeup-crawler|webpros.com|webprosbot|x09Mozilla|x22Mozilla) {
        return 403;
    }
    ## Deny certain Referers ###
    if ( $http_referer ~* (seo|referrer|redirect|babes|click|girl|jewelry|love|organic|poker|porn|sex|teen|video|webcam) ) {
        return 403;
    }
    # deny access to .htaccess files
    location ~ /\.ht {
        deny all;
    }
    # Deny access to hidden files (beginning with a period)
    location ~ /\. {
        deny all;
    }

    expires $expires;

    listen [::]:443 ssl http2; # managed by Certbot
    listen 443 ssl http2; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/example.net/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/example.net/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}

# 80端口主域名跳转:仅处理example.net和www.example.net的http转https
server {
    if ($host = www.example.net) {
        return 301 https://example.net$request_uri;
    } 
    if ($host = example.net) {
        return 301 https://example.net$request_uri;
    }

    listen 80;
    listen [::]:80;

    server_name example.net www.example.net;
    return 301 https://example.net$request_uri;
}

3. 验证并重启Nginx

nginx -t
systemctl restart nginx
关键说明
  • 新增的两个默认服务器块会优先处理所有IP访问(无论80还是443端口),直接返回444关闭连接,不会触发任何跳转。
  • 原有的主域名和子域名配置仅处理对应域名的请求,逻辑更清晰。
  • 移除了冗余的$host匹配判断,避免Nginxif指令的优先级问题。

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 09:35:14