You are here: Home > 技術…… > 總算把Iodine的Android版搞定了

總算把Iodine的Android版搞定了

14號把Iodine的服務器架起來之後,就一直想讓手機也享受到這個東西(其實這纔是主要目的阿,否則就真的只能玩玩而已)。

結果搞了兩個晚上(工作日的白天我可是有好好在幹活的)加今天一整個白天,終于被我搞出來了,其中彎路無數……

Iodine的主葉有個連接:SupportedPlatforms,裏面赫然寫著:Android,並且連接到這裡。我很高興,把它下載下來,按照上面的腳本一條條手動執行(腳本的很多地方和我的手機環境不符,懶得一個個改了,還不如挑有用的執行)。首先踫到的一個坎是這麽一行: insmod tun.ko。這個tun.ko已經附帶在剛剛下好的包裏面了。好吧,查了查insmod是啥意思,然後一執行,說我下下來的tun.ko不能識別,好,死馬當作活馬騎,先跳過去看看。

然後終于到跑iodine客戶端了,根據腳本和在windows下的參數對照一跑,居然說我協議版本號不對,要我放棄(iodine you use protocol v 0x00000500, server uses v 0x00000502. giving up)……在Iodine的頁面上亂撞了一陣,幾乎每個連接都點開過之後,不得不決定:好吧,自己下源代碼來編譯算了……沒有辦法,誰叫我是程序員呢- -b。Android畢竟不是標準的Linux,再説了,就算是大的Linux發行版之間也沒有做到二進制兼容阿。但是要我在Windows環境下編譯一個Linux程序出來,光編譯環境就夠我搭一陣的。不管怎樣,還是把源代碼下下來了,發現怎麽也看不懂,也不知道該怎麽編譯。編譯腳本是我最頭痛的Make,而且看樣子既能編出windows版本來也能編出各種Linux版本……後來我還發現,Iodine的svn版本庫和我下下來的版本還不一樣,裏面多了個Android.mk文件。打開一看,還是我看不懂的make,不過有一個鏈接,進去后發現說得很詳細,如何搭建環境如何編譯……讓我最高興的是,文章最後附帶了一個編譯好的iodine安卓客戶端的連接!

這個新的iodine客戶端在我手機上跑得很順利,看起來也很正常。這下我手機上多了一個叫dns0的網卡,並且也拿到了正常的内網IP10.1.3.2,不過就是ping不通服務器網関(10.1.3.1)……我想trace一下,卻告訴我沒有tracert這個命令……於是我就想各種原因,是不是之前的tun.ko沒有跑起來的原因?於是上網搜,後來才發現原來我的rom本來就有tun.ko。然後又想,是不是DNS的原因?我nslookup了一下,發現nslookup失敗。DNS服務器沒有設。但是我ping各種域名又沒有問題。開始懷疑我的路由器是不是做了什麽手腳,於是手動在wifi設置界面設置DNS,還是不行。於是自己改/etc/resolv.conf,nslookup終于出來了,不過還是ping不通服務器内網網関。認真看了看後來那個客戶端腳本,他設的路由表的思路是這樣的:先把DNS主機指向原來的網関,然後把默認網関改爲内網網関。問題是我現在内網網関都ping不通啊,搜了一大圈后無意中發現原來linux下的trace命令是traceroute……趕緊trace,確認一個事實:去10.1.3.1的包,還是走了我的路由器網関192.168.1.1……於是各種搜,看看Andriod是怎麽設路由的……因爲我之前就發現Andriod的DNS是設在net.dns1和net.dns2屬性裏面的,並不用像普通的linux裏面設在/etc/resolv.conf裏面,那麽路由表也會是這樣麽?還是設在別的某個Andriod特有的文件裏面呢?其間熟悉了不少linux命令,但是還是一無所獲。也知道了一些事情,例如linux支持256張路由表啦,路由表的各種Flag是什麽意思啦等等。後來無意中看到GTalk裏面snnn同學在綫,聊了一下,他基本上確認是路由的問題,iodine本身應該沒有問題的,他有一句“会不会设置了多个默认路由?”我覺得應該是這樣,不過我當時一下子沒有完全反應過來。後來上網搜Linux雙網卡的各種配置,包括内外網的,電信網通綫路的。有的時候提到ip rule,之前我也搜到過這個,不過不是很明白,然後忽然想到,認真查了一下,我再看我手機的ip rule,如下:

1
2
3
4
5
#ip rule
0:           from all lookup local
3001:    from all lookup wifi
32766:  from all lookup main
32767:  from all lookup default

而用route命令改的路由表,事實上改的是main。於是我用ip route命令,把10.1.3.0/27的路由在wifi表裏面一改,就ok了……其實只要能連上我的服務器,能ssh,別的我就可以不管了。

爲了通用一些(好吧,是我的潔癖,事實上,按道理來説,除了wifi應該也不會有別的了),我決定不直接改wifi表,而是加了一張路由表,在/system/etc/iproute2/rt_tables文件最後加上一行:251 iodine

於是最後,我寫了兩個腳本:

iod.sh:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
echo "Starting iodine client ..."
#Configuration
NS="abc.def.ghi"             #iodine的域名……
NSIP="173.255.214.56"  #服務器IP
PWD="password"            #在服務器跑iodined的時候設的密碼
TUN="10.1.3.1"                 #在服務器跑iodined的時候設的内網地址,之前用的172的,後來改爲10段的了
TUNNET="10.1.3.0/27" #iodined分配的内網網段。iodine默認就是27位子網
DNS=`getprop net.dns1`#默認的DNS
DEV="eth0"                       #默認網卡
GW=`ip route show | grep default.*$DEV | awk '{ print $3 }'`   #默認網関

echo "DNS Server: $DNS"
echo "Gateway $DEV: $GW"#Start iodine client

if iodine -r -P $PWD $NSIP $NS; then   #連接iodine

ip route add $DNS via $GW table iodine    #往iodine路由表加上DNS的路由
ip route add $TUNNET dev dns0 table iodine #往iodine路由表裏面加上内網網段的路由,都從dns0網卡走
ip rule add table iodine pref 2000 #把iodine路由表加進ip rule裏面……,優先級是2000,因爲wifi是3001,而VPN是2500,這個要在VPN的前面。
echo "Ready"
fi

停止Iodine就簡單多了:

iodstop.sh

1
2
3
4
5
6
echo "Stopping iodine client ..."
DNS=`getprop net.dns1`
killall iodine
ip route del $DNS table iodine
ip rule del table iodine
echo "Ready"

不過後來經過測試,發現用10.1.3.1連VPN,連上幾秒就斷,不知道爲什麽。可能是和IP有關。因爲設置VPN的時候,好幾個地方都要填VPS的公網IP的。可能這樣子設置就只能通過公網連了吧。

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注