【AWS】AWS Client VPN メモ　～固定グローバルIPでインターネット接続～

# はじめに
AWS Client VPNの環境構築してみました。
今回はビジネス用途で使うケース想定して、インターネットに出るグローバルIPを固定にする環境もあわせて作りました。

基本的には参考にさせていただいた記事、公式のドキュメントの通りですが、
実際に自分で手を動かしてみての、備忘録兼ねた自分用メモです。


# AWS Client VPN 

>『AWS Client VPN は、AWS リソースやオンプレミスネットワーク内のリソースに安全にアクセスできるようにする、クライアントベースのマネージド VPN サービスです。
クライアント VPN を使用すると、OpenVPN ベースの VPN クライアントを使用して、どこからでもリソースにアクセスできます。』

[AWS 公式ドキュメント](https://docs.aws.amazon.com/ja_jp/vpn/latest/clientvpn-admin/what-is.html)

ネットワーク機器の設定が不要で、クライアントソフトについてもAWSが提供しているものがあるため、簡単にVPN接続環境を構築できるのが良い所です。

Client VPNが登場するまでは、AWSにVPN接続をする場合はAWS Site-to-Site VPNを使用する必要がありました。
ただし、Site-to-Site VPNを使用する場合、ルーターを用意して接続設定をする必要があったり、実際に構築した後はルータの保守・運用をする必要があったりと、少しハードルが高めです。
それに比べるとClient VPN、は導入するまでの手順がだいぶ簡単になってます。

## 仕組み（特徴）
ネットワーク的な仕組みについて、前述したAWS Site-to-Site VPNと比較すると、
大きな違いとしては以下になります。

- **Site to Site VPNでは、接続先VPCを超えてVPC Peeringやインターネットへの通信はできない。**
- **ClientVPNでは、接続先VPCを超えた宛先への通信が可能。**

上記それぞれの特徴の詳細な違いについては、以下資料を参考にさせていただきました。
特に14ページからの「ClientVPNがVPCを超えた先への通信が可能」な理由が、とても分かりやすかったです。

■[JAWS-UG Tokyo 32] AWS Client VPNの特徴
[![thumbnail](http://image.slidesharecdn.com/jaws-ugtokyonw-190925163728/95/slide-14-1024.jpg)](https://www.slideshare.net/skikuchi/jawsug-tokyo-32-aws-client-vpn)

## 制限（クオータ）
AWS アカウントには、クライアント VPN エンドポイントに関連する次のクォータがあります。
特に明記されていない限り、これらのクォータの引き上げをリクエストできます。

|   | クオータ数  |
|:-:|--:|
| アカウントあたりの クライアント VPN エンドポイント数 |  5 |
| クライアント VPN エンドポイントあたりの承認ルールの数 |  50 |
| クライアント VPN エンドポイントあたりのルート数 | 10 |
| クライアント VPN エンドポイントあたりの同時クライアント接続数 |2,000|
| クライアント証明書失効リストのエントリ数 |20,000|

参考：[AWS クライアント VPN クォータ](https://docs.aws.amazon.com/ja_jp/vpn/latest/clientvpn-admin/limits.html)

## 料金（環境全体）
今回構築する環境全体で発生する費用としては、
大きく分けて、AWS Client VPNの費用とNATゲートウェイの費用の2つです。
（2021/01現在）東京リージョンで考えると、以下のようになります。

### ①AWS Client VPNの料金
1. ClientVPCエンドポイントに関連付けられているサブネットの数 × 利用時間：0.15USD/時間
2. ClientVPCエンドポイントに接続されているアクティブなクライアントの数 × 利用時間：0.05USD/時間


### ②NAT ゲートウェイの料金
1. NAT ゲートウェイがプロビジョニングされ利用可能であった 時間料金：0.062USD/時
2. データ処理料金(NAT ゲートウェイで処理されたギガバイト単位)     ：0.062USD/GB

### 環境全体の料金(①＋②)
(データ処理料金と VPN 接続料金は除いて)
環境を作って維持しておくだけで、以下の費用が発生します。結構いいお値段です。

- 1日あたり <br>
(0.062 + 0.15) * 24時間 = 5.09USD/日
- 1ヶ月あたり <br>
5.09 * 30日 = 152.7USD/月 

※最新の情報、及び料金詳細については、以下公式ページをご参照ください。
[AWS公式のVPN料金ページ](https://aws.amazon.com/jp/vpn/pricing/)
[AWS公式のVPC料金ページ](https://aws.amazon.com/jp/vpc/pricing/)


# 実際にやってみる（環境構築）

## 全体構成（アーキテクチャ）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955507/919f38ed-31cc-a64c-80aa-dc174ccf8028.png)


### 認証
- VPN接続の認証は
Active Directoryによるアカウント管理, 
サーバ証明書・クライアント証明書による相互認証、その両方の3種から選択できますが、今回は**証明書による相互認証**で試します。

(2021/01/29更新)SAML認証のサポートしてましたね。。
今度、SAML認証で試してみたいと思います。
[AWS Client VPN で SAML 2.0 経由のフェデレーション認証のサポートを開始](https://aws.amazon.com/jp/about-aws/whats-new/2020/05/aws-client-vpn-supports-federated-authentication-via-saml-2/)


- 認証に必要な証明書を作成について、今回はAWS上のCloud9（Linuxサーバ）で作成します。

## 環境構築手順

構築は以下の手順で進めます。
大きく分けて「AWSClientVPNの設定」と「NATゲートウェイの設定」の2つです。
AWS Client VPNの設定は[公式ドキュメント](https://docs.aws.amazon.com/ja_jp/vpn/latest/clientvpn-admin/cvpn-getting-started.html)の手順を参考にしています。

### 1.AWS Client VPNの設定
[1-1. 証明書の作成](#1-1証明書の作成)
[1-2. 証明書をACMへインポート](#1-2証明書をacmへインポート)
[1-3. クライアントVPNエンドポイントの作成](#1-3クライアントvpnエンドポイントの作成)
[1-4. サブネットの関連付け](#1-4サブネットの関連付け)
[1-5. クライアントのネットワークへのアクセスを承認する](#1-5クライアントのネットワークへのアクセスを承認する)
[1-6. クライアントVPNエンドポイントの設定ファイルをダウンロードする](#1-6クライアントvpnエンドポイントの設定ファイルをダウンロードする)
[1-7. クライアントアプリケーションの入手、設定](#1-7クライアントアプリケーションの入手設定)

### 2.NATゲートウェイの設定
[2-1. パブリックサブネットにNATゲートウェイを作成](#2-1パブリックサブネットにnatゲートウェイを作成)
[2-2. プライベートサブネットのルートテーブルを設定](#2-2プライベートサブネットのルートテーブルを設定)
[2-3. ClientVPNエンドポイントにプライベートサブネットを関連付け](#2-3clientvpnエンドポイントにプライベートサブネットを関連付け)
[2-4. ClientVPNエンドポイントのルートテーブルと認証ルールを設定](#2-4clientvpnエンドポイントのルートテーブルと認証ルールを設定)
[2-5. 通信確認](#2-5通信確認)

## 1-1.証明書の作成
- OpenVPN easy-rsa を使用してサーバーとクライアントの証明書とキーを生成してから、<br>
そのサーバーの証明書とキーを ACM にアップロードします

OpenVPN easy-rsa リポジトリのクローンをローカルコンピュータに作成して、easy-rsa/easyrsa3 フォルダに移動します。

```
$ git clone https://github.com/OpenVPN/easy-rsa.git
$ cd easy-rsa/easyrsa3
```
新しい PKI 環境を初期化します。

```
$ ./easyrsa init-pki
```

新しい認証機関 (CA) を構築します。CommonNameは任意の名前を入力します。

```
$ ./easyrsa build-ca nopass
```
サーバー証明書とキーを生成します。

```
$ ./easyrsa build-server-full server nopass
```
クライアント証明書とキーを生成します。

```
$ ./easyrsa build-client-full client1.domain.tld nopass
```
サーバー証明書とキー、およびクライアント証明書とキーをcert_folderフォルダにコピーして移動します。

```
$ mkdir ~/cert_folder/
$ cp pki/ca.crt ~/cert_folder/
$ cp pki/issued/server.crt ~/cert_folder/
$ cp pki/private/server.key ~/cert_folder/
$ cp pki/issued/client1.domain.tld.crt ~/cert_folder
$ cp pki/private/client1.domain.tld.key ~/cert_folder/
$ cd ~/cert_folder/
```
## 1-2.証明書をACMへインポート
- 作成した証明書をACM（AWS Certificate Manager）へインポートする必要があります。<br>
 AWS CLIでインポートする場合は以下のコマンドで実行できます。<br>
 今回はCloud9からそのままインポートを実行します。

```
$ aws acm import-certificate --certificate fileb://server.crt --private-key fileb://server.key --certificate-chain fileb://ca.crt --region region
$ aws acm import-certificate --certificate fileb://client1.domain.tld.crt --private-key fileb://client1.domain.tld.key --certificate-chain fileb://ca.crt --region region
```

マネジメントコンソールのACMの画面で見ると、インポートされているのが確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955507/0ba7d0af-7de9-03b5-aee6-4ccae5e934da.png)

## 1-3.クライアントVPNエンドポイントの作成
- マネジメントコンソールのVPCの画面からクライアントVPNエンドポイントを作成していきます。<br>
ナビゲーションペインで [クライアント VPN エンドポイント] を選択し、<br>
[クライアント VPN エンドポイントの作成] を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955507/765bd0b6-6370-7ae3-75b7-15b002b129f3.png)

- 以下のように入力します。
    - 名前タグ：任意の名前を入力します。記載しなくても問題ありません。
    - クライアント IPv4 CIDR：PCが所属するネットワークのCIDRを指定します。**VPCのCIDRとは別です。**<br>
        - クライアント CIDR は、/12～/22 の範囲のブロックサイズが必要で、VPC CIDR またはルートテーブル内のその他のルートと重複できません。
    - サーバー証明書 ARN： #1-2で、 ACMにインポートしたサーバ証明書を指定します。
    - 認証オプション：[相互認証の使用]を選択します。
    - クライアント証明書 ARN：#1-2で、ACMにインポートしたクライアント証明書を指定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955507/778c1708-64d2-3224-3ca2-fcc4d8e1254e.png)

- 以降の設定は、すべてデフォルトのままエンドポイントを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955507/2d806b73-d86b-f750-5cd9-f4a2167279a6.png)


## 1-4.サブネットの関連付け
- クライアントが VPN セッションを確立できるようにするため、ターゲットネットワークをクライアント VPN エンドポイントに関連付ける必要があります。ターゲットネットワークは、VPC のサブネットです.
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955507/3e3bf828-3ea4-1dd6-f5d9-a93da56c0ef6.png)

- 関連付けするVPCとサブネットを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955507/bf95df53-8ccf-b837-67f2-6932128fce20.png)

- しばらくすると関連付けが完了して使用可能な状態になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955507/2fcd93b4-171e-a8ea-95d6-5e83c2e97386.png)

## 1-5.クライアントのネットワークへのアクセスを承認する
- 関連付けられているサブネットが存在する VPC へのアクセスをクライアントに承認するために、承認ルールを作成する必要があります。承認ルールには、どのクライアントが VPC にアクセスできるかを指定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955507/cbc19b0c-54f0-fb53-628a-37e433b1e1fd.png)

- アクセスを有効にする送信先ネットに接続するVPC全体のCIDR(今回でいうと10.0.0.0/16)を指定して「すべてのユーザーにアクセスを許可する」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955507/7ef7aace-8f57-9083-f46d-73d710bb6af4.png)

## 1-6.クライアントVPNエンドポイントの設定ファイルをダウンロードする
- 最後のステップでは、クライアント VPN エンドポイント設定ファイルをダウンロードして準備します。設定ファイルには、クライアント VPN エンドポイントと VPN 接続を確立するために必要な証明書情報が含まれています。
- VPN 接続を確立するためにクライアント VPN エンドポイントに接続する必要があるクライアントにこのファイルを指定する必要があります。クライアントは、VPN クライアントアプリケーションにこのファイルをアップロードします。

- エンドポイントの画面から設定ファイルをダウンロードします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955507/90389f02-143d-90e0-d9b0-1833fe3c7fd5.png)

- 1-1で生成されたクライアント証明書とキーを確認しておきます。
クライアント証明書とキーは、クローンされた OpenVPN easy-rsa repo の次の場所にあります。
クライアント証明書 — easy-rsa/easyrsa3/pki/issued/client1.domain.tld.crt
クライアントキー — easy-rsa/easyrsa3/pki/private/client1.domain.tld.key

- ダウンロードした.ovpn拡張子のファイルを、任意のテキストエディタを使用してクライアント VPN エンドポイント設定ファイルを開き、
<cert></cert> タグ間にクライアント証明書(client1.domain.tld.crt)の内容を追加し、
<key></key> タグ間にプライベートキー(client1.domain.tld.key)の内容を追加します。

```
<cert>
-----BEGIN CERTIFICATE-----
※最初に作成したclient1.domain.tld.crt　の中身
-----END CERTIFICATE-----
</cert>

<key>
-----BEGIN PRIVATE KEY-----
※最初に作成したclient1.domain.tld.key
-----END PRIVATE KEY-----
</key>
```

- クライアント VPN エンドポイントの DNS 名の先頭にランダムな文字列を追加します。クライアント VPN エンドポイントの DNS 名を指定する行を見つけ、その前にランダム文字列を追加します

```
remote cvpn-endpoint-0102bc4c2eEXAMPLE.prod.clientvpn.us-west-2.amazonaws.com　443
```
↓

```
remote asdfa.cvpn-endpoint-0102bc4c2eEXAMPLE.prod.clientvpn.us-west-2.amazonaws.com　443
```

## 1-7.クライアントアプリケーションの入手、設定
- OpenVPN ベースのクライアントアプリケーションである、AWS公式のクライアントアプリケーションを今回は使用します。
- 以下からダウンロードして手順に沿って、インストールします。<br>
https://aws.amazon.com/jp/vpn/client-vpn-download/
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955507/bb827a53-97a3-3ca5-d0cb-016d5a232618.png)

- クライアントアプリケーションを起動して、先ほど修正した設定ファイルをプロファイルとして登録します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955507/624152d8-060e-340b-eb6b-0c9f7c00cbf4.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955507/ce37e47b-bb5b-1806-058a-6049f8bb3ffe.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955507/63081e6e-6281-8e6d-195e-0e405528b980.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955507/3d2d2ff1-4e56-fe5b-4045-a6f10bbba8ce.png)

- 接続準備完了となったら接続してみて、[接続済み]となればOKです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955507/fe2f8960-b995-58e2-bb3a-da172b7cb0f4.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955507/8a16a42e-4e29-b8b6-07e0-240cfa80ceea.png)

- PCのIPアドレスを確認すると、「クライアント IPv4 CIDR」に設定したネットワークのIPアドレス「10.20.0.130」が設定されていることがわかります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955507/aa1f53fc-fb15-3cd9-8e87-55262acc98eb.png)

## 2-1.パブリックサブネットにNATゲートウェイを作成
- パブリックサブネットにNATゲートウェイを作成します。ここで割り当てられたElastic IPが、インターネットにアクセスするSource IPになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955507/c2a9663b-ea98-b896-5a06-0eb6ed09ce9d.png)

## 2-2.プライベートサブネットのルートテーブルを設定
- 「#1.AWS Client VPNの設定」で既に作成しているプライベートサブネットに対して、専用のルートテーブルを作成し、宛先0.0.0.0/0へのターゲットを先ほど作成したNATゲートウェイに設定します。
- プライベートサブネットに設定するサブネットに、そのルートテーブルを割り当てます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955507/0e993c74-0eb8-4d28-9c52-3e0207a4bdd9.png)

## 2-3.ClientVPNエンドポイントにプライベートサブネットを関連付け
- Client VPN エンドポイントのルートテーブルに、宛先0.0.0.0/0を設定し、ターゲットサブネットには同様にプライベートサブネットを選びます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955507/3017b4e5-4a92-e80b-a506-dbf5d38c291d.png)

## 2-4.ClientVPNエンドポイントのルートテーブルと認証ルールを設定
- 認証ルールの設定です。ルートテーブルと同様に、宛先0.0.0.0/0を追加して許可します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955507/809e0d99-c4b9-2d70-dc32-3ac72f7abb4a.png)

## 2-5.通信確認
- 「1.AWS Client VPNの設定」で作成したVPNクライアントソフト、でVPN接続をおこないます。[Whatismyip](https://www.whatismyip.com/) でアクセスしているIPアドレスを確認します。
- 「2-1.パブリックサブネットにNAT Gatewayを作成」で確認した、NAT Gateway割り当てのElastic IPと一致していることが確認できました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955507/102979d9-46c1-4b69-5872-2fe915d5f706.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955507/62b50fe0-7d1f-0d6c-6e8f-4f1dc4320433.png)


## 参考にさせていただいた記事：
* [AWS Client VPN　クライアント VPN の開始方法（AWS公式）](https://docs.aws.amazon.com/ja_jp/vpn/latest/clientvpn-admin/cvpn-getting-started.html)
* [[AWS Client VPN] VPC を経由して固定のIPでインターネットへアクセスする（Developers.IO）](https://dev.classmethod.jp/articles/aws-client-vpn-with-static-ip/)
* [AWS Client VPNを試してみる（fu3ak1‘s tech days）]
(https://fu3ak1.hatenablog.com/entry/2020/08/12/145243)
* [AWS Client VPN 経由でグローバルIPを固定する](https://qiita.com/kskinaba/items/f7d848a5621de19e1db4)
* [AWS Client VPN の導入](https://qiita.com/tomozo6/items/92382f57b747d325352b)