概要
Raspberry PiでUSBモデム挿入時にSORACOMへ自動接続するで RPi2 を使って SORACOM への接続ができるようになったので、それを冗長化回線として使うようにしました。
仕様
- 主回線を既設の FTTH 、予備回線を SORACOM Air とします
- 両回線友にルータには RPi2 を使います
- 主回線時は予備回線側に自動切り替えし、回復時には切り戻します
- SORACOM Air 側も常時接続とします
- LAN からインターネットへの接続の冗長化だけであれば障害時だけダイヤルアップすれば十分ですが、別途 VPN を使って外部からのアクセス経路の冗長化も予定しているため常時接続としました
- SORACOM Air の速度クラスは通常 s1.minimum とし、主回線障害時には s1.fast に上げます
- 主回線の障害の有無は特定サイトへの ping の成否で判断します
- ppp インターフェースの監視だけだとプロバイダと上流間での障害を検知できないため
- 通常時は sub も main をデフォルト GW とします
- なるべく SORACOM 側にトラフィックを生じさせないため
- 主回線側に障害が生じても main 自体が生きていれば sub をデフォルト GW として main もインターネット接続性を維持します
構成
- 主回線側ルータ(main)に 192.168.0.1 、予備回線側ルータ(sub)に 192.168.0.2 を割り当てます
- VIP 192.168.0.254 を LAN 内のデフォルト GW とし、回線状況によって主回線・予備回線のどちらかに割り当てます
通常時
FTTH SORACOM
ppp0(主回線)| | ppp0(予備回線)
+---+---+ +---+---+
| main | | sub |
+-------+ +-------+
192.168.0.1 |eth0 eth0| 192.168.0.2
192.168.0.254 +-------+------+
|
----------------+------------------ LAN
障害時
FTTH SORACOM
ppp0(主回線)X | ppp0(予備回線)
+---+---+ +---+---+
| main | | sub |
+-------+ +-------+
192.168.0.1 |eth0 eth0| 192.168.0.2
+-------+------+ 192.168.0.254
|
----------------+------------------ LAN
準備
ルータと DHCP の設定
main と sub それぞれが NAT ルータになるように iptables 等の設定を済ませておきます。
また、 VIP 192.168.0.254 が LAN 内のデフォルト GW になるよう DHCP サーバーの設定を変更しておきます。
速度クラス変更専用の SORACOM ユーザーを作成
予備回線への切り替え時に SORACOM の速度クラスを s1.fast に変更するので専用のユーザーを作成します。 keepalived から呼び出すのでユーザー名も keepalived にしておきます。予め SORACOM SDK for Ruby を参照して SORACOM のコマンドラインインターフェースが使えるようにしておきます。この作業は sub 側で行います。
ユーザー作成:
pi@sub:~ $ soracom user create_user --user-name=keepalived
{
"result": "success"
}
権限付与:
pi@sub:~ $ soracom user update_permission --user_name=keepalived --permission="{\"statements\": [ {\"effect\": \"allow\", \"api\": \"Subscriber:updateSpeedClass\"} ] }"
{
"result": "success"
}
認証設定:
keepalived は root で動作するのですが、その際の HOME は / になるので、認証情報は /.soracom に保存しておく必要があります。
pi@sub:~ $ soracom user generate_auth_key --user-name=keepalived
{
"authKeyId": “keyId-<略>",
"authKey": "secret-<略>"
}
pi@sub:~ $ soracom configure --profile=keepalived
--- SORACOM CLI setup ---
This will create .soracom directory under /home/pi and place 'keepalived.json' in it.
Please select which authentication method to use.
1. Input AuthKeyId and AuthKey *Recommended*
2. Input Operator credentials (Operator Email and Password)
3. Input SAM credentials (OperatorId and UserName and Password)
select(1-3)> 1
authKeyId: keyId-<略>
authKey:
wrote to /home/pi/.soracom/keepalived.json
pi@sub:~ $ sudo cp -r /home/pi/.soracom/keepalived.json /
主回線側(main)
keepalived のインストールと設定
pi@main:~ $ sudo apt-get install -y keepalived
main がバックアップに回る際のスクリプトを作成
#!/bin/sh
ip route replace default via 192.168.0.254 dev eth0
main がマスターに戻る際のスクリプトを作成
#!/bin/sh
ip route replace default dev ppp0
keepalived の設定ファイルを作成
global_defs {
notification_email {
# メール設定は省略
}
}
vrrp_script check_ftth {
script "ping -n -s 0 -c 1 -I ppp0 <ping対象のIPアドレス>"
interval 1
fall 3
raise 3
}
vrrp_instance VI_1 {
interface eth0
state MASTER
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass xxxxxxxx
}
virtual_ipaddress {
192.168.0.254/24 brd 192.168.0.255 dev eth0
}
track_script {
check_ftth
}
notify_master "/etc/keepalived/master.sh"
notify_backup "/etc/keepalived/backup.sh"
notify_fault "/etc/keepalived/backup.sh"
}
keepalived を起動します
pi@main:~ $ sudo systemctl start keepalived
予備回線側(sub)
SORACOM Air への接続設定
例えばRaspberry PiでUSBモデム挿入時にSORACOMへ自動接続する等の設定により、 sub から SORACOM Air に自動で常時接続されるようにしておきます。
また、今回の設定では障害が発生しない限り SORACOM Air に一切のパケットが流れません。 SORACOM Air では1時間の無通信で回線が切断されますので、切れる前に ppp 側に ping を打つように crontab に登録しておきます。
pi@sub:~ $ sudo crontab -e
<略>
0 * * * * ping -w 3 -n 10.64.64.64
keepalived のインストールと設定
pi@sub:~ $ sudo apt-get install -y keepalived
sub がマスターになる場合のスクリプトを作成
#!/bin/sh
ip route replace default dev ppp0
echo 1 > /proc/sys/net/ipv4/ip_forward
/usr/local/bin/soracom sim update_speed_class —-imsi=<SORACOM Air SIM の IMSI> --speed-class=s1.fast --profile=keepalived > /dev/null 2>&1
sub がバックアップに戻る際のスクリプトを作成
#!/bin/sh
/usr/local/bin/soracom sim update_speed_class —imsi=<SORACOM Air SIM の IMSI> --speed-class=s1.minimum --profile=keepalived > /dev/null 2>&1
echo 0 > /proc/sys/net/ipv4/ip_forward
ip route replace default via 192.168.0.254 dev eth0
keepalived の設定ファイルを作成
global_defs {
notification_email {
# メール設定は省略
}
}
vrrp_instance VI_1 {
interface eth0
state BACKUP
virtual_router_id 51
priority 50
advert_int 1
authentication {
auth_type PASS
auth_pass xxxxxxxx
}
virtual_ipaddress {
192.168.0.254/24 brd 192.168.0.255 dev eth0
}
notify_master "/etc/keepalived/master.sh"
notify_backup "/etc/keepalived/backup.sh"
notify_fault "/etc/keepalived/backup.sh"
}
main と同様に keepalived を起動します。
pi@sub:~ $ sudo systemctl start keepalived
動作確認
通常時
main に 192.168.0.254 が割り当たっていることを確認します。
pi@main:~ $ ip -f inet addr show eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
inet 192.168.0.1/24 brd 192.168.0.255 scope global eth0
valid_lft forever preferred_lft forever
inet 192.168.0.254/24 brd 192.168.0.255 scope global secondary eth0
valid_lft forever preferred_ft forever
main で FTTH 回線がデフォルト GW になっていることを確認します。
pi@main:~ $ ip route show
default dev ppp0 scope link
<FTTHから割り当てられたアドレス> dev ppp0 proto kernel scope link src <FTTHでの対向アドレス>
192.168.0.0/24 dev eth0 proto kernel scope link src 192.168.0.1
LAN 内のホストから外部への traceroute が main 経由になっていることを確認します。
gimy@localhost ~ $ traceroute -n 8.8.8.8
traceroute to 8.8.8.8 (8.8.8.8), 64 hops max, 52 byte packets
1 192.168.0.1 2.234 ms 1.151 ms 1.173 ms
<略>
9 8.8.8.8 4.613 ms 5.948 ms 4.475 ms
障害時
外部サイトに ping を打ち続けておきます。
gimy@locahost ~ $ ping -n 8.8.8.8
PING 8.8.8.8 (8.8.8.8): 56 data bytes
64 bytes from 8.8.8.8: icmp_seq=0 ttl=56 time=5.142 ms
64 bytes from 8.8.8.8: icmp_seq=1 ttl=56 time=6.954 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=56 time=8.226 ms
64 bytes from 8.8.8.8: icmp_seq=3 ttl=56 time=7.622 ms
<略>
main 側の ppp を落とし疑似的に障害状態を作ります。
pi@main:~ $ sudo poff dsl-provider
先程開始した ping が途中で通らなくなりやがて回復することを確認します。
64 bytes from 8.8.8.8: icmp_seq=21 ttl=56 time=5.205 ms
64 bytes from 8.8.8.8: icmp_seq=22 ttl=56 time=7.666 ms
64 bytes from 8.8.8.8: icmp_seq=23 ttl=56 time=5.761 ms
64 bytes from 8.8.8.8: icmp_seq=24 ttl=56 time=5.418 ms
64 bytes from 8.8.8.8: icmp_seq=25 ttl=56 time=7.017 ms
64 bytes from 8.8.8.8: icmp_seq=26 ttl=56 time=6.637 ms
64 bytes from 8.8.8.8: icmp_seq=27 ttl=56 time=5.582 ms
92 bytes from 192.168.0.1: Destination Net Unreachable
Vr HL TOS Len ID Flg off TTL Pro cks Src Dst
4 5 00 5400 8904 0 0000 40 01 2087 192.168.0.102 8.8.8.8
Request timeout for icmp_seq 28
92 bytes from 192.168.0.1: Destination Net Unreachable
Vr HL TOS Len ID Flg off TTL Pro cks Src Dst
4 5 00 5400 b0a6 0 0000 40 01 f8e4 192.168.0.102 8.8.8.8
Request timeout for icmp_seq 29
92 bytes from 192.168.0.1: Destination Net Unreachable
Vr HL TOS Len ID Flg off TTL Pro cks Src Dst
4 5 00 5400 23cd 0 0000 40 01 85be 192.168.0.102 8.8.8.8
Request timeout for icmp_seq 30
92 bytes from 192.168.0.1: Destination Net Unreachable
Vr HL TOS Len ID Flg off TTL Pro cks Src Dst
4 5 00 5400 6cb1 0 0000 40 01 3cda 192.168.0.102 8.8.8.8
Request timeout for icmp_seq 31
Request timeout for icmp_seq 32
92 bytes from 192.168.0.1: Redirect Host(New addr: 192.168.0.254)
Vr HL TOS Len ID Flg off TTL Pro cks Src Dst
4 5 00 0054 57b0 0 0000 3f 01 52db 192.168.0.102 8.8.8.8
Request timeout for icmp_seq 33
64 bytes from 8.8.8.8: icmp_seq=34 ttl=55 time=131.398 ms
64 bytes from 8.8.8.8: icmp_seq=35 ttl=55 time=136.203 ms
64 bytes from 8.8.8.8: icmp_seq=36 ttl=55 time=391.485 ms
64 bytes from 8.8.8.8: icmp_seq=37 ttl=55 time=188.250 ms
64 bytes from 8.8.8.8: icmp_seq=38 ttl=54 time=143.007 ms
64 bytes from 8.8.8.8: icmp_seq=39 ttl=54 time=597.688 ms
<略>
sub 経由になっていることを確認します。
gimy@localhost ~ $ traceroute -n 8.8.8.8
traceroute to 8.8.8.8 (8.8.8.8), 64 hops max, 52 byte packets
1 192.168.0.2 2.949 ms 1.179 ms 1.152 ms
<略>
8.8.8.8 130.123 ms
sub に 192.168.0.254 が割り当たっていることを確認します。
pi@sub:~ $ ip -f inet addr show eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
inet 192.168.0.2/24 brd 192.168.0.255 scope global eth0
valid_lft forever preferred_lft forever
inet 192.168.0.254/24 brd 192.168.0.255 scope global secondary eth0
valid_lft forever preferred_ft forever
sub で SORACOM 側がデフォルト GW になっていることを確認します。
gimy@sub:~ $ ip route show
default dev ppp0 scope link
10.64.64.64 dev ppp0 proto kernel scope link src <SORACOM から割り当てられたアドレス>
192.168.0.0/24 dev eth0 proto kernel scope link src 192.168.0.2
切り戻し
main の ppp 接続を回復させ、切り戻されていることを確認します。
pi@main:~ $ sudo pon dsl-provider
Plugin rp-pppoe.so loaded.
確認内容は通常時と同じです。
感想
s1.fast であっても 2Mbps なので、 SORACOM Air 側に failover した状態で LAN 内のクライアント機から Web ブラウズするとやはりストレスを感じます。しかし、月額300円程度で予備回線を維持できるというのはそれなりに意味があると思います。