NGINX 配置内网访问

NGINX 配置内网访问

需求

我们有一个测试站的域名: https://test.zhiexa.com/ 这个域名是公网域名, 我希望限制其访问,只有在内网,或者办公室 IP 能够访问 ,该如何配置呢?

1. geo 模块配置

首先在虚拟主机文件中domain-vhost.conf添加,全局模块


# 添加允许的IP地址
geo $allowed_ip {
    default 0;  # 默认拒绝所有IP

    # 内网地址范围
    10.0.0.0/8 1;      # 允许所有10开头的内网IP
    172.16.0.0/12 1;   # 允许172.16-172.31范围的内网IP
    192.168.0.0/16 1;  # 允许所有192.168开头的内网IP

    # 添加特定的外网IP(示例) xxx.xxx.xxx.137 改成自己希望可以访问的IP
    xxx.xxx.xxx.137 1;  # 允许特定的办公室IP
   
}

这部分使用 geo 模块创建了一个变量 $allowed_ip ,用于判断访问IP是否在允许列表中:

  • 值为0表示禁止访问
  • 值为1表示允许访问

2. 访问控制判断

在server 段里面配置

# 在server 段配置
if ($allowed_ip = 0) {
    return 403;  # 如果IP不在允许列表中,返回403禁止访问错误
}

3. 错误页面配置

在server 段里面配置

# 先配置错误页面,将403错误重定向到一个命名location
error_page 403 @403_handler;

# 使用命名location来处理403错误
location @403_handler {
    root /usr/local/nginx/html;
    try_files /403.html =404;
    
    # 强制添加调试头信息 可以不用添加,调试使用
    add_header X-Debug-Path $document_root always;
    add_header X-Debug-File $request_filename always;
    add_header X-Debug-Uri $uri always;
    add_header X-Debug-Request-Uri $request_uri always;
    add_header X-Debug-Remote-Addr $remote_addr always;
    
    # 确保内容类型正确
    default_type text/html;
    charset utf-8;
    
    # 详细的错误日志
    error_log /usr/local/nginx/logs/403_debug.log debug;
}

# 正确配置错误页面 403.html 放在这个位置 /usr/local/nginx/html/403.html
location = /403.html {
    root /usr/local/nginx/html;
    internal;  # 只允许内部重定向访问,不能直接从外部访问
}
  • error_page 403 @403_handler 将403错误重定向到一个命名location

  • location @403_handler 定义了处理403错误的具体方式,包括显示自定义错误页面和添加调试信息

  • location = /403.html 定义了403错误页面的位置,并设置为internal,防止直接访问

整个配置的工作流程是:

  1. 当有请求访问服务器时,Nginx检查访问IP
  2. 通过geo模块判断IP是否在允许列表中
  3. 如果不在允许列表中,返回403错误
  4. 403错误被重定向到自定义错误页面
  5. 同时记录详细的调试信息和日志
  6. 这样就实现了只允许特定IP访问,其他IP都会被拒绝并显示自定义错误页面的功能。

我需要准备一个 403.html 页面 , 这个页面放到 /usr/local/nginx/html 这个目录下面

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>访问被拒绝 - 智AI</title>
    <style>
        body {
            font-family: 'PingFang SC', 'Helvetica Neue', Arial, sans-serif;
            background-color: #f8f9fa;
            color: #333;
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            margin: 0;
            padding: 0 20px;
        }
        .container {
            max-width: 600px;
            background-color: white;
            border-radius: 8px;
            box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
            padding: 40px;
            text-align: center;
        }
        .icon {
            font-size: 64px;
            margin-bottom: 20px;
            color: #f44336;
        }
        h1 {
            font-size: 28px;
            margin-bottom: 20px;
            color: #333;
        }
        p {
            font-size: 16px;
            line-height: 1.6;
            color: #666;
            margin-bottom: 30px;
        }
        .btn {
            display: inline-block;
            background-color: #1890ff;
            color: white;
            text-decoration: none;
            padding: 10px 20px;
            border-radius: 4px;
            font-size: 16px;
            transition: background-color 0.3s;
        }
        .btn:hover {
            background-color: #40a9ff;
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="icon">&#x1F6AB;</div>
        <h1>访问被拒绝</h1>
        <p>很抱歉,您当前的IP地址没有权限访问此页面。此页面仅限内部网络或授权IP访问。</p>
        <p>如需访问,请使用公司网络或联系管理员将您的IP添加到白名单。</p>
        <!-- 换成 公网正式域名  -->
        <a href="https://blog.youkuaiyun.com/u010339879" class="btn">前往公开网站</a>
    </div>
</body>
</html>

4. 一个完整的配置

map $http_upgrade $connection_upgrade {
    default upgrade;
    '' close;
}


# 添加允许的IP地址
geo $allowed_ip {
    default 0;

    # 内网地址范围
    10.0.0.0/8 1; # 10.0.0.0 - 10.255.255.255
    172.16.0.0/12 1; # 172.16.0.0 - 172.31.255.255
    192.168.0.0/16 1; # 192.168.0.0 - 192.168.255.255

    # 添加特定的外网IP(示例)
    222.65.141.137 1; # office ip
    47.116.213.148 1; # 测试服务器IPIP_ADDRESS 1;
}


server {
    listen 80;
    server_name test.zhiexa.com;

    # 添加访问日志以便调试
    access_log /usr/local/nginx/logs/test.com.access.log main;
    error_log /usr/local/nginx/logs/test.com.error.log debug;
	
    # 重定向到https
    return 302 https://$host$request_uri;
}


server {
    listen 443 ssl;
    server_name test.zhiexa.com;


    # 添加访问日志以便调试
    access_log /usr/local/nginx/logs/test.com.ssl.access.log main buffer=16k flush=5s;
    error_log /usr/local/nginx/logs/test.com.ssl.error.log debug;

    # 先配置错误页面
    error_page 403 @403_handler;

    # 使用命名location来处理403错误
    location @403_handler {
        root /usr/local/nginx/html;
        try_files /403.html =404;

        # 强制添加调试头信息
        add_header X-Debug-Path $document_root always;
        add_header X-Debug-File $request_filename always;
        add_header X-Debug-Uri $uri always;
        add_header X-Debug-Request-Uri $request_uri always;
        add_header X-Debug-Remote-Addr $remote_addr always;

        # 确保内容类型正确
        default_type text/html;
        charset utf-8;

        # 详细的错误日志
        error_log /usr/local/nginx/logs/403_debug.log debug;
    }


    if ($allowed_ip = 0) {
        return 403;
    }

    # 正确配置错误页面
    location = /403.html {
        root /usr/local/nginx/html;
        internal;
    }

    ssl_certificate cert/zhiexa.com.pem;
    ssl_certificate_key cert/zhiexa.com.key;
    ssl_session_cache shared:SSL:1m;
    ssl_session_timeout 5m;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
    ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers on;


    # 开启 Gzip 压缩
    gzip on;
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;


    # 根路径配置
    location / {
        root /aaa/zhiexa-cloud-web/dist/;
        try_files $uri $uri/ /index.html;
        index index.html;
        error_log /usr/local/nginx/logs/test.com.root.error.log debug;

        # HTML 文件缓存控制
        location ~* \.(html|htm)$ {
            add_header Cache-Control "no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0" always;
            expires off;
            # add_header X-Debug-Path $document_root always;
            # add_header X-Debug-Uri $uri always;
        }

        # 设置 .css 和 .js 文件的缓存时间为 4 小时
        location ~* \.(css|js)$ {
            expires 4h;
            add_header Cache-Control "public, no-transform";
        }

        # 设置图片文件的缓存时间为 4 小时
        location ~* \.(gif|jpg|jpeg|png|svg)$ {
            expires 4h;
            add_header Cache-Control "public, no-transform";
        }
    }


    location /h5 {
        root /service/customized-h5;
        try_files $uri $uri/ /index.html;
        index index.html;

        # 禁用 HTML 文件的缓存
        location ~* \.(html|htm)$ {
            add_header Cache-Control "no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0" always;
            expires off;
        }

        # 设置 .css 和 .js 文件的缓存时间为 4 小时
        location ~* \.(css|js)$ {
            expires 4h;
            add_header Cache-Control "public, no-transform";
        }

        # 设置图片文件的缓存时间为 4 小时
        location ~* \.(gif|jpg|jpeg|png|svg)$ {
            expires 4h;
            add_header Cache-Control "public, no-transform";
        }
    }


    location /api/file-assistant {
        # 真实代理的IP:PORT 
        proxy_pass http://172.xxx.xxxx.xxx:8200;
        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_connect_timeout 300; #代理连接web超时时间
        proxy_send_timeout 600; #web回传数据至代理超时时间
        proxy_read_timeout 600; #代理等待web响应超时时间


        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";

        proxy_cache off;
        proxy_buffering off;
    }


    location /zhiexa/prompt/api/v1 {
        # 真实代理的IP:PORT 
        proxy_pass http://172.xxx.xxxx.xxx:8009/zhiexa/prompt/api/v1;
        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_connect_timeout 300; #代理连接web超时时间
        proxy_send_timeout 300; #web回传数据至代理超时时间
        proxy_read_timeout 300; #代理等待web响应超时时间


        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";

        proxy_buffering on; #开启代理缓冲区,web回传数据至缓冲区,代理边收边传给客服端
        proxy_buffer_size 32k; #代理接收web响应的头部信息的缓冲区大小
        proxy_buffers 4 128k; # 缓冲代理接收单个长连接内包含的web相应的数量和大小
    }

}

配置完成后 重启 NGINX ,或者重新加载配置文件即可 。

# 检查配置文件 是否存在语法错误
nginx -t 

# 重新加载配置文件
nginx -s reload 

参考文档

Nginx 官方文档 ngx_http_geo_module

Nginx 官方文档

Nginx 核心模块文档

Nginx 变量说明

Nginx 开发从入门到精通

分享快乐,留住感动. '2025-03-22 07:52:42' --frank
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值