歡迎您光臨本站 註冊首頁

Linux 2.4有狀態防火牆設計(三)

←手機掃碼閱讀     火星人 @ 2014-03-12 , reply:0
  第五章 有狀態改進

明確關閉 ECN


我以前提到過應當關閉 ECN(明確擁塞通知),以便網際網路通信可以正確工作。雖然您可能會按我的建議禁用了 ECN,但在將來您也許會忘了這樣做。或者,您可能將防火牆腳本傳送給某個人,而那個人啟用了 ECN。由於這些原因,最好使用 /proc 介面來明確禁用 ECN,如下所示:


if [ -e /proc/sys/net/ipv4/tcp_ecn ]
then
echo 0 > /proc/sys/net/ipv4/tcp_ecn
fi


轉發

如果使用 Linux 機器作為路由器,那麼應該啟用 IP 轉發,它給予內核許可權,以允許包在 eth0 和 eth1 之間傳遞,反之亦然。在我們的配置示例中,eth0 連接到 LAN,eth1 連接到網際網路,在允許 LAN 經由 Linux 機器連接網際網路時,啟用 IP 轉發是必要步驟。要啟用 IP 轉發,請使用以下這行命令:


echo 1 > /proc/sys/net/ipv4/ip_forward


處理拒絕,第 1 部分


目前,我們已經刪除了所有來自網際網路的未經請求的通信流。雖然這是一種阻止討厭的網路活動的有效方法,但是它有一些缺點。這種方法最大的問題是闖入者很容易就可以檢測到我們正在使用防火牆,因為我們的機器沒有應答標準 TCP 複位和 ICMP 埠不可到達響應 -- 一般機器發送會的響應,用於表示對不存在服務的連接失敗。


處理拒絕,第 2 部分


與其讓潛在的闖入者知道我們在運行防火牆(對於在提示他們,我們正在運行一些他們不能得到的有價值服務),還不如假裝我們根本沒有運行服務。通過將以下兩個規則添加到 INPUT 鏈的末端,可以成功地完成此項任務:


iptables -A INPUT -p tcp -i eth1 -j REJECT --reject-with tcp-reset
iptables -A INPUT -p udp -i eth1 -j REJECT --reject-with icmp-port-unreachable

第一個規則負責正確傳遞 TCP 連接,而第二個規則處理 UDP。只要這兩個規則就位,闖入者就很難檢測到我們運行了防火牆;但願,這會使闖入者離開我們的機器,轉而搜索其它更潛在的目標以供他濫用。


處理拒絕,第 3 部分


除了使防火牆變得更「隱蔽」,這些規則還消除了由於連接到某些 ftp 和 irc 伺服器帶來的延遲。這個延遲是由於伺服器對您的機器執行身份查找(連接到埠 113)而引起的,並最終(大約 15 秒之後)導致超時。現在,防火牆將返回 TCP 複位,身份查找將立即失敗,而不是重試 15 秒(而您正在耐心地等待伺服器的響應)。


防止欺騙


在許多發行版中,當建成網路介面時,還會將舊的 ipchains 規則添加到系統。這些特殊規則是由發行版的創建程序添加的,用於處理電子欺騙問題,即包的源地址已經過調整,這樣它們就包含了無效值(某些腳本騙子做的事)。雖然我們可以創建類似的 iptables 規則來阻攔受到欺騙的包,但還有一種更簡單的方法。目前,內核的內置功能可以刪除受到欺騙的包;我們要做的只是通過簡單的 /proc 介面來啟用它。方法如下。

for x in lo eth0 eth1
do
echo 1 > /proc/sys/net/ipv4/conf/${x}/rp_filter
done

此 shell 腳本將告訴內核刪除介面 lo、eth0 和 eth1 上所有受到欺騙的包。可以將這些行添加到防火牆腳本中,也可以將它們添加到創建 lo、eth0 和 eth1 介面的腳本中。


偽裝


NAT(網路地址轉換)和 IP 偽裝雖然與防火牆沒有直接關係,但通常與防火牆一起使用。我們將討論您可能需要使用的兩種常用 NAT/偽裝配置。第一個規則負責處理那種用撥號鏈接到使用動態 IP 的網際網路 (ppp0) 的情況:


iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE

如果您屬於這種情況,那麼還應該轉換防火牆腳本,將對 "eth1"(我們的示例 DSL 路由器)更改成 "ppp0"。如果 ppp0 還不存在,最好添加引用 "ppp0" 的防火牆規則。只要創建了 ppp0,一切立即就會正常工作。請確保還啟用了 IP 轉發。


SNAT


如果使用 DSL 來連接網際網路,那麼您或許有兩種可能配置中的一種。一種可能性是 DSL 路由器或數據機有其自己的 IP 號碼,並為您執行網路地址轉換。如果是這種情況,那麼就不需要 Linux 來執行 NAT,因為 DSL 路由器已經這樣處理了。

但是,如果想要更多地控制 NAT 功能,也許應該與 ISP 討論關於 DSL 連接的配置,以便使您的 DSL 連接處於「橋接方式」。在橋接方式中,防火牆將成為 ISP 的網路中的正式部分,DSL 路由器將會在 ISP 和您的 Linux 機器之間透明的來迴轉發 IP 通信流,而不會讓任何人知道它的存在。它不再擁有 IP 號碼;事實上,eth1(在我們的示例中)隱藏了 IP。如果有人從網際網路上 ping 您的 IP,他們將從您的 Linux 機器上得到應答,而不是路由器。


使用了這種設置,就應該使用 NAT(源 NAT),而不是偽裝。以下就是您應該添加到防火牆的一行代碼:


iptables -t nat -A POSTROUTING -o eth1 -j SNAT --to 1.2.3.4

在這個示例中,應該將 eth1 更改成直接連接到 DSL 路由器的乙太網介面,1.2.3.4 應該更改成靜態 IP(乙太網介面的 IP)。再次聲明,請記住要啟用 IP 轉發。


NAT 問題


幸好,NAT 和偽裝與防火牆能夠和睦相處。在編寫防火牆過濾規則時,應忽略正在使用 NAT 的事實。您的規則應該根據包的「真正」源地址和目的地址接受、刪除或拒絕它們。防火牆過濾代碼能夠看到包的原始源地址,以及最終目的地址。這對我們很有用處,因為它可以讓防火牆繼續正常工作,即使我們暫時禁用了 NAT 或偽裝。


了解表


在以上的 NAT/偽裝示例中,我們將規則附加到鏈,但還做了一些略有不同的事。請注意 "-t" 選項。"-t" 選項可以讓我們指定鏈所屬的表。當省略這個選項時,預設表將預設為 "filter"。因此,以前所有與非 NAT 相關的命令修改 "filter" 表中的 INPUT 鏈。"filter" 表包含了所有與接收或拒絕包相關的規則,而 "nat" 表(如您假設的)包含了與網路地址轉換相關的規則。還有其它內置 iptables 鏈,在 iptables 幫助頁面以及 Rusty 的 HOWTO(請參閱本教程結尾處的「參考資料」部分,以獲取鏈接)中詳細描述了這些鏈。


增強的腳本


現在已經討論過一些可能的增強,讓我們看一下第二種更靈活的防火牆啟動/停止腳本:


#!/bin/bash

# An enhanced stateful firewall for a workstation, laptop or router that isn
# running any network services like a web server, SMTP server, ftp server, etc.

#change this to the name of the interface that provides your "uplink"
#(connection to the Internet)

UPLINK="eth1"

#if you e a router (and thus should forward IP packets between interfaces),
#you want ROUTER="yes"; otherwise, ROUTER="no"

ROUTER="yes"

#change this next line to the static IP of your uplink interface for static SNAT, or
#"dynamic" if you have a dynamic IP. If you don need any NAT, set NAT to "" to
#disable it.

NAT="1.2.3.4"

#change this next line so it lists all your network interfaces, including lo

INTERFACES="lo eth0 eth1"

if [ "$1" = "start" ]
then
echo "Starting firewall..."
iptables -P INPUT DROP
iptables -A INPUT -i ! ${UPLINK} -j ACCEPT
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p tcp -i ${UPLINK} -j REJECT --reject-with tcp-reset
iptables -A INPUT -p udp -i ${UPLINK} -j REJECT --reject-with icmp-port-unreachable

#explicitly disable ECN
if [ -e /proc/sys/net/ipv4/tcp_ecn ]
then
echo 0 > /proc/sys/net/ipv4/tcp_ecn
fi

#disable spoofing on all interfaces
for x in ${INTERFACES}
do
echo 1 > /proc/sys/net/ipv4/conf/${x}/rp_filter
done

if [ "$ROUTER" = "yes" ]
then
#we e a router of some kind, enable IP forwarding
echo 1 > /proc/sys/net/ipv4/ip_forward
if [ "$NAT" = "dynamic" ]
then
#dynamic IP address, use masquerading
echo "Enabling masquerading (dynamic ip)..."
iptables -t nat -A POSTROUTING -o ${UPLINK} -j MASQUERADE
elif [ "$NAT" != "" ]
then
#static IP, use SNAT
echo "Enabling SNAT (static ip)..."
iptables -t nat -A POSTROUTING -o ${UPLINK} -j SNAT --to ${UPIP}
fi
fi

elif [ "$1" = "stop" ]
then
echo "Stopping firewall..."
iptables -F INPUT
iptables -P INPUT ACCEPT
#turn off NAT/masquerading, if any
iptables -t nat -F POSTROUTING
fi


第六章 有狀態服務

查看規則


在開始定製防火牆以便可以在伺服器上使用它之前,我需要演示如何列出當前活動的防火牆規則。要查看過濾器表的 INPUT 鏈中的規則,輸入:


# iptables -v -L INPUT

-v 選項給出一個冗長的輸出,這樣我們可以查看每個規則傳送的總包數和總的位元組數。還可以使用以下命令查看 nat POSTROUTING 表:


# iptables -t nat -v -L POSTROUTING
Chain POSTROUTING (policy ACCEPT 399 packets, 48418 bytes)
pkts bytes target prot opt in out source destination
2728 170K SNAT all -- any eth1 anywhere anywhere to:215.218.215.2


準備提供服務


現在,防火牆不允許陌生人連接我們機器上的服務,因為它只接受進入 ESTABLISHED 或 RELATED 包。由於它刪除了所有進入 NEW 包,因此所有連接嘗試都將被無條件拒絕。但是,只要有選擇地允許一些進入通信流通過防火牆,我們就可以讓陌生人連接到我們指定的服務。

有狀態 HTTP


雖然我們要接受一些進入連接,但我們可能並不想接受所有進入連接。最好從「預設拒絕」策略開始(就象我們現在使用的策略),逐漸開放對那些希望人們可以連接的服務的訪問。例如,如果正在運行 Web 伺服器,我們允許 NEW 包進入我們的機器,只要它們去往埠 80 (HTTP)。那就是我們需要做的。一旦允許 NEW 包進入,那我們就允許建立連接。一旦建立了連接,就匹配了允許進入 ESTABLISHED 和 RELATED 包的現有規則,從而 HTTP 連接將變得暢通無阻。


有狀態 HTTP 示例


讓我們看一下防火牆的「核心」,以及允許進入 HTTP 連接的新規則:


iptables -P INPUT DROP
iptables -A INPUT -i ! ${UPLINK} -j ACCEPT
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
#our new rule follows
iptables -A INPUT -p tcp --dport http -m state --state NEW -j ACCEPT
iptables -A INPUT -p tcp -i ${UPLINK} -j REJECT --reject-with tcp-reset
iptables -A INPUT -p udp -i ${UPLINK} -j REJECT --reject-with icmp-port-unreachable

這個新規則允許去往我們機器的埠 80 (http) 的 NEW TCP 包進入。請注意這個規則的位置。它出現在 REJECT 規則有重要意義。由於 iptables 將應用第一個匹配的規則,因此將它放到 REJECT 行的後面會使這個規則無法生效。


最後的防火牆腳本


現在來看一下最後的防火牆腳本,它可以用於膝上型計算機、工作站、路由器或伺服器(或者其中的某些組合!)。


#!/bin/bash

#Our complete stateful firewall script. This firewall can be customized for
#a laptop, workstation, router or even a server. :)

#change this to the name of the interface that provides your "uplink"
#(connection to the Internet)

UPLINK="eth1"

#if you e a router (and thus should forward IP packets between interfaces),
#you want ROUTER="yes"; otherwise, ROUTER="no"

ROUTER="yes"

#change this next line to the static IP of your uplink interface for static SNAT, or
#"dynamic" if you have a dynamic IP. If you don need any NAT, set NAT to "" to
#disable it.

NAT="1.2.3.4"

#change this next line so it lists all your network interfaces, including lo

INTERFACES="lo eth0 eth1"

#change this line so that it lists the assigned numbers or symbolic names (from
#/etc/services) of all the services that youd like to provide to the general
#public. If you don want any services enabled, set it to ""

SERVICES="http ftp smtp ssh rsync"

if [ "$1" = "start" ]
then
echo "Starting firewall..."
iptables -P INPUT DROP
iptables -A INPUT -i ! ${UPLINK} -j ACCEPT
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

#enable public access to certain services
for x in ${SERVICES}
do
iptables -A INPUT -p tcp --dport ${x} -m state --state NEW -j ACCEPT
done

iptables -A INPUT -p tcp -i ${UPLINK} -j REJECT --reject-with tcp-reset
iptables -A INPUT -p udp -i ${UPLINK} -j REJECT --reject-with icmp-port-unreachable

#explicitly disable ECN
if [ -e /proc/sys/net/ipv4/tcp_ecn ]
then
echo 0 > /proc/sys/net/ipv4/tcp_ecn
fi

#disable spoofing on all interfaces
for x in ${INTERFACES}
do
echo 1 > /proc/sys/net/ipv4/conf/${x}/rp_filter
done

if [ "$ROUTER" = "yes" ]
then
#we e a router of some kind, enable IP forwarding
echo 1 > /proc/sys/net/ipv4/ip_forward
if [ "$NAT" = "dynamic" ]
then
#dynamic IP address, use masquerading
echo "Enabling masquerading (dynamic ip)..."
iptables -t nat -A POSTROUTING -o ${UPLINK} -j MASQUERADE
elif [ "$NAT" != "" ]
then
#static IP, use SNAT
echo "Enabling SNAT (static ip)..."
iptables -t nat -A POSTROUTING -o ${UPLINK} -j SNAT --to ${UPIP}
fi
fi

elif [ "$1" = "stop" ]
then
echo "Stopping firewall..."
iptables -F INPUT
iptables -P INPUT ACCEPT
#turn off NAT/masquerading, if any
iptables -t nat -F POSTROUTING
fi



[火星人 ] Linux 2.4有狀態防火牆設計(三)已經有454次圍觀

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