柴少鹏的官方网站 技术在分享中进步,水平在学习中升华

iptables详解(二)

http://www.51niux.com/?id=100  #这里已经对iptables的基础知识和基本使用进行了记录,但是只是记录了一个简单的filter表的操作,这里会对其他表以及其他的操作做一些记录。

一、使用一些模块举例

1.1 connlimit模块举例:

iptables -I INPUT 1 -s 192.168.1.109 -p tcp -m tcp --dport 22 -m connlimit ! --connlimit-above 2 -j ACCEPT 
iptables -I OUTPUT 1 -d 192.168.1.109 -p tcp -m tcp --sport 22  -j ACCEPT

#这里是允许192.168.1.109的ssh访问,允许2个连接,因为如果取反的话就是小于等于后面的数,就会匹配到ACCEPT,不匹配ACCETP就相当于拒绝。

iptables -I INPUT 1  -p tcp --dport 80 -m connlimit  --connlimit-above 3 -j DROP

#这就是限制80端口的tcp连接为3次,这里--connlimit-above 3 就是当连接次数大于3次的时候,就会匹配到后面的不给予应答操作。

1.2 state、icmp、multiport、tcp、udp和iprange模块前面已经举例了,也是常用的,这里就不举例了。

1.3 mac模块举例:

iptables -I OUTPUT 1  -p tcp --sport 22 -m mac --mac-source 00:0c:29:fe:d7:f3 -j ACCEPT

#上面的例子是让来源mac地址是:00:0c:29:fe:d7:f3 的请求可以进入,由于只有一个来源mac选项,所以我们要么在OUTPUT方向就不要做限制,要么就开放此端口的的OUTPUT请求。同时就不能用-s选项来指定来源IP了。也不能指定多mac。一是这样会比IP的形式更保险一点,二呢办公网只有等级了mac地址才能获得dhcp服务啊上网啊等操作,当然其他的设备和软件也能完成此操作,前提是mac地址已经批量在你手里了,想用iptables批量来操作一下的话。

1.4 string模块举例:

iptables -I INPUT -m string --algo kmp --string "test" -j DROP

#上面是对访问名称带有test关键字的文件不给予应答

iptables -I OUTPUT -m string --algo kmp --string "h6n5" -j DROP

#上面是在出上面做限制,如果文件中包含有关键字“h65n",这个文件就不会应答。这样可以做到让哪些带有敏感关键字的网页不给予应答。但是这样做的话会大大影响网页的相应效率。当一旦并发高,网页内容过多的时候,那响应是很慢的。

博文来自:www.51niux.com

1.5 limit模块举例:

这个主要是来限制包的数量的,限制一个速率,如:'/second', '/minute', '/hour', or'/day',如1小时要限制三个包,就是3/hour或者3/h,但是这是从我们的角度,如果是同iptables的计算角度呢,就是每20分钟允许1个包。下面用一个ping测试来验证一下:

iptables -I INPUT 1  -p icmp  -m limit --limit 6/m --limit-burst 3 -j ACCEPT

#上面的意思是用了limit模块,--limit 6/m每10秒钟通过一个包,--limit-burst 3  这里是前三个包是正常的,如果不加--limit-burst这个选项的话默认是5个包,从第六个包开始进入限速模式。

#但是这种限速要注意,这是全局性的,因为这里没有加来源IP什么的,所以iptables就会认为从四个包开始之后,每10秒中只允许进入1个包,所以当有好几个机器同时ping我们这台机器的时候,每10秒只有一台机器能够ping通一次。

 ping 192.168.1.108 | awk '{ print $0"\t" strftime("%Y-%m-%d %H:%M:%S",systime())}'

#上面是用ping打印时间的形式,来查看一下结果,限速是否生效,下面是测试截图:

图片.png

1.6 hashlimit模块举例

上面那个limit模块说过了,不会根据来源IP做判断对包做限速,这个模块就显得更加灵活了,而且选项更多。

iptables -I INPUT -p icmp -m hashlimit --hashlimit-name icmp-ping --hashlimit 6/m --hashlimit-burst 3 --hashlimit-mode srcip --hashlimit-htable-expire 90000 -j ACCEPT

#这里用到了hashlimit模块,--hashlimit-name icmp-ping 定义了此条规则的名称为icmp-ping然后就会产生/proc/net/ipt_hashlimit/icmp-ping的记录文件,--hashlimit 6/m 就相当于--hashlimit-upto 6/m这里是每10秒钟允许通过一个包,--hashlimit-burst 3就是三个包之后开始触发前面的限速模式,--hashlimit-mode srcip 就是针对源IP来做hash管理即每一个来源IP就是一个匹配项,--hashlimit-htable-expire 90000  #这就相当于一个倒计时时间,90000为90000毫秒,即是90S,就是如果在90S内没有在触发的话,又恢复成最初的状态。

图片.png

#观察记录文件发现前面的秒数是一致在减少的。

# cat /proc/net/ipt_hashlimit/icmp-ping
81 192.168.1.109:0->0.0.0.0:0 270208 960000 320000

#81 就是剩余秒数,如果没有新的触发就会一致减到0.

#192.168.1.109:0->0.0.0.0:0  这里是srcip:port->dstip:port,这里mode值设置了srcip

#270208 是剩余的令牌数

#960000是令牌桶最大容量,是一个定值

#320000是一次触发使用的令牌数,也是令牌产生速率,也是一个定值。

博文来自:www.51niux.com

二、目标扩展举例

2.1 LOG扩展

通常情况下,iptables的默认政策为DRIO,不匹配的数据包将被直接丢弃。不过可以在丢弃之前将记录记录下来,或者我们自己定义规则记录,可以判断是否有人尝试攻击我们的服务器或者有一些其他的违规操作。

iptables -I INPUT 1 -p icmp -j LOG --log-prefix "icmp-drop:"

#前面我们已经做了禁ping操作,这里引入了LOG的扩展,其中有一个选项--log-prefix "icmp-drop:"就是给内容加前缀,前缀为:icmp-drop:

默认记录在/var/log/message中,下面让我们看一下记录的日志内容:

Apr  9 14:17:59 master kernel: icmp-drop:IN=eth0 OUT= MAC=00:0c:29:d5:d2:5e:00:0c:29:fe:d7:f3:08:00 SRC=192.168.1.109 DST=192.168.1.108 LEN=84 TOS=0x00 PREC=0x00 TTL=64 ID=0 DF PROTO=ICMP TYPE=8 CODE=0 ID=9235 SEQ=1
#字段1:Apr  9 14:17:59 为日期时间,由rsyslog产生。

#字段2:master 为主机名称

#字段3:kernel 进程名由rsyslogd生成kernel为内核产生的日志说明netfilter在内核中运行

#字段4: icmp-drop:  这就是我们定义的输出前缀方便区分。

#字段5:IN=eth0 为数据报进入的接口名称,若为空说明此包是本机产生

#字段6:OUT= 数据报流出的接口,若为空说明是本机接收或者就没有流出

#字段7:MAC=00:0c:29:d5:d2:5e:00:0c:29:fe:d7:f3中00:0c:29:d5:d2:5e为目标mac地址,00:0c:29:fe:d7:f3为来源mac地址

#字段8:08:00 为上层协议代码,这里表示IP协议

#字段9:SRC=192.168.1.109 为来源IP地址

#字段10:DST=192.168.1.108 为目标地址

#字段11:LEN=84 IP封包+承载数据的总长度(MTU)

#字段12:TOS=0x00 IP包头内的服务类型字段,能反应服务质量包括延迟、可靠性和拥塞等

#字段13:PREC=0x00 服务类型的优先级字段

#字段14:TTL=64 IP数据报的生存时间

#字段15:ID=0 IP数据报标识

#字段16:DF DF表示不分段,此字段还可能为MF/FRAG

#字段17:PROTO=ICMP 传输层的协议类型

#字段18:TYPE=8 CODE=0 ID=9235 SEQ=1 当协议是ICMP时出现

如果要记录22端口的错误连接呢,当然这里没有必要。ssh本身就会有记录哪些连接失败了。

iptables -I INPUT 1 -p tcp ! -s 192.168.1.101 --dport 22 -j LOG --log-prefix "ssh-drop:"

#要将允许通过的IP去掉,不然正确的ssh记录也会记录的。

Apr  9 14:44:20 master kernel: ssh-drop:IN=eth0 OUT= MAC=00:0c:29:d5:d2:5e:00:0c:29:a8:33:98:08:00 SRC=192.168.1.112 DST=192.168.1.108 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=59830 DF PROTO=TCP SPT=59525 DPT=22 WINDOW=14600 RES=0x00 SYN URGP=0
#这里有些字段跟上面的ICMP有些不一样

#SPT=59525 表示源端口,DPT=22表示目标端口,WINDOW=14600 是IP包头内的窗口大小, RES=0x00 是保留值,CWR/ECE/URG/ACK/PSH/RST/SYN/FIN 这些都是TCP的标志位,如果通过了SSH连接这里的标志位就不是syn而是ACK了,URGP=0  是紧急指针起点。

既然记录日志了,日志肯定是要单独记录了啊,下面是设置iptables日志的设置:

# vim /etc/rsyslog.conf

kern.warning                                            /var/log/iptables.log

# /etc/init.d/rsyslog restart 

前面我们不是做了iptables的敏感词过滤和请求文件的限制吗,这里也可以结合到一起记录日志:

iptables -I INPUT 1 -m string --algo kmp --string "test" -j LOG --log-prefix "http-drop:"
iptables -I OUTPUT 1 -m string --algo kmp --string "h6n5" -j LOG --log-prefix "http-mingan-drop:"

#这些LOG记录条件都要在DROP限制条件的上方,因为它本身并不具备限制条件,如果在DROP下方,都已经匹配完了就不会再跳到LOG这条规则上了。

图片.png

博文来自:www.51niux.com

2.2 DNAT和SNAT扩展

DNAT就是根据目标地址和端口进行地址和端口的转发,好多设备上面也具有这个功能,很常见的应用场景就是我们大部分的机器是内网地址,然后我们想远程访问的话,就需要有一个有公网地址的服务器来充当这台中转站,他会根据我们目标地址和端口进行判断,把请求发送到对应的内网机器中去。SNAT:源地址转换,是Linux防火墙的一种地址转换操作,也是iptables命令中的一种数据包控制类型,其作用是根据指定条件修改数据包的源IP地址。SNAT策略只能用在nat表的POSTROUTING链中,使用iptables命令编写SNAT策略时,需要结合“--to-source  IP地址”选项来指定修改后的源IP地址。

下面是一条,模拟找一台有公网的中转机,做80端口转发的举例:

echo 1 > /proc/sys/net/ipv4/ip_forward 
iptables -t nat -A PREROUTING -p tcp -d 192.168.1.108 --dport 81  -j DNAT --to-destination 192.168.1.109:80
iptables -t nat -A POSTROUTING -d 192.168.1.109 -p tcp --dport 80 -j SNAT --to 192.168.1.108

#第一条是内核的转发功能

#第二条是, -A PREROUTING -p tcp -d 192.168.1.108 --dport 81 就是在进入路由表之前进行判断目标地址地址是192.168.1.108(本机)目标端口是81的,-j DNAT 进行目标地址转发操作,--to-destination 192.168.1.109:80 转发到192.168.1.109的80端口上面去。

#第三条是在出方向做设置,-A POSTROUTING -d 192.168.1.109 -p tcp --dport 80 将目标地址是192.168.1.109的目标端口是80的数据报,-j SNAT --to 192.168.1.108将本机IP转化为本机IP地址。

下面是效果图:

图片.png#我在192.168.1.109的index.html页面里面插入了这个内容方便区分判断。

下面是一条模拟代理上网,防火墙做网段的设置:

echo 1 > /proc/sys/net/ipv4/ip_forward  #开启转发
iptables -t nat  -D POSTROUTING 1   #这条没有必要写,刚才实验成功了,我这里将此条规则删除再来添加一次。因为是指定了表删除规则所以记录下。
iptables -t nat -I POSTROUTING -s 192.168.233.0/24 -o eth0 -j SNAT --to-source 192.168.1.108

#第三条,这里呢192.168.233段属于内网IP段默认是不能上网的,192.168.1.108这台机器是可以上网的,同时192.168.1.108也有一个内网IP是192.168.233.2,然后所有内网段的机器把网关指向到192.168.233.2,就可以上网了。-o eth0这就代表数据从eth0网卡出去,如果是 -i eth1就代表从eth1网卡进入的数据,如果不加就默认所有的网卡接口。这里注意如果转发只有IP没有端口的话就默认指的是所有端口进行转发。

下面是192.168.1.108未添加防火墙转发前的内网机器测试结果:

图片.png

下面是192.168.1.108添加了防火墙转发之后的内网机器的测试结果:

图片.png

紧接着上面的再举一个例子,现在我们所有内网的都已经可以连接外网了,但是呢我们想对它不同的用途做些限制,比如,我们让其ssh的连接不管指向某个网段的ssh端口,最终都连接到某一个机器,当然对外转发到内部也可以这么玩。

iptables -t nat -I PREROUTING -p tcp -i eth1 -d 192.168.1.0/24 --dport 22  -j DNAT --to-destination 192.168.1.109:22

#因为我们的eth1是内网网卡接口,假设192.168.1.0是我们的公网段,我们让内网网卡进入的数据的22端口请求,请求192.168.1.0这个段的请求,都给转发到192.168.1.109的22端口上面去。下面是测试结果:

图片.png

这些只是iptables的一小部分的功能,iptables的自定义规则链(iptables -N),recent模块抵御DOS攻击啊等其他的一些网络攻击啊,FORWARD限制转发行为啊,ip_conntrack实现报文跟踪啊(如ftp这种随机端口的服务就需要用到报文跟踪来开启防火墙),mangle表的使用,MASQUERADE对于adsl上网的设置,等还有好多好多,埋个坑,以后有机会在记录吧。现在的这些已经够日常大部分的操作了。

作者:忙碌的柴少 分类:防火墙 浏览:2857 评论:0
留言列表
发表评论
来宾的头像