「VyOS と Tailscale で高速・冗長化された VPN を作る方法」の版間の差分

提供: hkatou_Lab
ナビゲーションに移動 検索に移動
 
(同じ利用者による、間の6版が非表示)
2行目: 2行目:
 
IPsec VPN を超える速度で、拠点間通信を暗号化できる
 
IPsec VPN を超える速度で、拠点間通信を暗号化できる
  
* Tailscale : フレッツ IPoE <-> Nuro で 125Mbps を確認
+
* Tailscale : フレッツ IPoE <-> Nuro で 125Mbps を確認
 
* IPsec : フレッツ PPPoE <-> Nuro では 50Mbps 程度
 
* IPsec : フレッツ PPPoE <-> Nuro では 50Mbps 程度
  
30行目: 30行目:
 
[[ファイル:Tailscale VyOS 01.png|フレームなし|800x800ピクセル]]
 
[[ファイル:Tailscale VyOS 01.png|フレームなし|800x800ピクセル]]
  
West01,02 , East01,02 : VyOS 1.4
+
=== 試験環境 ===
 +
West01,02 , East01,02 : '''VyOS 1.4'''
  
West_vSwitch , East_vSwitch : ESXi vSwitch
+
West_vSwitch , East_vSwitch : '''ESXi vSwitch'''
  
West_PC01 , East_PC01 : LAN ホスト
+
West_PC01 , East_PC01 : '''LAN ホスト'''
  
 
=== ポイント ===
 
=== ポイント ===
 
BGP は Tailscale の 100.64.x.x/32 でピアを張らず、広報する集約ルートから切り出したサブネットを使用し、Loopback (以下 Lo) インターフェースで BGP セッションを張る
 
BGP は Tailscale の 100.64.x.x/32 でピアを張らず、広報する集約ルートから切り出したサブネットを使用し、Loopback (以下 Lo) インターフェースで BGP セッションを張る
  
* 100.64.x.x/32 で張ると、広報する内部ネットワークが通信できない場合にも BGP ピアを張り続けてしまう
+
* tailscale のインターフェースである 100.64.x.x/32 で張ると、広報する内部ネットワークが通信できない場合にも BGP ピアを張り続けてしまう
** 例) Tailscale の 1 アカウント内で同一サブネットを 2 つのノードで advertise-routes したとき、片方のノードで集約ルートが広報できず、通信不可になる
+
** 例) Tailscale の 1 アカウント内で同一サブネットを 2 つのノードで advertise-routes したとき、片方のノードでルートが広報できず、通信不可になる
 
** Lo を BGP ピアに使用することで、集約ルートの通信不可を検出し、切り替えることが可能
 
** Lo を BGP ピアに使用することで、集約ルートの通信不可を検出し、切り替えることが可能
* BGP ピアの宛先 Lo 宛 Static Route を interface tailscale0 に向ける + ebgp-multihop 2 を設定
+
* BGP ピアの宛先 Lo 宛 Static Route を interface Tailscale 0 に向ける + ebgp-multihop 2 を設定
** eBGP のデフォルトは Keepalive の IP ヘッダが TTL=1 のため、/30 サブネットを経由した時点で TTL=0 で Drop してしまい、Lo とピアできない
+
** eBGP のデフォルトは Keepalive の IP ヘッダが TTL=1 のため、tailscale インターフェースを経由した時点で TTL=0 で Drop してしまい、Lo とピアできない
** multihop の数を多くする場合は、IGP / iBGP の迂回経路経由で切り替わる
 
 
Tailscale 上で Lo のルート交換に OSPF を試してみたが、動作しなかった
 
Tailscale 上で Lo のルート交換に OSPF を試してみたが、動作しなかった
  
* Tailscale でマルチキャスト or OSPF IP protocol number がフィルタリングされている
+
* Tailscale で OSPF Hello のマルチキャスト or OSPF IP protocol number がフィルタリングされている
 +
** neighbor 指定でも Up しないため、おそらく protocol number による
  
== 構築手順 ==
+
== 構築手順概要 ==
Tailscale のアカウントを作成する
+
 
 +
=== Tailscale ===
 +
アカウントを作成する
  
 
* 冗長化なし : 1 つ
 
* 冗長化なし : 1 つ
 
* 冗長化あり : 2 つ
 
* 冗長化あり : 2 つ
** アカウントが 1 つ + Free プランの場合、tailscale subnet router は同じプレフィックスを 1 台しか広報できない
+
** アカウントが 1 つ + Free プランの場合、Tailscale subnet router は同じプレフィックスを 1 台しか広報できない
 +
** アカウントを 2 つ取得し、1 アカウントを 2 ルータを別拠点に配置する
  
VyOS をハイパーバイザにインストール
+
=== VyOS ===
 +
ハイパーバイザにデプロイする
  
 
* WAN 側ポートグループに DHCP や PPPoE などの Vlan を割り当て、eth4 にアサイン
 
* WAN 側ポートグループに DHCP や PPPoE などの Vlan を割り当て、eth4 にアサイン
63行目: 68行目:
 
* VyOS の CD-ROM をマウントして起動、install image で VM の HDD へインストール
 
* VyOS の CD-ROM をマウントして起動、install image で VM の HDD へインストール
  
VyOS をインターネットに接続する設定を行う
+
インターネットに接続する設定を行う
  
VyOS に Tailscale をインストールする
+
Tailscale をインストールする
  
 
* VyOS 1.4 の場合、ベースとなる Linux<ref>2021-06-25
 
* VyOS 1.4 の場合、ベースとなる Linux<ref>2021-06-25
71行目: 76行目:
 
T3641 (feature): Upgrade base system from Debian Buster -> Debian Bullseye</ref> [https://tailscale.com/download/linux/debian-bullseye Debian 11 Bullseye の手順]を使用する
 
T3641 (feature): Upgrade base system from Debian Buster -> Debian Bullseye</ref> [https://tailscale.com/download/linux/debian-bullseye Debian 11 Bullseye の手順]を使用する
 
* VyOS の CLI から、直接 bash shell のコマンドを投入可能
 
* VyOS の CLI から、直接 bash shell のコマンドを投入可能
* これはインストール直後に行ったほうが良い
+
* これは VyOS のインストール直後に行ったほうが良い
** VyOS 設定後に tailscale をインストールすると、VyOS が正常に動作しなくなる場合があった
+
** VyOS 設定後に Tailscale をインストールすると、VyOS が正常に動作しなくなる場合があった
  
VyOS を再起動
+
再起動
  
VyOS で WAN 側ルーティングを設定する
+
WAN 側ルーティングを設定する
  
* PPPoE や DHCP などでインターネットに接続し、tailscale を動作可能にする
+
* PPPoE や DHCP などでインターネットに接続し、Tailscale を動作可能にする
  
VyOS で tailscale を起動する
+
Tailscale を起動する
  
VyOS で WAN 側 VPN にルーティングを設定する
+
WAN 側 にルーティングを設定する
  
 
* 冗長化しない場合は、スタティックルーティングで OK
 
* 冗長化しない場合は、スタティックルーティングで OK
* 冗長化する場合は、BGP でダイナミックルーティングさせる
+
* 冗長化する場合は、BGP でダイナミック ルーティングさせる
VyOS で LAN 側にルーティングを設定する
+
LAN 側にルーティングを設定する
  
 
* ホストを直接収容する場合 : VRRP で冗長化する
 
* ホストを直接収容する場合 : VRRP で冗長化する
 
* LAN 側に L3 スイッチがある場合 : OSPF / BGP で冗長化する
 
* LAN 側に L3 スイッチがある場合 : OSPF / BGP で冗長化する
  
 +
== VyOS に Tailscale をインストールする ==
 +
 +
=== VyOS をインターネットに接続する ===
 +
<syntaxhighlight lang="diff">
 +
vyos@West01# set interfaces ethernet eth3 address 'dhcp'
 +
vyos@West01# set protocols static route 0.0.0.0/0 next-hop x.x.x.x
 +
vyos@West01# set system name-server '8.8.8.8'
 +
</syntaxhighlight>
 +
x.x.x.x にはインターネットへ抜けられる IP を指定する
 +
 +
=== VyOS に Tailscale をインストールする ===
 +
Tailscale の GPG キーとリポジトリを登録<syntaxhighlight lang="diff">
 +
vyos@West01# curl -fsSL https://pkgs.tailscale.com/stable/debian/bullseye.noarmor.gpg | sudo tee /usr/share/keyrings/tailscale-archive-keyring.gpg >/dev/null
 +
vyos@West01# curl -fsSL https://pkgs.tailscale.com/stable/debian/bullseye.tailscale-keyring.list | sudo tee /etc/apt/sources.list.d/tailscale.list
 +
</syntaxhighlight>
 +
 +
=== Tailscale をインストール ===
 +
<syntaxhighlight lang="diff">
 +
vyos@West01# sudo apt-get update
 +
Get:1 https://pkgs.tailscale.com/stable/debian bullseye InRelease
 +
Get:2 https://pkgs.tailscale.com/stable/debian bullseye/main amd64 Packages [5,389 B]
 +
Fetched 10.9 kB in 1s (11.5 kB/s)
 +
Reading package lists... Done
 +
[edit]
 +
</syntaxhighlight><syntaxhighlight lang="diff">
 +
vyos@West01# sudo apt-get install tailscale
 +
Reading package lists... Done
 +
Building dependency tree... Done
 +
Reading state information... Done
 +
The following NEW packages will be installed:
 +
  tailscale
 +
0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
 +
Need to get 19.2 MB of archives.
 +
After this operation, 35.6 MB of additional disk space will be used.
 +
Get:1 https://pkgs.tailscale.com/stable/debian bullseye/main amd64 tailscale amd64 1.24.0 [19.2 MB]
 +
Fetched 19.2 MB in 3s (6,108 kB/s)
 +
Selecting previously unselected package tailscale.
 +
(Reading database ... 67158 files and directories currently installed.)
 +
Preparing to unpack .../tailscale_1.24.0_amd64.deb ...
 +
Unpacking tailscale (1.24.0) ...
 +
Setting up tailscale (1.24.0) ...
 +
Created symlink /etc/systemd/system/multi-user.target.wants/tailscaled.service → /lib/systemd/system/tailscaled.service.
 +
localepurge: Disk space freed:      0 KiB in /usr/share/locale
 +
localepurge: Disk space freed:      0 KiB in /usr/share/man
 +
localepurge: Disk space freed:      0 KiB in /usr/share/aptitude
 +
 +
Total disk space freed by localepurge: 0 KiB
 +
 +
[edit]
 +
vyos@West01#
 +
</syntaxhighlight>
 +
 +
==== Tailscale を起動、アカウントに機器を紐づける ====
 +
<syntaxhighlight lang="diff">
 +
vyos@West01# sudo tailscale up --advertise-routes 172.16.0.0/16 --accept-routes=true
 +
 +
To authenticate, visit:
 +
 +
        https://login.tailscale.com/x/abcdef
 +
 +
Success.
 +
</syntaxhighlight>
 +
West01 の広報するルートに 172.16.0.0/16 を指定し、別機器から広報されたルートを受け入れるオプションを指定する
 +
 +
出てきた URL をブラウザに貼り付けて、ログインすれば OK
 +
 +
あとは別拠点側の East01 側も設定する
 +
 +
=== アカウントの紐づけ ===
 +
 +
* アカウント 1 : West01 , East01
 +
* アカウント 2 : West02 , East02
 +
同一アカウント内のホスト間で、VPN 通信が可能
 +
 +
= Loopback 間 疎通確認 =
 +
 +
=== West01 : 事前疎通不可確認 ===
 +
<syntaxhighlight lang="diff">
 +
vyos@West01# run ping 172.31.255.1
 +
PING 172.31.255.1 (172.31.255.1) 56(84) bytes of data.
 +
 +
</syntaxhighlight>West01 -> East01 の Loopback へ ping を打ちながら設定変更する。
 +
 +
=== West01 : Tailscale にログインして、広報するルートを確定 ===
 +
対向側で集約ルートを広報させる。
 +
 +
Subnets に "!" がついている場合、広報されていないルートが存在する。
 +
 +
=== West01 : 疎通可能を確認 ===
 +
<syntaxhighlight lang="diff">
 +
vyos@West01# run show ip route 172.31.255.1
 +
Routing entry for 0.0.0.0/0
 +
  Known via "static", distance 1, metric 0, best
 +
  Last update 00:31:07 ago
 +
  * 10.10.60.1, via eth3, weight 1
 +
 
 +
vyos@West01# run pin 172.31.255.1
 +
PING 172.31.255.1 (172.31.255.1) 56(84) bytes of data.
 +
64 bytes from 172.31.255.1: icmp_seq=1 ttl=64 time=17.7 ms
 +
64 bytes from 172.31.255.1: icmp_seq=2 ttl=64 time=11.6 ms
 +
^C
 +
--- 172.31.255.1 ping statistics ---
 +
2 packets transmitted, 2 received, 0% packet loss, time 1002ms
 +
rtt min/avg/max/mdev = 11.632/14.681/17.730/3.049 ms
 +
 +
vyos@West01# run traceroute 172.31.255.1
 +
traceroute to 172.31.255.1 (172.31.255.1), 30 hops max, 60 byte packets
 +
1  172.31.255.1 (172.31.255.1)  11.104 ms  13.310 ms  12.934 ms
 +
</syntaxhighlight>対向側 East01 Loopback 宛ルートが存在せず、デフォルトルートに向いてしまっており、
 +
 +
VyOS 上でルートが見えないのは好ましくない。
 +
 +
=== West01 : 対向拠点 Loopback 宛スタティックルートを設定 ===
 +
<syntaxhighlight lang="diff">
 +
vyos@West01# set protocols static route 172.31.255.1/32 interface tailscale0
 +
[edit]
 +
vyos@West01# compare
 +
[edit protocols static]
 +
+route 172.31.255.1/32 {
 +
+    interface tailscale0 {
 +
+    }
 +
+}
 +
[edit]
 +
vyos@West01# compare commands
 +
set protocols static route 172.31.255.1/32 interface 'tailscale0'
 +
[edit]
 +
vyos@West01# commit
 +
[edit]
 +
vyos@West01# run show ip route 172.31.255.1/32
 +
Routing entry for 172.31.255.1/32
 +
  Known via "static", distance 1, metric 0, best
 +
  Last update 00:00:36 ago
 +
  * directly connected, tailscale0, weight 1
 +
</syntaxhighlight>VyOS 上でスタティックルートが正常に見えるようになった。
 +
 +
=== West01 : 疎通確認を実施 ===
 +
<syntaxhighlight lang="diff">
 +
vyos@West01# run ping 172.31.255.1
 +
PING 172.31.255.1 (172.31.255.1) 56(84) bytes of data.
 +
64 bytes from 172.31.255.1: icmp_seq=1 ttl=64 time=30.2 ms
 +
^C
 +
--- 172.31.255.1 ping statistics ---
 +
1 packets transmitted, 1 received, 0% packet loss, time 0ms
 +
rtt min/avg/max/mdev = 30.244/30.244/30.244/0.000 ms
 +
[edit]
 +
vyos@West01#
 +
[edit]
 +
vyos@West01# run ping 172.31.255.1 source-address 172.16.255.1
 +
PING 172.31.255.1 (172.31.255.1) from 172.16.255.1 : 56(84) bytes of data.
 +
^C
 +
--- 172.31.255.1 ping statistics ---
 +
3 packets transmitted, 0 received, 100% packet loss, time 2055ms
 +
 +
[edit]
 +
vyos@West01#
 +
</syntaxhighlight>West01 Tailscale の 100.64.x.x から対向側 East01 Loopback には疎通可能だが、
 +
 +
Loopback -> Loopback には疎通不可のため、
 +
 +
このままでは eBGP ピアが張れない。
 +
 +
 +
East01 でもスタティックルートを設定する。<syntaxhighlight lang="diff">
 +
vyos@East01# set protocols static route 172.16.255.1/32 interface tailscale0
 +
[edit]
 +
vyos@East01# compare
 +
[edit protocols static route 172.16.255.1/32]
 +
+interface tailscale0 {
 +
+}
 +
[edit]
 +
vyos@East01# commit
 +
[edit]
 +
vyos@East01# run show ip route 172.16.255.1/32
 +
Routing entry for 172.16.255.1/32
 +
  Known via "static", distance 1, metric 0, best
 +
  Last update 00:00:05 ago
 +
  * directly connected, tailscale0, weight 1
 +
 +
[edit]
 +
vyos@East01#
 +
</syntaxhighlight>
 +
 +
=== Loopback -> Loopback 間の疎通可能を確認 ===
 +
<syntaxhighlight lang="diff">
 +
vyos@West01# run ping 172.31.255.1 source-address 172.16.255.1
 +
PING 172.31.255.1 (172.31.255.1) from 172.16.255.1 : 56(84) bytes of data.
 +
64 bytes from 172.31.255.1: icmp_seq=1 ttl=64 time=10.2 ms
 +
64 bytes from 172.31.255.1: icmp_seq=2 ttl=64 time=11.3 ms
 +
^C
 +
--- 172.31.255.1 ping statistics ---
 +
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
 +
rtt min/avg/max/mdev = 10.224/10.778/11.333/0.554 ms
 +
</syntaxhighlight>BGP ピアの前提条件となる、Loopback 間で疎通可能となった。
 +
 +
= 各プロトコルの設定例 =
 +
 +
=== West01 : BGP ===
 +
<syntaxhighlight lang="diff">
 +
vyos@West01:~$ show configuration commands | match "bgp|route-map|prefix-list"
 +
set policy prefix-list PL_out rule 10 action 'permit'
 +
set policy prefix-list PL_out rule 10 prefix '172.16.0.0/16'
 +
set policy route-map RMAP_out rule 10 action 'permit'
 +
set policy route-map RMAP_out rule 10 match ip address prefix-list 'PL_out'
 +
set protocols bgp address-family ipv4-unicast aggregate-address 172.16.0.0/16 summary-only
 +
set protocols bgp address-family ipv4-unicast redistribute connected
 +
set protocols bgp local-as '64512'
 +
set protocols bgp neighbor 172.16.255.2 address-family ipv4-unicast nexthop-self
 +
set protocols bgp neighbor 172.16.255.2 address-family ipv4-unicast soft-reconfiguration inbound
 +
set protocols bgp neighbor 172.16.255.2 remote-as '64512'
 +
set protocols bgp neighbor 172.16.255.2 update-source 'lo'
 +
set protocols bgp neighbor 172.31.255.1 address-family ipv4-unicast route-map export 'RMAP_out'
 +
set protocols bgp neighbor 172.31.255.1 address-family ipv4-unicast soft-reconfiguration inbound
 +
set protocols bgp neighbor 172.31.255.1 ebgp-multihop '2'
 +
set protocols bgp neighbor 172.31.255.1 remote-as '65552'
 +
set protocols bgp neighbor 172.31.255.1 update-source 'lo'
 +
set protocols bgp parameters router-id '172.16.255.1'
 +
set protocols bgp timers holdtime '30'
 +
set protocols bgp timers keepalive '10'
 +
</syntaxhighlight>
 +
 +
=== East01 の BGP 設定例 ===
 +
<syntaxhighlight lang="diff">
 +
vyos@East01:~$ show configuration commands | match "bgp|route-map|prefix-list"
 +
set policy prefix-list PL_out rule 10 action 'permit'
 +
set policy prefix-list PL_out rule 10 prefix '172.31.0.0/16'
 +
set policy route-map RMAP_out rule 10 action 'permit'
 +
set policy route-map RMAP_out rule 10 match ip address prefix-list 'PL_out'
 +
set protocols bgp address-family ipv4-unicast aggregate-address 172.31.0.0/16 summary-only
 +
set protocols bgp address-family ipv4-unicast redistribute connected
 +
set protocols bgp local-as '65552'
 +
set protocols bgp neighbor 172.16.255.1 address-family ipv4-unicast route-map export 'RMAP_out'
 +
set protocols bgp neighbor 172.16.255.1 address-family ipv4-unicast soft-reconfiguration inbound
 +
set protocols bgp neighbor 172.16.255.1 ebgp-multihop '2'
 +
set protocols bgp neighbor 172.16.255.1 remote-as '64512'
 +
set protocols bgp neighbor 172.16.255.1 update-source 'lo'
 +
set protocols bgp neighbor 172.31.255.2 address-family ipv4-unicast soft-reconfiguration inbound
 +
set protocols bgp neighbor 172.31.255.2 remote-as '65552'
 +
set protocols bgp neighbor 172.31.255.2 update-source 'lo'
 +
set protocols bgp parameters router-id '172.31.255.1'
 +
set protocols bgp timers holdtime '30'
 +
set protocols bgp timers keepalive '10'
 +
</syntaxhighlight>
 +
 +
== おまけ : 冗長切替のヒント ==
 +
下位側を connected + VRRP とした場合、HyperVisor 配下で connected の障害を検出することが難しい。
 +
 +
VRRP の切り替えは可能だが、BGP の広報を止められないため、下りトラフィックが流れ込んでしまう。
 +
 +
* bash script で peer shutdown という手もあるが・・・
 +
 +
以下に下位側を L3SW と OSPF でダイナミックルーティングとした場合について記載する。
 +
 +
=== 上位 eBGP ピア Down 時 ===
 +
わたり eth2 の OSPF + iBGP で迂回するか、下位 OSPF に対向拠点宛のルート広報をやめて、下位側で迂回させる
  
 +
BGP で受信するルートを死活監視 + tracking して、Down 時に VRRP の優先度を下げる
  
== 冗長切替のポイント ==
+
=== わたりレス構成で下位 OSPF Down 時 ===
BGP ピア Down 時は、わたり eth2 の OSPF + iBGP で迂回するか、下位 IGP に対抗拠点宛のルート広報をやめて、下位側で迂回させる
+
下位 OSPF Down 時に、BGP で集約ルートの広報をやめるように設計する
  
わたりレスとする場合は、下位 IGP Down 時に集約ルートの広報をやめる
+
* BGP で aggregate-address + redistribute ospf する
 +
** OSPF Down で再配布が停止される
 +
* OSPF でサブネットルートが 1 つでもあると BGP で aggregate-address が広報されるため、route-map で Lo を再配布の対象から除外するなどの工夫が必要
  
 
== Tailscale の TIPS ==
 
== Tailscale の TIPS ==
tailscale の subnet router は、有効化時に VyOS の動作に影響がある
+
Tailscale の subnet router は、有効化時に VyOS の動作に影響がある
  
* 2 台のルータで同じプレフィックスを advetise-routes すると、片方は通信できない
+
* Free プランの 1 アカウント内に 2 台のルータで、同じプレフィックスを advetise-routes すると、片方は通信できない
 
** subnet router 冗長化は有料プランのため、Free プランだとこの動作となる模様
 
** subnet router 冗長化は有料プランのため、Free プランだとこの動作となる模様
** LAN 側の OSPF も止まる
+
** 副作用で LAN 側の OSPF も止まる
  
  
 
== リファレンス ==
 
== リファレンス ==
[https://internet.watch.impress.co.jp/docs/column/shimizu/1303751.html 100台まで無料のVPNサービス「tailscale」、リンクだけでマシンのシェアも可能!?]
+
[https://internet.watch.impress.co.jp/docs/column/shimizu/1303751.html 100台まで無料のVPNサービス「Tailscale 」、リンクだけでマシンのシェアも可能!?]
  
 
== 引用 ==
 
== 引用 ==
 +
<references />
 +
[[カテゴリ:VyOS]]
 +
[[カテゴリ:Tailscale]]

2022年10月26日 (水) 08:09時点における最新版

目的・メリット

IPsec VPN を超える速度で、拠点間通信を暗号化できる

  • Tailscale : フレッツ IPoE <-> Nuro で 125Mbps を確認
  • IPsec : フレッツ PPPoE <-> Nuro では 50Mbps 程度

ダイナミック ルーティングで、拠点間通信を冗長化できる

固定・動的グローバル IP が必要ない

  • IPsec は、少なくとも片方にグローバル IP が必要
  • Tailscale は両拠点とも NAT 配下で OK

リモートアクセス VPN も同時に構築可能

必要なもの

x86 サーバ x2

タグ Vlan 対応 L2 スイッチ

あると良いもの

x86 サーバ x4

  • 2 拠点に 2 台ずつ設置して、物理的にも冗長化させる

タグ Vlan 対応 L3 スイッチ

論理構成例

Tailscale VyOS 01.png

試験環境

West01,02 , East01,02 : VyOS 1.4

West_vSwitch , East_vSwitch : ESXi vSwitch

West_PC01 , East_PC01 : LAN ホスト

ポイント

BGP は Tailscale の 100.64.x.x/32 でピアを張らず、広報する集約ルートから切り出したサブネットを使用し、Loopback (以下 Lo) インターフェースで BGP セッションを張る

  • tailscale のインターフェースである 100.64.x.x/32 で張ると、広報する内部ネットワークが通信できない場合にも BGP ピアを張り続けてしまう
    • 例) Tailscale の 1 アカウント内で同一サブネットを 2 つのノードで advertise-routes したとき、片方のノードでルートが広報できず、通信不可になる
    • Lo を BGP ピアに使用することで、集約ルートの通信不可を検出し、切り替えることが可能
  • BGP ピアの宛先 Lo 宛 Static Route を interface Tailscale 0 に向ける + ebgp-multihop 2 を設定
    • eBGP のデフォルトは Keepalive の IP ヘッダが TTL=1 のため、tailscale インターフェースを経由した時点で TTL=0 で Drop してしまい、Lo とピアできない

Tailscale 上で Lo のルート交換に OSPF を試してみたが、動作しなかった

  • Tailscale で OSPF Hello のマルチキャスト or OSPF IP protocol number がフィルタリングされている
    • neighbor 指定でも Up しないため、おそらく protocol number による

構築手順概要

Tailscale

アカウントを作成する

  • 冗長化なし : 1 つ
  • 冗長化あり : 2 つ
    • アカウントが 1 つ + Free プランの場合、Tailscale subnet router は同じプレフィックスを 1 台しか広報できない
    • アカウントを 2 つ取得し、1 アカウントを 2 ルータを別拠点に配置する

VyOS

ハイパーバイザにデプロイする

  • WAN 側ポートグループに DHCP や PPPoE などの Vlan を割り当て、eth4 にアサイン
  • LAN 側ポートグループにホストや L3SW の Vlan を割り当て、eth0 にアサイン
  • VyOS の CD-ROM をマウントして起動、install image で VM の HDD へインストール

インターネットに接続する設定を行う

Tailscale をインストールする

  • VyOS 1.4 の場合、ベースとなる Linux[1] Debian 11 Bullseye の手順を使用する
  • VyOS の CLI から、直接 bash shell のコマンドを投入可能
  • これは VyOS のインストール直後に行ったほうが良い
    • VyOS 設定後に Tailscale をインストールすると、VyOS が正常に動作しなくなる場合があった

再起動

WAN 側ルーティングを設定する

  • PPPoE や DHCP などでインターネットに接続し、Tailscale を動作可能にする

Tailscale を起動する

WAN 側 にルーティングを設定する

  • 冗長化しない場合は、スタティックルーティングで OK
  • 冗長化する場合は、BGP でダイナミック ルーティングさせる

LAN 側にルーティングを設定する

  • ホストを直接収容する場合 : VRRP で冗長化する
  • LAN 側に L3 スイッチがある場合 : OSPF / BGP で冗長化する

VyOS に Tailscale をインストールする

VyOS をインターネットに接続する

vyos@West01# set interfaces ethernet eth3 address 'dhcp'
vyos@West01# set protocols static route 0.0.0.0/0 next-hop x.x.x.x 
vyos@West01# set system name-server '8.8.8.8'

x.x.x.x にはインターネットへ抜けられる IP を指定する

VyOS に Tailscale をインストールする

Tailscale の GPG キーとリポジトリを登録

vyos@West01# curl -fsSL https://pkgs.tailscale.com/stable/debian/bullseye.noarmor.gpg | sudo tee /usr/share/keyrings/tailscale-archive-keyring.gpg >/dev/null
vyos@West01# curl -fsSL https://pkgs.tailscale.com/stable/debian/bullseye.tailscale-keyring.list | sudo tee /etc/apt/sources.list.d/tailscale.list

Tailscale をインストール

vyos@West01# sudo apt-get update
Get:1 https://pkgs.tailscale.com/stable/debian bullseye InRelease
Get:2 https://pkgs.tailscale.com/stable/debian bullseye/main amd64 Packages [5,389 B]
Fetched 10.9 kB in 1s (11.5 kB/s)
Reading package lists... Done
[edit]
vyos@West01# sudo apt-get install tailscale
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following NEW packages will be installed:
  tailscale
0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
Need to get 19.2 MB of archives.
After this operation, 35.6 MB of additional disk space will be used.
Get:1 https://pkgs.tailscale.com/stable/debian bullseye/main amd64 tailscale amd64 1.24.0 [19.2 MB]
Fetched 19.2 MB in 3s (6,108 kB/s)
Selecting previously unselected package tailscale.
(Reading database ... 67158 files and directories currently installed.)
Preparing to unpack .../tailscale_1.24.0_amd64.deb ...
Unpacking tailscale (1.24.0) ...
Setting up tailscale (1.24.0) ...
Created symlink /etc/systemd/system/multi-user.target.wants/tailscaled.service → /lib/systemd/system/tailscaled.service.
localepurge: Disk space freed:      0 KiB in /usr/share/locale
localepurge: Disk space freed:      0 KiB in /usr/share/man
localepurge: Disk space freed:      0 KiB in /usr/share/aptitude

Total disk space freed by localepurge: 0 KiB

[edit]
vyos@West01#

Tailscale を起動、アカウントに機器を紐づける

vyos@West01# sudo tailscale up --advertise-routes 172.16.0.0/16 --accept-routes=true

To authenticate, visit:

        https://login.tailscale.com/x/abcdef

Success.

West01 の広報するルートに 172.16.0.0/16 を指定し、別機器から広報されたルートを受け入れるオプションを指定する

出てきた URL をブラウザに貼り付けて、ログインすれば OK

あとは別拠点側の East01 側も設定する

アカウントの紐づけ

  • アカウント 1 : West01 , East01
  • アカウント 2 : West02 , East02

同一アカウント内のホスト間で、VPN 通信が可能

Loopback 間 疎通確認

West01 : 事前疎通不可確認

vyos@West01# run ping 172.31.255.1
PING 172.31.255.1 (172.31.255.1) 56(84) bytes of data.

West01 -> East01 の Loopback へ ping を打ちながら設定変更する。

West01 : Tailscale にログインして、広報するルートを確定

対向側で集約ルートを広報させる。

Subnets に "!" がついている場合、広報されていないルートが存在する。

West01 : 疎通可能を確認

vyos@West01# run show ip route 172.31.255.1
Routing entry for 0.0.0.0/0
  Known via "static", distance 1, metric 0, best
  Last update 00:31:07 ago
  * 10.10.60.1, via eth3, weight 1
  
vyos@West01# run pin 172.31.255.1
PING 172.31.255.1 (172.31.255.1) 56(84) bytes of data.
64 bytes from 172.31.255.1: icmp_seq=1 ttl=64 time=17.7 ms
64 bytes from 172.31.255.1: icmp_seq=2 ttl=64 time=11.6 ms
^C
--- 172.31.255.1 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1002ms
rtt min/avg/max/mdev = 11.632/14.681/17.730/3.049 ms

vyos@West01# run traceroute 172.31.255.1
traceroute to 172.31.255.1 (172.31.255.1), 30 hops max, 60 byte packets
 1  172.31.255.1 (172.31.255.1)  11.104 ms  13.310 ms  12.934 ms

対向側 East01 Loopback 宛ルートが存在せず、デフォルトルートに向いてしまっており、

VyOS 上でルートが見えないのは好ましくない。

West01 : 対向拠点 Loopback 宛スタティックルートを設定

vyos@West01# set protocols static route 172.31.255.1/32 interface tailscale0
[edit]
vyos@West01# compare
[edit protocols static]
+route 172.31.255.1/32 {
+    interface tailscale0 {
+    }
+}
[edit]
vyos@West01# compare commands
set protocols static route 172.31.255.1/32 interface 'tailscale0'
[edit]
vyos@West01# commit
[edit]
vyos@West01# run show ip route 172.31.255.1/32
Routing entry for 172.31.255.1/32
  Known via "static", distance 1, metric 0, best
  Last update 00:00:36 ago
  * directly connected, tailscale0, weight 1

VyOS 上でスタティックルートが正常に見えるようになった。

West01 : 疎通確認を実施

vyos@West01# run ping 172.31.255.1
PING 172.31.255.1 (172.31.255.1) 56(84) bytes of data.
64 bytes from 172.31.255.1: icmp_seq=1 ttl=64 time=30.2 ms
^C
--- 172.31.255.1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 30.244/30.244/30.244/0.000 ms
[edit]
vyos@West01#
[edit]
vyos@West01# run ping 172.31.255.1 source-address 172.16.255.1
PING 172.31.255.1 (172.31.255.1) from 172.16.255.1 : 56(84) bytes of data.
^C
--- 172.31.255.1 ping statistics ---
3 packets transmitted, 0 received, 100% packet loss, time 2055ms

[edit]
vyos@West01#

West01 Tailscale の 100.64.x.x から対向側 East01 Loopback には疎通可能だが、

Loopback -> Loopback には疎通不可のため、

このままでは eBGP ピアが張れない。


East01 でもスタティックルートを設定する。

vyos@East01# set protocols static route 172.16.255.1/32 interface tailscale0
[edit]
vyos@East01# compare
[edit protocols static route 172.16.255.1/32]
+interface tailscale0 {
+}
[edit]
vyos@East01# commit
[edit]
vyos@East01# run show ip route 172.16.255.1/32
Routing entry for 172.16.255.1/32
  Known via "static", distance 1, metric 0, best
  Last update 00:00:05 ago
  * directly connected, tailscale0, weight 1

[edit]
vyos@East01#

Loopback -> Loopback 間の疎通可能を確認

vyos@West01# run ping 172.31.255.1 source-address 172.16.255.1
PING 172.31.255.1 (172.31.255.1) from 172.16.255.1 : 56(84) bytes of data.
64 bytes from 172.31.255.1: icmp_seq=1 ttl=64 time=10.2 ms
64 bytes from 172.31.255.1: icmp_seq=2 ttl=64 time=11.3 ms
^C
--- 172.31.255.1 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 10.224/10.778/11.333/0.554 ms

BGP ピアの前提条件となる、Loopback 間で疎通可能となった。

各プロトコルの設定例

West01 : BGP

vyos@West01:~$ show configuration commands | match "bgp|route-map|prefix-list"
set policy prefix-list PL_out rule 10 action 'permit'
set policy prefix-list PL_out rule 10 prefix '172.16.0.0/16'
set policy route-map RMAP_out rule 10 action 'permit'
set policy route-map RMAP_out rule 10 match ip address prefix-list 'PL_out'
set protocols bgp address-family ipv4-unicast aggregate-address 172.16.0.0/16 summary-only
set protocols bgp address-family ipv4-unicast redistribute connected
set protocols bgp local-as '64512'
set protocols bgp neighbor 172.16.255.2 address-family ipv4-unicast nexthop-self
set protocols bgp neighbor 172.16.255.2 address-family ipv4-unicast soft-reconfiguration inbound
set protocols bgp neighbor 172.16.255.2 remote-as '64512'
set protocols bgp neighbor 172.16.255.2 update-source 'lo'
set protocols bgp neighbor 172.31.255.1 address-family ipv4-unicast route-map export 'RMAP_out'
set protocols bgp neighbor 172.31.255.1 address-family ipv4-unicast soft-reconfiguration inbound
set protocols bgp neighbor 172.31.255.1 ebgp-multihop '2'
set protocols bgp neighbor 172.31.255.1 remote-as '65552'
set protocols bgp neighbor 172.31.255.1 update-source 'lo'
set protocols bgp parameters router-id '172.16.255.1'
set protocols bgp timers holdtime '30'
set protocols bgp timers keepalive '10'

East01 の BGP 設定例

vyos@East01:~$ show configuration commands | match "bgp|route-map|prefix-list"
set policy prefix-list PL_out rule 10 action 'permit'
set policy prefix-list PL_out rule 10 prefix '172.31.0.0/16'
set policy route-map RMAP_out rule 10 action 'permit'
set policy route-map RMAP_out rule 10 match ip address prefix-list 'PL_out'
set protocols bgp address-family ipv4-unicast aggregate-address 172.31.0.0/16 summary-only
set protocols bgp address-family ipv4-unicast redistribute connected
set protocols bgp local-as '65552'
set protocols bgp neighbor 172.16.255.1 address-family ipv4-unicast route-map export 'RMAP_out'
set protocols bgp neighbor 172.16.255.1 address-family ipv4-unicast soft-reconfiguration inbound
set protocols bgp neighbor 172.16.255.1 ebgp-multihop '2'
set protocols bgp neighbor 172.16.255.1 remote-as '64512'
set protocols bgp neighbor 172.16.255.1 update-source 'lo'
set protocols bgp neighbor 172.31.255.2 address-family ipv4-unicast soft-reconfiguration inbound
set protocols bgp neighbor 172.31.255.2 remote-as '65552'
set protocols bgp neighbor 172.31.255.2 update-source 'lo'
set protocols bgp parameters router-id '172.31.255.1'
set protocols bgp timers holdtime '30'
set protocols bgp timers keepalive '10'

おまけ : 冗長切替のヒント

下位側を connected + VRRP とした場合、HyperVisor 配下で connected の障害を検出することが難しい。

VRRP の切り替えは可能だが、BGP の広報を止められないため、下りトラフィックが流れ込んでしまう。

  • bash script で peer shutdown という手もあるが・・・

以下に下位側を L3SW と OSPF でダイナミックルーティングとした場合について記載する。

上位 eBGP ピア Down 時

わたり eth2 の OSPF + iBGP で迂回するか、下位 OSPF に対向拠点宛のルート広報をやめて、下位側で迂回させる

BGP で受信するルートを死活監視 + tracking して、Down 時に VRRP の優先度を下げる

わたりレス構成で下位 OSPF Down 時

下位 OSPF Down 時に、BGP で集約ルートの広報をやめるように設計する

  • BGP で aggregate-address + redistribute ospf する
    • OSPF Down で再配布が停止される
  • OSPF でサブネットルートが 1 つでもあると BGP で aggregate-address が広報されるため、route-map で Lo を再配布の対象から除外するなどの工夫が必要

Tailscale の TIPS

Tailscale の subnet router は、有効化時に VyOS の動作に影響がある

  • Free プランの 1 アカウント内に 2 台のルータで、同じプレフィックスを advetise-routes すると、片方は通信できない
    • subnet router 冗長化は有料プランのため、Free プランだとこの動作となる模様
    • 副作用で LAN 側の OSPF も止まる


リファレンス

100台まで無料のVPNサービス「Tailscale 」、リンクだけでマシンのシェアも可能!?

引用

  1. 2021-06-25 T3641 (feature): Upgrade base system from Debian Buster -> Debian Bullseye