iptables如何学习
有了基本的基础再多动手自己添加规则,自己测试,边测试边查资料,同时学习和测试各个模块的使用,慢慢就会越来越熟悉。
icmp协议
icmp是基于ip协议的,但不是tcp和udp
参考文章:https://erg.abdn.ac.uk/users/gorry/course/inet-pages/icmp-code.html
Echo Reply (0), Echo Request (8), Redirect (5), Destination Unreachable (3), Traceroute (30), Time Exceeded (11).
回显请求和回显应答
// 8表示回显请求,服务器设置如下规则之后,本机ping服务器,将会显示请求超时,服务器对本机的ping回显应答请求会DROP,不回显
iptables -A INPUT -p icmp --icmp-type 8 -j DROP
// 0表示回显应答,服务器设置如下规则之后,服务器ping百度服务器,将什么都不显示,百度服务器本来会回复我的服务器,但是被我DROP
iptables -A INPUT -p icmp --icmp-type 0 -j DROP
Redirect (5) 指示主机向其发送数据报的网关不再是到达有关网络的最佳网关。网关将已经转发数据报,但是主机应该修改它的路由表,为这个网络有一个不同的直接地址。
Destination Unreachable (3)意思就是ping一台服务器,但是不存在,路由器或下一跳都找不到,路由器会回复不可达的信息。
Traceroute (30) Time Exceeded (11) 它的工作原理是发送ICMP echo (ICMP类型为“8”)消息到相同的目的地,并增加TTL (time-to-live)字段的值。当TTL字段变为0时,traceroute路径上的路由器返回ICMP Time Exceeded (ICMP type '11')。
Time Exceeded (11) ICMP Time Exceeded消息通知主机,当它发送的数据包因为“超时”而被丢弃时。数据包实际上并没有计时,但是为了防止数据包在路由环路中被永远转发,每个IP数据包报头都包含一个TTL (Time to Live)字段。
打印日志
iptables -A INPUT -p tcp -m tcp --dport 22 -m state --state NEW -m recent --set --name SSH
iptables -A INPUT -p tcp -m tcp --dport 22 -m state --state NEW -m recent --update --seconds 12 --hitcount 3 --name SSH -j LOG --log-prefix 'iptables-attack: ' --log-ip-options
iptables -A INPUT -p tcp -m tcp --dport 22 -m state --state NEW -m recent --update --seconds 12 --hitcount 3 --name SSH -j DROP
如果使用Ubuntu1804,日志会打印在/var/log/kern.log,其中 --log-ip-options 会显示远程的ip和mac地址
查看日志:tail -n 10 /var/log/kern.log | grep iptables-attack
模块使用
iptables -m 选项可以使用模块进行更高级的限制,很多模块都是内核自带的,不需要特别安装,如果没有这些模块,应该需要更新内核或者自己编译,
以下使用的模块都是Ubuntu1804内核4.15.0自带的,如果不是自带的会特别说明
tcp模块 使用该模块可以指定端口
//默认policy DROP,设置之后所有进入的包都会DROP,ping也ping不通,仅可以ssh访问
iptables -P INPUT DROP
iptables -A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
//不允许 ssh 连接
iptables -A INPUT -p tcp -m tcp --dport 22 --syn -j DROP
multiport模块
该模块可以同时指定多个端口
//以下规则,如果不是访问22,80,443这三个端口的,都DROP
iptables -A INPUT -p tcp -m multiport ! --dports 22,80,443 -j DROP
state模块
这个模块太重要了,该模块的牛逼之处就是可以放行回应报文,回应报文就是先由我们主机发出去的请求,然后服务器做出回应。如果是服务器想连接我们,则不行。
参考资料:https://kb.novaordis.com/index.php/Iptables_State_Module
该模块配合policy DROP很完美。
connlimit 该模块限制连接数
//以下命令限制ssh连接的个数
//注意参数 --connlimit-mask 0 表示所有ip一共只能连10个,如果去掉该参数表示,单个ip只能连10个
//注意参数 --syn 这个表示tcp握手的一些标识,如果不加该参数表示一共只能连10个(包括当前已有的连接),如果加了该参数表示还可以再连10个没问题
iptables -A INPUT -p tcp --syn --dport 22 -m connlimit --connlimit-above 10 --connlimit-mask 0 -j DROP
recent模块
//该模块用来限制连接频率,相当于节流,并不会封禁ip
//以下命令允许12秒内最多允许连接3次,如果还想连,等一会儿即可
iptables -A INPUT -p tcp -m tcp --dport 22 -m state --state NEW -m recent --set --name SSH
iptables -A INPUT -p tcp -m tcp --dport 22 -m state --state NEW -m recent --update --seconds 12 --hitcount 3 --name SSH -j DROP
总结
对于web服务器,主要是用来给别人访问,而不是访问别人,使用iptables检查的内容应该是:
0、policy 默认规则,最后执行 INPUT DROP、FORWARD DROP、OUTPUT ACCEPT
1、blacklist 先检查全局黑名单,在黑名单内的直接DROP
2、port-right 访问本机暴露的端口,进入各个端口的处理链,需要指定网卡
3、respond 回应报文全部放行
4、lo 发给本地回环网卡的直接放行
5、port-wrong 访问本机未暴露的端口,进入黑名单
注意点:如果iptables规则过于复杂,占用资源也较大,所以应该出一个复杂规则和一个简单规则。
复杂规则
0、policy 默认规则,最后执行 INPUT DROP、FORWARD DROP、OUTPUT ACCEPT
1、blacklist 建立全局黑名单链,黑名单链只有一条规则,进入该链的添加进黑名单表并DROP,数据包进入先检查是否在全局黑名单,在黑名单内的直接DROP并且打印日志,否则进入下面规则
2、port-right 3条INPUT规则分别监听https、http、ssh端口(ssh端口应该自己设定不用22),数据包进入分别交给3个链处理:
2-1、处理https
2-1-1、判断是新连接还是已建立的连接,如果是已建立的连接,进入已建立链(意味着已经知道如何连通了),否则进入新连接链
2-1-2、已建立链处理规则:如果连接数超出进入黑名单;如果发送频率超出进入黑名单,发送频率参考SSL建立连接的流程
2-1-2、新连接链处理规则:如果发送频率超出进入黑名单
2-2、处理http,http 80 端口一般用于跳转到443端口,一般在输入域名打开首页的时候会跳转,频率不高
2-2-1、判断是新连接还是已建立的连接,如果是已建立的连接,进入已建立链(意味着已经知道如何连通了),否则进入新连接链
2-2-2、已建立链处理规则:如果连接数超出进入黑名单;如果发送频率超出进入黑名单
2-2-2、新连接链处理规则:如果发送频率超出进入黑名单
2-3、处理ssh,直接对指定的ip开放ssh白名单,其他ip统统禁止,省事儿又安全
3、respond 回应报文全部放行 ,一条规则即可
4、lo 发给本地回环网卡的直接放行,一条规则即可
5、port-wrong 访问本机未暴露的端口,进入黑名单,一条规则即可
(注:ssh客户端在vim粘贴的每个字符,移动的每次光标都会发报文给服务器,会影响已建立连接的频率统计,所以如果已经登录,就不需要处理)
(注:http、https可以放一块儿处理)
(注:如果想限制网速,限制流量,直接可以通过限制INPUT频率来限制,基本是一样的)
(注:如果黑客知道了你的频率限制,可能会在允许频率内,进行最大的连接,虽然这样没啥意义,解决该问题我想可以使用两个频率限制)
简单规则
0、policy 默认规则,最后执行 INPUT DROP、FORWARD DROP、OUTPUT ACCEPT
1、blacklist 建立全局黑名单链,黑名单链只有一条规则,进入该链的添加进黑名单表并DROP,数据包进入先检查是否在全局黑名单,在黑名单内的直接DROP,否则进入下面规则
2、port-right 2条INPUT规则分别监听https+http、ssh端口(ssh端口应该自己设定不用22),数据包进入分别交给2个链处理:
2-1、处理https+http,如果发送频率超出进入黑名单,发送频率参考SSL建立连接的流程;
2-2、处理ssh,直接对指定的ip开放ssh白名单,其他ip统统禁止,省事儿又安全
3、respond 回应报文全部放行 ,一条规则即可
4、lo 发给本地回环网卡的直接放行,一条规则即可
5、port-wrong 访问本机未暴露的端口,进入黑名单,一条规则即可