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的管理工具,並且
-
drop(丟棄),任何接受的網絡數據包都被丟棄,沒有任何回復。僅能有發送出去的網路連接。
-
block(限制),任何接收的網絡連接都被IPv4的icmp-host-prohibited信息和IPv6的icmp6-adm-prohibited信息所拒絕。
-
public(公共),在公共區域內使用,不能相信網絡內的其他計算機不會對你的計算機造成危害,只能接收經過選取的連接。
-
external(外部),特別是為路由器啟動了偽裝功能的外部網。你不能相信來自網絡的其他計算機,不能相信他們不會對你的計算機造成危害,只能接收經過選擇的連接。
-
dmz(非軍事區),用於你的非軍事區內的電腦,此區域內可公開訪問,可以有限的進入你的內部網絡,僅僅接收經過選擇的連接。
-
work(工作),用於工作區。你可以基本相信網絡內的其他計算機不會危害到你。僅僅接收經過選擇的連接。
-
home(家庭),用於家庭網絡。你可以基本相信網絡內的其他計算機不會危害到你。僅僅接收經過選擇的連接。
-
internal(內部),用於內部網絡。你可以基本相信網絡內的其他計算機不會危害到你。僅僅接收經過選擇的連接。
-
首先,我們來看看一個規則集中都包含了什么:
[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 按下列順序處理一個包:
- 相應的源區域。可以存在零個或一個這樣的區域。如果這個包滿足一個富規則rich rule、服務是白名單中的、或者目標沒有定義,那么源區域處理這個包,並且在這里結束。否則,向上傳遞這個包。
- 相應的接口區域。肯定有一個這樣的區域。如果接口處理這個包,那么到這里結束。否則,向上傳遞這個包。
- 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
區域的 mdns
、samba-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 ~]#
原因:
原因: