AWS Client VPN の構築・設定（AWS公式VPNアプリ利用）

# AWS Client VPNの構築・設定
今回はテレワークの促進で注目のAWSサービスの１つのであるAWS Clinet VPNをお試し構築してみます。
この手の記事は大量にありますが意外と記事の手順通りにやっても上手くいかないものです...(´・ω・｀)
そこで初心者向けに自分が躓いたところを何が必要で、実際にどう設定したか、備忘録もかねて記事にしました。皆さんのお役に立てれば幸いです。

# AWS Client VPNとは

>AWS VPN は、AWS サイト間 VPN と AWS Client VPN で構成されています。これらを組み合わせることで、ネットワークトラフィックを保護する、高可用性かつ柔軟なマネージドクラウド VPN ソリューションを提供します。

>AWS サイト間 VPN は、ネットワークと Amazon Virtual Private Cloud または AWS Transit Gateway の間に暗号化されたトンネルを作成します。リモートアクセスを管理するために、AWS Client VPN は無料 VPN ソフトウェアクライアントを使用して、ユーザーを AWS またはオンプレミスのリソースに接続します。

ざっくりと何ができるかというとAWS VPCにVPN接続できるようになり、インスタンスなどにプライベートIPアドレスで接続できるようになります。Cisco Anyconnect のAWS版のようなイメージです。

# 今回のゴール
　AWS 公式のクライアントツール（VPNアプリ）を使って、VPN接続を確立し、PCからプライベートIPアドレスでVPC内のEC2インスタンスにRDPできる。

# イメージ図
![修正Client-VPN_Qiita用.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/655033/194c10b5-1386-29f3-9285-b80ebdd64af6.png)

#注意事項
AWS Clinet VPN はエンドポイントにサブネットを関連付けしたタイミングで課金が発生します


#前提条件
 1. AWS Client VPNアプリをインストールできるPCの準備する
 2. 各種証明書発行を行うEC2（Amazon Linux)とVPN接続後にRDP接続するEC2(WindowsOS)を用意する
 3. VPNの認証には「相互認証（証明書認証）」を利用
 4. VPN接続元のPCのセグメントと接続先EC2のセグメントを別セグメントにしておく
 5. 基本的に無料もしくは最低限のスペックで構築する

# 構築手順
 1. 証明書発行を行うEC2（Amazon Linux)をデプロイし、SSH接続できるようにセキュリティグループを設定する
 2. 上記EC2で各種証明書発行を行う
 3. EC2から発行したサーバ証明書と秘密鍵をACMへアップロードする
 4. EC2から発行したクライアント証明書をS3にアップロードする
 5. S3のコンソール画面からPCにクライアント証明書をダウンロードする
 6. クライアントVPNエンドポイントを作成し、有効化する
 7. PCにAWS Client VPNアプリをインストールし、プロファイルを設定する
 8. VPC内にRDP接続試験を行うEC2(WindowsOS) をデプロイする

# 実際にやってみた
　1. は各所に詳しい記事があるので割愛して、2.より始めます。
 
    #EC2にSSH接続して、rootに切替
     sudo su root
    #git コマンドが使えるようにインストール
     yum -y install git
    #git からEASY-RSA をインストール
     git clone https://github.com/OpenVPN/easy-rsa.git
コマンド実行とする以下画面のようになります。
![git-clone_Qiita用.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/655033/5f8af87e-08ee-2758-8518-96b7c7859597.png)
    

    #Eeasyrsa3 のディレクトに移動
     cd easy-rsa/easyrsa3
    #pkiを初期化します
     ./easyrsa init-pki
コマンド実行すると以下画面のようになります。
![easy-rsa-init_Qiita用.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/655033/b11b7a35-059a-68f3-ab31-9651e124d09e.jpeg)

    #CA作成
     ./easyrsa build-ca nopass
     Common Name (eg: your user, host, or server name) [Easy-RSA CA]:sample
      "Sample"の部分は任意の名前に変えてもらってOKです
コマンド実行すると以下画面のようになります。
![comon-name_Qiita用.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/655033/15b797c4-fa55-136f-1dc3-33d44e8ff9f8.jpeg)
![sample-Qiita用.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/655033/fbae12dc-02a7-232e-c5d4-c7b1ba45005e.jpeg)


    #サーバ証明書作成
     ./easyrsa build-server-full server nopass
「server」という名前のサーバ証明書が出来上がります。
コマンド実行すると以下画面のようになります。
![server-cert_Qiita用.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/655033/e68cbb92-612a-6e59-d2d4-75b9022006b6.jpeg)


    #クライアント証明書作成
     ./easyrsa build-client-full client1.domain.tld nopass
コモンネームが「client1.domain.tld」というクライアント証明書が出来上がります。
コマンド実行すると以下画面のようになります。
![Client-cert_Qiita用.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/655033/982105bd-6d08-e00b-2ec8-72e4cbe7db9c.jpeg)

    #作成したサーバ証明書、クライアント証明書、キーを「tmp/sample-key」というディレクトリを作り、そこに集約
     pwd
     mkdir /tmp/sample-key/
     cp pki/ca.crt /tmp/sample-key/
     cp pki/issued/server.crt /tmp/sample-key/
     cp pki/private/server.key /tmp/sample-key/
     cp pki/issued/client1.domain.tld.crt /tmp/sample-key/
     cp pki/private/client1.domain.tld.key /tmp/sample-key/
    # /tmp/sample-keyへディレクトリ移動
     cd /tmp/sample-key/
    # コピーされているか確認
     ls- l
コマンド実行して、以下画面のような表示であればOKです。
![ls-l-Qiita用.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/655033/50761e01-83ce-6a22-12d5-1ecdb5d342cc.png)

これで各種証明書の発行は完了しました。

続いて発行した証明書をACMへアップロードします。
今回はAWS CLIを使ってEC2から直接ACMへアップロードしていきます。EC2からACMにアップロードするにはEC2にACMへのアクセス権限（IAMロール）をアタッチする必要があります。
IMAロールを作成は他に詳しい記事がたくさんありますので、本記事では割愛します。

とりあえず「信頼されたエンティティ」はEC2で、ロールにアタッチするポリシーは「AWSCertificateManagerFullAccess」がついていればOKです。

IAMロールの作成が完了したら、作成したIAMロールをEC2へアタッチします。
EC2のコンソール画面から、対象のEC2インスタンスを選択して、「インスタンスの設定」－「IAMロールの割当て／置換」を選択します。
![IAMロール_Qiita用.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/655033/51162286-1030-48c4-e67d-9f71e03ee0e4.png)

今回は「ACM-Upload」というロールを作成しましたので、それをアタッチします。
![IAMロールー割当_Qiita用.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/655033/d49c8860-753a-b62f-f7b1-24fc4f2a08a2.png)

これでEC2からACMへ証明書をアップロードできる環境が整いしましたので、アップロードしていきます。


    #サーバ証明書をACMへ登録
     aws acm import-certificate --certificate file://server.crt --private-key file://server.key --certificate-chain file://ca.crt --region ap-northeast-1
    #秘密鍵をACMへ登録
     aws acm import-certificate --certificate file://client1.domain.tld.crt --private-key file://client1.domain.tld.key --certificate-chain file://ca.crt --region ap-northeast-1

　これで必要な証明書のACM登録はOKです。
　ACMのコンソール画面で登録されているか確認してみましょう。
　以下の画面のようになっていればOKです。
![ACM-画面_Qiita用.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/655033/51a55a2a-06f7-2081-ec59-89c6764f0879.png)



VPN接続の認証のために作成したクライアント証明書とキーファイルをPCに入れておく必要があります。
それにはPCからアクセスできる場所に各種ファイルをエクスポートしておく必要がありますので、今回はS3へエクスポートします。

まずEC2からS3へデータをアップロードするにあたり、ACMと同じくIAMロールをアタッチする必要があります。EC2からS3へのデータアップロードは以前に記事にしましたので、以下を参考に進めてください。
参考記事：[Amazon EC2(Amazon linux)から直接S3へのファイルコピー](https://qiita.com/u-bayashi/items/89718b1f567a93486e4a)

PCにダウンロードする必要があるのは「client1.domain.tld.crt」と「client1.domain.tld.key」の２つのため、この２つをS3へアップロードして、PCへダウンロードできるようにしておきます。

次にVPCに接続できるようにClient VPN　エンドポイントを設定していきます。
VPCのコンソール画面の「クライアントVPN エンドポイント」を選択
![VPNエンドポイント_コンソールQiita用.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/655033/4f23bf68-c489-ecc1-8d81-4c7db81d8fc9.png)

設定は以下の画面の通りに行います。
![Client-VPN_詳細Qiita用.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/655033/bc065076-98fa-ffe5-4495-3c331048ed45.png)

設定が完了したら、ステータスが「使用可能」になるのを待って
「関連付」でVPN接続で接続可能にするサブネットを設定していきます。
![Client-関連付け_Qiita用.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/655033/49ccc253-9899-4e51-9672-76b09dc08286.png)

★サブネットを関連付けしたタイミングで課金が発生するので注意してください★
　必要なくなったら、関連付けを解除するか、エンドポイントごと削除しましょう！

セキュリティグループで、VPN接続元のCIDRからのRDPを許可しておきましょう。

そして「認証」でVPNでアクセスを有効にするサブネットを設定します。
![Client-VPN-受信の承認_Qiita用.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/655033/ff2df38e-f576-9b60-8be5-d92d510a877c.png)

「受信の承認」をクリックすると15分ほどでステータスが「アクティブ」になります。

これでACMとクライアントVPNエンドポイントの設定は完了です。

最後にVPN接続を行うPCへの設定を行っていきます。
まず当該PCへAWS Clinet VPNアプリをダウンロードします。
DLページ：[AWS Client VPN download](https://aws.amazon.com/jp/vpn/client-vpn-download/)

次にPCからクライアントVPNエンドポイントのコンソール画面にアクセスして、画面上に表示されている「クライアント設定のダウンロード」をクリックし、プロファイルをダウンロードします。
![Client-VPN_DL-Qiita用.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/655033/c26fcded-2cbf-8164-719d-ca9093c1ee50.png)

「downloaded-client-config.ovpn」というファイルがダウンロードされます。
次にEC2からS3へアップデートした証明書と秘密鍵をPCにダウンロードします。

downloaded-client-config.ovpn　をテキストファイルで開くと以下のようになってます。

    client
    dev tun
    proto udp
    remote cvpn-endpoint-xxxxxxxxxx.prod.clientvpn.ap-northeast-1.amazonaws.com 443
    remote-random-hostname
    resolv-retry infinite

    persist-key
    persist-tun
    remote-cert-tls server
    cipher AES-256-GCM
    verb 3
    <ca>
     -----BEGIN CERTIFICATE-----
      XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
      XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
      XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
      XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
      XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
      XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
      XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
      XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
      XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
      XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
     -----END CERTIFICATE-----

    </ca>

    reneg-sec 0

上記の最後に以下を追記します。

    cert /"ファイルを格納しているフォルダ"/client1.domain.tld.crt
    key /"ファイルを格納しているフォルダ"/client1.domain.tld.key

上記２つへのファイルパスは~~downloaded-client-config.ovpnからの相対パス~~以下のように記述します。
例）Cドライブ直下にtmpフォルダを作成して、そこにclient1.domain.tld.crtを置く場合は
　　c:/tmp/client1.domain.tld.crt

PCにダウンロードしたアプリを起動し、プロファイル設定をします。
![AWS_ClientVPN.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/655033/fd8af119-0ef5-6cee-6b74-9a2cb26c631b.png)

★プロファイルを追加しようとして、エラーが出る場合、パスの記述を確認してください。★
"￥"が含まれていたり、パスが間違っていないか確認してください。
downloaded-client-config.ovpn とclient1.domain.tld.crtおよびclient1.domain.tld.keyは同じフォルダに格納しておいた方が分かりやすくて良いと思います。
ただ格納するフォルダにアクセス制限が設定されているとエラーになったりしますので注意しましょう！

プロファイルを設定して接続できるようになれば実際にVPN接続してみましょう。
プライベートIPでEC2インスタンスへRDPしてみます。
![RDP_Qiita用.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/655033/00f59ac9-96cf-d1a2-fa8a-02ed23355a6e.png)
![RDP2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/655033/195e1f07-63b5-22d0-e18b-54ef9e097397.png)

RDPできましたね！
長くなりましたがこれで設定完了です。

# AWS Client VPN の使いどころ
クライアント数に制限なく、、AWS環境へどのPCからでもVPN接続できるようになるのは便利だと思いますが、ランニング費用がVPN Connectと比べてかかるため、利用するシーンを選ぶ必要のあるサービスになります。
例えば会社支給の持ち出し用PCで使うとかですかね。
テレワークの一環として、BYODでの活用できなくはないですが、セキュリティの観点からWorkSpacesの方がいいような気がします...

# おまけ(12月7日更新）
Client VPN には下記のような制約があるのでご注意ください。

・通信可能なケース : VPNクライアント => EC2インスタンスへの HTTP や RDPなどの通信
・通信不可なケース : EC2インスタンス => VPNクライアントへの HTTP や RDPなどの通信

AWS側の仕様で、クライアントPCからVPN内のEC2へ接続はできますが、EC2からクライアントPCへPingやRDPはできないです。
もう少し細かい理由ですが、VPCのルートテーブルにクライアントVPNエンドポイントをターゲットとするルーティングを記載できないからです。
サイト間VPN接続の場合、ターゲットとしてVPGWを選択できますが、クライアントVPNエンドポイントはターゲットとして選択できないため、VPC → クライアントVPNエンドポイントへのルーティングが出来ないということです。

クライアントPC →VPN内のEC2やFSxは問題なく通信できるので、単純にVPN接続して、社内環境にアクセスしたいという用途は満たせますが以下のようなことをしたい場合は実現できません。

・VPC内のEC2からクライアントPCへファイルやソフトウェアの配信および状態監視
・VPC内のEC2にインストールしたクライアント管理ソフトウェア（LanScopeとか）でクライアントPCの遠隔操作

まぁ、万能とはいかないですよね(´・ω・｀)

#参考にしたページ
[[AWS Client VPN] VPC を経由して固定のIPでインターネットへアクセスする](https://dev.classmethod.jp/cloud/aws/aws-client-vpn-with-static-ip/)
[AWS Client VPN 設定メモ](https://qiita.com/hmatsu47/items/ce0cc8b7f5747dbb3190)