Login

Navigation

Linux的防火牆(iptables)初探

前言:
我之前較為回避Linux的防火牆(iptables),因為在接觸ubuntu系統時已經有內置的簡易的防火牆「UFW (Uncomplicated Firewall)」,大大簡化防火牆的使用,但在學習WireguardZero-tierNAT等應用又好像跨不開iptables,於是重新面對iptables

Red Hat 在Linux內核2.4後就引入了iptables,是以Netfilter的機制過濾MACIPTCPUDPICMPpacket

可以簡單理解為iptables以是一款提供給人去使用的程式去給指令Netfilter執行操作。

操作流程:

iptables_small.png

圖片來自於: Red Hat iptables

  1. 所有packet進入PREROUTING
  2. 路由判斷

    • 使用本機的資源-由INPUT進入到本機處理然後OUTPUT出去
    • 沒有使用本機資源-直接FORWARD內網的其他裝置
  3. 最終經POSTROUTING出到本機外
執行順序:
通常iptables ruleallow放前,deny放後。自上而下,從左至右的方式。

packet進入到防火牆會一一對應每條tablerule,當第一條不匹配時會跳到第二條rule,直到找到匹配的rule去執行指定動作(後面所有的rule會被忽略)、如果沒有找到相對應的rule會根據iptables的預設Policy判斷是ACCEPT還是DROP

iptables的tables與chain:
iptables有三個tabels(表) (*最少),而每個table都有相對應的chain(鏈)去執行指定功能。如下圖示

2022-03-15_150210.png

iptables的簡單應用:

指令的輸入規則

iptables -t table -A/I/D/R chain -i/o Ethernet -p tcp/udp/icmp -s source_IP --sport source_port -d destination_IP --dport destination_port -j ACCEPT/DROP/REJECT/REDIRECT

iptables基本參數

參數作用
-P--policy 設置默認策略:iptables -P INPUT 是ACCEPT
-F--flush 清空所有table內的chain
-L--list 查看table內的chain
-A--append 在規則鏈的末尾加入新規則
-I--insert 在規則鏈的頭部加入新規則
-D--delete 刪除某一條規則(rule)
-s--source 來源地址IP/MASK,加嘆號"!"表示除這個IP外。如192.168.1.5 或192.168.1.0/24
-d--destination 目標地址,使用和-s相似
-i--in-interface 從網卡流入的數據
-o--out-interface 從網卡流出的數據
-pprotocol協議,如tcp、udp、icmp
-m使用state/mac,如: --state 可以有NEW、ESTABLISHED、RELATED、INVALID
--dport目標端口號,如: --dport 80或 --dport 21:22
--sport來源端口號
-j--jump 匹配修件後跳至指定的動作,如ACCEPT、DROP、REJECT、REDIRECT

實例:

允許SSH連線

iptables -t filter -A INPUT -p tcp --dport 22 -j ACCEPT

SSH_2022-03-17_083441.png

允許多組的端口通過,如HTTP和HTTPS服務

iptables -t filter -A INPUT -i eth0 -p tcp -m multiport --dport 80,443 -j ACCEPT
-i eth0 從網卡流入的數據

允許連續的端口通過,如FTP服務

iptables -t filter -A INPUT -i eth0 -p tcp --dport 20:22 -j ACCEPT 

只允許ICMP內的PING進入

iptables -A INPUT -i eth0 -p icmp --icmp-type echo-request -j ACCEPT

已經建立的連接允許通過

iptables -t filter -A INPUT -i eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
已連線和本機相關的packet都被允許

NAT的端口映射

iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 8080 -j DNAT --to-destination 10.10.10.54:80
本機的 8080 端口映射到內網其他裝置(IP-10.10.10.54)的80 端口
iptables -t nat -A POSTROUTING -d 10.10.10.54 -p tcp --dport 80 -j SNAT --to-source 10.10.10.50
指定packet header的來源IP為本機(即10.10.10.50)

最後啟用IP轉發功能

echo 'net.ipv4.ip_forward = 1' >> /etc/sysctl.conf

即時生效

sysctl -p
net.ipv4.ip_forward = 1

如果多組端口要做映射,而又不想每一次指定來源IP

iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
MASQUERADE是將所有的IP 偽裝成 -o eht0 上的 IP 出去

NAT_2022-03-17_092820.png

訪問的是10.10.10.50:8080,實際是指向10.10.10.54:80

設置默認的規則

iptables -P INPUT DROP # 更改默認不允許進入,只有已設定的rules才會被允許
iptables -P FORWARD ACCEPT # 默認的允許轉發
iptables -P OUTPUT ACCEPT # 默認的可以出去

查看iptables的filter設定

iptables -t filter -L -n
-t:指定的table 如: filter、nat、mangle

-L :列出目前的 table 的chain

-n :只顯示IP及Port號碼

--line-numbers:顯示table內chain的rules次序

List_2022-03-17_094645.png

或者

iptables-save
# Generated by iptables-save v1.8.4 on Thu Mar 17 09:47:39 2022
*nat
:PREROUTING ACCEPT [7:1112]
:INPUT ACCEPT [1:251]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
-A PREROUTING -i eth0 -p tcp -m tcp --dport 8080 -j DNAT --to-destination 10.10.10.54:80
-A POSTROUTING -o eth0 -j MASQUERADE
COMMIT
# Completed on Thu Mar 17 09:47:39 2022
# Generated by iptables-save v1.8.4 on Thu Mar 17 09:47:39 2022
*filter
:INPUT DROP [1:251]
:FORWARD ACCEPT [20:2390]
:OUTPUT ACCEPT [97:11556]
-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -i eth0 -p tcp -m tcp --dport 443 -j ACCEPT
-A INPUT -i eth0 -p tcp -m tcp --dport 21:22 -j ACCEPT
-A INPUT -i eth0 -p icmp -m icmp --icmp-type 8 -j ACCEPT
-A INPUT -i eth0 -p tcp -m multiport --dports 80,443 -j ACCEPT
COMMIT
# Completed on Thu Mar 17 09:47:39 2022

刪除指定的規則

iptables -t filter -D INPUT 1
刪除filter 表內的INPUT chain第一條rule

DEL_2022-03-17_111129.png

iptables -t filter -D INPUT -p tcp --dport 22 -j ACCEPT
也可以是輸入規則的形式刪除

清空規則

iptables -t filter -F
清空filter(table)內所有chain的rules設定
參數功能
-t指定的table 如: filter、nat、mangle
-F清空所有table內的chain
-X清除自定rule
-Zchain 的統計流量清零

儲存設定

所有的iptables設定是即時生效,但下次開機時會被清空,所以需要將iptables的所有設定儲存,并在下次開機時自動加載iptables設定。

CentOSRHEL 儲存設定

/etc/init.d/iptables save

UbuntuDebian儲存設定

需要安裝一款iptables-persistent的軟件進行儲存

安裝

apt install iptables-persistent -y

儲存

netfilter-persistent save
Usage: /usr/sbin/netfilter-persistent (start|stop|restart|reload|flush|save)
結語:
這貼文初步對iptables的學習記錄,對netfilter實現豐富功能需要更多地去探索,而且netfilter是有內核(kernel)所提供,所以在效能上非常有優勢。

netfilter機制正是和好多軟/硬件防火牆的運作原理相近,對往後接觸不同的防火牆系統設定可以更好地了解。

參考資料:

鳥哥的防火牆與 NAT 伺服器

Linux上常用的防火牆軟件

Red Hat IPTables