4.1 Managing Firewalld
4.1.1 Firewalld overview
firewalld.service
在 RHEL7 中目前是預設的防火牆管理用服務,因此也管理了 Linux kernel netfilter。
但因為 firewalld.service
與舊有的 iptables.service
/ip6tables.service
/ebtables.service
會衝突,因此兩個陣營建議選一個使用就好,假設若要使用 firewalld,那就使用 systemctl mask
指令把其他的 system unit 停止掉:
1 | $ sudo systemctl mask iptables.service |
firewalld 將所有進入的流量分為不同的 zone
來看待,每個 zone 都會擁有相對應的一組規則,處理原則就是先比對到的規則就先處理
預設的 firewalld zone 如下:
Zone name | Default configuration |
---|---|
trusted |
允許全部進入的流量 |
home |
1. 允許 ssh , mdns , ipp-client , samba-client , dhcpv6-client 等服務的流量2. 允許與連外相關的進入流量 3. 其他所有進入的流量皆拒絕 |
internal |
與 zone home 相同 |
work |
1. 允許 ssh , ipp-client , dhcpv6-client 等服務的流量2. 允許與連外相關的進入流量 3. 其他所有進入的流量皆拒絕 |
public |
1. 允許 ssh , dhcpv6-client 等服務的流量2. 允許與連外相關的進入流量 3. 其他所有進入的流量皆拒絕 4. 是新增 network interface 的 default zone |
external |
1. 僅允許 ssh 服務的流量2. 允許與連外相關的進入流量 3. 其他所有進入的流量皆拒絕 4. 所有連外的流量都會偽裝來源(NAT) |
dmz |
1. 僅允許 ssh 服務的流量2. 允許與連外相關的進入流量 3. 其他所有進入的流量皆拒絕 |
block |
僅允許與連外相關的進入流量 |
drop |
允許與連外相關的進入流量(連 ICMP error 都不會回應) |
4.1.2 Managing firewalld
Configure firewall settings with firewall-cmd
RHEL7 提供 firewall-cmd
(console) & firewall-config
(GUI) 作為管理防火牆之用。
透過 firewall-cmd 設定規則,有幾個重點需要注意:
若沒特別指定都只是會只有在 runtime 才有效,重開機就無效了,除非加上
--permanent
選項。指令中都會加上
--zone=<ZONE>
,若沒加就會預設為 default zone設定規則一般都會加上
--permanent
選項,並使用firewall-cmd --reload
來進行永久性的變更套用若只是暫時的測試,可以使用
timeout=<TIMEINSECONDS>
來讓規則短暫在 runtime 時有效
firewall-cmd commands | Explanation |
---|---|
--get-default-zone |
查詢 default zone |
--set-default-zone=<ZONE> |
設定 dfault zone |
--get-zones |
列出所有支援的 zone |
--get-services |
列出所有支援的 service |
--add-source=<CIDR> [–zone= |
允許來自指定 source 的進入流量 |
--remove-source=<CIDR> [–zone= |
禁止來自特定 source 的進入流量 |
--add-interface=<INTERFACE> [--zone=<ZONE>] |
允許從特定裝置進入的流量 |
--change-interface=<INTERFACE> [--zone=<ZONE>] |
設定指定的 interface 與 zone 關聯 |
--list-all [--zone=<ZONE>] |
列出指定 zone 的所有 interface, source, service, port 等規則 |
--list-all-zones |
取得所有 zone 的設定規則資訊 |
--add-service=<SERVICE> [--zone=<ZONE>] |
允許進入流量到指定的 service |
--add-port=<PORT/PROTOCOL> [--zone=<ZONE>] |
允許進入流量到指定的 port or protocol |
--remove-service=<SERVICE> [--zone=<ZONE>] |
禁止進入流量到指定的 service |
--remove-port=<PORT/PROTOCOL> [–zone= |
禁止進入流量到指定的 port or protocol |
--reload |
將 runtime 設定變成永久設定 (沒有加上 –permanent 選項的規則會失效) |
firewall-cmd example
以下用幾個簡單範例,示範使用 firewall-cmd 達成以下設定:(使用 dmz
zone)
將 default zone 設定為
dmz
zone
internal
允許來自 192.168.0.0/24 的流量zone
internal
允許存取 mysql 服務
1 | $ sudo firewall-cmd --set-default-zone=dmz |
Firewall configuration files
firewalld 的設定檔放在 /etc/firewalld
& /usr/lib/firewalld
目錄下,同樣的設定,放在 /etc/firewalld 目錄下的會優先被採用,這是讓管理者可以用來修改原有的預設值之用
Practice: Configuring a Firewall
目標
在 server 上安裝
httpd
&mod_ssl
套件,並確認httpd.service
有啟用且運行中web 首頁顯示
COFFEE
字眼server 上必須啟動
firewalld.service
在 server 上進行 firewalld 設定,使用
dmz
zone 的設定處理未指定的連線來自
172.25.X.0/24
的流量必須導引到work
zone 來處理work
zone 必須開啟https
服務所需要的所有 port,而http
的流量則必須被過濾
實作過程
安裝 & 設定 httpd.service,並修改首頁:
1 | $ sudo yum -y install httpd mod_ssl |
確認 firewalld.service 狀態為啟動中:
1 | # firewalld.service 狀態 |
設定 dmz
zone 處理為指定連線:(即是設定為預設的 zone)
1 | $ sudo firewall-cmd --set-default-zone=dmz |
來自 172.25.X.0/24
的流量必須導引到 work
zone 來處理
1 | $ sudo firewall-cmd --permanent --zone=work --add-source=172.25.X.0/24 |
work
zone 必須開啟 https
服務所需要的所有 port,而 http
的流量則必須被過濾:
1 | $ sudo firewall-cmd --permanent --zone=work --add-service=https |
套用 & 檢查設定:
1 | $ sudo firewall-cmd --reload |
最後,從 desktop 查詢:curl -k https://serverX
4.2 Managing Rich Rules
4.2.1 Rich rules concepts
除了 firewalld 原生支援的 zone & service 之外,使用者還可以透過 direct rules
& rich rules
兩種機制來自訂規則
Direct rules
顧名思義,這種機制就是為了相容 {ip,ip6,eb}tables rule 所產生出來的,若已經有既有的 rules,可透過此機制加入到 firewalld 的管理下,詳細的設定可以參考 firewall-cmd(1)
& firewalld.direct(5)
Rich rules
這就是全新給 firewalld 使用的客製化 rule 機制,除了規則之外,還可以設定 logging 的機制(使用 syslog
& auditd
),甚至連 port forwards, masquerading, rate limiting 等功能都可以設定。
rich rule 的設定基本語法架構如下:
1 | rule |
完整的 rich rule 設定語法可以參考
firewalld.richlanguage(5)
Rule ordering
當規則多起來時,順序的問題就很重要了,順序如下:
任何與 port forwarding & masquerading 相關的規則
任何 logging 相關的規則
任何放行的規則
任何禁止的規則
基本上,先比對到的規則就會先使用,都沒相符的規則就使用預設的規則,而每個 zone 都會有不同的預設規則。
不過 direct rule 會是例外,direct rule 會在 firewalld 開始過濾前就會先執行。
Test and debugging
為了測試與 debug 的方便,幾乎所有加入到 runtime 設定的規則都可以額外加上 timeout
的設定,時間到就會自動移除,之後確認沒問題就可以改用 --permanent
讓設定永久生效
4.2.2 Working with rich rules
firewall-cmd 有 4 個選項用來處理 rich rule 之用,這些選項都可以搭配 --permanent
& --zone
使用:
--add-rich-rule='<RULE>'
新增規則--remove-rich-rule='<RULE>'
:移除規則--query-rich-rule-'<RULE>'
:查詢規則是否有被加入到指定的 zone(or default zone),回傳 0 表示有,1 則是沒有--list-rich-rules
:顯示所有規則 (也可以用--list-all
or--list-all-zones
檢視所有規則)
以下為一些簡單範例:(以下權限以 root 身份執行)
1 | # default zone = public |
4.2.3 Loggind with rich rules
logging 的功能很適合用在 debug or monitor 的需求上,firewalld 可以使用 syslog
,也可以將訊息送給 auditd
;此外,還可以設定 rate limit,避免 log 爆量產生塞滿硬碟
若要搭配 syslog
,使用下面語法:(其中 Log Level 有 emerg
, alert
, crit
, error
, warning
, notice
, info
, debug
幾種可用)
log [prefix=”
“] [level= ] [limit value=”<RATE/DURATION>”]
若搭配 auditd
,則使用下列語法:
audit [limit value=”<RATE/DURATION>”]
以下是則是設定 logging 功能相關的範例:
1 | # 在 zone "work" 中,設定允許 ssh 的流量 |
Practice: Writing Custom Rules
目標
server 安裝
web server
要讓 desktop 可以連限定
最多每秒三筆 log 記錄
,且 log 記錄開頭必須為NEW HTTP
實作過程
1 | $ sudo yum -y install httpd |
4.3 Masquerading and Port Forwarding
firewalld 也支援了 masquerading
(SNAT, 稍有差異) & port forwarding
(DNAT) 兩種 NAT 模式
4.3.1 Masquerading
設定 masquerading 的方式如下:
1 | # 將此機器設定為 zone "work" 的 NAT |
也可以使用 rich rule 設定較為複雜的規則:
1 | # 在 zone "work" 中,將此機器設定為來源為 192.168.0.0/24 的 NAT |
4.3.2 Port forwarding
設定 port forwarding 的語法如下:
firewall-cmd –permanent –zone=<ZONE> –add-forward-port=port=<PORT NUMBER>:proto=<PROTOCOL>[:toport=<PORTNUMBER>] [:toaddr=<IPADDR>]
1 | # 在 zone "public" 中,將到達 tcp:513 的流量導向 192.168.0.254:132 |
也可以使用 rich rule 設定較為複雜的規則:
1 | # 在 zone "work" 中,將來自 192.168.0.0/26,且到 tcp:80 的流量,導向 tcp:8080 |
Practice: Forwarding a port
目標
將來自 172.25.0.10/32 的 tcp port 443
ssh
連線流量轉到 tcp port 22
實作過程
1 | [root@server ~]# firewall-cmd --permanent --add-rich-rule='rule family=ipv4 source address=172.25.0.10/32 forward-port port=443 protocol=tcp to-port=22' |
4.4 Managing SELinux Port Labeling
要確保服務可以正常運行,就要確定 network port 擁有正確的 SELinux type 來與服務搭配才可以
4.4.1 SELinux port labeling
不僅是 file & process,連 network traffic 都屬於 SELinux 的管理範圍內,舉例來說:22/tcp
就有一個 ssh_port_t
的 label 與其相關
因此當一個 process 要監聽某一個 port 時,SELinux 會去檢查 port 有沒有相對應的 label 可供 process 進行 binding,若沒有則 process 會無法正常監聽指定的 port;這功能可以防範不正常的 process 使用到一般服務的 port
4.4.2 Managing SELinux port labeling
Listing port labels
需要調整 label 通常是因為管理者要讓服務監聽一個非標準的 port 上,以下指令可以列出目前系統中已經存在的 SELinux port type:
1 | $ sudo semanage port -l |
Managing port labels
RHEL7 中提供 semanage
指令可用來修改 SELinux port type,指令類似如下:
sudo semanage port -a -t PORT_LABEL -p tcp|udp PORT_NUMBER
1 | # 允許 gopher service 監聽 tcp port 71 |
其他
詳細的 SELinux 參考文件可透過安裝 selinux-policy-devel
套件取得:
1 | $ sudo yum -y install selinux-policy-devel |
Practice: Managing SELinux Port Labeling
目標
確保
httpd.service
啟用且執行web server 監聽
82/tcp
實作過程
1 | # 新增 port type label |
Lab: Network Port Security
目標
讓
sshd.service
同時監聽兩個 port(22/tcp
&999/tcp
)來自
172.25.0.0/24
的流量可以允許進入 zonework
22/tcp
&999/tcp
在 zonework
中必須都要能夠使用
實作過程
檢查 sshd.service 狀態:
1 | $ sudo systemctl status sshd.service |
加入 port label for sshd.service:
1 | [root@server ~]# semanage port -a -t ssh_port_t -p tcp 999 |
放行相關的防火牆:
1 | [root@server ~]# firewall-cmd --permanent --zone=work --add-source=172.25.0.0/24 |
老師補充(iptables)
Linux 防火牆叫做 netfilter
Linux 把很多功能獨立出來成一個一個小檔案,可以到 /lib/modules/
/kernel/ 目錄下找*.ko
的檔案
在上面的目錄的
netfilter
/ipv4
/ipv6
等資料夾下,都是跟網路有關的模組,可參考 http://www.netfilter.org 尋找extention howto
文件,查詢 ko 的使用方式
1、netfilter tables
主要有五個 table:
filter:主要防火牆的功能
nat:IP 分享器的功能進到主機之後,就直接轉出去的封包,歸類為 FORWARD (例如:本機為 router)
mangle:可對封包的內容小幅度的修改(例如:TTL,可偽裝成不同的作業系統)
raw:調整連線追蹤的功能,可以指定某些電腦不做連線追蹤
security
1.1 filter chains
INPUT:從外面進來,目的地為本機應用程式的封包,歸類為 INPUT
FORWARD:進到主機之後,就直接轉出去的封包,歸類為 FORWARD (例如:本機為 router)
OUTPUT:本機的應用程式,目的地是外面主機的封包,歸類為 OUTPUT
Linux netfilter 架構:
table
->chain
->rule
chain default policy:只有
ACCEPT
&DROP
兩種,完全沒動過就會是 ACCEPT
1.2 連線追蹤(使用 state 模組)
狀態分為四種:
NEW:所有連線的第一個封包狀態,皆為 NEW
ESTABLISHED:當封包穿越了 FW,這條連線的後續封包狀態都會變成 ESTABLISHED
RELATED:因為主動產生的連線而發生的其他類型封包
INVALID:狀態不明的封包,建議一律丟棄
1.3 iptables 他使用上的注意事項
若要阻擋特定其他使用上的注意事項
若要阻擋特定網路流量,對內使用 REJECT、對外使用 DROP
--dport 80
:destination port = 80-i eth0
:incoming interface = eth0-o eth1
:outgoing interface = eth1為了避免影響 loopback interface,不建議設定 chain default policy,而是加上
iptables -t filter -A INPUT -i eth0 -j DROP
到最後一條規則iptables -L -v -n
:可看出那一條規則比較熱門
2、NAT 種類
把來源端 ip 換掉的 NAT,稱為 SNAT (POSTROUTING chain 的任務)
把目的端 ip 換掉的 NAT,稱為 DNAT (PREROUTING chain 的任務)
本機產生的封包,原本僅能有 SNAT,而 nat OUTPUT chain 是要補足 DNAT 的功能
要作 NAT 必須開啟 port forward 功能:
echo 1 > /proc/sys/net/ipv4/ip_forward
3、iptables 使用方式
1 | [root@server0 /]# systemctl disable firewalld |
4、基本操作練習
1 | [root@server0 ~]# iptables -t filter -L |
5、使用 shell script 建立 FW
1 |
|