Nginx实践--安全升级
之前写了一些nginx的东西,这次继续,主要使用upstream针对proxy_pass转发做个处理
一般情况下我们在使用nginx反向代理的时候,都是如下配置,
...
location /api {
proxy_pass https://b.test.com; # 设置代理服务器的协议和地址
proxy_cookie_domain b.test.com a.test.com; # 修改cookie,针对request和response互相写入cookie
}
...
这样就实现了'/api'目录接口的转发。功能是实现了,但是有什么问题么?还真有!
如果我们可以反向代理,如果别人也知道了我们的接口域名也不是可以自己搭一个nginx服务器就可以代理到我们的接口服务器上去???是不是感觉很危险,是的。。。对此当时做的时候就加了一个临时方案,在接口服务中添加一个ip白名单,白名单中的ip都是nginx服务器的ip,然后就项目上线了。这样也实现了需求,但ip如果被伪造了怎么办?于是我们想到了另一个方案,使用内网IP代替对外开放的域名,这样在一定程度上就直接拦截了外部的直接访问,具体实现如下,
upstream apiServer {
server 10.10.10.10.:8888
}
...
location /api {
proxy_pass http://apiServer;
proxy_cookie_domain apiServer a.test.com;
}
...
我们使用upstream定义了一个apiServer的组,将转发都指向这里,这时相当于我们把可能存在的用户直接访问接口服务器的可能给关闭了,也就是途中红色的那部分危险操作~~
可能你会想upstream的使用纯属多余,的确当apiServer只有一台机器的时候,这个的确可以不用,但是多台机器的时候,虽然proxy_pass虽然可以定义多条但是太麻烦了。。。使用upstream组统一管理即可,同时使用upstream还有一些优势比如给多个server设置负载均衡,upstream组中支持通过weight参数来设置当前server在负载均衡中所占的比重,此外还可以通过设置backup参数指定某些服务器作为备份机等等。详细的配置内容还是建议大家参考Nginx upstream官方文档。
此外,除了安全性方面,使用内网ip进行接口转发也省去了转发中的DNS重新解析的过程,有利于大幅提升接口转发效率。同时若不想破坏已经做好的SLB的话,也可以不使用upstream,直接转发到SLB服务器的内网ip应该也是可以的。
综上,在proxy_pass转发中我们使用了两种方案来对安全性做一些提升
- proxy_pass转发到外网域名,同时在接口服务器上添加访问来源白名单,把nginx服务器的ip写进去
- proxy_pass转发到内网域名,多服务器的话使用upstream统一管理并实现负载均衡,也能提升转发效率
第二种方案是不是通用的呢?这样可行的话,我们的接口服务器是不是都不用设置外网可访问的域名了呢?
第二种方案是可以通用的,但是这不意味着我们就可以抛弃外部可访问的域名,因为在一个落地业务中,比如第三方授权、微信支付等情况下外部可访问域名还是必须要有的。因此只有那些不需要与第三方进行通信,比如仅供公司内部使用的管理系统等,就可以直接抛弃外网域名了。此时个人建议就是上面两种方案结合一下:
- proxy_pass的转发使用内网ip,来提升转发效率,同时对外部访问添加白名单,只暴露需要和第三方通信的接口即可。
这样在安全和效率高上就都能得到一定的提升。
如有错误,欢迎大家指正
好好学习,天天向上~~
此处添加一个修正,最初版原文中在proxy_pass后面我们使用了https+upstream的方式进行转发,但是在生产环境上发现使用https出现服务器502网关问题。
...
location /api {
proxy_pass https://apiServer;
proxy_cookie_domain apiServer a.test.com;
}
...
考虑到内网ip访问,不需要https,于是我们把https换成了http,问题解决。