Iptables是專為Linux作業系統打造的極為靈活的防火牆工具。對Linux極客玩家和系統管理員來說,iptables非常有用。本文將向你展示如何設定最通用的Linux防火牆。
關於iptables
Iptables是一個基於命令行的防火牆工具,它使用規則鏈來允許/阻止網路流量。當一條網路連線試圖在你的系統中建立時,iptables會找出其對應的匹配規則。如果找不到,iptables將對其採取預設操作。
幾乎所有的Linux發行版都預先安裝了iptables。在Ubuntu/Debian中更新/安裝iptables的命令為:
sudo apt-get install iptables
現有的一些圖形介面軟體也可以取代iptables,如Firestarter。但iptables用起來並不難。設定iptables的規則時要特別小心,特別是當你遠端登陸伺服器的時候。因為這時的一個錯誤有可能讓你和伺服器永久失去連接,而你必須要到伺服器面前才能解決它。
Iptables規則鏈的型別
Iptables的規則鏈分為三種:輸入、轉送和輸出。
輸入-這條鏈用來過濾目的位址是本機的連接。例如,如果使用者試圖使用SSH登陸到你的PC/伺服器,iptables會先匹配其IP位址和連接埠到iptables的輸入鏈規則。
轉送-這條鏈用來過濾目的位址和來源位址都不是本機的連接。例如,路由器收到的絕大數資料均需要轉送給其它主機。如果你的系統沒有開啟類似路由器的功能,例如NATing,你就不需要使用這條鏈。
有一個安全且可靠的方法可以檢測你的系統是否需要轉發鏈:
iptables -L -v
上圖是對一台已經運行了幾個星期的伺服器的截圖。這台伺服器沒有對輸入和輸出做任何限制。從中可以看到,輸入鍊和輸出鏈已經分別處理了11GB和17GB的數據,而轉送鏈則沒有處理任何數據。這是因為此伺服器沒有開啟類似路由器的轉送功能。
輸出-這條鏈用來過濾來源位址是本機的連接。例如,當你嘗試ping howtogeek.com時,iptables會檢查輸出鏈中與ping和howtogeek.com相關的規則,然後決定允許或拒絕你的連線要求。
注意:當ping一台外部主機時,看上去好像只是輸出鏈在運作。但是請記住,外部主機傳回的資料要經過輸入鏈的過濾。當配置iptables規則時,請牢記許多協定都需要雙向通信,所以你需要同時配置輸入鍊和輸出鏈。人們在配置SSH的時候通常會忘記在輸入鍊和輸出鏈都配置它。
鏈的預設行為
在配置特定的規則之前,也許你想配置這些鏈的預設行為。換句話說,當iptables無法匹配現存的規則時,你想讓它做出何種行為。
你可以運行如下的命令來顯示當前iptables對無法匹配的連接的預設動作:
iptables -L
正如上面所顯示的,我們可以使用grep來使輸出的結果變得更加簡潔。在上面的截圖中,所有的鏈在預設情況下均接受所有的連接。
通常情況下,你會希望你的系統預設接收所有的網路資料。這種設定也是iptables的預設配置。接收網路連線的設定指令是:
iptables --policy INPUT ACCEPT iptables --policy OUTPUT ACCEPT iptables --policy FORWARD ACCEPT
你也可以在使用預設設定的情況下,加入一些指令來過濾特定的IP位址或連接埠號碼。我們稍後在本文介紹這些命令。
如果你想預設拒絕所有的網路連接,然後在其基礎上添加允許的IP位址或連接埠號,你可以將預設配置中的ACCEPT變成DROP,如下圖所示。這對於一些含有敏感資料的伺服器來說是極其有用的。通常這些伺服器只允許特定的IP位址存取它們。
iptables --policy INPUT DROP iptables --policy OUTPUT DROP iptables --policy FORWARD DROP
對特定連接的配置
下面來看看如何對特定的IP位址或連接埠作出設定。本文主要介紹三種最基本、最常見的設定。
Accept – 接收所有的資料。
Drop – 丟棄資料。應用場景:當你不想讓資料的來源位址意識到你的系統的存在(最好的處理方法)。
Reject – 不允許建立連接,但回傳一個錯誤回應。應用場景:當你不想讓某個IP位址存取你的系統,但又想讓它們知道你的防火牆阻止了其存取。
为了直观的区分上述三种情况,我们使用一台PC来ping一台配置了iptables的Linux电脑:
允许或阻止特定的连接
在配置完基本的规则链之后,你就可以配置iptables来允许或者阻止特定的IP地址或者端口。
注意:在这些例子中,我们使用iptables -A将额外的规则添加到现存的链中。Iptables在执行匹配的时候,会从列表的顶端开始搜索。你可以使用iptables -I [chain] [number]将新的规则插入到列表的指定位置。
来自同一IP地址的连接
下面这个例子展示了如何阻止来自IP地址为10.10.10.10的所有连接。
iptables -A INPUT -s 10.10.10.10 -j DROP
来自一组IP地址的连接
下面这个例子展示了如何阻止来自子网10.10.10.0/24内的任意IP地址的连接。你可以使用子网掩码或者标准的/符号来标示一个子网:
iptables -A INPUT -s 10.10.10.0/24 -j DROP
或
iptables -A INPUT -s 10.10.10.0/255.255.255.0 -j DROP
特定端口的连接
这个例子展示了如何阻止来自10.10.10.10的SSH连接。
iptables -A INPUT -p tcp --dport ssh -s 10.10.10.10 -j DROP
你可以将“ssh”替换成其它任何协议或者端口号。上述命令中的-p tcp告诉iptables连接使用的是何种协议。
下面这个例子展示了如何阻止来自任意IP地址的SSH连接。
iptables -A INPUT -p tcp --dport ssh -j DROP
连接状态
我们之前提到过,许多协议均需要双向通信。例如,如果你打算允许SSH连接,你必须同时配置输入和输出链。但是,如果你只想允许来自外部的SSH请求,那该怎么做?
下面这个例子展示了如何允许源IP地址为10.10.10.10同时阻止目的地址为10.10.10.10的SSH连接:
iptables -A INPUT -p tcp --dport ssh -s 10.10.10.10 -m state --state NEW,ESTABLISHED -j ACCEPT iptables -A OUTPUT -p tcp --sport 22 -d 10.10.10.10 -m state --state ESTABLISHED -j ACCEPT
保存更改
上述方法对iptables规则作出的改变是临时的。如果你想永久保存这些更改,你需要运行额外的命令(不同Linux发行版下的保存命令也不相同):
Ubuntu:
sudo /sbin/iptables-save
Red Hat / CentOS:
/sbin/service iptables save
或者
/etc/init.d/iptables save
其它命令
列出iptables的当前配置:
iptables -L
使用-v选项将显示数据包和字节信息;使用-n选项将以数字形式列出信息,即不将IP地址解析为域名。
换句话讲,主机名,协议和网络都以数字的形式列出。
清除当前所有的配置规则:
iptables -F
原文 The Beginner’s Guide to iptables, the Linux Firewall