一、防火墙
防火墙主要用来依据策略对穿越防火墙的流量进行过滤,iptables与firewalld是linux系统中用来定义防火墙策略的防火墙管理工具。
iptables服务会把配置好的防火墙策略交由内核层面的netfilter网络过滤器来处理,而firewalld服务则是把配置好的防火墙策略交由内核层面的nftables包过滤框架来处理。
防火墙会从上至下的顺序来读取配置的策略规则,在找到匹配项后就立即结束匹配工作并去执行匹配项中定义的行为(即放行或阻止)。如果在读取完所有的策略规则之后没有匹配项,就去执行默认的策略。
一般而言,防火墙策略规则的设置有两种:一种是"通"(即放行),一种是"堵"(即阻止)。当防火墙的默认策略为拒绝时(堵),就要设置允许规则(通),否则谁都进不来;如果防火墙的默认策略为允许时,就要设置拒绝规则,否则谁都能进来,防火墙也就失去了防范的作用。
二、iptables
(1)四表五链
四表:
名称 | 作用 |
---|---|
filter | 主要用于过滤数据包。包含INPUT、OUTPUT、FORWARD链。 |
nat | 主要用于NAT网络地址转换。包含INPUT、OUTPUT、PREROUTING、POSTROUTING链。 |
mangle | 主要用于修改数据包中的原数据。包含INPUT、OUTPUT、FORWARD、PREROUTING、POSTROUTING链。 |
raw | 主要用于决定数据包是否被状态跟踪机制处理。包含OUTPUT、PREROUTING链 |
五链:
名称 | 作用 |
---|---|
INPUT | 处理流入的数据包 |
OUTPUT | 处理流出的数据包 |
FORWARD | 处理转发的数据包 |
PREROUTING | 在进行路由选择前处理数据包,所有的数据包进来的时侯都先由这个链处理 |
POSTROUTING | 在进行路由选择后处理数据包,所有的数据包出来的时侯都先由这个链处理 |
(2)常用选项
链相关:
选项 | 含义 |
---|---|
-t, –table table | 指定表 |
-P, –policy chain target | 设置链的默认策略,不适用用户自定义链。 |
-N, –new-chain chain | 新建一条用户自定义链 |
-E, –rename-chain old-chain new-chain | 重命名用户自定义链 |
-Z, –zero [chain [rulenum]] | 将所有链 或者 指定链 或者 仅给定规则 的包和字节计数器清零 |
-X, –delete-chain [chain] | 删除表中所有的非内置空链( 空链的引用计数要为0) |
-F, –flush [chain] | 清空指定的链。如果未指定链,则将删除所有规则。 |
-L, –list [chain] | 列出所选链中的所有规则。如果未指定链,则将列出所有链的所有规则。通常和-n一起用。 |
规则相关:
选项 | 含义 |
---|---|
-A, –append chain rule-specification | 将一个或多个规则添加到所选链的末尾。当源名称或者目标名称解析为多个地址时,将为每种可能的地址组合添加一条规则。 |
-I, –insert chain [rulenum] rule-specification | 将一个或多个规则添加到所选链中,位置由给定的规则编号决定。如果规则编号为1,则将规则插入到链的开头。如果未指定规则编号,1也是默认值。 |
-D, –delete chain rule-specification -D, –delete chain rulenum |
从所选链中删除一个或多个规则。此命令有两种版本:规则可以指定为链中的数字(第一个规则从1开始)或匹配的规则。 |
-R, –replace chain rulenum rule-specification | 替换所选链中的规则。如果源名称或者目标名称解析为多个地址,该命令将失败。 |
-p, –protocol protocol | 匹配协议。支持"!"取反。 |
-s, –source address[/mask][,…] | 匹配来源地址。此地址可以是网络名称、主机名、网络IP地址(带有/ mask)或纯IP地址。支持"!"取反。 |
-d, –destination address[/mask][,…] | 匹配目标地址。有关说明参照-s选项。支持"!"取反。 |
-i, –in-interface name | 1、接收数据包所经过的网络接口的名称(仅适用于进入INPUT,FORWARD和PREROUTING链的数据包)。 2、当在接口名称之前使用" ! "参数时,含义会颠倒。如果接口名称以" + "结尾,则任何以该名称开头的接口都将匹配。 3、如果省略此选项,则任何接口名称都将匹配。 |
-o, –out-interface name | 1、数据包将通过其发送的网络接口的名称(用于进入FORWARD,OUTPUT和POSTROUTING链的数据包)。 2、当在接口名称之前使用" ! "参数时,含义会颠倒。如果接口名称以" + "结尾,则任何以该名称开头的接口都将匹配。 3、如果省略此选项,则任何接口名称都将匹配。 |
–dport num | 匹配目标端口号 |
–sport num | 匹配来源端口号 |
-j, –jump target | 指定数据包匹配规则后的动作。常用动作有ACCEPT(允许流量通过)、REJECT(拒绝流量通过)、LOG(记录日志信息)、DROP(拒绝流量通过并不会响应)。 |
-n, –numeric | 不做名称解析。可以避免长时间的DNS解析。 |
–line-numbers | 显示规则的序列号 |
(3)扩展匹配条件
必须用-m option选项指定扩展匹配的类型,常用的有以下几种:(推荐阅读:http://www.zsythink.net/archives/1564
1、multiport —— 匹配多个离散的端口
[!] --source-ports,--sports port[,port|,port:port]...: # 指定多个源端口
[!] --destination-ports,--dports port[,port|,port:port]...: # 指定多个目标端口
例如:
iptables -I INPUT -d 10.0.0.1 -p tcp -m multiport --dports 22,80,3306 -j ACCEPT
2、iprange —— 匹配连续IP地址
[!] --src-range from[-to] # 指定匹配源地址所在范围
[!] --dst-range from[-to] # 指定匹配目录地址所在范围
例如:
iptables -I INPUT -d 10.0.0.1 -p tcp -m iprange --src-range 172.16.0.1-172.16.0.10 -j ACCEPT
3、string —— 匹配数据包中的字符
--algo {bm|kmp} # 用于指定匹配算法,此选项为必须选项,我们不用纠结于选择哪个算法,但是我们必须指定一个
[!] --string pattern # 用于指定需要匹配的字符串
例如:
iptables -I INPUT -m string --algo bm --string "test" -j REJECT
4、connlimit —— 限制同一IP可建立的连接数目
--connlimit-above n # 限制的可连接数量
--connlimit-upto n # 同一IP连接数量未达到指定的连接数量
例如:
iptables -I INPUT -d 10.0.0.1 -p tcp --dport 22 -m connlimit --connlimit-above 2 -j REJECT
5、state —— 限制收发数据包的状态
[!] --state state
state 有 INVALID、STABLISHED、NEW、RELATED、UNTRACKED。
NEW: 连接中的第一个数据包,状态就是NEW,我们可以理解为新连接的第一个数据包的状态为NEW。
ESTABLISHED:已建立的连接
INVALID:无法识别或者没有状态的数据包
RELATED:相关联的,或者说该数据包得与本机发出的数据包有关。
UNTRACKED:数据包未被追踪,当数据包的状态为Untracked时通常表示无法找到相关的连接。
例如:
iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
(3)默认规则
在centos7中iptables服务默认情况不再处于活动状态(不是说不能用默认可用),安装iptables-services将iptables服务加入到systemd服务管理中。注意此时会生成 /etc/sysconfig/iptables 文件,规则保存在这个文件中。启动iptables服务,其实只是加载这个文件中规则,关闭就是不加载这个文件中的规则。
[root@web1 ~]# yum install -y iptables-services
[root@web1 ~]# cat /etc/sysconfig/iptables
# sample configuration for iptables service
# you can edit this manually or use system-config-firewall
# please do not ask us to add additional ports/services to this default configuration
*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
我们来看看以上信息代表的含义
*filter:表示filter表
:INPUT ACCEPT [0:0]: 该规则表示INPUT链默认策略是ACCEPT
:FORWARD ACCEPT [0:0]: 该规则表示FORWARD链默认策略是ACCEPT
:OUTPUT ACCEPT [0:0]: 该规则表示OUTPUT链默认策略是ACCEPT
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
# 该规则意思是允许通过的数据包只能是刚刚我发出去的数据包的回应。
-A INPUT -p icmp -j ACCEPT
# -p参数指定协议,该规则意思是允许icmp协议的流量通过。
-A INPUT -i lo -j ACCEPT
# -i参数指定网络接口,lo即Loopback(本地回环接口),该规则的意思是允许本地回环接口在INPUT表的所有流量通过。
-A INPUT -p tcp -m state --state NEW -m tcp —dport 22 -j ACCEPT
# 该规则的意思是允许新连接ssh端口为22的流量通过。
-A INPUT -j REJECT --reject-with icmp-host-prohibited
# 该规则的意思是在INPUT链中拒绝所有其他不符合上述任何一条规则的数据包。并且发送一条host prohibited的消息给被拒绝的主机。
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
# 该规则的意思是在FORWARD链中拒绝所有其他不符合上述任何一条规则的数据包。并且发送一条host prohibited的消息给被拒绝的主机。
(4)简单示例
从上面的默认规则我们可以知道,iptables默认动作是accept允许,进行下面示例前,我们现将默认规则删除。
[root@web1 ~]# iptables -F
[root@web1 ~]# iptables -nL
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
开放80、3306和22端口,其它端口访问全部拒绝。
[root@web1 ~]# iptables -A INPUT -p tcp --dport 80 -j ACCEPT
[root@web1 ~]# iptables -A INPUT -p tcp --dport 22 -j ACCEPT
[root@web1 ~]# iptables -A INPUT -p tcp --dport 3306 -j ACCEPT
[root@web1 ~]# iptables -P INPUT DROP
[root@web1 ~]# iptables -nL
Chain INPUT (policy DROP)
target prot opt source destination
ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:80
ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:22
ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:3306
......
拒绝172.16.1.0/24网段的主机和 10.0.0.1 访问本机的ssh服务,同时拒绝访问端口1000-1005。
[root@web1 ~]# iptables -A INPUT -s 172.16.1.0/24 -p tcp --dport 22 -j DROP
[root@web1 ~]# iptables -A INPUT -s 10.0.0.1 -p tcp --dport 22 -j DROP
[root@web1 ~]# iptables -A INPUT -p tcp --dport 1000:1005 -j DROP
[root@web1 ~]# iptables -nL
Chain INPUT (policy ACCEPT)
target prot opt source destination
DROP tcp -- 172.16.1.0/24 0.0.0.0/0 tcp dpt:22
DROP tcp -- 10.0.0.1 0.0.0.0/0 tcp dpt:22
DROP tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpts:1000:1005
......
基于前面的案列,假如需要开放10.0.0.1访问本机ssh服务,开放端口1000。因为规则匹配从上往下,所以这里使用-I参数将规则添加到头部。
[root@web1 ~]# iptables -I INPUT -s 10.0.0.1 -p tcp --dport 22 -j ACCEPT
[root@web1 ~]# iptables -I INPUT -p tcp --dport 1000 -j ACCEPT
[root@web1 ~]# iptables -nL
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:1000
ACCEPT tcp -- 10.0.0.1 0.0.0.0/0 tcp dpt:22
......
当然也可以删除原规则,或者替换规则。删除规则可以用规则也可以用规则的编号,如下:
[root@web1 ~]# iptables -nL --line-numbers
Chain INPUT (policy ACCEPT)
num target prot opt source destination
1 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:22
2 DROP tcp -- 172.16.1.0/24 0.0.0.0/0 tcp dpt:22
3 DROP tcp -- 10.0.0.1 0.0.0.0/0 tcp dpt:22
4 DROP tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpts:1000:1005
......
[root@web1 ~]# iptables -D INPUT -s 10.0.0.1 -p tcp --dport 22 -j DROP
[root@web1 ~]# iptables -D INPUT 2 # 这里得特别注意规则编号的变化,使用前最好每次都查看一下规则现在的编号
[root@web1 ~]# iptables -R INPUT 2 -p tcp --dport 1001:1005 -j DROP
[root@web1 ~]# iptables -nL
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:22
DROP tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpts:1001:1005
......
以上操作都是临时的,重启iptbles服务就会失效。如果想让配置的防火墙策略永久生效,还要执行以下命令。
[root@web1 ~]# service iptables save
iptables: Saving firewall rules to /etc/sysconfig/iptables:[ OK ]
[root@web1 ~]# cat /etc/sysconfig/iptables
# Generated by iptables-save v1.4.21 on Wed Sep 16 06:19:32 2020
*filter
:INPUT ACCEPT [12:624]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [70:6064]
-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 1001:1005 -j DROP
COMMIT
# Completed on Wed Sep 16 06:19:32 2020
(5)端口转发
# 将本机5555的端口的流量转发到本机的22上
[root@web1 ~]# iptables -t nat -A PREROUTING -d 10.0.0.7 -p tcp --dport 5555 -j DNAT --to-destination 10.0.0.7:22
[root@web1 ~]# iptables -t nat -nL
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
DNAT tcp -- 0.0.0.0/0 10.0.0.7 tcp dpt:5555 to:10.0.0.7:22
......
# 将10.0.0.8:5555的流量转发到10.0.0.7:22上
[root@m1 ~]# iptables -t nat -A PREROUTING -d 10.0.0.8 -p tcp --dport 5555 -j DNAT --to-destination 10.0.0.7:22
[root@m1 ~]# iptables -t nat -A POSTROUTING -d 10.0.0.7 -p tcp -j SNAT --to-source 10.0.0.8
[root@m1 ~]# iptables -t nat -nL
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
DNAT tcp -- 0.0.0.0/0 10.0.0.8 tcp dpt:5555 to:10.0.0.7:22
......
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
SNAT tcp -- 0.0.0.0/0 10.0.0.7 to:10.0.0.8
(6)内部共享上网
环境:
web01处于内网环境,没有公网ip,其内网ip地址为172.16.1.7
web02有两块网卡,一块地址为内网172.16.1.8,一块地址为公网10.0.0.8
此时web01通过将网关指向10.0.0.8共享上网,iptables规则设置如下:
[root@web2 ~]# echo 'net.ipv4.ip_forward = 1' >> /etc/sysctl.conf //开启内核转发参数
[root@web2 ~]# sysctl -p
[root@web2 ~]# iptables -t nat -A POSTROUTING -s 172.16.1.7 -j SNAT --to-source 172.16.1.8
[root@web2 ~]# iptables -t nat -nL
......
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
SNAT all -- 172.16.1.7 0.0.0.0/0 to:172.16.1.8
或者:
[root@web2 ~]# iptables -t nat -A POSTROUTING -s 172.16.1.0/24 -j MASQUERADE
[root@web2 ~]# iptables -t nat -nL
......
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
MASQUERADE all -- 172.16.1.0/24 0.0.0.0/0
参考文章:
https://www.linuxprobe.com/chapter-08.html
http://www.zsythink.net/archives/1564