我家裡的桌機有兩個有線網路,一個是 HiNet 光世代,另外一個是社區網路 (其實出去也是光世代),像是這篇提到的架構 (只是當時還住在後山埤,另外那條是北都的第四台網路):「Ubuntu 下面搞 Multi-home 架構」。
我在上面那篇提到要怎麼以 source ip address 來決定 routing,然後我就可以跑 Squid,並且在 Squid 上面指定 source ip 來達到目標。
後來有做了一些改變,最主要是換成 microsocks。
一個原因個是 Squid 比較「重」(heavy),microsocks 比較清量;第二個是 Squid 走的 CONNECT
支援的程式比較少,SOCKS 支援度高一些。
不過當 HiNet 線路有問題的時候,會發現 DNS 的查詢失敗,主要的原因是 microsocks 會讀 /etc/resolv.conf
的資料,裡面是 168.95.192.1
與 168.95.1.1
,而且 microsocks 呼叫的 getaddrinfo()
沒有 IP binding,還是會試著走原來的線路出去。
所以這邊就得想辦法把 /etc/resolv.conf
換成我們自己加工的版本,這邊我用了 bubblewrap 來做:
/usr/bin/bwrap --unshare-all --share-net --ro-bind /usr /usr --ro-bind /lib /lib --ro-bind /lib64 /lib64 --ro-bind ~/microsocks/resolv.conf /etc/resolv.conf /usr/sbin/microsocks -i 0.0.0.0 -p 11080 -b 192.168.2.123
先把所有東西都隔開 (--unshare-all
),再把網路開通 (--share-net
),接著把 /usr
、/lib
以及 /lib64
掛上來 (因為 microsocks 需要這些 library),然後 /etc
下的東西只掛了一個自己建的 /etc/resolv.conf
上來,裡面指到 router 上 (我的 router 有 DNS proxy):
nameserver 192.168.2.254
這邊因為是 subnet traffic,自動選定的 source ip 會是本機 192.168.2.x 的 IP,就剛好避開這個問題,這樣無論 HiNet 線路的情況都不會影響到 microsocks 了。
這邊有個小插曲,因為追問題所以用 strace 看了半天才發現一開始我用 bubblewrap 時是這樣寫:
/usr/bin/bwrap --bind / / --bind ~/microsocks/resolv.conf /etc/resolv.conf /usr/sbin/microsocks -i 0.0.0.0 -p 11080 -b 192.168.2.123
結果發現 microsocks 第一次讀 /etc/resolv.conf
的時候的確是讀到 ~/microsocks/resolv.conf
,但網路斷掉後 (/etc/resolv.conf
會被改動) 他會讀到原始的 /etc/resolv.conf
(i.e. 沒有被替換掉),判讀 strace log 到這邊的時候差點罵出來... @_@
沒有往下追的太細,但猜測可能是 --bind / /
與 --bind ~/microsocks/resolv.conf /etc/resolv.conf
有處理上的衝突?總之我後來改成 --unshare-all
,再把要掛的東西掛上去,就沒這個問題了...