iptables入門:郵件服務器簡單防護
原創本文針對iptables初學者。如果你剛剛學習了iptables的原理和基本語法,但還不清楚在線上服務器環境中如何實際的利用這個工具,那么建議閱讀本文。
iptables的兩種主要工作模式
對于iptables的數據包而言,有以下幾個流向:
PREROUTING→FORWARD→POSTROUTING
PREROUTING→INPUT→本機→OUTPUT→POSTROUTING
大家可以留意下,數據包的主要兩種流向(其實也是我們后面iptables的兩種工作模式):一是做為NAT路由器,另一種是做為主機防火墻。
iptables數據流入和流出詳細流程建議參考下圖:
iptables根據不同的數據包處理功能使用不同的規則表。它包括如下三個表:filter、nat和mangle。
- filter是默認的表,它包含真正的防火墻過濾規則。內建的規則鏈包括:INPUT、OUTPUT和FORWARD。
- nat表包含源和目的地址及端口轉換使用的規則,內建的規則鏈包括PREROUTING、OUTPUT和POSTROUTING。
- mangle表包含用于設置特殊的數據包路由標志的規則,這些標志隨后被filter表中的規則檢查。內建的規則鏈包括:PREROUTING、INPUT、FORWARD、POSTROUTING和OUTPUT。
表對應的相關規則鏈的功能如下:
- INPUT鏈:當一個數據包由內核中的路由計算確定為本地的Linux系統后,它會通過INPUT鏈的檢查。
- OUTPUT鏈:保留給系統自身生成的數據包。
- FORWARD鏈:經過Linux系統路由的數據包(即當iptables防火墻用于連接兩個網絡時,兩個網絡之間的數據包必須流經該防火墻)。
- PREROUTING鏈:用于修改目的地地址(DNAT)。
- POSTROUTING鏈:用于修改源地址(SNAT)。
iptables詳細語法如下所示:
iptables [-t表名] <-A| I |D |R > 鏈名[規則編號] [-i | o 網卡名稱] [-p 協議類型] [-s 源IP地址 | 源子網][--sport 源端口號] [-d 目標IP地址 | 目標子網][--dport 目標端口號] <-j 動作>
注:此語法規則詳細,邏輯清晰,推薦以此公式記憶。我們在剛開始寫iptables規則時就應該養成好習慣,用公式來規范腳本,這對于我們的以后工作大有幫助。
這一節我們通過編寫一個簡單的用于郵件主機防護iptables腳本來熟悉iptables語法規則。網絡拓樸很簡單,iptables本身機器IP為:192.168.1.101/24,另一臺機器的IP為:192.168.1.102。
普通的郵件主機防護腳本
普通的郵件主機防護腳本比較容易實現。郵件主機主要開放二個端口:80和25,其他端口則關閉,另外由于這里沒有涉及多少功能,所以模塊的載入也很簡單,只涉及Filter表,而且腳本的初始化也很簡單。
我們可以按照編寫iptables的流程順序來寫腳本,腳本內容如下:
(注:此服務器置于自己的機房內,所以沒有開放22端口,調試時直接進機房調試。如果遠程操作,需要打開22端口。)
#/bin/bash iptables -F iptables -X iptables -Z modprobe ip_tables modprobe iptable_nat modprobe ip_nat_ftp modprobe ip_conntrack iptables -P INPUT DROP iptables -P FORWARD ACCEPT iptables -P OUTPUT ACCEPT iptables -A INPUT -i lo -j ACCEPT iptables -A OUTPUT -o lo -j ACCEPT iptables -A INPUT -p tcp -m multiport --dports 25,80 -j ACCEPT iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
說明一下:
前面三條可以將iptables初始化。
modprobe這段是手動加載模塊的過程。一般如果用 service iptables start 來啟動iptables,會加載很多不必要的模塊,所以這里我們采用手動加載的方式。ip_conntrack模塊在平時的測試學習環境可以開啟,方便追蹤數據包的流向。不過,生產環境下我不建議大家開啟此模塊,以免加重服務器的負載。
默認規則下方的兩條用于開啟系統回環端口,以免造成不必要的麻煩。具體是什么樣的麻煩?大家可以先想一想,文末會給出解答。
最后一條是允許RELATED和ESTABLISHED狀態的連接通過iptables。為什么要這樣設置,也會在文末解答。
iptables腳本開啟后,我們可以用命令查看一下結果,如下所示:
iptables -nv -L
此命令顯示結果如下:
Chain INPUT (policy DROP 13539 packets, 763K bytes) pkts bytes target prot opt in out source destination 0 0 ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0 480 32744 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 multiport dports 25,80 13 1411 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED Chain FORWARD (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination Chain OUTPUT (policy ACCEPT 472 packets, 52779 bytes) pkts bytes target prot opt in out source destination 0 0 ACCEPT all -- * lo 0.0.0.0/0 0.0.0.0/0
這時80和25之外的端口就被iptables成功隱蔽了。比如我們嘗試在另一臺機器上nmap掃描這臺服務器:
nmap -sT 192.168.1.101
此命令顯示結果如下:
Starting Nmap 4.11 ( http://www.insecure.org/nmap/ ) at 2011-05-25 00:46 CST Interesting ports on 192.168.1.101: Not shown: 1678 filtered ports PORT STATE SERVICE 25/tcp open ssh 80/tcp open http MAC Address: 00:E0:62:12:7B:65 (Host Engineering) Nmap finished: 1 IP address (1 host up) scanned in 37.721 seconds
看到這個結果說明iptables生效了。
另外,對剛剛學習iptables的朋友提供一個建議。一開始玩iptables很容易犯的一個錯誤就是把自己鎖在服務器外面了。針對這種情況,我們可以編寫一個crontab計劃任務,每5分鐘關閉一次防火墻,等完全調試完后再關閉此crontab任務:
vim /etc/crontab */5 * * * * /etc/init.d/iptables stop
以上只是初級的防護腳本。至于其它的SYN和Ping及其它攻擊,等大家熟悉了解其原理后,可以在此腳本的基礎上添加。
以下是上文中兩個問題的解答:
一、為什么要打開系統回環接口?
Linux系統默認會有一塊名為lo的環回網絡接口,而真正的網卡一般則被Linux系統識別成名為eth0, eth1這樣的網絡接口。
一般,lo接口對應的ip地址為127.0.0.1。
當你從一臺linux主機向自身發送數據包時,實際上的數據包是通過虛擬的lo接口來發送接受的,而不會通過你的物理網卡eth0/eth1。
如果lo接口被墻,會發生ping/telnet/ssh本機(本機域名、localhost和127.0.0.1)不通的情況,會給調試帶來一些麻煩。
二、為什么要設置RELATED、ESTABLISHED狀態檢測?
相對于純IP過濾,狀態防火墻更加智能,效率更高。這個比較適合FTP服務器。有關iptables的狀態機制,可參閱這篇文章:http://os.51cto.com/art/201108/285209.htm
【編輯推薦】