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 sysapp = 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 = partsif 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")# 重载Nginxos.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 = Falsefor user in USERS:if submitted_user == user["username"] and submitted_pass == user["password"]:authenticated = Truebreakif not authenticated:abort(401)# 获取真实客户端IPclient_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小时。", 200if __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
<!DOCTYPE html>
<html>
<head><title>访问授权</title>
</head>
<body><h2>请输入管理员凭据</h2><form action="/auth" method="POST"><label>用户名: <input type="text" name="user"></label><br><label>密码: <input type="password" name="pass"></label><br><button type="submit">授权我的IP</button></form>
</body>
</html>
四、配置Nginx
在nginx.conf
的http块内添加:
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 sysIP_LOG = "/usr/local/nginx/conf/whitelist/ip_time.log"def main():# 读取并过滤过期IPvalid_entries = []current_time = time.time()if not os.path.exists(IP_LOG):returnwith open(IP_LOG, "r") as f:for line in f:parts = line.strip().split()if len(parts) == 2:ip, timestamp = partsif current_time - float(timestamp) < 7200: # 保留未过期IPvalid_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
七、验证功能
访问
http://your_domain.com/protected
将被重定向到登录页
输入用户名
admin1
和密码111111
成功后:
你的IP会被添加到
temporary.conf
可访问
/protected
资源2小时后IP自动删除
注意
# 确保所有脚本有执行权限
chmod +x /opt/script/*.py