About me

Monday 8 August 2016

[Linux] Firewalld

  

Firewalld 介紹 firewalld是一套Linux上的防火牆管理工具,最初版本是在2011年1月3號釋出的,穩定版直到2016年4月20號才釋出。主要提供Linux核心的iptables封包過濾(packet filtering)系統 - 『netfilter』的前端(front-end)功能。命名規則主要遵循著Unix的命名規則daemon的名字加一個『d』。這一套工具是由Python所寫的,之前原本想要移植到C++上面,但是這個計畫在2015年時就取消了。 官方上有firewalld的主要功能: - D-Bus API - Timed firewall rules - Rich Language for specific firewall rules - IPv4 and IPv6 NAT support - Firewall zones - IP set support - Simple log of denied packets - Direct interface - Lockdown: Whitelisting of applications that may modify the firewall - Support for iptables, ip6tables, ebtables and ipset firewall backends - Automatic loading of Linux kernel modules - Integration with Puppet

Firewalld支援IPv4和IPv6,而且可以在zone組態檔裡面去定義各式各樣的規則,然後可以根據不一樣的zone來定義你的防火牆。如果你搭配Network Manager軟體的話,還可以根據你的介面來自動切換你的組態,舉例來說,會隨著你的介面是Wi-fi或是Ethernet網路來切換不同的zone組態。

你的服務或是軟體可以藉由D-Bus介面來查詢和使用PolicyKit驗證法來設定你的firewall。Firewalld也支援timed規則,也就是可以限制最多連線數,但是沒有辦法根據IP去限制他的連線次數和總共的連線次數。限制次數主要個功能是用來減少暴力攻擊(brute-force hacking)和阻斷服務攻擊(distributed denial of service)的效果。

firewalld的命令語法會跟其他的iptables前端軟體(像是Ubuntu的ufw)相似,但是互動性會更強(我不知道是真是假,改天我來試試),命令介面允許管理防火牆的規則,並且將其當成群組來管理,像是以協定(protocol),埠口(port),來源(source)和目的(destination)端,或是已經預先定義好的服務名字當成群組來定義。跟之前的iptables服務(system-config-firewall/lokkit 模組)主要的差別是彈性和增強了安全性規則管理,就像是現在新增規則到組態裡面不需要暫停防火牆服務(所以你也可以說firewalld是Dynamic Firewall)。

裡面的服務是用XML的格式來定義,裡面包含了Port和Protocol的對應(Mapping),還有其他的像是子網域(subnet)的資訊還是需要核心模組(kernel modules)的資訊等等。底下是個簡單web server的服務防火牆定義:


<?xml version="1.0" encoding="utf-8"?>
    <service>
      <short/> Web Server </short>
      <?description>Public web host over HTTPS.</description>
      <port port="443" protocol="tcp" />
    </service>



Tools 要藉由firewalld來管理你的防火牆,主要有三套工具: firewall-config: 這是一套GUI的前端工具,包含在firewalld裡面,主要提供了簡單的介面來開啟關閉已經定義好的zone組態檔。如果想要新增zone組態檔或是服務組態,就必須要用firewall-cmd了。 firewall-applet: 這也是一套GUI的前端工具,也包含在firewalld裡面,它提供了防火牆的event log通知一套可以快速開啟防火牆組態的方法。 firewall-cmd: 使用command line的方式來管理你的firewalld,功能是最齊全的,互動性也很強。
採用firewalld的作業系統 在底下三個distros預設都採用firewalld為預設的防火牆: - CentOs 7 或更新的版本 - Fedora 18 或更新的版本 - Red Hat Enterprise Linux 7 或更新的版本 除了以上三套以外,在其他的Distros的套件資料庫(Package Repository)裡面也有,像是Debian。
Zones 想要知道怎麼利用firewall來設置防火牆,第一課就是先學習『zones』的概念,因為firewalld主要就是利用zones和service來取代iptables的chain和rules。zones就是將你電腦的所有流量分成幾個區域,每個區域都有不同的安全等級,只要每一次有連線的要求,或是有傳輸的要求,系統便會用這次傳輸的封包的特徵來分類到相對應的區域裡,所以你的工作就是預先定義好這些zone的組態,對象包含了services,ports和protocols,masquerading/port forwarding和rich的規則。 假設目前有一個即將要進來的網路流量,zone的分類規則如下: - 一個zone可以被綁定在一個網路介面/位址上。 - 任何的封包只要進入網路堆疊(network stack)都會和一個zone作關聯。 - 如果某個zone裡面已經定義了符合這個來源IP位址的規則,則將這個封包給route到這個zone。(就是你有定義這個來源IP全盤接受) - 如果這個封包的來源IP沒有符合任何一個zone,但是你的某個zone有定義這個封包的介面(interface),則將這個封包給route到這個zone(假設你有定義ssh都接受或是tcp都接受)。 - 如果都沒有規則符合,則將這個封包給route到預設的zone (預設為public zone)。 底下有幾個系統已經預先定義好的zones,每個都有不同預設service的規則,哪些service都以通過,哪些是被拒絕的: - trusted: 在這個網路裡面的機器都被允許連線,完全信任 - internal: 既然有外部網路,那gateway的另一邊一定就是內部網路了,裡面的電腦大多處於被允許的狀態,大部份的服務也都被允許。 - home: 比工作環境更高,相信大部分的電腦,也允許更多的服務。 - work: 定義為使用在你的工作環境裡,允許在區網裡的大部分電腦,允許部分的服務。 - dmz: 只有在你的DMZ裡面的電腦能連線,只有允許特定的連線。 - external: 使用你的防火牆來當你的gateway,主要用來當成NAT的masquerading,所以你的內網(internal network)仍然是私密,無法直接連進來的。 - public: 代表公用,不可信任的網路。原則上是不信任其它台電腦的連線,只允許少數的連線規則。 - block: 類似於『drop』,只是外來的連線不會丟棄,取而代之是用訊息『icmp-host-prohibited』和『icmp6-adm-prohibited』來拒絕連線。 - drop: 最低等級的安全性,幾乎所有外來的連線都會丟棄,只有允許往外的連線。 如果想要了解更多這些預設zone的資訊,請執行底下指令參考man 頁面: # man firewalld.zones 當然你也可以建立你自己客製化的zone規則,或者是修改預設的規則。所有zone裡service的定義都被放在『/usr/lib/firewalld/services』資料夾底下,像是我們上面舉過得web sevice的例子,其檔案位置就在『/usr/lib/firewalld/services/https.xml』。如果你有開啟SE-Linux,而且你是自己手動加入你的xml檔的話,記得執行底下這個命令,才會套用: # restorecon
Managing Firewalld 一開始比較重要的點是,舊的『iptables-service』和『firewalld』是衝突的,所以不能同時開啟,如果你還是比較習慣舊的iptables的話,記得把firewall關掉。底下大概講一下怎麼安裝這兩個軟體和關閉衝突的軟體。 關閉iptables # sudo systemctl stop iptables # sudo systemctl mask iptables 檢查狀態 # sudo systemctl status iptables In Ubuntu 移除UFW # sudo apt-get remove ufw 安裝firewalld # sudo apt-get install firewall-applet In Red Hat system 安裝firewalld # sudo yum install firewalld firewall-config -y 檢查狀態 # sudo systemctl status firewalld # firewall-cmd --state
Rule Permanence 在firewalld裡面,規則可以是永久(permanent)和暫時(runtime)的,runtime的意思就是目前系統正在運行的,而permanent則是會確實存起來,只要restart就會重新讀取。如果你只是暫時修改,下一次開機就恢復成原本設定。 如果你想要永久的改變你的設定,記得在你設定時加入『--permanent』,這樣才會寫到硬碟裡面,重開機以後才不會消失。如果你想要把你現在的runtime的設定都永久的存起來,就必須使用: # firewall-cmd --runtime-to-permanent 就算你已經使用『--permanent』選項了,但是它也不會馬上套用到目前的runtime環境,這時候你就必須要執行: # firewall-cmd --reload
Basic Usage - 顯示預設zone # firewall-cmd --get-default-zone - 建立一個新的zone # firewall-cmd --permanent --new-zone=testing - 設定預設zone (這些檔案都存在『/etc/firewalld/firewalld.conf』) # firewall-cmd --permanent --set-default-zone=testing - 顯示所有可取得的zones # firewall-cmd --get-zones - 顯示所有可取得的zones,並且更多資訊。 # firewall-cmd --list-all-zones - 顯示某個zone的詳細資訊 # firewall-cmd --permanent --zone=public --list-all - 顯示使用中或是已經binding到某個介面的zones。 # firewall-cmd --get-active-zones Service Management - 顯示所有預先定義規則並且可取得的service務,這些service都已經有綁port了。 # firewall-cmd --get-services - 顯示出在這個zone底下允許的所有service,如果沒有用『--zone』指定的話,會直接顯示zone public。 # firewall-cmd --list-services - 在某個zone底下新增額外的service,底下的例子以kerberos為例。 # firewall-cmd --add-service=kerberos - 增加複數service。 # firewall-cmd --zone=internal --add-service={http,https,dns} - 在某個zone底下刪除特定的service。 # firewall-cmd --remove-service=kerberos Source Management - 加入某個IP或是某個範圍的IP到某個zone裡面。如果任何的來源流量特徵符合這個規則,則系統將會把這個流量給route到這個zone裡面。 # firewall-cmd --permanent --zone=testing --add-source=10.10.10.0/24 - 顯示出目前在這個zone底下,已經被套用的來源位址。 # firewall-cmd --permanent --zone=testing --list-sources - 移除某個zone底下某個來源IP或是某個範圍的來源IP。 # firewall-cmd --permanent --zone=testing --remove-source=10.10.10.0/24 Port Management - 新增某個port (沒有指定zone就是用預設)。 # firewall-cmd --add-port=9000/tcp - 刪除某個port(使用add-port增加的port)。 # firewall-cmd --remove-port=9000/tcp - 顯示出在某個zone底下所有的port規則。 # firewall-cmd --zone=internal --list-ports Interface Management - 將網路介面eth0分配給internal zone # firewall-cmd --permanent --zone=internal --change-interface=eth0 # nmcli con mod "System eth0" connection.zone internal # nmcli con up "System eth0" - 顯示出哪個zone被分配到介面eth0 # firewall-cmd --get-zone-of-interface=eth0 如果想要了解更多的細節,就請參考man了: # man 1 firewall-cmd 底下先來個比較簡單的例子,接下來在進入比較麻煩的rich 規則: Case: 假設我們現在要新增一個zone - 『test』,然後在這個zone底下允許來源IP - 『192.168.1.0/24』通過,並且也允許ssh service和port 9000被連線。 # firewall-cmd --permanent --new-zone=test # firewall-cmd --permanent --zone=test --add-source=192.168.1.0/24 # firewall-cmd --permanent --zone=test --add-service=ssh # firewall-cmd --permanent --add-port=9000/tcp --zone=test # firewall-cmd --reload 然後檢查: # firewall-cmd --list-all --zone=test test interfaces: sources: 192.168.1.0/24 services: ssh ports: 9000/tcp masquerade: no forward-ports: icmp-blocks: rich rules:
Firewalld Rich Rules 如果基本的設定無法滿足你的需求,想要更細的設定就必須要用到『Rich Rules』,底下會給幾個例子,但是進階資訊的話就請參考: # man 5 firewalld.richlanguage 這個部份會有多重的規則設定,所以將會被依序的執行,首先優先權最高的都是『port forwarding』和『masquerading rules』,在來是『logging rules』,下一個是其他的『allow rules』,最後才是『deny rules』。反正就是最先碰到哪個rule就使用誰,都沒碰到的話,就會使用deny的意思。 想要使用rich rule的話,一定要有關鍵選項『--add-rich-rule=’RULE’』 Case : 只允許來源 IP 10.0.0.0/24 通過TCP進入內部 IP 192.168.0.10/32,並且限定Port 8080~8090 # firewall-cmd --permanent --zone=testing --add-rich-rule='rule family=ipv4 source address=10.0.0.0/24 destination address=192.168.0.10/32 port port=8080-8090 protocol=tcp accept' - 顯示某個特定zone底下的所有rich rules。 # firewall-cmd --permanent --zone=testing --list-rich-rules - 刪除一個既存的rich rule。 # firewall-cmd --permanent --zone=testing --remove-rich-rule='rule family=ipv4 source address=10.0.0.0/24 destination address=192.168.0.10/32 port port=8080-8090 protocol=tcp accept' Case: 拒絕從來源IP 192.168.0.10/24來的封包。 # firewall-cmd --permanent --zone=testing --add-rich-rule='rule family=ipv4 source address=192.168.0.10/24 reject' 通常『reject』會傳回ICMP的封包,但是『drop』將不會處理這個封包,就讓它石沉大海,以安全性來說,設置成drop比reject好,因為至少對方不會知道到底這邊有沒有攻擊目標。 - rate limiting Case: 每分鐘限制10個SSH連線。 # firewall-cmd --permanent --add-rich-rule='rule service name=ssh limit value=10/m accept' - logging Case: 每分鐘限制50個SSH連線,並且將訊息記錄到log,log 的等級設定為『info』 # firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.0.0/24" service name="ssh" log prefix="ssh" level="info" limit value="50/m" accept' Network Address Translation (NAT) NAT這邊就不多加解釋,有興趣或不知道的人請參考鳥哥,簡單來說就是你的內網裡面有很多的電腦,每台電腦都有自己的IP,但是外面的人只會知道你這台對外server的IP,不會知道你裡面的配置,當然你的流量要出去的話都要透過這一台server。NAT的防火牆可以透過『masquerading』和『port forwarding』的設置來達成。這邊比較重要的是,『masquerading』只可以用在IPv4。 Masquerading With Firewalld 當你現在有個封包要出去外網的話,masquerading將會將這個封包的來源IP位址改為系統的,而不是你原本電腦的IP位址,然後在傳出去到目的地;等到目的地回傳以後,傳到我們的系統,系統會將這個封包的目的IP位置在改為我們當初傳出去的那個原始IP。 開啟這個功能如下: # firewall-cmd --permanent --zone=testing --add-masquerade 確認masquerade的狀態: # firewall-cmd --permanent --query-masquerade Case: 任何從IP 192.168.1.0/24送出去的封包都會被masquerade # firewall-cmd --permanent --zone=testing --add-rich-rule='rule family=ipv4 source address=192.168.1.0/24 masquerade' Port Forwarding With Firewalld port forwarding功能可以將送到系統裡面某個port的封包都導到其他特定的port。 Case: 系統會將所有傳送到這個server的port 22的封包都給導到 10.0.0.10:2222 (TCP)。 # firewall-cmd --permanent --zone=testing --add-forward-port=port=22:proto=tcp:toport=2222:toaddr=10.0.0.10 確認是否已經設定成功: # firewall-cmd --permanent --zone=testing --query-forward-port=port=22:proto=tcp:toport=2222:toaddr=10.0.0.10 如果只要要確認設定是否有成功,上面masquerading和port forwarding的語法都非常的長,所以可以用底下的命令,將所有的設定印出來就好: # firewall-cmd --permanent --list-all --zone=testing testing interfaces: sources: services: ports: masquerade: yes forward-ports: port=22:proto=tcp:toport=2222:toaddr=10.0.0.10 icmp-blocks: rich rules: rule family="ipv4" source address="192.168.1.0/24" masquerade
Direct Rules firewalld這邊也可以像之前iptables一樣的方式來設定你的防火牆,只要透過選項『--direct』就可以了,如果要永久加入請記得加入permanent,並且不需要用reload,因為是direct mode。 Case: 我們要接受所有tcp port 9000的連線。 # firewall-cmd --direct --add-rule ipv4 filter INPUT 0 -p tcp --dport 9000 -j ACCEPT Case: 刪除我們剛剛建立的這個direct rule。 # firewall-cmd --direct --remove-rule ipv4 filter INPUT 0 -p tcp --dport 9000 -j ACCEPT Case: 顯示所有的direct rules。 # firewall-cmd --direct --get-all-rules
Offline Configuration 在有些你還沒啟動firewalld的狀況之下,但是你還是想要設定firewalld,你就可以用『firewall-offline-cmd』來達到這個效果。 Case: 離線設定一個接受port 22的規則。 #firewall-offline-cmd --direct --add-rule ipv4 filter INPUT 0 -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
Configuration Backup 如果想要把你目前的所有防火牆設定都儲存備份: # iptables -S > firewalld_rules_ipv4 # ip6tables -S > firewalld_rules_ipv6
Debugging Tip 如果你想要更加的了解firewalld的運作原理,可以在檔案『/etc/sysconfig/firewalld』裡面增加如下資訊: # firewalld command line args # possile values: --debug FIREWALLD_ARGS='--debug' 然後在檔案『/var/log/firewalld』裡面就會有很多額外的資訊。
Ref https://www.rootusers.com/how-to-use-firewalld-rich-rules-and-zones-for-filtering-and-nat/ https://www.certdepot.net/rhel7-get-started-firewalld/ https://www.digitalocean.com/community/tutorials/how-to-set-up-a-firewall-using-firewalld-on-centos-7 http://ktaraghi.blogspot.tw/2013/10/what-is-firewalld-and-how-it-works.html https://en.wikipedia.org/wiki/FirewallD http://www.firewalld.org/ https://www.unixmen.com/iptables-vs-firewalld/ http://stackoverflow.com/questions/24756240/how-can-i-use-iptables-on-centos-7 http://serverfault.com/questions/674874/is-there-a-way-to-run-just-save-with-firewalld-in-rhel7 http://stackoverflow.com/questions/24756240/how-can-i-use-iptables-on-centos-7

No comments:

Post a Comment