1. 程式人生 > >5、iptables之nat

5、iptables之nat

回顧:

telnet: 23/tcp

samba: 137/udp, 138/udp, 139/tcp, 445/tcp

dns: INPUT: 53/udp, OUTPUT: 53/udp

 

核心轉發:/proc/sys/net/ipv4/ip_forward

/etc/sysct.conf

net.ipv4.ip_forward = 1

 

iptables:

顯式擴充套件、網路防火牆

 

顯式擴充套件:multiport, iprange, string, time, connlimit, limit, state

state:

/proc/net/nf_conntrack

/proc/sys/net/nf_conntrack_max

 

NEW, ESTABLISHED, RELATED, INVALID

 

iptables:

 

nat:Network Address Translation,安全性,網路層+傳輸層

proxy:代理,應用層

 

nat:

SNAT: 只修改請求報文的源地址;

DNAT:只修改請求報文的目標地址;

 

nat表:

PREROUTING:DNAT

OUTPUT

POSTROUTING:SNAT

 

源地址轉換:iptables -t nat -A POSTROUTING -s LocalNET ! -d LocalNet -j SNAT --to-source ExtIP

iptables -t nat -A POSTROUTING -s LocalNET ! -d LocalNet -j MASQUERADE

 

目標地址轉換:iptables -t nat -A PREROUTING -d ExtIP -p tcp|udp --dport PORT -j DNAT --to-destination InterSeverIP[:PORT]

 

 

 

 

iptables的連結跟蹤表最大容量為/proc/sys/net/ipv4/ip_conntrack_max,連結碰到各種狀態的超時後就會從表中刪除。

 

所以解決方法一般有兩個:

(1) 加大 ip_conntrack_max 值

vi /etc/sysctl.conf

net.ipv4.ip_conntrack_max = 393216

net.ipv4.netfilter.ip_conntrack_max = 393216

(2): 降低 ip_conntrack timeout時間

vi /etc/sysctl.conf

net.ipv4.netfilter.ip_conntrack_tcp_timeout_established = 300

net.ipv4.netfilter.ip_conntrack_tcp_timeout_time_wait = 120

net.ipv4.netfilter.ip_conntrack_tcp_timeout_close_wait = 60

net.ipv4.netfilter.ip_conntrack_tcp_timeout_fin_wait = 120

 

iptables -t nat -L -n

 

 

 

練習:INPUT和OUTPUT預設策略為DROP;

 

1、限制本地主機的web伺服器在週一不允許訪問;新請求的速率不能超過100個每秒;web伺服器包含了admin字串的頁面不允許訪問;web伺服器僅允許響應報文離開本機;

 

2、在工作時間,即週一到週五的8:30-18:00,開放本機的ftp服務給172.16.0.0網路中的主機訪問;資料下載請求的次數每分鐘不得超過5個;

 

3、開放本機的ssh服務給172.16.x.1-172.16.x.100中的主機,x為你的座位號,新請求建立的速率一分鐘不得超過2個;僅允許響應報文通過其服務埠離開本機;

 

4、拒絕TCP標誌位全部為1及全部為0的報文訪問本機;

 

5、允許本機ping別的主機;但不開放別的主機ping本機;

 

 

練習:判斷下述規則的意義:

# iptables -N clean_in

# iptables -A clean_in -d 255.255.255.255 -p icmp -j DROP

# iptables -A clean_in -d 172.16.255.255 -p icmp -j DROP

 

# iptables -A clean_in -p tcp ! --syn -m state --state NEW -j DROP

# iptables -A clean_in -p tcp --tcp-flags ALL ALL -j DROP

# iptables -A clean_in -p tcp --tcp-flags ALL NONE -j DROP

# iptables -A clean_in -d 172.16.100.7 -j RETURN

 

 

# iptables -A INPUT -d 172.16.100.7 -j clean_in

 

# iptables -A INPUT  -i lo -j ACCEPT

# iptables -A OUTPUT -o lo -j ACCEPT

 

 

# iptables -A INPUT  -i eth0 -m multiport -p tcp --dports 53,113,135,137,139,445 -j DROP

# iptables -A INPUT  -i eth0 -m multiport -p udp --dports 53,113,135,137,139,445 -j DROP

# iptables -A INPUT  -i eth0 -p udp --dport 1026 -j DROP

# iptables -A INPUT  -i eth0 -m multiport -p tcp --dports 1433,4899 -j DROP

 

# iptables -A INPUT  -p icmp -m limit --limit 10/second -j ACCEPT

 

 

 

 

補充:利用iptables的recent模組來抵禦DOS攻擊: 22,建立一個列表,儲存有所有訪問過指定的服務的客戶端IP

 

 

ssh: 遠端連線,

 

iptables -I INPUT -p tcp --dport 22 -m connlimit --connlimit-above 3 -j DROP

 

 

iptables -I INPUT  -p tcp --dport 22 -m state --state NEW -m recent --set --name SSH

iptables -I INPUT  -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 300 --hitcount 3 --name SSH -j LOG --log-prefix "SSH Attach: "

iptables -I INPUT  -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 300 --hitcount 3 --name SSH -j DROP

 

1.利用connlimit模組將單IP的併發設定為3;會誤殺使用NAT上網的使用者,可以根據實際情況增大該值;

 

2.利用recent和state模組限制單IP在300s內只能與本機建立2個新連線。被限制五分鐘後即可恢復訪問。

 

下面對最後兩句做一個說明:

 

1.第二句是記錄訪問tcp 22埠的新連線,記錄名稱為SSH

--set 記錄資料包的來源IP,如果IP已經存在將更新已經存在的條目

 

2.第三句是指SSH記錄中的IP,300s內發起超過3次連線則拒絕此IP的連線。

--update 是指每次建立連線都更新列表;

--seconds必須與--rcheck或者--update同時使用

--hitcount必須與--rcheck或者--update同時使用

 

3.iptables的記錄:/proc/net/xt_recent/SSH

 

 

也可以使用下面的這句記錄日誌:

iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --name SSH --second 300 --hitcount 3 -j LOG --log-prefix "SSH Attack"

 

 

 

 

 

iptables實現七層訪問過濾:

 

模組:layer7

識別應用層協議

 

iptables/netfilter

iptables -m state,

netfilter state

 

對核心中的netfilter,打補丁layer7,重新編譯核心

對iptables打補丁,補上layer7模組,重新iptables

 

 

diff/patch:文字操作工具

 

 

diff是Unix系統的一個很重要的工具程式。它用來比較兩個文字檔案的差異,是程式碼版本管理的核心工具之一。其用法非常簡單:

# diff <變動前的檔案> <變動後的檔案>

 

由於歷史原因,diff有三種格式:

* 正常格式(normal diff)

* 上下文格式(context diff)

* 合併格式(unified diff)

 

1、正常格式的diff

例如,對file1(變動前的檔案)和file2(變動後的檔案)進行比較可使用如下命令:

# diff file1 file2

顯示結果中,第一行是一個提示,用來說明變動位置。它分成三個部分:前面的數字,表示file1的第n行有變化;中間的"c"表示變動的模式是內容改變(change),其他模式還有"增加"(a,代表addition)和"刪除"(d,代表deletion);

 

2、上下文格式的diff

上個世紀80年代初,加州大學伯克利分校推出BSD版本的Unix時,覺得diff的顯示結果太簡單,最好加入上下文,便於瞭解發生的變動。因此,推出了上下文格式的diff。它的使用方法是加入-c選項(即context)。

# diff -c f1 f2

結果分成四個部分。第一部分的兩行,顯示兩個檔案的基本情況:檔名和時間資訊,"***"表示變動前的檔案,"---"表示變動後的檔案。第二部分是15個星號,將檔案的基本情況與變動內容分割開。第三部分顯示變動前的檔案,即file1。

另外,檔案內容的每一行最前面,還有一個標記位。如果為空,表示該行無變化;如果是感嘆號(!),表示該行有改動;如果是減號(-),表示該行被刪除;如果是加號(+),表示該行為新增。

第四部分顯示變動後的檔案,即file2。

 

3、合併格式的diff

如果兩個檔案相似度很高,那麼上下文格式的diff,將顯示大量重複的內容,很浪費空間。1990年,GNU diff率先推出了"合併格式"的diff,將f1和f2的上下文合併在一起顯示。

它的使用方法是加入u引數(代表unified)。

# diff -u f1 f2

其結果的第一部分,也是檔案的基本資訊。"---"表示變動前的檔案,"+++"表示變動後的檔案。第二部分,變動的位置用兩個@作為起首和結束。第三部分是變動的具體內容。

除了有變動的那些行以外,也是上下文各顯示3行。它將兩個檔案的上下文,合併顯示在一起,所以叫做"合併格式"。每一行最前面的標誌位,空表示無變動,減號表示第一個檔案刪除的行,加號表示第二個檔案新增的行。

 

diff

-u

 

patch

 

儘管並沒有指定patch和diff的關係,但通常patch都使用diff的結果來完成打補丁的工作,這和patch本身支援多種diff輸出檔案格式有很大關係。patch通過讀入patch命令檔案(可以從標準輸入),對目標檔案進行修改。通常先用diff命令比較新老版本,patch命令檔案則採用diff的輸出檔案,從而保持原版本與新版本一致。

 

patch的標準格式為

patch [options] [originalfile] [patchfile]

 

如果patchfile為空則從標準輸入讀取patchfile內容;如果originalfile也為空,則從patchfile(肯定來自標準輸入)中讀取需要打補丁的檔名。因此,如果需要修改的是目錄,一般都必須在patchfile中記錄目錄下的各個檔名。絕大多數情況下,patch都用以下這種簡單的方式使用:

 

 

patch命令可以忽略檔案中的冗餘資訊,從中取出diff的格式以及所需要patch的檔名,檔名按照diff引數中的"原始檔"、"目標檔案"以及冗餘資訊中的"Index:"行中所指定的檔案的順序來決定。

 

-p引數決定了是否使用讀出的原始檔名的字首目錄資訊,不提供-p引數,則忽略所有目錄資訊,-p0(或者-p 0)表示使用全部的路徑資訊,-p1將忽略第一個"/"以前的目錄,依此類推。如/usr/src/linux-2.4.15/Makefile這樣的檔名,在提供-p3引數時將使用linux-2.4.15/Makefile作為所要patch的檔案。

 

patch

-p

-R

 

mockbuild

 

總結:操作步驟

 

1、獲取並編譯核心

 

# useradd mockbuild

# rpm -ivh kernel-2.6.32-431.5.1.x86_64.el6.src.rpm

# cd rpmbuild/SOURCES

# tar linux-2.6.32-*.tar.gz -C /usr/src

# cd /usr/src

# ln -sv

 

2、給核心打補丁

# tar xf netfilter-layer7-v2.23.tar.bz2

# cd /usr/src/linux

# patch -p1 < /root/netfilter-layer7-v2.23/kernel-2.6.32-layer7-2.23.patch

# cp /boot/config-*  .config

# make menuconfig

 

按如下步驟啟用layer7模組

Networking support → Networking Options →Network packet filtering framework → Core Netfilter Configuration

<M>  “layer7” match support

 

3、編譯並安裝核心

# make

# make modules_install

# make install

 

4、重啟系統,啟用新核心

 

5、編譯iptables

 

# tar xf iptables-1.4.20.tar.gz

# cp /root/netfilter-layer7-v2.23/iptables-1.4.3forward-for-kernel-2.6.20forward/* /root/iptables-1.4.20/extensions/

# cp /etc/rc.d/init.d/iptales /root

# cp /etc/sysconfig/iptables-config /root

# rpm -e iptables iptables-ipv6 --nodeps

# ./configure  --prefix=/usr  --with-ksource=/usr/src/linux

# make && make install

 

# cp /root/iptables /etc/rc.d/init.d

# cp /root/iptables-config /etc/sysconfig

 

6、為layer7模組提供其所識別的協議的特徵碼

 

# tar zxvf l7-protocols-2009-05-28.tar.gz

# cd l7-protocols-2009-05-28

# make install

 

7、如何使用layer7模組

 

ACCT的功能已經可以在核心引數中按需啟用或禁用。此引數需要裝載nf_conntrack模組後方能生效。

net.netfilter.nf_conntrack_acct = 1

 

 

 

l7-filter uses the standard iptables extension syntax

# iptables [specify table & chain] -m layer7 --l7proto [protocol name] -j [action]

 

 

# iptables -A FORWARD -m layer7 --l7proto qq -j REJECT

 

 

 

編譯核心:

make menuconfig

make -j #

make modules_install

make install

 

清理核心原始碼樹:

 

提示:xt_layer7.ko依賴於nf_conntrack.ko模組

 

部落格:iptables所有應用,包括layer7的實現;

 

 

課外擴充套件:recent模組,layer7模組;

 

tcp_wrapper:tcp包裝器

 

對基於tcp協議開發並提供服務的應用程式,提供的一層訪問控制工具;

基於庫呼叫實現其功能:

libwrap

 

判斷服務是否能夠由tcp_wrapper進行訪問控制:

(1) 動態編譯:ldd命令;

(2) 靜態編譯:strings命令檢視應用程式檔案,其結果中如果出現

hosts.allow

hosts.deny

 

在配置檔案在為各服務分別定義訪問控制規則實現訪問控制:

/etc/hosts.allow

/etc/hosts.deny

 

配置檔案語法:

daemon_list: client_list [:options]

 

daemon_list:

應用程式的檔名稱,而非服務名;

應用程式檔名稱列表,彼此間使用逗號分隔;

例如:sshd, vsftpd:

ALL表示所有服務;

 

client_list:

IP地址;

主機名;

網路地址:必須使用完整格式的掩碼,不使用字首格式掩碼;所以類似於172.16.0.0/16不合法;

簡短格式的網路地址:例如172.16. 表示 172.16.0.0/255.255.0.0;

ALL:所有主機;

KNOWN:

UNKNOWN

PARANOID

 

例如:vsftpd服務不允許172.16.100.1訪問

 

EXCEPT: 除了

hosts.allow

vsftpd: 172.16. EXCEPT 172.16.100.0/255.255.255.0 EXCEPT 172.16.100.1

 

[:options]

deny: 拒絕,主要用於hosts.allow檔案中

allow:允許,用於hosts.deny檔案,實現allow的功能

spawn: 啟動額外應用程式:

vsftpd: ALL :spawn /bin/echo `date` login attempt from %c to %s, %d >> /var/log/vsftpd.deny.log

%c: client ip

%s: server ip

%d: daemon name

 

練習:控制telnet服務僅允許172.16.0.0網路中的主機訪問,但不包括172.16.100.0/255.255.255.0中的主機;

對所有正常登入的主機都記錄於/var/log/telnet.allow.log中;

所有未授權訪問嘗試都記錄於/var/log/telnet.deny.log中;

 

部落格作業:iptables