新聞中心
現(xiàn)在的新聞里充斥著服務(wù)器被攻擊和數(shù)據(jù)失竊事件。對(duì)于一個(gè)閱讀過(guò)安全公告博客的人來(lái)說(shuō),通過(guò)訪問(wèn)錯(cuò)誤配置的服務(wù)器,利用最新暴露的安全漏洞或通過(guò)竊取的密碼來(lái)獲得系統(tǒng)控制權(quán),并不是件多困難的事情。在一個(gè)典型的 linux 服務(wù)器上的任何互聯(lián)網(wǎng)服務(wù)都可能存在漏洞,允許未經(jīng)授權(quán)的系統(tǒng)訪問(wèn)。

專注于為中小企業(yè)提供成都網(wǎng)站建設(shè)、成都網(wǎng)站制作服務(wù),電腦端+手機(jī)端+微信端的三站合一,更高效的管理,為中小企業(yè)龍安免費(fèi)做網(wǎng)站提供優(yōu)質(zhì)的服務(wù)。我們立足成都,凝聚了一批互聯(lián)網(wǎng)行業(yè)人才,有力地推動(dòng)了上1000+企業(yè)的穩(wěn)健成長(zhǎng),幫助中小企業(yè)通過(guò)網(wǎng)站建設(shè)實(shí)現(xiàn)規(guī)模擴(kuò)充和轉(zhuǎn)變。
因?yàn)樵趹?yīng)用程序?qū)用嫔蠌?qiáng)化系統(tǒng)以防范任何可能的威脅是不可能做到的事情,而防火墻可以通過(guò)限制對(duì)系統(tǒng)的訪問(wèn)提供了安全保證。防火墻基于源 IP、目標(biāo)端口和協(xié)議來(lái)過(guò)濾入站包。因?yàn)檫@種方式中,僅有幾個(gè) IP/端口/協(xié)議的組合與系統(tǒng)交互,而其它的方式做不到過(guò)濾。
Linux 防火墻是通過(guò) netfilter 來(lái)處理的,它是內(nèi)核級(jí)別的框架。這十幾年來(lái),iptables 被作為 netfilter 的用戶態(tài)抽象層(LCTT 譯注: userland,一個(gè)基本的 UNIX 系統(tǒng)是由 kernel 和 userland 兩部分構(gòu)成,除 kernel 以外的稱為 userland)。iptables 將包通過(guò)一系列的規(guī)則進(jìn)行檢查,如果包與特定的 IP/端口/協(xié)議的組合匹配,規(guī)則就會(huì)被應(yīng)用到這個(gè)包上,以決定包是被通過(guò)、拒絕或丟棄。
Firewalld 是最新的 netfilter 用戶態(tài)抽象層。遺憾的是,由于缺乏描述多區(qū)域配置的文檔,它強(qiáng)大而靈活的功能被低估了。這篇文章提供了一個(gè)示例去改變這種情況。
Firewalld 的設(shè)計(jì)目標(biāo)
firewalld 的設(shè)計(jì)者認(rèn)識(shí)到大多數(shù)的 iptables 使用案例僅涉及到幾個(gè)單播源 IP,僅讓每個(gè)符合白名單的服務(wù)通過(guò),而其它的會(huì)被拒絕。這種模式的好處是,firewalld 可以通過(guò)定義的源 IP 和/或網(wǎng)絡(luò)接口將入站流量分類到不同區(qū)域zone。每個(gè)區(qū)域基于指定的準(zhǔn)則按自己配置去通過(guò)或拒絕包。
另外的改進(jìn)是基于 iptables 進(jìn)行語(yǔ)法簡(jiǎn)化。firewalld 通過(guò)使用服務(wù)名而不是它的端口和協(xié)議去指定服務(wù),使它更易于使用,例如,是使用 samba 而不是使用 UDP 端口 137 和 138 和 TCP 端口 139 和 445。它進(jìn)一步簡(jiǎn)化語(yǔ)法,消除了 iptables 中對(duì)語(yǔ)句順序的依賴。
最后,firewalld 允許交互式修改 netfilter,允許防火墻獨(dú)立于存儲(chǔ)在 XML 中的永久配置而進(jìn)行改變。因此,下面的的臨時(shí)修改將在下次重新加載時(shí)被覆蓋:
# firewall-cmd
而,以下的改變?cè)谥丶虞d后會(huì)永久保存:
# firewall-cmd --permanent
# firewall-cmd --reload
區(qū)域
在 firewalld 中最上層的組織是區(qū)域。如果一個(gè)包匹配區(qū)域相關(guān)聯(lián)的網(wǎng)絡(luò)接口或源 IP/掩碼 ,它就是區(qū)域的一部分??捎玫膸讉€(gè)預(yù)定義區(qū)域:
# firewall-cmd --get-zones
block dmz drop external home internal public trusted work
任何配置了一個(gè)網(wǎng)絡(luò)接口和/或一個(gè)源的區(qū)域就是一個(gè)活動(dòng)區(qū)域active zone。列出活動(dòng)的區(qū)域:
# firewall-cmd --get-active-zones
public
interfaces: eno1 eno2
Interfaces (接口)是系統(tǒng)中的硬件和虛擬的網(wǎng)絡(luò)適配器的名字,正如你在上面的示例中所看到的那樣。所有的活動(dòng)的接口都將被分配到區(qū)域,要么是默認(rèn)的區(qū)域,要么是用戶指定的一個(gè)區(qū)域。但是,一個(gè)接口不能被分配給多于一個(gè)的區(qū)域。
在缺省配置中,firewalld 設(shè)置所有接口為 public 區(qū)域,并且不對(duì)任何區(qū)域設(shè)置源。其結(jié)果是,public 區(qū)域是唯一的活動(dòng)區(qū)域。
Sources (源)是入站 IP 地址的范圍,它也可以被分配到區(qū)域。一個(gè)源(或重疊的源)不能被分配到多個(gè)區(qū)域。這樣做的結(jié)果是產(chǎn)生一個(gè)未定義的行為,因?yàn)椴磺宄?yīng)該將哪些規(guī)則應(yīng)用于該源。
因?yàn)橹付ㄒ粋€(gè)源不是必需的,任何包都可以通過(guò)接口匹配而歸屬于一個(gè)區(qū)域,而不需要通過(guò)源匹配來(lái)歸屬一個(gè)區(qū)域。這表示通過(guò)使用優(yōu)先級(jí)方式,優(yōu)先到達(dá)多個(gè)指定的源區(qū)域,稍后將詳細(xì)說(shuō)明這種情況。首先,我們來(lái)檢查 public 區(qū)域的配置:
# firewall-cmd --zone=public --list-all
public (default, active)
interfaces: eno1 eno2
sources:
services: dhcpv6-client ssh
ports:
masquerade: no
forward-ports:
icmp-blocks:
rich rules:
# firewall-cmd --permanent --zone=public --get-target
default
逐行說(shuō)明如下:
public (default, active)表示public區(qū)域是默認(rèn)區(qū)域(當(dāng)接口啟動(dòng)時(shí)會(huì)自動(dòng)默認(rèn)),并且它是活動(dòng)的,因?yàn)?,它至少有一個(gè)接口或源分配給它。interfaces: eno1 eno2列出了這個(gè)區(qū)域上關(guān)聯(lián)的接口。sources:列出了這個(gè)區(qū)域的源?,F(xiàn)在這里什么都沒(méi)有,但是,如果這里有內(nèi)容,它們應(yīng)該是這樣的格式 xxx.xxx.xxx.xxx/xx。services: dhcpv6-client ssh列出了允許通過(guò)這個(gè)防火墻的服務(wù)。你可以通過(guò)運(yùn)行firewall-cmd --get-services得到一個(gè)防火墻預(yù)定義服務(wù)的詳細(xì)列表。ports:列出了一個(gè)允許通過(guò)這個(gè)防火墻的目標(biāo)端口。它是用于你需要去允許一個(gè)沒(méi)有在 firewalld 中定義的服務(wù)的情況下。masquerade: no表示這個(gè)區(qū)域是否允許 IP 偽裝。如果允許,它將允許 IP 轉(zhuǎn)發(fā),它可以讓你的計(jì)算機(jī)作為一個(gè)路由器。forward-ports:列出轉(zhuǎn)發(fā)的端口。icmp-blocks:阻塞的 icmp 流量的黑名單。rich rules:在一個(gè)區(qū)域中優(yōu)先處理的高級(jí)配置。default是目標(biāo)區(qū)域,它決定了與該區(qū)域匹配而沒(méi)有由上面設(shè)置中顯式處理的包的動(dòng)作。
一個(gè)簡(jiǎn)單的單區(qū)域配置示例
如果只是簡(jiǎn)單地鎖定你的防火墻。簡(jiǎn)單地在刪除公共區(qū)域上當(dāng)前允許的服務(wù),并重新加載:
# firewall-cmd --permanent --zone=public --remove-service=dhcpv6-client
# firewall-cmd --permanent --zone=public --remove-service=ssh
# firewall-cmd --reload
在下面的防火墻上這些命令的結(jié)果是:
# firewall-cmd --zone=public --list-all
public (default, active)
interfaces: eno1 eno2
sources:
services:
ports:
masquerade: no
forward-ports:
icmp-blocks:
rich rules:
# firewall-cmd --permanent --zone=public --get-target
default
本著盡可能嚴(yán)格地保證安全的精神,如果發(fā)生需要在你的防火墻上臨時(shí)開放一個(gè)服務(wù)的情況(假設(shè)是 ssh),你可以增加這個(gè)服務(wù)到當(dāng)前會(huì)話中(省略 --permanent),并且指示防火墻在一個(gè)指定的時(shí)間之后恢復(fù)修改:
# firewall-cmd --zone=public --add-service=ssh --timeout=5m
這個(gè) timeout 選項(xiàng)是一個(gè)以秒(s)、分(m)或小時(shí)(h)為單位的時(shí)間值。
目標(biāo)
當(dāng)一個(gè)區(qū)域處理它的源或接口上的一個(gè)包時(shí),但是,沒(méi)有處理該包的顯式規(guī)則時(shí),這時(shí)區(qū)域的目標(biāo)target決定了該行為:
ACCEPT:通過(guò)這個(gè)包。%%REJECT%%:拒絕這個(gè)包,并返回一個(gè)拒絕的回復(fù)。DROP:丟棄這個(gè)包,不回復(fù)任何信息。default:不做任何事情。該區(qū)域不再管它,把它踢到“樓上”。
在 firewalld 0.3.9 中有一個(gè) bug (已經(jīng)在 0.3.10 中修復(fù)),對(duì)于一個(gè)目標(biāo)是除了“default”以外的源區(qū)域,不管允許的服務(wù)是什么,這的目標(biāo)都會(huì)被應(yīng)用。例如,一個(gè)使用目標(biāo) DROP 的源區(qū)域,將丟棄所有的包,甚至是白名單中的包。遺憾的是,這個(gè)版本的 firewalld 被打包到 RHEL7 和它的衍生版中,使它成為一個(gè)相當(dāng)常見的 bug。本文中的示例避免了可能出現(xiàn)這種行為的情況。
優(yōu)先權(quán)
活動(dòng)區(qū)域中扮演兩個(gè)不同的角色。關(guān)聯(lián)接口行為的區(qū)域作為接口區(qū)域,并且,關(guān)聯(lián)源行為的區(qū)域作為源區(qū)域(一個(gè)區(qū)域能夠扮演兩個(gè)角色)。firewalld 按下列順序處理一個(gè)包:
- 相應(yīng)的源區(qū)域??梢源嬖诹銈€(gè)或一個(gè)這樣的區(qū)域。如果這個(gè)包滿足一個(gè)富規(guī)則rich rule、服務(wù)是白名單中的、或者目標(biāo)沒(méi)有定義,那么源區(qū)域處理這個(gè)包,并且在這里結(jié)束。否則,向上傳遞這個(gè)包。
- 相應(yīng)的接口區(qū)域??隙ㄓ幸粋€(gè)這樣的區(qū)域。如果接口處理這個(gè)包,那么到這里結(jié)束。否則,向上傳遞這個(gè)包。
- firewalld 默認(rèn)動(dòng)作。接受 icmp 包并拒絕其它的一切。
這里的關(guān)鍵信息是,源區(qū)域優(yōu)先于接口區(qū)域。因此,對(duì)于多區(qū)域的 firewalld 配置的一般設(shè)計(jì)模式是,創(chuàng)建一個(gè)優(yōu)先源區(qū)域來(lái)允許指定的 IP 對(duì)系統(tǒng)服務(wù)的提升訪問(wèn),并在一個(gè)限制性接口區(qū)域限制其它訪問(wèn)。
一個(gè)簡(jiǎn)單的多區(qū)域示例
為演示優(yōu)先權(quán),讓我們?cè)?public 區(qū)域中將 http 替換成 ssh,并且為我們喜歡的 IP 地址,如 1.1.1.1,設(shè)置一個(gè)默認(rèn)的 internal 區(qū)域。以下的命令完成這個(gè)任務(wù):
# 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
這些命令的結(jié)果是生成如下的配置:
# 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,這個(gè)請(qǐng)求將會(huì)成功,因?yàn)檫@個(gè)源區(qū)域(internal)被首先應(yīng)用,并且它允許 ssh 訪問(wèn)。
如果有人嘗試從其它的地址,如 2.2.2.2,去訪問(wèn) ssh,它不是這個(gè)源區(qū)域的,因?yàn)楹瓦@個(gè)源區(qū)域不匹配。因此,這個(gè)請(qǐng)求被直接轉(zhuǎn)到接口區(qū)域(public),它沒(méi)有顯式處理 ssh,因?yàn)?,public 的目標(biāo)是 default,這個(gè)請(qǐng)求被傳遞到默認(rèn)動(dòng)作,它將被拒絕。
如果 1.1.1.1 嘗試進(jìn)行 http 訪問(wèn)會(huì)怎樣?源區(qū)域(internal)不允許它,但是,目標(biāo)是 default,因此,請(qǐng)求將傳遞到接口區(qū)域(public),它被允許訪問(wèn)。
現(xiàn)在,讓我們假設(shè)有人從 3.3.3.3 拖你的網(wǎng)站。要限制從那個(gè) IP 的訪問(wèn),簡(jiǎn)單地增加它到預(yù)定義的 drop 區(qū)域,正如其名,它將丟棄所有的連接:
# firewall-cmd --permanent --zone=drop --add-source=3.3.3.3
# firewall-cmd --reload
下一次 3.3.3.3 嘗試去訪問(wèn)你的網(wǎng)站,firewalld 將轉(zhuǎn)發(fā)請(qǐng)求到源區(qū)域(drop)。因?yàn)槟繕?biāo)是 DROP,請(qǐng)求將被拒絕,并且它不會(huì)被轉(zhuǎn)發(fā)到接口區(qū)域(public)。
一個(gè)實(shí)用的多區(qū)域示例
假設(shè)你為你的組織的一臺(tái)服務(wù)器配置防火墻。你希望允許全世界使用 http 和 https 的訪問(wèn),你的組織(1.1.0.0/16)和工作組(1.1.1.0/8)使用 ssh 訪問(wèn),并且你的工作組可以訪問(wèn) samba 服務(wù)。使用 firewalld 中的區(qū)域,你可以用一個(gè)很直觀的方式去實(shí)現(xiàn)這個(gè)配置。
public 這個(gè)命名,它的邏輯似乎是把全世界訪問(wèn)指定為公共區(qū)域,而 internal 區(qū)域用于為本地使用。從在 public 區(qū)域內(nèi)設(shè)置使用 http 和 https 替換 dhcpv6-client 和 ssh 服務(wù)來(lái)開始:
# 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 區(qū)域的 mdns、samba-client 和 dhcpv6-client 服務(wù)(僅保留 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 的權(quán)限,增加一個(gè)富規(guī)則:
# firewall-cmd --permanent --zone=internal --add-rich-rule='rule family=ipv4 source address="1.1.1.0/8" service name="samba" accept'
最后,重新加載,把這些變化拉取到會(huì)話中:
# firewall-cmd --reload
僅剩下少數(shù)的細(xì)節(jié)了。從一個(gè) internal 區(qū)域以外的 IP 去嘗試通過(guò) ssh 到你的服務(wù)器,結(jié)果是回復(fù)一個(gè)拒絕的消息。它是 firewalld 默認(rèn)的。更為安全的作法是去顯示不活躍的 IP 行為并丟棄該連接。改變 public 區(qū)域的目標(biāo)為 DROP,而不是 default 來(lái)實(shí)現(xiàn)它:
# firewall-cmd --permanent --zone=public --set-target=DROP
# firewall-cmd --reload
但是,等等,你不再可以 ping 了,甚至是從內(nèi)部區(qū)域!并且 icmp (ping 使用的協(xié)議)并不在 firewalld 可以列入白名單的服務(wù)列表中。那是因?yàn)?,icmp 是第 3 層的 IP 協(xié)議,它沒(méi)有端口的概念,不像那些捆綁了端口的服務(wù)。在設(shè)置公共區(qū)域?yàn)?nbsp;DROP 之前,ping 能夠通過(guò)防火墻是因?yàn)槟愕?nbsp;default 目標(biāo)通過(guò)它到達(dá)防火墻的默認(rèn)動(dòng)作(default),即允許它通過(guò)。但現(xiàn)在它已經(jīng)被刪除了。
為恢復(fù)內(nèi)部網(wǎng)絡(luò)的 ping,使用一個(gè)富規(guī)則:
# firewall-cmd --permanent --zone=internal --add-rich-rule='rule protocol value="icmp" accept'
# firewall-cmd --reload
結(jié)果如下,這里是兩個(gè)活動(dòng)區(qū)域的配置:
# 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
這個(gè)設(shè)置演示了一個(gè)三層嵌套的防火墻。最外層,public,是一個(gè)接口區(qū)域,包含全世界的訪問(wèn)。緊接著的一層,internal,是一個(gè)源區(qū)域,包含你的組織,它是 public 的一個(gè)子集。最后,一個(gè)富規(guī)則增加到最內(nèi)層,包含了你的工作組,它是 internal 的一個(gè)子集。
這里的關(guān)鍵信息是,當(dāng)在一個(gè)場(chǎng)景中可以突破到嵌套層,最外層將使用接口區(qū)域,接下來(lái)的將使用一個(gè)源區(qū)域,并且在源區(qū)域中額外使用富規(guī)則。
調(diào)試
firewalld 采用直觀范式來(lái)設(shè)計(jì)防火墻,但比它的前任 iptables 更容易產(chǎn)生歧義。如果產(chǎn)生無(wú)法預(yù)料的行為,或者為了更好地理解 firewalld 是怎么工作的,則可以使用 iptables 描述 netfilter 是如何配置操作的。前一個(gè)示例的輸出如下,為了簡(jiǎn)單起見,將輸出和日志進(jìn)行了修剪:
# iptables -S
-P INPUT ACCEPT
... (forward and output lines) ...
-N INPUT_ZONES
-N INPUT_ZONES_SOURCE
-N INPUT_direct
-N IN_internal
-N IN_internal_allow
-N IN_internal_deny
-N IN_public
-N IN_public_allow
-N IN_public_deny
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -j INPUT_ZONES_SOURCE
-A INPUT -j INPUT_ZONES
-A INPUT -p icmp -j ACCEPT
-A INPUT -m conntrack --ctstate INVALID -j DROP
-A INPUT -j REJECT --reject-with icmp-host-prohibited
... (forward and output lines) ...
-A INPUT_ZONES -i eno1 -j IN_public
-A INPUT_ZONES -i eno2 -j IN_public
-A INPUT_ZONES -j IN_public
-A INPUT_ZONES_SOURCE -s 1.1.0.0/16 -g IN_internal
-A IN_internal -j IN_internal_deny
-A IN_internal -j IN_internal_allow
-A IN_internal_allow -p tcp -m tcp --dport 22 -m conntrack --ctstate NEW -j ACCEPT
-A IN_internal_allow -s 1.1.1.0/8 -p udp -m udp --dport 137 -m conntrack --ctstate NEW -j ACCEPT
-A IN_internal_allow -s 1.1.1.0/8 -p udp -m udp --dport 138 -m conntrack --ctstate NEW -j ACCEPT
-A IN_internal_allow -s 1.1.1.0/8 -p tcp -m tcp --dport 139 -m conntrack --ctstate NEW -j ACCEPT
-A IN_internal_allow -s 1.1.1.0/8 -p tcp -m tcp --dport 445 -m conntrack --ctstate NEW -j ACCEPT
-A IN_internal_allow -p icmp -m conntrack --ctstate NEW -j ACCEPT
-A IN_public -j IN_public_deny
-A IN_public -j IN_public_allow
-A IN_public -j DROP
-A IN_public_allow -p tcp -m tcp --dport 80 -m conntrack --ctstate NEW -j ACCEPT
-A IN_public_allow -p tcp -m tcp --dport 443 -m conntrack --ctstate NEW -j ACCEPT
在上面的 iptables 輸出中,新的鏈(以 -N 開始的行)是被首先聲明的。剩下的規(guī)則是附加到(以 -A 開始的行) iptables 中的。已建立的連接和本地流量是允許通過(guò)的,并且入站包被轉(zhuǎn)到 INPUT_ZONES_SOURCE 鏈,在那里如果存在相應(yīng)的區(qū)域,IP 將被發(fā)送到那個(gè)區(qū)域。從那之后,流量被轉(zhuǎn)到 INPUT_ZONES 鏈,從那里它被路由到一個(gè)接口區(qū)域。如果在那里它沒(méi)有被處理,icmp 是允許通過(guò)的,無(wú)效的被丟棄,并且其余的都被拒絕。
結(jié)論
firewalld 是一個(gè)文檔不足的防火墻配置工具,它的功能遠(yuǎn)比大多數(shù)人認(rèn)識(shí)到的更為強(qiáng)大。以創(chuàng)新的區(qū)域范式,firewalld 允許系統(tǒng)管理員去分解流量到每個(gè)唯一處理它的分類中,簡(jiǎn)化了配置過(guò)程。因?yàn)樗庇^的設(shè)計(jì)和語(yǔ)法,它在實(shí)踐中不但被用于簡(jiǎn)單的單一區(qū)域中也被用于復(fù)雜的多區(qū)域配置中。
本文標(biāo)題:理解多區(qū)域配置中的firewalld
文章網(wǎng)址:http://www.5511xx.com/article/djdosci.html


咨詢
建站咨詢
