用 bubblewrap (bwrap) 針對特定程式抽換 /etc/resolv.conf

我家裡的桌機有兩個有線網路,一個是 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.1168.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,再把要掛的東西掛上去,就沒這個問題了...

Leave a Reply

Your email address will not be published. Required fields are marked *