返回错误码 (推荐)

这是最常用也是最推荐的方法,当用户直接通过 IP 访问时,Nginx 会返回一个指定的 HTTP 状态码,通常是 444(Nginx 特有的,表示无响应,连接会立即关闭)或者 403 Forbidden(禁止访问),这种方法对搜索引擎和爬虫也友好,告诉它们这个地址不可用。

nginx禁止ip访问网站
(图片来源网络,侵删)

操作步骤

  1. 打开 Nginx 的主配置文件 这个文件通常是 /etc/nginx/nginx.conf

    sudo vim /etc/nginx/nginx.conf
  2. http 块中添加 serverhttp { ... } 的大括号内,添加一个专门用于处理 IP 访问的 server 块,这个块应该放在你最前面,以便优先匹配。

    # 在 http 块内部,其他 server 块之前
    server {
        # 监听所有端口
        listen 80 default_server;
        listen [::]:80 default_server;
        # 监听所有 HTTPS 端口(如果配置了 HTTPS)
        listen 443 ssl default_server;
        listen [::]:443 ssl default_server;
        # 如果配置了 HTTPS,需要指定证书和密钥路径
        # ssl_certificate /path/to/your/fullchain.pem;
        # ssl_certificate_key /path/to/your/privkey.pem;
        # 记录访问日志,方便排查问题
        access_log /var/log/nginx/ip_access.log;
        # 返回 444 状态码,表示无响应,连接会立即关闭
        # return 444;
        # 或者返回 403 Forbidden 状态码
        return 403;
    }

    代码解释:

    • listen 80 default_server;default_server 是关键,它表示这个 server 块是处理所有没有匹配到其他 server_name 的 HTTP 80 端口请求的默认服务器。
    • listen 443 ssl default_server;:同理,这是处理所有 HTTPS 443 端口默认请求的,如果你的网站开启了 HTTPS,这一行必须有,否则 IP 仍然可以通过 HTTPS 访问。
    • return 444;:这是 Nginx 的特殊状态码,不会返回任何内容给客户端,直接断开 TCP 连接,这是最高效的方式。
    • return 403;:返回标准的“禁止访问”错误页面。
    • access_log:强烈建议记录日志,这样你可以知道何时、有多少 IP 尝试直接访问你的服务器。
  3. 保存并退出

    nginx禁止ip访问网站
    (图片来源网络,侵删)
  4. 检查并重载 Nginx 配置 在应用新配置前,务必检查语法是否正确。

    # 检查配置文件语法
    sudo nginx -t
    # 如果输出如下,说明配置正确
    # nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
    # nginx: configuration file /etc/nginx/nginx.conf test is successful
    # 重载 Nginx 配置,使其生效
    sudo systemctl reload nginx

重定向到主页

这种方法会将所有通过 IP 的访问重定向到你网站的域名主页。

操作步骤

  1. 打开 Nginx 主配置文件 (/etc/nginx/nginx.conf)

  2. 添加 server,但将 return 指令改为 return 301 $scheme://$host$request_uri;

    nginx禁止ip访问网站
    (图片来源网络,侵删)
    server {
        listen 80 default_server;
        listen [::]:80 default_server;
        listen 443 ssl default_server;
        listen [::]:443 ssl default_server;
        # ssl_certificate ...;
        # ssl_certificate_key ...;
        # 将所有 IP 访问重定向到域名主页
        return 301 $scheme://www.yourdomain.com$request_uri;
    }

    代码解释:

    • return 301 ...;301 表示永久重定向,搜索引擎会更新其索引。
    • $scheme:自动获取协议,是 http 还是 https
    • $host:获取请求中的 Host 头部,但因为我们没有 server_name,所以这里 $host 是空的,我们直接指定你的域名,如 www.yourdomain.com
    • $request_uri:保留原始的请求路径(/some/path),这样访问 http://IP/some/path 就会重定向到 http://www.yourdomain.com/some/path
  3. 检查并重载 Nginx 配置

    sudo nginx -t
    sudo systemctl reload nginx

在每个网站配置中禁止 IP (备选方案)

如果你不想在主配置文件中添加一个全局的 server 块,也可以在每个网站的 server 块中添加 if 条件来判断并禁止 IP 访问。

注意:Nginx 官方不推荐在 locationserver 块中使用 if 指令,因为它可能会导致不可预期的行为,但对于这个简单的场景,它通常是可行的。

操作步骤

  1. 打开你网站的配置文件/etc/nginx/sites-available/yourdomain.com

  2. 在每个 server 块的开头添加 if 判断

    server {
        listen 80;
        server_name yourdomain.com www.yourdomain.com;
        # 如果访问的 Host 头部为空或者就是 IP 地址,则返回 403
        if ($host != 'yourdomain.com' and $host != 'www.yourdomain.com') {
            return 403;
        }
        # ... 其他网站配置,如 root, index, location 等 ...
        location / {
            root /var/www/yourdomain.com;
            index index.html;
        }
    }

    代码解释:

    • $host 变量包含了请求的 Host 头部内容。
    • 当用户直接通过 IP 访问时,Host 头部通常是空的,或者就是 IP 地址。
    • 这个 if 条件判断如果 host 不等于你的任何一个域名,就返回 403。
  3. 检查并重载 Nginx 配置

    sudo nginx -t
    sudo systemctl reload nginx

总结与推荐

方法 优点 缺点 推荐度
返回错误码 配置清晰、高效、集中管理。return 444 对服务器资源消耗最小。 无明显缺点。 ⭐⭐⭐⭐⭐ (最推荐)
重定向 可以将流量引导到主域名,对用户更友好。 会消耗一次重定向的请求,可能被恶意利用进行重定向攻击。 ⭐⭐⭐
if 判断 无需修改主配置文件,逻辑直观。 Nginx 官方不推荐 if,可能在复杂配置下出现问题,不够优雅。 ⭐⭐

最终建议:

强烈推荐使用 方法一,它在性能、安全性和可维护性上都是最佳选择,只需在 nginx.conf 中添加一个 server 块,就能一劳永逸地解决所有域名的 IP 访问问题,并且管理起来非常方便。