區域的服務

若要在防火牆上開啟一些連接埠,讓對外的服務使用,可以再區域設定中新增一些服務設定。firewalld 中有預先定義一些常用的服務名稱,這用這個指令查詢:

# 列出預先定義的服務名稱
firewall-cmd --get-services
RH-Satellite-6 amanda-client amanda-k5-client bacula bacula-client bitcoin bitcoin-rpc bitcoin-testnet bitcoin-testnet-rpc ceph ceph-mon cfengine condor-collector ctdb dhcp dhcpv6 dhcpv6-client dns docker-registry dropbox-lansync elasticsearch freeipa-ldap freeipa-ldaps freeipa-replication freeipa-trust ftp ganglia-client ganglia-master high-availability http https imap imaps ipp ipp-client ipsec iscsi-target kadmin kerberos kibana klogin kpasswd kshell ldap ldaps libvirt libvirt-tls managesieve mdns mosh mountd ms-wbt mssql mysql nfs nrpe ntp openvpn ovirt-imageio ovirt-storageconsole ovirt-vmconsole pmcd pmproxy pmwebapi pmwebapis pop3 pop3s postgresql privoxy proxy-dhcp ptp pulseaudio puppetmaster quassel radius rpc-bind rsh rsyncd samba samba-client sane sip sips smtp smtp-submission smtps snmp snmptrap spideroak-lansync squid ssh synergy syslog syslog-tls telnet tftp tftp-client tinc tor-socks transmission-client vdsm vnc-server wbem-https xmpp-bosh xmpp-client xmpp-local xmpp-server

大部分常見的網路服務都有在這個列表中,若要將指定的服務新增至指定的區域中,可執行:

# 將 http 服務新增至 public 區域中
sudo firewall-cmd --zone=public --add-service=http

上面這行指令只是暫時將 http 服務新增至 public 區域中,重新開機後這個設定就不見了,通常在比較重要的伺服器上,我們都會先使用暫時的設定先進行測試,若測試沒問題,再將設定寫入設定檔,永久保存:

# 永久將 http 服務新增至 public 區域中
sudo firewall-cmd --zone=public --permanent --add-service=http

執行永久的設定之後,可再重新查詢一次永久設定值,確認設定值是否正確:

# 列出 public 區域永久的服務設定值
sudo firewall-cmd --zone=public --permanent --list-services

這樣設定之後,在 public 這個區域就會開啟網頁的 80 連接埠,讓外面可以連進來我們的網站,而現在的網站都會提供安全加密的網頁,所以最好連 HTTPS 的 443 連接埠也一並開啟,開啟的方式大同小異:

# 將 https 服務新增至 public 區域中
sudo firewall-cmd --zone=public --add-service=https

# 永久將 https 服務新增至 public 區域中
sudo firewall-cmd --zone=public --permanent --add-service=https

自訂開啟連接埠

基本上 firewalld 有內定的服務都可以使用上面這種方式開啟,如果我們想要開啟的連接埠不在 firewalld 內建的服務名單中,也可以直接指定通訊協定(tcpudp)與埠號:

# 開啟 tcp 的 8080 連接埠
sudo firewall-cmd --zone=public --add-port=8080/tcp

# 永久開啟 tcp 的 8080 連接埠
sudo firewall-cmd --zone=public --permanent --add-port=8080/tcp

埠號的部分也可以用範圍的方式指定,一次開通多個連接埠:

# 開啟 udp 的 4990 至 4999 連接埠
sudo firewall-cmd --zone=public --add-port=4990-4999/udp

# 永久開啟 udp 的 4990 至 4999 連接埠
sudo firewall-cmd --zone=public --permanent --add-port=4990-4999/udp

移除服務

若要將指定的服務從某個區域中移除,可以執行:

# 將 http 服務從 public 區域中移除
sudo firewall-cmd --zone=public --remove-service=http

# 永久將 http 服務從 public 區域中移除
sudo firewall-cmd --zone=public --permanent --remove-service=http

如果是要移除自訂的通訊協定與埠號,則執行:

# 關閉 tcp 的 8080 連接埠
sudo firewall-cmd --zone=public --remove-port=8080/tcp

# 永久關閉 tcp 的 8080 連接埠
sudo firewall-cmd --zone=public --permanent --remove-port=8080/tcp

新增服務名稱

除了直接指定通訊協定與埠號之外,我們也可以自訂新的服務名稱,加入 firewalld 的服務名稱清單中,這樣就可以使用服務名稱的方式來設定開啟的服務,這樣做的好處是可以讓防火牆的設定看起來更容易理解,不會搞不清楚某些奇怪埠號的用途。

若要新增服務名稱,可以在 /etc/firewalld/services 新增服務的 XML 設定檔,XML 設定檔的語法可參考 /usr/lib/firewalld/services/ 中的範例,例如 http.xml 就是定義 http 服務的設定檔:

<?xml version="1.0" encoding="utf-8"?>
<service>
  <short>WWW (HTTP)</short>
  <description>HTTP is the protocol used to serve Web pages. If you plan to make your Web server publicly available, enable this option. This option is not required for viewing pages locally or developing Web pages.</description>
  <port protocol="tcp" port="80"/>
</service>

參考這些範例後,撰寫自己的服務設定檔(若需要開啟多個連接埠,可以自己新增,或是參考其他的範例檔),然後另外儲存成一個新的檔案,放在 /etc/firewalld/services 目錄下,檔名要設定為服務的名稱加上 XML 的附檔名,例如 my_service.xml,接著讓 firewalld 重新載入設定:

# 重新載入設定
sudo firewall-cmd --reload

重新查詢一次支援的服務名稱,應該就可以看到新加入的 my_service 服務了:

# 列出預先定義的服務名稱
firewall-cmd --get-services

常用範例

這裡蒐集一些常用的 firewalld 防火牆設定指令。

只允許特定來源 IP 位址使用服務

如果我們的服務只想讓某些特定來源 IP 位址的電腦使用,可以這樣設定:

# 允許 192.168.0.0/24 使用 http 服務
firewall-cmd --zone=public \
  --add-rich-rule 'rule family="ipv4" source address="192.168.0.0/24" service name="http" accept'

# 永久允許 192.168.0.0/24 使用 http 服務
firewall-cmd --zone=public \
  --add-rich-rule 'rule family="ipv4" source address="192.168.0.0/24" service name="http" accept' \
  --permanent

白名單 IP 位址

若要將特定的 IP 位址設定為白名單,讓它可以連接任何的連接埠,可以這樣做:

# 將 192.168.0.123 列為 public 區域的白名單
firewall-cmd --zone=public \
  --add-rich-rule='rule family="ipv4" source address="192.169.0.123" accept'

# 永久將 192.168.0.123 列為 public 區域的白名單
firewall-cmd --zone=public \
  --add-rich-rule='rule family="ipv4" source address="192.169.0.123" accept' \
  --permanent

黑名單 IP 位址

若要將特定的 IP 位址設定為黑名單,阻擋該 IP 來源的所有連線,可以這樣設定:

# 禁止 181.215.176.3 的所有連線
firewall-cmd --zone=public \
  --add-rich-rule 'rule family="ipv4" source address="181.215.176.3" reject'

# 永久禁止 181.215.176.3 的所有連線
firewall-cmd --zone=public \
  --add-rich-rule 'rule family="ipv4" source address="181.215.176.3" reject'
  --permanent

參考資料:Red HatFedoraTecmintDigitalOcean黃昏的甘蔗