iptables应用(五)—优化及其他

2017年12月7日18:19:46iptables应用(五)—优化及其他已关闭评论 560 views

第1章 iptables优化

提示:参考博文:http://blog.51cto.com/oldboy/1336488

1.1 内核基础优化

1.1.1 修改内核配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
[root@centos6 ~]# vim /etc/sysctl.conf
# ------------解决time-wait过多-------------
net.ipv4.tcp_fin_timeout = 2
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_max_tw_buckets = 36000
# ----------------------------------
net.ipv4.ip_local_port_range = 4000  65000
net.ipv4.tcp_max_syn_backlog = 16384
net.ipv4.route.gc_timeout = 100
net.ipv4.tcp_syn_retries = 1
net.ipv4.tcp_synack_retries = 1
# ----------------------------------
net.nf_conntrack_max = 25000000
net.netfilter.nf_conntrack_max = 25000000
net.netfilter.nf_conntrack_tcp_timeout_established = 180
net.netfilter.nf_conntrack_tcp_timeout_time_wait = 120
net.netfilter.nf_conntrack_tcp_timeout_close_wait = 60
net.netfilter.nf_conntrack_tcp_timeout_fin_wait = 120

1.1.2 错误分析

【问题现象】:

1
2
[root@centos6 ~]# dmesg
ip_conntrack: table full, dropping packet.

【原因分析】:

最大追踪文件数达到了上线,所以报错。

【解决办法】:

1
2
3
[root@centos6 ~]# vim /etc/sysctl.conf
net.nf_conntrack_max = 25000000
net.netfilter.nf_conntrack_max = 25000000

第2章 附录

2.1 iptables防火墙计数器说明

如何统计某个应用的网络流量(包括网络流入量和网络流出量)问题,可以转换成如何基于端口号进行网络流量统计的问题。大部分网络应用程序都是传输层及以上的协议,因此基于端口号(tcp,udp)统计网络流量基本能覆盖到此类需求。

2.1.1 iptables防火墙模拟测试环境

利用iptables实现基于端口的流量统计是一种比较简单可行的方案,它可以对流经每一条规则的包数量和流量进行计数。例如要对常规的Web服务器进行流量统计,可以设置如下规则:

1
2
[root@centos6 ~]# iptables -A INPUT -p tcp --dport 80
[root@centos6 ~]# iptables -A OUTPUT -p tcp --sport 80
  • 命令说明:
  1. 第一条规则表示在INPUT链上添加一条规则,该条规则对所有来自外部网络的、与本机80端口通信的请求有效,即网络流入量
  2. 第二条规则相反,它用于统计从本机80端口发出的网络流量,即网络流出量
提示:因为我们的目的是统计流量,故此处可以省略ACCEPT或DROP之类的动作。

2.1.2 iptables防火墙查看测试结果

查看流量计数时只要加上-nvx参数即可:

1
2
3
4
5
6
7
8
9
10
11
[root@centos6 ~]# iptables -nvx -L
Chain INPUT (policy ACCEPT 96 packets, 8240 bytes)
    pkts      bytes target     prot opt in     out     source        destination        
      47     4598            tcp  --  *      *       0.0.0.0/0     0.0.0.0/0           tcp dpt:80

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
    pkts      bytes target     prot opt in     out     source        destination        

Chain OUTPUT (policy ACCEPT 73 packets, 17523 bytes)
    pkts      bytes target     prot opt in     out     source        destination        
      42    13151            tcp  --  *      *       0.0.0.0/0     0.0.0.0/0           tcp spt:80
  • 命令说明:
  1. -vx:详细信息,可以以字节为单位显示包数量和网络流量,
  2. -n:以数字方式表示ip地址和端口号等

2.1.3 iptables防火墙技术统计应用

利用iptables规则统计网络流量可以保证应用在关闭重启后统计数据不丢失,但是对于主机重启的情况就无能为力了,因为默认情况下主机重启iptables规则会清空,即使使用刚开机任务等方式重建iptables规则,流量计数器也会清零。解决此类问题一个变通的方法是定期将网络流量值保存到文件并清零重新计数,定期更新的时间越短,机器重启造成的流量计数丢失问题影响越小(特别涉及计费相关的业务)。

创建一个crontab任务,定期执行流量统计脚本,例如:

1
2
[root@centos6 ~]# crontab -e
*/5 * * * * /bin/bash /server/scripts/nginx_count.sh &>/dev/null
  • 直接将流量值追加到文件:
1
/sbin/iptables -nvxL | sed -n '1p;3p;8p;$p' | awk '{print $2}'
  • 写入文件后将流量清零:
1
[root@test ~]# iptables -Z
  • 编写脚本:
1
2
3
4
5
[root@centos6 ~]# vim /server/scripts/nginx_count.sh
#!/bin/bash
/bin/date +%F_%T >> /tmp/nginx_count.log
/sbin/iptables -nvxL | sed -n '1p;3p;8p;$p' | awk '{print $2}' >> /tmp/nginx_count.log
iptables -Z

2.2 写一个脚本解决DOS攻击

2.2.1 提示

根据web日志或者网络连接数监控当某个IP并发连接数或者短时间内PV达到100,即调用防火墙命令封掉对应的IP,监控频率每隔3分钟,防火墙命令为:

1
iptables -I INPUT -s 10.0.1.10 -DROP

2.2.2 思路

  • 取到IP和IP访问次数
  • 统计IP访问次数是否大于100
  • 执行防火墙命令

2.2.3 编写脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#!/bin/bash
[ -f /etc/init.d/functions ] && ./etc/init.d/functions

function ipt() {
    awk '{print $1}' /server/scripts/access.log | sort | uniq -c | sort -nr -k1 > /tmp/tmp/log
  exec < /tmp/tmp.log
  while read line
    do
      IP=`echo $line|awk '{print $2}'`
      if [ `echo $line|awk '{print $1}'` -gt 100 -a `iptables -nL | grep "$IP" | wc -l` -lt 1 ];then
        iptables -I INPUT -s $IP -j DROP
        RETVAL=$
        if [ $RETVAL -eq 0 ];then
            action "iptables -I INPUT -s $IP -j DROP" /bin/true
            echo "$IP" >> /tmp/ip_$(date + %F).log
        else
          action "iptables -I INPUT -s $IP -j DROP" /bin/false
        fi
      fi
    done
}
   
function del() {
    exec < /tmp/ip_$(date + %F -d '-1day').log
    while read line
    do
      if [ `iptables -nL | grep "$line" | wc -l` -ge 1 ];then
        iptables -D INPUT -s $line -j DROP
      fi
    done
}

main () {
    flag=0
    while true
    do
      sleep 180
      ((flag++))
      ipt
      [ $flag -ge 480 ] && del && flag=0  # 表示480*180秒,一天后删除封的IP地址信息
    done
}

main
weinxin
我的微信
如果有技术上的问题可以扫一扫我的微信