iptables
iptables首先需要了解的:
1)规则概念
规则(rules)其实就是网络管理员预定义的条件,规则一般的定义为“如果数据包头符合这样的条件,就这样处理这个数据包”。规则存储在内核空间的信息 包过滤表中,这些规则分别指定了源地址、目的地址、传输协议(如TCP、UDP、ICMP)和服务类型(如HTTP、FTP和SMTP)等。
当数据包与规则匹配时,iptables就根据规则所定义的方法来处理这些数据包,如放行(accept),拒绝(reject)和丢弃(drop)等。配置防火墙的主要工作是添加,修改和删除等规则。
其中:
匹配(match):符合指定的条件,比如指定的 IP 地址和端口。
丢弃(drop):当一个包到达时,简单地丢弃,不做其它任何处理。
接受(accept):和丢弃相反,接受这个包,让这个包通过。
拒绝(reject):和丢弃相似,但它还会向发送这个包的源主机发送错误消息。这个错误消息可以指定,也可以自动产生。
目标(target):指定的动作,说明如何处理一个包,比如:丢弃,接受,或拒绝。
跳转(jump):和目标类似,不过它指定的不是一个具体的动作,而是另一个链,表示要跳转到那个链上。
规则(rule):一个或多个匹配及其对应的目标。
2)iptables和netfilter的关系:
Iptables和netfilter的关系是一个很容易让人搞不清的问题。很多的知道iptables却不知道 netfilter。其实iptables只是Linux防火墙的管理工具而已,位于/sbin/iptables。真正实现防火墙功能的是 netfilter,它是Linux内核中实现包过滤的内部结构。
3)iptables的规则表和链
表(tables):提供特定的功能,iptables内置了4个表,即filter表、nat表、mangle表和raw表,分别用于实现包过滤,网络地址转换、包重构(修改)和数据跟踪处理。
链(chains):是数据包传播的路径,每一条链其实就是众多规则中的一个检查清单,每一条链中可以有一 条或数条规则。当一个数据包到达一个链时,iptables就会从链中第一条规则开始检查,看该数据包是否满足规则所定义的条件。如果满足,系统就会根据 该条规则所定义的方法处理该数据包;否则iptables将继续检查下一条规则,如果该数据包不符合链中任一条规则,iptables就会根据该链预先定 义的默认策略来处理数据包。
Iptables采用“表”和“链”的分层结构,在Linux中现在是四张表五个链。下面罗列一下这四张表和五个链(注意一定要明白这些表和链的关系及作用)。
规则表:
1)filter表——三个链:INPUT、FORWARD、OUTPUT
作用:过滤数据包 内核模块:iptables_filter.
2)Nat表——三个链:PREROUTING、POSTROUTING、OUTPUT
作用:用于网络地址转换(IP、端口) 内核模块:iptable_nat
3)Mangle表——五个链:PREROUTING、POSTROUTING、INPUT、OUTPUT、FORWARD
作用:修改数据包的服务类型、TTL、并且可以配置路由实现QOS内核模块:iptable_mangle(别看这个表这么麻烦,咱们设置策略时几乎都不会用到它)
4)Raw表——两个链:OUTPUT、PREROUTING
作用:决定数据包是否被状态跟踪机制处理 内核模块:iptable_raw
规则链:
1)INPUT——进来的数据包应用此规则链中的策略
2)OUTPUT——外出的数据包应用此规则链中的策略
3)FORWARD——转发数据包时应用此规则链中的策略
4)PREROUTING——对数据包作路由选择前应用此链中的规则
(记住!所有的数据包进来的时侯都先由这个链处理)
5)POSTROUTING——对数据包作路由选择后应用此链中的规则
(所有的数据包出来的时侯都先由这个链处理)
管理和设置iptables规则:
4)iptables传输数据包的过程
1)当一个数据包进入网卡时,它首先进入PREROUTING链,内核根据数据包目的IP判断是否需要转送出去。
2)如果数据包就是进入本机的,它就会沿着图向下移动,到达INPUT链。数据包到了INPUT链后,任何进程都会收到它。本机上运行的程序可以发送数据包,这些数据包会经过OUTPUT链,然后到达POSTROUTING链输出。
3)如果数据包是要转发出去的,且内核允许转发,数据包就会如图所示向右移动,经过FORWARD链,然后到达POSTROUTING链输出。
如果还是不清楚数据包经过iptables的基本流程,再看下面更具体的流程图:
从图中可将iptables数据包报文的处理过程分为三种类型:
1)目的为本机的报文
报文以本机为目的地址时,其经过iptables的过程为:
1.数据包从network到网卡
2.网卡接收到数据包后,进入raw表的PREROUTING链。这个链的作用是在连接跟踪之前处理报文,能够设置一条连接不被连接跟踪处理。(注:不要在raw表上添加其他规则)
3.如果设置了连接跟踪,则在这条连接上处理。
4.经过raw处理后,进入mangle表的PREROUTING链。这个链主要是用来修改报文的TOS、TTL以及给报文设置特殊的MARK。(注:通常mangle表以给报文设置MARK为主,在这个表里面,千万不要做过滤/NAT/伪装这类的事情)
5.进入nat表的PREROUTING链。这个链主要用来处理 DNAT,应该避免在这条链里面做过滤,否则可能造成有些报文会漏掉。(注:它只用来完成源/目的地址的转换)
6.进入路由决定数据包的处理。例如决定报文是上本机还是转发或者其他地方。(注:此处假设报文交给本机处理)
7.进入mangle表的 INPUT 链。在把报文实际送给本机前,路由之后,我们可以再次修改报文。
8.进入filter表的 INPUT 链。在这儿我们对所有送往本机的报文进行过滤,要注意所有收到的并且目的地址为本机的报文都会经过这个链,而不管哪个接口进来的或者它往哪儿去。
9. 进过规则过滤,报文交由本地进程或者应用程序处理,例如服务器或者客户端程序。
2)本地主机发出报文
数据包由本机发出时,其经过iptables的过程为:
1.本地进程或者应用程序(例如服务器或者客户端程序)发出数据包。
2.路由选择,用哪个源地址以及从哪个接口上出去,当然还有其他一些必要的信息。
3.进入raw表的OUTPUT链。这里是能够在连接跟踪生效前处理报文的点,在这可以标记某个连接不被连接跟踪处理。
4.连接跟踪对本地的数据包进行处理。
5.进入 mangle 表的 OUTPUT 链,在这里我们可以修改数据包,但不要做过滤(以避免副作用)。
6.进入 nat 表的 OUTPUT 链,可以对防火墙自己发出的数据做目的NAT(DNAT) 。
7.进入 filter 表的 OUTPUT 链,可以对本地出去的数据包进行过滤。
8.再次进行路由决定,因为前面的 mangle 和 nat 表可能修改了报文的路由信息。
9.进入 mangle 表的 POSTROUTING 链。这条链可能被两种报文遍历,一种是转发的报文,另外就是本机产生的报文。
10.进入 nat 表的 POSTROUTING 链。在这我们做源 NAT(SNAT),建议你不要在这做报文过滤,因为有副作用。即使你设置了默认策略,一些报文也有可能溜过去。
11.进入出去的网络接口。
3)转发报文
报文经过iptables进入转发的过程为:
1.数据包从network到网卡
2.网卡接收到数据包后,进入raw表的PREROUTING链。这个链的作用是在连接跟踪之前处理报文,能够设置一条连接不被连接跟踪处理。(注:不要在raw表上添加其他规则)
3.如果设置了连接跟踪,则在这条连接上处理。
4.经过raw处理后,进入mangle表的PREROUTING链。这个链主要是用来修改报文的TOS、TTL以及给报文设置特殊的MARK。(注:通常mangle表以给报文设置MARK为主,在这个表里面,千万不要做过滤/NAT/伪装这类的事情)
5.进入nat表的PREROUTING链。这个链主要用来处理 DNAT,应该避免在这条链里面做过滤,否则可能造成有些报文会漏掉。(注:它只用来完成源/目的地址的转换)
6.进入路由决定数据包的处理。例如决定报文是上本机还是转发或者其他地方。(注:此处假设报文进行转发)
7.进入 mangle 表的 FORWARD 链,这里也比较特殊,这是在第一次路由决定之后,在进行最后的路由决定之前,我们仍然可以对数据包进行某些修改。
8.进入 filter 表的 FORWARD 链,在这里我们可以对所有转发的数据包进行过滤。需要注意的是:经过这里的数据包是转发的,方向是双向的。
9.进入 mangle 表的 POSTROUTING 链,到这里已经做完了所有的路由决定,但数据包仍然在本地主机,我们还可以进行某些修改。
10.进入 nat 表的 POSTROUTING 链,在这里一般都是用来做 SNAT ,不要在这里进行过滤。
11.进入出去的网络接口。
接下来说下iptables规则设置用法
1)iptables的基本语法格式
iptables [-t 表名] 命令选项 [链名] [条件匹配] [-j 目标动作或跳转]
说明:
表名、链名:用于指定iptables命令所操作的表和链;
命令选项:用于指定管理iptables规则的方式(比如:插入、增加、删除、查看等;
条件匹配:用于指定对符合什么样 条件的数据包进行处理;
目标动作或跳转:用于指定数据包的处理方式(比如允许通过、拒绝、丢弃、跳转(Jump)给其它链处理。
2)iptables命令的管理控制选项
-A 在指定链的末尾添加(append)一条新的规则
-D 删除(delete)指定链中的某一条规则,可以按规则序号和内容删除
-I 在指定链中插入(insert)一条新的规则,默认在第一行添加
-R 修改、替换(replace)指定链中的某一条规则,可以按规则序号和内容替换
-L 列出(list)指定链中所有的规则进行查看(默认是filter表,如果列出nat表的规则需要添加-t,即iptables -t nat -L)
-E 重命名用户定义的链,不改变链本身
-F 清空(flush)
-N 新建(new-chain)一条用户自己定义的规则链
-X 删除指定表中用户自定义的规则链(delete-chain)
-P 设置指定链的默认策略(policy)
-Z 将所有表的所有链的字节和数据包计数器清零
-n 使用数字形式(numeric)显示输出结果
-v 查看规则表详细信息(verbose)的信息
-V 查看版本(version)
-h 获取帮助(help)
3)防火墙处理数据包的四种方式ACCEPT 允许数据包通过
DROP 直接丢弃数据包,不给任何回应信息
REJECT 拒绝数据包通过,必要时会给数据发送端一个响应的信息。
LOG在/var/log/messages文件中记录日志信息,然后将数据包传递给下一条规则
4)iptables防火墙规则的保存与恢复
iptables-save把规则保存到文件中,再由目录rc.d下的脚本(/etc/rc.d/init.d/iptables)自动装载
使用命令iptables-save来保存规则。
一般用:
iptables-save > /etc/sysconfig/iptables
生成保存规则的文件/etc/sysconfig/iptables,
也可以用:
service iptables save
它能把规则自动保存在/etc/sysconfig/iptables中。
当计算机启动时,rc.d下的脚本将用命令iptables-restore调用这个文件,从而就自动恢复了规则。
5)iptables防火墙常用的策略梳理
设置默认链策略
ptables的filter表中有三种链:INPUT, FORWARD和OUTPUT。
默认的链策略是ACCEPT,可以将它们设置成DROP,如下命令就将所有包都拒绝了:
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT DROP
---------------------------------------------------------------------------------------------------------------------------
其实,在运维工作中最常用的两个规则就是白名单规则和NAT转发规则:
1)白名单规则
在linux终端命令行里操作时,如果不是默认的filter表时,需要指定表;
如果在/etc/sysconfig/iptables文件里设置,就在对应表的配置区域内设置;
上面两种方式设置效果是一样的!
比如开通本机的22端口,允许192.168.1.0网段的服务器访问(-t filter表配置可以省略,默认就是这种表的配置)
[root@linux-node1 ~]# iptables -A INPUT -s 192.168.1.0/24 -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
或者
[root@linux-node1 ~]# iptables -t filter -A INPUT -s 192.168.1.0/24 -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
开通本机的80端口,只允许192.168.1.150机器访问(32位掩码表示单机,单机指定时可以不加掩码)
[root@linux-node1 ~]# iptables -t filter -A INPUT -s 192.168.1.150/32 -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT
然后保存规则,重启iptables
[root@linux-node1 ~]# service iptables save
[root@linux-node1 ~]# service iptables restart
或者在/etc/sysconfig/iptables文件里设置如下(其实上面在终端命令行里设置并save和restart防火墙后,就会自动保存规则到/etc/sysconfig/iptables这个文件中的):
[root@bastion-IDC ~]# cat /etc/sysconfig/iptables
......
*filter
:INPUT ACCEPT [442620:173026884]
:FORWARD ACCEPT [118911:23993940]
:OUTPUT ACCEPT [8215384:539509656]
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -s 192.168.1.0/24 -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
-A INPUT -s 192.168.1.150/32 -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT
[root@bastion-IDC ~]# service iptables restart
2)NAT转发设置
比如访问本机(192.168.1.7)的8088端口转发到192.168.1.160的80端口;访问本机的33066端口转发到192.168.1.161的3306端口
准备工作:
本机打开ip_forword路由转发功能;192.168.1.160/161的内网网关要和本机网关一致!如果没有内网网关,就将网关设置成本机内网ip,并且关闭防火墙(防火墙要是打开了,就设置对应端口允许本机访问)
[root@kvm-server conf]# iptables -t nat -A PREROUTING -p tcp -m tcp --dport 8088 -j DNAT --to-destination 192.168.1.160:80
[root@kvm-server conf]# iptables -t nat -A POSTROUTING -d 192.168.1.160/32 -p tcp -m tcp --sport 80 -j SNAT --to-source 192.168.1.7
[root@kvm-server conf]# iptables -t filter -A INPUT -p tcp -m state --state NEW -m tcp --dport 8088 -j ACCEPT
[root@kvm-server conf]# iptables -t nat -A PREROUTING -p tcp -m tcp --dport 33066 -j DNAT --to-destination 192.168.1.161:3306
[root@kvm-server conf]# iptables -t nat -A POSTROUTING -d 192.168.1.161/32 -p tcp -m tcp --sport 3306 -j SNAT --to-source 192.168.1.7
[root@kvm-server conf]# iptables -t filter -A INPUT -p tcp -m state --state NEW -m tcp --dport 33066 -j ACCEPT
[root@kvm-server conf]# service iptables save
[root@kvm-server conf]# service iptables restart
或者在/etc/sysconfig/iptables文件里设置如下
[root@bastion-IDC ~]# cat /etc/sysconfig/iptables
......
*nat
:PREROUTING ACCEPT [60:4250]
:INPUT ACCEPT [31:1973]
:OUTPUT ACCEPT [3:220]
:POSTROUTING ACCEPT [3:220]
-A PREROUTING -p tcp -m tcp --dport 8088 -j DNAT --to-destination 192.168.1.160:80 //PREROUTING规则都放在上面
-A PREROUTING -p tcp -m tcp --dport 33066 -j DNAT --to-destination 192.168.1.161:3306
-A POSTROUTING -d 192.168.1.160/32 -p tcp -m tcp --sport 80 -j SNAT --to-source 192.168.1.7 //POSTROUTING规则都放在下面
-A POSTROUTING -d 192.168.1.161/32 -p tcp -m tcp --sport 3306 -j SNAT --to-source 192.168.1.7
.....
*filter
:INPUT ACCEPT [16:7159]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [715:147195]
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 8088 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 33066 -j ACCEPT
.....
[root@bastion-IDC ~]# service iptables restart
[root@bastion-IDC ~]# iptables -L //列出设置的规则,默认列出的是filter表下的规则
[root@bastion-IDC ~]# iptables -L -t nat //如果列出nat表下规则,就加-t参数
--------------------------------------------------------------------------------------------------------------------------
删除INPUT链的第一条规则
iptables -D INPUT 1
拒绝进入防火墙的所有ICMP协议数据包
iptables -I INPUT -p icmp -j REJECT
允许防火墙转发除ICMP协议以外的所有数据包
iptables -A FORWARD -p ! icmp -j ACCEPT
说明:使用“!”可以将条件取反
拒绝转发来自192.168.1.10主机的数据,允许转发来自192.168.0.0/24网段的数据
iptables -A FORWARD -s 192.168.1.11 -j REJECT
iptables -A FORWARD -s 192.168.0.0/24 -j ACCEPT
说明:注意一定要把拒绝的放在前面不然就不起作用了!
丢弃从外网接口(eth1)进入防火墙本机的源地址为私网地址的数据包
iptables -A INPUT -i eth1 -s 192.168.0.0/16 -j DROP
iptables -A INPUT -i eth1 -s 172.16.0.0/12 -j DROP
iptables -A INPUT -i eth1 -s 10.0.0.0/8 -j DROP
封堵网段(192.168.1.0/24),两小时后解封
# iptables -I INPUT -s 10.20.30.0/24 -j DROP
# iptables -I FORWARD -s 10.20.30.0/24 -j DROP
# at now 2 hours at> iptables -D INPUT 1 at> iptables -D FORWARD 1
说明:这个策略可以借助crond计划任务来完成,就再好不过了
只允许管理员从202.13.0.0/16网段使用SSH远程登录防火墙主机
iptables -A INPUT -s 202.13.0.0/16 -p tcp -m tcp -m state --state NEW --dport 22 -j ACCEPT
说明:这个用法比较适合对设备进行远程管理时使用,比如位于分公司中的SQL服务器需要被总公司的管理员管理时
通常在服务器上会对某一服务端口的访问做白名单限制,比如(其他端口设置和下面一致):
运行本机的3306端口(mysql服务)被访问
iptables -A INPUT -p tcp -m tcp -m state --state NEW --dport 3306 -j ACCEPT
或者只运行本机的3306端口被192.168.1.0/24网段机器访问
iptables -A INPUT -s 192.168.1.0/24 -p tcp -m tcp -m state --state NEW --dport 3306 -j ACCEPT
允许本机开放从TCP端口20-1024提供的应用服务
iptables -A INPUT -p tcp -m tcp -m state --state NEW --dport 20:1024 -j ACCEPT
允许转发来自192.168.0.0/24局域网段的DNS解析请求数据包
iptables -A FORWARD -s 192.168.0.0/24 -p udp --dport 53 -j ACCEPT
iptables -A FORWARD -d 192.168.0.0/24 -p udp --sport 53 -j ACCEPT
屏蔽指定的IP地址
以下规则将屏蔽BLOCK_THIS_IP所指定的IP地址访问本地主机:
BLOCK_THIS_IP="x.x.x.x"
iptables -A INPUT -i eth0 -s "$BLOCK_THIS_IP" -j DROP
(或者仅屏蔽来自该IP的TCP数据包)
iptables -A INPUT -i eth0 -p tcp -s "$BLOCK_THIS_IP" -j DROP
屏蔽环回(loopback)访问
iptables -A INPUT -i lo -j DROP
iptables -A OUTPUT -o lo -j DROP
屏蔽来自外部的ping,即禁止外部机器ping本机
iptables -A INPUT -p icmp --icmp-type echo-request -j DROP
iptables -A OUTPUT -p icmp --icmp-type echo-reply -j DROP
屏蔽从本机ping外部主机,禁止本机ping外部机器
iptables -A OUTPUT -p icmp --icmp-type echo-request -j DROP
iptables -A INPUT -p icmp --icmp-type echo-reply -j DROP
禁止其他主机ping本机,但是允许本机ping其他主机(禁止别人ping本机,也可以使用echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_all)
iptables -I INPUT -p icmp --icmp-type echo-request -j DROP
iptables -I INPUT -p icmp --icmp-type echo-reply -j ACCEPT
iptables -I INPUT -p icmp --icmp-type destination-Unreachable -j ACCEPT
禁止转发来自MAC地址为00:0C:29:27:55:3F的和主机的数据包
iptables -A FORWARD -m mac --mac-source 00:0c:29:27:55:3F -j DROP
说明:iptables中使用“-m 模块关键字”的形式调用显示匹配。咱们这里用“-m mac –mac-source”来表示数据包的源MAC地址
允许防火墙本机对外开放TCP端口20、21、25、110以及被动模式FTP端口1250-1280
iptables -A INPUT -p tcp -m multiport --dport 20,21,25,110,1250:1280 -j ACCEPT
注意:这里用“-m multiport --dport”来指定多个目的端口
iptables -A INPUT -p tcp -m tcp -m multiport --dports 22,80,443,1250-1280 -m state --state NEW -j ACCEPT
也可以将这几个端口分开设置多行:
iptables -A INPUT -p tcp -m tcp -m state --state NEW --dport 22 -j ACCEPT
iptables -A INPUT -p tcp -m tcp -m state --state NEW --dport 80 -j ACCEPT
iptables -A INPUT -p tcp -m tcp -m state --state NEW --dport 443 -j ACCEPT
iptables -A INPUT -p tcp -m tcp -m state --state NEW --dport 1250:1280 -j ACCEPT
禁止转发源IP地址为192.168.1.20-192.168.1.99的TCP数据包
iptables -A FORWARD -p tcp -m iprange --src-range 192.168.1.20-192.168.1.99 -j DROP
说明:
此处用“-m iprange --src-range”指定IP范围
1)过滤源地址范围:
iptables -A INPUT -m iprange --src-range 192.168.1.2-192.168.1.7 -j DROP
2)过滤目标地址范围:
iptables -A INPUT -m iprange --dst-range 192.168.1.2-192.168.1.7 -j DROP
3)针对端口访问的过滤。下面表示除了192.168.1.5-192.168.1.10之间的ip能访问192.168.1.67机器的80端口以外,其他ip都不可以访问!
iptables -A INPUT -d 192.168.1.67 -p tcp --dport 80 -m iprange --src-range 192.168.1.5-192.168.1.10 -j ACCEPT
禁止转发与正常TCP连接无关的非--syn请求数据包
iptables -A FORWARD -m state --state NEW -p tcp ! --syn -j DROP
说明:“-m state”表示数据包的连接状态,“NEW”表示与任何连接无关的
拒绝访问防火墙的新数据包,但允许响应连接或与已有连接相关的数据包
iptables -A INPUT -p tcp -m state --state NEW -j DROP
iptables -A INPUT -p tcp -m state --state ESTABLISHED,RELATED -j ACCEPT
说明:“ESTABLISHED”表示已经响应请求或者已经建立连接的数据包,“RELATED”表示与已建立的连接有相关性的,比如FTP数据连接等
防止DoS攻击
iptables -A INPUT -p tcp --dport 80 -m limit --limit 25/minute --limit-burst 100 -j ACCEPT
-m limit: 启用limit扩展,限制速度。
--limit 25/minute: 允许最多每分钟25个连接
--limit-burst 100: 当达到100个连接后,才启用上述25/minute限制
--icmp-type 8 表示 Echo request——回显请求(Ping请求)。下面表示本机ping主机192.168.1.109时候的限速设置:
iptables -I INPUT -d 192.168.1.109 -p icmp --icmp-type 8 -m limit --limit 3/minute --limit-burst 5 -j ACCEPT
允许路由
如果本地主机有两块网卡,一块连接内网(eth0),一块连接外网(eth1),那么可以使用下面的规则将eth0的数据路由到eht1:
iptables -A FORWARD -i eth0 -o eth1 -j ACCEPT
IPtables中可以灵活的做各种网络地址转换(NAT)
网络地址转换主要有两种:SNAT和DNAT
1)SNAT是source network address translation的缩写,即源地址目标转换。
比如,多个PC机使用ADSL路由器共享上网,每个PC机都配置了内网IP。PC机访问外部网络的时候,路由器将数据包的报头中的源地址替换成路由器的ip,当外部网络的服务器比如网站web服务器接到访问请求的时候,它的日志记录下来的是路由器的ip地址,而不是pc机的内网ip,这是因为,这个服务器收到的数据包的报头里边的“源地址”,已经被替换了。所以叫做SNAT,基于源地址的地址转换
2)DNAT是destination network address translation的缩写,即目标网络地址转换。
典型的应用是,有个web服务器放在内网中,配置了内网ip,前端有个防火墙配置公网ip,互联网上的访问者使用公网ip来访问这个网站。
当访问的时候,客户端发出一个数据包,这个数据包的报头里边,目标地址写的是防火墙的公网ip,防火墙会把这个数据包的报头改写一次,将目标地址改写成web服务器的内网ip,然后再把这个数据包发送到内网的web服务器上。这样,数据包就穿透了防火墙,并从公网ip变成了一个对内网地址的访问了。即DNAT,基于目标的网络地址转换
以下规则将会把本机192.168.1.17来自422端口的流量转发到22端口,这意味着来自422端口的SSH连接请求与来自22端口的请求等效。
1)启用DNAT转发
iptables -t nat -A PREROUTING -p tcp -d 192.168.1.17 --dport 422 -j DNAT --to-destination 192.168.1.17:22
2)允许连接到422端口的请求
iptables -t filter -A INPUT -p tcp -m tcp -m state --state NEW --dport 422 -j ACCEPT
3)保存规则
# service iptables save
# service iptables restart
假设现在本机外网网关是58.68.250.1,那么把HTTP请求转发到内部的一台服务器192.168.1.20的8888端口上,规则如下:
iptables -t nat -A PREROUTING -p tcp -i eth0 -d 58.68.250.1 --dport 8888 -j DNAT --to 192.168.1.20:80
iptables -A FORWARD -p tcp -i eth0 -d 192.168.0.2 --dport 80 -j ACCEPT
iptables -t filter -A INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT
service iptables save
service iptables restart
或者或本机内网ip是192.168.1.10,那么把HTTP请求转发到内部的一台服务器192.168.1.20的8888端口上,规则如下:
准备工作:本机打开ip_forword路由转发功能;192.168.1.20的内网网关要和本机网关保持一致!如果没有内网网关,就将网关地址设置成本机内网ip,并且关闭防火墙(防火墙要是打开了,就设置对应端口允许本机访问)
iptables -t nat -A PREROUTING -p tcp -m tcp --dport 20022 -j DNAT --to-destination 192.168.1.150:22
iptables -t nat -A POSTROUTING -d 192.168.1.150/32 -p tcp -m tcp --sport 22 -j SNAT --to-source 192.168.1.8
iptables -t filter -A INPUT -p tcp -m state --state NEW -m tcp --dport 20022 -j ACCEPT
service iptables save
service iptables restart
MASQUERADE,地址伪装,在iptables中有着和SNAT相近的效果,但也有一些区别:
1)使用SNAT的时候,出口ip的地址范围可以是一个,也可以是多个,例如:
1)如下命令表示把所有10.8.0.0网段的数据包SNAT成192.168.5.3的ip然后发出去
iptables -t nat -A POSTROUTING -s 10.8.0.0/255.255.255.0 -o eth0 -j SNAT --to-source 192.168.5.3
2)如下命令表示把所有10.8.0.0网段的数据包SNAT成192.168.5.3/192.168.5.4/192.168.5.5等几个ip然后发出去
iptables -t nat -A POSTROUTING -s 10.8.0.0/255.255.255.0 -o eth0 -j SNAT --to-source 192.168.5.3-192.168.5.5
这就是SNAT的使用方法,即可以NAT成一个地址,也可以NAT成多个地址。但是,对于SNAT,不管是几个地址,必须明确的指定要SNAT的ip!
假如当前系统用的是ADSL动态拨号方式,那么每次拨号,出口ip192.168.5.3都会改变,而且改变的幅度很大,不一定是192.168.5.3到192.168.5.5范围内的地址。这个时候如果按照现在的方式来配置iptables就会出现问题了,因为每次拨号后,服务器地址都会变化,而iptables规则内的ip是不会随着自动变化的,每次地址变化后都必须手工修改一次iptables,把规则里边的固定ip改成新的ip,这样是非常不好用的!
2)MASQUERADE就是针对上述场景而设计的,它的作用是,从服务器的网卡上,自动获取当前ip地址来做NAT。
比如下边的命令:
iptables -t nat -A POSTROUTING -s 10.8.0.0/255.255.255.0 -o eth0 -j MASQUERADE
如此配置的话,不用指定SNAT的目标ip了。
不管现在eth0的出口获得了怎样的动态ip,MASQUERADE会自动读取eth0现在的ip地址然后做SNAT出去
这样就实现了很好的动态SNAT地址转换
再看看几个运维实例设置:
1)限制本机的web服务器在周一不允许访问;
新请求的速率不能超过100个每秒;
web服务器包含了admin字符串的页面不允许访问:
web 服务器仅允许响应报文离开本机;
设置如下:
周一不允许访问
iptables -A INPUT -p tcp --dport 80 -m time ! --weekdays Mon -j ACCEPT
iptables -A OUTPUT -p tcp --dport 80 -m state --state ESTABLISHED -j ACCEPT
新请求速率不能超过100个每秒
iptables -A INPUT -p tcp --dport 80 -m limit --limit 100/s -j ACCEPT
web包含admin字符串的页面不允许访问,源端口:dport
iptables -A INPUT -p tcp --dport 80 -m string --algo bm --string 'admin' -j REJECT
web服务器仅允许响应报文离开主机,放行端口(目标端口):sport
iptables -A OUTPUT -p tcp --dport 80 -m state --state ESTABLISHED -j ACCEPT
2)在工作时间,即周一到周五的8:30-18:00,开放本机的ftp服务给 192.168.1.0网络中的主机访问;
数据下载请求的次数每分钟不得超过 5 个;
设置如下:
iptables -A INPUT -p tcp --dport 21 -s 192.168.1.0/24 -m time ! --weekdays 6,7 -m time --timestart 8:30 --timestop 18:00 -m connlimit --connlimit-above 5 -j ACCET
3)开放本机的ssh服务给192.168.1.1-192.168.1.100 中的主机;
新请求建立的速率一分钟不得超过2个;
仅允许响应报文通过其服务端口离开本机;
设置如下:
iptables -A INPUT -p tcp --dport 22 -m iprange --src-rang 192.168.1.1-192.168.1.100 -m limit --limit 2/m -j ACCEPT
iptables -A OUTPUT -p tcp --sport 22 -m iprange --dst-rang 192.168.1.1-192.168.1.100 -m state --state ESTABLISHED -j ACCEPT
4)拒绝 TCP 标志位全部为 1 及全部为 0 的报文访问本机;
iptables -A INPUT -p tcp --tcp-flags ALL ALL -j DROP
5)允许本机 ping 别的主机;但不开放别的主机 ping 本机;
iptables -I INPUT -p icmp --icmp-type echo-request -j DROP
iptables -I INPUT -p icmp --icmp-type echo-reply -j ACCEPT
iptables -I INPUT -p icmp --icmp-type destination-Unreachable -j ACCEPT
或者下面禁ping操作:
echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_all
1.防火墙安全基本概述
RHEL/CentOS 7系统中集成了多款防火墙管理工具,其中firewalld(Dynamic Firewall Manager of Linux systems, Linux系统的动态防火墙管理器)服务是默认的防火墙配置管理工具,它拥有基于CLI(命令行界面)和基于GUI(图形用户界面)的两种管理方式。
那么相较于传统的Iptables防火墙,firewalld支持动态更新,并加入了区域zone的概念。
简单来说,区域就是firewalld预先准备了几套防火墙策略集合(策略模板),用户可以根据生产场景的不同而选择合适的策略集合,从而实现防火墙策略之间的快速切换。
Firewalld规则配置,从外访问服务器内部如果没有添加规则默认是阻止,从服务器内部访问服务器外部默认是允许
需要注意的是Firewalld中的区域与接口
一个网卡仅能绑定一个区域,但一个区域可以绑定多个网卡。还可以根据来源的地址设定不同的规则。
比如:所有人能访问80端口,但只有公司的IP才可以访问22端口。
2.防火墙使用区域管理
划分不同的区域,制定出不同区域之间的访问控制策略来控制不同程序区域间传送的数据流。
区域
|
默认规则策略
|
trusted
|
允许所有的数据包流入与流出
|
home
|
拒绝流入的流量,除非与流出的流量相关;而如果流量与ssh、mdns、ipp-client、amba-client与dhcpv6-client服务相关,则允许流量
|
internal
|
等同于home区域
|
work
|
拒绝流入的流量,除非与流出的流量数相关;而如果流量与ssh、ipp-client与dhcpv6-client服务相关,则允许流量
|
public
|
拒绝流入的流量,除非与流出的流量相关;而如果流量与ssh、dhcpv6-client服务相关,则允许流量
|
external
|
拒绝流入的流量,除非与流出的流量相关;而如果流量与ssh服务相关,则允许流量
|
dmz
|
拒绝流入的流量,除非与流出的流量相关;而如果流量与ssh服务相关,则允许流量
|
block
|
拒绝流入的流量,除非与流出的流量相关
|
drop
|
拒绝流入的流量,除非与流出的流量相关
|
3.防火墙基本指令参数
firewall-cmd命令分类列表
参数
|
作用
|
zone区域相关指令
|
|
--get-default-zone
|
查询默认的区域名称
|
--set-default-zone=<区域名称>
|
设置默认的区域,使其永久生效
|
--get-active-zones
|
显示当前正在使用的区域与网卡名称
|
--get-zones
|
显示总共可用的区域
|
--new-zone=<zone>
|
新增区域
|
services服务相关指令
|
|
--get-services
|
显示预先定义的服务
|
--add-service=<服务名>
|
设置默认区域允许该服务的流量
|
--remove-service=<服务名>
|
设置默认区域不再允许该服务的流量
|
Port端口相关指令
|
|
--add-port=<端口号/协议>
|
设置默认区域允许该端口的流量
|
--remove-port=<端口号/协议>
|
设置默认区域不再允许该端口的流量
|
Interface网卡相关指令
|
|
--add-interface=<网卡名称>
|
将源自该网卡的所有流量都导向某个指定区域
|
--change-interface=<网卡名称>
|
将某个网卡与区域进行关联
|
其他相关指令
|
|
--list-all
|
显示当前区域的网卡配置参数、资源、端口以及服务等信息
|
--reload
|
让“永久生效”的配置规则立即生效,并覆盖当前的配置规则
|
4.防火墙区域配置策略
1.为了能正常使用firwalld服务和相关工具去管理防火墙,必须启动firwalld服务,同时关闭以前旧防火墙相关服务,同时需要注意firewalld的规则分两种状态:
runtime运行时: 修改规则马上生效,但是临时生效 [不建议]
permanent持久配置: 修改后需要reload重载才会生效 [强烈推荐]
# 禁用旧版防火墙服务
[root@Firewalld ~]# systemctl mask iptables
[root@Firewalld ~]# systemctl mask ip6tables
# 启动firewalld防火墙, 并加入开机自启动服务
[root@Firewalld ~]# systemctl start firewalld
[root@Firewalld ~]# systemctl enable firewalld
[root@Firewalld ~]# systemctl mask iptables
[root@Firewalld ~]# systemctl mask ip6tables
# 启动firewalld防火墙, 并加入开机自启动服务
[root@Firewalld ~]# systemctl start firewalld
[root@Firewalld ~]# systemctl enable firewalld
2.firewalld启动后,我们需要知道使用的是什么区域,区域的规则明细又有哪些?
# 默认使用的区域
[root@web01 ~]# firewall-cmd --get-default-zone
public
# 查看当前区域的规则有哪些
[root@web01 ~]# firewall-cmd --list-all
public (active)
target: default
icmp-block-inversion: no
interfaces: eth0 eth1
sources:
services: ssh dhcpv6-client
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
[root@web01 ~]# firewall-cmd --get-default-zone
public
# 查看当前区域的规则有哪些
[root@web01 ~]# firewall-cmd --list-all
public (active)
target: default
icmp-block-inversion: no
interfaces: eth0 eth1
sources:
services: ssh dhcpv6-client
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
3.使用firewalld中各个区域规则结合,当前默认区域拒绝所有的流量,但如果来源IP是10.0.0.0/24网段则允许。
#1.临时移除策略
[root@web01 ~]# firewall-cmd --remove-service=ssh --remove-service=dhcpv6-client
success
#2.添加来源是10.0.0.0/24网段,将其加入白名单
[root@web01 ~]# firewall-cmd --add-source=10.0.0.0/24 --zone=trusted
success
#3.检查当前活动的区域
[root@web01 ~]# firewall-cmd --get-active-zone
public
interfaces: eth0 eth1 # 针对客户端限制
trusted
sources: 10.0.0.0/24 # 针对公司网段限制
[root@web01 ~]# firewall-cmd --remove-service=ssh --remove-service=dhcpv6-client
success
#2.添加来源是10.0.0.0/24网段,将其加入白名单
[root@web01 ~]# firewall-cmd --add-source=10.0.0.0/24 --zone=trusted
success
#3.检查当前活动的区域
[root@web01 ~]# firewall-cmd --get-active-zone
public
interfaces: eth0 eth1 # 针对客户端限制
trusted
sources: 10.0.0.0/24 # 针对公司网段限制
4.查询public区域是否允许请求SSH HTTPS协议的流量
[root@Firewalld ~]# firewall-cmd --zone=public --query-service=ssh
yes
[root@Firewalld ~]# firewall-cmd --zone=public --query-service=https
no
yes
[root@Firewalld ~]# firewall-cmd --zone=public --query-service=https
no
7.最后将配置恢复至默认规则,--reload参数仅能恢复临时添加的规则策略
[root@web01 ~]# firewall-cmd --reload
5.防火墙端口访问策略
使用firewalld允许客户请求的服务器的80/tcp端口,仅临时生效,如添加--permanent重启后则永久生效
1.临时添加允许放行单个端口
[root@Firewalld ~]# firewall-cmd --add-port=80/tcp
2.临时添加放行多个端口
[root@Firewalld ~]# firewall-cmd --add-port={80/tcp,8080/tcp}
3.永久添加多个端口,需要添加--permanent,并且需要重载firewalld
[root@Firewalld ~]# firewall-cmd --add-port={80/tcp,8080/tcp} --permanet
[root@Firewalld ~]# firewall-cmd --reload
[root@Firewalld ~]# firewall-cmd --reload
4.通过--list-ports检查端口放行情况
[root@Firewalld ~]# firewall-cmd --list-ports
80/tcp 8080/tcp
80/tcp 8080/tcp
5.移除临时添加的端口规则
[root@Firewalld ~]# firewall-cmd --remove-port={80/tcp,8080/tcp}
6.防火墙服务访问策略
使用firewalld允许客户请求服务器的http https协议,仅临时生效,如添加--permanent重启后则永久生效
1.临时添加允许放行单个端口
[root@Firewalld ~]# firewall-cmd --add-service=http
2.临时添加放行多个端口
[root@Firewalld ~]# firewall-cmd --add-service={http,htps}
3.永久添加多个端口,需要添加--permanent,并且需要重载firewalld
[root@Firewalld ~]# firewall-cmd --add-service={http,htps} --permanet
[root@Firewalld ~]# firewall-cmd --reload
[root@Firewalld ~]# firewall-cmd --reload
4.通过--list-services检查端口放行情况
[root@Firewalld ~]# firewall-cmd --list-services
http https
http https
5.移除临时添加的http https协议
[root@Firewalld ~]# firewall-cmd --remove-port={http,htps}
6.如何添加一个自定义端口,转其为对应的服务
#1.拷贝相应的xml文件
[root@Firewalld ~]# cd /usr/lib/firewalld/services/
[root@Firewalld services]# cp http.xml zabbix-agent.xml
#2.修改端口为9000
[root@Firewalld services]# cat zabbix-agent.xml
<?xml version="1.0" encoding="utf-8"?>
<service>
<short>zabbix-agent</short>
<description> zabbix-agent </description>
<port protocol="tcp" port="10050"/>
</service>
#3.防火墙增加规则
[root@Firewalld ~]# firewall-cmd --permanent --add-service=zabbix-agent
[root@Firewalld ~]# firewall-cmd --list-services
ssh dhcpv6-client http https zabbix-agent
#4.安装php-fpm, 并监听9000端口
[root@Firewalld ~]# yum install zabbix-agent -y
[root@Firewalld ~]# systemctl start zabbix-agent
#5.测试验证
~ telnet 10.0.0.61 10050
Trying 10.0.0.61...
Connected to 10.0.0.61.
Escape character is '^]'.
[root@Firewalld ~]# cd /usr/lib/firewalld/services/
[root@Firewalld services]# cp http.xml zabbix-agent.xml
#2.修改端口为9000
[root@Firewalld services]# cat zabbix-agent.xml
<?xml version="1.0" encoding="utf-8"?>
<service>
<short>zabbix-agent</short>
<description> zabbix-agent </description>
<port protocol="tcp" port="10050"/>
</service>
#3.防火墙增加规则
[root@Firewalld ~]# firewall-cmd --permanent --add-service=zabbix-agent
[root@Firewalld ~]# firewall-cmd --list-services
ssh dhcpv6-client http https zabbix-agent
#4.安装php-fpm, 并监听9000端口
[root@Firewalld ~]# yum install zabbix-agent -y
[root@Firewalld ~]# systemctl start zabbix-agent
#5.测试验证
~ telnet 10.0.0.61 10050
Trying 10.0.0.61...
Connected to 10.0.0.61.
Escape character is '^]'.
7.防火墙端口转发策略
端口转发是指传统的目标地址映射,实现外网访问内网资源,流量转发命令格式为:
firewall-cmd --permanent --zone=<区域> --add-forward-port=port=<源端口号>:proto=<协议>:toport=<目标端口号>:toaddr=<目标IP地址>
如果需要将本地的10.0.0.61:5555端口转发至后端172.16.1.9:22端口
1.开启masquerade,实现地址转换
[root@Firewalld ~]# firewall-cmd --add-masquerade --permanent
2.配置转发规则
[root@Firewalld ~]# firewall-cmd --permanent --zone=public --add-forward-port=port=6666:proto=tcp:toport=22:toaddr=172.16.1.9
[root@Firewalld ~]# firewall-cmd --reload
[root@Firewalld ~]# firewall-cmd --reload
8.防火墙富规则策略
firewalld中的富规则表示更细致、更详细的防火墙策略配置,它可以针对系统服务、端口号、源地址和目标地址等诸多信息进行更有针对性的策略配置, 优先级在所有的防火墙策略中也是最高的。,下面为firewalld富规则帮助手册
[root@Firewalld ~]# man firewall-cmd # 帮助手册
[root@Firewalld ~]# man firewalld.richlanguage # 获取富规则手册
rule
[source]
[destination]
service|port|protocol|icmp-block|masquerade|forward-port
[log]
[audit]
[accept|reject|drop]
rule [family="ipv4|ipv6"]
source address="address[/mask]" [invert="True"]
destination address="address[/mask]" invert="True"
service name="service name"
port port="port value" protocol="tcp|udp"
protocol value="protocol value"
forward-port port="port value" protocol="tcp|udp" to-port="port value" to-addr="address"
log [prefix="prefix text"] [level="log level"] [limit value="rate/duration"]
accept | reject [type="reject type"] | drop
#富规则相关命令
--add-rich-rule='<RULE>' #在指定的区添加一条富规则
--remove-rich-rule='<RULE>' #在指定的区删除一条富规则
--query-rich-rule='<RULE>' #找到规则返回0 ,找不到返回1
--list-rich-rules #列出指定区里的所有富规则
[root@Firewalld ~]# man firewalld.richlanguage # 获取富规则手册
rule
[source]
[destination]
service|port|protocol|icmp-block|masquerade|forward-port
[log]
[audit]
[accept|reject|drop]
rule [family="ipv4|ipv6"]
source address="address[/mask]" [invert="True"]
destination address="address[/mask]" invert="True"
service name="service name"
port port="port value" protocol="tcp|udp"
protocol value="protocol value"
forward-port port="port value" protocol="tcp|udp" to-port="port value" to-addr="address"
log [prefix="prefix text"] [level="log level"] [limit value="rate/duration"]
accept | reject [type="reject type"] | drop
#富规则相关命令
--add-rich-rule='<RULE>' #在指定的区添加一条富规则
--remove-rich-rule='<RULE>' #在指定的区删除一条富规则
--query-rich-rule='<RULE>' #找到规则返回0 ,找不到返回1
--list-rich-rules #列出指定区里的所有富规则
1.比如允许10.0.0.1主机能够访问http服务,允许172.16.1.0/24能访问10050端口
[root@Firewalld ~]# firewall-cmd --add-rich-rule='rule family=ipv4 source address=10.0.0.1/32 service name=http accept'
[root@Firewalld ~]# firewall-cmd --add-rich-rule='rule family=ipv4 source address=172.16.1.0/24 port port="10050" protocol="tcp" accept'
[root@Firewalld ~]# firewall-cmd --add-rich-rule='rule family=ipv4 source address=172.16.1.0/24 port port="10050" protocol="tcp" accept'
2.默认public区域对外开放所有人能通过ssh服务连接,但拒绝172.16.1.0/24网段通过ssh连接服务器
[root@Firewalld ~]# firewall-cmd --add-rich-rule='rule family=ipv4 source address=172.16.1.0/24 service name="ssh" drop'
3.使用firewalld,允许所有人能访问http,https服务,但只有10.0.0.1主机可以访问ssh服务
[root@Firewalld ~]# firewall-cmd --add-service={http,https}
success
[root@Firewalld ~]# firewall-cmd --add-rich-rule='rule family=ipv4 source address=10.0.0.1/32 service name=ssh accept'
success
success
[root@Firewalld ~]# firewall-cmd --add-rich-rule='rule family=ipv4 source address=10.0.0.1/32 service name=ssh accept'
success
4.当用户来源IP地址是10.0.0.1主机,则将用户请求的5555端口转发至后端172.16.1.9的22端口
[root@Firewalld ~]# firewall-cmd --add-masquerade
[root@Firewalld ~]# firewall-cmd --add-rich-rule='rule family=ipv4 source address=10.0.0.1/32 forward-port port="5555" protocol="tcp" to-port="22" to-addr="172.16.1.6"'
success
[root@Firewalld ~]# firewall-cmd --add-rich-rule='rule family=ipv4 source address=10.0.0.1/32 forward-port port="5555" protocol="tcp" to-port="22" to-addr="172.16.1.6"'
success
5.查看设定的规则,如果没有添加--permanent参数则重启firewalld会失效。富规则按先后顺序匹配,按先匹配到的规则生效
[root@Firewalld ~]# firewall-cmd --list-rich-rules
rule family="ipv4" source address="10.0.0.1/32" service name="http" accept
rule family="ipv4" source address="172.16.1.0/24" port port="10050" protocol="tcp" accept
rule family="ipv4" source address="172.16.1.0/24" service name="ssh" drop
rule family="ipv4" source address="10.0.0.1/32" service name="ssh" accept
rule family="ipv4" source address="10.0.0.1/32" forward-port port="5555" protocol="tcp" to-port="22" to-addr="172.16.1.6"
rule family="ipv4" source address="10.0.0.1/32" service name="http" accept
rule family="ipv4" source address="172.16.1.0/24" port port="10050" protocol="tcp" accept
rule family="ipv4" source address="172.16.1.0/24" service name="ssh" drop
rule family="ipv4" source address="10.0.0.1/32" service name="ssh" accept
rule family="ipv4" source address="10.0.0.1/32" forward-port port="5555" protocol="tcp" to-port="22" to-addr="172.16.1.6"
9.防火墙开启内部上网
在指定的带有公网IP的实例上启动Firewalld防火墙的NAT地址转换,以此达到内部主机上网。
1.firewalld防火墙开启masquerade, 实现地址转换
[root@Firewalld ~]# firewall-cmd --add-masquerade --permanent
[root@Firewalld ~]# firewall-cmd --reload
[root@Firewalld ~]# firewall-cmd --reload
2.客户端将网关指向firewalld服务器,将所有网络请求交给firewalld
[root@web03 ~]# cat /etc/sysconfig/network-scripts/ifcfg-eth1
GATEWAY=172.16.1.61
GATEWAY=172.16.1.61
3.客户端还需配置dns服务器
[root@web03 ~]# cat /etc/resolv.conf
nameserver 223.5.5.5
nameserver 223.5.5.5
4.重启网络,使其配置生效
[root@web03 ~]# nmcli connection reload
[root@web03 ~]# nmcli connection down eth1 && nmcli connection up eth1
[root@web03 ~]# nmcli connection down eth1 && nmcli connection up eth1
5.测试后端web的网络是否正常
[root@web03 ~]# ping baidu.com
PING baidu.com (123.125.115.110) 56(84) bytes of data.
64 bytes from 123.125.115.110 (123.125.115.110): icmp_seq=1 ttl=127 time=9.08 ms
PING baidu.com (123.125.115.110) 56(84) bytes of data.
64 bytes from 123.125.115.110 (123.125.115.110): icmp_seq=1 ttl=127 time=9.08 ms
导读管理网络流量是系统管理员必需处理的最棘手工作之一,我们必需规定连接系统的用户满足防火墙的传入和传出要求,以最大限度保证系统免受攻击。很多用户把 Linux 中的 IPTables 当成一个防火墙,从严格意见上来说 IPTables 只是能够帮助管理员定义各种规则并与 Linux Kernel 进行沟通的一个命令行工具。它只是帮助管理员配置网络流量的传入、传出规则列表,具体的实现其实是在 Linux 内核当中。
IPTables 包括一组内置和由用户定义规则的「链」,管理员可以在「链」上附加各种数据包处理规则。
- FILTER 默认过滤表,内建的链有:
- INPUT:处理流入本地的数据包
- FORWARD:处理通过系统路由的数据包
- OUTPUT:处理本地流出的数据包
- NAT 实现网络地址转换的表,内建的链有:
- PREROUTING:处理即将接收的数据包
- OUTPUT:处理本地产生的数据包
- POSTROUTING:处理即将传出的数据包
- MANGLE 此表用于改变数据包,共 5 条链:
- PREROUTING:处理传入连接
- OUTPUT:处理本地生成的数据包
- INPUT:处理报文
- POSTROUTING:处理即将传出数据包
- FORWARD:处理通过本机转发的数据包
接下来我们将由简入难介绍 25 条 Linux 管理员最常会用到的 IPTables 规则。
1、启动、停止和重启IPTables
虽然 IPTables 并不是一项服务,但在 Linux 中还是可以像服务一样对其状态进行管理。
基于SystemD的系统
systemctl start iptables
systemctl stop iptables
systemctl restart iptables
systemctl stop iptables
systemctl restart iptables
基于SysVinit的系统
/etc/init.d/iptables start
/etc/init.d/iptables stop
/etc/init.d/iptables restart
/etc/init.d/iptables stop
/etc/init.d/iptables restart
2、查看IPtables防火墙策略
你可以使用如下命令来查看 IPtables 防火墙策略:
iptables -L -n -v
以上命令应该返回数据下图的输出:
以上命令是查看默认的 FILTER 表,如果你只希望查看特定的表,可以在 -t 参数后跟上要单独查看的表名。例如只查看 NAT 表中的规则,可以使用如下命令:
iptables -t nat -L -v –n
3、屏蔽某个IP地址
如果你发布有某个 IP 向服务器导入攻击或非正常流量,可以使用如下规则屏蔽其 IP 地址:
iptables -A INPUT -s xxx.xxx.xxx.xxx -j DROP
注意需要将上述的 XXX 改成要屏蔽的实际 IP 地址,其中的 -A 参数表示在 INPUT 链的最后追加本条规则。(IPTables 中的规则是从上到下匹配的,一旦匹配成功就不再继续往下匹配)
如果你只想屏蔽 TCP 流量,可以使用 -p 参数的指定协议,例如:
iptables -A INPUT -p tcp -s xxx.xxx.xxx.xxx -j DROP
4、解封某个IP地址
要解封对 IP 地址的屏蔽,可以使用如下命令进行删除:
iptables -D INPUT -s xxx.xxx.xxx.xxx -j DROP
其中 -D 参数表示从链中删除一条或多条规则。
5、使用IPtables关闭特定端口
很多时候,我们需要阻止某个特定端口的网络连接,可以使用 IPtables 关闭特定端口。
阻止特定的传出连接:
iptables -A OUTPUT -p tcp --dport xxx -j DROP
阻止特定的传入连接:
iptables -A INPUT -p tcp --dport xxx -j ACCEPT
6、使用Multiport控制多端口
使用 multiport 我们可以一次性在单条规则中写入多个端口,例如:
iptables -A INPUT -p tcp -m multiport --dports 22,80,443 -j ACCEPT
iptables -A OUTPUT -p tcp -m multiport --sports 22,80,443 -j ACCEPT
iptables -A OUTPUT -p tcp -m multiport --sports 22,80,443 -j ACCEPT
7、在规则中使用 IP 地址范围
在 IPtables 中 IP 地址范围是可以直接使用 CIDR 进行表示的,例如:
iptables -A OUTPUT -p tcp -d 192.168.100.0/24 --dport 22 -j ACCEPT
8、配置端口转发
有时我们需要将 Linux 服务器的某个服务流量转发到另一端口,此时可以使用如下命令:
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 25 -j REDIRECT --to-port 2525
上述命令会将所有到达 eth0 网卡 25 端口的流量重定向转发到 2525 端口。
9、屏蔽HTTP服务Flood攻击
有时会有用户在某个服务,例如 HTTP 80 上发起大量连接请求,此时我们可以启用如下规则:
iptables -A INPUT -p tcp --dport 80 -m limit --limit 100/minute --limit-burst 200 -j ACCEPT
上述命令会将连接限制到每分钟 100 个,上限设定为 200。
10、禁止PING
对 Linux 禁 PING 可以使用如下规则屏蔽 ICMP 传入连接:
iptables -A INPUT -p icmp -i eth0 -j DROP
11、允许访问回环网卡
环回访问(127.0.0.1)是比较重要的,建议大家都开放:
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
12、屏蔽指定MAC地址
使用如下规则可以屏蔽指定的 MAC 地址:
iptables -A INPUT -m mac --mac-source 00:00:00:00:00:00 -j DROP
13、限制并发连接数
如果你不希望来自特定端口的过多并发连接,可以使用如下规则:
iptables -A INPUT -p tcp --syn --dport 22 -m connlimit --connlimit-above 3 -j REJECT
以上规则限制每客户端不超过 3 个连接。
14、清空IPtables规则
要清空 IPtables 链可以使用如下命令:
iptables -F
要清空特定的表可以使用 -t 参数进行指定,例如:
iptables -t nat –F
15、保存IPtables规则
默认情况下,管理员对 IPtables 规则的操作会立即生效。但由于规则都是保存在内存当中的,所以重启系统会造成配置丢失,要永久保存 IPtables 规则可以使用 iptables-save 命令:
iptables-save > ~/iptables.rules
保存的名称大家可以自己改。
16、还原IPtables规则
有保存自然就对应有还原,大家可以使用 iptables-restore 命令还原已保存的规则:
iptables-restore < ~/iptables.rules
17、允许建立相关连接
随着网络流量的进出分离,要允许建立传入相关连接,可以使用如下规则:
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
允许建立传出相关连接的规则:
iptables -A OUTPUT -m conntrack --ctstate ESTABLISHED -j ACCEPT
18、丢弃无效数据包
很多网络攻击都会尝试用黑客自定义的非法数据包进行尝试,我们可以使用如下命令来丢弃无效数据包:
iptables -A INPUT -m conntrack --ctstate INVALID -j DROP
19、IPtables屏蔽邮件发送规则
如果你的系统不会用于邮件发送,我们可以在规则中屏蔽 SMTP 传出端口:
iptables -A OUTPUT -p tcp --dports 25,465,587 -j REJECT
20、阻止连接到某块网卡
如果你的系统有多块网卡,我们可以限制 IP 范围访问某块网卡:
iptables -A INPUT -i eth0 -s xxx.xxx.xxx.xxx -j DROP
源地址可以是 IP 或 CIDR
设定规则
iptables -p INPUT DROP
iptables -p OUTPUT ACCEPT
iptables -p FORWARD DROP
1、防止外网用内网IP欺骗
iptables -t nat -A PREROUTING -i eth0 -s 10.0.0.0/8 -j DROP
iptables -t nat -A PREROUTING -i eth0 -s 172.16.0.0/12 -j DROP
iptables -t nat -A PREROUTING -i eth0 -s 192.168.0.0/16 -j DROP
查看nat规则
iptables -t nat -L
2、如果想取消上面所加的规则:
iptables -F -t nat
iptables -X -t nat
iptables -Z -t nat
3、阻止一个IP连接本机
iptables -t filter -A INPUT -s 192.168.1.5 -i eth0 -j DROP
4、查看本机的IPTABLES的所填规则
iptables -L -n
5、清除filter中所有的规则连接
iptables -F
清除filter中使用者自定义连接中的规则
iptables -X
6、保存所修改的iptables规则
/etc/rc.d/init.d/iptables save
重新启动iptables服务
service iptables restart
7、关闭不安全的端口连接本机
iptables -A OUTPUT -p tcp --sport 31337 -j DROP
iptables -A OUTPUT -p tcp --dport 31337 -j DROP
8、开启所需要的端口
22
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -A OUTPUT -p tcp --sport 22 -j ACCEPT
80
iptables -A OUTPUT -p tcp --sport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
9、禁止一个IP或者一个IP段访问服务器端口服务
80端口
iptables -t filter -I INPUT 2 -s 192.168.5.0/24 -p tcp --dport http -j DROP
FTP端口
iptables -t filter -I INPUT 2 -s 192.168.7.9 -p tcp --dport ftp -j DROP
一、iptables的表与链
iptables具有Filter, NAT, Mangle, Raw四种内建表:
1. Filter表
Filter表示iptables的默认表,因此如果你没有自定义表,那么就默认使用filter表,它具有以下三种内建链:
- INPUT链 – 处理来自外部的数据。
- OUTPUT链 – 处理向外发送的数据。
- FORWARD链 – 将数据转发到本机的其他网卡设备上。
2. NAT表
NAT表有三种内建链:
- PREROUTING链 – 处理刚到达本机并在路由转发前的数据包。它会转换数据包中的目标IP地址(destination ip address),通常用于DNAT(destination NAT)。
- POSTROUTING链 – 处理即将离开本机的数据包。它会转换数据包中的源IP地址(source ip address),通常用于SNAT(source NAT)。
- OUTPUT链 – 处理本机产生的数据包。
3. Mangle表
Mangle表用于指定如何处理数据包。它能改变TCP头中的QoS位。Mangle表具有5个内建链:
- PREROUTING
- OUTPUT
- FORWARD
- INPUT
- POSTROUTING
4. Raw表
Raw表用于处理异常,它具有2个内建链:
- PREROUTING chain
- OUTPUT chain
5.小结
下图展示了iptables的三个内建表:
图: IPTables 内建表
二、IPTABLES 规则(Rules)
牢记以下三点式理解iptables规则的关键:
- Rules包括一个条件和一个目标(target)
- 如果满足条件,就执行目标(target)中的规则或者特定值。
- 如果不满足条件,就判断下一条Rules。
目标值(Target Values)
下面是你可以在target里指定的特殊值:
- ACCEPT – 允许防火墙接收数据包
- DROP – 防火墙丢弃包
- QUEUE – 防火墙将数据包移交到用户空间
- RETURN – 防火墙停止执行当前链中的后续Rules,并返回到调用链(the calling chain)中。
如果你执行iptables --list你将看到防火墙上的可用规则。下例说明当前系统没有定义防火墙,你可以看到,它显示了默认的filter表,以及表内默认的input链, forward链, output链。
# iptables -t filter --list
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
查看mangle表:
# iptables -t mangle --list
查看NAT表:
# iptables -t nat --list
查看RAW表:
# iptables -t raw --list
/!\注意:如果不指定-t选项,就只会显示默认的filter表。因此,以下两种命令形式是一个意思:
# iptables -t filter --list
(or)
# iptables --list
(or)
# iptables --list
以下例子表明在filter表的input链, forward链, output链中存在规则:
# iptables --list
Chain INPUT (policy ACCEPT)
num target prot opt source destination
1 RH-Firewall-1-INPUT all -- 0.0.0.0/0 0.0.0.0/0
Chain FORWARD (policy ACCEPT)
num target prot opt source destination
1 RH-Firewall-1-INPUT all -- 0.0.0.0/0 0.0.0.0/0
Chain OUTPUT (policy ACCEPT)
num target prot opt source destination
Chain RH-Firewall-1-INPUT (2 references)
num target prot opt source destination
1 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0
2 ACCEPT icmp -- 0.0.0.0/0 0.0.0.0/0 icmp type 255
3 ACCEPT esp -- 0.0.0.0/0 0.0.0.0/0
4 ACCEPT ah -- 0.0.0.0/0 0.0.0.0/0
5 ACCEPT udp -- 0.0.0.0/0 224.0.0.251 udp dpt:5353
6 ACCEPT udp -- 0.0.0.0/0 0.0.0.0/0 udp dpt:631
7 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:631
8 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
9 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:22
10 REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited
Chain INPUT (policy ACCEPT)
num target prot opt source destination
1 RH-Firewall-1-INPUT all -- 0.0.0.0/0 0.0.0.0/0
Chain FORWARD (policy ACCEPT)
num target prot opt source destination
1 RH-Firewall-1-INPUT all -- 0.0.0.0/0 0.0.0.0/0
Chain OUTPUT (policy ACCEPT)
num target prot opt source destination
Chain RH-Firewall-1-INPUT (2 references)
num target prot opt source destination
1 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0
2 ACCEPT icmp -- 0.0.0.0/0 0.0.0.0/0 icmp type 255
3 ACCEPT esp -- 0.0.0.0/0 0.0.0.0/0
4 ACCEPT ah -- 0.0.0.0/0 0.0.0.0/0
5 ACCEPT udp -- 0.0.0.0/0 224.0.0.251 udp dpt:5353
6 ACCEPT udp -- 0.0.0.0/0 0.0.0.0/0 udp dpt:631
7 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:631
8 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
9 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:22
10 REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited
以上输出包含下列字段:
- num – 指定链中的规则编号
target – 前面提到的target的特殊值
prot – 协议:tcp, udp, icmp等
source – 数据包的源IP地址
destination – 数据包的目标IP地址
三、清空所有iptables规则
在配置iptables之前,你通常需要用iptables --list命令或者iptables-save命令查看有无现存规则,因为有时需要删除现有的iptables规则:
iptables --flush
或者
iptables -F
或者
iptables -F
这两条命令是等效的。但是并非执行后就万事大吉了。你仍然需要检查规则是不是真的清空了,因为有的linux发行版上这个命令不会清除NAT表中的规则,此时只能手动清除:
iptables -t NAT -F
四、永久生效
当你删除、添加规则后,这些更改并不能永久生效,这些规则很有可能在系统重启后恢复原样。为了让配置永久生效,根据平台的不同,具体操作也不同。下面进行简单介绍:
1.Ubuntu
首先,保存现有的规则:
iptables-save > /etc/iptables.rules
然后新建一个bash脚本,并保存到/etc/network/if-pre-up.d/目录下:
#!/bin/bash
iptables-restore < /etc/iptables.rules
iptables-restore < /etc/iptables.rules
这样,每次系统重启后iptables规则都会被自动加载。
/!\注意:不要尝试在.bashrc或者.profile中执行以上命令,因为用户通常不是root,而且这只能在登录时加载iptables规则。
2.CentOS, RedHat
# 保存iptables规则
service iptables save
# 重启iptables服务
service iptables stop
service iptables start
service iptables save
# 重启iptables服务
service iptables stop
service iptables start
查看当前规则:
cat /etc/sysconfig/iptables
五、追加iptables规则
可以使用iptables -A命令追加新规则,其中-A表示Append。因此,新的规则将追加到链尾。
一般而言,最后一条规则用于丢弃(DROP)所有数据包。如果你已经有这样的规则了,并且使用-A参数添加新规则,那么就是无用功。
1.语法
iptables -A chain firewall-rule
- -A chain – 指定要追加规则的链
- firewall-rule – 具体的规则参数
2.描述规则的基本参数
以下这些规则参数用于描述数据包的协议、源地址、目的地址、允许经过的网络接口,以及如何处理这些数据包。这些描述是对规则的基本描述。
-p 协议(protocol)
- 指定规则的协议,如tcp, udp, icmp等,可以使用all来指定所有协议。
- 如果不指定-p参数,则默认是all值。这并不明智,请总是明确指定协议名称。
- 可以使用协议名(如tcp),或者是协议值(比如6代表tcp)来指定协议。映射关系请查看/etc/protocols
- 还可以使用–protocol参数代替-p参数
-s 源地址(source)
- 指定数据包的源地址
- 参数可以使IP地址、网络地址、主机名
- 例如:-s 192.168.1.101指定IP地址
- 例如:-s 192.168.1.10/24指定网络地址
- 如果不指定-s参数,就代表所有地址
- 还可以使用–src或者–source
-d 目的地址(destination)
- 指定目的地址
- 参数和-s相同
- 还可以使用–dst或者–destination
-j 执行目标(jump to target)
- -j代表”jump to target”
- -j指定了当与规则(Rule)匹配时如何处理数据包
- 可能的值是ACCEPT, DROP, QUEUE, RETURN
- 还可以指定其他链(Chain)作为目标
-i 输入接口(input interface)
- -i代表输入接口(input interface)
- -i指定了要处理来自哪个接口的数据包
- 这些数据包即将进入INPUT, FORWARD, PREROUTE链
- 例如:-i eth0指定了要处理经由eth0进入的数据包
- 如果不指定-i参数,那么将处理进入所有接口的数据包
- 如果出现! -i eth0,那么将处理所有经由eth0以外的接口进入的数据包
- 如果出现-i eth+,那么将处理所有经由eth开头的接口进入的数据包
-o 输出(out interface)
- -o代表”output interface”
- -o指定了数据包由哪个接口输出
- 这些数据包即将进入FORWARD, OUTPUT, POSTROUTING链
- 如果不指定-o选项,那么系统上的所有接口都可以作为输出接口
- 如果出现! -o eth0,那么将从eth0以外的接口输出
- 如果出现-i eth+,那么将仅从eth开头的接口输出
- 还可以使用–out-interface参数
3.描述规则的扩展参数
对规则有了一个基本描述之后,有时候我们还希望指定端口、TCP标志、ICMP类型等内容。
–sport 源端口(source port)针对 -p tcp 或者 -p udp
- 缺省情况下,将匹配所有端口
- 可以指定端口号或者端口名称,例如”–sport 22″与”–sport ssh”。
- /etc/services文件描述了上述映射关系。
- 从性能上讲,使用端口号更好
- 使用冒号可以匹配端口范围,如”–sport 22:100″
- 还可以使用”–source-port”
–-dport 目的端口(destination port)针对-p tcp 或者 -p udp
- 参数和–sport类似
- 还可以使用”–destination-port”
-–tcp-flags TCP标志 针对-p tcp
- 可以指定由逗号分隔的多个参数
- 有效值可以是:SYN, ACK, FIN, RST, URG, PSH
- 可以使用ALL或者NONE
-–icmp-type ICMP类型 针对-p icmp
- –icmp-type 0 表示Echo Reply
- –icmp-type 8 表示Echo
4.追加规则的完整实例:仅允许SSH服务
本例实现的规则将仅允许SSH数据包通过本地计算机,其他一切连接(包括ping)都将被拒绝。
# 1.清空所有iptables规则
iptables -F
# 2.接收目标端口为22的数据包
iptables -A INPUT -i eth0 -p tcp --dport 22 -j ACCEPT
# 3.拒绝所有其他数据包
iptables -A INPUT -j DROP
iptables -F
# 2.接收目标端口为22的数据包
iptables -A INPUT -i eth0 -p tcp --dport 22 -j ACCEPT
# 3.拒绝所有其他数据包
iptables -A INPUT -j DROP
六、更改默认策略
上例的例子仅对接收的数据包过滤,而对于要发送出去的数据包却没有任何限制。本节主要介绍如何更改链策略,以改变链的行为。
1. 默认链策略
/!\警告:请勿在远程连接的服务器、虚拟机上测试!
当我们使用-L选项验证当前规则是发现,所有的链旁边都有policy ACCEPT标注,这表明当前链的默认策略为ACCEPT:
# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT tcp -- anywhere anywhere tcp dpt:ssh
DROP all -- anywhere anywhere
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT tcp -- anywhere anywhere tcp dpt:ssh
DROP all -- anywhere anywhere
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
这种情况下,如果没有明确添加DROP规则,那么默认情况下将采用ACCEPT策略进行过滤。除非:
a)为以上三个链单独添加DROP规则:
iptables -A INPUT -j DROP
iptables -A OUTPUT -j DROP
iptables -A FORWARD -j DROP
iptables -A OUTPUT -j DROP
iptables -A FORWARD -j DROP
b)更改默认策略:
iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT DROP
iptables -P FORWARD DROP
糟糕!!如果你严格按照上一节的例子配置了iptables,并且现在使用的是SSH进行连接的,那么会话恐怕已经被迫终止了!
为什么呢?因为我们已经把OUTPUT链策略更改为DROP了。此时虽然服务器能接收数据,但是无法发送数据:
# iptables -L
Chain INPUT (policy DROP)
target prot opt source destination
ACCEPT tcp -- anywhere anywhere tcp dpt:ssh
DROP all -- anywhere anywhere
Chain FORWARD (policy DROP)
target prot opt source destination
Chain OUTPUT (policy DROP)
target prot opt source destination
Chain INPUT (policy DROP)
target prot opt source destination
ACCEPT tcp -- anywhere anywhere tcp dpt:ssh
DROP all -- anywhere anywhere
Chain FORWARD (policy DROP)
target prot opt source destination
Chain OUTPUT (policy DROP)
target prot opt source destination
七、配置应用程序规则
尽管5.4节已经介绍了如何初步限制除SSH以外的其他连接,但是那是在链默认策略为ACCEPT的情况下实现的,并且没有对输出数据包进行限制。本节在上一节基础上,以SSH和HTTP所使用的端口为例,教大家如何在默认链策略为DROP的情况下,进行防火墙设置。在这里,我们将引进一种新的参数-m state,并检查数据包的状态字段。
1.SSH
# 1.允许接收远程主机的SSH请求
iptables -A INPUT -i eth0 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
# 2.允许发送本地主机的SSH响应
iptables -A OUTPUT -o eth0 -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
# 2.允许发送本地主机的SSH响应
iptables -A OUTPUT -o eth0 -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT
- -m state: 启用状态匹配模块(state matching module)
- –-state: 状态匹配模块的参数。当SSH客户端第一个数据包到达服务器时,状态字段为NEW;建立连接后数据包的状态字段都是ESTABLISHED
- –sport 22: sshd监听22端口,同时也通过该端口和客户端建立连接、传送数据。因此对于SSH服务器而言,源端口就是22
- –dport 22: ssh客户端程序可以从本机的随机端口与SSH服务器的22端口建立连接。因此对于SSH客户端而言,目的端口就是22
如果服务器也需要使用SSH连接其他远程主机,则还需要增加以下配置:
# 1.送出的数据包目的端口为22
iptables -A OUTPUT -o eth0 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
# 2.接收的数据包源端口为22
iptables -A INPUT -i eth0 -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
# 2.接收的数据包源端口为22
iptables -A INPUT -i eth0 -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT
2.HTTP
HTTP的配置与SSH类似:
# 1.允许接收远程主机的HTTP请求
iptables -A INPUT -i eth0 -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
# 1.允许发送本地主机的HTTP响应
iptables -A OUTPUT -o eth0 -p tcp --sport 80 -m state --state ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
# 1.允许发送本地主机的HTTP响应
iptables -A OUTPUT -o eth0 -p tcp --sport 80 -m state --state ESTABLISHED -j ACCEPT
3.完整的配置
# 1.删除现有规则
iptables -F
# 2.配置默认链策略
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT DROP
# 3.允许远程主机进行SSH连接
iptables -A INPUT -i eth0 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT
# 4.允许本地主机进行SSH连接
iptables -A OUTPUT -o eth0 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT
# 5.允许HTTP请求
iptables -A INPUT -i eth0 -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 80 -m state --state ESTABLISHED -j ACCEPT
iptables -F
# 2.配置默认链策略
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT DROP
# 3.允许远程主机进行SSH连接
iptables -A INPUT -i eth0 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT
# 4.允许本地主机进行SSH连接
iptables -A OUTPUT -o eth0 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT
# 5.允许HTTP请求
iptables -A INPUT -i eth0 -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 80 -m state --state ESTABLISHED -j ACCEPT
开放x-shell连接端口
iptables -A INPUT -s Client-IP -d Server-IP -p tcp --dport 22 -j ACCEPT //放行x-shell入站数据
iptables -A OUTPUT -s Server-IP -d Client-IP -p tcp --sport 22 -j ACCEPT //放行x-shell出站数据
iptables -A INPUT -j DROP
iptables -A OUTPUT -j DROP
默认出站数据最好设置为放行已建立的连接,这样一来就不用单独放行每一条允许入站的数据的出站动作了
iptables -A OUTPUT -m state --state ESTABLISHED -j ACCEPT
开放自己使用ping探测别人
iptables -A INPUT -p icmp --icmp-type 0/0 -j ACCEPT //放行ping响应入站
iptables -A OUTPUT -p icmp --icmp-type 8/0 -j ACCEPT //放行ping请求出站
开放别人使用ping探测自己
iptables -A INPUT -p icmp --icmp-type 8/0 -j ACCEPT //放行ping请求入站
iptabels -A OUTPUT -p icmp --icmp-type 0/0 -j ACCEPT //放行ping响应出站
开放回环检测
iptables -A INPUT -i lo -p icmp -j ACCEPT
开放http连接端口
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
开放https连接端口
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
http、https连接端口合并
iptables -A INPUT -p tcp -m multiport --dports 80,443 -j ACCEPT
开放mysql连接端口
iptables -A INPUT -p tcp --dport 3306 -j ACCEPT
开放fastcgi连接端口
iptables -A INPUT -p tcp --dport 9000 -j ACCEPT
开放samba连接端口
iptables -A INPUT -p tcp multiport --dports 139,445 -j ACCEPT //开放samba主服务端口
iptables -A INPUT -p udp multiport --dports 137,138 -j ACCEPT //开放samba名称解析端口
开放ftp连接端口
iptables -A INPUT -p tcp --dport 21 -m state --state NEW,ESTABLISHED -j ACCEPT //开放ftp服务端口
iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT //开放相关、已建立的连接
开放nfs连接端口
首先到/etc/sysconfig/nfs文件中锁定端口
RQUOTAD_PORT=10001
LOCKD_TCPPORT=10002
LOCKD_UDPPORT=10002
MOUNTD_PORT=10003
STATD_PORT=10004
再开放锁定的多端口
iptables -A INPUT -p tcp multiport --dports 111,2049,10001:10004 -j ACCEPT
iptables -A INPUT -p udp multiport --dports 111,2049,10001:10004 -j ACCEPT
开放dns连接端口
iptables -A INPUT -p tcp --dport 53 -j ACCEPT //开放区域传送端口
iptables -A INPUT -p udp --dport 53 -j ACCEPT //开放解析查询端口
linux下要使用iptables限制只有指定的ip才能访问本机则需要先设置一个默认的规则
iptables有默认的规则,它可以适用于所有的访问
因为只有指定或特定的ip地址才能访问本机
所以可以将默认的规则设置为所有访问全部阻止(当然这里需要注意下,如果你要设置的机器是在远端,比如vps则需要注意在设置默认规则的同时要将与该服务器链接的ip添加进白名单,否则在设置完默认阻止后你也无法访问这台服务器,也无法再进行操作了,我们可以使用分号;或者&&来在同一个命令行下来完成默认阻止和将自己的ip添加进白名单,假如你的ip地址为1.2.3.4则可以这样输入iptables -P INPUT DROP;iptables -A INPUT -s 1.2.3.4 -p tcp -j ACCEPT,或者也可以指定一个端口)
设置默认规则后则可以添加白名单了
比如允许2.3.4.5访问则可以
iptables -A INPUT -s 2.3.4.5 -p tcp -j ACCEPT
如果要限定的不是整个服务器而只是该服务器中的某个服务
比如web服务(一般端口在80,https在443)
则我们可以使用0.0.0.0/0来阻止所有的ip地址
比如
iptables -A INPUT -s 0.0.0.0/0 -p tcp --dport 80 -j DROP
以及
iptables -A INPUT -s 0.0.0.0/0 -p tcp --dport 443 -j DROP
来阻止所有访问web服务器的ip地址
然后再添加指定的ip到白名单
比如添加1.2.3.4,我们可以
iptables -A INPUT -s 1.2.3.4 -p tcp --dport 80 -j ACCEPT
如果我们允许某个网段下的所有ip都可以访问的话比如1.2.3.[0-255],我们可以
iptables -A INPUT -s 1.2.3.0/24 -p tcp --dport -j ACCEPT
总之不管是阻止所有的服务还是只阻止指定的服务
我们可以先将默认的规则设置为所有ip都不可访问
然后再手动添加ip地址到白名单
一、iptables:从这里开始
删除现有规则
iptables -F
(OR)
iptables --flush
设置默认链策略
iptables的filter表中有三种链:INPUT, FORWARD和OUTPUT。默认的链策略是ACCEPT,你可以将它们设置成DROP。
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT DROP
你需要明白,这样做会屏蔽所有输入、输出网卡的数据包,除非你明确指定哪些数据包可以通过网卡。
屏蔽指定的IP地址
以下规则将屏蔽BLOCK_THIS_IP所指定的IP地址访问本地主机:
BLOCK_THIS_IP="x.x.x.x"
iptables -A INPUT -i eth0 -s "$BLOCK_THIS_IP" -j DROP
(或者仅屏蔽来自该IP的TCP数据包)
iptables -A INPUT -i eth0 -p tcp -s "$BLOCK_THIS_IP" -j DROP
允许来自外部的ping测试
iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
iptables -A OUTPUT -p icmp --icmp-type echo-reply -j ACCEPT
允许从本机ping外部主机
iptables -A OUTPUT -p icmp --icmp-type echo-request -j ACCEPT
iptables -A INPUT -p icmp --icmp-type echo-reply -j ACCEPT
允许环回(loopback)访问
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
二、iptables:协议与端口设定
允许所有SSH连接请求
本规则允许所有来自外部的SSH连接请求,也就是说,只允许进入eth0接口,并且目的端口为22的数据包
iptables -A INPUT -i eth0 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT
允许从本地发起的SSH连接
本规则和上述规则有所不同,本规则意在允许本机发起SSH连接,上面的规则与此正好相反。
iptables -A OUTPUT -o eth0 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT
仅允许来自指定网络的SSH连接请求
以下规则仅允许来自192.168.100.0/24的网络:
iptables -A INPUT -i eth0 -p tcp -s 192.168.100.0/24 --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT
上例中,你也可以使用-s 192.168.100.0/255.255.255.0作为网络地址。当然使用上面的CIDR地址更容易让人明白。
仅允许从本地发起到指定网络的SSH连接请求
以下规则仅允许从本地主机连接到192.168.100.0/24的网络:
iptables -A OUTPUT -o eth0 -p tcp -d 192.168.100.0/24 --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT
允许HTTP/HTTPS连接请求
# 1.允许HTTP连接:80端口
iptables -A INPUT -i eth0 -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 80 -m state --state ESTABLISHED -j ACCEPT
# 2.允许HTTPS连接:443端口
iptables -A INPUT -i eth0 -p tcp --dport 443 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 443 -m state --state ESTABLISHED -j ACCEPT
允许从本地发起HTTPS连接
本规则可以允许用户从本地主机发起HTTPS连接,从而访问Internet。
iptables -A OUTPUT -o eth0 -p tcp --dport 443 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp --sport 443 -m state --state ESTABLISHED -j ACCEPT
类似的,你可以设置允许HTTP协议(80端口)。
-m multiport:指定多个端口
通过指定-m multiport选项,可以在一条规则中同时允许SSH、HTTP、HTTPS连接:
iptables -A INPUT -i eth0 -p tcp -m multiport --dports 22,80,443 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp -m multiport --sports 22,80,443 -m state --state ESTABLISHED -j ACCEPT
允许出站DNS连接
iptables -A OUTPUT -p udp -o eth0 --dport 53 -j ACCEPT
iptables -A INPUT -p udp -i eth0 --sport 53 -j ACCEPT
允许NIS连接
如果你在使用NIS管理你的用户账户,你需要允许NIS连接。即使你已允许SSH连接,你仍需允许NIS相关的ypbind连接,否则用户将无法登陆。NIS端口是动态的,当ypbind启动的时候,它会自动分配端口。因此,首先我们需要获取端口号,本例中使用的端口是853和850:
rpcinfo -p | grep ypbind
然后,允许连接到111端口的请求数据包,以及ypbind使用到的端口:
iptables -A INPUT -p tcp --dport 111 -j ACCEPT
iptables -A INPUT -p udp --dport 111 -j ACCEPT
iptables -A INPUT -p tcp --dport 853 -j ACCEPT
iptables -A INPUT -p udp --dport 853 -j ACCEPT
iptables -A INPUT -p tcp --dport 850 -j ACCEPT
iptables -A INPUT -p udp --dport 850 -j ACCEPT
以上做法在你重启系统后将失效,因为ypbind会重新指派端口。我们有两种解决方法:1.为NIS使用静态IP地址2.每次系统启动时调用脚本获得NIS相关端口,并根据上述iptables规则添加到filter表中去。
允许来自指定网络的rsync连接请求
你可能启用了rsync服务,但是又不想让rsync暴露在外,只希望能够从内部网络(192.168.101.0/24)访问即可:
iptables -A INPUT -i eth0 -p tcp -s 192.168.101.0/24 --dport 873 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 873 -m state --state ESTABLISHED -j ACCEPT
允许来自指定网络的MySQL连接请求
你可能启用了MySQL服务,但只希望DBA与相关开发人员能够从内部网络(192.168.100.0/24)直接登录数据库:
iptables -A INPUT -i eth0 -p tcp -s 192.168.100.0/24 --dport 3306 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 3306 -m state --state ESTABLISHED -j ACCEPT
允许Sendmail, Postfix邮件服务
邮件服务都使用了25端口,我们只需要允许来自25端口的连接请求即可。
iptables -A INPUT -i eth0 -p tcp --dport 25 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 25 -m state --state ESTABLISHED -j ACCEPT
允许IMAP与IMAPS
# IMAP:143
iptables -A INPUT -i eth0 -p tcp --dport 143 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 143 -m state --state ESTABLISHED -j ACCEPT
# IMAPS:993
iptables -A INPUT -i eth0 -p tcp --dport 993 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 993 -m state --state ESTABLISHED -j ACCEPT
允许POP3与POP3S
# POP3:110
iptables -A INPUT -i eth0 -p tcp --dport 110 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 110 -m state --state ESTABLISHED -j ACCEPT
# POP3S:995
iptables -A INPUT -i eth0 -p tcp --dport 995 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 995 -m state --state ESTABLISHED -j ACCEPT
防止DoS攻击
iptables -A INPUT -p tcp --dport 80 -m limit --limit 25/minute --limit-burst 100 -j ACCEPT
-m limit: 启用limit扩展
–limit 25/minute: 允许最多每分钟25个连接
–limit-burst 100: 当达到100个连接后,才启用上述25/minute限制
三、转发与NAT
允许路由
如果本地主机有两块网卡,一块连接内网(eth0),一块连接外网(eth1),那么可以使用下面的规则将eth0的数据路由到eht1:
iptables -A FORWARD -i eth0 -o eth1 -j ACCEPT
DNAT与端口转发
以下规则将会把来自422端口的流量转发到22端口。这意味着来自422端口的SSH连接请求与来自22端口的请求等效。
# 1.启用DNAT转发
iptables -t nat -A PREROUTING -p tcp -d 192.168.102.37 --dport 422 -j DNAT --to-destination 192.168.102.37:22
# 2.允许连接到422端口的请求
iptables -A INPUT -i eth0 -p tcp --dport 422 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 422 -m state --state ESTABLISHED -j ACCEPT
假设现在外网网关是xxx.xxx.xxx.xxx,那么如果我们希望把HTTP请求转发到内部的某一台计算机,应该怎么做呢?
iptables -t nat -A PREROUTING -p tcp -i eth0 -d xxx.xxx.xxx.xxx --dport 8888 -j DNAT --to 192.168.0.2:80
iptables -A FORWARD -p tcp -i eth0 -d 192.168.0.2 --dport 80 -j ACCEPT
当该数据包到达xxx.xxx.xxx.xxx后,需要将该数据包转发给192.168.0.2的80端口,事实上NAT所做的是修改该数据包的目的地址和目的端口号。然后再将该数据包路由给对应的主机。但是iptables会接受这样的需要路由的包么?这就由FORWARD链决定。我们通过第二条命令告诉iptables可以转发目的地址为192.168.0.2:80的数据包。再看一下上例中422端口转22端口,这是同一IP,因此不需要设置FORWARD链。
SNAT与MASQUERADE
如下命令表示把所有10.8.0.0网段的数据包SNAT成192.168.5.3的ip然后发出去:
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j snat --to-source 192.168.5.3
对于snat,不管是几个地址,必须明确的指定要snat的IP。假如我们的计算机使用ADSL拨号方式上网,那么外网IP是动态的,这时候我们可以考虑使用MASQUERADE
iptables -t nat -A POSTROUTING -s 10.8.0.0/255.255.255.0 -o eth0 -j MASQUERADE
负载平衡
可以利用iptables的-m nth扩展,及其参数(–counter 0 –every 3 –packet x),进行DNAT路由设置(-A PREROUTING -j DNAT –to-destination),从而将负载平均分配给3台服务器:
iptables -A PREROUTING -i eth0 -p tcp --dport 443 -m state --state NEW -m nth --counter 0 --every 3 --packet 0 -j DNAT --to-destination 192.168.1.101:443
iptables -A PREROUTING -i eth0 -p tcp --dport 443 -m state --state NEW -m nth --counter 0 --every 3 --packet 1 -j DNAT --to-destination 192.168.1.102:443
iptables -A PREROUTING -i eth0 -p tcp --dport 443 -m state --state NEW -m nth --counter 0 --every 3 --packet 2 -j DNAT --to-destination 192.168.1.103:443
自定义的链
记录丢弃的数据包
# 1.新建名为LOGGING的链
iptables -N LOGGING
# 2.将所有来自INPUT链中的数据包跳转到LOGGING链中
iptables -A INPUT -j LOGGING
# 3.指定自定义的日志前缀"IPTables Packet Dropped: "
iptables -A LOGGING -m limit --limit 2/min -j LOG --log-prefix "IPTables Packet Dropped: " --log-level 7
# 4.丢弃这些数据包
iptables -A LOGGING -j DROP