修復 OpenWRT 上 Clash(OpenClash)影響 Port Forwarding 的問題

  1. 入手 Linksys WRT1900AC 作爲 AP,刷 DD-WRT 固件
  2. 闖入聯通定製烽火 HG220G-U(WO-36)
  3. 也許是最折騰的(隨身)迷你伺服器:計劃
  4. 也許是最折騰的(隨身)迷你伺服器:軟體
  5. 也許是最折騰的(隨身)迷你伺服器:裝機
  6. 在國科大(UCAS)宿舍配置 IPv6 穿透
  7. 斐訊 K3 上車,開啓 Telnet、刷已 Root 版官方固件和 Merlin
  8. 使用 bind9 建置混合 DNS(Response Policy Zone)
  9. 斐訊 K2T 開箱與動手艹(動手玩)
  10. Huawei B315s-936 4G LTE CPE 開箱與動手玩
  11. 透過 VLAN 從不同出口獲得 IPv4/IPv6 地址構建雙棧網路
  12. 關於半夜艹貓的這檔事:中興 ZTE ZXHN F677V2 ONT 設定橋接
  13. 修復 OpenWRT 上 Clash(OpenClash)影響 Port Forwarding 的問題
  14. 在 OpenWRT 上正確開啓網易 UU 加速器
  15. 在 Proxmox VE 上使用 LXC 建置 UU 加速器

透明代理是個好東西。隨着技術的發展,一些老的工具逐漸體現出各種問題並停止維護,浅羽終於也更換到了基於 Clash 包裝的 OpenClash。雖然 Clash 本身有一些爭議,但配合 OpenClash 使用 LuCI 加上網路上的規則,稍加自定就很獲得不錯的使用體驗,只有一個最大的問題——無論如何都無法連線家中的 VPN 伺服器。

浅羽的 VPN 伺服器並沒有直接架設在 OpenWRT 上,而是位於區域網路內 192.168.0.2 上並透過 port forwarding 接受外部連線。起初浅羽以爲是 port forwarding 及 firewall 設定問題,但幾經調整都無果。偶然查看了 VPN 伺服器的日誌,才發現客戶端其實已經與伺服器取得連線,卻因 TLS handshake timeout 無法成功認證。回想近期對網路的調整,浅羽開始懷疑 Clash 的問題,於是增加了一條 SRC-PORT,1194,DIRECT 規則,並在 Clash 中觀察到也已經直接連線,但客戶端依然提示連線失敗。

透過搜尋工作,浅羽找到並參考了一些相關的問題報告:

其中有回覆提到:

@neroanelli 分析的挺对的,就是包来回的路径不一样。SYN 通过主路由直接发到内网机器上,SYN ACK 发给Clash了,除非 Clash 使用 Raw Socket 特别处理这样的数据包,否则 Clash 没有任何办法处理此类 SYN ACK。

同時有幾位評論者都指出:在 mangle 表中增加規則過濾不希望經過 Clash 的流量可以解決問題。那麼按這個思路在 OpenWRT 上的 iptables 增加一條規則,匹配 host 與 port,使相關流量直接從 PREROUTINGRETURN

# iptables -t mangle -I PREROUTING -p udp -s 192.168.0.2 -m multiport --sports 1194,51820 -j RETURN

確認一下規則生效並且排在 Clash 相關規則前:

# iptables -t mangle -L PREROUTING
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination
RETURN     udp  --  192.168.0.2          anywhere             multiport sports openvpn,51820
openclash  all  --  anywhere

再在客戶端嘗試一下就可以成功連線了,同時訪問區域網路及使用透明代理都沒有問題。


總要一邊一邊地刪除加入防火牆規則非常麻煩,如果遇到不在家中、VPN 又連線不上的情況就更惱火了。那麼有什麼辦法可以在 Clash 重新啓動之後自動修改好防火牆規則呢?

研究一下 OpenClash 包裝的規則,主要的啓動和停止都寫在 luci-app-openclash/root/etc/init.d/openclash 中,其中在 set_firewall() 函式中主要處理了防火牆規則的增加。因此在函式最後添加上幾句:

iptables -t mangle -I PREROUTING -p udp -s 192.168.0.2 --sport 1194 -j RETURN
iptables -t mangle -I PREROUTING -p udp -s 192.168.0.2 --sport 51820 -j RETURN

順便在 revert_firewall() 函數最後也添加相反的指令:

   iptables -t mangle -D PREROUTING -p udp -s 192.168.0.2 --sport 51820 -j RETURN
   iptables -t mangle -D PREROUTING -p udp -s 192.168.0.2 --sport 1194 -j RETURN
   # 爲什麼縮進是三個空格?

這樣最起碼 Clash 重新啓動時不會把自己擋在家門外了。

11

發表於

發表在

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

此網站使用 Akismet 以減少垃圾留言。 瞭解你留言資料會被如何處理.