Skip to main content

10分鐘學會IPTables

Opass
A life well lived

先承認標題殺人,這東西不可能10分鐘學會的哈哈XD。

這篇文章是我在做NA作業後研究的心得與筆記,並盡量寫成易懂的形式,讓人可以在最短的時間內熟悉iptables。

本篇文章的Target是在linux下想要學習iptables的人,我的平台是Ubuntu 13.10。

練劍前先練心法,首先要先對網路上封包的走向有一定的了解,才能掌握如何使用iptables,先直接看圖。

上面綠色紫色的方塊是Linux Kernel中處理和過濾封包的兩個模組,我們專注的看綠色的IPTables就好。

簡單說,這招圖描述了封包進入主機到離開主機,會經過哪些tables,這些tables裡面會寫規則,進行放行或攔截。

大致上你可以發現封包在主機流通時有五個階段

  • PREROUTING
  • INPUT
  • FORWARD
  • OUTPUT
  • POSTROUTING

而且不是每個封包都會經過這五個階段,從主機內部出來的封包就會從output階段開始、通過主機把主機當router的封包就不會經過INTPUT和OUTPUT,反而會通過FORWARDING。

讓我們先不要管綠色的MANGLE,那是比較複雜的設定,也比較少用到。

簡單說,你可以把你腦海中的「封包流動」觀念抽象成下圖。

// 圖片已死

本圖來源為http://linux.vbird.org/linux_server/0250simple_firewall.php#nat_ip_share 鳥哥的文章。

實戰

有了觀念後,接下來進行實戰。

成為router

因為我當初在練習時,是把這台機器當Router,所以我們要把ubuntu的IP_FORWARD打開,這台機器才會成為router並幫忙轉送封包。

如果你只是要當router一下下,那就

echo 1 > /proc/sys/net/ipv4/ip_forward 下次開機就會消失。

你也可以寫到設定檔,讓下次開機繼續當router。 /etc/sysctl.conf: net.ipv4.ip_forward = 1 # 把ip forward功能打開 sysctl -p /etc/sysctl.conf # 使設定檔生效 更詳細關於打開ip_forward功能請參閱這邊

IPTables的觀念

一樣先看圖幫助理解。 圖片來源:http://www.thegeekstuff.com/2011/01/iptables-fundamentals/

可以看到IPTables中,其實規則的設定是這樣子

有n張table,每張table內有m個chain,每個chain裡面有一系列的rule。 圖片來源:http://www.thegeekstuff.com/2011/01/iptables-fundamentals/

上面這張圖是IPTables內建的table和chain。

來記得一些規則

每張table都有各自負責的工作,不要把規則隨意寫到任意table

  • Filter table 負責過濾進入主機或離開主機、還有經過主機做forward的封包。
  • NAT table 負責進行NAT,也就是更改source IP/port或destination IP/port。請不要在NAT table中進行過濾的工作。如果你做了,他會把你擋下來並且說你不行XD
  • MANGLE 不講,因為少用而且我也不懂。

你可以自行在任意table的任意chain上添加或修改rule,也可以自己添加自定義的chain,再在裡面寫rule

  • 規則由上往下依序比對,這些rule包含「accept, drop, reject, return」,只要一符合該規則,接下來該封包就會直接套用上去pass或丟棄或阻擋。
  • 你可以在內建的chain中指定跳到某個自訂的chain比對。如果比對成功會套用規則,如果失敗,那就會自動return回當初跳過去的chain的rule位置,並繼續比對下去。

動手下指令

打開你的終端機,開始開心下指令。

首先先記一個簡單的格式 sudo iptables [-t Table] -L -n # 這可以列出你iptables現在的規則

  • -t Tables: 如果你沒有寫就代表預設指定Filter table
  • 如果你下 -t nat 代表使用nat Table,這樣該指令會列出nat這張tables下所有chain的規則
  • -L 代表List chian rule
  • -n 代表避開dns反查,這樣會直接列IP速度也比較快

現在立刻下該指令,動手學習最快。

簡單的講一下常用的指令格式

「指定某張table裡的某個chain,進行[添加/移除/修改] rule,而這些rule包含通過、阻擋、丟棄、跳到其他chain繼續比對、修改source/destination IP/port」

iptables -A [chain] [-s 來源] [-d 目的地] [-p 協定] [.....還有很多自己man] [-j 套用的rule]

  • -A some_chain : append rule到某個chain的最後面
  • -I some_chain : Insert rule到某個chain的最前面
  • -I some_chain 3: Insert rule到某個chain的第三個rule
  • -s 來源:source IP, 來源的格式可以是 192.168.1.1或是192.168.1.1/24,也可以是 -s ! source,這會排除所有source
  • -d 目的地:敘述同上。
  • -p 協定:協定可以是tcp, udp, icmp

其他常用的:

  • --dport port:match TCP或UDP封包的port,port的格式可以是 --dport 80或是 --dport 80:90
  • --sport port:同上
  • -j rule,這裡的rule其實是「target of rule」,也就是你可以是一個chain_name,或是「ACCEPT, DROP, QUEUE, RETURN, REJECT, LOG, DNAT, SNAT」 更多指令規則請自己man iptables,或是你喜歡網頁版的話這裡不錯

實戰

封鎖你討厭的人的IP,讓他永遠無法跟你連線,假設是140.113.235.151

`sudo iptables -A INPUT -s 140.113.235.151 -d 你自己的IP -j REJECTED`

你反悔了,你想要和他和好

sudo iptables -D INPUT n # n填入由上往下數第幾個規則,第1個就填1第2個就填2...`

你有一連串討厭的人,不想和他們連線

那我們最好另外開一條chain來管理所有你討厭的人

sudo iptables -N BLACKLIST # 在Filter這個預設table下開一條新的chain叫做BLACKLIST
sudo iptables -A BLACKLIST -s 140.113.235.151 -d 你自己的IP -j REJECTED # 加入兩個你討厭的人
sudo iptables -A BLACKLIST -s 140.113.235.152 -d 你自己的IP -j REJECTED
sudo iptables -A INPUT -j BLACKLIST # 讓所有進入的封包都要經過BLACKLIST chain進行比對

# 指定一個IP range,不想讓這個IP range的所有人透過tcp連線到我的port 22
sudo iptables -A INPUT -p tcp --dport 22 -m iprange --src-range 192.168.1.100-192.168.1.200 -j REJECT

-m 的意思是match,先match到的先得

進階,設定NAT

設定NAT不能在Filter這張表中設定,要在nat這張表中設定,所以請一定要記得-t nat

先觀察nat這張表的預設規則是什麼。

sudo iptables -t nat -L -n

我這台機器後面有192.168.2.0/24的子網域,我想讓這些人可以正常上網。

sudo iptables -t nat -A POSTROUTING -s 192.168.2.0/24 -o eth0 -j MASQUERADE

從服務器的eth0網卡上,自動獲取當前ip地址來做NAT

更詳細關於SNAT,請看這裡

我想讓外面的人透過port 222連到我內部內網的port 192.168.2.1這台server的port 22,來進行ssh

sudo iptables -t nat -A POSTROUTING -s 192.168.2.0/24 -o eth0 -j MASQUERADE

預設的nat table規則是什麼?

sudo iptables -t nat -L -n

我這台機器後面有192.168.2.0/24的子網域,我想讓這些人可以正常上網。

sudo iptables -t nat -A POSTROUTING -s 192.168.2.0/24 -o eth0 -j MASQUERADE

從服務器的eth0網卡上,自動獲取當前ip地址來做NAT

更詳細關於SNAT和MASQUERADE的區別,請看這裡

為什麼是POSTROUTING? 因為封包會經過你機器route後離開,離開你機器前會先經過POSTROUTING,這時再改source IP

我想讓外面的人透過port 222連到我內部內網的port 192.168.2.1這台server的port 22,來進行ssh

sudo iptables -t nat -A PREROUTING -d x.x.x.x(你家IP) -p tcp --dport 222 -j DNAT--to-destination 192.168.2.1:22

為什麼是改PREROUTING? 因為封包到你機器進行route前會先經過preroute,這時你就可以趁天賜良機(?)的時候改掉目的地。達成NAT的效果。

BONUS:

你很害羞,不想讓所有人ping到你。

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

ping是使用icmp protocal實作的,其他的機器會對你發出echo-request,這時你要選擇無視他(Drop)。

LOG通過該規則的封包

sudo iptables ....somerule... -j LOG

要如何觀察呢?

在ubuntu上是tail -f /var/log/kern.log

匯出/匯入設定檔

sudo iptables-save > 你電腦裡的祕密小角落 sudo iptables-restore < 你電腦裡的祕密小角落

結語

以上是我的iptables學習筆記,整理成比較易讀的形式,畢竟這東西不碰大概1個月就忘光了哈哈XD。如果對你有幫助的話歡迎轉載記得附上來源就好。希望有幫助到大家!

參考資料