用 xiuno 搭建了一个用来专门做笔记的论坛,主要看上它可以 web 端访问,手机也可以随时查阅,搜索可以标题搜索,也可以内容搜索。
放在腾讯云上面,在腾讯云的后台防火墙设置了 ip 白名单可以访问,但是现在想分享给认识的人也能访问也不想完全开放到互联网,但是又不想被一堆机器人扫描,因为目前我有个服务器为了做企业微信的验证,开放 80 端口,就一堆扫描爆破,只能通过记录日志,把那些 ip 拉入防火墙黑名单,黑名单容量有限还要定期删除一部分
另外我曾经建个自己用的 phpwind 论坛开放互联网访问,结果一堆机器人在上面发乱七八糟的广告信息
为了给某人访问,给他添加防火墙白名单也很麻烦,虽然可以通过腾讯云的 api 添加,但是一个人还好,人多了就要添加很多条 ip 白名单,而且手机的 ip 地址隔段时间还会变的
因为分享网站链接给别人是在微信上的,如果在 nginx 使用 auth_basic 认证,微信内置浏览器不会弹出输入用户名密码的框,直接显示 401 Authorization Required
目前我有一个想法,现在我有个企业微信,可以自建应用,可以拉朋友进应用里,他只有在应用里点击访问的菜单按钮,应用会接到后台服务器,后台软件会通过 2FA 验证器方式生成一个 6 位的数字(我把有效期设置为两个小时),然后就会生成一个包含验证数字的网址,比如 myxiuno.com/342567 ,后台软件也会用 2FA 验证器以同样的密钥在网站根目录生成一个作为验证的 342567 的文件夹,软件会每两小时重命名验证文件夹 然后 nginx 能否实现检测访问网址的二级目录和网站验证文件夹名字做比较,如果是一样的,那么就 proxy_pass http://127.0.0.1:8888/;#搭建的论坛访问端口 比如访问的网址是 myxiuno.com/342567/?thread-311.htm ,如果网站根目录的验证文件夹名字是 342567 ,那就可以正确访问到 http://127.0.0.1:8888/?thread-311.htm 。 但是如果是 myxiuno.com/?thread-311.htm ,或者验证码过期了 myxiuno.com/652092/?thread-311.htm ,那么就返回 404
我目前是这样写配置的
location / {
root C:\website;
if (-f $request_filename)
{
proxy_pass http://127.0.0.1:8888/;
}
return 404;
}
可是提示错误
nginx: [emerg] "proxy_pass" cannot have URI part in location given by regular expression, or inside named location, or inside "if" statement, or inside "limit_except" block in C:\phpstudy_pro\Extensions\Nginx1.15.11/conf/nginx.conf:275
1
cdlnls 322 天前 via Android
用 lua 脚本去实现比较方便。我有个网站就这么做的,访问一个特定的 url 后,lua 脚本里面获取客户端的 ip ,把 ip 加入到白名单,白名单有效时间几个小时。
xx@opsc:/data/www/lua$ cat save_ip.lua -- save_ip.lua -- 获 取 客 户 端 IP 地 址 local client_ip = ngx.var.remote_addr -- 设 置 shared dictionary 的 名 称 和 键 local dict_name = "ip_dict" local dict_key = client_ip -- 设 置 过 期 时 间 为 3600 秒 ( 1 小 时 ) local expire_time = 28800 -- 将 IP 保 存 到 shared dictionary 并 设 置 过 期 时 间 local ok, err = ngx.shared[dict_name]:set(dict_key, true, expire_time) if not ok then ngx.log(ngx.ERR, "Failed to save IP in dictionary: ", err) ngx.exit(500) end ngx.header.content_type = "text/plain" ngx.say('Added: ', client_ip) ngx.log(ngx.INFO, "IP saved: ", client_ip) xx@opsc:/data/www/lua$ cat check_ip.lua -- check_ip.lua -- -- nginx.conf: lua_shared_dict ip_dict 10m; -- 获 取 客 户 端 IP 地 址 local client_ip = ngx.var.remote_addr -- 设 置 shared dictionary 的 名 称 和 键 local dict_name = "ip_dict" local dict_key = client_ip -- 设 置 白 名 单 , 这 里 假 设 白 名 单 为 一 个 Lua table local whitelist = { ["127.0.0.1"] = true, ["10.10.0.1"] = true, -- 添 加 其 他 白 名 单 IP } -- 检 查 是 否 在 白 名 单 中 if whitelist[client_ip] then ngx.log(ngx.INFO, "IP is in whitelist: ", client_ip) else -- 检 查 shared dictionary 中 是 否 存 在 客 户 端 IP local ip_found = ngx.shared[dict_name]:get(dict_key) -- 如 果 IP 不 存 在 , 则 返 回 403 if not ip_found then ngx.log(ngx.INFO, "IP not found: ", client_ip) ngx.exit(403) end ngx.log(ngx.INFO, "IP found: ", client_ip) end |
2
Vegetable 322 天前
我看你描述了一大堆需求,路子不太对,不过既然已经到了这一步,还是看最后的问题吧
proxy_pass 不能出现在 if 里边,但是你可以通过变量来变相实现这个配置。总结你的需求:如果匹配了,就 proxy_pass ,不匹配就 404 。 一个可行的方案是: set $final_upstream = 必然 404 的地址; if (condition) { $final_upstream = http://127.0.0.1:8888/; } proxy_pass $final_upstream; 这样也会有一些别的限制,nginx 要在启动时解析出所有可能的 upstream ,所以你的 127.0.0.1 或者 404 地址包含域名,就需要动态 dns 。 |
4
colitude OP @cdlnls 谢谢,之前搜索答案的时候也出现过类似 lua 的解决方案,不过我现在用的 phpstudy 里面的 nginx ,找不到怎么开启 lua 模块,以为可以直接通过改 nginx.conf 实现,所以上来问问
另外我的需求确实类似“访问一个特定的 url 后,lua 脚本里面获取客户端的 ip ,把 ip 加入到白名单,白名单有效时间几个小时” |
5
colitude OP @Vegetable 或者说 nginx 能不能读取访问网址 myxiuno.com/342567/?thread-311.htm 中间那个 342567 作为一个变量,然后读取文件名,或者文件名里面的 342567 (这个两小时会更新的)作为另外一个变量做比对
|
6
JaguarJack 322 天前
auth_request 呢?我没试过 Get 转发,你可以让你认证系统内的用户生成一个 token ,然后通过 auth_request 传递 token 到这个页面的认证下?
|