nginx 可以通过二级目录进行用户验证吗

95 天前
 colitude
  1. 用 xiuno 搭建了一个用来专门做笔记的论坛,主要看上它可以 web 端访问,手机也可以随时查阅,搜索可以标题搜索,也可以内容搜索。

  2. 放在腾讯云上面,在腾讯云的后台防火墙设置了 ip 白名单可以访问,但是现在想分享给认识的人也能访问也不想完全开放到互联网,但是又不想被一堆机器人扫描,因为目前我有个服务器为了做企业微信的验证,开放 80 端口,就一堆扫描爆破,只能通过记录日志,把那些 ip 拉入防火墙黑名单,黑名单容量有限还要定期删除一部分

  3. 另外我曾经建个自己用的 phpwind 论坛开放互联网访问,结果一堆机器人在上面发乱七八糟的广告信息

  4. 为了给某人访问,给他添加防火墙白名单也很麻烦,虽然可以通过腾讯云的 api 添加,但是一个人还好,人多了就要添加很多条 ip 白名单,而且手机的 ip 地址隔段时间还会变的

  5. 因为分享网站链接给别人是在微信上的,如果在 nginx 使用 auth_basic 认证,微信内置浏览器不会弹出输入用户名密码的框,直接显示 401 Authorization Required

  6. 目前我有一个想法,现在我有个企业微信,可以自建应用,可以拉朋友进应用里,他只有在应用里点击访问的菜单按钮,应用会接到后台服务器,后台软件会通过 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. 请问我上面设想的功能能否通过 nginx 实现,如果能实现是我上面配置写的有问题吗,应该怎么修改
1398 次点击
所在节点    NGINX
6 条回复
cdlnls
95 天前
用 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
Vegetable
95 天前
我看你描述了一大堆需求,路子不太对,不过既然已经到了这一步,还是看最后的问题吧

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 。
colitude
95 天前
@Vegetable if (condition) 这个 condition 要怎么写
colitude
95 天前
@cdlnls 谢谢,之前搜索答案的时候也出现过类似 lua 的解决方案,不过我现在用的 phpstudy 里面的 nginx ,找不到怎么开启 lua 模块,以为可以直接通过改 nginx.conf 实现,所以上来问问
另外我的需求确实类似“访问一个特定的 url 后,lua 脚本里面获取客户端的 ip ,把 ip 加入到白名单,白名单有效时间几个小时”
colitude
95 天前
@Vegetable 或者说 nginx 能不能读取访问网址 myxiuno.com/342567/?thread-311.htm 中间那个 342567 作为一个变量,然后读取文件名,或者文件名里面的 342567 (这个两小时会更新的)作为另外一个变量做比对
JaguarJack
94 天前
auth_request 呢?我没试过 Get 转发,你可以让你认证系统内的用户生成一个 token ,然后通过 auth_request 传递 token 到这个页面的认证下?

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1013953

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX