LoginSignup
22
31

More than 3 years have passed since last update.

AWS Client VPN の導入

Last updated at Posted at 2020-04-12

1. AWS Clinent VPN 導入の目的

スマホからのアクセスを固定IP化したい。

2. AWS Clinetn VPN 導入の経緯

 とある受託案件の検証環境は、今までIP制限をしていました。
 会社のIPはもちろん許可していたため、PCもスマホも会社のネットワークに繋ぐことで検証環境にアクセスできていました。
 しかしコロナウイルスによって在宅勤務が強制されることになったため、自宅環境ではIPの固定化ができず、検証環境にアクセスすることができなくなってしまいました。
※PCであれば会社が用意したVPNに接続することができるのですが、スマホは会社が用意したVPNに接続することができません。
 そのため案件専用のVPNとしてAWS Client VPNを用意し、スマホからのアクセスを固定IP化することにしました。

3. AWSClientVPNのポイント

  • VPC上にClient VPN Endpointを作成することで、クライアント(PCやスマホ)とVPCの間でVPNを張ることができます。

  • OpenVPN(オープンソースのVPNソフトウェア)を利用しています。

  • 認証は ActiveDirectoryによるアカウント管理, サーバ証明書・クライアント証明書による相互認証 のいづれか、もしかは その両方 を利用できます。

  • ActiveDirectory認証では AWSDirectoryService を利用することになります。オンプレのADと連携したい場合は ADConnector を噛ませることで実現可能です。

4. AWSClientVPNの料金

  • A) ClientVPNEndpointに関連付けられているサブネットの数 × 利用時間(hrs)
  • B) アクティブなクライアント接続の数 × 利用時間(hrs)

AとBの合算になります。

4-1. シミュレーション

条件
冗長構成にするために2つのサブネットに関連付けをし、営業日には10端末からそれぞれ2h利用する。

金額計算
- A) 2 × 24 × 30 × 0.15 = $216
- B) 10 × 2 × 20 × 0.05 = $20

合計 $236/月

5. 今回構築した構成のアーキテクチャ

スクリーンショット 2020-04-12 17.27.28.png

5-1. 認証

"ActiveDirectoryによるアカウント管理" をするためには別途 "AWSDirectoryService" の費用がかかってしまうため、今回はサーバ証明書・クライアント証明書による相互認証のみで構築しました。
SimpleADで最低$36/月かかるっぽいです。

5-2. 証明書の作成

もちろん自分自身のPCでもできますが、他のインフラ担当者も同じ認証局が使えるように、共用環境としてVPN Client Endpointを構築するVPCのbastionサーバーにて作成しました。

証明書は内部利用(いわゆるオレオレ証明書)に限られるので、有効期限を100年に設定しました。

5-3. VPC

アクセス先はステージング環境のVPCとなりますが。Client VPN Endpointをステージング環境に構築しても基本的には問題ありませんが、なるべく外部からのアクセスっぽくしたかったのと、ステージング環境に極力手を入れたくなかったため、Client VPN Endpointは別のVPNに構築することにしました。

5-4. 関連付けるサブネット

導入の経緯に書いたようにサービスにクリティカルな用途ではないため、冗長構成にせず1つのサブネットのみに関連付けさせるようにしました。

6. 構築手順

6-1. 証明書の作成

bastionサーバーログインしOpenVPN Easy-RSA レポジトリのクローンを作成します。
なお私はbastionサーバーのrootユーザーになりホームディレクトリをカレントディレクトリとして作業をしましたが、rootユーザーである必要性はありません。

$ cd ~
$ git clone https://github.com/OpenVPN/easy-rsa.git

作成した証明書や鍵をまとめて保管ためのディレクトリを作成しておきます。

$ mkdir ssl

ローカルリポジトリの easy-rsa/easyrsa3 フォルダに移動します

$ cd easy-rsa/easyrsa3

証明書の有効期限を100年に変更します。

$ cp vars.example vars
$ vim vars
$ diff vars.example vars
125c125
< #set_var EASYRSA_CA_EXPIRE    3650
---
> set_var EASYRSA_CA_EXPIRE 36500
129c129
< #set_var EASYRSA_CERT_EXPIRE  825
---
> set_var EASYRSA_CERT_EXPIRE   36500
134c134
< #set_var EASYRSA_CRL_DAYS 180
---
> set_var EASYRSA_CRL_DAYS  36500

新しい PKI 環境を初期化します。

$ ./easyrsa init-pki

6-1-1. ルート証明書

1つだけ作成します。ACMに登録する必要があります。
まずは新しい認証機関(CA)を構築します。

$ ./easyrsa build-ca nopass

画面の指示に従って、CA を構築します。

作成されたルート証明書とルート鍵を保管用ディレクトリにコピーします。

$ cp pki/ca.crt ~/ssl/
$ cp pki/private/ca.key ~/ssl/

ACMに登録します。その際中間証明書(chain)は指定無しで大丈夫です。

$ cd ~/ssl
$ aws acm import-certificate --certificate file://ca.crt --private-key file://ca.key --region ap-northeast-1

6-1-2. サーバー証明書

サーバー証明書は1つだけ作成します。ACMに登録する必要があります。
サーバー証明書とキーを生成します。

$ ./easyrsa build-server-full server nopass

作成されたルート証明書とルート鍵を保管用ディレクトリにコピーします。

$ cp pki/issued/server.crt ~/ssl/
$ cp pki/private/server.key ~/ssl/

サーバー証明書をACMに登録します。その際中間証明書(chain)はルート証明書を指定します。

$ cd ~/ssl
$ aws acm import-certificate --certificate file://server.crt --private-key file://server.key --certificate-chain file://ca.crt --region ap-northeast-1

6-1-3. クライント証明書

ルート証明書をベースに作成します。ユーザー単位、もしくは端末単位など、管理したい単位ごとに作成します。
クライント証明書はACMに登録する必要はありません。

ここでは例として、山田太郎さんのandroid端末用としてクライント証明書を発行します。

$ ./easyrsa build-client-full taro.yamada.android nopass

これでクライント証明書とクライント鍵が以下に作成されました。

6-2. Client VPN Endpoint の作成

AWSマネジメントコンソールにログインし下記の手順で Client VPN Endpoint を作成します。
ステップ 2: Client VPN エンドポイントを作成する

エンドポイント名前、クライアントに割り当てるCIDR、利用するサーバ証明書・ルート証明書などを選択します。(選択する証明書はACMに登録されている必要があります)

接続ログを CloudWatch Logs に残すかどうかも選択できますが、ロググループは自動生成してくれないため、事前に作成したうえで指定するあります。ログストリームはおそらく自動生成してくれるかも。

またクライアントが使用するDNSサーバやTLSセッションにTCP/UDPのどちらを利用するかを選択することができますが、特にこだわりはないのでデフォルトのままとしています。

なお Client VPN Endpoint を作成した時点ではまだ利用料金は発生しません

6-3. Client VPN Endpoint をVPCのサブネットに関連付ける

Client VPN Endpointをサブネットに関連付けすると、サブネットごとにENIが作成されます。ENIが作成された時点から料金が発生することになります。
ステップ 3: クライアントの VPN 接続を有効にする

作成されたENIには、自動的にそのVPCのデフォルトセキュリティグループがアタッチされます。通信元/先IPアドレスやポートを制限したい場合は、別のセキュリティグループをアタッチすることができます。
本来であれば専用のセキュリティグループをアタッチすべきですが、今回はちょっとサボってデフォルトのままとしました。

またクライアントPCからVPN経由でVPC内のリソース等にアクセスすると、接続元IPアドレスはENIのIPになっています(NATされている)。接続先リソースのセキュリティグループ設計はそれを考慮する必要があります。

6-4. クライアントのアクセスの「承認」

クライアント端末からVPC内のどのIPレンジへの通信を許可するか、CIDR形式で許可する必要があります。
ステップ 4: クライアントのネットワークへのアクセスを承認する

認証タブを選択すると、クライアント端末から接続可能な接続先一覧が表示され、許可を追加することができます。デフォルトではどのCIDRも許可されていないので、接続先を追加します。

VPC内の特定のCIDRのみを許可すれば、クライアント端末からはその範囲までにしかアクセスできません。

今回はNATGateway経由でインターネットに出る必要があるため0.0.0.0/0への通信を許可する必要があります。

6-5. 追加のネットワークへのアクセスを有効にする

Client VPN Endpoint には「ルートテーブル」の設定があります。
ステップ 5: (オプション) 追加のネットワークへのアクセスを有効にする

クライアント端末からVPC内にだけ通信する用途であれば、デフォルト設定で問題ありません。
今回はクライアント端末からNATGateway経由でインターネットに出たいので、追加の設定が必要になります。

Client VPN Endpointのルートテーブルにレコードを追加する際には、宛先のCIDRターゲットサブネットの2つを指定します。クライアント端末から通信がClient VPN Endpointに到達すると、その後パケットは、宛先CIDR情報をもとにターゲットサブネットに振られ、そのサブネットのルートテーブルに従います。

そのため今回の用途のように、NATGateway経由でインターネットに出たい場合は、以下のレコードをClient VPN Endpointのルートテーブルに追加することになります。

宛先のCIDRが「0.0.0.0/0」。ターゲットサブネットが「Client VPN Endpointに関連付けたプライベートサブネット」

※そもそもターゲットサブネットは、関連付けたサブネットからしか設定することができません。今回は1つしか関連付けていないため一択となります。

6-6. クライアント用の設定プロファイルをダウンロードする

クライアント用の設定プロファイルをダウンロードして、クライアントソフトに設定します。
ステップ 6: Client VPN エンドポイントの設定ファイルをダウンロードする

マネコンでクライアント設定のダウンロードボタンを押せば.ovpnという拡張子の設定プロファイルをダウンロードできます。

中身は以下のようになっているはずです。

client
dev tun
proto udp
remote cvpn-endpoint-xxxxxxxxxxxxxxxxx.prod.clientvpn.ap-northeast-1.amazonaws.com 443
remote-random-hostname
resolv-retry infinite
nobind
persist-key
persist-tun
remote-cert-tls server
cipher AES-256-GCM
verb 3
<ca>
-----BEGIN CERTIFICATE-----
XXXXXXXXXXXXXXXX
-----END CERTIFICATE-----

</ca>
reneg-sec 0

しかし、このプロファイルそのままではVPN接続ができないため、少しイジってあげる必要があります。

6-6-1. 接続先エンドポイントの細工

接続先のエンドポイントとしては、*.[エンドポイント名].prod.clientvpn.ap-northeast-1.amazonaws.com でIPを取得できますが、ダウンロードしたクライアント設定プロファイルは以下のようになっていました。

remote cvpn-endpoint-xxxxxxxxxxxxxxxxx.prod.clientvpn.ap-northeast-1.amazonaws.com 443

そこで、接続先に適当なホスト部を追記します。

remote dummy.cvpn-endpoint-xxxxxxxxxxxxxxxxx.prod.clientvpn.ap-northeast-1.amazonaws.com 443

6-6-2. クライント証明書と鍵の埋め込み

作成したクライアント証明書の—–BEGIN CERTIFICATE—–から—–END CERTIFICATE—–までと、
クライアント鍵の—–BEGIN PRIVATE KEY—–から—–END PRIVATE KEY—–までを追記します。

<cert>
-----BEGIN CERTIFICATE-----
YYYYYYYYYYYYYYYYYYYY
-----END CERTIFICATE-----
</cert>
<key>
-----BEGIN PRIVATE KEY-----
ZZZZZZZZZZZZZZZZZZZZ
-----END PRIVATE KEY-----
</key>

設定プロファイルは最終的には以下のようになります。

client
dev tun
proto udp
remote *.cvpn-endpoint-XXXXXXXXXXXXXXXX.clientvpn.ap-northeast-1.amazonaws.com 443
remote-random-hostname
resolv-retry infinite
nobind
persist-key
persist-tun
remote-cert-tls server
cipher AES-256-GCM
verb 3
<ca>
-----BEGIN CERTIFICATE-----
XXXXXXXXXXXXXXXXXXXX
-----END CERTIFICATE-----
</ca>
<cert>
-----BEGIN CERTIFICATE-----
YYYYYYYYYYYYYYYYYYYY
-----END CERTIFICATE-----
</cert>
<key>
-----BEGIN PRIVATE KEY-----
ZZZZZZZZZZZZZZZZZZZZ
-----END PRIVATE KEY-----
</key>
reneg-sec 0

7. 運用フェーズ

7-1. クライアント証明書の新規発行

ここでは例として、山田太郎さんのios端末用クライント証明書を新規発行します。

$ CLIENTNAME=taro.yamada.ios
$ cd ~/easy-rsa/easyrsa3
$ ./easyrsa build-client-full ${CLIENTNAME} nopass
$ cp pki/issued/${CLIENTNAME}.crt ~/ssl/
$ cp pki/private/${CLIENTNAME}.key ~/ssl/

7-2. クライアント証明書の無効化

端末を紛失した場合や、漏洩の可能性がある場合には、クライアント証明書を無効化する必要があります。

CRL(クライアント証明書失効リスト)を使用すると、特定のクライアント証明書をブラックリストに入れることができます。ブラックリストに入れたクライアントは、クライアント VPN エンドポイントにアクセスできなくなります。

ここでは例として山田太郎さんのios端末用クライント証明書を失効させます。

ルート証明書・サーバー証明書・クライアント証明書などを作成したbastionサーバーにログインし、easy-rsa/easyrsaフォルダに移動します。

$ CLIENTNAME=taro.yamada.ios
$ cd ~/easy-rsa/easyrsa3

失効リスト用の前準備をします。プロンプトが表示されたらyesと入力します。

$ ./easyrsa revoke ${CLIENTNAME}

Note: using Easy-RSA configuration from: /root/easy-rsa/easyrsa3/vars
Using SSL: openssl OpenSSL 1.0.2k-fips  26 Jan 2017


Please confirm you wish to revoke the certificate with the following subject:

subject=
    commonName                = taro.yamada.ios


Type the word 'yes' to continue, or any other input to abort.
  Continue with revocation:

クライアント証明書失効リストを生成します。

$ ./easyrsa gen-crl
Note: using Easy-RSA configuration from: /root/easy-rsa/easyrsa3/vars
Using SSL: openssl OpenSSL 1.0.2k-fips  26 Jan 2017
Using configuration from /root/easy-rsa/easyrsa3/pki/easy-rsa-17745.1UBzCm/tmp.XrqfAj

An updated CRL has been created.
CRL file: /root/easy-rsa/easyrsa3/pki/crl.pem

このcrl.pemは、今まで失効されたクライアント証明書情報も入っています。
Cleient VPN Endpointに適用します。

$ aws ec2 import-client-vpn-client-certificate-revocation-list --certificate-revocation-list file:/root/easy-rsa/easyrsa3/pki/crl.pem --client-vpn-endpoint-id ${endpoint_id} --region ap-northeast-1

これ以降、該当のクライアント証明書からはVPN接続ができなくなります。

8. AWS Clinetn VPNの制限

Key Value
アカウントあたりの クライアント VPN エンドポイント数 5
クライアント VPN エンドポイントあたりの承認ルールの数 50
クライアント VPN エンドポイントあたりのルート数 10
クライアント VPN エンドポイントあたりの同時クライアント接続数 2000
22
31
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
22
31