第2篇:Linux防火墻-firewalld的rich規(guī)則配置

這是承接上一篇的內(nèi)容

在某些情況下,我們可能需要創(chuàng)建更復(fù)雜的規(guī)則,而不僅僅是允許區(qū)域中的某些端口或服務(wù)。例如,我們可能想要創(chuàng)建一條規(guī)則來阻止來自特定機器的某種類型的流量。這就是rich規(guī)則的意義所在。規(guī)則基本上由兩部分組成:在第一部分中,我們指定要應(yīng)用規(guī)則必須滿足的條件,在第二部分中,指定要執(zhí)行的操作:accept、drop或reject

實驗?zāi)康?/h3>

在下面的實驗拓網(wǎng)絡(luò)拓撲中,防火墻的 ens33網(wǎng)卡是分配到external區(qū)域,ens34網(wǎng)卡分配的internal區(qū)域


我們的實現(xiàn)目的是防止特定外網(wǎng)(用192.168.168.0/24來模擬)的主機192.168.168.105訪問我們防火墻的ssh服務(wù)

我們先來看看防火墻本身的一些以下是external區(qū)域的預(yù)配置

以下是internal區(qū)域的預(yù)配置

攔截來自外部網(wǎng)路中IP為192.168.168.105主機的流量:我們將如何組成我們的規(guī)則,事實上,就是iptables規(guī)則的一種變相語法:

firewall-cmd --zone=external --add-rich-rule="rule \
family="ipv4" \
source address=192.168.168.105 \
service name=ssh 
reject \"

rich規(guī)則詳解

  • --add-rich-rule選項,將該規(guī)則描述為其參數(shù)。規(guī)則以rule關(guān)鍵字開頭。
    • family:我們指定該規(guī)則僅應(yīng)用于IPv4數(shù)據(jù)包:如果未提供此關(guān)鍵字,則該規(guī)則將同時應(yīng)用于IPv4和IPv6。
    • source address:我們提供數(shù)據(jù)包必須具有的源地址,才能使用源地址觸發(fā)規(guī)則。
    • service,我們指定了規(guī)則的服務(wù)類型,在本例中為ssh。
    • reject/drop/accept,我們提供了數(shù)據(jù)包與規(guī)則匹配時要執(zhí)行的操作,在本例中為reject.

當我們將上面的rich規(guī)則添加的external區(qū)域,我們192.168.168.105再也無法訪問到防火墻的外部接口192.168.168.106了。這是rich規(guī)則的一個簡單用法

上面的一個非常簡單,但是規(guī)則可能變得非常復(fù)雜。您應(yīng)該查看firewalld文檔,以查看所有可用設(shè)置和選項的范圍。

rich規(guī)則的其他命令行參數(shù)

可以查看如下表,里面列舉了rich規(guī)則常用的方法


我這里沒必要一一列出示例,我們先將剛才添加的rich規(guī)則刪掉

firewall-cmd --zone=external --remove-rich-rule=" \
rule family="ipv4" \
 source address="192.168.168.105" \
service name="ssh"  \
reject"

Rich規(guī)則的優(yōu)先級

首先我們在解析這個問題,仍然使用上面的例子,比如我們希望只有192.168.50.17的主機能夠遠程ssh到防火墻,而同一網(wǎng)絡(luò)192.168.50.0/24的其他主機我們禁止其他訪問。


在寫rich規(guī)則時,往往會遇到兩條沖突的規(guī)則。例如,為了只允許來自192.168.50.0/24網(wǎng)絡(luò)的一臺主機192.168.50.17允許通過ssh訪問防火墻,顯然下面的規(guī)則是不可取的

  • 規(guī)則1:-拒絕來自192.168.50.0/24網(wǎng)絡(luò)的所有主機(drop/reject)
  • 規(guī)則2:-允許來自192.168.50.17的主機(accept)

由于192.168.50.17主機也屬于192.168.50.0/24這個網(wǎng)絡(luò)號,因此這兩個規(guī)則都將應(yīng)用于該主機,如果你對iptables規(guī)則熟悉的話,可能會去如下這樣理解防火墻匹配規(guī)則的行為。

  1. 僅處理入站的數(shù)據(jù)包
  2. 數(shù)據(jù)包始終以從上到下的方向進行處理。
    • Step1:一旦數(shù)據(jù)包與規(guī)則匹配,將立即對該數(shù)據(jù)包執(zhí)行關(guān)聯(lián)操作(允許或拒絕)。
    • Step2:數(shù)據(jù)包將不可用于進一步處理。

然后可能就許就這樣定義防火墻的規(guī)則:

  • 規(guī)則1:允許來自192.168.50.17的主機(accept)
  • 規(guī)則2:拒絕來自192.168.50.0/24網(wǎng)絡(luò)的所有主機(drop/reject)

規(guī)則精確度越高的放在規(guī)則列表的最前,邏輯上應(yīng)該是先設(shè)定accept行為的規(guī)則,然后再設(shè)定drop/reject行為的規(guī)則,這樣的邏輯在iptables是正確,甚至其他傳統(tǒng)的防火墻也是這樣行為邏輯的。但你要搞清楚,到了firewalld的rich規(guī)則就不適用了。為了證實這一說法,我么參考了firewalld.org的技術(shù)文檔,請好好理解圖中劃黃線的一段話。


中文的翻譯

當前的rich規(guī)則的一個問題是,它們是基于規(guī)則操作來組織的。 日志規(guī)則始終在拒絕規(guī)則之前發(fā)生。 拒絕規(guī)則總是發(fā)生在允許規(guī)則之前。 這導(dǎo)致用戶感到困惑,因為它隱式地對規(guī)則進行了重新排序。 這也使得不可能添加全面的rich規(guī)則來拒絕流量。

因此firewalld的rich規(guī)則執(zhí)行邏輯如下:

  1. 日志規(guī)則
  2. drop/reject規(guī)則
  3. accept規(guī)則

實驗示例

目標:驗證rich規(guī)則的潛在問題

  • 我們允許192.168.50.0/24所有網(wǎng)絡(luò)訪問局域網(wǎng)的10.10.10.1上的遠程桌面
  • 允許192.168.50.17的主機通過ssh訪問防火墻
  • 拒絕192.168.50.0/24其他主機通過ssh訪問防火墻
  • 拒絕所有來自192.168.50.0/24對防火墻的ping請求

進行上面的拓撲實驗前,我們檢測一下防火墻的狀態(tài)


在Linux管理配置防火墻時,先在文本編輯器將你的思路理順了,然后一條條命令拷貝到shell中回車,是一種很好的習(xí)慣,這些命令能出錯的話,我們部署到生產(chǎn)環(huán)境再寫成shell或python腳本程序。

rich規(guī)則有兩種書寫方法,你不得不吐嘈:"這些地球上最丑陋的命令形式,沒有之一",你不管使用那種形式,都很容易出錯,所以建議你在文件編輯器修改到?jīng)]有毛病才粘貼到shell終端窗口中。

  • 不換行風(fēng)格--add-rich-rule=之后的規(guī)則內(nèi)容用單引號括起來,見下圖第一個的命令
  • 換行風(fēng)格,需要了解一些shell解析器的基礎(chǔ),說明見下圖第二個命令


允許192.168.50.0/24所有主機網(wǎng)絡(luò)訪問局域網(wǎng)的10.10.10.1上的遠程桌面

firewall-cmd --zone=external --add-forward-port=\
port=3389:proto=tcp:toport=3389:toaddr=10.10.10.1

允許192.168.50.17的主機通過ssh訪問防火墻

firewall-cmd --zone=external --add-rich-rule="rule \
family="ipv4" \
source address="192.168.50.17" \
service name="ssh" \
log prefix=\"ssh connect from:\" \
level="notice" \
accept"

拒絕192.168.50.0/24的其他主機訪問防火墻的ssh服務(wù)

firewall-cmd  --zone=external --add-rich-rule="rule \
family="ipv4" \
source address="192.168.50.0/24" \
service name="ssh" \
log prefix=\"ssh reject from:\" \
level="notice" \
drop"

拒絕所有來自192.168.50.0/24對防火墻的ping請求

firewall-cmd  --zone=external --add-rich-rule="rule \
protocol value="icmp" \
reject"

ok,整個過程沒出錯


我們使用以下命令查看,剛才在external區(qū)域配置的rich規(guī)則

firewall-cmd --zone=external --list-rich-rules

實驗的重點:就是要驗證第一條rich的規(guī)則是否會被優(yōu)先執(zhí)行,還是第二條drop規(guī)則會先于第一條accept規(guī)則執(zhí)行?

我們在192.168.50.17的主機上測試一下能否ssh到防火墻?如下圖ssh請求無響應(yīng)且沒有錯誤提示返回,這里至少已經(jīng)證實

  • 即便在規(guī)則列表中accept規(guī)則位置先于drop規(guī)則,但是drop規(guī)則總是會優(yōu)先于accept規(guī)則被匹配。
  • 已經(jīng)無法ping通防火墻,并且由防火墻返回錯誤信息。

防火墻的端口轉(zhuǎn)發(fā)測試,192.168.50.17是一臺Ubuntu主機,我們使用Remmina遠程桌面軟件連接到內(nèi)網(wǎng)10.10.10.1的主機

OK,端口轉(zhuǎn)發(fā)也是成功

那么實現(xiàn)遺留的問題,就是rich規(guī)則如何能如我們所愿地定的規(guī)則順序執(zhí)行?這正是本文的重點

Rich規(guī)則的priority字段

新版的firewalld添加了新的priority字段。它可以是-32768到32767之間的任何數(shù)字,其中數(shù)字越小,優(yōu)先級越高。此范圍足夠大,以允許從腳本或其他實體自動生成規(guī)則。

那么就非常簡單:只需在你想優(yōu)先執(zhí)行的rich規(guī)則中給priority字段定義一個足夠小的負數(shù),就能確保能優(yōu)先于其他drop/reject規(guī)則被firewalld匹配。如下圖所示

Ok,此時,accept的規(guī)則優(yōu)先于其他drop/reject規(guī)則被匹配,這正是我們所希望的。

按照我上面的實驗步驟,應(yīng)該沒什么問題,能達到預(yù)期實驗的目地,結(jié)束本篇之前,要記得
將上面的運行時配置轉(zhuǎn)化為持久配置,執(zhí)行下面命令

firewall-cmd --runtime-to-permanent

小結(jié)

目前,rich規(guī)則的定義,至少目前來說我算是全簡書里解說地很清楚了,但rich規(guī)則的語法是非常令人惡心的,這點不容否認。

參考文獻

https://firewalld.org/2018/12/rich-rule-priorities

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容