技术解析

如何让 nginx 在 https 握手前就判断并阻断黑名单 IP 连接
0
2021-05-21 01:54:58
idczone
使用 if ( $remote_addr = x.x.x.x ){ return 444; }和 deny x.x.x.x,都不行,都会先握手。
抗投诉服务器
但是就是连握手也不想让它握,怎么做。
不能设置防火墙,因为还有同 IP:443 下还有别的虚拟主机
iptables

没看到不能防火墙,无视吧

没办法,你不让人家说话怎么知道要说什么

在对方第一次 TCP 跟自己的说话的时候就判断它的 IP 是否在黑名单
因为需要隐藏源站 IP,但是对方可以带上 host 穷举,我如果跟他握手了。把自己的有效证书发出去了,就相当于告诉对方我就是源站了

nginx 在应用层 而你需要的功能在传输层 无解

哦,简单,写个 nginx 模块来搞定。

握手的时候 并不知道他的目标域名是哪个

隐藏源站 IP 的话,在源站设置只允许 cdn 访问呀,其他的 ip 直接干掉

不要老从 nginx 考虑 , 防火墙直接设置只允许白名单不就行了嘛

在 https 握手前就判断并阻断黑名单 IP 连接
这个问题有有点奇怪,他没握手你怎么知道他这个连接是否在黑名单
而且还有同 IP:443 下还有别的虚拟主机,反正我个人感觉有点矛盾,可能是我技术不到家。

这个问题比较奇怪,你既然阻止与 ng 握手,那干嘛还在 ng 上做限制,试试别的想法

我先猜测一下你的需求:你的网站隐藏在 CloudFlare 之类 CDN/抗 D 服务的背后,希望只对 CDN 的白名单内 IP 开放服务。
理论上是可行的,需要在 SNI 的部分做处理,但是我简单查了一下 Nginx 的 SNI 是让 openssl 处理的,好像没有现成的配制方法。建议用另外端口、IP 的方式做处理。
另外端口:这个网站不开在 443,而是 4430 之类其他端口,用防火墙处理限制,然后设置 CDN 的源站为非标准端口;
另外 IP:同一台机器能加 IP 的话那就直接用新 IP+防火墙;否则假如是 VPS 的话,开一台新的小鸡做个转发,把新机器的 443 转发到老机器的 4430,然后同上


nginx 开启 SNI(RFC 6066)拓展之后,可以在 tls client hello 这一步就知 server name。
查了一圈应该没有留这种接口出来,硬是要这么做的话改 nginx 源码写拓展吧。

仔细想了想要是跟 nginx 这个层面的话用 Netfilter 做一个就好了,不过要做额外的协议解析工作,只是不要让 nginx 完成这个发送证书应该就算是成功了








我猜测你们可能没有完全理解 LZ 的想法,或者有一些知识遗漏。
现在支持同一个 IP 开多个 HTTPS 网站的 SNI,是会在请求的最开始加上想要访问的域名的;所以同一个 IP、同一个端口,在握手前实现 IP 黑白名单是做得到的;效果就是该 IP 能访问同一 IP 的其它域名,但是访问指定域名就握手失败,看起来像该 IP 上没有架设指定网站。
(跑个题,这一步是明文的,所以在中国大陆,部分 https 网站上不去,也是在这一步被 XX )


http://nginx.org/en/docs/http/configuring_https_servers.html
In order to use SNI in nginx, it must be supported in both the OpenSSL library with which the nginx binary has been built as well as the library to which it is being dynamically linked at run time.
看起来是把很多工作交给 openssl 库了

你都不让握手 Nginx 怎么判断要访问哪个主机呢?判断不了只能全不让访问了呗,iptables...

那我也想问个问题,如何探测站源的 ip,以前没了解过这方面。

看错了,以为是 tcp 的握手...无视我吧

https://github.com/Lochnair/xt_tls
把这个编辑进 iptables,然后配合源 IP 限制就好了,不会影响其他域名

貌似,openResty 可解。本贴右侧有链接。


是的,这个是 TLS 那层的事,所以丢给 openssl 处理这么做设计上来说没什么问题。
要实现这种需求估计只能魔改 nginx 了,在把数据转发到 bio 之前解析 client hello 取出 server name 然后再判断写入到 bio 还是关闭这个链接……真是太 hack 了。

对的,理解有偏差。一说握手就本能的反应到 tcp 的握手去了。lz 的这个情况应该是在 ssl 的握手环节来处理

楼上都说 SSL 握手,个人觉得不是。LZ 的主要目的,就是为了爬虫访问的时候,能防止网站证书外泄。
如果严格控制 SNI 的走的路径,是可以在 ClientHello 阶段,就直接阻断的。

嗯,第一反应是 TCP 握手就阶段,后来想了想只要证书不发送即可

你的需求是 tcpwrapper
但不知道 nginx 是否支持这个

楼主可以说下解决思路以及解决方法啊

还是计算机基础没有学好。

nginx 单独可能不行,deny、return 貌似都是证书验证以后才执行
nginx 前面放 haproxy 之类的应 i 该可以解决

写一个 ssl 的 default server,里面配一个假证书,这样 nginx 在 SNI 过程中如果没有找到对应主机名的配置就会返回这个证书

正解,这么简单的需求用 OpenResty 几行 Lua 代码就搞定了,可以在握手前就断开连接,也不会发送证书。
https://github.com/openresty/lua-nginx-module/>https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl.md#raw_client_addr

这么简单的话就不会这么多公司被 ddos 了

openResty 试试, 写点 LUA 脚本

据我所知 ddos 用 cdn 挡不住的,目前我们客户都是直接防火墙或者安全组做源站保护白名单地址,你源站 ip 直接在 4 层 deny 了怎么会有这个问题呢,莫非有其他需求,希望楼主解答一下

补充一下,目前就是做抗 d 和 cc,,就说网站业务,cdn 基本没用,要干你直接打到回源,也许根本没法跑,waf 和抗 d 基本都是网络创业的买路费,很多客户被打的莫名其妙的也没收到勒索

数据地带为您的网站提供全球顶级IDC资源
在线咨询
专属客服