woff 發表於 2022-3-27 17:32:34

CentOS Firewalld 防火牆說明及使用NAT上網

在 CentOS 防火牆 iptables 是以 Rules 寫在 Chain 建立規則然後給 kernel 去執行,每次重建規則必須先清除原有規則,這會導致既有連線中斷。到 CentOS 7 之後改用 firewalld 以 zone 的區域分割觀念來建立,並以動態設定方式執行避免中斷的問題。請注意:不能同時執行 iptables 跟 firewalld 這會造成衝突錯誤。

Firewalld 相關路徑
/etc/firewalld:設定檔路徑
/usr/bin/:firewall-cmd 指令所在的位置
/usr/lib/firewalld/:firewalld 預設的設定資料 (xml 格式),例如 nfs.xml 就定義了 <port protocol="tcp" port="2049"/>

--------------------------------------------------------------------------------

註: 如果你直接複製底下的執行卻發生底下錯誤
$ sudo firewall-cmd --permanent --add-service=https
usage: see firewall-cmd man page
firewall-cmd: error: unrecognized arguments: –-permanent –-add-service=https

有可能是因為 - 這個符號透過 web 編碼後產生的錯誤,仔細看下圖 ... 居然還會有 - 符號的不同

解決方式: 把錯誤指令的 - 在 console/ terminal 上重新輸入就 OK了

--------------------------------------------------------------------------------

所謂的 zone 就表示主機位於何種環境,需要設定哪些規則,在 firewalld 裡共有 7 個zones
> 先決定主機要設定在那個區域 zone >> 再往該 zone 設定規則 >>> 重新讀取設定檔 sudo firewall-cmd --reload

public: 公開的場所,不信任網域內所有連線,只有被允許的連線才能進入,一般只要設定這裡就可以了
For use in public areas. You do not trust the other computers on the network to not harm your computer. Only selected incoming connections are accepted.
external: 公開的場所,應用在IP是NAT的網路
For use on external networks with masquerading enabled especially for routers. You do not trust the other computers on the network to not harm your computer. Only selected incoming connections are accepted.
dmz: (Demilitarized Zone) 非軍事區,允許對外連線,內部網路只有允許的才可以連線進來
For computers in your demilitarized zone that are publicly-accessible with limited access to your internal network. Only selected incoming connections are accepted.
work: 公司、工作的環境
For use in work areas. You mostly trust the other computers on networks to not harm your computer. Only selected incoming connections are accepted.
home: 家庭環境
For use in home areas. You mostly trust the other computers on networks to not harm your computer. Only selected incoming connections are accepted.
internal: 內部網路,應用在NAT設定時的對內網路
For use on internal networks. You mostly trust the other computers on the networks to not harm your computer. Only selected incoming connections are accepted.
trusted: 接受所有的連線
All network connections are accepted.
drop: 任何進入的封包全部丟棄,只有往外的連線是允許的
Any incoming network packets are dropped, there is no reply. Only outgoing network connections are possible.
block: 任何進入的封包全部拒絕,並以 icmp 回覆對方 ,只有往外的連線是允許的
Any incoming network connections are rejected with an icmp-host-prohibited message for IPv4 and icmp6-adm-prohibited for IPv6. Only network connections initiated from within the system are possible.

-------------------------------------------------------------------------------

預設主機是被放在 public zone 區域,並有開啟兩個服務 dhcpv6-client ssh
> 在這樣的設定下,任何來源都可以透過 ssh 服務來連接到本主機,但其他的服務 service-port 都是關閉的。
★★★ 顯示目前的設定 ★★★
# firewall-cmd --list-all
public (default, active)
interfaces: ens160
sources:
services: dhcpv6-client ssh
ports:
masquerade: no
forward-ports:
icmp-blocks:
rich rules:

若你的環境沒在用 DHCP ,則可以將他關掉 DHCP 服務 port
★★★ 關掉 DHCP 服務 port ★★★
# sudo firewall-cmd --zone=public --remove-service dhcpv6-client

暫時允許外部連接本機 DNS 服務
★★★ 暫時開啟 DNS port 53 ★★★
# sudo systemctl start named
# sudo systemctl enable named
# sudo firewall-cmd --add-service=dns
# sudo firewall-cmd --reload
# firewall-cmd --list-all
public (default, active)
interfaces: ens160
sources:
services: dhcpv6-client dns ssh
ports: (略)

★★★ 永久開啟 DNS port 53 ★★★
# sudo firewall-cmd --add-service=dns --permanent
# sudo firewall-cmd --reload



QQ:為何可以直接指定加入的服務名稱為 dns 呢?那他怎麼知道要開啟哪些連接埠?
Ans:他會參考 /usr/lib/firewalld/services/ 下的服務,例如 dns.xml ,啟用本服務就會連帶的開啟 TCP 跟 UDP 的 port 53
<?xml version="1.0" encoding="utf-8"?>
<service>
<short>DNS</short>
<description>The Domain Name System (DNS) is used to provide and request host and domain names. Enable this option, if you plan
to provide a domain name service (e.g. with bind).</description>
<port protocol="tcp" port="53"/>
<port protocol="udp" port="53"/>
</service>


總共有這些服務,可以直接叫用
amanda-client.xml high-availability.xml kpasswd.xml mysql.xml pop3s.xml smtp.xml
bacula-client.xml https.xml ldaps.xml nfs.xml postgresql.xml ssh.xml
bacula.xml http.xml ldap.xml ntp.xml proxy-dhcp.xml telnet.xml
dhcpv6-client.xml imaps.xml libvirt-tls.xml openvpn.xml radius.xml tftp-client.xml
dhcpv6.xml ipp-client.xml libvirt.xml pmcd.xml RH-Satellite-6.xml tftp.xml
dhcp.xml ipp.xml mdns.xml pmproxy.xml rpc-bind.xml transmission-client.xml
dns.xml ipsec.xml mountd.xml pmwebapis.xml samba-client.xml vnc-server.xml
ftp.xml kerberos.xml ms-wbt.xml pmwebapi.xml samba.xml wbem-https.xml



★★★ 如何修改主機的預設 zone ★★★
前面說過預設為 public zone ,但有些主機服務是要建立在 DMZ 下,我們可以透過修改 /etc/firewalld/firewalld.conf 來將預設的區域改為 dmz
# sudo vi /etc/firewalld/firewalld.conf
> 修改 DefaultZone=public
> 變成 DefaultZone=dmz
然後重新載入
# sudo firewall-cmd --reload



★★★ 加入自行指定的連接埠 ★★★
# sudo firewall-cmd --add-port=8080/tcp --permanent
success
# sudo firewall-cmd --reload
success
# sudo firewall-cmd --list-all
public (default, active)
interfaces: ens160
sources:
services: dhcpv6-client dns ssh
ports: 8080/tcp
masquerade: no



QQ:為何我設定暫時的 rules 都無效呢?
ANS:假設你臨時要開放 port 8888,於是你執行了
# sudo firewall-cmd --add-port=8888/tcp
# sudo firewall-cmd --reload
# sudo firewall-cmd --list-all

卻發現 --list-all 的結果都沒將 port:8888 這 rule 給加入,這是因為你在第二步驟時做了 reload ,不是設定沒用而是被你的 reload 給清除了,所以臨時性的只要
# sudo firewall-cmd --add-port=8888/tcp
# sudo firewall-cmd --list-all

查看永久的設定
# firewall-cmd--list-all --permanent

★★★ 修改服務的預設連接埠 ★★★
假設你的主機為 web /www ,預設是走 port 80 但有時候某些網站就不是使用 80 port ,這時候該怎麼修改呢?
Step 1:先複製對應的 xml 檔到 /etc/firewalld/services
# sudo cp /usr/lib/firewalld/services/http.xml/etc/firewalld/services
Step 2:修改 http.xml
# sudo vi /etc/firewalld/services/http.xml
Step 3:修改對應連接埠
<port protocol="tcp" port="80"/>
改為
<port protocol="tcp" port="8080"/>
Step 4:重新載入
# sudo firewall-cmd --reload



★★★ 限制某服務只能從哪IP連入 ★★★
通常我們會限制 ssh 只能從某些IP來進來,我們可以使用 rich-rule 來加入
# sudo firewall-cmd --add-rich-rule="rule family="ipv4" source address="192.168.1.88" service name="ssh" accept"
或 ip subnet
# sudo firewall-cmd --add-rich-rule="rule family="ipv4" source address="192.168.1.0/24" service name="ssh" accept"



★★★ 限制某 port 只能從哪IP連入 ★★★
# sudo firewall-cmd --add-rich-rule="rule family="ipv4" source address="192.168.12.9" port port="8080" protocol="tcp" accept"
注意:port port="8080" 不是寫錯唷!這是他的格式



★★★ 直接指定 rule 到 INPUTchain★★★
# sudo firewall-cmd --permanent --direct --add-rule ipv4 filter INPUT 0 -p tcp -s "192.168.12.9" --dport 22 -j ACCEPT
這樣的寫法使用 # firewall-cmd --list-all 是看不到的,要用 iptables -L -n



★★★ 查看預設載入的 rule ★★★
所有的 zone 設定檔會放在 /etc/firewalld/zones 跟 /usr/lib/firewalld/zones/ ,你所執行的 --permanent 參數會寫在 /etc/firewalld/zones 對應的 zone 檔案裡(例:public.xml),所以當你下了
# sudo firewall-cmd --add-service=dns --permanent
就會在 /etc/firewalld/zones/public.xml 變成 多了 <service name="dns"/>
<?xml version="1.0" encoding="utf-8"?>
<zone>
<short>Public</short>
<description>For use in public areas. You do not trust the other computers on networks to not harm your computer. Only selected incoming connections are accepted.</description>
<service name="dhcpv6-client"/>
<service name="ssh"/>
<service name="dns"/>
<port protocol="tcp" port="8080"/>
</zone>



★★★ 從 /etc/sysconfig/iptables 轉為 firewalld 的 direct★★★

假設你原有的 /etc/sysconfig/iptables 有規則
-A INPUT -s 140.113.12.9 -j ACCEPT
-A INPUT -m state --state NEW -m udp -p udp -s 140.113.0.0/16 --dport 123 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp -s 140.114.88.0/24 --dport 161 -j ACCEPT
要轉換到 firewalld 的 direct 規則
新增 /etc/firewalld/direct.xml,如果你之前有執行過 #sudo firewall-cmd --permanent --direct .... 則這個檔案會自動的產生

新增/修改 direct.xml 增加對應上面的 rules
# sudo vi /etc/firewalld/direct.xml
<?xml version="1.0" encoding="utf-8"?>
<direct>
   <rule priority="0" table="filter" ipv="ipv4" chain="INPUT">-p tcp -s 192.168.12.9 --dport 22 -j ACCEPT</rule>
   <rule priority="0" table="filter" ipv="ipv4" chain="INPUT">-s 140.113.12.9 -j ACCEPT</rule>
   <rule priority="0" table="filter" ipv="ipv4" chain="INPUT">-p udp -s 140.113.0.0/16 --dport 123 -j ACCEPT</rule>
   <rule priority="0" table="filter" ipv="ipv4" chain="INPUT">-p tcp -s 140.114.88.0/24 --dport 161 -j ACCEPT</rule>
</direct>

★★★ 從 zone 移除某項服務 ★★★
# sudo firewall-cmd --zone=public --add-service=http --permanent
# sudo firewall-cmd --zone=public --remove-service=http --permanent

# sudo firewall-cmd --zone=public --add-port=8080/tcp --permanent
# sudo firewall-cmd --zone=public --remove-port=8080/tcp --permanent



★★★ port forward 將從某 port number 的封包轉送另外的 port 或其他主機 ★★★
# 將 80 port 收到的訊息轉往 port 8080
# sudo firewall-cmd --zone="public" --add-forward-port=port=80:proto=tcp:toport=8080

# 將 80 port 收到的訊息轉往其他台主機的 port 8080
# sudo firewall-cmd --zone="public" --add-forward-port=port=80:proto=tcp:toport=8080:toaddr=140.113.1.1



★★★ 如何禁止某些網段連結該主機 ★★★
# 阻擋某個網域連接所有的 port
# sudo firewall-cmd --add-rich-rule 'rule family="ipv4" source address="52.184.0.0/16" reject'



★★★ 如何禁止某些網段連結 主機某個服務,例如 http 80 ★★★
# 阻擋某個網域連接所有的 port
# sudo firewall-cmd --add-rich-rule 'rule family="ipv4" source address="52.184.0.0/16" port port="80" protocol="tcp" reject'
NAT
使用帶有 firewalld 的 CentOS 7,所以您需要做的就是告訴 firewalld 在與您的外部接口對應的區域上啟用偽裝。
firewall-cmd --zone=public --add-rich-rule='rule family=ipv4 masquerade' [--permanent]


Reference:
https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/Security_Guide/sec-Using_Firewalls.html
https://www.youtube.com/watch?v=7_XwTdZlqes
https://www.linode.com/docs/security/firewalls/introduction-to-firewalld-on-centos



Useful ‘FirewallD’ Rules to Configure and Manage Firewall in Redhat Linux, CentOS 7 & Fedora
https://www.youtube.com/watch?v=mF2IwthpvT4

---------------------

#查看 firewall 目前設定
$ sudo firewall-cmd --list-all

#查看 firewall 預設設定
$ sudo firewall-cmd --list-all --permanent

# 增加 http、https 連接埠開啟
$ sudo firewall-cmd --add-service=http --permanent
$ sudo firewall-cmd --add-service=https --permanent
$ sudo firewall-cmd --list-all --permanent

#開啟特定來源可以連線 SSH
$ sudo firewall-cmd --add-rich-rule="rule family="ipv4" source address="140.112.13.0/24" service name="ssh" accept" --permanent

#關閉全開 ssh
$ sudo firewall-cmd --zone=public --remove-service=ssh --permanent

#關閉 ipv6 dhcp client
$ sudo firewall-cmd --zone=public --remove-service=dhcpv6-client --permanent

# 如果都直接使用 --permanent 參數,則目前的設定並不會受影響,可以用 reload 載入
$ sudo firewall-cmd --reload
文章出處
頁: [1]
查看完整版本: CentOS Firewalld 防火牆說明及使用NAT上網