[温故知新] Cisco ASA の VPN ロードバランスをもう一度楽しんでみる

# はじめに

私は、シスコシステムズ合同会社で、Firewall やリモートアクセス VPN、IPS といった Network Security 製品とその管理ツールのプリセールスエンジニアとして働いております。
そんな中、シスコシステムズで働く有志による Cisco Systems Japan Advent Calendar 2018 に参加する機会に恵まれました。

2017年版: https://qiita.com/advent-calendar/2017/cisco
2018年版: https://qiita.com/advent-calendar/2018/cisco

この記事は、その Cisco Systems Japan Advent Calendar 2018 の 23日目として投稿しました。
新しい技術にチャレンジする記事が多い中、古くからあって今でも十分使えるかなり便利な機能なのに、なぜかあまり使われていないように見える機能を、どうしてもいろいろな方々に伝えたいので、今回、記事にしてみました。


# リモートアクセス VPN への要件

パブリッククラウド全盛の現代ではありますが、内部ネットワークへの安全なアクセスのためのリモートアクセス VPN の需要というのは、まだまだ非常に多いと思われます。
シスコ社員も、様々なパブリッククラウドでのサービスを利用しながらも、特にエンジニアは、オフィスにあるラボにアクセスするために、社内への安全なアクセス手段として、リモートアクセス VPN を多用しています。

リモートアクセス VPN は、止まってしまうのは困るサービスの一つとなっておりますが、かといって高い費用をかけてまで完全なる無停止な構成を Active / Standby で実現するほどでもない、という声をよく聞きます。もちろん、サービスとしての重要度が高く、無停止でのサービス提供を求める声も多々ありますが、インラインの Firewall や IPS に比べると重要度は低いように感じます。


# シスコ製品でのリモートアクセス VPN

Cisco ASA という、Basic Firewall 兼 VPN 終端装置 + AnyConnect Client という組み合わせが、最も多く使われており、私も商談で提案することが多い組み合わせです。
この ASA は、Active / Standby の HA 構成が実現できます。AnyConnect Client からのリモートアクセス VPN 接続も、単体障害発生時であれば、ほぼ無停止で　Active / Standby の切り替わりが可能です。

一方、Active / Active で全ての ASA をきちんと稼働させて、接続中の ASA がダウンした際にも、"VPN 接続が切れたな" と感じたエンドユーザが再度 AnyConnect Client からの VPN 接続を行えば、何事も無く VPN 接続が確立する、という要件を満たす技術があります。

VPN ロードバランスという機能です。

歴史は古く、ASA の前にあった VPN3000 という製品から組み込まれている機能であり、20年近く経過した今でも、まだ削除されることなく、安定して動く、非常に便利な機能です。
モデルを問わず、複数の ASA を同じ L2 ネットワークに並べて、VPN 接続を受け付けるインターフェイス (一般的には outside 側) に仮想の IP アドレスを持たせ、AnyConnect Client はその仮想 IP アドレス宛てに VPN 接続を行い、ロードバランスされている ASA はその中でいちばん負荷の低い (VPN の接続数という意味での負荷) ASA がその VPN 接続を請け負う、という仕組みです。
専用のロードバランサが無くても、市場からニーズの多い Active / Active 構成を安価に簡単に組める、お得な機能です。

# VPN 接続が確立するまでの流れ図

簡単に図にしてみました。AnyConnect Client は、VPN クラスタの Public (outside) 側の仮想 IP アドレス宛てに VPN 接続を開始しますが、その仮想 IP アドレス宛てに来た VPN 接続要求に対して、Master となる ASA が、クラスタメンバーの中でいちばん負荷が低い ASA の Public IP アドレスに対して再度 VPN 接続を出すように、Client に返します。Client は受け取ったその新しい IP アドレス宛てに、自動的に直接 VPN 接続を開始し、認証が通れば、その ASA と直接 VPN 接続が確立されます。

![20181219_VPNLB-summary.png](https://qiita-image-store.s3.amazonaws.com/0/309674/85a5fff2-3e9c-eebb-f40e-51e066c794c8.png)

# VPN ロードバランスに必要な条件

ASA は、ソフトウェアバージョンもモデルもバラバラで構いません。が、ソフトウェアバージョンは合わせた方がいろいろと楽ではあります。
ASA はクラスタメンバーとなる ASA の Public (outside) 側、および Private (inside) 側が、それぞれ同一サブネット内に配置される必要があります。
クライアントは AnyConnect 3.0 以降で、SSL-VPN フルトンネルでも IPsec でもどちらでも動作します。他には Cisco IOS や ASA5506 などの EzVPN Client、あるいは、Clientless SSL-VPN でも動作します。

# 検証ネットワーク図

ということで実際に設定して動作確認をしてみました。

![20181219_VPNLB-NW.png](https://qiita-image-store.s3.amazonaws.com/0/309674/b88a9256-c57b-6934-770d-eb151a5fb08d.png)

VPN ロードバランスは ASAv でも動作するので、ASA やクライアント PC は ESXi にて動作させています。
ASAv のソフトウェアバージョンは 9.10 を利用しました。AnyConnect のバージョンは 4.7 です。

ASAv10 と ASAv30 (VPN クラスタのマスター選定プライオリティは、ASAv30 の方を高くしています) の 2台の ASA で VPN クラスタを構成し、Public (outside) 側に 192.168.10.50 の VPN 仮想 IP アドレスを持たせています。
クライアント PC は 192.168.10.50 宛てに AnyConnect で SSL-VPN フルトンネルの VPN 接続を行うようにします。

それぞれの ASAv には、内部ネットワークとは異なる IP アドレスをプールさせております。AnyConnect からの VPN 接続が確立された際には、クライアントに割り当てた IP アドレスがホストルートで ASA のルーティングテーブルに乗るようになり、内部のルータと OSPF で経路交換をしています。内部ルータからそれぞれのプールアドレスへの static route を作成しても構いませんし、この例であれば、192.168.20.0/24 のネットワークを、お互いに重ならないように ASAv10 と ASAv30 にプールアドレスとして定義しておけば、内部ルータとのルーティングは考えなくても良くなります。

その他、ユーザ認証はテスト的に ASAv ローカルユーザ DB を使い、証明書エラーは無視するものとして検証を行います。

余談になりますが、ASAv ってライセンス無しでも全機能が使えるので (スループットや同時接続数は落ちます)、ASAv をいろいろと遊んでみる、といったあたりの記事のニーズがあれば、そのうち書いてみたいと思います。

# ASA の設定

ASA で必要な設定を抜粋します。細かいところは人によって変わって来ると思いますが、ざっと雑に設定すると、とりあえずこうなります、という例として参考にしてみてください。また、VPN ロードバランス以外については、設定すべてを拾っているわけではありませんのでご留意ください。
もちろん ASDM (無償 GUI) で設定した方が、感覚的にはわかりやすいかと思います。

ASAv10

```
! ホスト名設定
hostname TMP-ASAv10-1

! VPN 接続時に払い出す IP アドレス (IP Pool) を設定 
ip local pool POOL-1 192.168.110.1-192.168.110.254 mask 255.255.255.0

! インターフェイス設定
interface GigabitEthernet0/0
 nameif outside
 security-level 0
 ip address 192.168.10.51 255.255.255.0 
 no shut
!
interface GigabitEthernet0/1
 nameif inside
 security-level 100
 ip address 192.168.20.51 255.255.255.0 
 no shut
!
interface Management0/0
 management-only
 nameif mgmt
 security-level 100
 ip address 10.71.153.51 255.255.255.128 
 no shut

! VPN 接続時に割り当てたアドレスを隣接ルータに広報する (Reverse Route Injection) ための定義
prefix-list VPN_PREFIX_1 seq 5 permit 192.168.110.0/24 le 32
route-map VPN_POOL_1 permit 1
 match ip address prefix-list VPN_PREFIX_1
router ospf 1
 network 0.0.0.0 0.0.0.0 area 0
 area 0
 redistribute static subnets route-map VPN_POOL_1

! データネットワークと管理ネットワークのゲートウェイ指定
route mgmt 0.0.0.0 0.0.0.0 10.71.153.126 1
route outside 0.0.0.0 0.0.0.0 192.168.10.254 1
route inside 0.0.0.0 0.0.0.0 192.168.20.254 tunneled

! VPN ロードバランスの有効化
vpn load-balancing 
 priority 5
 cluster key CISCO
 cluster ip address 192.168.10.50
 participate

! AnyConnect SSL-VPN フルトンネルをデフォルトのグループポリシーで有効化
webvpn
 enable outside
 anyconnect image disk0:/anyconnect-win-4.7.00136-webdeploy-k9.pkg 1
 anyconnect enable
!
group-policy DfltGrpPolicy attributes
 vpn-tunnel-protocol ssl-client
!
tunnel-group DefaultWEBVPNGroup general-attributes
 address-pool POOL-1

! テスト用ローカルユーザを追加
username user1 password XXXXX
username user2 password YYYYY
username user3 password ZZZZZ
username user4 password PPPPP
```

ASAv30

```

! ホスト名設定
hostname TMP-ASAv30-1

! VPN 接続時に払い出す IP アドレス (IP Pool) を設定 
ip local pool POOL-2 192.168.120.1-192.168.120.254 mask 255.255.255.0

! インターフェイス設定
interface GigabitEthernet0/0
 nameif outside
 security-level 0
 ip address 192.168.10.52 255.255.255.0 
 no shut
!
interface GigabitEthernet0/1
 nameif inside
 security-level 100
 ip address 192.168.20.52 255.255.255.0 
 no shut
!
interface Management0/0
 management-only
 nameif mgmt
 security-level 100
 ip address 10.71.153.52 255.255.255.128 

! Reverse Route Injection (RRI) のための定義

prefix-list VPN_PREFIX_2 seq 5 permit 192.168.120.0/24 le 32
route-map VPN_POOL_2 permit 1
 match ip address prefix-list VPN_PREFIX_2
router ospf 1
 network 0.0.0.0 0.0.0.0 area 0
 area 0
 redistribute static subnets route-map VPN_POOL_2

! データネットワークと管理ネットワークのゲートウェイ指定
route mgmt 0.0.0.0 0.0.0.0 10.71.153.126 1
route outside 0.0.0.0 0.0.0.0 192.168.10.254 1
route inside 0.0.0.0 0.0.0.0 192.168.20.254 tunneled

! VPN ロードバランスの有効化
vpn load-balancing 
 priority 10
 cluster key CISCO
 cluster ip address 192.168.10.50
 participate

! AnyConnect SSL-VPN フルトンネルをデフォルトのグループポリシーで有効化
webvpn
 enable outside
 anyconnect image disk0:/anyconnect-win-4.7.00136-webdeploy-k9.pkg 1
!
group-policy DfltGrpPolicy attributes
 vpn-tunnel-protocol ssl-client 
!
tunnel-group DefaultWEBVPNGroup general-attributes
 address-pool POOL-2

! テスト用ローカルユーザを追加
username user1 password XXXXX
username user2 password YYYYY
username user3 password ZZZZZ
username user4 password PPPPP
```

VPN ロードバランスは、ASA 間の設定の自動同期の仕組みがありません。ユーザ認証 DB は、一般的には RADIUS や LDAP サーバに持たせるので問題無いですが、今回の例のように ASA ローカルに持たせる場合、パスワードの不一致にご注意ください。

見ての通り、VPN ロードバランスそのものの設定は、最低限で以下だけです。

```
vpn load-balancing 
 priority 10   (1-10 で指定、10 が最高。高い方が VPN Cluster のマスターになる)
 cluster key *****
 cluster ip address xx.xx.xx.xx
 participate
```
もしも cluster key を設定しなければ、同一サブネットにある ASA で participate のコマンドが有効になっているものは同じ VPN クラスタを組んでしまうので、cluster key で合言葉を決めておいてください。

Public (outside) 側と Private (inside) 側では、デフォルトで UDP 9023 番ポートを使って互いの情報をやりとりします。このポート番号が使えない場合には、cluster port コマンドで任意のポート番号に変更してください。TCP は使わず、UDP のみになります。

# 動作確認

ここまでの設定が正しく動作すると、show vpn load-balancing コマンドで以下のように表示されます。

ASAv10 (バックアップ)

```
TMP-ASAv10-1# show vpn load-balancing 
--------------------------------------------------------------------------
  Status     Role     Failover   Encryption   Peers     Cluster IP        
--------------------------------------------------------------------------
  Enabled    Backup   n/a        Disabled         1     192.168.10.50

Peers:
--------------------------------------------------------------------------
 Role    Pri  Model             Load-Balancing Version  Public IP         
--------------------------------------------------------------------------
 Backup    5  ASA-VASA                               4  192.168.10.51*
 Master   10  ASA-VASA                               4  192.168.10.52

Total License Load:
--------------------------------------------------------------------------
 AnyConnect Premium/Essentials        Other VPN         Public IP         
 -----------------------------   ---------------------                    
   Limit    Used   Load          Limit    Used   Load                     
--------------------------------------------------------------------------
     250       0      0%           250       0      0%  192.168.10.51*

Licenses Used By Inactive Sessions :
--------------------------------------------------------------------------
 AnyConnect Premium/Essentials     Inactive Load        Public IP         
--------------------------------------------------------------------------
                             0                 0%       192.168.10.51*

```

ASAv30 (マスター)

```
TMP-ASAv30-1# show vpn load-balancing 
--------------------------------------------------------------------------
  Status     Role     Failover   Encryption   Peers     Cluster IP        
--------------------------------------------------------------------------
  Enabled    Master   n/a        Disabled         1     192.168.10.50

Peers:
--------------------------------------------------------------------------
 Role    Pri  Model             Load-Balancing Version  Public IP         
--------------------------------------------------------------------------
 Master   10  ASA-VASA                               4  192.168.10.52*
 Backup    5  ASA-VASA                               4  192.168.10.51

Total License Load:
--------------------------------------------------------------------------
 AnyConnect Premium/Essentials        Other VPN         Public IP         
 -----------------------------   ---------------------                    
   Limit    Used   Load          Limit    Used   Load                     
--------------------------------------------------------------------------
     750       0      0%           750       0      0%  192.168.10.52*
     250       0      0%           250       0      0%  192.168.10.51

Licenses Used By Inactive Sessions :
--------------------------------------------------------------------------
 AnyConnect Premium/Essentials     Inactive Load        Public IP         

```

マスターとバックアップの選定は、priority で指定した数字が大きい方が優先でマスターになります。マスターとなる ASA がダウンした場合には、次に高い priority を指定した ASA がマスターになります。priority コマンドで指定しない場合はデフォルトで "5" になるようです。コマンドラインガイドは、古い ASA のモデルしか書いていないので、あくまでも試した結果でしかありませんが…

では、実際に AnyConnect で VPN 接続を試してみましょう。PC への AnyConnect のインストールおよび日本語化は済んでいるものとします。また、今回はテストということで、以下のように "信頼されていないサーバへの接続をブロック" を無効化しています。

![20181219_AC-untrust-setting.png](https://qiita-image-store.s3.amazonaws.com/0/309674/381fc821-6c33-a935-a8c3-1db38281b996.png)

まず、PC1 から 192.168.10.50 に AnyConnect Client で SSL-VPN フルトンネルの接続を開始してみます。

![20181219_AC-connection-1.png](https://qiita-image-store.s3.amazonaws.com/0/309674/2ea344ed-af95-899e-b785-e2ca36fc9f37.png)

今回のテスト環境では、以下のように証明書が信頼できない旨の警告が出ます。この警告が 192.168.10.50 という仮想 IP アドレスから出ていることを気に留めておいてください。あくまでもテストなので、ここは了承して進みましょう。

![20181219_AC-untrust-warning1.png](https://qiita-image-store.s3.amazonaws.com/0/309674/027615a8-3c3b-4f8b-901e-da53757b2242.png)

すると、次に同じ警告が、ASAv10 の Public アドレスである 192.168.10.51から出てきました。これは、すなわち、AnyConnect Client が、192.168.10.51 に SSL-VPN フルトンネルの接続を開始した (そして、証明書が信頼できない警告が出た) ことになります。つまり、VPN ロードバランスにより、ASAv10 側に直接の VPN 接続を行ったことになります。

![20181219_AC-untrust-warning2.png](https://qiita-image-store.s3.amazonaws.com/0/309674/0c2c03f3-42fb-e263-821e-9c9b053230ea.png)

同様に先に進めてみましょう。user1 というアカウントで認証させると、無事に VPN 接続が確立できました。確立直後のメッセージは、最初に接続しようとした 192.168.10.50 に接続されたように見えます。

![20181219_AC-established.png](https://qiita-image-store.s3.amazonaws.com/0/309674/193d99d9-3f22-cdd7-18f5-225a4989c9a3.png)

しかしながら、改めて AnyConnect Client のアイコンから見てみると、VPN 接続先は、192.168.10.51、すなわち ASAv10 本体であることがわかります。

![20181219_AC-statistics.png](https://qiita-image-store.s3.amazonaws.com/0/309674/a80968d0-4dad-6a2b-4bd0-5eb8ac1f4b03.png)

この状態で、ASAv10 および ASAv30 で show vpn load-balancing コマンドを実行してみると、以下のようになります。

ASAv10

```
TMP-ASAv10-1# show vpn load-balancing 
--------------------------------------------------------------------------
  Status     Role     Failover   Encryption   Peers     Cluster IP        
--------------------------------------------------------------------------
  Enabled    Backup   n/a        Disabled         1     192.168.10.50

Peers:
--------------------------------------------------------------------------
 Role    Pri  Model             Load-Balancing Version  Public IP         
--------------------------------------------------------------------------
 Backup    5  ASA-VASA                               4  192.168.10.51*
 Master   10  ASA-VASA                               4  192.168.10.52

Total License Load:
--------------------------------------------------------------------------
 AnyConnect Premium/Essentials        Other VPN         Public IP         
 -----------------------------   ---------------------                    
   Limit    Used   Load          Limit    Used   Load                     
--------------------------------------------------------------------------
     250       1      0%           250       0      0%  192.168.10.51*

Licenses Used By Inactive Sessions :
--------------------------------------------------------------------------
 AnyConnect Premium/Essentials     Inactive Load        Public IP         
--------------------------------------------------------------------------
                             0                 0%       192.168.10.51*

```

ASAv30

```
TMP-ASAv30-1# show vpn load-balancing 
--------------------------------------------------------------------------
  Status     Role     Failover   Encryption   Peers     Cluster IP        
--------------------------------------------------------------------------
  Enabled    Master   n/a        Disabled         1     192.168.10.50

Peers:
--------------------------------------------------------------------------
 Role    Pri  Model             Load-Balancing Version  Public IP         
--------------------------------------------------------------------------
 Master   10  ASA-VASA                               4  192.168.10.52*
 Backup    5  ASA-VASA                               4  192.168.10.51

Total License Load:
--------------------------------------------------------------------------
 AnyConnect Premium/Essentials        Other VPN         Public IP         
 -----------------------------   ---------------------                    
   Limit    Used   Load          Limit    Used   Load                     
--------------------------------------------------------------------------
     750       0      0%           750       0      0%  192.168.10.52*
     250       1      0%           250       0      0%  192.168.10.51

Licenses Used By Inactive Sessions :
--------------------------------------------------------------------------
 AnyConnect Premium/Essentials     Inactive Load        Public IP         
--------------------------------------------------------------------------
                             0                 0%       192.168.10.52*
                             0                 0%       192.168.10.51

```

ASAv10 が、ライセンスを 1つ消費しており、負荷 (load) はまだ 0% であることがわかります。ASAv10 は、最大で VPN は 250同時接続までが可能で、1接続ということは、まだライセンスの 1% も消費していない、ということです。
また、マスターとなる ASAv30 側は、自分自身にはまだ VPN 接続してくるクライアントがいませんが、VPN ロードバランスのマスターとして、クラスタメンバである ASAv10 の負荷状況を把握しています。

では、PC2 からも 192.168.10.50 に接続してみます。実際に VPN 接続された先は、やはり ASAv10 でした。

ASAv10

```
TMP-ASAv10-1# show vpn load-balancing 
--------------------------------------------------------------------------
  Status     Role     Failover   Encryption   Peers     Cluster IP        
--------------------------------------------------------------------------
  Enabled    Backup   n/a        Disabled         1     192.168.10.50

Peers:
--------------------------------------------------------------------------
 Role    Pri  Model             Load-Balancing Version  Public IP         
--------------------------------------------------------------------------
 Backup    5  ASA-VASA                               4  192.168.10.51*
 Master   10  ASA-VASA                               4  192.168.10.52

Total License Load:
--------------------------------------------------------------------------
 AnyConnect Premium/Essentials        Other VPN         Public IP         
 -----------------------------   ---------------------                    
   Limit    Used   Load          Limit    Used   Load                     
--------------------------------------------------------------------------
     250       2      1%           250       0      0%  192.168.10.51*

Licenses Used By Inactive Sessions :
--------------------------------------------------------------------------
 AnyConnect Premium/Essentials     Inactive Load        Public IP         
--------------------------------------------------------------------------
                             0                 0%       192.168.10.51*

```

ASAv30

```
TMP-ASAv30-1# show vpn load-balancing 
--------------------------------------------------------------------------
  Status     Role     Failover   Encryption   Peers     Cluster IP        
--------------------------------------------------------------------------
  Enabled    Master   n/a        Disabled         1     192.168.10.50

Peers:
--------------------------------------------------------------------------
 Role    Pri  Model             Load-Balancing Version  Public IP         
--------------------------------------------------------------------------
 Master   10  ASA-VASA                               4  192.168.10.52*
 Backup    5  ASA-VASA                               4  192.168.10.51

Total License Load:
--------------------------------------------------------------------------
 AnyConnect Premium/Essentials        Other VPN         Public IP         
 -----------------------------   ---------------------                    
   Limit    Used   Load          Limit    Used   Load                     
--------------------------------------------------------------------------
     750       0      0%           750       0      0%  192.168.10.52*
     250       2      1%           250       0      0%  192.168.10.51

Licenses Used By Inactive Sessions :
--------------------------------------------------------------------------
 AnyConnect Premium/Essentials     Inactive Load        Public IP         
--------------------------------------------------------------------------
                             0                 0%       192.168.10.52*
                             0                 0%       192.168.10.51

```

ただし、先程までと異なり、ASAv10 側の load が 1% まで上昇しました。今、この VPN クラスタは、バックアップである ASAv10 の方が 1% load が高い、という状態です。
ここで、PC3 を同様に 192.168.10.50 に対して VPN 接続してみます。今度は、192.168.10.52、すなわち ASAv30 の Public アドレスに対して接続されました。

![20181219_AC-established-PC3.png](https://qiita-image-store.s3.amazonaws.com/0/309674/fccc685c-01ff-7f0b-d2de-13a639923506.png)

実際に ASA 側で見ても、そのようになっています。

ASAv10

```
TMP-ASAv10-1# show vpn load-balancing 
--------------------------------------------------------------------------
  Status     Role     Failover   Encryption   Peers     Cluster IP        
--------------------------------------------------------------------------
  Enabled    Backup   n/a        Disabled         1     192.168.10.50

Peers:
--------------------------------------------------------------------------
 Role    Pri  Model             Load-Balancing Version  Public IP         
--------------------------------------------------------------------------
 Backup    5  ASA-VASA                               4  192.168.10.51*
 Master   10  ASA-VASA                               4  192.168.10.52

Total License Load:
--------------------------------------------------------------------------
 AnyConnect Premium/Essentials        Other VPN         Public IP         
 -----------------------------   ---------------------                    
   Limit    Used   Load          Limit    Used   Load                     
--------------------------------------------------------------------------
     250       2      1%           250       0      0%  192.168.10.51*

Licenses Used By Inactive Sessions :
--------------------------------------------------------------------------
 AnyConnect Premium/Essentials     Inactive Load        Public IP         
--------------------------------------------------------------------------
                             0                 0%       192.168.10.51*

```

ASAv30

```
TMP-ASAv30-1# show vpn load-balancing 
--------------------------------------------------------------------------
  Status     Role     Failover   Encryption   Peers     Cluster IP        
--------------------------------------------------------------------------
  Enabled    Master   n/a        Disabled         1     192.168.10.50

Peers:
--------------------------------------------------------------------------
 Role    Pri  Model             Load-Balancing Version  Public IP         
--------------------------------------------------------------------------
 Master   10  ASA-VASA                               4  192.168.10.52*
 Backup    5  ASA-VASA                               4  192.168.10.51

Total License Load:
--------------------------------------------------------------------------
 AnyConnect Premium/Essentials        Other VPN         Public IP         
 -----------------------------   ---------------------                    
   Limit    Used   Load          Limit    Used   Load                     
--------------------------------------------------------------------------
     750       1      0%           750       0      0%  192.168.10.52*
     250       2      1%           250       0      0%  192.168.10.51

Licenses Used By Inactive Sessions :
--------------------------------------------------------------------------
 AnyConnect Premium/Essentials     Inactive Load        Public IP         
--------------------------------------------------------------------------
                             0                 0%       192.168.10.52*
                             0                 0%       192.168.10.51

```

PC4 も同様に 192.168.10.50 に接続してみます。結果、192.168.10.52 の ASAv30 側に接続されました。
ASAv30 の show vpn load-balancing 結果だけ載せておきます。

ASAv30

```
TMP-ASAv30-1# show vpn load-balancing 
--------------------------------------------------------------------------
  Status     Role     Failover   Encryption   Peers     Cluster IP        
--------------------------------------------------------------------------
  Enabled    Master   n/a        Disabled         1     192.168.10.50

Peers:
--------------------------------------------------------------------------
 Role    Pri  Model             Load-Balancing Version  Public IP         
--------------------------------------------------------------------------
 Master   10  ASA-VASA                               4  192.168.10.52*
 Backup    5  ASA-VASA                               4  192.168.10.51

Total License Load:
--------------------------------------------------------------------------
 AnyConnect Premium/Essentials        Other VPN         Public IP         
 -----------------------------   ---------------------                    
   Limit    Used   Load          Limit    Used   Load                     
--------------------------------------------------------------------------
     750       2      0%           750       0      0%  192.168.10.52*
     250       2      1%           250       0      0%  192.168.10.51

Licenses Used By Inactive Sessions :
--------------------------------------------------------------------------
 AnyConnect Premium/Essentials     Inactive Load        Public IP         
--------------------------------------------------------------------------
                             0                 0%       192.168.10.52*
                             0                 0%       192.168.10.51

```

実際には、以下のようなアルゴリズムで、マスターは VPN 接続先を決定しております。

* VPN 最大同時接続数に対しての Active な VPN 接続数で、load が決まる。% 単位で表示される。
* マスターは、load がいちばん小さい機器に対して接続させる。
* マスター以外のクラスタメンバすべてが同じ load になったらマスター自身が VPN 接続を受け付ける。
* マスター・バックアップすべてが同じ load になったら、いちばん接続数が小さい機器に対して接続させる。
* マスター・バックアップすべてが同じ load と同じ接続数になったら、IP アドレスがいちばん小さい機器に対して接続させる。

# まとめ

ASA の VPN ロードバランスを使うと、エンドユーザが意識することなく、VPN 接続を複数の ASA で自動的にきれいにロードバランスさせることが可能になります。
すべての ASA デバイス (Max 10台) を、専用のロードバランサを使うことなく、All Active で利用できます。

非常に歴史が長い、古くからある機能ですが、未だに色褪せることなく、便利に利用できる機能です。にもかかわらず、あまり広まっていないように感じておりますので、安価に VPN 接続の冗長性を確保したい場合には、検討してみてください。

### 参考サイト

ASA 9.10 VPN CLI configuration guide
https://www.cisco.com/c/en/us/td/docs/security/asa/asa910/configuration/vpn/asa-910-vpn-config/vpn-ha.html#ID-2186-000003f0

ASA 9.10 VPN ASDM configuration guide
https://www.cisco.com/c/en/us/td/docs/security/asa/asa910/asdm710/vpn/asdm-710-vpn-config/vpn-ha.html#ID-2186-000003f0

### (Appendix) RRI の確認

PC1 から PC4 をこの環境で VPN 接続させると、ルーティングテーブルは以下のようになります。
PC1 は ASAv10 で 192.168.110.1 を、PC2 は ASAv10 で 192.168.110.2 を、PC3 は ASAv30 で 192.168.120.1 を、PC4 は ASAv30 で 192.168.120.2 を割り当てられています。

ASAv10

```
TMP-ASAv10-1# show route 

Codes: L - local, C - connected, S - static, R - RIP, M - mobile, B - BGP
       D - EIGRP, EX - EIGRP external, O - OSPF, IA - OSPF inter area 
       N1 - OSPF NSSA external type 1, N2 - OSPF NSSA external type 2
       E1 - OSPF external type 1, E2 - OSPF external type 2, V - VPN
       i - IS-IS, su - IS-IS summary, L1 - IS-IS level-1, L2 - IS-IS level-2
       ia - IS-IS inter area, * - candidate default, U - per-user static route
       o - ODR, P - periodic downloaded static route, + - replicated route
Gateway of last resort is 192.168.10.254 to network 0.0.0.0

S*       0.0.0.0 0.0.0.0 [1/0] via 192.168.10.254, outside
C        192.168.10.0 255.255.255.0 is directly connected, outside
L        192.168.10.51 255.255.255.255 is directly connected, outside
C        192.168.20.0 255.255.255.0 is directly connected, inside
L        192.168.20.51 255.255.255.255 is directly connected, inside
O        192.168.30.0 255.255.255.0 
           [110/11] via 192.168.20.254, 03:05:32, inside
V        192.168.110.1 255.255.255.255 connected by VPN (advertised), outside
V        192.168.110.2 255.255.255.255 connected by VPN (advertised), outside
O E2     192.168.120.2 255.255.255.255 
           [110/20] via 192.168.10.52, 00:20:03, outside
O E2     192.168.120.3 255.255.255.255 
           [110/20] via 192.168.10.52, 00:14:33, outside
S    0.0.0.0 0.0.0.0 [255/0] via 192.168.20.254, inside tunneled 
              
TMP-ASAv10-1# 
```

ASAv30

```
TMP-ASAv30-1# show route

Codes: L - local, C - connected, S - static, R - RIP, M - mobile, B - BGP
       D - EIGRP, EX - EIGRP external, O - OSPF, IA - OSPF inter area 
       N1 - OSPF NSSA external type 1, N2 - OSPF NSSA external type 2
       E1 - OSPF external type 1, E2 - OSPF external type 2, V - VPN
       i - IS-IS, su - IS-IS summary, L1 - IS-IS level-1, L2 - IS-IS level-2
       ia - IS-IS inter area, * - candidate default, U - per-user static route
       o - ODR, P - periodic downloaded static route, + - replicated route
Gateway of last resort is 192.168.10.254 to network 0.0.0.0

S*       0.0.0.0 0.0.0.0 [1/0] via 192.168.10.254, outside
C        192.168.10.0 255.255.255.0 is directly connected, outside
L        192.168.10.52 255.255.255.255 is directly connected, outside
C        192.168.20.0 255.255.255.0 is directly connected, inside
L        192.168.20.52 255.255.255.255 is directly connected, inside
O        192.168.30.0 255.255.255.0 [110/11] via 192.168.20.254, 1d19h, inside
O E2     192.168.110.1 255.255.255.255 
           [110/20] via 192.168.10.51, 00:35:41, outside
O E2     192.168.110.2 255.255.255.255 
           [110/20] via 192.168.10.51, 00:25:34, outside
V        192.168.120.2 255.255.255.255 connected by VPN (advertised), outside
V        192.168.120.3 255.255.255.255 connected by VPN (advertised), outside
S    0.0.0.0 0.0.0.0 [255/0] via 192.168.20.254, inside tunneled 

TMP-ASAv30-1# 
```

内部ルータ (本当は古い L3 スイッチ)

```
tky1-p04-c3750g-02#show ip route
Codes: L - local, C - connected, S - static, R - RIP, M - mobile, B - BGP
       D - EIGRP, EX - EIGRP external, O - OSPF, IA - OSPF inter area 
       N1 - OSPF NSSA external type 1, N2 - OSPF NSSA external type 2
       E1 - OSPF external type 1, E2 - OSPF external type 2
       i - IS-IS, su - IS-IS summary, L1 - IS-IS level-1, L2 - IS-IS level-2
       ia - IS-IS inter area, * - candidate default, U - per-user static route
       o - ODR, P - periodic downloaded static route, H - NHRP, l - LISP
       + - replicated route, % - next hop override

Gateway of last resort is not set

O     192.168.10.0/24 [110/11] via 192.168.20.52, 1d19h, Vlan383
                      [110/11] via 192.168.20.51, 03:07:56, Vlan383
      192.168.20.0/24 is variably subnetted, 2 subnets, 2 masks
C        192.168.20.0/24 is directly connected, Vlan383
L        192.168.20.254/32 is directly connected, Vlan383
      192.168.30.0/24 is variably subnetted, 2 subnets, 2 masks
C        192.168.30.0/24 is directly connected, Vlan385
L        192.168.30.254/32 is directly connected, Vlan385
      192.168.110.0/32 is subnetted, 2 subnets
O E2     192.168.110.1 [110/20] via 192.168.20.51, 00:36:36, Vlan383
O E2     192.168.110.2 [110/20] via 192.168.20.51, 00:26:29, Vlan383
      192.168.120.0/32 is subnetted, 2 subnets
O E2     192.168.120.2 [110/20] via 192.168.20.52, 00:22:20, Vlan383
O E2     192.168.120.3 [110/20] via 192.168.20.52, 00:16:50, Vlan383
tky1-p04-c3750g-02#
```

内部ルータは、各クライアントのホストルートを ASA から OSPF で受け取っており、クライアントからの通信をどちらの ASA に戻せばいいかを把握できています。