執行人: gawei1206
專題解說錄影
SuNsHiNe-75
好奇此 Netfilter 可過濾哪些傳輸協定(如 UDP、TCP)的封包,連 QUIC 的封包都能過濾嗎?
gawei1206
關於這個問題我可能要再確認一下
yinghuaxia
規則放置在特定 table 的特定 chain 裡面。當 chain 被呼叫的時候,封包會依序比對 chain 裡面的規則,根據封包的資料比對先前定義的規則內容,若封包資料與規則內容相同則進行動作,否則就繼續下一條規則的比對。
這裡所說的規則為何?而 chain 是如何被呼叫的?在什麼情況下會呼叫特定的 chain?根據封包的資料比對是比對哪些條件?
gawei1206
這邊所說的規則是用來定義如何處理封包的具體指令。每條規則包含一個符合條件和一個動作,像以下這條規則
$ sudo iptables -A OUTPUT -o enp3s0f1 -d 103.31.6.33 -j REJECT
條件(-o enp3s0f1 -d 103.31.6.33):表示發送至 103.31.6.33 的封包,並且這些封包透過介面 enp3s0f1 發送
目標動作(-j REJECT):表示拒絕這些封包
OUTPUT : 當封包從本地主機發送出去時呼叫
nosba0957
封包處理是在哪個 hook 處理?還是 5 個 hook 都有對應處理?
gawei1206
這邊的是在NF_IP_LOCAL_OUT
steven523
我看去年同樣做這個主題的學員沒有成功阻擋 HTTPS 類型的廣告,請問你有嘗試用什麼方法成功阻擋過嗎
jujuegg
在阻擋廣告的方法中,你提到的 2 個辦法都需要得知特定廣告伺服器的網域名稱,請問現在有甚麼方法可以一次性的阻擋掉所有廣告的封包嗎?
在 Linux v6.8 重現透過 Netfilter 自動過濾廣告實驗,並修正對應的程式碼。
可重用去年報告的素材,但要更新到 Linux v6.8+
Netfilter 是 Linux 核心中的一個框架,用於處理封包內容修改及過濾,我們可以透過 iptables 告訴 Netfilter 如何處理接收到的或是準備發送出去的封包。
iptables 他會透過分析封包的表頭資料來進行封包的過濾,根據表頭資料與我們自己定義的規則來決定該封包是否可以進入主機或者是被丟棄。
介紹 netfilter,應該闡述 Linux 核心的封包處理流程。參見本學期教材 Linux 核心網路
不要捨近求遠,本課程教材已經整理很多關鍵概念,避免學員研讀網際網路上面一堆品質低劣的簡體中文素材。
Netfilter 提供了 5 個 hook,當封包經過這些 hook 時我們可以對封包進行過濾或是修改內容。
NF_IP_PRE_ROUTING
是在做 Routing 之前的 hook
NF_IP_LOCAL_IN
是在把封包傳遞到 local process 之前的 hook
NF_IP_FORWARD
是在把封包傳遞到別的 network interface 之前的 hook
NF_IP_POST_ROUTING
是在做 Routing 之後的 hook
NF_IP_LOCAL_OUT
是從 local 往外傳遞的封包的 hook
每個 hook 的位置可以參考下圖:
iptables 中有一系列的 table,並根據要用來做什麼分為不同的 table,在每個 table 中,規則被進一步組織成 chain。
這邊以 filter 來介紹,最常用的 table 之一,用來判斷是否允許一個封包通過。
filter :主要跟進出 Linux 本機的封包有關
規則放置在特定 table 的特定 chain 裡面。當 chain 被呼叫的時候,封包會依序比對 chain 裡面的規則,根據封包的資料比對先前定義的規則內容,若封包資料與規則內容相同則進行動作,否則就繼續下一條規則的比對。
要解釋為何過濾的條件可讓 Linux 核心處理封包時,予以生效且可持續適用。中間有非常多細節,詳見 Linux 核心文件。
在過濾廣告之前,我們要先要知道廣告是如何成現在網頁上的:
阻擋廣告的方法
根據上面的流程我們不難發現,只要在步驟 3 的地方多加注意,則可以將向廣告伺服器送出的請求給阻擋下來,使得廣告最後不會成現在瀏覽的網頁上,我們通過以下方法可以阻擋向廣告伺服器的請求:
/etc/hosts
檔案:將提供廣告服務的網域映射到本地(127.0.0.1),這樣請求就不會發送到廣告伺服器。在 Linux v6.8+ 重現實驗,並修正對應的程式碼。紀錄相關問題
更新到 6.8.0-35-generic 後不能正常開機,問題尚未解決,所以目前是在 recovery mode 上使用
嘗試透過 ZhuMon 先前有實作過的方式將網域 mapping 到 localhost
注意用語:
首先我們可以更改 /etc/hosts
檔案,將網域映射到 localhost 上,廣告的網域可以參考 adblock.txt,也可以觀察常用網站的廣告來源,再自行加上。
這使得當瀏覽器嘗試訪問 itadapi.ithome.com.tw
時,被指向 localhost,從而阻擋廣告。
我們也可以 ping
看看,可以看到 itadapi.ithome.com.tw
確實映射到 localhost
接來我們可以看網頁上的效果,這邊以 OP.GG 當範例
原本的網站,可以看到廣告非常多
將網域映射到 localhost 後
查看去年 ItisCaleb 的 Netfilter-Adblock,根據他的說明依序操作,但目前無法找到 libnetfilter-dev 套件並安裝
參考之前都有提到的 Use the iptables firewall to block ads on your Linux machine 的作法。
從先前的敘述我們可以知道要過濾封包的話,應該要在本機向廣告伺服器發送封包後,所以這邊要對 filter table 中的 OUTPUT chain 中新增規則。
可以參考這個規則作為測試
範例:
將 rule 加到指定 chain 的最後,這邊是加到 filter table 的 OUTPUT chain 中,如果封包的目標的 IP 在 table 中,則會把封包拒絕傳出。
先以 ifconfig
確認網路介面的名稱,再把剛剛下載下來的 script 放到 /etc/network/if-up.d
底下修改並啟用,我自己也有新增一些規則。
我們可以列出 filter table 已經加入的規則。
再 ping
看看加入的網域,可以看到我們與廣告網域的連線將會逾時,以這種拒絕與特定網域傳送封包的方法來達到過濾廣告的效果。
但在以 iptables 過濾廣告這部份的效果沒有很好,
避免說「沒有很好」,應該明確說廣告數量、網址類型的落差等量化資訊,理工人說話要精準且有效。
以前面測試的網站去測試,還是會看到許多廣告,也可能是腳本中加入的規則沒有網頁上的廣告來源,後來我嘗試把網頁上的廣告網域加上,但同時也發現一個問題,對於有些網域即使我把他加入到了規則中,但卻無法阻止與他的連線,這部份可能還要再想一下原因。
去年的報告已解釋相關原因,注意看。
參考資料: