我有一个网站,目前是通过路由做了 nat 映射,允许用户通过外网直接访问网站,用户也可以在内网通过访问公网的 IP 来访问这个网站。 现在我想添加一个限制: 用户如果是在外部网络(如果是通过 vpn 也认为是内网)访问这个 web 网站,检查数据库中该用户是否允许通过外网来访问网站,如果允许则放行,不允许则拒绝。 目前我是这样处理的: 1 ) web 后端添加一个 api /auth ,前端在 login 网站前先通过这个 api 的私有地址访问这个 api ,如果访问得到证明这个用户目前在内网,反之在外网。并且将 auth 返回的 token 记录在前端 2 )在执行 /login 的时候,将 token 携带到 login 的请求头, 后端收到这个请求头,如果含有这个 token 就可以判断用户是否在外网了
存在的问题: 由于访问 /auth 用的是私有地址,但访问 web 网站用的是公有 ip ,导致会涉及到跨域访问,目前 chrome 浏览器做了安全限制,需要将私有地址手动的添加到允许访问列表。 但是我们目前想让用户无感,最好用户什么都不需要操作。所以想请问下,是否有其它更好的方案,对用户使用无感的操作,当用户在访问 web 的时候就能准确知道用户是否在内外网,便于下一步的权限控制。
1
Latin 31 天前
nginx 获取用户真实 ip 地址与服务器(内网公网) ip 地址校验
当客户真实 ip 地址和服务器(内网公网) ip 地址相同,此时客户在内网 是否可以这样 |
2
Vraw5 31 天前
内网通过内网 IP 访问,外网通过外网 IP 访问,得到的来源 IP 不同,可以根据来源 IP 做限制。
内网将域名 DNS 解析成内网 IP ,这样来自内网的全部放过,无需判断。如果改不了,内网的出口 IP 一般是固定的,后端默认来自这个公网 IP 的为内网登录,全部放过。 非上述来源 IP 的,登录时判断是否允许外网登录 |
3
kiracyan 31 天前
登陆时,访问一个内网 API ,验证成功就是内网,无法验证就是外网
|
4
N0vermber11 31 天前
听起来像是 vpn 的使用场景
|
5
litchinn 31 天前
从你的问题描述我感觉你是有 PNA 问题,公网访问服务后无法发起请求到/auth 端点,被 chrome 拦截了,所以没法通过这个接口判断
https://www.cnblogs.com/lizhigang/p/18008373 这文章说可以通过 https 解决,但我没试过,不是很了解 楼上说的 ip 过滤也是一种办法 |
6
shuyunquan 31 天前
之前搞过就是 IP 白名单, 内网的 IP 存储起来, 网页写个中间件,凡是请求 IP 不在白名单的统一禁止
|
7
Foxkeh 31 天前
Nginx 反向代理, 加入以下参数定义
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; (不建议用$remote_addr, 这样多层 Nginx 反代后识别到的用户 IP 不准确) 假设是否允许公网登录存储在用户表, 那么在用户登录时, 加入一层逻辑校验: 后端从请求头获取上面的参数, 分析用户 IP, 按照, 内网 IP 放行, 公司的出口 IP 放行, 其他 IP 判断用户是否有外网允许登录标记即可. |
8
supermama OP @Latin 你这种场景只适合企业只有一条专线的情况(用户的 pc 和服务器都是走的专线,两者访问网络的时候都是转化为固定 ip) 。 但是目前我们服务器是固定 ip(专线) ,其它的 pc 用户走的是动态 ip ,以至 pc 用户的外部 ip 一直在变化。 没办法简单的通过这种 ip 相等去判断是否是在内网访问。
|
10
supermama OP @litchinn 是的,目前我就是用这个方案去访问。 最大的问题是,用户第一次要手工点击,允许这个域名访问。 变成第一次需要用户手工介入,将这个域名纳入白名单,后续才能正常使用。
|
11
supermama OP @Foxkeh 你这个方案可行,但是我目前比较特殊: 我的服务器是固定 ip (一个专线)、pc 用户走的另外一根动态 ip 的线。两根线都插在同一个网关,所以两者其实也是属于一个内网。 按你的方法,其实是判断不出来,或者说现在的 pc 用户会被判断成是在外网访问。
|
12
supermama OP @Vraw5 感觉可以,但是这个要怎么配置呢? 我前端是用 vue 写的,一般就是把域名配置到 vue 代码里面去了,访问的时候 dns 动态区分映射出来的 ip 是公网还是私网 ip 。 但如果用户是拿着笔记本一会儿在内网,一会儿在外网要怎么处理。 另外 nginx 那边收到的用户请求是不是都是访问的是域名,而不是访问的 ip ,这个在 nginx 要怎么配置呢?
|
13
Vraw5 31 天前
@supermama #12 域名在代码里正常配置,搭个 DNS 给公司 WIFI(以及 vpn)用,公司 WIFI 用这个 DNS ,这个域名的解析就是内网 IP ,连其他 WIFI 时的解析就是外网 IP 。
nginx 那边可以通过#7 楼的方法获取到真实 IP 并传给后端,后端读 header 能拿到真实 IP 如果搭 DNS 费劲,可以直接禁掉外网登录的需求,全部改为内网登录。在公司的不谈,在外的使用 vpn 连接后访问。这样可以直接让他们在 hosts 里写死解析 |
14
Atma 31 天前 via Android
vpn 那边权限限制
|
15
webszy 31 天前 2
已经有认证了,直接限制登陆用户就行了,何必脱裤子放屁
|
16
catamaran 31 天前
你先理清楚,怎么判断是不是内网用户,如果人脑从逻辑上都区分不了,电脑也起不到啥作用。
|
17
supermama OP @catamaran 你看我正文里面,我是直接去访问 一个 192.168.0.xx/auth 的接口,如果是内网肯定是可以通的,外网不行。 只不是这种会跟我正常的网站 www.xxx.com 访问,会有跨域的冲突,用户需要将 192.168.0.xx 这个 ip 手工加入白名单。我不想让用户手动加白名单这个动作。
|
18
catamaran 31 天前
@supermama #17 所以方案只有你说的这种。如果是问题是跨域访问,有成熟的方案,像以前的 jsonp ,或者 http head 做一些限制(我不是很了解这块)。我不明白你说的这个白名单指什么?是在浏览器配置里操作吗?
|
19
xinzhanghello 31 天前
cf WAF + static html apply + IP whitelist
|
20
NSAgold 31 天前 via Android
cors 跨域我记得有个 access-control-allow-credentials 是可以带 cookie 的
或者内网 DNS 把内网访问 ip 解析成服务器内网 ip 然后 nginx 内外网不同策略处理 再或者你给 token 的接口挪到主站来,内网地址负责 302 到这个接口,外网访问用户没有 302 访问不到这个接口 |
21
chobitssp 31 天前
做个 electron 应用(也可以是别的) 让客户先安装 前端通过应用判断是否内网
|
22
lisongeee 30 天前
私有网络访问限制 https://developer.chrome.com/blog/private-network-access-update?hl=zh-cn
最无感的方式是买个域名后控制台解析 A 记录到 192.168.0.xx ,申请 ssl 证书,直接用 https 访问 你的现有操作都是在 http 上下文,它就是有很多限制,直接升级到 https 就完了呗 |
23
cat1879 30 天前
我以前弄类似的,感觉你这个需求和我当年类似。我这个是内网不限制,外网访问时加个扫码或者 auth 的认证。认证的 IP 允许一段时间进行访问
|