最後更新: 2023-11-27
介紹
- zones - to define the trust level of network connections(source ip) or interfaces
* If firewalld gets started after the network is already up, the connections are not bound to a zone
- D-BUS interface - for firewall configuration of services and applications
- Command line - client for the user
目錄
- 安裝
- firewall-cmd
- Temporary 與 Permanent Rule
- ...
- Trusted Zone
- Complete Reload
- Masquerade
- Port forwarding(DNAT)
- Direct Rules
- Drop All Packets (Panic Mode)
- ICMP (ping)
- Log denied
- Cheat List
- Add rules comment
- Doc
安裝
yum install firewalld
systemctl start firewalld
# 當 sure 所有 rule 無問題才好 "enable", 否則 reboot 後也不能自救
systemctl enable firewalld
Opts:
-h, --help
# foreground process
--nofork
Check status
service firewalld status
stop:
Redirecting to /bin/systemctl status firewalld.service
firewalld.service - firewalld - dynamic firewall daemon
Loaded: loaded (/usr/lib/systemd/system/firewalld.service; disabled)
Active: inactive (dead)
start:
Redirecting to /bin/systemctl status firewalld.service
firewalld.service - firewalld - dynamic firewall daemon
Loaded: loaded (/usr/lib/systemd/system/firewalld.service; enabled)
Active: active (running) since Wed 2015-01-14 00:12:28 EST; 22h ago
Main PID: 31670 (firewalld)
CGroup: /system.slice/firewalld.service
└─31670 /usr/bin/python -Es /usr/sbin/firewalld --nofork --nopid
Warning: Journal has been rotated since unit was started. Log output is incomplete or unavailable.
firewall-cmd
Check version
firewall-cmd --version
0.3.9
Check status
firewall-cmd --state
running
查看
firewall-cmd --get-services [--permanent]
amanda-client bacula bacula-client dhcp dhcpv6 dhcpv6-client dns ftp high-availability http https imaps ipp ipp-client ipsec kerberos kpasswd ldap ldaps libvirt libvirt-tls mdns mountd ms-wbt mysql nfs ntp openvpn pmcd pmproxy pmwebapi pmwebapis pop3s postgresql proxy-dhcp radius rpc-bind samba samba-client smtp ssh telnet tftp tftp-client transmission-client vnc-server wbem-https
firewall-cmd --list-all [--permanent] [--zone=public]
public (default, active) interfaces: eth0 sources: services: dhcpv6-client ssh ports: masquerade: no forward-ports: icmp-blocks: rich rules:
其他類似 cmd 有
- --list-ports
- --list-services
- --list-rich-rules
- --list-interfaces List interfaces that are bound to a zone [P] [Z]
- --list-sources List sources that are bound to a zone [P] [Z]
- .......................
* "--list-all" 係不會顯示 direct rule
* "--list-all" default 只會顯示 public zone
P.S.
firewall-cmd --get-active-zone
internal interfaces: ens224 public interfaces: ens192
firewall-cmd --list-all --zone=internal
Remark
If NetworkManager is not used, there are some limitations:
* firewalld will not get notified about network device renames.
* Manually created interfaces are not bound to a zone.
* Please add them to a zone with
/bin/systemctl stop NetworkManager.service
firewall-cmd --zone=zone --add-interface=interface
* 一個 interface 只跟一個 zone !!
Temporary 與 Permanent Rule
Runtime configuration = temporary
actual active configuration and is not permanent. (reload/restart of the service)
Temporary Rule:
# --remove-service=http
firewall-cmd --zone=internal --add-port=443/tcp
Make the new settings persistent:
firewall-cmd --runtime-to-permanent
P.S.
在 cron job 上用 "/usr/sbin/iptables -F" 是無用的, 定期行亦 login 唔返入去
Zone
生效次序
- source already bound to a zone
- interface
- default zone
* an interface cannot be assigned to more than one zone.
* In its default configuration, firewalld pairs all interfaces with the public zone
* A source cannot be assigned to multiple zones.
zone 的設定
length of zone_name is currently limited to 17 chars
# Default 都有好多 zone
firewall-cmd --get-zones
block dmz drop external home internal public trusted work
firewall-cmd --list-all-zones
.............. block target: %%REJECT%% icmp-block-inversion: no interfaces: sources: services: ports: protocols: masquerade: no forward-ports: source-ports: icmp-blocks: rich rules: .............. public (active) target: default icmp-block-inversion: no interfaces: eth0 sources: services: dhcpv6-client ssh ports: 3260/tcp protocols: masquerade: no forward-ports: source-ports: icmp-blocks: rich rules: .............. trusted target: ACCEPT icmp-block-inversion: no interfaces: sources: services: ports: protocols: masquerade: no forward-ports: source-ports: icmp-blocks: rich rules: ..............
firewall-cmd --get-active-zones
public
interfaces: eno16777736
# 加了 source ip 才 active
trusted
sources: 192.168.88.0/24
firewall-cmd --get-default-zone
# 所有沒有指定 "--zone=???" 的 Rule 都是在這個 zone
public
設定 default zone
# "firewall-cmd --state" 是 running 時才可設定
firewall-cmd --set-default-zone=public
Interface with zone
A zone can be bound to a network interface (see above) and/or to a network addressing (called here a source).
# 某 zone 有什麼 interface
firewall-cmd --list-interfaces
firewall-cmd --zone=public --list-interfaces
eth0
# 某 nic 是屬於那個 zone
firewall-cmd --get-zone-of-interface=eth0
public
加一 IP 入某 Zone
# Add
# Block an IP
firewall-cmd --zone=drop --add-source=n.n.n.n
Notes
如果要中止已建立的連線, 就要行
conntrack -D -s n.n.n.n
# Checking
firewall-cmd --zone=drop --list-all
Add / Remove Interface to a zone
# Remove interface from a zone
firewall-cmd --zone=public --remove-interface=virbr0 --permanent
msg
The interface is under control of NetworkManager and already bound to the default zone The interface is under control of NetworkManager, setting zone to default.
* 可以不理此 msg, 因為所有 Interface default 在 public Zone
# Add interface to a zone
firewall-cmd --zone=internal --add-interface=virbr0 --permanent
# Apply & Checking
firewall-cmd --reload
success
firewall-cmd --get-active-zone
internal interfaces: lxcbr0 public interfaces: ens4
Service
查看現成的 Service
firewall-cmd --get-services [--permanent]
ls -1 /usr/lib/firewalld/services
自定的 Service
ls -1 /etc/firewalld/services
service 的 xml file
myftp.xml
<?xml version="1.0" encoding="utf-8"?> <service> <short>ftp</short> <description>PASV FTP Service</description> <port protocol="tcp" port="21"/> <port protocol="tcp" port="9000-9049"/> </service>
Notes
#1. short = short description (是非必要的)
firewall-cmd --service=myftp --permanent --get-short
#2. description (是非必要的)
firewall-cmd --service=myftp --permanent --get-description
i.e. 自定 ftp service
建立 /etc/firewalld/services/myftp.xml
<?xml version="1.0" encoding="utf-8"?> ...
* 檔名只可以是 alphanumeric, '_' 及 '-'
firewall-cmd --reload
查看 Service 的 Info
firewall-cmd --info-service=myftp [--permanent]
myftp # 檔案名 ports: 21/tcp 9000-9049/tcp protocols: source-ports: modules: destination: includes: helpers:
找出 service 檔的位置
firewall-cmd --path-service=myftp --permanent # 必須加上 "--permanent"
/etc/firewalld/services/myftp.xml
加 service
firewall-cmd --add-service=myftp --permanent
firewall-cmd --reload
刪除 service: --remove-service
firewall-cmd --remove-service=myftp --permanent
firewall-cmd --reload
P.S.
# 同時刪除多個 Services (多項的 "--remove-service")
firewall-cmd --zone=internal --permanent --remove-service={cockpit,dhcpv6-client,mdns,samba-client,ssh}
check-config
--check-config
Run checks on the permanent configuration. This includes XML validity and semantics.
firewall-cmd --check-config
success
Open Port
"--add-port" 與 "--remove-port"
firewall-cmd --zone=public --add-port=22/tcp --permanent
firewall-cmd --zone=zone --remove-port=portid[-portid]/protocol --permanent
firewall-cmd --remove-port=80/tcp
Port value
port=<port>[-<port>]
protocol="tcp|udp"
short - Is an optional start and end tag and is used to give a zone a more readable name.
interface - Is an optional empty-element tag and can be used several times. It can be used to bind an interface to a zone.
查看 status
systemctl status firewalld
firewalld.service - firewalld - dynamic firewall daemon Loaded: loaded (/usr/lib/systemd/system/firewalld.service; enabled) Active: active (running) since Mon 2015-01-12 21:46:47 EST; 49min ago Main PID: 597 (firewalld) CGroup: /system.slice/firewalld.service └─597 /usr/bin/python -Es /usr/sbin/firewalld --nofork --nopid Jan 12 21:46:47 localhost.localdomain systemd[1]: Started firewalld - dynamic firewall daemon. Jan 12 21:53:13 localhost.localdomain systemd[1]: Started firewalld - dynamic firewall daemon. Jan 12 22:32:44 localhost.localdomain firewalld[597]: 2015-01-12 22:32:44 ERROR: PARSE_ERROR: Unexpected element source Jan 12 22:33:13 localhost.localdomain firewalld[597]: 2015-01-12 22:33:13 ERROR: Failed to load service file '/etc/firewalld/services/mysql.xml': PARSE_ERROR: Unexp...ent source Hint: Some lines were ellipsized, use -l to show in full.
# rich-rule
Is an optional element tag and can be used several times to have more than one rich language rule entry.
<rule [invert="ipv4|ipv6"]/> <source address="address[/mask]" [invert="bool"]/> [ <log [prefix="prefixtext"] [level="emerg|alert|crit|err|warn|notice|info|debug"]/> [<limit value="rate/duration"/>] </log> ] [ <audit> [<limit value="rate/duration"/>] </audit> ] <accept/> | <reject [type="rejecttype"]/> | <drop/> </rule>
target="ACCEPT|REJECT|DROP"
The ACCEPT target is used in the trusted zone, every packet will be accepted.
The REJECT target is used in the block zone, every packet will be rejected with the default firewalld reject type.
The DROP target is used in the drop zone, every packet will be dropped.
The default
target is {chain}_ZONE_{zone} and will be used if the target is not specified.
If other than the default target is used, all settings except interface and source are ignored,
because the first rule created in firewall for this zone is 'jump to target'.
Example:
allow an ip range to port
* 要一句過, 唔用得 "/"
firewall-cmd --permanent --zone=public \
--add-rich-rule='rule family="ipv4" source address="x.x.x.x/24" port protocol="tcp" port="3306" accept'
allow an ip to a service
firewall-cmd --permanent --zone=public \
--add-rich-rule='rule family="ipv4" source address="x.x.x.x" service name="rsync" accept'
source-port
firewall-cmd --add-rich-rule='rule family="ipv4" source-port port="12345" protocol="tcp" drop'
# remove rich-rule:
firewall-cmd [--zone=zone] --remove-rich-rule='rule'
i.e.
firewall-cmd --add-rich-rule='rule family="ipv4" source address="x.x.x.x" port port="7" protocol="tcp" accept'
firewall-cmd --remove-rich-rule='rule family="ipv4" source address="x.x.x.x" port port="7" protocol="tcp" accept'
firewall-cmd --list-all
Rich Rule Structure
rule [family="rule family"] [ source [NOT] [address="address"] [mac="mac-address"] [ipset="ipset"] ] [ destination [NOT] address="address" ] [ element ] [ log [prefix="prefix text"] [level="log level"] [limit value="rate/duration"] ] [ audit ] [ action ]
ACL: Allow ALL from an IP
# By rich rule
firewall-cmd --add-rich-rule='rule family="ipv4" source address="x.x.x.x" accept'
# By create a new zone
# FirewallD zones are defined by source addresses and by interfaces
# "--new-zone" 一定要 "--permanent"
i.e "work" zone rules will apply to the particular subnet.
firewall-cmd --new-zone=MyOffice --permanent
firewall-cmd --zone=MyOffice --add-source=192.168.123.200/32 --permanent
firewall-cmd --zone=MyOffice --add-port=2222/tcp --permanent
# Add IP to trusted zone
# Checking
firewall-cmd --get-active-zones
原本
public interfaces: eth0
新:
public interfaces: eth0 MyOffice sources: 192.168.123.200/32
Trusted Zone
firewall-cmd --permanent --zone=trusted --add-source=192.168.2.0/24
firewall-cmd --permanent --zone=trusted --list-sources
# –remove-source
# –change-source
Complete Reload
# To reload the firewall and interrupt user connections, that is to say, to discard state information
firewall-cmd --complete-reload
Masquerade
/etc/sysctl.conf
net.ipv4.ip_forward=1
sysctl -p
以前: (iptables 年代)
iptables -t nat -A POSTROUTING -s 192.168.123.0/24 -o eth0 -j MASQUERADE
現在: (firewall-cmd 年代)
# ens192 是第一張 NIC, 它本身在 public zone
firewall-cmd --zone=internal --add-interface=ens224 --permanent
firewall-cmd --zone=public --add-masquerade --permanent
firewall-cmd --reload
# Checking
cat /proc/sys/net/ipv4/ip_forward
1
firewall-cmd --get-active-zone
internal interfaces: ens224 public interfaces: ens192
firewall-cmd --zone=public --query-masquerade
yes
Port Forwarding(DNAT)
Add Port forwarding
# 2222/tcp -> 22/tcp
firewall-cmd --zone=public --permanent \ --add-forward-port=port=2222:proto=tcp:toport=22:toaddr=192.168.200.11
Checking Port forwarding
firewall-cmd --list-all
... forward-ports: port=2222:proto=tcp:toport=22:toaddr=192.168.200.11 ...
Remark
iptables-save | grep 2222
-A PRE_public_allow -p tcp -m tcp --dport 2222 -j MARK --set-xmark 0x64/0xffffffff
iptables-save | grep 0x64
-A PRE_public_allow -p tcp -m mark --mark 0x64 -j DNAT --to-destination 192.168.200.29:22 -A FWDI_public_allow -m conntrack --ctstate NEW,UNTRACKED -m mark --mark 0x64 -j ACCEPT
Remove Port Forwarding
firewall-cmd --zone=public --permanent \ --remove-forward-port=port=2222:proto=tcp:toport=22:toaddr=192.168.200.11
限 Source IP 版本 Port Forwarding [Rich rule]
# 3307/tcp -> 3306/tcp
firewall-cmd --add-rich-rule='rule family=ipv4
source address=S.S.S.S
forward-port port=3307 protocol=tcp
to-port=3306 to-addr=192.168.200.12'
Checking
firewall-cmd --list-rich-rules
多 Wan IP 版本 DNAT
# Set
D.D.D.D = Wan IP2
firewall-cmd --add-rich-rule='rule family=ipv4 destination address=D.D.D.D forward-port port=3307 protocol=tcp to-port=3306 to-addr=192.168.200.22'
# Checking
firewall-cmd --list-all --permanent
Port Redirect
firewall-cmd --direct \ --add-rule ipv4 nat PREROUTING 0 -p tcp --dport 1025:1030 -j REDIRECT --to-port 25
* Priority 0 means add rule on top of the chain
Checking
firewall-cmd --direct --get-all-rules
ipv4 nat PREROUTING 0 -p tcp --dport 1025:1030 -j REDIRECT --to-port 25
P.S.
"REDIRECT" 的 "--to-port" 只會去本機的第一粒 IP (Sub IP 無效)
i.e.
postfix-1 10.0.0.11:1025~1030 --> 10.0.0.11:25 postfix-2 10.0.0.12:1025~1030 -/ postfix-3 10.0.0.13:1025~1030 /
* 25/tcp 本身要 allow 先
* "REDIRECT" 只有 "--to-port", 沒有 "-d"
加強版(比 "REDIRECT" 強) [Direct rule]
WAN_IP=10.0.0.12 firewall-cmd --direct --permanent \ --add-rule ipv4 nat PREROUTING 0 \ -p tcp -d $WAN_IP --dport 1025:1030 \ -j DNAT --to-destination $WAN_IP:25
Checking
iptables -nL -t nat | grep 1025
firewall-cmd --direct --get-all-rules | grep 1025
Direct Rules
Which enables directly passing rules to iptables, ip6tables and ebtables.
It is intended for use by applications and not users.
CLI
firewall-cmd [--permanent] --direct ..
加減 Chain
firewall-cmd [--permanent] --direct --add-chain <ipv4|ipv6|eb> <table> <chain>
firewall-cmd [--permanent] --direct --remove-chain <ipv4|ipv6|eb> <table> <chain>
firewall-cmd [--permanent] --direct --query-chain <ipv4|ipv6|eb> <table> <chain>
firewall-cmd [--permanent] --direct --get-chains <ipv4|ipv6|eb> <table>
Chain
所有 chain 都會被自動改名
i.e.
- INPUT -> INPUT_direct
- FORWARD -> FORWARD_direct
- OUTPUT -> OUTPUT_direct
Query & Get / Add / Remove Rule
Query & Get Rule
firewall-cmd [--permanent] --direct --get-all-rules
ie. firewall-cmd --direct --get-all-rules
ipv4 nat PREROUTING 0 -p tcp --dport 1025:1030 -j REDIRECT --to-port 587 ipv4 nat PREROUTING 0 -p tcp --dport 2525 -j REDIRECT --to-port 587
firewall-cmd [--permanent] --direct --get-rules <ipv4|ipv6|eb> <table> <chain>
i.e. firewall-cmd --direct --get-rules ipv4 nat PREROUTING
0 -p tcp --dport 1025:1030 -j REDIRECT --to-port 587 0 -p tcp --dport 2525 -j REDIRECT --to-port 587
firewall-cmd [--permanent] --direct --query-rule <ipv4|ipv6|eb> <table> <chain> <args>
Add Rule
firewall-cmd [--permanent] --direct --add-rule { ipv4 | ipv6 | eb } <table> <chain> <priority> <args>
i.e.
# ttl > 100 的 Outgoing block 了.
firewall-cmd --direct --add-rule ipv4 filter OUTPUT_direct 1 -o ens192 -p icmp -m ttl --ttl-gt 100 -j DROP
# 所有主機的 IP 都 port forward (443->192.168.200.29:443)
firewall-cmd --direct --permanent --add-rule \
ipv4 filter FORWARD 1 -p tcp --dport 443 -j ACCEPT
# 指定某 IP port forward
firewall-cmd --direct --permanent --add-rule \ ipv4 nat PREROUTING 1 -p tcp -d 10.10.10.11 --dport 443 -j DNAT \ --to-destination 192.168.200.29:443
Remove Rule
firewall-cmd [--permanent] --direct --remove-rule { ipv4 | ipv6 | eb } <table> <chain> <args>
* { ipv4 | ipv6 | eb } <table> <chain> <args> 不用 ""
Drop All Packets (Panic Mode)
# Result: no
firewall-cmd --query-panic
# All incoming and outgoing packets are dropped, active connections will expire.
firewall-cmd --panic-on
# Resume normal
firewall-cmd --panic-off
ICMP (ping)
firewall-cmd --get-icmptypes
... echo-request ... timestamp-request
firewall-cmd --add-icmp-block=timestamp-request --permanent
firewall-cmd --reload
# Checking
firewall-cmd --list-all
public (active) target: default icmp-block-inversion: no ... icmp-blocks: timestamp-request ...
Log denied
firewall-cmd --set-log-denied=all
firewall-cmd --get-log-denied
# log over limit (10 per minute)
firewall-cmd --permanent \ --add-rich-rule='rule family="ipv4" service name="ssh" log prefix="fw-ssh" level="info" limit value="10/m" accept'
Disable Log
/etc/firewalld/firewalld.conf
LogDenied=off
systemctl restart firewalld
Cheat List
Useful command
firewall-cmd --reload
firewall-cmd --list-all
firewall-cmd --add-service=mosh --permanent
firewall-cmd --zone=trusted --add-source=192.168.2.0/24 --permanent
CMD:
systemctl start firewalld
cp -a /usr/lib/firewalld/zones/public.xml /etc/firewalld/zones/
cp -a /usr/lib/firewalld/services/ssh.xml /etc/firewalld/services/
cp -a /usr/lib/firewalld/services/dhcpv6-client.xml /etc/firewalld/services/
# 只看 rich rules
firewall-cmd --list-rich-rules
# Set zone interface
firewall-cmd --zone=public --add-interface=eth1 --permanent
# FTP
firewall-cmd --add-port=21/tcp --permanent
firewall-cmd --add-port=9001-9050/tcp --permanent
# Limit SSH
firewall-cmd --add-rich-rule='rule family="ipv4" source address="w.x.y.z" port protocol="tcp" port="22" accept' --permanent
firewall-cmd --remove-service=ssh --permanent
Checking before auto start:
firewall-cmd --list-all --zone=public --permanent
Apply setting & auto start:
firewall-cmd --reload
systemctl enable firewalld
Comment
There is no option for firewalld rich rules yet,
but direct rule can via '-m comment --comment "description"'.
i.e.
firewall-cmd --permanent \
--direct --add-rule ipv4 filter INPUT 0 -p tcp -m tcp -s 1.2.3.4 --dport=22 -j ACCEPT -m comment --comment "Office IP"
Checking
firewall-cmd --direct --get-all-rules
Doc
man 5 firewalld.icmptype — Describes XML configuration files for ICMP filtering.
man 5 firewalld.service — Describes XML configuration files for firewalld service.
man 5 firewalld.zone — Describes XML configuration files for firewalld zone configuration.
man 5 firewalld.richlanguage
https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/Security_Guide/sec-Using_Firewalls.html