#キッカケ
Android端末に自動でproxy設定を行いたい。少なくとも、http-proxyのアドレスを自動で振ってやって、有効にするプログラムを書きたいので、Proxyの設定を調べてみた。(Androidアプリケーションを使って設定なんて皆やるのでadbフル活用で書きたい。)
wifiの状態を獲得するコマンドがadb shell dumpsys wifi
でproxyの設定状態を取得できる。
###基本:wifi選択画面から設定する方法
簡単。設定すると、Android標準ブラウザの通信にhttp-proxyが入る。ただし、設定値がadb shell経由で取れるか調べてない。
D/WifiConfigStore( 448): proxy changed SSID = "hogehoge"
D/WifiConfigStore( 448): proxy changed SSID = "hogehoge"
D/WifiConfigStore( 448): proxyProperties: [192.168.11.3] 8118 xl=
###基本2:ProxyDroidで設定する方法
簡単。Root化済みの端末にProxyDroid入れて設定する。しかし、ProxyDroidから設定した場合、adb shell
から設定値が見えない。
###試行:Androidのshellからsetporpで設定する方法
これもGoogle先生に聞くとでてくる。しかし、JellyBeans(4.2.2)だとどうも上手くいかない。
adb shell setporp http-proxy http://<porxy-server>:<port>
How to Use Proxy to Access Network in Androidによれば開発コードによって方法が違うらしい。
Gingerbread(2.3.x)は以下の通り。
1. Enable http proxy
> sqlite3 /data/data/com.android.providers.settings/databases/settings.db "INSERT INTO secure VALUES (99, 'http_proxy', 'wwwgate0.freescale.net:1080');"
With this setting, you can access network for web browsing.
If you want to play some http streaming content, you need to set a property for the player,
> setprop rw.HTTP_PROXY http://wwwgate0-az.freescale.net:1080
2. Disable http proxy
> sqlite3 /data/data/com.android.providers.settings/databases/settings.db "delete from secure where name='http_proxy'"
> setprop rw.HTTP_PROXY ""
ICS(Ice Cream Sandwith:4.0.x)は以下の通り。
1. Enable http proxy
> setprop net.proxy wwwgate0-az.freescale.net:1080
With this setting, you can access network for web browsing.
If you want to play some http streaming content, you need to set a proxy property for the player,
> setprop rw.HTTP_PROXY http://wwwgate0-az.freescale.net:1080
2. Disable http proxy
> setprop net.proxy ""
> setprop rw.HTTP_PROXY ""
私が使っているOSは4.2.2なので、Jelly Beans(4.1.x,4.2.x,4.3)を調べるが特に言及されてないので、Gingerbread(2.3.x)の方法を試す。sqlite3 /data/data/com.android.providers.settings/databases/settings.db
から、直にSettingの値を変えてるのではないか、と思う。
設定を変える前に、JellyBeansにsqlite3をインストールする。
1.sqlite3 をダウンロードする。
2.端末をUSB接続して、ダウンロードしたコマンドをSDカードに転送する。
adb push sqlite3 /mnt/sdcard
3.sqlite3を/system/xbin/下に置く。
>adb shell
shell@android:/ $ su
shell@android:/ # mount -o remount,rw -t yaffs2 /dev/block/mtdblock3 /system
shell@android:/ # cp /mnt/sdcard/sqlite3 /system/xbin/sqlite3
shell@android:/ # chmod 777 /system/xbin/sqlite3
shell@android:/ # mount -o remount,ro -t yaffs2 /dev/block/mtdblock3 /system
shell@android:/ # sqlite3
その後、
sqlite3 /data/data/com.android.providers.settings/databases/settings.db "INSERT INTO secure VALUES (99, 'http_proxy', 'http-server:port');"
を実行する。
何してたかというと、com.android.proviers.settingのhttp_proxyの値を直接変更していた。公式ドキュメントでは、
public static final String HTTP_PROXY
Added in API level 3
This constant was deprecated in API level 17.
Use HTTP_PROXY
Host name and port for global http proxy. Uses ':' seperator for between host and port.
Constant Value: "http_proxy"
とある。しかし、この方法では有効にならなかった。
ProxyDroidを有効にしたときに出力されるログを見ると、
D/ProxyDroidService( 4388): Service Start
D/ProxyDroidService( 4388): Proxy: 192.168.11.3
D/ProxyDroidService( 4388): Local Port: 8118
D/ProxyDroid( 4388): chmod 700 /data/data/org.proxydroid/iptables
D/ProxyDroid( 4388): chmod 700 /data/data/org.proxydroid/redsocks
D/ProxyDroid( 4388): chmod 700 /data/data/org.proxydroid/proxy.sh
D/ProxyDroid( 4388): chmod 700 /data/data/org.proxydroid/cntlm
D/ProxyDroid( 4388): chmod 700 /data/data/org.proxydroid/stunnel
D/ProxyDroid( 4388): chmod 700 /data/data/org.proxydroid/shrpx
D/ProxyDroid( 4388): Connecting start
D/ProxyDroid( 4388): /data/data/org.proxydroid/proxy.sh start http 192.168.11.3 8118 false "" ""
D/ProxyDroid( 4388): /data/data/org.proxydroid/iptables -t nat -A OUTPUT -p tcp -d 192.168.11.5 -j RETURN
D/ProxyDroid( 4388): /data/data/org.proxydroid/iptables -t nat -A OUTPUT -p tcp --dport 80 -j REDIRECT --to 8123
D/ProxyDroid( 4388): /data/data/org.proxydroid/iptables -t nat -A OUTPUT -p tcp --dport 443 -j REDIRECT --to 8124
D/ProxyDroid( 4388): /data/data/org.proxydroid/iptables -t nat -A OUTPUT -p tcp --dport 5228 -j REDIRECT --to 8124
D/ProxyDroid( 4388): Connecting finish
D/ProxyDroid( 4388): /data/data/org.proxydroid/iptables -t nat -F OUTPUT
D/ProxyDroid( 4388): /data/data/org.proxydroid/proxy.sh stop
とあって、直接settingするというよりも、iptablesを設定している模様。iptablesをadb shell経由で設定すれば、できるのかな。
手動でlogcatに出てきたログを実行すると、
protoent* getprotobyname(char const*)(3) is not implemented on Android
というエラーが出てきた。
前述のログから、設定前に/data/data/org.proxydroid/proxy.sh start http 192.168.11.3 8118
を行ってるから、proxy.shのコードを読み変える読む。
#!/system/bin/sh
DIR=/data/data/org.proxydroid
type=$2 =http
host=$3 =192.168.11.3
port=$4 =8118
auth=$5 =false
user=$6 =""
pass=$7 =""
($1=start)
PATH=$DIR:$PATH
case $1 in
start)
echo "
base {
log_debug = off;
log_info = off;
log = stderr;
daemon = on;
redirector = iptables;
}
" >$DIR/redsocks.conf
case $type in
http)
case $auth in
true)
echo "
redsocks {
local_ip = 127.0.0.1;
local_port = 8123;
ip = $host;
port = $port;
type = http-relay;
login = \"$user\";
password = \"$pass\";
}
redsocks {
local_ip = 127.0.0.1;
local_port = 8124;
ip = $host;
port = $port;
type = http-connect;
login = \"$user\";
password = \"$pass\";
}
" >>$DIR/redsocks.conf
;;
<-- 今回はここ以下の設定 -->
false)
echo "
redsocks {
local_ip = 127.0.0.1;
local_port = 8123;
ip = $host;
port = $port;
type = http-relay;
}
redsocks {
local_ip = 127.0.0.1;
local_port = 8124;
ip = $host;
port = $port;
type = http-connect;
}
" >>$DIR/redsocks.conf
;;
esac
;;
<-- 今回はここまでの設定 -->
socks5)
case $auth in
true)
echo "
redsocks {
local_ip = 127.0.0.1;
local_port = 8123;
ip = $host;
port = $port;
type = socks5;
login = \"$user\";
password = \"$pass\";
}
" >>$DIR/redsocks.conf
;;
<-- 今回はここ以下の設定 -->
false)
echo "
redsocks {
local_ip = 127.0.0.1;
local_port = 8123;
ip = $host;
port = $port;
type = socks5;
}
" >>$DIR/redsocks.conf
;;
esac
;;
<-- 今回はここまでの設定 -->
socks4)
case $auth in
true)
echo "
redsocks {
local_ip = 127.0.0.1;
local_port = 8123;
ip = $host;
port = $port;
type = socks4;
login = \"$user\";
password = \"$pass\";
}
" >>$DIR/redsocks.conf
;;
<-- 今回はここ以下の設定 -->
false)
echo "
redsocks {
local_ip = 127.0.0.1;
local_port = 8123;
ip = $host;
port = $port;
type = socks4;
}
" >>$DIR/redsocks.conf
;;
<-- 今回はここまでの設定 -->
esac
;;
esac
$DIR/redsocks -p $DIR/redsocks.pid -c $DIR/redsocks.conf
;;
stop)
killall -9 redsocks
killall -9 cntlm
killall -9 stunnel
killall -9 tproxy
kill -9 `cat $DIR/redsocks.pid`
rm $DIR/redsocks.pid
rm $DIR/redsocks.conf
esac
resocksのファイルタイプは
redsocks: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked (uses shared libs), stripped
どっちにせよ、redsocks.confを調べないとわからない。
ProxyDroidを見る限りだと、proxy設定はデフォルトのandroidでは難しそう。。
###参考
Android 端末上で透過型プロキシを動かしてみる 〜 VPN のように使えて、しかも省電力
WiFi接続とHTTP-Proxyを取り巻く状況まとめ(2011-05現在)
Root for Android
脳みそタンス