初心者向けAWS Client VPN入門

AWSには幾つかの接続方法があります。
普通に接続するのはインターネット接続になります。
ただAWSにセキュアに接続したい場合は幾つかの方法があります。
AWS社の資料[「複数拠点からセキュアにVPCに接続」](https://d1.awsstatic.com/webinars/jp/pdf/services/201910_AWSInnovate_Network.pdf#page=16)を参照して頂ければ解りやすいのですが、代表的な接続方法として以下の3パターンがあります。

|#|方法|回線|内容|
|:------|:------|:------|:-----------------------------------------------|
|1|[Direct Connect](https://docs.aws.amazon.com/ja_jp/directconnect/latest/UserGuide/Welcome.html)|専用線|お客様のデータセンターやオフィスを専用線を介してAWSへプライベートに接続するサービス。|
|2|[Site-to-Site VPN](https://docs.aws.amazon.com/ja_jp/vpn/latest/s2svpn/VPC_VPN.html)|インターネット回線|お客様のデータセンターやオフィスをIPsec VPNを介してAWSへプライベートに接続するサービス。|
|3|[Client VPN](https://docs.aws.amazon.com/ja_jp/vpn/latest/clientvpn-admin/how-it-works.html)|インターネット回線|お客様のクライアントをOpen VPNベースのVPNを介してAWSへプライベートに接続するサービス。|

[<H2>Direct Connect</H2>](https://docs.aws.amazon.com/ja_jp/directconnect/latest/UserGuide/Welcome.html)

Direct Connectは専用線を利用して接続します。メリットは専用線という事で安定した通信が可能という事です。残り2つの方法はインターネット回線の為、帯域が保障されていません。そのため、クリティカルな業務を構築する場合などに利用されます。ただし回線費用が残りの2つの方法と比較すると高額であり、専用線の敷設に3か月程度かかるなど、なかなか大規模な対応が必要になります。

[<H2>Site-to-Site VPN</H2>](https://docs.aws.amazon.com/ja_jp/vpn/latest/s2svpn/VPC_VPN.html)
Site-to-Site VPNはインターネット回線を利用して接続します。専用線と比較すると回線の安定性は劣ります。オンプレ環境側にルーターを設置してIPsec VPNによる暗号化を実現しています。価格の安さと接続の容易さからDirect Connectのバックアップ回線として利用される場合もあります。

[<H2>Client VPN</H2>](https://docs.aws.amazon.com/ja_jp/vpn/latest/clientvpn-admin/how-it-works.html)
Client VPNはインターネット回線を利用して接続します。名前の通りクライアントPCからOpen VPNベースのVPN接続を可能にしています。Site-to-Site VPNはルータの準備が必要でしたが、こちらはツールをダウンロードするだけで接続できるため、安価に即日で接続が可能です。テレワークで自宅環境から会社のAWS環境に接続したい場合などに利用できます。


今回の記事では、誰でも簡易に利用できる「Client VPN」の手順について説明したいと思います。なお、記載内容は個人的なものであり、所属する企業や組織、団体を代表する見解その他ではありませんので、ご承知おきください。


# ■ClientVPN接続を実際にやってみる
ClientVPNの接続方法をイメージする為には、一度実際に接続してみることをお薦めします。ここからは必要な手順を順を追って説明していきます。

まず今回記載する構成の最終系は以下の通りです。
今回はクライアントPCからAWSにClientVPNで接続することを目標とします。また、TeratermからのSSH接続でEC2(Linux)に接続しますが、その接続をVPN経由でのみ可能とする設定を実施します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2253105/d929be38-b76f-ec3b-03d3-ec0611e93c80.png)

当初はインターネットからパブリックIPで接続する以下の構成が出来ていることを前提とします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2253105/22dbd9ff-a487-c6c5-842f-3552888f7c91.png)

また、もう1点、今回はClinetVPN接続に証明書を利用する為、証明書設定の流れが重要です。証明書に関しては以下の関連図を前提に説明します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2253105/4222a850-1909-7f78-a5cd-3aa4f27a6eba.png)


## [（1）サーバーおよびクライアント証明書とキーの生成](https://docs.aws.amazon.com/ja_jp/vpn/latest/clientvpn-admin/client-authentication.html#mutual)

ClientVPNでは3つの認証の最低1つの認証を実施する必要があります。
今回は「相互認証」を実施します。

>・Active Directory 認証 (ユーザーベース)
・相互認証 (証明書ベース)
・シングルサインオン (SAML ベースのフェデレーション認証) (ユーザーベース)

相互認証では、ClientVPN は証明書を使用してクライアントPCとサーバー間の認証を実行します。このステップでは認証機関 (CA) を構築して証明書を発行する必要があります。

なお、ここで実施してる作業は以下の図の通りです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2253105/896f2594-03d5-58e3-f7ed-b98efd688376.png)


まず、前提として証明書サーバ用のEC2環境を起動させる必要があります。
「Amazon Linux 2 AMI (HVM) 」で起動させてみましょう。
その後は「[Linux/macOS](https://docs.aws.amazon.com/ja_jp/vpn/latest/clientvpn-admin/client-authentication.html#linux%2Fmacos)」の手順に従って証明書を作成していきます。

ただし、最初に「git clone」コマンドを実施してますが、gitがインストールされていないので失敗します。開始前に以下のコマンドを実行して、gitのインストールを実施してください。

```linux
sudo yum install git
```
上記でインストール後に「git clone」以降の手順が実施可能です。

「5.」の「クライアント証明書とキーを生成」手順は必要とするエンドユーザ単位で実施する必要があります。例えば3台のクライアントからClientVPNを利用する場合は、以下のような形で3つ作成する必要がある訳です。

```linux
$ ./easyrsa build-client-full client1.domain.tld nopass
$ ./easyrsa build-client-full client2.domain.tld nopass
$ ./easyrsa build-client-full client3.domain.tld nopass
```

「7.」でCLIで「AWS Certificate Manager」に対して証明書をアップロードする手順が記載されています。CLIの初期設定が必要なのですが、ここでは環境から一旦ファイルをダウンロードして、その後「AWS Certificate Manager」に手動でアップロードする手順を（２）に記載します。

## ファイルの取り出し手順
Linuxあまり利用したことが無い人の為に、抽出方法を記載しておきます。Linuxサーバへの接続を「[Tera Term](https://ja.osdn.net/projects/ttssh2/)」で接続している事を前提とします。

まずは「Tera Term」で「ファイル＞SSH SCP」を選択してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2253105/cc081d41-ad13-99dd-e730-a381b9405d24.png)

その後、以下の画面が表示されるので、以下の条件で入力して「Receive」ボタンを押してください。
ファイルが「To」で指定した場所に出力されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2253105/278e5c52-2270-0405-e291-5390b9d969f6.png)
まず、「①」に出力するファイルのフルパスを入力します。出力するファイルのフルパスは「Amazon Linux 2 AMI (HVM) 」であれば以下になると思います。

```linux
/home/ec2-user/custom_folder/ca.crt
/home/ec2-user/custom_folder/client1.domain.tld.crt
/home/ec2-user/custom_folder/client1.domain.tld.key
/home/ec2-user/custom_folder/server.crt
/home/ec2-user/custom_folder/server.key
```

ただし「No such file or directory」と表示された場合はパスが間違っているので、ファイルの場所をもう一度確認するようにしてください。以下の様に対象ファイルの存在するフォルダ階層で「pwd」と打てば確認できます。

```linux
[ec2-user@ip-10-1-0-202 custom_folder]$ ls -t
client2.domain.tld.key  client1.domain.tld.key  server.key  server.crt
client2.domain.tld.crt  client1.domain.tld.crt  ca.crt
[ec2-user@ip-10-1-0-202 custom_folder]$ pwd
/home/ec2-user/custom_folder
```
②にクライアントPC側の出力先を指定します。画面ではディスクトップを指定しています。
そして③の「Recive」ボタンを押すことで出力が可能です。


## [（2）AWS Certificate Managerへの証明書のインポート](https://docs.aws.amazon.com/ja_jp/acm/latest/userguide/import-certificate-api-cli.html)
AWS Certificate Managerへの証明書のインポートは「[証明書のインポート](https://docs.aws.amazon.com/ja_jp/acm/latest/userguide/import-certificate-api-cli.html)」の通り実施します。

作業の内容は以下の図の部分となります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2253105/eefde7b6-9fc7-b973-6add-f1f8f868457d.png)

この証明書登録の際に、何を設定したら良いか悩むと思いますので、貼り付ける必要がある情報を以下に記載します。中身すべてコピーして貼り付ける様にしてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2253105/4392a764-eb48-bbf5-fe28-7bf286e45257.png)

|#|項目名|サーバ証明書|クライアント証明書|
|:------|:------|:------|:-----------------------------------------------|
|①|証明書本文|server.crt|client1.domain.tld.crt|
|①|証明書のプライベートキー|server.key|client1.domain.tld.key|
|①|証明書チェーン|ca.crt|ca.crt|

実際に入力すると以下のようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2253105/c54bb123-964e-06f3-8cc4-74588d319911.png)

クライアント証明書は台数分登録してください。
結果として以下のような状況となります。以下は「サーバ証明書」と2台分の「クライアント証明書」を登録した状態となります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2253105/3a55a54b-fd92-6e89-1a92-efbebeeb903e.png)

証明書について注意が必要なのは「有効期限」です。証明書IDを選択して詳細を確認すると「有効期限」が設定されていることが確認できます。証明書が失効しないように定期的な更新が必要になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2253105/d5852a70-47fc-ab4a-f76d-6159bb838406.png)


## [（3）クライアント VPN エンドポイントを作成する](https://docs.aws.amazon.com/ja_jp/vpn/latest/clientvpn-admin/cvpn-working-endpoints.html#cvpn-working-endpoint-create)
クライアント VPN エンドポイントを作成するとき、VPN 接続を確立するためにクライアントが接続できる VPN 構造を作成します。手順は[「クライアント VPN エンドポイントを作成する」](https://docs.aws.amazon.com/ja_jp/vpn/latest/clientvpn-admin/cvpn-working-endpoints.html#cvpn-working-endpoint-create)の通りです。

以下の図の部分の作業となります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2253105/d11e1e91-51ad-12b6-9d33-e5be436786ec.png)

また、エンドポイント作成時には証明書を定義します。証明書関連図では以下の部分の作業となります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2253105/3e51c880-6853-a889-445c-7e0ad9d765ad.png)

この際にエンドポイント用のCIDRを設定する必要がありますが、IPアドレスの設定は注意が必要です。
>IP アドレス範囲は、ターゲットネットワークまたはクライアント VPN エンドポイントに関連するいずれかのルートと重複できません。クライアント CIDR は、/12～/22 の範囲のブロックサイズが必要で、VPC CIDR またはルートテーブル内のその他のルートと重複できません。クライアント VPN エンドポイントの作成後にクライアント CIDR を変更することはできません。

エンドポイント作成画面では以下の登録画面が表示されるので、先ほどAWS Certificate Managerにインポートしたサーバ証明書をクライアント証明を設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2253105/2e2885b2-765e-1683-5192-8391e8df2950.png)

エンドポイントを作成すると「保留中」と表示されます。そのまま（４）の作業に進んでください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2253105/aaf66c10-2a5a-427a-b839-1b7238a018ca.png)

また、エンドポイントの作成は接続するクライアント単位で作成します。クライアント2台が接続する場合は、以下のクライアント証明書単位で2つ作成する訳です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2253105/d586f56a-fbb3-664c-db7a-f8b735fd6199.png)

## [（4）ターゲットネットワークをクライアント VPN エンドポイントに関連付ける](https://docs.aws.amazon.com/ja_jp/vpn/latest/clientvpn-admin/cvpn-working-target.html#cvpn-working-target-associate)
クライアントが VPN セッションを確立できるようにするため、ターゲットネットワークをクライアント VPN エンドポイントに関連付ける必要があります。ターゲットネットワークは、VPC のサブネットとなります。手順は[「ターゲットネットワークをクライアント VPN エンドポイントに関連付ける」](https://docs.aws.amazon.com/ja_jp/vpn/latest/clientvpn-admin/cvpn-working-target.html#cvpn-working-target-associate)の通りです。

以下の図の部分の作業となります。この関連付けを実施することで、関連付けしたサブネット内にENIで作成されるのがポイントです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2253105/4d228ee5-9db1-a510-aea7-a60652e2b8a4.png)

関連付け実施後は「保留中-関連付け」と表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2253105/b46f114d-7a0c-4202-ae65-db33994a72b9.png)

最終的に時間が経過すると「使用可能」という状態になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2253105/19bb3be9-ecf3-b69d-9c6a-7b786d84e900.png)

この後ネットワークインタフェース画面を確認すると新規に２つのENIが追加されていることが解ります。これがサブネットとClientVPNゲートウェイが通信するためのENIとなります。どのClientVPCエンドポイントと関連しているかは、ENIの「説明」欄で確認することができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2253105/fc6b7164-0853-9946-efd6-8b58ee8b9748.png)

## [（5）クライアント VPN エンドポイントへの承認ルールの追加](https://docs.aws.amazon.com/ja_jp/vpn/latest/clientvpn-admin/cvpn-working-rules.html#cvpn-working-rule-authorize)
承認ルールは、ネットワークへのアクセス許可を与えるファイアウォールルールとして機能します。承認ルールを追加することで、特定のクライアントに対し、特定のネットワークへのアクセス許可を与えます。手順は[「クライアント VPN エンドポイントへの承認ルールの追加」](https://docs.aws.amazon.com/ja_jp/vpn/latest/clientvpn-admin/cvpn-working-rules.html#cvpn-working-rule-authorize)の通りです。

承認設定後は「認証中」となります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2253105/3c50f280-477e-4ae7-c71c-448a6f14991f.png)
最終的に時間が経過すると「アクティブ」になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2253105/8c913051-b08d-f415-ed6e-ddc9de5c9fe6.png)

## [（6）クライアント VPN エンドポイントの分割トンネルに関する考慮事項](https://docs.aws.amazon.com/ja_jp/vpn/latest/clientvpn-admin/cvpn-working-routes.html#split-tunnel-routes)
クライアント VPN エンドポイントで分割トンネルを使用する場合、VPN が確立されると、クライアント VPN ルートテーブル内のすべてのルートがクライアントルートテーブルに追加されます。VPN の確立後にルートを追加する場合は、新しいルートがクライアントに送信されるように接続をリセットする必要があります。今回の作業では割愛しますが、必要に応じて設定してください。

## [（7）クライアント設定ファイルをエクスポートして設定する](https://docs.aws.amazon.com/ja_jp/vpn/latest/clientvpn-admin/cvpn-working-endpoints.html#cvpn-working-endpoint-export)
クライアントPCの設定に必要なクライアント設定ファイルをエクスポートして、設定を実施します。手順は[「クライアント設定ファイルをエクスポートして設定する」](https://docs.aws.amazon.com/ja_jp/vpn/latest/clientvpn-admin/cvpn-working-endpoints.html#cvpn-working-endpoint-export)の通りです。

以下の図の部分の作業となります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2253105/ad380fa3-7a2b-e45f-af61-2f97d3240668.png)

「downloaded-client-config.ovpn」というファイルを開いて修正する必要があるのですが、以下の通り修正すれば問題ありません。

```linux
client
dev tun
proto udp
remote asdf.cvpn-endpoint-0011abcabcabcabc1.prod.clientvpn.eu-west-2.amazonaws.com 443
remote-random-hostname
resolv-retry infinite
nobind
remote-cert-tls server
cipher AES-256-GCM
verb 3

<ca>
※ここはファイルをエクスポートした時点で設定されているので設定不要。
</ca>

<cert>
※ここに「client1.domain.tld.crt」の内容を張り付ける。
</cert>

<key>
※ここに「client1.domain.tld.key」の内容を張り付ける。
</key>

reneg-sec 0
```

## [（8）AWS クライアント VPN をダウンロードしてインストールする](https://aws.amazon.com/jp/vpn/client-vpn-download/)
VPN接続を実施したいクライアントPC(Windows)にClientVPNクライアントをインストールします。インストーラーは[AWS Client VPN download](https://aws.amazon.com/jp/vpn/client-vpn-download/)からダウンロードしてインストールしてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2253105/730696a8-2ebb-b989-c287-4499f805028c.png)

以下の図の部分の作業となります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2253105/048291c1-038a-f0ae-9e35-123a8fa6363f.png)

## [（9）AWS VPN クライアントで接続する](https://docs.aws.amazon.com/ja_jp/vpn/latest/clientvpn-user/client-vpn-connect-windows.html#client-vpn-connect-windows-connecting)
クライアントPCのClientVPNクライアントにプロファイルを登録して接続を実施します。手順は[「AWS VPN クライアントで接続する」](https://docs.aws.amazon.com/ja_jp/vpn/latest/clientvpn-user/client-vpn-connect-windows.html#client-vpn-connect-windows-connecting)の通りです。

以下の図の部分の作業となります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2253105/8d09a9bb-e0ba-5671-7046-405f9382d067.png)


証明書関連図では以下の部分の作業となります。接続用のプロファイルに証明書情報が含まれており、それによって認証されていることが理解できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2253105/603fb72f-e380-0002-64e3-bc1ee2c2c18c.png)


これが接続できている状態です。この状態になると通常のインターネット通信はできなくなります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2253105/acc77548-b833-e2e0-6847-322a948dfb1f.png)

通常ではPingが飛ばないプライベートIPにPingを飛ばして応答があることで、正常に接続出来ていることが確認できます。

```linux
ping 10.1.0.202

10.1.0.202 に ping を送信しています 32 バイトのデータ:
10.1.0.202 からの応答: バイト数 =32 時間 =118ms TTL=63
10.1.0.202 からの応答: バイト数 =32 時間 =123ms TTL=63
10.1.0.202 からの応答: バイト数 =32 時間 =276ms TTL=63
10.1.0.202 からの応答: バイト数 =32 時間 =293ms TTL=63

10.1.0.202 の ping 統計:
    パケット数: 送信 = 4、受信 = 4、損失 = 0 (0% の損失)、
ラウンド トリップの概算時間 (ミリ秒):
    最小 = 118ms、最大 = 293ms、平均 = 202ms
```

敢えて誤った設定で接続してみましたが、その場合は以下の様なメッセージが表示されて接続できません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2253105/b76ad669-437a-3990-fbb3-5da891a23195.png)

実際にTeraTermからもプライベートIPでEC2にSSHで接続できました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2253105/66777d86-0159-79d9-7ba5-55d141c370c5.png)

## （10）EC2へのSSH接続をClinetnVPN経由に制限する
ただ、現状だとパブリックIP経由でもプライベートIP経由でも接続できる状態となっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2253105/acca02d2-f136-0796-69a2-ae98a31c9083.png)


例えばプライベートIP経由での接続のみをSSHで許可したい場合は、セキュリティグループで以下の様に設定変更すれば制御可能です。インターネットからの接続を可能にする場合はソースが「0.0.0.0/0」となっている場合があると思いますが、ここをサブネットの「10.1.0.0/24」に設定変更すれば、プライベートIPでの接続のみが可能となり、ClientVPN経由のみでSSH接続が可能となります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2253105/d9f6b011-b822-ec83-4c6f-b1fa8e8beb4c.png)


# ■まとめ
以上がAWSにおけるClientVPNの接続手順になります。
誰でも簡単に設定できるので、一度自分の手で実施してみることをお薦めします。