歡迎您光臨本站 註冊首頁

用IPIW實現BSD防火牆(上)

←手機掃碼閱讀     火星人 @ 2014-03-12 , reply:0
  FreeBSD操作系統本身帶有二種內置的IP信息包檢查機制:ipfw和ipfilter。在創建決定允許哪些信息包進入系統、哪些信息包會被拒之系統門外的規則集方面,二種機制各有自己獨特的語法。在這裡,我們將討論如何使用ipfw配置系統的防火牆。

在能夠使用ipfw防火牆機制之前,我們需要在FreeBSD的內核配置文件中添加一些選項,並重新編譯內核。如果不太清楚如何編譯FreeBSD的內核,請參閱相關的手冊。

可供ipfw使用的選項有好幾個,我們首先從討論LINT開始。在這裡,我通過使用「/」符號進行搜索,以便能夠快速地發現恰當的小節:

cd /usr/src/sys/i386/conf
more LINT
/IPFIREWALL
# IPFIREWALL和ipfw軟體,這二者就可以支持IP防火牆的構建。IPFIREWALL_VERBOSE向
# 系統的註冊程序發送註冊信息包,IPFIREWALL_VERBOSE_LIMIT限制一台機器註冊的次
# 數。注意:如果沒有在啟動時添加任何允許IP訪問的規則,IPFIREWALL的預設配置是
# 禁止任何IP數據包進出系統的,這時你甚至不能訪問網路中的其他機器。建議首次使
# 用這一功能時在/etc/rc.conf中設置firewall_type=open,然後在對內核進行測試后
# 再在/etc/rc.firewall仔細地調整防火牆的設置。IPFIREWALL_DEFAULT_TO_ACCEPT使
# 得預設的規則允許所有形式的訪問。在使用這一變數時應該非常小心,如果黑客能夠
# 突破防火牆,就能任意訪問你的系統。

要啟用ipfw,必須設置IPFIREWALL選項,它將通知操作系統的內核檢查每個IP數據包,將它們與規則集進行比較,通過添加IPFIREWALL_VERBOSE選項包括註冊支持是一個好主意,還應該通過添加IPFIREWALL_VERBOSE_LIMIT選項來限制內核註冊的數據包的數量。

除非在規則集中進行了特別的說明,預設情況下ipfw將阻塞所有的IP數據包。由於預設設置可以仔細地控制哪些數據包會被接受,因此我非常喜歡它。我不喜歡內核會接受自己都不清楚內容的數據包,如果需要的數據沒有被系統接受,會得到系統的提示,並修改規則集使系統可以接受它們。這時,如果有沒有預料到的數據包通過系統也不會知道。因此,我不會通過包括IPFIREWALL_DEFAULT_TO_ACCEPT選項來繞過預設的設置。

# IPDIVERT啟用由ipfw divert使用的轉向IP套接字。這一選項需要與natd聯合使用。由
# 於在本例中建立的防火牆僅用於保護一台機器,因此不需要這個選項。
# IPSTEALTH啟動支持秘密轉發的代碼,這一選項在使防火牆不被traceroute和類似工具發現時很有用。

這是一個非常有趣的選項,因此我將在防火牆中包含這一選項,並在對防火牆進行測試時看看它的工作原理。

# 接受過濾器中的靜態連接
# options ACCEPT_FILTER_DATA
# options ACCEPT_FILTER_HTTP

在這台計算機上運行的不是互聯網伺服器,因此無需在編譯時包括這二個選項。

# 下面的選項和系統級變數控制系統如何處理適當的TCP數據包。
#
# TCP_DROP_SYNFIN可以支持包含有SYN+FIN的TCP數據包,它使nmap不能識別TCP/IP棧,# 但可以破壞對RFC1644擴展的支持,建議不要在互聯網伺服器中使用。
#
# TCP_RESTRICT_RST支持阻止TCP RST棧的泄出,對於需要大量SYN的系統或者不希望被簡單地掃描到埠的系統非常有用。

我將在防火牆中包括這些選項,在測試防火牆時,仔細看看它們有什麼作用。

# ICMP_BANDLIM根據帶寬限制產生icmp錯誤。一般情況下我們需要這個選項,它有助於
# 你的系統免受D.O.S.攻擊。
#
options ICMP_BANDLIM

FreeBSD內核預設支持這一選項。

# DUMMYNET啟動「dummynet」帶寬限制軟體。還需要有IPFIREWALL選項的支持
# BRIDGE啟動乙太網卡之間的橋接功能

在本例中我不會選這二個選項,因為在獨立的計算機系統上無需對流量進行控制。

在重新編譯FreeBSD內核之前,我將在內核配置文件中添加下面的內容:

#以預設的、拒絕所有數據包方式啟動IPFW
options IPFIREWALL
options IPFIREWALL_VERBOSE
options IPFIREWALL_VERBOSE_LIMIT=10

#隱藏防火牆
options IPSTEALTH

#使不被nmap發現,如果是互聯網伺服器則去掉該選項。
options TCP_DROP_SYNFIN

#防止埠掃描
options TCP_RESTRICT_RST

在重新編譯內核時,我將再次仔細審查在/etc/rc.conf中添加的選項。下面是手冊中有關各個選項的說明:

man rc.conf
/firewall

firewall_enable
(布爾型)如果不想在系統啟動時載入防火牆規則集,將其值設置為NO;否則,將其設置為YES。如果它被設置為YES,而內核在編譯時沒有使用IPFIREWALL選項,ipfw內核模塊將自動被載入。
firewall_script
(字元串型)如果要運行一段防火牆腳本程序,而不是/etc/rc.firewall,將這一變數設置為腳本程序的路徑全名。
firewall_type
(字元串型)從/etc/rc.firewall或包含規則集的文件中的防火牆類型中指定防火牆類型。/etc/rc.firewall中可選的防火牆類型為:open-不限制IP訪問;closed-禁止除通過lo0進行的之外的所有IP服務;client-對工作站的基本保護;simple-對LAN的基本保護。如果給的是一個指定的文件名,則必須使用全路徑名。

由於我希望系統啟動時載入防火牆規則,因此將把firewall_enable變數的值設置為YES。由於要使用自己的規則集,需要指定使用firewall_type創建的文件的全路徑名。

firewall_quiet
(布爾型)如果設置為YES,則系統在啟動時,不會在控制台上顯示ipfw規則。

由於會顯示載入的各條規則,將這個變數設置為YES是一個好主意。如果相關規則中出現了錯誤,則在這個錯誤之後的所有規則都不會被載入。如果在啟動時看著屏幕,就會在成功載入的最後一條規則之後看到一個ipfw語法消息。這樣就可以在規則集中發現出現的錯誤,然後重新啟動機器,使所有的規則都能夠被成功地載入。

firewall_logging
(布爾型)設置為YES會啟動ipfw事件日誌功能,與IPFIREWALL_VERBOSE內核選項的功能相同。
tcp_extensions
(布爾型)預設狀態下被設置為NO。設置為YES可以啟動由RFC 1323定義的一些TCP選項。如果連接有隨機的問題出現,將其重新設置為NO,看是否能夠解決問題,因為一些軟、硬體問題都與這個選項有關。
log_in_vain
(布爾型)預設狀態下設置為NO。設置為YES將把對埠的連接嘗試記入日誌中。
tcp_keepalive
(布爾型)預設狀態下設置為YES。設置為NO會禁止對空閑的TCP連接的探查。
tcp_drop_synfin
(布爾型)預設狀態下設置為NO。設置為YES會使內核忽略有SYN和FIN標誌的TCP幀。 雖然這樣會提供操作系統的指紋,但會使一些正常的應用軟體出毛病。只有在編譯內核時使用了TCP_DROP_SYNFIN選項,該選項才有效。

由於在內核中添加了TCP_DROP_SYNFIN選項,我將這一變數的值設置為YES。如果在計算機上運行互聯網伺服器軟體,應該去掉這一選項。

tcp_restrict_rst
(布爾型)預設狀態下設置為NO。設置為YES將使內核在響應無效的TCP數據包時不能輸出TCP RST幀。只有在編譯內核時使用了TCP_RESTRICT_RST選項,這一選項才有效。
icmp_drop_redirect
(布爾型)預設狀態下設置為NO。設置為YES將使內核忽略ICMP REDIRECT信息包。
icmp_log_redirect
(布爾型)預設狀態下設置為NO。設置為YES將使內核在日誌中記錄ICMP REDIRECT信息包。由於日誌是沒有什麼限制的,因此只有在對網路維護時才會使用這一選項。

最終,我在系統中的/etc/rc.conf文件中加入了下面的內容:

#用於支持ipfw的選項
firewall_enable="YES"
firewall_script="/etc/rc.firewall"
firewall_type="/etc/ipfw.rules"
firewall_quiet="NO" #對現有的規則滿意后將其值改為YES
firewall_logging_enable="YES"
#附加的防火牆選項
log_in_vain="YES"
tcp_drop_synfin="YES" #如果要創建互聯網伺服器,將其值改為NO。
tcp_restrict_rst="YES"
icmp_drop_redirect="YES"

在重新啟動機器運行新的內核之前,有一點需要注意。如果LINT文件顯示出「YOU WILL LOCK YOURSELF OUT」(你將封鎖自己),說明新的規則已經起作用了。在重新創建允許所需的IP數據包進入系統之前,所有的IP數據包都不能進入或傳出計算機。如果想從互聯網上收發電子郵件和下載資料,就需要在重新啟動系統之前完成這些工作。

創建一個好的規則集是一件技術性很強固的工作。如果是第一次創建防火牆,需要有大量的時間進行練習,就會發現ipfw所使用的邏輯與你認為的邏輯不完全相同。

此外,防火牆並非是安裝后就一勞永逸了,需要花些時間對它進行優化,在它不能完成你預期的任務時多想想這是為什麼。一旦用有防火牆的新內核啟動機器后,你可能希望完成下面的三項工作。

▲系統地在規則集中添加新的規則,測試每條規則的作用,確保只有你需要的數據包才能夠出入你的系統。

▲決定你要將哪些IP數據包記入日誌並查看日誌文件,隨著不斷發現你禁止或允許的一些數據包出入系統,會不斷地修改規則。

▲一旦對防火牆允許或不允許通過哪些數據包滿意了,就需要測試防火牆的性能是否能夠令人滿意。

好了,下面我要重新啟動機器載入新的內核。在啟動時盯著屏幕,在NIC載入後會看到下面的信息:

Flushed all rules.
00100 allow ip from any to any via lo0
00200 deny ip from any to any to 127.0.0.0/8
Firewall rules loaded, starting divert daemons:.
Additional routing options: tcp extensions=NO ignore ICMP redirect=YES TCP keepalive=YES restrict TCP reset=YES drop SYN+FIN packets=YES.

Additional TCP options: log_in_vain=YES.

你可能會有疑惑,沒有創建包含規則集的文件,怎麼會顯示頭三行信息呢?在編輯/etc/rc.conf時,我在其中添加了下面一行的內容:

firewall_script="/etc/rc.firewall"

在啟動時系統會讀取/etc/rc.firewall文件,該文件包含下面的內容:

############
# Flush out the list before we begin.
#
${fwcmd} -f flush

############
# 只有在極少數的情況下才需要改變這些規則
#
${fwcmd} add 100 pass all from any to any via lo0
${fwcmd} add 200 deny all from any to 127.0.0.0/8

由於規則100和規則200在啟動時會用到,因此在創建規則時應該從規則300開始。在創建規則之前,我會用下面的方法分二次檢查ipfw是否預設地禁止所有的信息包出入我的計算機系統。可以通過運行ipfw show命令來進行檢查:

ipfw show
ipfw: socket: Operation not permitted

似乎只有超級用戶才有查看防火牆規則的許可權,因此我將再次以超級用戶再身份次進行檢查:

su
Password:
ipfw show
00100 0 0 allow ip from any to any via lo0
00200 0 0 deny ip from any to 127.0.0.0/8
65535 115 14092 deny ip from any to any

確實已經禁止所有的信息包出入計算機系統,我再來試著使用一下網路連接。

ping www.freebsd.org
ping: cannot resolve www.freebsd.org: Host name lookup failure

traceroute www.freebsd.org
traceroute: unknown host www.freebsd.org

lynx www.freebsd.org
Alert!: Unable to access document.

好了,名字解析也無效,我們再試試ping吧:

ping 24.141.116.1
PING 24.141.116.1 (24.141.116.1): 56 data bytes
ping: sendto: Permission denied
ping: sendto: Permission denied
^C
--- 24.141.116.1 ping statistics ---
2 packets transmitted, 0 packets received, 100% packet loss

由於我是以超級用戶的身份運行最後一個ping的,因此ipfw確實已經禁止所有信息包的出入,我已經完全不能使用網路連接了。現在我們來創建一個允許收發我需要的IP信息包的規則集。

有二種方式可以創建被ipfw讀取的規則:

如果已經在使用ipfw,不用重啟動機器就能使規則生效。但是,如果重新啟動機器后,添加的規則就會丟了。

你還可以在讓ipfw讀取的文件中添加一條規則,這樣只有機器重新啟動后,新添加的規則才能生效。

由於這台機器只有我一個人使用,因此,我將把規則直接加進文件中並重啟機器。我已經在/etc/rc.conf中添加了下面的一行內容:

firewall_type="/etc/ipfw.rules"

因此,我將創建一個名字為/etc/ipfw.rules的文件。


[火星人 ] 用IPIW實現BSD防火牆(上)已經有615次圍觀

http://coctec.com/docs/security/show-post-72815.html