環境: Android:CyanogenMod 6.1.1, PC:Ubuntu 10.10
逆USBテザリングをブリッジ接続で行うと、不便が生じた。
- テザリングを止めるとき、PC側でブリッジ削除スクリプトを実行する必要がある。
- ブリッジ削除スクリプトを実行しないとPC側の通信ができなくなる。
それに、Androidにsshで入りたいわけでもないので、AndroidのIPアドレスがLAN内で見える必要もないし。
ということで、NATを利用する方法を考えた。この方法ならば、いつUSBを抜いてもPC側の通信には影響がない。
まずPC側のIP Forwardを有効にする。
/etc/sysctl.conf:
net.ipv4.ip_forward=1
sysctl -p で反映。sysctl.confを変更せずに一時的に試すなら、
sysctl -w net.ipv4.ip_forward=1 で。
次にiptablesの設定。
iptables -A INPUT -j ACCEPT
iptables -A OUTPUT -j ACCEPT
iptables -A FORWARD -i usb0 -j ACCEPT
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
Ubuntuでiptablesの設定をOS起動時に有効にするには、自分でスクリプトを書く必要がある。私は /etc/rc.local に次のように書いている。
/etc/rc.local:
#!/bin/sh -e
/sbin/iptables-restore < /etc/iptables-rusbnat.rules
iptables-rusbnat.rules は上記の設定を行った後に iptables-save > iptables-rusbnat.rules で作った。
ここまで一度設定すれば良い。
以下はテザリングを有効にする度にPC側で実行するもの。
Android側ではやることはテザリングの設定を有効にするだけ。
停止するときはAndroidでテザリングの設定を無効にする。PC側は何もする必要がない。
rusbtether-nat:
#!/bin/sh
set -e
export LANG=C
ROUTE=/system/bin/route
GWA=`LANG=C ifconfig usb0 | grep "inet addr:" | \
sed 's/ *inet addr:\([0-9\.]\+\).*$/\1/'`
if [ "$GWA" = "" ]; then
echo exit
exit 1
fi
ping -I usb0 -c 1 $GWA > /dev/null
# add route
adb shell su -c "$ROUTE add default gw $GWA dev usb0"
DNS=`grep nameserver /etc/resolv.conf | head -n1 | awk '{print$2}'`
# clear dns
for p in net.dns1 net.dns2 net.dns3 net.rmnet0.dns1 \
net.rmnet0.dns2 dhcp.eth0.dns1 dhcp.eth0.dns2 \
dhcp.eth0.dns3 dhcp.eth0.dns4 net.eth0.dns1 \
net.eth0.dns2 net.usb0.dns1 net.usb0.dns2; do
adb shell su -c "setprop $p ''"
done
# set dns
adb shell su -c "setprop net.dns1 $DNS"
echo Completed
なお、AndroidのDNSを再設定するところはブリッジ接続の方法と変わらないので、テザリング中にWiFi/3GをONしない方が良い。
ONにした場合DNSの設定が変わって名前解決できなくなるが、再度 rusbtether-nat を実行すれば解決できるようになる。
Android側に付くアドレス 192.168.42.129 は固定のようだ。com.android.server.connectivity.Tethering にハードコーディングされていた。
0 件のコメント:
コメントを投稿