動機

記錄下自己怎麼看待iptables

iptables把firewall的功能與network stack緊緊地結合在一起 所以有的時候會看不懂到底發生甚麼事,也不好寫出自己想要的rule 故在此寫下自己的看法

table : something like java’s interface

firewall的功能有二

  1. 接受/拒絕pkt
  2. 修改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

一個封包進入主機,會判斷

  1. 我該處理嗎? <= 所以有兩個chain
  2. 最後再丟出去。

所以有

  1. PREROUTING
  2. INPUT
  3. FORWARD
  4. OUTPUT
  5. 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對起來

  1. NF_IP_PRE_ROUTING
  2. NF_IP_LOCAL_IN
  3. NF_IP_FORWARD
  4. NF_IP_LOCAL_OUT
  5. NF_IP_POST_ROUTING

function & jump

每個chain都有許多rule,而這些rule就可以想成一般寫程式的指令 以剛剛的想法為基礎,這些chain就可以想像成function!!

但是不同於一般的function被call完後會自動回到的被call的位置

chain中的rule只要碰到ACCEPT/DROP/REJECT/QUEUE其中一個action,就不會繼續往下跑 其他都是繼續往下走,如果沒有rule可以執行,就會觸動chain的預設action

順便提一下

  1. 自定義的chain的預設action是RETURN,就是我們熟悉的return
  2. 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有兩種

  1. connmark (ctmark)
  2. mark (nfmark)

一個是針對connection的一個是針對個別封包的

除了基本的set-mark 還有

  1. save-mark: 把mark寫到connmark
  2. restore-mark: 把connmark寫到mark

Ref

十分詳細必看