firewalld
众所周知,在RHEL7系统中,firewalld防火墙取代了iptables防火墙。我们都知道iptables的防火墙策略是交由内核层面的netfilter网络过滤器来处理的,而firewalld则是交由内核层面的nftables包过滤框架来处理。
相较于iptables防火墙而言,firewalld支持动态更新技术并加入了区域(zone)的概念。简单来说,区域就是firewalld预先准备了几套防火墙策略集合(策略模板),用户可以根据生产场景的不同而选择合适的策略集合,从而实现防火墙策略之间的快速切换。
firewalld中常用的区域名称及策略规则
区域(noze) | 默认策略规则 |
---|---|
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 | 拒绝进入的流量,除非与出去的流量相关 |
firewalld 服务基本使用
查看防火墙状态 | systemctl status firewalld |
---|---|
关闭防火墙,停止 firewall 服务 | systemctl stop firewalld |
开启防火墙,启动 firewall 服务 | systemctl start firewalld |
重启防火墙,重启 firewall 服务 | systemctl restart firewalld |
重启防火墙,重启 firewall 服务 | systemctl is-enabled firewalld |
开机时自动启动 firewall 服务 | systemctl enable firewalld.service |
开机时自动禁用 firewall 服务 | systemctl disable firewalld.service |
firewalld-cmd 防护墙命令使用
—get-default-zone | 查访默认的区域名称 |
---|---|
—set-default-zone=<区域名称> | 设置默认的区域,使其永久生效 |
—get-zones | 显示可用的区域 |
—get-services | 显示预定义的服务 |
—get-active-zones | 显示当前正在使用的区域、来源地址和网卡名称 |
—add-source= | 将源自此IP或子网的流量导向指定的区域 |
—remove-source= | 不再将源自此IP或子网的流量导向这个区域 |
—add-interface=<网卡名称> | 将源自该网卡的所有流量都导向某个指定区域 |
—change-interface=<网卡名称> | 将某个网卡与区域进行关联 |
—list-all | 显示当前区域的网卡配置参数、资源、端口以及服务等信息 |
—list-all-zones | 显示所有区域的网卡配置参数、资源、端口以及服务等信息 |
—add-service=<服务名> | 设置默认区域允许该服务的流量 |
—add-port=<端口号/协议> | 设置默认区域允许该端口的流量 |
—remove-service=<服务名> | 设置默认区域不再允许该服务的流量 |
—remove-port=<端口号/协议> | 设置默认区域不再允许该端口的流量 |
—reload | 让“永久生效”的配置规则立即生效,并覆盖当前的配置规则 |
—panic-on | 开启应急状况模式 |
—panic-off | 关闭应急状况模式 |
firewalld-cmd使用举例
查看默认当前使用的区域:firewall-cmd —get-default-zone
查看所有可用区域:firewall-cmd —get-zones
查看区域的所有设置
- firewall-cmd —zone=internal —list-all # 查看指定区域设置
- firewall-cmd —list-all # 查看默认区域设置
- firewall-cmd —list-all-zones # 查看所有区域的设置
更改默认区域(此为永久设置):firewall-cmd —set-default-zone=drop
更改网卡关联区域
- firewall-cmd —permanent —zone=drop —change-interface=ens32 # 永久设置
- firewall-cmd —zone=drop —change-interface=ens32 # 当前生效
设置来源地址
- firewall-cmd —zone=drop —add-source=192.168.1.12 # 作用在指定区域
- firewall-cmd —add-source=192.168.1.12 # 作用在默认区域
- firewall-cmd —remove-source=192.168.1.12 # 取消源IP为192.168.1.12的包作用在drop区域
对于一个接收到的请求具体使用哪个zone,firewalld是通过三种方式来判断的:
1、source,来源地址
2、Interface,接收请求的网卡
3、firewalld配置的默认区域(zone)
这三个方式的优先级按顺序依次降低
查询是否允许请求某服务的流量
- firewall-cmd —zone=drop —query-service=ssh # 指定区域
- firewall-cmd —query-service=https # 默认区域
开放关闭服务
- firewall-cmd —zone=drop —add-service=https
- firewall-cmd —zone=drop —remove-service=https
开放关闭端口
- firewall-cmd —zone=drop —add-port=22/tcp
- firewall-cmd —zone=drop —remove-port=22/tcp
- firewall-cmd —zone=drop —add-port=8080-8081/tcp
查询指定区域开放了哪些端口:firewall-cmd —zone=drop —list-ports
开放关闭ping
- firewall-cmd —zone=drop —add-protocol=icmp
- firewall-cmd —zone=drop —remove-protocol=icmp
查询指定区域开放了哪些协议:firewall-cmd —zone=drop —list-protocols
将原本访问本机888端口的流量转发到本机22端口
- firewall-cmd —zone=drop —add-forward-port=port=888:proto=tcp:toport=22
将原本访问本机888端口的流量转发到ip为192.168.2.208的主机的22端口
firewall-cmd --zone=drop --add-masquerade
firewall-cmd --zone=drop --add-forwardport=port=888:proto=tcp:toport=22:toaddr=192.168.2.208
ip转发
firewall-cmd --permanent --add-masquerade
firewall-cmd --permanent --add-service=openvpn
firewall-cmd --permanent --direct --passthrough ipv4 -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
firewall-cmd --reload
// -s 10.8.0.0/24 -o eth0 -j MASQUERADE
伪装来自的10.8.0.0/24 ip 为 eth0,并通过eth0转发
共享上网
1.服务端操作(m01:172.16.1.61)
1)开启防火墙并加入开机自启动
[root@m01 ~]# systemctl start firewalld
[root@m01 ~]# systemctl enable firewalld
2)开启ip伪装,为后续主机提供共享上网【管理机】
[root@m01 ~]# firewall-cmd --add-masquerade --permanent
[root@m01 ~]# firewall-cmd --add-rich-rule="rule family=ipv4 source address=172.16.1.0/24 masquerade"
3)重启firewalld生效
[root@m01 ~]# firewall-cmd --reload
2.没有外网的服务器操作
1)没有公网地址的内部服务器配置指向管理机的网关
[root@web03 ~]# /etc/sysconfig/network-scripts/ifcfg-eth1
#配置新增如下2条规则
GATEWAY=172.16.1.61 #有外网的服务器内网ip
DNS1=223.5.5.5
2)重启网卡ping baidu.com(如果不通尝试重启服务器)
[root@web03 ~]# nmcli connection down eth1 && nmcli connection up eth1
[root@web03 ~]# ping baidu.com
firewalld-cmd 富规则
富规则常用的options
firewall-cmd
--list-rich-rules --列出富规则
--add-rich-rule=<rule> --使用富规则语言添加富规则
--remove-rich-rule=<rule> --移除富规则
--query-rich-rule=<rule> --查询某条富规则是否存在
--list-rich-rules --列出指定区域中的所有富规则
--list-all 和 --list-all-zones --也能列出存在的富规则
富规则language语法
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
富规则log语法
log [prefix="<PREFIX TEXT>" [level=<LOGLEVEL>] [limit value="<RATE/DURATION>"]
其中:
<LOGLEVEL> 可以是emerg 、 alert 、 crit 、 error 、 warning 、 notice 、 info或debug之一。
<RATE/DURATION>" 可以是s(表示秒)、m(表示分钟)、h(表示小时)或d(表示天)之一。
例如:limit value=3/m会将日志消息限制为每分钟最多三条。
limit value = 3/m 这里是有BUG 的,常常时间控制会不精准
允许192.168.2.208主机的所有流量
- firewall-cmd —zone=drop —add-rich-rule=”rule family=”ipv4” source address=”192.168.2.208” accept”
允许192.168.2.208主机的icmp协议,即允许192.168.2.208主机ping
- firewall-cmd —add-rich-rule=”rule family=”ipv4” source address=”192.168.2.208” protocol value=”icmp” accept”
取消允许192.168.2.208主机的所有流量
- firewall-cmd —zone=drop —remove-rich-rule=”rule family=”ipv4” source address=”192.168.2.208” accept”
允许192.168.2.208主机访问ssh服务
- firewall-cmd —zone=drop —add-rich-rule=”rule family=”ipv4” source address=”192.168.2.208” service name=”ssh” accept”
禁止192.168.2.208访问https服务,并返回错误信息
- firewall-cmd —zone=drop —add-rich-rule=”rule family=”ipv4” source address=”192.168.2.208” service name=”https” reject”
允许192.168.2.0/24网段的主机访问22端口
- firewall-cmd —zone=drop —add-rich-rule=”rule family=”ipv4” source address=”192.168.2.0/24” port protocol=”tcp” port=”22” accept”
每分钟允许2个新连接访问ftp服务
- firewall-cmd —add-rich-rule=”rule service name=ftp limit value=2/m accept”
拒绝来自192.168.2.0/24网段的连接,10秒后自动取消
- firewall-cmd —add-rich-rule=”rule family=ipv4 source address=192.168.2.0/24 reject” —timeout=10
将来自192.168.2.0/24网段访问本机80端口的流量转发到本机的22端口
- firewall-cmd —zone=drop —add-rich-rule=”rule family=ipv4 source address=192.168.2.0/24 forward-port port=80 protocol=tcp to-port=22”
将来自192.168.2.0/24网段访问本地80端口的流量转发到192.168.2.208主机的22端口
- firewall-cmd —zone=drop —add-rich-rule=”rule family=ipv4 source address=192.168.2.0/24 forward-port port=80 protocol=tcp to-port=22 to-addr=192.168.2.208”
将来自局域网192.168.2.0/24网段访问外网的流量映射为网络出口公网IP,即修改源IP地址
firewall-cmd --zone=drop --add-masquerade
firewall-cmd --zone=drop --add-rich-rule="rule family=ipv4 source address=192.168.2.0/24 masquerade"
iptables
iptables 是 Linux 管理员用来设置 IPv4 数据包过滤条件和 NAT 的命令行工具。iptables 工具运行在用户态,主要是设置各种规则。而 netfilter 则运行在内核态,执行那些设置好的规则
相比firewalld,iptables有如下缺点
- 配置麻烦
- 服务是允许访问,需要拒绝的才去限制,不够安全
- 必选重启生效,firewalld只有永久生效的才需要重启
table
- RAW表只使用在PREROUTING链和OUTPUT链上,因为优先级最高,从而可以对收到的数据包在连接跟踪前进行处理。一但用户使用了RAW表,在某个链上,RAW表处理完后,将跳过NAT表和ip_conntrack处理,即不再做地址转换和数据包的链接跟踪处理了
- filter表是预设规则表,拥有 INPUT、FORWARD 和 OUTPUT 三个规则链,这个规则表顾名思义是用来进行封包过滤的理动作
- net表拥有prerouting和postrouting两个规则链, 主要功能为进行一对一、一对多、多对多等网址转译工作(SNATDNAT)
- mangle表拥有prerouting、FORWARD、postrouting三个规则链,除了进行网址转译工作会改写封包外,在某些特殊应用可能也必须去改写封包(ITL、TOS)或者是设定MARK(将封包作记号,以进行后续的过滤)这时就必须将这些工作定义在mangles规则表中
iptables的工作机制
iptables的前身叫ipfirewall (内核1.x时代),这是一个作者从freeBSD上移植过来的,能够工作在内核当中的,对数据包进行检测的一款简易访问控制工具。但是ipfirewall工作功能极其有限(它需要将所有的规则都放进内核当中,这样规则才能够运行起来,而放进内核,这个做法一般是极其困难的)。
当内核发展到2.x系列的时候,软件更名为ipchains,它可以定义多条规则,将他们串起来,共同发挥作用,而现在,它叫做iptables,可以将规则组成一个列表,实现绝对详细的访问控制功能。
他们都是工作在用户空间中,定义规则的工具,本身并不算是防火墙。它们定义的规则,可以让在内核空间当中的netfilter来读取,并且实现让防火墙工作。而放入内核的地方必须要是特定的位置,必须是tcp/ip的协议栈经过的地方。而这个tcp/ip协议栈必须经过的地方,可以实现读取规则的地方就叫做 netfilter.(网络过滤器)
作者一共在内核空间中选择了5个位置,
1.内核空间中:从一个网络接口进来,到另一个网络接口去的
2.数据包从内核流入用户空间的
3.数据包从用户空间流出的
4.进入/离开本机的外网接口
5.进入/离开本机的内网接口
从上面的发展我们知道了作者选择了5个位置,来作为控制的地方,但是你有没有发现,其实前三个位置已经基本上能将路径彻底封锁了,但是为什么已经在进出的口设置了关卡之后还要在内部卡呢? 由于数据包尚未进行路由决策,还不知道数据要走向哪里,所以在进出口是没办法实现数据过滤的。所以要在内核空间里设置转发的关卡,进入用户空间的关卡,从用户空间出去的关卡。那么,既然他们没什么用,那我们为什么还要放置他们呢?因为我们在做NAT和DNAT的时候,目标地址转换必须在路由之前转换。所以我们必须在外网而后内网的接口处进行设置关卡。
这五个位置也被称为五个钩子函数(hook functions),也叫五个规则链。
- 1.PREROUTING (路由前)
- 2.INPUT (数据包流入口)
- 3.FORWARD (转发管卡)
- 4.OUTPUT(数据包出口)
- 5.POSTROUTING(路由后)
这是NetFilter规定的五个规则链,任何一个数据包,只要经过本机,必将经过这五个链中的其中一个链。
我们现在用的比较多个功能有3个:
- 1.filter 定义允许或者不允许的
- 2.nat 定义地址转换的
- 3.mangle功能:修改报文原数据
详解COMMAND
常用命令
-A 追加规则:iptables -A INPUT
-D 删除规则:iptables -D INPUT 1(编号)
-R 修改规则:iptables -R INPUT 1 -s 192.168.12.0 -j DROP 取代现行规则,顺序不变(1是位置)
-I 插入规则:iptables -I INPUT 1 —dport 80 -j ACCEPT 插入一条规则,原本位置上的规则将会往后移动一个顺位
-L 查看规则:iptables -L INPUT 列出规则链中的所有规则
通用参数
p 指定协议:iptables -A INPUT -p tcp
s 指定源地址:iptables -A INPUT -s 192.168.1.1
d 指定目的地址:iptables -A INPUT -d 192.168.12.1
sport 指定源端口:iptables -A INPUT -p tcp —sport 22
dport 指定目的端口:iptables -A INPUT -p tcp —dport 22
i 指定入口网卡:iptables -A INPUT -i eth0
o 指定出口网卡:iptables -A FORWARD -o eth0
j 指定要进行的处理动作
- DROP:丢弃
- REJECT:明示拒绝
- ACCEPT:接受
- SNAT基于源地址的转换
- source 指定源地址
- 比如我们现在要将所有192.168.10.0网段的IP在经过的时候全都转换成172.16.100.1这个假设出来的外网地址
- iptables -t nat -A POSTROUTING -s 192.168.10.0/24 -j SNAT —to-source 172.16.100.1(外网有效ip)
DNAT基于目标地址的转换
- destination指定目标地址
- iptables -t nat -A PREROUTING -d 192.168.10.18 -p tcp —dport 80 -j DNAT —to-destination 172.16.100.2
- 10.18访问80端口转换到100.2上
MASQUERADE:源地址伪装
- REDIRECT:重定向:主要用于实现端口重定向
- MARK:打防火墙标记的
- RETURN:返回,在自定义链执行完毕后使用返回,来返回原规则链
查看 iptables 的链和规则
查看规则的命令格式为:iptables [-t tables] [-L] [-nv]
-t :后面接 table ,例如 nat 或 filter ,若省略此项目,则使用默认的 filter
-L :列出某个 table 的所有链或某个链的规则
-n :直接显示 IP,速度会快很多
-v :列出更多的信息,包括通过该规则的数据包总位数、相关的网络接口等
列出 filter table INPUT 链的规则:$ iptables -L INPUT
列出 nat table 三条链的规则:$ iptables -t nat -L -n
列出 filter table 三条链的规则:$ iptables -L
添加规则
我们可以通过规则来匹配数据包,具体的匹配条件包括 IP、网段、网络接口(interface)和传输协议(tcp、udp 等)。
添加规则的命令格式如下:
iptables [-AI chain] [-io interface] [-p 协议] [-s 来源 IP] [-d 目标 IP] -j [ACCEPT,DROP,REJECT,LOG]
使用举例
放开本机接口 lo:
$ sudo iptables -A INPUT -i lo -j ACCEPT
上面的命令假设 lo 接口是可以信任的设备,所有进出该接口的数据包都会被接受。
注意,上面的命令中并没有设置 -s、-d 等参数,其实没有指定的参数表示该参数是任何值都可以被接受
完全放开某个接口
和 lo 接口类似,如果你完全信任某个接口,可以像设置 lo 一样设置它
$ sudo iptables -A INPUT -i eth1 -j ACCEPT
只接受来自内网中某个网段的数据包:
$ sudo iptables -A INPUT -i eth2 -s 192.168.10.0/24 -j ACCEPT
接受/丢弃来自指定 IP 的数据包:
$ sudo iptables -A INPUT -i eth3 -s 192.168.100.5 -j ACCEPT
$ sudo iptables -A INPUT -i eth3 -s 192.168.100.6 -j DROP
丢弃所有通过 tcp 协议访问本机 21 端口的数据包:
$ sudo iptables -A INPUT -i eth0 -p tcp --dport 21 -j DROP
丢弃来自 192.168.1.0/24 的 1024:65535 端口的访问本机 ssh 端口的数据包:
$ sudo iptables -A INPUT -i eth0 -p tcp -s 192.168.1.0/24 --sport 1024:65535 --dport ssh -j DROP
注意,因为只有 tcp 协议和 udp 协议使用了端口号,所以在使用 —sport 和 —dport 时,一定要指定协议的类型(-p tcp 或 -p udp)。
允许自己ping别人,但是别人ping自己ping不通
在出去的端口上:iptables -A OUTPUT -p icmp --icmp-type 8 -j ACCEPT
在进来的端口上:iptables -A INPUT -p icmp --icmp-type 0 -j ACCEPT
iptables生效问题
通过命令添加的规则都是即时生效,不过是存在内存中的,机器重启后就失效了
如何永久生效呢?
service iptables save
或则直接编辑iptables配置文件
vim /etc/sysconfig/iptables
将语句-A INPUT -p tcp -m state --state NEW -m tcp --dport 82 -j ACCEPT
直接插入到上述文件中。重启服务service iptables restart。之后这条规则就永久生效了