一個強大優秀的防火牆工具 – iptables

前言廢話

在各個 linux 中,通常都有內建一個基礎的防火牆工具,名為 iptables。他能做到的事情非常多,因此我也仍在學習階段,這篇文章將會滾動式調整。

安裝 iptables

雖然我並不認為有 linux 中沒有內建這東西,不過如果你真的沒有,可以使用下面命令安裝:

sudo apt-get install iptables

新手入門

在預設的情況下,我們使用 iptables -L 命令,可以看到 INPUTFORWARDOUTPUT 的預設 policy 都是 ACCEPT,這意味著目前為全開狀態。我們要做的事情就是先新增規則,在改變 Policy。

我們先允許 TCPPort 22,也就是 SSH 訪問:

sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT

允許與現有連接相關的流量通過,包括回應你的服務器發起的請求等等:

sudo iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT

INPUT 的 Default Policy 設定為 DROP

sudo iptables -P INPUT DROP

iptables 存檔

iptables 是不會存檔的,因此當你重新啟動後,這些規則就會消失。

根據我在網路上查到的方法,使用 sudo iptables-save > /etc/iptables/rules.v4 即可保存,但我個人是使用不同的方法。

首先先安裝 iptables-persistent

sudo apt-get install iptables-persistent

接著就可以使用以下兩條命令來保存規則啦,重啟後也會自動載入:

sudo netfilter-persistent save
sudo netfilter-persistent reload

新增規則

以下一樣提供幾個範例參考,可以自己融會貫通去改變成適合自己的。

允許任何地方的 ICMP 要求:

sudo iptables -A INPUT -p icmp -j ACCEPT

也可以更精確的控制要允許那一種的 ICMP 類型,例如 echo-request

sudo iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT

允許任何地方訪問 TCPPort 80

sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT

允許任何地方訪問 TCPPort 80,並新增一個註解 HTTP Server

sudo iptables -A INPUT -p tcp --dport 80 -m comment --comment "HTTP Server" -j ACCEPT

可以使用帶有 -s 的參數來指定源 IP,例如允許 192.168.0.1 訪問任何地方:

sudo iptables -A INPUT -s 192.0.2.1 -j ACCEPT

反之,若是要丟棄 192.168.0.1 的封包,則使用 DROP

sudo iptables -A INPUT -s 192.0.2.1 -j DROP

允許 192.168.0.1 訪問 UDPPort 25565

sudo iptables -A INPUT -p udp --dport 25565 -s 192.168.0.1 -j ACCEPT

刪除命令

上面都是關於新增規則的命令,但若是要進行刪除,則將 -A 改成 -D 即可,例如:

# 新增一條允許 ICMP 的規則
sudo iptables -A INPUT -p icmp -j ACCEPT

# 刪除一條允許 ICMP 的規則
sudo iptables -D INPUT -p icmp -j ACCEPT

列出目前的所有規則(有幾種任選):

sudo iptables -S
sudo iptables -L
iptables -L -n -v

刪除所有規則:

sudo iptables -F

刪除自定義的 chain:

sudo iptables -X

適用於 IPv6

看了這麼多,其實上面的命令都不適用於 IPv6!因為 iptables 是管理 IPv4 的,若你想要管理 IPv6,則將所有指令都改成 ip6tables 即可。

紀錄流量到日誌

若你想要將防火牆紀錄 Log 下來,你可以使用下面命令(以 TCP 3031 為例):

sudo iptables -A INPUT -p tcp --dport 3031 -j LOG --log-prefix "TCP 3031 traffic: "

接著可以使用以下命令來列出 Log:

sudo cat /var/log/messages | grep "TCP 3031 traffic:"