やりたいこと
- USの家に置いてあるAppleTVで、日本のIPからしか使えないサービスを使いたい。
- AbemaTV
- Netflix(日本版)
- 常時日本経由のインターネットだと速度面、レイテンシ面で不利なので任意に切り替えられるようにしたい。
実装の方針
- RaspberryPiで日本の実家においてあるサーバへVPNを張り、日本側の出口とする。
- RaspberryPiの
wlan0
を家庭内LAN、eth0
を切り替え用LANにして、eth0
の先にAppleTVをぶら下げる。 - RaspberryPiにて
-
eth0
にDHCPサーバ立てて、IP配るようにする -
eth0
→wlan0
の転送設定を入れる - デフォルトゲートウェイ(DGW)をJP側とUS側の間で切り替えることで、出口を制御する
- DGWの切り替えはコマンド入力だと家族が使えないので、Homebridgeを使ってiPhoneから制御できるようにする
-
実際の構築
VPNを張る
SoftEther VPN Serverを使った拠点間VPN。これはまぁ色んな所に参考情報が記載されているので簡単に。
-
実家側はNIC2枚刺しのCentOSに
SoftEther VPN Server
のVPNサーバを用意- 仮想HUBを作成し、2枚めのethにブリッジするようにする
- これでこの仮想HUBへアクセスすると、実家のLANにL2接続できるようになる
-
USのRaspberryPiに
SoftEther VPN Bridge
をインストール -
この時点でうまくローカルブリッジが動いていれば、数百msec遅延のping、すなわち日本経由でのpingが返ってくるはず。
$ ping -I tap_jikka 8.8.8.8
ラズパイのネットワークの設定
IPアドレスを固定
/etc/dhcpcd.conf
で、下記行を追加して、eth0
とwlan0
のIPアドレスを固定する。
interface eth0
static ip_address=10.0.0.1/8
interface wlan0
static ip_address=192.168.50.111/24
udhcpd設定
DHCPサーバをインストールしてセットアップ。
-
udhcpd
をインストール。 -
/etc/udhcpd.conf
をデフォルトの設定を参考にしながら編集。
start 10.0.0.2 #default: 192.168.0.20
end 10.0.0.254 #default: 192.168.0.254
option subnet 255.0.0.0
interface eth0 #default: eth0
opt dns 8.8.8.8
opt router 10.0.0.1
option domain local
option lease 864000 # 10 days of seconds
- 自動起動とかを設定
# systemctl enable udhcpd
# systemctl restart udhcpd
ルーティングやNATの設定
/etc/rc.local
のexit 0
より前に下記記載を追加する。
これにより起動時にこれらのコマンドが実行され、再起動後も有効になる。
# パケット転送を許可
echo 1 > /proc/sys/net/ipv4/ip_forward
# 実家サーバへのアクセスは、常にUS側のゲートウェイを通るようにスタティックルートを設定
jikka_ip=$(ping <実家サーバドメイン> | head -n1 | awk 'BEGIN{FS="\\(|\\)"}{print $2}')
route add -host ${jikka_ip} gw 192.168.50.1 wlan0
# iptablesで転送の許可と、10.0.0.0/8 ネットワークへのIPマスカレード設定
iptables -I FORWARD -j ACCEPT
iptables -t nat -I POSTROUTING -s 10.0.0.0/8 -j MASQUERADE
ここまでで、eth0
に繋がっている装置からインターネットに出ていこうとすると、10.0.0.1
を経由して、192.168.50.1
のルータ経由での通信となる。
ここでデフォルトゲートウェイを下記コマンドで変更すると、日本のルータ192.168.0.1
からインターネットに出ていくようになる。
# route add default gw 192.168.0.1 tap_jikka
# route del default gw 192.168.50.1 wlan0
Homebridgeで切り替えできるようにする
HomebridgeはApple HomeKitの装置を模倣するオープンソースプロダクト。
これを使って電球と同じような感じでiPhoneから切り替えられるようにする。
Homebridgeは導入済みとする。
- cmdswitch2プラグインを導入する。
# npm -g install homebridge-cmdswitch2
- config.json を編集する。
-
on_cmd
には日本ルータをデフォルトゲートウェイにする設定を入れる。 -
off_cmd
にはUSルータをデフォルトゲートウェイにする設定を入れる。また、VPNサーバへのスタティックルートが落ちる事があるので、ここで改めて追加するようにする。 -
state_cmd
には、日本ルータを向いているときに終了コード0を返すようなコマンドを設定する。
{
"platform": "cmdSwitch2",
"name": "JP-US switch",
"switches": [
{
"name": "JP net",
"on_cmd": "sudo sh -c 'route add default gw 192.168.0.1 tap_jikka; route del default gw 192.168.50.1 wlan0; true'",
"off_cmd": "sudo sh -c 'route add default gw 192.168.50.1 wlan0; route del default gw 192.168.0.1 tap_jikka; true'",
"state_cmd": "ip route | grep default | grep jikka",
"polling": true,
"interval": 5
}
]
}
これでHomebridgeをrestartするとこんな感じにiPhoneに表示されるようになり、切り替えられるようになる。
Apple TVリモートを使えるようにする
この構成だとApple TVは10.0.0.0/8
のネットワークにあり、iPhoneは192.168.0.50/24
のネットワークにあるので、Apple TVからのBonjourのマルチキャストDNS配信がiPhoneから見えないことになる。iOSにはAppleTVのリモコンとして動く機能があるが、この機能はBonjourに依存しているため、このままでは使えないことになる。
Bonjourの実装のひとつであるAvahi-daemonがRaspbianにはプリインストールされており、これのreflector機能を使って、プロキシとして機能して他のネットワークに伝播させることができる。
設定は、/etc/avahi/avachi-daemon.conf
のenable-refrector
をyes
にして有効にすればOK。
enable-reflector=yes
ただしこれだけでは10.0.0.0/8
への経路がiOSからは分からないので、家のルータにLAN側のスタティックルートを設定してやる必要がある。うちのASUSのルータだとこんな感じ。