Nginx IP授权页面实现步骤

目标:

一、创建白名单文件

sudo mkdir -p /usr/local/nginx/conf/whitelist
sudo touch /usr/local/nginx/conf/whitelist/temporary.conf

二、创建Python认证服务

文件路径:/opt/script/auth_server.py

import os
import time
from flask import Flask, request, abort
import sys

app = Flask(__name__)

# 配置参数
USERS = [
    {"username": "admin1", "password": "111111"},
    {"username": "admin2", "password": "222222"}
]
TEMP_CONF = "/usr/local/nginx/conf/whitelist/temporary.conf"
IP_LOG = "/usr/local/nginx/conf/whitelist/ip_time.log"  # 存储IP和添加时间

def update_whitelist():
    """更新临时白名单文件"""
    current_time = time.time()
    valid_ips = []
    
    # 读取所有IP并过滤过期项
    if os.path.exists(IP_LOG):
        with open(IP_LOG, "r") as f:
            for line in f.readlines():
                parts = line.strip().split()
                if len(parts) == 2:
                    ip, timestamp = parts
                    if current_time - float(timestamp) < 7200:  # 2小时=7200秒
                        valid_ips.append(ip)
    
    # 生成新的白名单配置
    with open(TEMP_CONF, "w") as f:
        for ip in set(valid_ips):  # 去重
            f.write(f"allow {ip};\n")
    
    # 重载Nginx
    os.system("sudo /usr/local/nginx/sbin/nginx -s reload")

@app.route('/auth', methods=['POST'])
def auth():
    # 获取客户端提交的凭证
    submitted_user = request.form.get('user')
    submitted_pass = request.form.get('pass')

    # 验证用户名密码 - 支持多个账号
    authenticated = False
    for user in USERS:
        if submitted_user == user["username"] and submitted_pass == user["password"]:
            authenticated = True
            break

    if not authenticated:
        abort(401)
    
    # 获取真实客户端IP
    client_ip = request.headers.get('X-Real-IP', request.remote_addr)
    
    # 记录IP和当前时间戳
    with open(IP_LOG, "a") as f:
        f.write(f"{client_ip} {time.time()}\n")
    
    # 更新白名单文件
    update_whitelist()
    
    return "认证成功!您的IP已加入白名单,有效期2小时。", 200

if __name__ == '__main__':
    if len(sys.argv) > 1 and sys.argv[1] == "update":
        update_whitelist()
    else:
        app.run(host='127.0.0.1', port=5000)

三、创建登录页面

文件路径:/usr/local/nginx/html/auth.html




    访问授权


    

请输入管理员凭据



四、配置Nginx

nginx.confhttp块内添加:

server {
    listen 80;
    server_name your_domain.com;  # 改为你的域名或IP

    # 授权页面
    location = /auth.html {
        alias /usr/local/nginx/html/auth.html;
    }

    # Python认证服务代理
    location = /auth {
        proxy_pass http://127.0.0.1:5000/auth;
        proxy_set_header X-Real-IP $remote_addr;  # 传递真实IP
    }

    # 需要保护的资源
    location /protected {
        if ($whitelist = 0) {
            return 302 /auth.html;  # 重定向到登录页
        }
        
        # 这里放被保护的内容(例如反向代理)
        # proxy_pass http://your_backend;
    }
}

五、设置定时清理任务

创建清理脚本:/usr/local/nginx/scripts/clean_whitelist.py

#!/usr/bin/env python3
import os
import time
import sys

IP_LOG = "/usr/local/nginx/conf/whitelist/ip_time.log"

def main():
    # 读取并过滤过期IP
    valid_entries = []
    current_time = time.time()
    
    if not os.path.exists(IP_LOG):
        return
    
    with open(IP_LOG, "r") as f:
        for line in f:
            parts = line.strip().split()
            if len(parts) == 2:
                ip, timestamp = parts
                if current_time - float(timestamp) < 7200:  # 保留未过期IP
                    valid_entries.append(line)
    
    # 更新日志文件
    with open(IP_LOG, "w") as f:
        f.writelines(valid_entries)
    
    # 调用认证服务更新白名单
    os.system("sudo /usr/bin/python3 /usr/local/nginx/scripts/auth_server.py update")

if __name__ == '__main__':
    main()

 添加cron任务

# 添加cron任务
sudo crontab -e
# 每10分钟检查一次
*/10 * * * * /usr/bin/python3 /opt/script/clean_whitelist.py

六、启动服务

启动Python认证服务:

sudo pip3 install flask
sudo -b nohup python3 auth_server.py > /var/log/auth_server.log 2>&1

重载Nginx配置:

sudo /usr/local/nginx/sbin/nginx -s reload

七、验证功能

  1. 访问 http://your_domain.com/protected

  2. 将被重定向到登录页

  3. 输入用户名 admin1 和密码 111111

  4. 成功后:

    • 你的IP会被添加到 temporary.conf

    • 可访问 /protected 资源

    • 2小时后IP自动删除

注意

# 确保所有脚本有执行权限
chmod +x /opt/script/*.py

你可能感兴趣的:(Nginx IP授权页面实现步骤)