防火墙,就是用于实现访问控制的功能的,它分为硬件的和软件的防火墙两种。无论是在哪个网络中,防火墙工作的地方一定是在网络的边缘。而我们的任务就是需要去定义到底防火墙如何工作,这就是防火墙的策略-规则,以达到让它对出入网络的IP
、数据进行检测。
目前市面上比较常见的有3、4层的防火墙,叫网络层的防火墙,还有7层的防火墙,其实是代理层的网关。
对于TCP/IP
的七层模型来讲,我们知道第三层是网络层,三层的防火墙会在这层对源地址和目标地址进行检测。但是对于七层的防火墙,不管你源端口或者目标端口,源地址或者目标地址是什么,都将对你所有的内容进行检查。所以,对于设计原理来讲,七层防火墙更加安全,但是这却带来了效率更低。所以市面上通常的防火墙方案,都是两者结合的。而又由于我们都需要从防火墙所控制的这个口来访问,所以防火墙的工作效率就成了用户能够访问数据多少的一个最重要的控制,配置的不好甚至有可能成为流量的瓶颈。
netfilter
与iptables
Netfilter
是由Rusty Russell
提出的Linux 2.4
内核防火墙框架,该框架既简洁又灵活,可实现安全策略应用中的许多功能,如数据包过滤、数据包处理、地址伪装、透明代理、动态网络地址转换,以及基于用户及媒体MAC
地址的过滤和基于状态的过滤、包速率限制等。iptables
是为用户提供的Netfilter
管理工具,用于实现对内核中网络防火墙的管理防火墙策略一般分为两种,一种叫通
策略,一种叫堵
策略。通策略,默认门是关着的,必须要定义谁能进;堵策略则是,大门是洞开的,但是你必须有身份认证,否则不能进。所以我们要定义,让进来的进来,让出去的出去,所以通,是要全通,而堵,则是要选择。当我们定义的策略的时候,要分别定义多条功能。其中:定义数据包中允许或者不允许的策略,filter
过滤的功能;而定义地址转换的功能的则是nat
选项。为了让这些功能交替工作,我们制定出了表
这个定义,来定义、区分各种不同的工作功能和处理方式。
描述了iptables
功能的大类,如包过滤(filter)或网络地址转换(NAT)。共定义了5个表。
raw 用于配置数据包,raw中的数据包不会被系统跟踪
filter(过滤)用于过滤本机流入、流出的数据包。是iptables
默认使用的表。
nat(网络地址转换)用于五元组的转换
mangle(变更)主要用于修改数据包中的路由标记。如TTL
TOS
MARK
等。
security用于强制访问控制网络规则(例如: SELinux – 详细信息参考 该文章)
大部分情况仅需要使用filter
和nat
iptables
是工作在用户空间的,它可以让规则进行生效的,本身不是一种服务,而且规则是立即生效的。而我们iptables
现在被做成了一个服务,可以进行启动,停止的。启动,则将规则直接生效,停止,则将规则撤销。iptables
还支持自己定义链。但是自己定义的链,必须是跟某种特定的链关联起来的。
注意:规则的次序非常关键,检查规则的时候,是按照从上往下的方式进行检查,如果匹配到对应规则,则执行动作,不再往下匹配。
每个表都有自己的一组内置链,用户还可以自定义链,这样用户就可以建立一组规则,它们都关联到一个共同的标签如MYCHAIN
。默认定义了五个链
PREROUTING
路由前,数据包进入本机,进入路由表之前INPUT
数据包通过路由表后,目的地为本机FORWARD
数据包通过路由表后,目的地不为本机OUTPUT
由本机发出的数据包POSTROUTING
数据包通过路由表后,发送至出口网卡前表跟链的关系图
详细的数据包流经图
只关注filter
和nat
表的数据包流经图
iptables [-t 表]
<命令>
[链]
[规则号码]
[匹配条件]
[-j 匹配后的动作]
来自192.168.2.0/24
的icmp
全部DROP
iptables -t filter -A INPUT -s 192.168.2.0/24 -p icmp -j DROP
-L
- -t 接表名,如果不加-t,默认是-t filter
- -n 以数字的方式显示ip port
- -v 显示详细信息
- -x 在计数器上显示精确值,不做单位换算
- –line-numbers 显示规则的行号
查看filter表所有规则: iptables -L(没加 -t 默认查看的是filter表)
iptables -vnL # 等价于iptables -t filter -vnL
查看nat表所有规则
iptables -t nat -vnL
查看filter表的INPUT链规则
iptables -vnL INPUT
查看filter表所有规则并显示行号
iptables -t filter -vnL --line-numbers
-P 设置默认策略
当数据包不在我们设置的规则之内时,则该数据包的通过与否,是以策略的设置为准。
默认策略一般只有两种:
iptables -P INPUT 默认是关/开的
iptables -P INPUT DROP
这就把默认规则给拒绝了。并且没有定义哪个动作,所以远程连接ssh
都被拒绝了。
-F 清空规则链的(注意每个链的管理权限)
iptables -t filter -F # 清空filter表的所有链
iptables -t filter -F OUTPUT # 清空filter表的OUTPUT链
-N 新建一个用户自定义链
iptables -N MYCHAIN
-E 用来Rename chain
主要是用来给用户自定义的链重命名
iptables -E MYCHAIN MYNEWCHAIN
-X 用于删除用户自定义的空链使用方法跟-N
相同,但是在删除之前必须要将里面的链给清空了
iptables -X MYNEWCHAIN
-Z 清空链,及链中默认规则的计数器的(有两个计数器,被匹配到的数据包数、字节数,使用iptales -vnL
查看)
iptables -Z # 默认只清空filter链
iptables -t nat -Z
-A chain 追加,在当前链的最后新增一个规则
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 80 -j DROP
只有把ACCEPT
规则删除才能DROP
-I chain num : 插入,把当前规则插入为第几条,默认第一条
iptables -I INPUT -p tcp --dport 80 -j DROP
-R chain num:Replays替换/修改第几条规则
iptables -R INPUT 1 -p tcp --dport 81 -j DROP
-D chain num:删除,明确指定删除第几条规则
iptables -t filter -D INPUT 1
每个iptables
规则都包含一组匹配以及一个目标,后者告诉iptables
对于符合规则的数据包应该采取什么动作。iptables
匹配指的是数据包必须匹配的条件,只有当数据包满足所有的匹配条件时,iptables
才能根据由该规则的目标所指定的动作来处理该数据包。
每个匹配都在iptables
命令行中指定。常用的iptables
匹配如下:
匹配源地址或网络,这里不能指定主机名称,必须是IP IP | IP/MASK | 0.0.0.0/0.0.0.0,而且地址可以取反,加一个!
匹配目标地址或网络
匹配上层协议(TCP/UDP/ICMP/ALL)
匹配流入接口,一般用在INPUT
和PREROUTING
上
流出接口,一般在OUTPUT
和POSTROUTING
上
匹配 分片的包的第二片或及以后的部分
tcp udp icmp all
指定端口,不能指定多个非连续端口,只能指定单个端口或多个连续的端口。不指定此项,则默认所有端口。
从80
到90
目的端口全部DROP
iptables -A INPUT -p tcp --dport 80:90 -j DROP
从0
到80
的所有目的端口端口全部DROP
iptables -A INPUT -p tcp --dport :80 -j DROP
从80
到65535
的所有目的端口全部DROP
iptables -A INPUT -p tcp --dport 80: -j DROP
TCP的标志位(SYN
ACK
FIN
PSH
RST
URG
)
匹配SYN
标记被设置而FIN
和ACK
标记没有设置的包
iptables -p tcp --tcp-flags SYN,FIN,ACK SYN -j ACCEPT
匹配所有标记都未置的包
iptables -p tcp --tcp-flags ALL NONE -j DROP
匹配SYN
标记被设置而ACK
和RST
标记没有设置的包,等同于下命令
iptables -p tcp --tcp-flags SYN,RST,ACK SYN
根据选项匹配包
与tcp
一样
根据ICMP类型匹配包
echo-request
(请求数据包)一般用8
来表示
echo-reply
(响应数据包)一般用0
来表示
用于检测会话之间的连接关系的。对于整个TCP协议来讲,它是一个有连接的协议,三次握手中,第一次握手,我们就叫NEW连接,而从第二次握手完成的ack都为1,这是正常的数据传输,和tcp的第二次第三次握手,叫做已建立的连接(ESTABLISHED);还有一种状态,比较诡异的,比如:SYN=1 ACK=1 RST=1,对于这种我们无法识别的,我们都称之为INVALID
无法识别的;还有第四种,FTP这种古老的拥有的特征,每个端口都是独立的,21号和20号端口都是一去一回,他们之间是有关系的,这种关系我们称之为RELATED。所以我们的状态一共有四种:
格式
-m state --state 状态
示例
iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
比如进来的只允许状态为NEW
和ESTABLISHED
的进来,出去只允许ESTABLISHED
的状态出去,这就可以将比较常见的反弹式木马有很好的控制机制。
mac
匹配阻断来自00:0c:29:a7:bb:99
MAC
地址的数据包通过本机
iptables -A INPUT -m mac --mac-source 00:0c:29:a7:bb:99 -j DROP
格式
单位时间连接控制,使用/second
/minute
/hour
/day
等单位为后缀,默认是3/hour
--limit RATE
间的连接的并发连接控制,默认为5
--limit-burst N
示例
限制目的ip为192.168.2.201
每秒3个包
iptables -A INPUT -d 192.168.2.201 -m limit --limit 3/s -j ACCEPT
iptables -A INPUT -d 192.168.2.201 -j DROP
limit
英语上看是限制的意思,但实际上只是按一定速率去匹配而已,要想限制的话后面要再跟一条DROP
格式
-m iprange [!] <--src-range|--dst-range> IPADDR-IPADDR
源ip
从192.168.2.202
到192.168.2.220
的tcp
包全部DROP
iptables -A INPUT -p tcp -m iprange --src-range 192.168.2.202-192.168.2.220 -j DROP
用来匹配多个不连续的端口,最多能够匹配 15 个不连续的源端口。
格式
-m multiport [!] <--sports|--dports|--ports> port1[,port2,..,portn]
匹配80
和90
目的端口都被DROP
iptables -A INPUT -p tcp -m multiport --dports 80,90 -j DROP
必须与-p
参数一起使用
根据 IP 头里的 TTL (Time To Live,即生存期)字段来匹配包
–ttl-eq –ttl-gt –ttl-lt
iptables -A INPUT -p icmp -m ttl --ttl-eq 64 -j DROP
匹配起始时间与结束时间
-m time --datestart YYYY[-MM[[-DD[Thh[:mm[:ss]]]]] --datestop YYYY[-MM[-DD[Thh[:mm[:ss]]]]]
根据时间和星期几来匹配
--timestart hh:mm[:ss] --timestop hh:mm[:ss] [!] --monthdays day[,day...]
--timestart hh:mm[:ss] --timestop hh:mm[:ss] [!] --weekdays day[,day...]
每周的周六日拒绝ping
iptables -A INPUT -p icmp -m time --timestart 00:00:01 --timestop 23:59:59 --weekdays Sat,Sun -j DROP
iptables
支持一组目标和跳转,它们告诉一条规则当报文完全匹配该条规则的时候,应该怎么处
理此报文。
常用的目标如下:
允许数据包通过
丢弃数据包,不对该数据包做进一步处理,对接受栈而言,就好像该数据包从来没有被接收一样
将数据包信息记录到rsyslog
中
--log-level
所有级别debug,info,notice,warning,warn,err,error,crit,alert, emerg,panic
--log-prefix
在记录的信息之前加上指定的前缀,前缀最多能有29
个英文字符
–log-tcp-sequence
–log-tcp-options
–log-ip-options
需要在/etc/rsyslog.conf
添加一条配置kern.=info /var/log/firewall.log
,然后重启rsyslog
服务
iptables -A INPUT -p icmp -j LOG --log-prefix ICMP_ --log-level info
丢弃数据包,同时发生适当的响应报文(如:针对TCP
连接的RST
包或针对UDP
的ICMP
端口不可达消息)
--reject-with
指定返回什么样的信息
例子
iptables -A INPUT -p tcp --dport 80 -j REJECT --reject-with tcp-reset
iptables -A INPUT -p tcp --dport 81 -j REJECT --reject-with net-unreach
iptables -A INPUT -p tcp --dport 82 -j REJECT --reject-with host-unreach
iptables -A INPUT -p tcp --dport 83 -j REJECT --reject-with icmp-net-unreachable
iptables -A INPUT -p tcp --dport 85 -j DROP
对于目标地址转换,数据流向是从外向内的,外面的是客户端,里面的是服务器端通过目标地址转换,我们可以让外面的IP
通过我们对外的外网IP
来访问我们服务器不同的服务器,而我们的服务却放在内网服务器的不同的服务器上。
–to-destination
iptables -t nat -A PREROUTING -d 192.168.2.201 -p tcp --dport 80 -j DNAT --to-destination 192.168.2.202
注意:目标地址转换要做在到达网卡之前进行转换,所以要做在PREROUTING
这个位置上
基于原地址的转换一般用在我们的许多内网用户通过一个外网的口上网的时候,这时我们将内网地址转换为一个外网的IP
,我们就可以实现连接公网的功能。
--to-source
指定源地址和端口,可以是单独的ip
也可以是ip
段
将所有192.168.2.0/24
段的IP
在经过的时候全都转换成172.16.100.1
这个是外网地址
iptables -t nat -A POSTROUTING -s 192.168.2.0/24 -j SNAT --to-source 172.16.100.1
动态源地址伪装,自动查找可用的IP地址,当外网接口是通过ppp拨号上网时,拨到的公网地址可能会不通
--to-ports
设置外出包能使用的端口,可以省略
iptables -t nat -A POSTROUTING -s 192.168.2.0/24 -j MASQUERADE
iptables -t nat -A POSTROUTING -s 192.168.2.0/24 -j MASQUERADE --to-ports 80-90
在防火墙所在的机子内部转发包或流到另一个端口
–to-ports
将外网访问80端口的数据转发到8080端口
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 81
将外网访问80端口的数据转发到81-89端口
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 81-89
打防火墙标记
在父链中继续处理数据包
注意:你所定义的所有内容,当你重启的时候都会失效,要想我们能够生效,需要使用一个命令将它保存起来
iptables-save
命令iptables-save > /etc/sysconfig/iptables
在开机的时候,会自动加载/etc/sysconfig/iptabels
,如果开机不能加载或者没有加载,而你想让一个自己写的配置文件(假设为iptables.test)手动生效的话:iptables-restore < /etc/sysconfig/iptables.test
则完成了将iptables.test
中定义的规则手动生效。
cat /etc/sysconfig/iptables
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-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 22 -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
COMMIT
说明: ACCEPT后面的[0:0]表示通过该规则的数据包和字节总数
iptables
是一个非常重要的工具,它是每一个防火墙上几乎必备的设置,也是我们在做大型网络的时候,为了很多原因而必须要设置的。学好iptables
,可以让我们对整个网络的结构有一个比较深刻的了解,同时,我们还能够将内核空间中数据的走向以及Linux
的安全给掌握的非常透彻。我们在学习的时候,尽量能结合着各种各样的项目,实验来完成,这样对你加深iptables
的配置,以及各种技巧有非常大的帮助。
netfilter官网文档
How to edit iptables rules/zh-cn