iptables
- 防火墙
- 防火墙的分类
- Netfilter
- 链的概念
- 表的概念
- 表链的关系
- iptables规则的匹配
- iptables 的命令
- 查询规则
- 添加规则
- 删除规则
- 修改规则
- 保存规则
- iptables的扩展模块
- Tcp模块
- multiport模块
- iprange模块
- string模块
- time模块
- connlimit模块
- limit模块
- udp模块
- icmp模块
- state模块
- 其他
防火墙
在计算中,防火墙是基于预定安全规则来监视和控制传入和传出网络流量的网络安全系统。该计算机流入流出的所有网络通信均要经过此防火墙。防火墙对流经它的网络通信进行扫描,这样能够过滤掉一些,以免其在目标计算机上被执行。防火墙还可以关闭不使用的端口。而且它还能禁止特定端口的流出通信,封锁特洛伊木马。最后,它可以禁止来自特殊站点的访问,从而防止来自不明入侵者的所有通信。
防火墙的分类
防火墙分为硬件防火墙和软件防火墙:
硬件防火墙:拥有经过特别设计的硬件及芯片,性能高、成本高(当然硬件防火墙也是有软件的,只不过有部分功能由硬件实现,所以硬件防火墙其实是硬件+软件的方式)。
软件防火墙:应用软件处理逻辑运行于通用硬件平台之上的防火墙,性能比硬件防火墙低、成本低。
Netfilter
Netfilter是由Rusty Russell提出的Linux 2.4内核防火墙框架,该框架既简洁又灵活,可实现安全策略应用中的许多功能,如数据包过滤、数据包处理、地址伪装、透明代理、动态网络地址转换(Network Address Translation,NAT),以及基于用户及媒体访问控制(Media Access Control,MAC)地址的过滤和基于状态的过滤、包速率限制等。
功能
- 网络地址转换(Network Address Translate)
- 数据包内容修改
- 以及数据包过滤的防火墙功能
链的概念
iptables开启后,数据报文从进入服务器到出来会经过5道关卡,分别为Prerouting(路由前)、Input(输入)、Output(输出)、Forward(转发)、Postrouting(路由后):
每个程序中有多条规则,数据报文进入后需要进行一条一条的进行匹配,这些规则串起来就像是一条链。
- INPUT链: 当接收到防火墙本机地址的数据包(入站)时,应用此链中的规则;
- OUTPUT链: 当防火墙本机向外发送数据包(出站)时,应用此链中的规则;
- FORWARD链: 当接收到需要通过防火墙发送给其他地址的数据包(转发)时,应用此链中的规则;
- PREROUTING链:(互联网进入局域网)在对数据包作路由选择之前,应用此链中的规则,如DNAT;
- POSTROUTING链:(局域网出互联网)在对数据包作路由选择之后,应用此链中的规则,如SNAT。
表的概念
虽然每一条链上有多条规则,但有些规则的作用(功能)很相似,多条具有相同功能的规则合在一起就组成了一个“表”,iptables提供了四种“表”:
– filter表: 主要用于对数据包进行过滤,根据具体的规则决定是否放行该数据包(如DROP、ACCEPT、REJECT、LOG),所谓的防火墙其实基本上是指这张表上的过滤规则,对应内核模块iptables_filter;
– nat表: network address translation,网络地址转换功能,主要用于修改数据包的IP地址、端口号等信息(网络地址转换,如SNAT、DNAT、MASQUERADE、REDIRECT)。属于一个流的包(因为包的大小限制导致数据可能会被分成多个数据包)只会经过这个表一次,如果第一个包被允许做NAT或Masqueraded,那么余下的包都会自动地被做相同的操作,也就是说,余下的包不会再通过这个表。对应内核模块iptables_nat;
– mangle表: 拆解报文,做出修改,并重新封装,主要用于修改数据包的TOS(Type Of Service,服务类型)、TTL(Time To Live,生存周期)指以及为数据包设置Mark标记,以实现Qos(Quality Of Service,服务质量)调整以及策略路由等应用,由于需要相应的路由设备支持,因此应用并不广泛。对应内核模块iptables_mangle;
– raw表: 是自1.2.9以后版本的iptables新增的表,主要用于决定数据包是否被状态跟踪机制处理,在匹配数据包时,raw表的规则要优先于其他表,对应内核模块iptables_raw。
表链的关系
5条链(即5个关卡)中,并不是每条链都能应用所有类型的表,事实上除了Ouptput链能同时有四种表,其他链都只有两种或三种表:
iptables规则的匹配
匹配的条件
- S_IP: source ip,源ip
- S_PORT: source port,源端口
- D_IP: destination ip,目标ip
- D_PORT: destination port,目标端口
- TCP/UDP: 第四层(传输层)协议
这就类似于我们网络中的五元组。
处理的动作
- ACCEPT: 允许数据包通过;
- DROP: 直接丢弃数据包,不回应任何信息,客户端只有当该链接超时后才会有反应;
- REJECT: 拒绝数据包,会给客户端发送一个数据包被丢弃的响应的信息;
- SNAT: S指Source,源NAT(源地址转换)。在进入路由层面的route之后,出本地的网络栈之前,改写源地址,目标地址不变,并在本机建立NAT表项,当数据返回时,根据NAT表将目的地址数据改写为数据发送出去时候的源地址,并发送给主机。解决私网用户用同一个公网IP上网的问题;
- MASQUERADE: 是SNAT的一种特殊形式,适用于动态的、临时会变的IP上;
- DNAT: D指Destination,目的NAT,解决私网服务端,接收公网请求的问题。和SNAT相反,IP包经过route之前,重新修改目标地址,源地址不变,在本机建立NAT表项,当数据返回时,根据NAT表将源地址修改为数据发送过来时的目标地址,并发给远程主机。可以隐藏后端服务器的真实地址;
- REDIRECT: 在本机做端口映射;
- LOG: 在
/var/log/messages
文件中记录日志信息,然后将数据包传递给下一条规则。
除去最后一个LOG,前3条规则匹配数据包后,该数据包不会再往下继续匹配了,所以编写的规则顺序极其关键。
iptables 的命令
启动iptables
service iptables start
CentOS7默认没有iptables(CentOS7默认防火墙是firewalld),但我们还是可以自己安装iptables。
centos安装iptables:
[root@localhost ~]# yum install iptables-services -y
启用iptables服务:
[root@localhost ~]# systemctl restart iptables
其他操作
查看iptables状态
systemctl status iptables
停止iptables
systemctl stop iptables
重启iptables
systemctl restart iptables
重载iptables
systemctl reload iptables
查询规则
命令格式:iptables [选项] [参数]
-L
: list的缩写,list我们通常翻译成列表,意思是列出每条链上的规则,因为多条规则就是一个列表,所以用-L
来表示。-L
后面还可以跟上5条链(POSTROUTING、INPUT、FORWARD、OUTPUT、POSTROUTING)的其中一条链名,注意链名必须全大写,如查看“INPUT链”上的规则:
iptables -L INPUT
[root@localhost ~]# iptables -L INPUT
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED
ACCEPT icmp -- anywhere anywhere
ACCEPT all -- anywhere anywhere
ACCEPT tcp -- anywhere anywhere state NEW tcp dpt:ssh
REJECT all -- anywhere anywhere reject-with icmp-host-prohibited
不指定的话就是默认查看所有链上的规则列表。
-t
:默认参数-t
,t是table的缩写,意思是指定显示哪张“表”中的规则(前面说过iptables有四种表),iptables -L
其实就相当于iptables -t filter -L
,即相当于你查看的是“filter”表中的规则。而根据前面的讲解,filter表只可用于INPUT、FORWARD、OUTPUT三条链中,这就是为什么iptables -L
不显示PREROUTING链和POSTROUTING链的原因。
-n
: numeric的缩写,numeric意思是数字的,数值的,意思是指定源和目标地址、端口什么的都以数字/数值的方式显示,否则默认会以域名/主机名/程序名等显示,该选项一般与-L
合用,因为单独的-n
是没有用的(没有-L
列表都不显示,所以用-n
就没有意义了)。
v:-v
在Linux命令里,一般都是指“verbose”,这个词的意思是是“冗余的,啰嗦的”,即输出更加详细的信息,在iptables这里也是这个意思,一般可以跟-L
连用。
iptables -v -L
-x
: 加了-v
后,Policy那里变成了“(policy ACCEPT 0 packets, 0 bytes)”,即多了过滤的数据包数量和字节数,其中的字节数,如果数据大了之后,会自动转换单位,比如够KB不够MB,它会显示“xxxk”,够了MB它显示“MB”,但单位转换之后,就不完全精确了,因为它没有小数,如果还是想要看以“字母”即“byptes”为单位查看的话,加个-x
就行了,“x”来自于“exact”,意思是“精确的;准确的”,不取首字母应该是太多选项首字母是e了。
--line-numbers
: 如果你想列表有序号,可以加上该选项。
iptables -nxvL --line-numbers
[root@localhost ~]# iptables -nvxL --line-numbers
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
num pkts bytes target prot opt in out source destination
1 230 16472 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
2 0 0 ACCEPT icmp -- * * 0.0.0.0/0 0.0.0.0/0
3 0 0 ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0
4 0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:22
5 16 2305 REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
num pkts bytes target prot opt in out source destination
1 0 0 REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited
Chain OUTPUT (policy ACCEPT 168 packets, 12920 bytes)
num pkts bytes target prot opt in out source destination
添加规则
向INPUT链的filter表中添加一条规则:
iptables -t filter -I INPUT -s 10.37.129.2 -j DROP
-
-t
: 是指定插入到哪个表中,不写的话默认为“filter”表; -
-I
: 指定插入到哪条链中,并且会在该链指定表(在这里是filter表)中的最前面插入(I:Input),如果用-A
则是在最后插入(A:Append)。 -
-s
: 匹配源ip,s: source,源。 -
-j
: jump,跳转的意思,后面可指定跳转的target(目标),比如自定义的链,当然更多的是跳转到“action(动作)”中,比如ACCEPT、DROP、REJECT等等。
删除规则
1.根据编号删除
iptables -t filter -D INPUT 2
-t filter
指定操作的表为filter表,-D
表示delete,后面跟的两个参数,第一个是链名,第二个是要删除的规则的编号。
2.根据条件删除
iptables -t filter -D INPUT -s 10.37.129.2 -j DROP
3.清除-F
: flush的缩写,flush是“冲洗、冲掉”的意思,在这里是清空的意思,iptables -t filter -F INPUT
代表清空“INPUT”链中“filter”表中的所有规则,如果不指定链不指定表,即直接用iptables -F
,则清空所有链中所有表的规则。
修改规则
iptables -t filter -R INPUT 1 -s 10.37.129.3 -j ACCEPT
其中的-R
就是replace,即替换的意思,整句命令意思是从INPUT链中的filter表中替换编号为1的规则,编号1后面的-s 10.37.129.3 -j ACCEPT
就是要替换成的新规则。
iptables -P FORWARD DROP
-P
: policy,即策略。整个意思是把FORWARD链的默认规则设置为DROP。
保存规则
service iptables save
保存时它会输出:
iptables: Saving firewall rules to /etc/sysconfig/iptables:[ OK ]
iptables的扩展模块
Tcp模块
-p tcp -m tcp --sport
用于匹配tcp协议报文的源端口。
iptables -t filter -I OUTPUT -d 192.168.1.146 -p tcp -m tcp --sport 22 -j REJECT
iptables -t filter -I INPUT -s 192.168.1.146 -p tcp -m tcp --dport 22:25 -j REJECT
iptables -t filter -I INPUT -s 192.168.1.146 -p tcp -m tcp --dport :22 -j REJECT
iptables -t filter -I INPUT -s 192.168.1.146 -p tcp -m tcp --dport 80: -j REJECT
iptables -t filter -I OUTPUT -d 192.168.1.146 -p tcp -m tcp ! --sport 22 -j ACCEPT
multiport模块
-p tcp -m multiport --sports
用于匹配报文的源端口,可以指定离散的多个端口号,端口之间用”逗号”隔开;-p udp -m multiport --dports
用于匹配报文的目标端口,可以指定离散的多个端口号,端口之间用”逗号”隔开:
iptables -t filter -I OUTPUT -d 192.168.1.146 -p udp -m multiport --sports 137,138 -j REJECT
iptables -t filter -I INPUT -s 192.168.1.146 -p tcp -m multiport --dports 22,80 -j REJECT
iptables -t filter -I INPUT -s 192.168.1.146 -p tcp -m multiport ! --dports 22,80 -j REJECT
iptables -t filter -I INPUT -s 192.168.1.146 -p tcp -m multiport --dports 80:88 -j REJECT
iptables -t filter -I INPUT -s 192.168.1.146 -p tcp -m multiport --dports 22,80:88 -j REJECT
iprange模块
用iprange扩展模块可以指定”一段连续的IP地址范围”,用于匹配报文的源地址或者目标地址。
– --src-range
(匹配源地址范围)
– --dst-range
(匹配目标地址范围)
iptables -t filter -I INPUT -m iprange --src-range 192.168.1.127-192.168.1.146 -j DROP
string模块
假设我们访问的是“http://192.168.1.146/index.html”,当“index.html”中包括字符时,就会被以下规则匹配上:
iptables -t filter -I INPUT -m string --algo bm --string" -j REJECT
-m string
:表示使用string模块--algo bm
:表示使用bm算法来匹配index.html中的字符串,“algo”是“algorithm”的缩写。
time模块
我们可以通过time扩展模块,根据时间段区匹配报文,如果报文到达的时间在指定的时间范围以内,则符合匹配条件。
每天早上9点到下午6点不能看网页:
iptables -t filter -I INPUT -p tcp --dport 80 -m time --timestart 09:00:00 --timestop 18:00:00 -j REJECT
iptables -t filter -I INPUT -p tcp --dport 443 -m time --timestart 09:00:00 --timestop 18:00:00 -j REJECT
周六日不能看网页:
iptables -t filter -I INPUT -p tcp --dport 80 -m time --weekdays 6,7 -j REJECT
iptables -t filter -I INPUT -p tcp --dport 443 -m time --weekdays 6,7 -j REJECT
匹配每月22,23号:
iptables -t filter -I INPUT -p tcp --dport 80 -m time --monthdays 22,23 -j REJECT
connlimit模块
使用connlimit扩展模块,可以限制每个IP地址同时链接到server端的链接数量,注意:我们不用指定IP,其默认就是针对”每个客户端IP”,即对单IP的并发连接数限制。
限制22端口(ssh默认端口)连接数量上限不能超过2个:
iptables -t filter -I INPUT -p tcp --dport 22 -m connlimit --connlimit-above 2 -j REJECT
对--connlimit-above
取反:
iptables -t filter -I INPUT -p tcp --dport 22 -m connlimit ! --connlimit-above 2 -j REJECT
表示连接数量只要不超过两个就允许连接,至于超过两个并不一定不允许连接,这得看默认策略是ACCEPT还是DROP或REJECT,又或者有其它规则对它进行限制。
limit模块
limit模块是限速用的,用于限制“单位时间内流入的数据包的数量”。
每6秒放行一下ping包:
iptables -t filter -I INPUT -p icmp -m limit --limit 10/minute -j ACCEPT
--limit
后面的单位除了minute,还可以是second、hour、day。
udp模块
dp扩展模块中能用的匹配条件比较少,只有两个,就是--sport
与--dport
,即匹配报文的源端口与目标端口。
放行samba服务的137和138端口:
iptables -t filter -I INPUT -p udp -m udp --dport 137 -j ACCEPT
iptables -t filter -I INPUT -p udp -m udp --dport 138 -j ACCEPT
当使用扩展匹配条件时,如果未指定扩展模块,iptables会默认调用与-p
对应的协议名称相同的模块,所以,当使用-p udp
时,可以省略-m udp
:
iptables -t filter -I INPUT -p udp --dport 137 -j ACCEPT
iptables -t filter -I INPUT -p udp --dport 138 -j ACCEPT
iptables -t filter -I INPUT -p udp --dport 137:157 -j ACCEPT
--dport 137:157
表示匹配137-157之间的所有端口。
icmp模块
ping是使用icmp协议的,假设要禁止所有icmp协议的报文进入本机。
你ping别人能ping通
别人ping你不行
iptables -t filter -I INPUT -p icmp -j REJECT
1、别人ping本机时,无法ping通,因为数据报文无法进入;
2、本机ping别人时,虽然数据包可以出去,但别人的响应包也是icmp协议,无法进来(即“有去无回”)。
所以这样设置会导致,不止别人ping不通本机,本机也ping不通别人。
state模块
在TCP/IP协议簇中,UDP和ICMP是没有所谓的连接的,但是对于state模块来说,tcp报文、udp报文、icmp报文都是有连接状态的。
接”中的报文可以分为5种状态,报文状态可以为NEW、ESTABLISHED、RELATED、INVALID、UNTRACKED。
放行RELATED和ESTABLISHED状态的报文:
iptables -t filter -I INPUT -m state --state RELATED, ESTABLISHED -j ACCEPT
其他
报文在经过iptables的链时,会匹配链中的规则,遇到匹配的规则时,就执行对应的动作,如果链中的规则都无法匹配到当前报文,则使用链的默认策略(默认动作),链的默认策略通常设置为ACCEPT或者DROP。
当链的默认策略设置为ACCEPT时,如果对应的链中没有配置任何规则,就表示接受所有的报文,如果对应的链中存在规则,但是这些规则没有匹配到报文,报文还是会被接受。