海外に置いたAppleTVで日本のNetflixを見る - Raspberry Piで作るVPN切り替え機

やりたいこと

  • USの家に置いてあるAppleTVで、日本のIPからしか使えないサービスを使いたい。
  • 常時日本経由のインターネットだと速度面、レイテンシ面で不利なので任意に切り替えられるようにしたい。

実装の方針

  1. RaspberryPiで日本の実家においてあるサーバへVPNを張り、日本側の出口とする。
  2. RaspberryPiのwlan0を家庭内LAN、eth0を切り替え用LANにして、eth0の先にAppleTVをぶら下げる。
  3. RaspberryPiにて
    • eth0DHCPサーバ立てて、IP配るようにする
    • eth0wlan0の転送設定を入れる
    • デフォルトゲートウェイ(DGW)をJP側とUS側の間で切り替えることで、出口を制御する
    • DGWの切り替えはコマンド入力だと家族が使えないので、Homebridgeを使ってiPhoneから制御できるようにする

実際の構築

VPNを張る

SoftEther VPN Serverを使った拠点間VPN。これはまぁ色んな所に参考情報が記載されているので簡単に。

  • 実家側はNIC2枚刺しのCentOSSoftEther VPN ServerVPNサーバを用意
    • 仮想HUBを作成し、2枚めのethにブリッジするようにする
    • これでこの仮想HUBへアクセスすると、実家のLANにL2接続できるようになる
  • USのRaspberryPiにSoftEther VPN Bridgeをインストール

    • 仮想HUBを作成して実家の仮想ハブにカスケード接続を設定する。
    • tapバイスにローカルブリッジするように設定する。(ここではtap_jikkaとした)
  • この時点でうまくローカルブリッジが動いていれば、数百msec遅延のping、すなわち日本経由でのpingが返ってくるはず。

$ ping -I tap_jikka 8.8.8.8

ラズパイのネットワークの設定

IPアドレスを固定

/etc/dhcpcd.conf で、下記行を追加して、eth0wlan0IPアドレスを固定する。

interface eth0
static ip_address=10.0.0.1/8

interface wlan0
static ip_address=192.168.50.111/24

udhcpd設定

DHCPサーバをインストールしてセットアップ。

  1. udhcpdをインストール。
  2. /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
  1. 自動起動とかを設定
# systemctl enable udhcpd
# systemctl restart udhcpd

ルーティングやNATの設定

/etc/rc.localexit 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は導入済みとする。

  1. cmdswitch2プラグインを導入する。
# npm -g install homebridge-cmdswitch2
  1. config.json を編集する。
  2. on_cmdには日本ルータをデフォルトゲートウェイにする設定を入れる。
  3. off_cmdにはUSルータをデフォルトゲートウェイにする設定を入れる。また、VPNサーバへのスタティックルートが落ちる事があるので、ここで改めて追加するようにする。
  4. 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のネットワークにあり、iPhone192.168.0.50/24のネットワークにあるので、Apple TVからのBonjourマルチキャストDNS配信がiPhoneから見えないことになる。iOSにはAppleTVのリモコンとして動く機能があるが、この機能はBonjourに依存しているため、このままでは使えないことになる。

Bonjourの実装のひとつであるAvahi-daemonがRaspbianにはプリインストールされており、これのreflector機能を使って、プロキシとして機能して他のネットワークに伝播させることができる。

設定は、/etc/avahi/avachi-daemon.confenable-refrectoryesにして有効にすればOK。

enable-reflector=yes

ただしこれだけでは10.0.0.0/8への経路がiOSからは分からないので、家のルータにLAN側のスタティックルートを設定してやる必要がある。うちのASUSのルータだとこんな感じ。