firewall詳解與操作


firewall是什么:

  先聲明一點,不知道iptables的,可以先去了解下。

  firewalld的底層是通過iptables來實現的,,firewalld 和 iptables 都不是防火牆,它們只是防火牆的管理程序,真正的防火牆是內核的netfilter。CentOs 6 中使用iptables來管理防火牆,到了CentOs 7 默認使用firewalld來管理防火牆, firewalld 的底層還是調用 iptables 的,firewalld在iptables的基礎上加了許多很好用的功能。總的來說,firewalld 是系統服務,有守護進程。iptables 也只是一個工具,不是服務。firewall的包過濾機制也是通過iptables來實現的,

  firewalld 的設計者認識到大多數的 iptables 使用案例僅涉及到幾個單播源 IP,僅讓每個符合白名單的服務通過,而其它的會被拒絕。這種模式的好處是,firewalld 可以通過定義的源 IP 和/或網絡接口將入站流量分類到不同區域zone。每個區域基於指定的准則按自己配置去通過或拒絕包。

firewall對比iptables有什么變化:

firewall基於iptables 進行語法簡化。firewalld 通過使用服務名而不是它的端口和協議去指定服務,使它更易於使用,例如,是使用 samba 而不是使用 UDP 端口 137 和 138 和 TCP 端口 139 和 445。它進一步簡化語法,消除了 iptables 中對語句順序的依賴。可以認為firewall就是iptables的管理工具,並且firewall中加入了防火牆的“zone”的概念 ,zone可以理解為 firewalld 的單位、規則集:

默認的規則集有:

  • drop(丟棄),任何接受的網絡數據包都被丟棄,沒有任何回復。僅能有發送出去的網路連接。

  • block(限制),任何接收的網絡連接都被IPv4的icmp-host-prohibited信息和IPv6的icmp6-adm-prohibited信息所拒絕。

  • public(公共),在公共區域內使用,不能相信網絡內的其他計算機不會對你的計算機造成危害,只能接收經過選取的連接。  

  • external(外部),特別是為路由器啟動了偽裝功能的外部網。你不能相信來自網絡的其他計算機,不能相信他們不會對你的計算機造成危害,只能接收經過選擇的連接。

  • dmz(非軍事區),用於你的非軍事區內的電腦,此區域內可公開訪問,可以有限的進入你的內部網絡,僅僅接收經過選擇的連接。

  • work(工作),用於工作區。你可以基本相信網絡內的其他計算機不會危害到你。僅僅接收經過選擇的連接。

  • home(家庭),用於家庭網絡。你可以基本相信網絡內的其他計算機不會危害到你。僅僅接收經過選擇的連接。

  • internal(內部),用於內部網絡。你可以基本相信網絡內的其他計算機不會危害到你。僅僅接收經過選擇的連接。

  • trusted(信任),可接受所有的網絡連接。

firewall的默認zone是public,默認只開放ssh服務和ipv6-client服務

firewall規則集使用詳解:

首先,我們來看看一個規則集中都包含了什么:

[root@localhost opt]# firewall-cmd --zone=public --list-all public target: default icmp-block-inversion: no interfaces: sources: services: ssh dhcpv6-client ports: protocols: masquerade: no forward-ports: source-ports: icmp-blocks: rich rules:

public  表示 public 區域
target: default

默認可以取四個值:default、ACCEPT、%%REJECT%%、DROP

  • ACCEPT:通過這個包。
  • %%REJECT%%:拒絕這個包,並返回一個拒絕的回復。
  • DROP:丟棄這個包,不回復任何信息。
  • default:不做任何事情。

icmp-block-inversion: no
interfaces:   划歸本規則集管理的硬件設備,如網卡等
sources:   信任區域的源ip
services: ssh dhcpv6-client  開放的服務
ports:   開放的端口
protocols: 
masquerade:   no表示這個區域是否允許 IP 偽裝。如果允許,它將允許 IP 轉發,它可以讓你的計算機作為一個路由器。
forward-ports:   列出轉發的端口。
source-ports:   信任區域的源ip及端口
icmp-blocks:   阻塞的 icmp 流量的黑名單。
rich rules:  在一個區域中優先處理的高級配置。

firewall的使用:

活動區域中扮演兩個不同的角色。關聯接口行為的區域作為接口區域,並且,關聯源行為的區域作為源區域(一個區域能夠扮演兩個角色)。firewalld 按下列順序處理一個包:

  1. 相應的源區域。可以存在零個或一個這樣的區域。如果這個包滿足一個富規則rich rule、服務是白名單中的、或者目標沒有定義,那么源區域處理這個包,並且在這里結束。否則,向上傳遞這個包。
  2. 相應的接口區域。肯定有一個這樣的區域。如果接口處理這個包,那么到這里結束。否則,向上傳遞這個包。
  3. firewalld 默認動作。接受 icmp 包並拒絕其它的一切。

這里的關鍵信息是,源區域優先於接口區域。因此,對於多區域的 firewalld 配置的一般設計模式是,創建一個優先源區域來允許指定的 IP 對系統服務的提升訪問,並在一個限制性接口區域限制其它訪問。

 

一個簡單的多區域示例

為演示優先權,讓我們在 public 區域中將 http 替換成 ssh,並且為我們喜歡的 IP 地址,如 1.1.1.1,設置一個默認的 internal 區域。以下的命令完成這個任務:

# firewall-cmd --permanent --zone=public--remove-service=ssh # firewall-cmd --permanent --zone=public--add-service=http # firewall-cmd --permanent --zone=internal --add-source=1.1.1.1 # firewall-cmd --reload

 

這些命令的結果是生成如下的配置:

# firewall-cmd --zone=public--list-all public(default, active) interfaces: eno1 eno2 sources: services: dhcpv6-client http ports: masquerade:no forward-ports: icmp-blocks: rich rules: # firewall-cmd --permanent --zone=public--get-target default # firewall-cmd --zone=internal --list-all internal (active) interfaces: sources:1.1.1.1 services: dhcpv6-client mdns samba-client ssh ports: masquerade:no forward-ports: icmp-blocks: rich rules: # firewall-cmd --permanent --zone=internal --get-target default

 

 

在上面的配置中,如果有人嘗試從 1.1.1.1 去 ssh,這個請求將會成功,因為這個源區域(internal)被首先應用,並且它允許 ssh 訪問。

如果有人嘗試從其它的地址,如 2.2.2.2,去訪問 ssh,它不是這個源區域的,因為和這個源區域不匹配。因此,這個請求被直接轉到接口區域(public),它沒有顯式處理 ssh,因為,public 的目標是 default,這個請求被傳遞到默認動作,它將被拒絕。

如果 1.1.1.1 嘗試進行 http 訪問會怎樣?源區域(internal)不允許它,但是,目標是 default,因此,請求將傳遞到接口區域(public),它被允許訪問。

現在,讓我們假設有人從 3.3.3.3 拖你的網站。要限制從那個 IP 的訪問,簡單地增加它到預定義的 drop 區域,正如其名,它將丟棄所有的連接:

# firewall-cmd --permanent --zone=drop --add-source=3.3.3.3 # firewall-cmd --reload

 

 

下一次 3.3.3.3 嘗試去訪問你的網站,firewalld 將轉發請求到源區域(drop)。因為目標是 DROP,請求將被拒絕,並且它不會被轉發到接口區域(public)。

 

一個實用的多區域示例

假設你為你的組織的一台服務器配置防火牆。你希望允許全世界使用 http 和 https 的訪問,你的組織(1.1.0.0/16)和工作組(1.1.1.0/8)使用 ssh 訪問,並且你的工作組可以訪問 samba 服務。使用 firewalld 中的區域,你可以用一個很直觀的方式去實現這個配置。

public 這個命名,它的邏輯似乎是把全世界訪問指定為公共區域,而 internal 區域用於為本地使用。從在 public 區域內設置使用 http 和 https 替換 dhcpv6-client 和 ssh 服務來開始:

# firewall-cmd --permanent --zone=public--remove-service=dhcpv6-client # firewall-cmd --permanent --zone=public--remove-service=ssh # firewall-cmd --permanent --zone=public--add-service=http # firewall-cmd --permanent --zone=public--add-service=https

 

然后,取消 internal 區域的 mdnssamba-client 和 dhcpv6-client 服務(僅保留 ssh),並增加你的組織為源:

# firewall-cmd --permanent --zone=internal --remove-service=mdns # firewall-cmd --permanent --zone=internal --remove-service=samba-client # firewall-cmd --permanent --zone=internal --remove-service=dhcpv6-client # firewall-cmd --permanent --zone=internal --add-source=1.1.0.0/16

 

為容納你提升的 samba 的權限,增加一個富規則:

# firewall-cmd --permanent --zone=internal --add-rich-rule='rule family=ipv4 source address="1.1.1.0/8" service name="samba" accept'

 

最后,重新加載,把這些變化拉取到會話中:

# firewall-cmd --reload

 

 

僅剩下少數的細節了。從一個 internal 區域以外的 IP 去嘗試通過 ssh 到你的服務器,結果是回復一個拒絕的消息。它是 firewalld 默認的。更為安全的作法是去顯示不活躍的 IP 行為並丟棄該連接。改變 public 區域的目標為 DROP,而不是 default 來實現它:

# firewall-cmd --permanent --zone=public--set-target=DROP # firewall-cmd --reload

 

但是,等等,你不再可以 ping 了,甚至是從內部區域!並且 icmp (ping 使用的協議)並不在 firewalld 可以列入白名單的服務列表中。那是因為,icmp 是第 3 層的 IP 協議,它沒有端口的概念,不像那些捆綁了端口的服務。在設置公共區域為 DROP 之前,ping 能夠通過防火牆是因為你的 default 目標通過它到達防火牆的默認動作(default),即允許它通過。但現在它已經被刪除了。

為恢復內部網絡的 ping,使用一個富規則:

# firewall-cmd --permanent --zone=internal --add-rich-rule='rule protocol value="icmp" accept' # firewall-cmd --reload

 

結果如下,這里是兩個活動區域的配置:

# firewall-cmd --zone=public--list-all public(default, active) interfaces: eno1 eno2 sources: services: http https ports: masquerade:no forward-ports: icmp-blocks: rich rules: # firewall-cmd --permanent --zone=public--get-target DROP # firewall-cmd --zone=internal --list-all internal (active) interfaces: sources:1.1.0.0/16 services:ssh ports: masquerade:no forward-ports: icmp-blocks: rich rules: rule family=ipv4 source address="1.1.1.0/8" service name="samba" accept rule protocol value="icmp" accept # firewall-cmd --permanent --zone=internal --get-target default

 

這個設置演示了一個三層嵌套的防火牆。最外層,public,是一個接口區域,包含全世界的訪問。緊接着的一層,internal,是一個源區域,包含你的組織,它是 public 的一個子集。最后,一個富規則增加到最內層,包含了你的工作組,它是 internal 的一個子集。

這里的關鍵信息是,當在一個場景中可以突破到嵌套層,最外層將使用接口區域,接下來的將使用一個源區域,並且在源區域中額外使用富規則。

firewall常用的配置命令:

修改firewall防護等級 firewall-cmd --set-default-zone=block

查看當前zone的詳細規則
firewall-cmd --list-all

放開22tcp端口
firewall-cmd --zone=public --add-port=22/tcp --permanent 限制ip的同時限制端口

firewall-cmd --permanent --add-rich-rule="rule family="ipv4" source address="192.168.74.129" port protocol="tcp" port="28088" accept"
systemctl restart firewalld

 添加單個ip為信任 firewall-cmd --permanent --add-rich-rule="rule family='ipv4' source address='192.168.1.128' accept" 添加IP段為信任 firewall-cmd --permanent --add-rich-rule="rule family='ipv4' source address='192.168.1.0/24' accept" 刪除信任的ip段 firewall-cmd --permanent --remove-rich-rule="rule family='ipv4' source address='192.168.1.128' accept" 還有更多的富規則配置方法可以使用man firewalld.richlanguage來查看 在添加信任的時候,我們除了可以在當前的規則集中添加信任,還可以將需要信任的ip或ip段添加到更受信任的規則集中來實現 如:firewall-cmd --permanent --zone=trusted --add-source=192.168.74.1 效果與在當前zone中添加信任的效果是一樣的,不過,最好在當前zone中添加富規則,這樣的話,相對易管理

 這里僅列出幾個常用的,更多的寫法可以參考man,使用man firewalld.richlanguage來查看

在日常維護中,我們可能用的比較多的就是使用防火牆來對ip進行封禁等操作:

永久封禁單個ip的所有請求 firewall-cmd --permanent --add-rich-rule="rule family='ipv4' source address='222.222.222.222' reject" 當然,我們平時或許不需要這樣來做,因為這樣做的話,還需要重啟下firewall,firewall還提供timeout參數 即時生效,一定時間內對服務/ip等等的需求來進行開放或者封禁,比如我們可以寫個自動化腳本,當發現有異常的連接時就可以添加一條rule將其相應的地址drop掉 而且還可以使用--timeout給設置個時間段,過時之后自動刪除!所以--timeout和--permanent是不可以一起使用的。 如:firewall-cmd --add-service=ssh --timeout=10s

 

在實際的應用中發現:

1.安裝並運行docker的主機,在打開firewall服務后,創建新容器會報如下錯誤,且舊容器的服務無法訪問:

[root@localhost ~]# docker run -d -p 8080:80 --name="nginx-8080" docker.io/nginx
e0243020be093c04c3c6de16692839156655f489631077693f2cb3cdab7ebb4c
/usr/bin/docker-current: Error response from daemon: driver failed programming external connectivity on endpoint nginx-8080 (cebe58ea6558cf6a5eb2b39d7eae5520ef365538e1cc5f39f50ee83aacc8862b):  (iptables failed: iptables --wait -t nat -A DOCKER -p tcp -d 0/0 --dport 8080 -j DNAT --to-destination 172.17.0.3:80 ! -i docker0: iptables: No chain/target/match by that name.
 (exit status 1)).
[root@localhost ~]# 

解決辦法是重啟docker,重啟后問題不再出現,且之后對每次對firewall服務的操作都會影響docker提供的服務,所以每次修改firewall之后都要重啟docker

原因:

docker 使用iptables 來實現網絡隔離。docker 默認使用 bridge 網橋模式來實現容器的網絡。dockerd 會在 iptables 建立 docker 鏈來設置所有的規則。firewalld 啟動或重啟時,會將iptables的規則清空。導致docker啟動新容器出錯。舊容器服務無法訪問,這時就需要重啟docker。

2.測試發現,在限制192.168.74.129只能訪問28088端口的同時,docker啟動的其他端口的服務也可以被訪問。而系統本地的服務正常被限制。

原因: docker會將一些映射規則自動的加載到iptables的DOCKER chain中。docker配置后的轉發規則允許ip對這個docker下所有的服務端口進行訪問。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM