動機
記錄下自己怎麼看待iptables
iptables把firewall的功能與network stack緊緊地結合在一起 所以有的時候會看不懂到底發生甚麼事,也不好寫出自己想要的rule 故在此寫下自己的看法
table : something like java’s interface
firewall的功能有二
- 接受/拒絕pkt
- 修改pkt
所以firewall會改pkt的內容(mangle,nat),之後根據使用者的rule做接受/拒絕(filter) 最後再return (先不算中間直接離開的情況)
整個流程大概像
mangle -> nat -> filter <= 這段是進入
|
\ /
mangle <- nat <- filter <= 這段是出去
同樣都是修改pkt,因為nat太常用了就被獨立出來
table可以當成pkt在firewall中是怎麼被處理的概述,很像OO的interface pkt會被某種程度的改動 => mangle 在sport/dport/sip/dip改動 => nat firewall的business rule => filter
chain
all about routing
一個封包進入主機,會判斷
- 我該處理嗎? <= 所以有兩個chain
- 最後再丟出去。
所以有
- PREROUTING
- INPUT
- FORWARD
- OUTPUT
- POSTROUTING
寫成code
PREROUTING()
if this_pkt_is_for_this_host():
INPUT()
OUTPUT()
else:
FORWARD()
POSTROUTING()
把chain與table組合一下就是wiki的這張圖
Netfilter Hooks
當pkt在network stack中流動時,會觸發netfilter的hook,再調用註冊再裡面的函數對pkt做處理 可以看到每個hook都可以與上面的五個chain對起來
- NF_IP_PRE_ROUTING
- NF_IP_LOCAL_IN
- NF_IP_FORWARD
- NF_IP_LOCAL_OUT
- NF_IP_POST_ROUTING
function & jump
每個chain都有許多rule,而這些rule就可以想成一般寫程式的指令 以剛剛的想法為基礎,這些chain就可以想像成function!!
但是不同於一般的function被call完後會自動回到的被call的位置
chain中的rule只要碰到ACCEPT/DROP/REJECT/QUEUE其中一個action,就不會繼續往下跑 其他都是繼續往下走,如果沒有rule可以執行,就會觸動chain的預設action
順便提一下
- 自定義的chain的預設action是RETURN,就是我們熟悉的return
- QUEUE會把pkt轉到userspace
DROP/REJECT
都是丟到pkt,但是REJECT還會回傳訊息給sender
connection state
if is_tracked(): # 1. 要不要track
if is_nat(): # 2. 是不是nat
if is_from_dnat():
return DNAT()
else:
return SNAT()
else:
if is_from_existing_conn():
return ESTABLISHED()
elif is_related_to_existing_conn():
return RELATED()
else:
try:
return NEW()
except:
return INVALID()
else:
return UNTRACKED() #這個與raw有關
mark: custom state
mark有兩種
- connmark (ctmark)
- mark (nfmark)
一個是針對connection的一個是針對個別封包的
除了基本的set-mark 還有
- save-mark: 把mark寫到connmark
- restore-mark: 把connmark寫到mark