分类: 网络与安全
2011-04-15 17:57:22
使用iptable模块进行安全设置
state模块
此模块过滤连接状态,如果设置了全局INPUT DROP的话,以下规则是必须的。
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
此规则能跟踪已产生的连接并允许接收,没有此规则当前连接会被全局规则drop。
注意:远程在一个未设置防火墙的机器上运行iptables -P INPUT DROP的话ssh的输入将立刻中断,必须在配置所有防火墙规则前设置
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
设置了上面规则后,NEW状态(新发起的连接)还未被允许, 新发起的http,ssh等是无法连接的,所以需要给指定端口允许NEW状态:
比如:
iptables -A INPUT -m state --state NEW -p tcp -m multiport --dport 21,22,25,80,110 -j ACCEPT
此规则允许ftp pop3 http ssh smtp的NEW状态,也就是接入(其实不要前面的-m state就可以了,这样写可以阻止一个TCP连接的不明状态,由于ssh和ftp端口都要做连接尝试限制,所以这个规则里不要写ssh和ftp的端口)
限制模块limit(以下规则设置前都设置了全局drop规则),经尝试limit是针对所有IP的
这样设置了无法ping入,所以需要设置ping允许,可以设置高级模块控制ping次数
iptables -A INPUT -p icmp --icmp-type echo-request -m limit --limit 1/s --limit-burst 2 -j ACCEPT
允许1秒ping一次,--limit-burst 2表示允许超过峰值2-1=1次
由于limit是针对所有IP的,如果限制太低,2~3台windows机器ping丢弃的包就很多了,可以设高点,也可以向下面SSH设置一样配置分别配置单独IP与所有IP限制。
由于22端口开放会被人反复测试账号,加入防火墙限制(如果使用此规则,前面的NEW允许规则要去掉22端口,如果前面的规则被匹配后面阻止就没用了)
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m limit --limit 5/m --limit-burst 6 -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -j LOG --log-level "debug" --log-prefix " [SSHLIMIT] "
NEW状态22端口连接限制为5次每分钟,超过就被记录并丢弃。针对所有IP,也就是说其他人发起多个连接,所有IP都会被禁止登陆1分钟。
也可以使用recent模块如下规则
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --set --name SSH
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 60 --hitcount 8 --rttl --name SSH -j DROP
第一条规则给给每个连入22端口,状态为NEW的包增加一个名字为SSH的标记
第二条规则设置每分钟接收到超过8个状态为NEW,端口为22的包后就丢弃,不超过进入下一条(所以后面没有允许操作而是全局drop的话ssh还是无法接收NEW包)
这个规则能针对单个IP而不是所有IP进行限制
尝试综合上面两个规则(全局drop规则)
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --set --name SSH
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 600 --hitcount 10 --rttl --name SSH -j \
LOG --log-level "debug" --log-prefix " [TESTIP] "
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 600 --hitcount 10 --rttl --name SSH -j DROP
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m limit --limit 40/m --limit-burst 45 -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -j LOG --log-level "debug" --log-prefix " [SSHATKIP] "
对于所有IP,SSH连接次数1分钟40次,单个IP 10分钟内能连接10次,单个IP测试成功,超过10次正常阻止,40次上限未设置,实际使用中次数还要做调整。
owner模块
此模块可以过滤指定用户或者用户组的外联。经过测试,这里owner为进程的运行使用的用户,也就是说root是肯定需要允许的(SSH守护进程用户是root),所以output的默认设置不适合做全局drop。可以用来阻止特定程序的数据外流,比如禁止mysql端口数据流出到外网
比如:
iptables -A OUTPUT -o eth0 -m owner --uid-owner 27 -j DROP //阻止外网网卡eth0获取mysql(uid27)用户进程数据
iptables -A OUTPUT -s ! 192.168..1.44 -m owner --uid-owner 27 -j DROP
输出丢弃除了192.168.1.44外所有27用户——也就是mysql进程的外流数据。这样可以让指定ip得到mysql的数据。
测试好的规则,实现ping 1秒15次限制(所有IP),ssh连接限制(单个IP十分钟5次,所有IP每分钟30次并以不同的日志头记录),25、80、110端口无限制,其他端口阻止。由于允许RELATED,所以所有端口的反弹连接是被允许的。
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -m state --state NEW -p tcp -m multiport --dport 25,80,110 -j ACCEPT
iptables -A INPUT -p icmp --icmp-type echo-request -m limit --limit 15/s --limit-burst 20 -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --set --name SSH
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 600 --hitcount 10 --rttl --name SSH -j LOG --log-level "debug" --log-prefix " [TESTIP] "
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 600 --hitcount 5 --rttl --name SSH -j DROP
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m limit --limit 30/m --limit-burst 45 -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -j LOG --log-level "debug" --log-prefix " [SSHATKIP] "
iptables -P INPUT DROP
iptables -A FORWARD -i eth1 -m connlimit --connlimit-above 30 -j REJECT
iptables -A FORWARD -i eth1 -s 192.168.1.0/24 -j ACCEPT
测试好的规则,实现ping 1秒15次限制(所有IP),ssh连接限制(单个IP十分钟5次,所有IP每分钟30次并以不同的日志头记录),25、80、110端口无限制,其他端口阻止。由于允许RELATED,所以所有端口的反弹连接是被允许的。
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -m state --state NEW -p tcp -m multiport --dport 25,80,110 -j ACCEPT
iptables -A INPUT -p icmp --icmp-type echo-request -m limit --limit 15/s --limit-burst 20 -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --set --name SSH
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 600 --hitcount 10 --rttl --name SSH -j LOG --log-level "debug" --log-prefix " [TESTIP] "
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 600 --hitcount 5 --rttl --name SSH -j DROP
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m limit --limit 30/m --limit-burst 3 -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -j LOG --log-level "debug" --log-prefix " [SSHATKIP] "
iptables -P INPUT DROP
iptables -A FORWARD -i eth1 -m connlimit --connlimit-above 30 -j REJECT
iptables -A FORWARD -i eth1 -s 192.168.1.0/24 -j ACCEPT
攻击防御
iptables -A INPUT -p tcp --tcp-flags SYN,ACK SYN,ACK -m state --state NEW -j REJECT --reject-with tcp-reset
禁止序列号预测,禁止包头标记SYN,ACK同时存在,但是状态确为NEW的包
封锁QQ——包括阻止QQ使用代理、web代理登陆。
iptables -t nat -A PREROUTING -i eth1 -s 192.168.1.2 -j ACCEPT //不转特定IP的目标地址,此处为squid代理服务器
iptables -t nat -A PREROUTING -i eth1 -p tcp --dport 80 -d ! 192.168.1.1 -j DNAT --to 192.168.1.2:3180
//将所有非本机80端口请求转发到squid代理服务器端口,允许防火墙本机IP的80端口请求
iptables -t nat -A PREROUTING -i eth1 -p tcp --dport 53 -j DNAT --to 192.168.1.2:53
iptables -t nat -A PREROUTING -i eth1 -p udp --dport 53 -j DNAT --to 192.168.1.2:53
//将所有非本机53端口请求转发到本地DNS服务器,由于用了透明代理转发了目标地址dns会被代理服务器做二次查询,自己架设个dns比较快。
iptables -A FORWARD -i eth1 -d 192.168.1.2 -j ACCEPT //允许内网用户的请求被转发到代理服务器(由于前面只转发了80和53端口,所以内网用户只有这两端口被转发)
iptables -A FORWARD -i eth1 -s 192.168.1.2 -j ACCEPT //允许特定IP无限制,此处为squid代理服务器
iptables -A FORWARD -i eth1 -m connlimit --connlimit-above 25 -j REJECT //限制连接数限制为25
iptables -P FORWARD DROP //全局转发禁止,不转发非squid服务器的IP
iptables -t nat -A POSTROUTING -o eth1 -s 192.168.1.2 -j ACCEPT //不转特定IP源地址
iptables -t nat -A POSTROUTING -o eth1 -p tcp --dport 53 -j SNAT --to192.168.1.1
//将DNS请求IP伪装成防火墙IP,否则真实IP的请求将无法返回
iptables -t nat -A POSTROUTING -o eth0 SNAT --to 外网IP
然后在squid代理服务器上做设置阻止QQ服务器IP(包括web QQ服务器)。
新版带raw表的iptable图,最左边是内核route,上面是网络入口route,下面是出口route。