Linux防火墙---firewall详解

本章主要介绍RHEL8中的firewalld的配置。

  • firewalld中的名词介绍
  • firewalld的基本配置配置
  • firewalld的规则添加
  • firewalld的富规则

    了解 firewalld 

在RHEL8中用的防火墙是firewalld,在 firewalld中又涉及zone的概念。首先来了解一下什么是zone。 

如在进地铁或高铁时需要安检,安检有不同的入口,如下图所示。

以安检入口举例 

不同的入口严格度不一样,有的入口大包小包都要检测;有的入口只要检测大包即可,背包或单肩包就不用检测了;有的入口是绿色通道,不用检测直接通过。这里不同的安检入口制定了不同的规则。 

同理,firewalld中的zone我们就理解为如上的安检入口,不同的zone中制定了不同的规则。某网卡要和某一个zone进行关联,如下图所示,ens160和 zone2进行关联,这样从网卡ens160进来的数据包都要使用zone2中的过滤规则。 

 了解firewall中的zone

网卡是不能同时和多个 zone关联的,最多只能和一个 zone关联。如果网卡没有和任何 zone关联,则使用默认的zone中的规则。 


firewalld的基本配置 

查看系统中有多少个 zone,命令如下。 

[root@rhel03 ~]# firewall-cmd --get-zones
block dmz drop external home internal libvirt nm-shared public trusted work
[root@rhel03 ~]# 

在这许多的zone中,其中 block拒绝所有的数据包通过,trusted允许所有的数据包通过。所以,如果把网卡和 trusted关联,则来自这张网卡的数据包都能通过。 

查看系统默认的 zone,命令如下。 

[root@rhel03 ~]# firewall-cmd --get-default-zone 
public
[root@rhel03 ~]# 

可以看到,默认的zone是 public。

把默认的zone修改为trusted,命令如下。 

[root@rhel03 ~]# firewall-cmd --set-default-zone=trusted 
success
[root@rhel03 ~]# firewall-cmd --get-default-zone 
trusted
[root@rhel03 ~]#

再次把默认的zone改成public,命令如下。 

[root@rhel03 ~]# firewall-cmd --set-default-zone=public 
success
[root@rhel03 ~]# firewall-cmd --get-default-zone 
public
[root@rhel03 ~]# 

查看网卡ens160和哪个zone关联,命令如下。 

[root@rhel03 ~]# firewall-cmd --get-zone-of-interface=ens160 
public
[root@rhel03 ~]# 

可以看到,网卡 ens160是和public关联的。

把网卡加入某个 zone,语法如下。 

  • firewall‐cmd ‐‐add‐interface=网卡名 ‐‐zone=zone 名 

如果不指定zone名,则是默认的zone。

把ens160和home这个 zone关联,命令如下。 

[root@rhel03 ~]# firewall-cmd --add-interface=ens160 --zone=home 
Error: ZONE_CONFLICT: 'ens160' already bound to a zone
[root@rhel03 ~]# 

一张网卡只能在一个zone中,这里可以看到ens160已经属于一个zone了,所以发生了冲突。 

可以先把网卡从public中删除,然后重新添加,这里把ens160 从 public中删除,命令如下。 

[root@rhel03 ~]# firewall-cmd --remove-interface=ens160 --zone=public 
success
[root@rhel03 ~]# firewall-cmd --get-zone-of-interface=ens160 
no zone
[root@rhel03 ~]#

这样ens160就不属于任何zone了,如果不属于任何zone,则使用默认的zone中的规则。 

然后把 ens160加入 home中,命令如下。 

[root@rhel03 ~]# firewall-cmd --add-interface=ens160 --zone=home 
success            
[root@rhel03 ~]# firewall-cmd --get-zone-of-interface=ens160 
home
[root@rhel03 ~]# 

以后ens160会使用home中的规则,不再使用public中的规则。先从 zone中删除,然后再添加到其他的zone 中,这个过程可以用一条命令替换,命令如下。 

[root@rhel03 ~]# firewall-cmd --change-interface=ens160 --zone=public 
success
[root@rhel03 ~]#

这里的意思是把ens160切换到public这个zone,如果不指定zone,则是默认的zone, 命令如下。 

[root@rhel03 ~]# firewall-cmd --get-zone-of-interface=ens160 
public
[root@rhel03 ~]# 

后面的练习均是在public 中做。


配置firewalld的规则 

网卡在哪个zone中就使用那个zone 中的规则,如果网卡不属于任何zone,则使用默认的zone中的规则。 

一个zone中的规则可以通过“firewall-cmd --list-all --zone=zone名”来查看,如果不指定zone,则是默认的zone. 

现在查看 public这个 zone中的规则,命令如下。

[root@rhel03 ~]# firewall-cmd --list-all --zone=public 
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: ens160
  sources: 
  services: cockpit dhcpv6-client mountd nfs rpc-bind ssh
  ports: 123/udp 323/udp 20-21/tcp 10010-10020/tcp
  protocols: 
  forward: no
  masquerade: no
  forward-ports: 
  source-ports: 
  icmp-blocks: 
  rich rules: 
[root@rhel03 ~]# 

因为默认的zone就是 public,所以这里即使不加--zone=public选项,显示的也是 public这个zone中的规则。 

我们看一下最常用的一些设置。


icmp-blocks 

平时测试网络通或不通是用ping进行测试的,使用的是 icmp 协议,如下图所示。

 ping的过程

icmp有很多类型的数据包,ping的时候用的是以下两种。 

  1. echo-request:我ping对方时发出去的包。
  2. echo-reply:对方回应我的包。 

一共有多少种类型的icmp包,可以通过“firewall-cmd --get-icmptypes”来查看。 在rhel03上执行 tcpdump命令进行抓包,命令如下。 

[root@rhel03 ~]# tcpdump -i ens160 icmp
dropped privs to tcpdump
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ens160, link-type EN10MB (Ethernet), capture size 262144 bytes

在rhel04上ping rhel03的IP两次,命令如下。 

[root@rhel04 ~]# ping 192.168.23.33 -c2
PING 192.168.23.34 (192.168.23.34) 56(84) bytes of data.
64 bytes from 192.168.23.34: icmp_seq=1 ttl=64 time=0.055 ms
64 bytes from 192.168.23.34: icmp_seq=2 ttl=64 time=0.089 ms

--- 192.168.23.34 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 0.055/0.072/0.089/0.017 ms
[root@rhel04 ~]# 

然后到rhel03上查看,命令如下。 

[root@rhel03 ~]# tcpdump -i ens160 icmp
dropped privs to tcpdump
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ens160, link-type EN10MB (Ethernet), capture size 262144 bytes
11:19:13.367888 IP 192.168.23.34 > rhel03: ICMP echo request, id 1896, seq 1, length 64
11:19:13.368001 IP rhel03 > 192.168.23.34: ICMP echo reply, id 1896, seq 1, length 64
11:19:14.374796 IP 192.168.23.34 > rhel03: ICMP echo request, id 1896, seq 2, length 64
11:19:14.374928 IP rhel03 > 192.168.23.34: ICMP echo reply, id 1896, seq 2, length 64
^C
4 packets captured
4 packets received by filter
0 packets dropped by kernel
[root@rhel03 ~]# 

这里rhel04往rhel03发送了两个echo-request包,rhel03均回应了echo-reply包。 在rhel03上用防火墙设置拒绝别人发过来的echo-request包,命令如下。 

[root@rhel03 ~]# firewall-cmd --add-icmp-block=echo-request 
success
[root@rhel03 ~]# firewall-cmd --list-all
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: ens160
  sources: 
  services: cockpit dhcpv6-client mountd nfs rpc-bind ssh
  ports: 123/udp 323/udp 20-21/tcp 10010-10020/tcp
  protocols: 
  forward: no
  masquerade: no
  forward-ports: 
  source-ports: 
  icmp-blocks: echo-request
  rich rules: 
[root@rhel03 ~]# 

此时,rhel03就不再接收别人发过来的echo-request包了,然后到rhel04再次ping,命 令如下。 

[root@rhel04 ~]# ping 192.168.23.33 -c2
PING 192.168.23.33 (192.168.23.33) 56(84) bytes of data.
From 192.168.23.33 icmp_seq=1 Packet filtered
From 192.168.23.33 icmp_seq=2 Packet filtered

--- 192.168.23.33 ping statistics ---
2 packets transmitted, 0 received, +2 errors, 100% packet loss, time 1007ms

[root@rhel04 ~]# 

可以看到,在rhel04上已经 ping不通rhel03了。 

如果要想继续ping操作,就取消对应的设置,命令如下。 

[root@rhel03 ~]# firewall-cmd --remove-icmp-block=echo-request 
success
[root@rhel03 ~]# 

services 

两台主机通信必须使用某个协议,例如,浏览器访问网站用的是http,远程登录到Linux 服务器用的是ssh 协议等。 

默认情况下,public这个 zone只允许很少的服务通过,如下所示。 

[root@rhel03 ~]# firewall-cmd --list-all
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: ens160
  sources: 
  services: cockpit dhcpv6-client mountd nfs rpc-bind ssh
  ports: 123/udp 323/udp 20-21/tcp 10010-10020/tcp
  protocols: 
  forward: no
  masquerade: no
  forward-ports: 
  source-ports: 
  icmp-blocks: 
  rich rules: 
[root@rhel03 ~]# 

可以看到,这里没有允许http通过。如果要查看防火墙是否开放了某个协议,也可以通过如下语法来查看。 

  • firewall‐cmd ‐‐query‐service=服务名 

要获取系统所支持的所有服务,可以通过如下命令来查看。 

[root@rhel03 ~]# firewall-cmd --get-services 
RH-Satellite-6 RH-Satellite-6-capsule amanda-client amanda-k5-client amqp amqps apcupsd audit bacula bacula-client bb bgp bitcoin bitcoin-rpc bitcoin-testnet bitcoin-testnet-rpc bittorrent-lsd ceph ceph-mon cfengine cockpit collectd condor-collector ctdb dhcp dhcpv6 dhcpv6-client distcc dns dns-over-tls docker-registry docker-swarm dropbox-lansync elasticsearch etcd-client etcd-server finger foreman foreman-proxy freeipa-4 freeipa-ldap freeipa-ldaps freeipa-replication freeipa-trust ftp galera ganglia-client ganglia-master git grafana gre high-availability http https imap imaps ipp ipp-client ipsec irc ircs iscsi-target isns jenkins kadmin kdeconnect kerberos kibana klogin kpasswd kprop kshell kube-apiserver ldap ldaps libvirt libvirt-tls lightning-network llmnr managesieve matrix mdns memcache minidlna mongodb mosh mountd mqtt mqtt-tls ms-wbt mssql murmur mysql nbd nfs nfs3 nmea-0183 nrpe ntp nut openvpn ovirt-imageio ovirt-storageconsole ovirt-vmconsole plex pmcd pmproxy pmwebapi pmwebapis pop3 pop3s postgresql privoxy prometheus proxy-dhcp ptp pulseaudio puppetmaster quassel radius rdp redis redis-sentinel rpc-bind rquotad rsh rsyncd rtsp salt-master samba samba-client samba-dc sane sip sips slp smtp smtp-submission smtps snmp snmptrap spideroak-lansync spotify-sync squid ssdp ssh steam-streaming svdrp svn syncthing syncthing-gui synergy syslog syslog-tls telnet tentacle tftp tftp-client tile38 tinc tor-socks transmission-client upnp-client vdsm vnc-server wbem-http wbem-https wsman wsmans xdmcp xmpp-bosh xmpp-client xmpp-local xmpp-server zabbix-agent zabbix-server
[root@rhel03 ~]#

再次验证http是否被firewall允许,命令如下。 

[root@rhel03 ~]# firewall-cmd --query-service=http
no
[root@rhel03 ~]# 

在rhel03上通过yum install httpd -y安装httpd包,启动服务并写一些测试数据,命令如下。 

[root@rhel03 ~]# yum -y install httpd
[root@rhel03 ~]# systemctl start httpd
[root@rhel03 ~]# echo "1234" > /var/www/html/index.html
[root@rhel03 ~]# cat /var/www/html/index.html 
1234
[root@rhel03 ~]#

然后在宿主机上用浏览器访问rhel03(IP地址是192.168.23.33),结果如下图所示。 

测试宿主机能不能访问 

可以看到,现在根本访问不了,这是因为rhel03上的防火墙并不允许http的数据包通过,然后在防火墙中开放http,命令如下。 

[root@rhel03 ~]# firewall-cmd --add-service=http
success
[root@rhel03 ~]# firewall-cmd --query-service=http
yes
[root@rhel03 ~]#

再次打开浏览器验证,结果如下图所示。

 

此时可以正常打开了。如果要从防火墙中把此服务删除,则可用--remove-service选项, 命令如下。 

[root@rhel03 ~]# firewall-cmd --remove-service=http
success
[root@rhel03 ~]# firewall-cmd --query-service=http
no
[root@rhel03 ~]# 

此时浏览器中是访问不了192.168.23.33的。 


ports 

前面介绍了对服务进行过滤与放行,这些服务使用的都是标准端口,例如,http对应的是端口80,ssh对应的是端口22等。 

但有时服务使用的是一个非标准端口,例如,把服务httpd的端口更改为8080。如果在防火墙中只是放行http这个服务,本质上就是放行了端口80,此时用户肯定是访问不到Web服 务的,因为只能通过端口8080才能访问到Web 服务。下面做一下这个实验。 

先临时关闭SELinux,命令如下。 

[root@rhel03 ~]# setenforce 0
[root@rhel03 ~]# getenforce 
Permissive
[root@rhel03 ~]#

确保SELinux是处在Permissive模式的。 

用如下命令把 httpd的端口替换为8080,并重启httpd服务,命令如下。 

[root@rhel03 ~]# sed -i '/^Listen/cListen 8080' /etc/httpd/conf/httpd.conf
[root@rhel03 ~]# systemctl restart httpd
[root@rhel03 ~]# netstat -anpt | grep httpd
tcp6       0      0 :::8080                 :::*                    LISTEN      3761/httpd          
[root@rhel03 ~]#

首先在防火墙中放行http,命令如下。 

[root@rhel03 ~]# firewall-cmd --add-service=http
success
[root@rhel03 ~]#

在浏览器中访问192.168.23.33:8080,结果如下图所示。 

 可以看到,访问失败,因为放行http也只是允许端口80而非端口8080。 

把 http服务从防火墙中删除,命令如下。 

[root@rhel03 ~]# firewall-cmd --remove-service=http
success
[root@rhel03 ~]#

下面开始放行端口,常用的语句如下。

  1. firewall-cmd --query-port=N/协议:查询是否开放了端口N。
  2. firewall-cmd --add-port=N/协议:开放端口N。
  3. firewall-cmd --remove-port=N/协议:删除端口N。这里的协议包括TCP、UDP 等。 

在防火墙中添加端口,也可以添加一个范围。例如,要在防火墙中开放1000~-2000范围的端口,可以用如下命令。 

[root@rhel03 ~]# firewall-cmd --add-port=1000-2000/tcp
success
[root@rhel03 ~]#

这里“-”表示到的意思。

下面把端口8080放行,命令如下。 

[root@rhel03 ~]# firewall-cmd --add-port=8080/tcp
success
[root@rhel03 ~]# firewall-cmd --query-port=8080/tcp
yes
[root@rhel03 ~]#

然后再次在浏览器中访问,结果如下图所示。

防火墙放行之后就能访问了 

防火墙放行之后就能访问了

在防火墙中删除此端口,命令如下。 

[root@rhel03 ~]# firewall-cmd --remove-port=8080/tcp
success
[root@rhel03 ~]# firewall-cmd --query-port=8080/tcp
no
[root@rhel03 ~]#

下面把环境还原,再次开启SELinux,确保状态为Enforcing模式,命令如下。 

[root@rhel03 ~]# setenforce 1
[root@rhel03 ~]# getenforce 
Enforcing
[root@rhel03 ~]#

再次把httpd的端口改为80,并重启服务,命令如下。

[root@rhel03 ~]# sed -i '/^Listen/cListen 80' /etc/httpd/conf/httpd.conf
[root@rhel03 ~]# systemctl restart httpd
[root@rhel03 ~]# netstat -anpt | grep httpd
tcp6       0      0 :::80                   :::*                    LISTEN      4166/httpd          
[root@rhel03 ~]# 

富规则 

前面不管是对端口放行还是对服务放行,都会遇到一个问题就是,如果允许则是允许所有的客户端,如果拒绝则是拒绝所有的客户端,有种一刀切的感觉。 

有时需要设置只允许特定的客户端访问,其他客户端都不能访问,此时就需要使用到富规则。 

富规则可以对服务进行限制,也可以对端口进行限制。放行服务的语法如下。 

  • firewall‐cmd ‐‐add‐rich‐rule='rule family=ipv4 source address=源网段 service name=服务名 accept' 

这里用单引号或双引号均可,先查看现在是否有富规则。 

[root@rhel03 ~]# firewall-cmd --list-rich-rules 

[root@rhel03 ~]#

现在还没有任何富规则,下面开始创建富规则。 

练习1:允许192.168.23.10(我的宿主机)访问本机的 http服务,其他客户端都不能访问。 

先确保在防火墙的services中没有添加http,否则所有的客户端都能访问了。 

[root@rhel03 ~]# firewall-cmd --query-service=http
no
[root@rhel03 ~]#

现在确定在rhel03中是没有添加 http的,所以现在所有客户端都是被拒绝访问的。下面开始添加富规则,命令如下。 

[root@rhel03 ~]# firewall-cmd --add-rich-rule="rule family=ipv4 source address=192.168.23.10 service name=http accept"
success
[root@rhel03 ~]# 

在宿主机(192.168.23.10)用浏览器访问。结果如下图所示

 

可以看到,现在是正常的,然后在192.168.23.34(rhel04机器)上用浏览器访问 rhel03,结果如下图所示。 

 可以看到,访问不了。查看现有富规则,命令如下。

[root@rhel03 ~]# firewall-cmd --list-rich-rules 
rule family="ipv4" source address="192.168.23.10" service name="http" accept
[root@rhel03 ~]# 

富规则的命令只要把添加时的add换成remove即可删除此富规则,命令如下。 

[root@rhel03 ~]# firewall-cmd --remove-rich-rule="rule family=ipv4 source address=192.168.23.10 service name=http accept "
success
[root@rhel03 ~]# 

放行端口的语法如下。 

  • firewall‐cmd ‐‐add‐rich‐rule='rule family=ipv4 source address=源网段 port port=M‐N protocol=协议 accept'

这里M-N的意思是从端口M到端口N。 

练习2:允许192.168.23.10访问本机的端口80。 

[root@rhel03 ~]# firewall-cmd --add-rich-rule="rule family=ipv4 source address=192.168.23.10 port port=80 protocol=tcp accept"
success
[root@rhel03 ~]# 
[root@rhel03 ~]# firewall-cmd --list-rich-rules 
rule family="ipv4" source address="192.168.23.10" port port="80" protocol="tcp" accept
[root@rhel03 ~]#

在192.168.23.10(宿主机)上用浏览器访问rhel03(IP地址是192.168.23.33),结果如下图所示。

 

然后在192.168.23.34(rhel04机器)上用浏览器访问rhel03(IP地址是192.168.23.33), 结果下图所示。

此时,防火墙的规则如下。 

[root@rhel03 ~]# firewall-cmd --list-all
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: ens160
  sources: 
  services: cockpit dhcpv6-client mountd nfs rpc-bind ssh
  ports: 123/udp 323/udp 20-21/tcp 10010-10020/tcp 1000-2000/tcp
  protocols: 
  forward: no
  masquerade: no
  forward-ports: 
  source-ports: 
  icmp-blocks: 
  rich rules: 
	rule family="ipv4" source address="192.168.23.10" port port="80" protocol="tcp" accept
[root@rhel03 ~]# 

删除此规则,命令如下。 

[root@rhel03 ~]# firewall-cmd --remove-rich-rule="rule family=ipv4 source address=192.168.23.10 port port=80 protocol=tcp accept"
success
[root@rhel03 ~]# firewall-cmd --list-rich-rules 

[root@rhel03 ~]# 

注意:

前面讲的对这些规则的管理(包括服务、端口、富规则等)都只是临时生效,如果希望能永久生 效,需要加上--permanent选项。

不加--permanent选项,当前生效,重启系统或firewalld之后不再生效。

加上--permanent选项,当前不生效,重启系统或firewalld之后生效。

所以,写的时候可以写两条,一条不包含--permanent,另一条包含--permanent。 

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要安装Linux firewall-cmd,您需要执行以下步骤: 1. 确保您的系统是基于CentOS/RHEL 7,并且已启用防火墙服务firewalld。 2. 使用以下命令安装防火墙管理工具firewall-cmd: ``` yum install firewalld ``` 3. 安装完成后,您可以使用firewall-cmd命令行客户端来管理防火墙规则。 例如,您可以使用以下命令查看防火墙状态: ``` firewall-cmd --state ``` 需要注意的是,firewalld是Red Hat Enterprise Linux 7中用于管理主机级别防火墙的默认方法。它通过firewalld.service systemd服务来启动,并使用iptables、ip6tables和ebtables命令来管理Linux内核netfilter子系统。同时,为了防止意外启动*tables.service服务并擦除任何正在运行的防火墙配置,可以使用systemctl mask命令对其进行屏蔽。 引用123 #### 引用[.reference_title] - *1* *2* [Linux 防火墙firewall-cmd配置命令大全](https://blog.csdn.net/weixin_45626288/article/details/120343979)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}} ] [.reference_item] - *3* [Linux系统- firewall-cmd的使用详解](https://blog.csdn.net/qq_35550345/article/details/102388546)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值