VyOSにSerfを入れてフルメッシュVPNをメンテナンスレスでやってみる試み
提供: もみあげうぃき
目次
経緯
AWS上で、複数Regionを一つの固まりと見せるようにするためスター型風トポロジでVyattaにてVPNを構築し運用していてとっても便利でした。 しかし!あたりまえですが、接続が集中しているVyattaが落ちると、そこから先の経路が全滅します。あたりまえですが!あたりまえですが! Failoverするようにしても、やっぱり一時的に全滅は痛い・・・
そこで!やっぱ、フルメッシュでつないだ方がよくね? でも、、、トンネルの数!!!拠点増えた時めんどい?! 15台のVyattaをつなぐと、トンネルの数は、15x(15-1)/2=。。。
あれ?こういう時にSerfって使うんじゃないの?
ということで!
作ってみた感じ(アルファ版)
とりあえず、GitHubの使い方がいまいちわからないので、AWSにAMIを用意してみました。 GitHubのこと、誰か口頭で教えてください!
動かし方
いまのところ、AmazonWebServices(AWS)での動かし方を書いておきます。
まずはLaunchボタンから
- VyOS 1.0.4 amd64 with Serf FullmeshVPN alpha (HVM) - ami-e5abf6e4 というAMIを探してLaunchします。
- 現状は、TokyoRegionのみに準備してます。必要な方は、AMIからLaunch後にAMIを作成して、別リージョンにコピーしてお使いください。
※別リージョン用のAMIを作成する方は、AMI作成前に、
configure delete interfaces ethernet eth0 hw-id commit save
を行ってください。 行わないと、コピーしたAMIからLaunchしても、 MACアドレスが変更になって、SSH接続できなくなります。
VPN設定情報
- Launch時に、UserDataに以下を設定します。
例: PREKEY,aaabbbPREKEY22cccddd SERFKEY,6UIpjHbohEyOETGiuNqgNQ== ROLE,vpngrp1 JOINIP,127.0.0.1 DISPNAME,VyOSSerf1-Tokyo LOCALNET,10.15.0.0/16
- SERFKEY (必須)
- SerfのEncription用のKeyです。
- このKeyをもとにSerfにJoinし暗号化を行うので(たぶん)、他のNodeと合わせる必要があります。
- KeyはどっかのマシンにSerfを入れて、 serf keygen コマンドで生成したものを使ってください。
- JOINIP (必須)
- Join先のNodeのIPアドレスです。
- 基本的にはGlobalIPアドレスになりますが、まず最初のNodeを立ち上げるときには、 127.0.0.1 で大丈夫です。
- PREKEY (必須)
- IPSec接続用のPreSharedKeyです。
- 特に他のNodeと合わせる必要はありません。※という予定ですが、いまはバグがあって他のNodeと合わせる必要があります(^^;)
- ROLE (任意)
- まだ実装してませんが、将来的にはこのROLEに応じてVPNの接続グループを分ける予定
- DISPNAME (任意)
- 表示用の名前です。
- 各種表示される部分に出てくる名前になります。実際のNode名、マシン名、NameTagと全然違ってもOKです。
- LOCALNET (任意)
- IPSec接続先ノードに対して自分の裏にいるネットワークを教えるためにCIDRを書きます。
- 省略すると、自分のSubnetを指定したことになります。
- AWSの場合は、VPCのNetworkAddressを書くと、そのVPC全体へのRoutingをPeerに伝播させることができます。
- また、自分の裏にさらにSubnetがいる場合は、もう少し大きく 10.0.0.0/10 とかも書けます。
- いまのところ1つのCIDRしか書けません・・・
- SERFKEY (必須)
- こんな感じです
他のAWS設定
- セキュリティグループ
- IPSecとSerfのプロトコルが通るようにしてください。
- UDP 500
- ESP
- TCP/UDP 7946
- あたりを開ければよいかと思いますが、良くわからん方は、とりあえずフルオープン!で後で閉じて行きましょう。逆に。
- IPSecとSerfのプロトコルが通るようにしてください。
- Source / Dest Check
- Launch後は、速やかにインスタンスの、 Source / Dest Check を Disable にします。
VPNだから相手がいないとね☆
- あとは、同様の手順で2台以上動かすと、勝手にフルメッシュVPNが構築されちゃうっていう寸法です!
Serfで構築する利点
- どれか1つのNodeのGlobalIPを知っていればそれでOK!万事休す!
- なぜJOINするのか?そこにNODEがあるから。
- あとはほとんど気にしなくてよい
- 全VPNルータを設定しなくてもよい
- 逆に、いつ切断してもOK
※悪いことにはマスクがかかっています
今後の予定
- 同一セグメント内に2台以上いた場合は勝手に冗長構成にする⇒AWSのIAM RoleとRouteTableを使えばたぶんすぐできる
- ROLEによる複数フルメッシュVPN群の作成⇒フルメッシュVPN群同士をつなぐのも!
- 同一セグメントも気にしないでつなぎたい⇒L2TPv3も組み合わせる?
現状の課題
- セキュリティ
- Serfのencryptionのみなので・・・VyOSのFirewallで対応?最初のjoin先は手動で開ける、他はjoinメッセージを受けたら対象GlobalIPを開ける???う~ん。。。
- 品質
- 本番環境への適用に向けて、もう少し安定するようにしたい雰囲気!
- コマンドが重複してたりとか、謎のsleep入れてたりとか・・・
AWS以外でもたぶん動きます
- スクリプトは全体的に、ただのテキスト処理をひたすらやっている、vbashのシェルスクリプトです。
- /opt/serf に全体的に入っています。
- /opt/serf/bin/getinfo.sh にて、AWSのUserDataやMetaDataから情報を取得する処理を行っているので、そこのAWS依存部分を書き換えれば他のクラウドや他の仮想化環境でも動くはず!(たぶん)
SerfによるMonitoringとか
- /opt/serf/etc/webmonitor/ に、このSerfで作ったフルメッシュVPNの状態を可視化するもどきのサンプルページが入っているので、適当なWebServerでそこを見れるようにすれば、なんとなくグラフっぽくなるかも?!
- どっかのNodeで
cd /opt/serf/bin ; ./updateconcheck.sh &
しておくと、serf queryでVPN接続したmember間のlatency(rtt)をとって返してくれたものを、Web用のデータにします。