2018年9月20日 星期四

用ipset配置linux防火牆

From:http://blog.chinaunix.net/uid-21706718-id-3561951.html
iptables是在linux內核裡配置防火牆規則的用戶空間工具,它實際上是netfilter框架的一部分.可能因為iptables是netfilter框架裡最常見的部分,所以這個框架通常被稱為iptables,iptables是linux從2.4版本引入的防火牆解決方案. 


ipset是iptables的擴展,它允許你創建匹配整個地址sets(地址集合)的規則。而不像普通的iptables鍊是線性的存儲和過濾,ip集合存儲在帶索引的數據結構中,這種結構即時集合比較大也可以進行高效的查找. 

除了一些常用的情況,比如阻止一些危險主機訪問本機,從而減少系統資源佔用或網絡擁塞,IPsets也具備一些新防火牆設計方法,並簡化了配置. 

在本文中,在快速的討論ipsets的安裝要求後,我會花一點時間來介紹iptables的核心機制和基本概念.然後我會介紹ipset的使用方法和語法,並且演示ipset如何與iptables結合來完成各種不同的配置。最後,我會提供一些細節和較高級的例子來演示如何解決現實中的問題。

ipset比傳統的iptables擁有顯著的性能提升和擴展特性,比如將單個防火牆規則通過一次配置應用到整個主機所在的組和網絡。

由於ipset只是iptables的擴展,所以也會對iptables進行描述。

在許多的linux發布中ipset是一個簡單的安裝包,大家可以通過自己的linux發行版提供的包管理工具進行安裝。

需要理解的重點時,同iptables一樣,ipset是由用戶空間的工具和內核空間的模塊兩部分組成,所以你需要將這兩部分都準備好。你也需要"ipset-aware"這個iptables模塊,這個模塊用來增加rules that match against sets。(……)

首先我們使用自己的linux發行版的包管理工具對ipset進行搜索。在ubuntu上安裝需要安裝ipset和xtables-addons-source包,然後,運行module-assistant auto-install xtables-addons,等待大約30秒後ipset就可以使用了。

如果你的linux發行版沒有被支持,那就需要根據ipset首頁中的安裝步驟構建源碼並對內核打補丁。

這篇文章中使用ipset v4.3和iptables v1.4.9。

iptables概述

簡單來講,iptables防火牆配置由規則鏈的集合組成,每一個鏈包含一個規則。一個數據包,在各個處理階段,內核商量合適的規則來決定數據報的命運。

規則鏈按照順序進行匹配,基於數據包的流向(remote-to-local, remote-to-remote or local-to-remote)和當前所處的處理階段(before or after "routing")。參考圖1。

當需要匹配規則鏈時,數據包需要與鏈中的每個規則按照順序進行比對,直道找到匹配的規則。一旦找到了匹配的規則,目標規則就會被調用。如果最後一個規則與數據包也不匹配,就會使用默認規則。
一個規則鏈就是許多規則按順序排列組成,一個規則就是match/target的組合。一個簡單的match例子是“TCP目標端口為80”。target的例子是“接受這個包”。target同樣可以將數據包重定向到其他的用戶自定義的鏈,用戶自定義鏈提供了一些機制,包括組合和細分規則,將多個鏈級聯來完成一個功能。
每一個用來定義規則的iptables命令,不管是用於簡單的規則還是複雜的規則,都有三個基本的部分組成,包括指定table/chain (and order), match和target。

Figure 2.解析iptables命令
配置所有的這些選項,創建一個完整得防火牆,你需要按照特定的順序運行一系列的iptables命令。
iptables非常強大並且可擴展。除了許多內部特性,iptables提供了擴展match和target的API。
ipset
ipset是iptables的match擴展。如果要使用它,需要使用ipset命令行工具創建一個集合併指定一個唯一的集和名,然後在iptables規則的match部分分別索引這些集合。
一個集合是一個方便有效快速查詢的地址列表。
下面有兩個常見的iptables命令,這兩個命令阻止從1.1.1.1和2.2.2.2進入主機的數據包:
iptables -A INPUT -s 1.1.1.1 -j DROP
iptables -A INPUT -s 2.2.2.2 -j DROP 
match部分語法-s 1.1.1.1表示“匹配源地址是1.1.1.1的數據包”。
下面的ipset/iptables命令同樣可以達到上面的目的:
ipset -N myset iphash 
ipset -A myset 1.1.1.1 
ipset -A myset 2.2.2.2 
iptables -A INPUT -m set --set myset src -j DROP 
上面的ipset命令創建了一個包含兩個地址(1.1.1.1 and 2.2.2.2)的集合(myset of type iphash)。
然後iptables命令通過-m set --set myset src這個match選項使用這個集合,這個匹配規則的意思是“匹配源地址包含在集合myset中的數據包” 
src表示源地址,dst表示目標地址。如果同時使用src和dst表示既要匹配源地址又要匹配目的地址。
在第二個例子裡,只需要一個iptables命令,不管集合裡有多少ip地址需要添加。雖然這個例子裡只使用了兩個地址,但是你可以依據這個例子簡單的定義1000個地址,並且仍然只需要一條iptables語句。而如果使用第一個例子的方法,不使用ipset,就需要1000條iptables規則。
Set Types
每一個集合都是特定類型的,它不但定義了什麼類型的值可以儲存在裡面(IP addresses, networks, ports and so on),而且定義瞭如何匹配數據包(換言之,數據包的那一部分需要被檢查和如何檢查)。除了一些最通用的集合類型,比如檢查ip地址,也提供了一些其他的集合類型,比如檢查端口,地址和端口同時檢查,mac地址和ip地址同時檢查等。
每一種集合類型都有自己的規則,這些規則表示集合的類型,範圍,它包含的值得分佈。不同的集合類型使用不同的類型索引,並且在不同的情況下被優化。需要根據不同的現實情況選擇集合類型。
最靈活的集合類型是iphash,它可以存儲任意的ip地址和nethash(IP/mask)。請參考ipset的man手冊來了解所有的集合類型。
setlist是一個特別的集合類型,它允許組織多個集合到一個集合裡面。比如你需要一個單獨的集合既包含ip地址又包含網絡信息。
Advantages of ipset 
除了性能優勢,一些情況下ipset允許更直接的配置方法。
如果你想定義一個防火牆環境,該環境不會處理來自1.1.1.1和2.2.2.2的包,並且處理過程包含在mychain中,注意下面的方法是無效的:
iptables -A INPUT -s ! 1.1.1.1 -g mychain 
iptables -A INPUT -s ! 2.2.2.2 -g mychain 
如果數據包來自1.1.1.1,它匹配第一條規則失敗,但是匹配第二條規則時會成功。如果數據包來自2.2.2.2,匹配第一個規則就會成功。
雖然有有一些其它的方法可以不適用ipset就能達到指定的要求,但是ipset是最直接了當的。
ipset -N myset iphash 
ipset -A myset 1.1.1.1 
ipset -A myset 2.2.2.2 
iptables -A INPUT -m set ! --set myset src -g mychain 
用上面的方法,如果數據包來自1.1.1.1,它不會匹配規則(because the source address 1.1.1.1 does match the set myset)。如果數據包來自2.2.2.2,它也不會匹配規則。
這只是一個簡單的例子,它說明在一個規則裡匹配完整條件的基本優點。其他方面,每個iptables規則與其它規則是獨立的,並且將規則邏輯的連接起來是比較難的,特別當它包含混合了正常和反向測試時。ipset只是在這些情況下使配置變簡單。
ipset的另一個優勢是集合可以動態的修改,即使iptables的規則正在使用這個集合。添加/修改/刪除接口使用很簡單並且是順序無關的。另一方面,在iptables裡每一條規則都比較複雜,並且規則的順序也是很重要的元素,所以修改內部規則很困難並且會存在潛在問題。

Excluding WAN, VPN and Other Routed Networks from the NAT—the Right Way

Outbound NAT (SNAT或IP偽裝)允許私有局域網內的主機訪問internet.iptables NAT規則匹配私網內訪問internat的包,並用網關地址替換包的源地址(使數據包看起來像是從網關發送的,從而隱藏網關後面的主機)。

NAT自動跟踪活動的連接,所以它能將返回的包發送給正確的內網主機(通過將數據包的目的地址修改為內部主機地址)。

下面是一個簡單的outbound NAT規則,10.0.0.0/24是內部局域網:

iptables -t nat -A POSTROUTING \ 
         -s 10.0.0.0/24 -j MASQUERADE 

該規則匹配所有來自內網的包,並對他們進行偽裝。如果只有一個路由連接到internat這種方法是非常有效率的,通過該路有的所有流量都是公網的流量。然而,如果有連接到其它私有網絡的路由存在,比如VPN或無力WAN連接,你可能就不會使用地址偽裝。

克服這個限制的一個簡單方法是基於物理接口建立NAT規則,而不是使用基於網絡地址的方式。

iptables -t nat -A POSTROUTING \ 
         -o eth0 -j MASQUERADE 

該規則假設eth0是外部接口,該規則會匹配所有離開這個接口的包。與前面的規則不同的是,其他內網的數據包通過其它接口訪問公網時不會匹配這條規則(比如OpenVPN的連接)。

雖然許多連接是通過不同的接口路由,但並不能假設所有的鏈接都是這樣。一個例子是基於KAME的IPsec VPN連接(比如Openswan)就不是使用虛擬接口。

不適用上面的接口匹配技術的另一種情況是如果向外的接口(連接到Internet的接口)連接路由到其他私有網絡的中間網絡,而不是連接到Internet。

通過匹配物理接口來設計的防火牆規則可以使用在一些人為限制方面,並且依賴網絡拓撲。

後來發現,ipset還有另一個應用。假設有一個本地LAN (10.0.0.0/24)需要連接到internet,除此之外還有三個本地網絡(10.30.30.0/24, 10.40.40.0/24, 192.168.4.0/23和172.22.0.0/22 ),執行下面的命令:


ipset -N routed_nets nethash 
ipset -A routed_nets 10.30.30.0/24 
ipset -A routed_nets 10.40.40.0/24 
ipset -A routed_nets 192.168.4.0/23 
ipset -A routed_nets 172.22.0.0/22 
iptables - t nat -A POSTROUTING \ 
         -s 10.0.0.0/24 \ 
         -m set ! --set routed_nets dst \ 
         -j MASQUERADE

如我們所見,ipset簡單的實現了精確匹配。該規則偽裝所有來自(10.0.0.0/24)的數據包,而不處理其他在routed_nets集合中的網絡的包。由於該配置完全基於網絡地址,所以你完全不用擔心其他特殊的網絡連接(比如VPN),也不用擔心物理接口和網絡拓撲。

Limiting Certain PCs to Have Access Only to Certain Public Hosts

假設老闆較關心員工上班時間上網問題,請你限制員工的PC只能訪問指定的幾個網站,但是不想所有的內部PC都受到限制。

限制3台PC (10.0.0.5, 10.0.0.6 and 10.0.0.7)只能訪問worksite1.com,worksite2.com和worksite3.com。執行下面的命令:
ipset -N limited_hosts iphash 
ipset -A limited_hosts 10.0.0.5 
ipset -A limited_hosts 10.0.0.6 
ipset -A limited_hosts 10.0.0.7 
ipset -N allowed_sites iphash 
ipset -A allowed_sites worksite1.com 
ipset -A allowed_sites worksite2.com 
ipset -A allowed_sites worksite3.com 
iptables -I FORWARD \
         -m set --set limited_hosts src \ 
         -m set ! --set allowed_sites dst \ 
         -j DROP 

該例子在一條規則裡使用了兩個集合。如果源地址匹配limited_hosts目的地址不匹配allowed_sites,數據包就被丟棄。

注意該規則被添加到了FORWARD鏈,它不會影響防火牆主機自己的通信。

 Blocking Access to Hosts for All but Certain PCs (Inverse Scenario)

假設老闆想阻止員工訪問幾個特定的網站,但是不阻止他自己的PC和他助理的PC。在這個例子裡,我們可以匹配老闆和助理的PC的MAC地址,而不是匹配IP地址。假設他們的MAC是11:11:11:11:11:11和22:22:22:22:22:22,需要組織員工訪問的站點是badsite1.com, badsite2.com和badsite3.com. 

這次我們不使用第二個集合匹配MAC地址,而是使用多個iptables命令,利用MARK target標記數據包,而利用後面的規則處理被標記的數據包。

ipset -N blocked_sites iphash 
ipset -A blocked_sites badsite1.com 
ipset -A blocked_sites badsite2.com 
ipset -A blocked_sites badsite3.com
iptables -I FORWARD -m mark --mark 0x187 -j DROP 
iptables -I FORWARD \ 
         -m mark --mark 0x187 \ 
         -m mac --mac-source 11:11:11:11:11:11 \ 
         -j MARK --set-mark 0x0 
iptables -I FORWARD \ 
         -m mark --mark 0x187 \ 
         -m mac --mac-source 22:22:22:22:22:22 \ 
         -j MARK --set-mark 0x0 
iptables - I FORWARD \ 
         -m set --set blocked_sites dst \ 
         -j MARK --set-mark 0x187 

上面的例子,由於沒有使用ipset完成所有的匹配工作,所以使用的命令比較多,而且比較複雜。由於用到了多個iptables命令,所以各個命令的順序是非常重要的。

注意這些規則是使用—I (insert)選項而不是使用-A (append)選項。當一個規則被插入,他會被添加的鏈的頂端,而以前的規則自動下移。因為每一格規則都是被插入德,所以實際的有效順序是相反的。

最後一個iptables命令實際在FORWARD鏈的頂端。該規則匹配所有目的地址與blocked_sites集合相匹配的數據包,然後將這些數據標記為0x187.下面的兩個規則匹配來自特定MAC地址並且已經標記為0x187的數據包,然後將他們標記為0。

最後,最後的iptables規則丟棄所有的被標記為0x187的數據包。除了來源是兩個特定MAC地址的數據包,他將會匹配所有的目標地址在blocked_sites集合裡的數據包。

這是解決問題的一種方法。還有一些其他方法,除了使用第二個ipset集合的方法,還可以使用用戶自定義鍊等。

使用第二個ipset集合代替標記的方法是不可能完成上面的要求的,因為ipset沒有machash集合類型,只有集合類型,但是他要求同時匹配IP和MAC,而不是只匹配MAC地址。

警告:在大多數實際環境裡,這個方法可能不可行,應為大部分你需要屏蔽的網站他們的主機都有多個ip地址(比如Facebook, MySpace等等),而且這些ip會頻繁的更換。iptables/ipset的一個限制是主機名只有被解析為單個ip地址時才能使用。

而且,主機名lookup只有在命令執行時發生,所以如果ip地址改變了,防火牆是不會意識到的,而是仍然使用以前的ip地址。基於這個原因,一個完成Web訪問限制的更好的方法是使用HTTP代理,比如Squid。

Automatically Ban Hosts That Attempt to Access Invalid Services

ipset為iptables提供了目標擴展功能,它提供了一種向集合動態添加和刪除目標的機制。不必手動使用ipset命令添加目標,而是在運行時通過iptables自動添加。

比如,如果遠程主機嘗試連接端口25,但是你並沒有運行SMTP服務,我們懷疑對方不懷好意,所以我們在對方還沒有乾什麼壞事前就組織他的其他嘗試,使用下面的規則:

ipset -N banned_hosts iphash 
iptables -A INPUT \ 
         -p tcp --dport 25 \ 
         -j SET --add-set banned_hosts src 
iptables -A INPUT \ 
         -m set --set banned_hosts src \ 
         -j DROP 

如果從端口25接收到數據包,假設來源地址是1.1.1.1,那麼該地址馬上就被添加到banned_hosts集合,和下面的例子等效:

ipset -A banned_hosts 1.1.1.1 

所有的1.1.1.1的連接都會被阻塞。

他同樣會阻止其他主機對本設備進行端口掃描,除非他不掃描25號端口。
Clearing the Running Config 

如果你想清除ipset和iptables的配置,將防火牆reset,運行下面的命令:

iptables -P INPUT ACCEPT 
iptables -P OUTPUT ACCEPT 
iptables -P FORWARD ACCEPT 
iptables -t filter -F
iptables -t raw -F 
iptables -t nat -F 
iptables -t mangle -F 
ipset -F 
ipset -X 

如果集合正在被使用,意味著其它的iptables規則正在引用該集合,就不能對集合進行銷毀(ipset - X),所以為了在任何狀態下都完成reset,iptables鏈必須首先清除。

Conclusion

ipset為netfilter/iptables在增加了很多有用的特性和功能,正如本篇文章描述的,ipset不僅提供了新的防火牆配製的可能性,而且他減少了之前只使用iptables來配置防火牆的困難。

任何時候,如果你想將防火牆規則應用到一個組,你應該使用ipset。正如前面的例子,你可以通過將ipset與iptables的其它特性相結合,來完成各種各樣的網絡配置和策略。

下一次你再進行防火牆配置時,考慮使用ipset。我相信你會被他的可用性和靈活性震驚。
Resources 

Netfilter/iptables Project Home Page: http://www.netfilter.org 

ipset Home Page: http://ipset.netfilter.org 

原文地址:http://www.linuxjournal.com/content/advanced-firewall-configurations -ipset?page=0,0 

沒有留言:

張貼留言

How to use simple speedtest in RaspberryPi CLI

  pi@ChunchaiRPI2:/tmp $  wget -O speedtest-cli https://raw.githubusercontent.com/sivel/speedtest-cli/master/speedtest.py --2023-06-26 10:4...