简介
iptables功能十分丰富,它能够对网关下带客户端的上网行为进行有效的控制,下面介绍如何利用它的string模块来对客户端的上网行为进行控制。
string模块是iptables的一个扩展模块,目前大多数系统都已集成了该模块,少数较老的openwrt路由如果没有的话,可通过opkg命令安装。
应用场景
部署于基于Linux操作系统的网关上,可以是路由器,也可以是挂于旁路的防火墙、审计系统,只要可收集到客户端的上网流量即可。
保护客户端数据安全,避免被某些无底线的互联网公司收集个人数据。
屏蔽令人不适的广告。
操作命令示范
如果要屏蔽一个具体的网站,具体思路是让防火墙匹配客户端请求的数据包中的关键字,然后将该包丢弃,使客户端放弃连接。
比如百度地图在定位的同时会收集当前IP地址所对应的物理位置。美名其曰收集地理位置提供更好的服务,实则令人厌烦,暴露了用户的行踪,时常有人代理服务器IP被定位到自家门口的情况。该API目前已关闭,然而不仅仅是百度地图,其他某些地图厂家也会这么干。而客户端向百度上报自己地点的数据包会携带相应的域名,即HTTP请求的Host头部(api.map.baidu.com和map.baidu.com),基于此原理即可将域名作为关键词来进行匹配。
iptables -I FORWARD 1 -p tcp -m multiport --dports 80,443 -m tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG PSH,ACK -m string --string "api.map.baidu.com" --algo bm -j REJECT --reject-with tcp-reset
iptables -I FORWARD 1 -p tcp -m multiport --dports 80,443 -m tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG PSH,ACK -m string --string "map.baidu.com" --algo bm -j REJECT --reject-with tcp-reset
客户端的数据经由网关发出时,经过的是FORWARD链,所以应在它上面配置规则,multiport模块用于匹配多端口。即使它使用了SSL来传输数据,通过443端口传送时,我们仍然能从其中Client Hello数据包内的server_name(SNI)字段得知请求的主机名。这样,即使传输内容虽已加密,但是请求的主机名是明文传送的,iptables仍可以通过这一点来进行匹配。--tcp-flags可以更精确地匹配不同状态的数据包,避免错杀,若无额外配置该选项,则很可能将baidu的其他业务也屏蔽。--algo bm是匹配算法,默认是使用bm,当然也有较为复杂的kmp算法。最后的--reject-with tcp-reset较为重要的作用是将连接重置,令客户端无法与服务器建立连接。
当然,这个操作已经将整个百度地图的服务全部屏蔽,客户端无法通过该局域网使用百度地图。而实际情况,我们常在室外(LTE网络)使用它,在室内基本是用不到的。
题外话
对于防火墙来说,通过返回TCP RST数据包给客户端来达到终止客户端的连接是非常合适的,因为在TCP/IP协议中,RST包是用来关闭异常的连接的,客户端一旦收到该数据包,将会立即关闭对主机的连接,不再尝试重连,应用会发出“连接已重置”或者"Connection reset by peer"的错误提示。而若将REJECT改为DROP,防火墙则是默默地丢弃数据包,不明真相的客户端迟迟未收到服务器回应,会多次发包尝试重连,防火墙则必须多次丢弃该数据包。因此REJECT与DROP相比,前者对防火墙的资源消耗少,显然采取它是明智的,这也与某些ISP的网络审计和过滤系统原理是类似的。
防火墙被设计出来的目的就是为了保证内部网络的安全,将关键词过滤这一功能统一部署于网关将给防火墙后的客户端带来极大的方便和安全性,可以阻止无底线公司上传用户敏感数据,屏蔽流氓软件广告推送等等。
评论