2026年1月5日 星期一

[IT Network]如何配置反向路徑過濾器(rp_filter),以解決路由不對稱問題?


前陣子開始在樹莓派中安裝Rocky Linux OS,基於個人方便使用,一併部署Tailscale並建置Subnet Router,便於由外網連到樹莓派作業。經過一段時間使用,發現一個現象,當在同一個區域網路(LAN)內,電腦若啟動Tailscale往往無法透過內部區網IP直接SSH連線到樹莓派,同時也無法ping到內部區網IP。經查詢,才了解有一個反向路徑過濾(rp_filter)機制需要適當配置模式,Linux 核心才會依照模式處理封包和路徑。另外,Rocky Linux OS和Ubuntu的rp_filter預設值不同,所以之前ssh 連線到Ubuntu沒有發現該現象。

本文說明反向路徑過濾(rp_filter)的機制,以及如何透過調整Linux 核心的"反向路徑過濾(rp_filter)"配置,達到內部區網(不需啟動Tailscale)和外網(需啟動Tailscale)環境下,均能順利連線的效果。


一、反向路徑過濾 (rp_filter) 原理詳解

1. 機制原理

反向路徑過濾 (Reverse Path Filtering, 簡稱 rp_filter) 是 Linux 核心中用於防止 IP 欺騙 (IP Spoofing) 的一種防護機制。

當 Linux 主機收到一個封包時,它不僅檢查封包的目的地 IP 是否為自己,還會進行一項「反向路徑」檢查:

  • 邏輯: 系統會查看路由表,詢問「如果我要回覆這個來源 IP,我會從收到該封包的同一個網路介面(網卡)發送出去嗎?」
  • 目的: 如果發現回傳路徑與進入路徑不符(稱為不對稱路由),系統會懷疑該封包來源是偽造的,進而將其丟棄。

2. 模式分類說明

Linux 提供了三種模式,透過 /proc/sys/net/ipv4/conf/*/rp_filter 進行設定:

3. 如何查看現有模式

執行以下指令查看目前系統中所有網卡的設定值。

sysctl -a | grep rp_filter

或直接讀取特定檔案(以 end0 為例)

cat /proc/sys/net/ipv4/conf/end0/rp_filter

4. 使用情境

  • 嚴格模式(Strict): 適用於只有單一網卡的伺服器,直接暴露在公網時提供最強防禦。
  • 鬆散模式(Loose): 適用於多網卡環境、使用 VPN (Tailscale/WireGuard) 或多線路負載平衡的設備。

二、為何 Tailscale 環境需要調整 rp_filter?

在該現象中,衝突點在於 「不對稱路由 (Asymmetric Routing)」

  1. 環境背景: 樹莓派同時擁有實體網卡(end0wlan0)與虛擬網卡(tailscale0)
  2. 問題發生: 當在內部區網的電腦透過內網IP連線樹莓派時,封包從end0wlan0進入。
    • 樹莓派內部因已有Tailscale的路由規則,系統可能認為回覆路徑應該優先考慮 Tailscale tunnel。
    • Strict Mode (1) 發現:「封包從end0wlan0進來,但我回覆時可能會走其他邏輯」,於是判斷封包為非法並丟棄。
  3. 現象: 這就是為什麼發現"必須先啟動電腦的Tailscale(即建立點對點隧道)後,才能讓路徑一致化"。

三、解決方式:

將 rp_filter 設為鬆散模式 2 (Loose),允許樹莓派即使在路徑不對稱的情況下(從實體網卡進,但具備 VPN 路由),能正常回覆內網請求。

1. 將rp_filter設定為鬆散模式 2 (Loose)

將全部與預設rp_filter統一設定為 2,讓未來新增的VPN模式也被預設為鬆散模式。

sudo sysctl -w net.ipv4.conf.all.rp_filter=2
sudo sysctl -w net.ipv4.conf.default.rp_filter=2

針對目前正在運作的實體網卡(有線與無線)也一併設定

sudo sysctl -w net.ipv4.conf.end0.rp_filter=2
sudo sysctl -w net.ipv4.conf.wlan0.rp_filter=2

2. 建立永久設定檔

為了防止重新開機後設定失效,我們在 /etc/sysctl.d/ 目錄下建立設定檔,並確保留核心轉發功能開啟,以維持 Subnet Router 的穩定性。

cat <<EOF | sudo tee /etc/sysctl.d/99-tailscale-safety.conf
# 允許不對稱路由,解決內網連線衝突
net.ipv4.conf.all.rp_filter = 2
net.ipv4.conf.default.rp_filter = 2
net.ipv4.conf.end0.rp_filter = 2
net.ipv4.conf.wlan0.rp_filter = 2

# 開啟 IP 轉發(Subnet Router 必備)
net.ipv4.ip_forward = 1
EOF

3. 立即套用設定

執行下列指令讓剛才寫入檔案的設定立即生效,不需重開機,配置完成後查詢結果如下圖。

sudo sysctl -p /etc/sysctl.d/99-tailscale-safety.conf



四、測試與驗證

配置完成後,分別在內部區網(不需啟動Tailscale)和外網(需啟動Tailscale)環境下測試效果。

情境 A:內部區網測試

  1. 動作: 關閉電腦的Tailscale,確保電腦與樹莓派連接著同一個路由器。
  2. 指令: ssh <使用者名稱>@192.168.x.y
  3. 預期結果: 應立即連上,且 ping 192.168.x.y 回應延遲極低(<5ms),表示流量直接走實體區域網路,未經過 VPN。

情境 B:外網測試

  1. 動作: 將電腦連線至手機熱點(模擬外網環境),並開啟電腦的Tailscale。
  2. 指令: ssh <使用者名稱>@192.168.x.y
  3. 預期結果: 應能連上,表示Tailscale Subnet Router成功將封包透過tunnel轉發至內部區網的樹莓派。


除了達到內部區網(不需啟動Tailscale)和外網(需啟動Tailscale)環境下皆可順利連線的效果之外,另外,尚可進一步配置防火牆規則,例如設置特定網段才能連接ssh埠,一併兼顧資安疑慮。 


沒有留言:

張貼留言