返回
Featured image of post 通过http api添加iptables白名单

通过http api添加iptables白名单

一些服务我们想要暴露在网上,但是互联网上的探测与扫描从未停息过,所以在向公网开放一些敏感的或者是易受攻击的服务时我们需要考虑怎么才能保证安全性。有一种方法就是ip白名单,对于特定的端口,只允许特定的ip访问,这样可以很好的拦截恶意的探测,但是使用ip白名单我们又会面临一个新的问题——如果自己的ip是动态ip,怎么实现动态的添加?为了解决这个问题,我制作了一个通过http请求来添加ip白名单,以及对探测进行记录的小工具。

iptables自助白名单工具——通过http api控制iptables

2021/9/1更新: 添加了反向代理的说明

2021/9/29更新: trigger 参数的说明

一些服务我们想要暴露在网上,但是互联网上的探测与扫描从未停息过,比如之前我部署的一个hadoop,不出一天就被好几个黑客造访了,所以在向公网开放一些敏感的或者是易受攻击的服务时我们需要考虑怎么才能保证安全性。有一种方法就是ip白名单,对于特定的端口,只允许特定的ip访问,这样可以很好的拦截恶意的探测,但是使用ip白名单我们又会面临一个新的问题——如果自己的ip是动态ip,怎么实现动态的添加ip白名单呢?

为了解决这个问题,我制作了一个通过http请求来添加ip白名单,以及对探测进行记录的小工具selfhelp-iptables

使用说明

准备

因为对探测的计数需要能够读取内核日志,我主要只在ubuntu/debian上测试过,centos上可能存在一些问题… centos要用的话请systemctl stop firewalld,仅使用iptables

开始运行后,程序会尝试去寻找iptables的日志文件,并实时读取文件,当文件更新时,实时输出内容。不同系统的日志目录有差异。

在 Ubuntu/debian中,日志位于 /var/log/kern.log 而 centos/rhel中,日志位于 /var/log/messages,理论上程序已经做了判断,当然你也可以把iptables日志记录到单独的文件中,需使用下面的名字

!!!建议不需要修改保存路径

个人尝试,在某些系统下,把日志保存到其他文件中的尝试失败了,所以如果你修改了保存文件后发现iptables.log迟迟没有写入信息,那么删掉这个文件和配置文件中的设置并重新运行程序吧。或者参考此文折腾一下,如果还是不行,就删掉自己新建的文件,使用默认的系统日志文件。

启动参数

当前版本 2.0,./selfhelp-iptables start启动程序,程序有以下参数

启动时参数

# 查看帮助
./selfhelp-iptables start -h
-u, --userkey userkey # 必须 用户添加http api时使用的key
-a, --adminkey adminkey # 必须 通过http进行管理(如添加其他ip、移除白名单、查看日志)等操作时使用的key
-p, --protect port1,port2 # 可选 需要保护的端口
-w --white port1,port2 # 可选 如果不指定 -p, 则会进行全端口保护, 这时作为白名单模式,需要设置放行的端口
-l --listen port # 可选 http服务器监听的端口 默认8080
-d --reject # 当未经授权的ip访问的时候,拒绝连接并返回一个端口不可达的icmp包
-t --threshold n # 可选 一个自动添加白名单的连接次数阈值,当尝试连接n次后,自动添加白名单
--trigger [count]/[seconds] # 包速率触发,当某一ip发超过特定速率时,添加白名单 比如 9/3 代表客户三秒内发送了超过9个包时,为其添加白名单 
-r --autoreset hh|h|hd|d|w # 可选 如果设置了-t,那么可以接着设置自动重置的周期 分别是半小时 每小时 半天 每天 每周
--reverse # 开启反向代理支持(默认关闭)

通过上面的trigger可以在防御扫描的同时,实现基本无感的白名单添加。

总结起来就是两种模式:

  1. 拦截特定端口,放行其他端口
  2. 拦截所有端口,放行特定端口

效果如下:

我尝试使用nmap扫描服务器上的一个端口,只能得到filtered的结果,如果启动时带上了-d选项,那么这里显示的是close。

nmap
nmap

命令行交互模式

启动后进入命令行交互模式,有以下指令可以使用:

  • help 显示帮助
  • add ip 添加白名单
  • list 列出当前添加的ip
  • remove ip 移除一个ip的白名单
  • record 列出所有探测记录
  • reset 重置所有记录

http请求模式

http api 有以下可用

  • 为自己添加白名单

    http://example.com:8080/api/add?key=[你设置的key] 程序会获取访问者的ip,并添加到iptables白名单中。

  • 列出白名单

    http://example.com:8080/api/list?key=[你设置的key]

  • 删除白名单

    http://example.com:8080/api/remove/[要删除的ip]?key=[你设置的key]

  • 查看探测记录

    http://example.com:8080/api/log?key=[你设置的key]

  • 查看探测计数

    http://example.com:8080/api/record?key=[你设置的key]

关于反向代理

2.3.1的更新中添加了反向代理的支持,通过http请求添加白名单时,siw会尝试读取X-Forward-For或者X-Real-IP(优先级最高)中指定的ip,但是考虑到客户端可以修改成任意的Header进行请求,存在一些风险,所以这个功能默认关闭,需要使用--reverse开启,如果是对外开放的服务,请仅在使用可信反向代理的情况下使用,下面是nginx反向代理的例子:

location /api {
  proxy_set_header  X-real-ip $remote_addr;
  proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_pass http://127.0.0.1:8080/api;
}

程序对系统的影响:

该程序的拦截规则是在一条新的链里面进行的,在退出程序后程序会清空这条规则链,所以如果设置错了导致连不上ssh,那么可以尝试使用vnc连接到机器上,ps aux |grep self 找到进程并kill即可。

手动清空规则链:

iptables -D INPUT -j SELF_WHITELIST
iptables -F SELF_WHITELIST
iptables -X SELF_WHITELIST
comments powered by Disqus
本站访客数:
Built with Hugo
Theme Stack designed by Jimmy