経緯
社内ネットワークのパブリック IP ベースで接続を許可しているものがあるが、
ビルの点検やオフィス移転などにより、一時的に IP が使えない状況が起きても、VPN 経由で対応をできるようにしておきたいといったケースを想定
ただし、スタンバイ状態にしておくと、接続していなくても
0.15USD x 24h x 31day x 2サブネット(接続先) で 約232USD (約2万5千円) 月額かかるので、
使わないときは停止しておきたい
今回前提
- 東京リージョンで利用する前提
- 今回の VPN routing の CIDR は 0.0.0.0/0 で全リクエスト VPN 経由としている
- 本来は IP 許諾が 必要な CIDR だけに絞るほうが帯域による課金も減らせるのでおすすめ
- VPN が起動状態になるまで 10分〜15分まつのは許容
- AD は使わず証明書での認証方式とする
要件
- 一時的なので使っていない間は料金がかからないようにしたい
- AWSの知識がそれほどなくても簡単にVPNを使える状態、使えない状態にしたい
- オフィスの移転が起きようが常に変わらない IP を確保して、許諾したい
サーバ構成図 (稼働時)
サーバ構成図 (停止時)
手順
準備
固定IP取得
$ aws ec2 allocate-address --domain vpc
// 以下のように表示されるので、 IP と AllocationId をメモしておく
{
"PublicIp": "xx.xx.xx.xx",
"PublicIpv4Pool": "amazon",
"Domain": "vpc",
"AllocationId": "eipalloc-00000000000000"
}
ルート証明書、サーバ証明書、サーバ秘密鍵 を AWS Certificate Manager (ACM) に登録
$ git clone https://github.com/OpenVPN/easy-rsa.git
$ cd easy-rsa/easyrsa3
$ echo 'set_var EASYRSA_KEY_SIZE 16384' > vars # 鍵長を 16384bit とする
$ echo 'set_var EASYRSA_CERT_EXPIRE 365' >> vars # 有効期限は 365日とする
$ ./easyrsa init-pki # 初期化
$ ls pki # pki フォルダ配下に必要なデータが生成される
$ ./easyrsa build-ca nopass # Common Name を入力 (ex. vpn.hapitas.jp)
$ ls -l pki/ca.crt # ルート証明書が生成される
$ ./easyrsa build-server-full server nopass # サーバ証明書・サーバ秘密鍵作成
$ ls -l pki/issued/server.crt # サーバ証明書が存在
$ ls -l pki/private/server.key # サーバ秘密鍵が存在
# pki フォルダに生成されたファイルは厳重に管理しておく
# ACM に鍵を登録
$ aws acm import-certificate \
--certificate file://pki/issued/server.crt \
--private-key file://pki/private/server.key \
--certificate-chain file://pki/ca.crt \
--region ap-northeast-1
# 以下のように表示されるのでメモしておく
{
"CertificateArn": "arn:aws:acm:ap-northeast-1:111111111:certificate/11111-1111-1111-1111-1111111111"
}
クライアント証明書、秘密鍵 (これらの情報は機密にメンバー個別に共有しておく)
# 先程のサーバ証明書を作ったあとの手順 (接続するメンバー分だけ作成)
$ USER=s-urabe
$ ./easyrsa build-client-full ${USER} nopass
$ mkdir -p keys/$USER
$ mv -v pki/issued/$USER.crt keys/$USER/client.crt
$ mv -v pki/private/$USER.key keys/$USER/private.key
Nat インスタンス接続用 SSH 鍵作成 (普段接続することないと思いますが)
以下のコマンドの場合はキー名は vpn_nat
$ aws ec2 create-key-pair \
--key-name vpn_nat \
--query 'KeyMaterial' \
--output text > ~/.ssh/vpn_nat.pem
VPN 起動
サーバー側構築
gist に置いている vpn-start-cloudformation.yml をダウンロードします。
yaml ファイルの中で EIPAllocationId
ACMArn
SSHKeyName
の Default 値 は適当な値を設定しているので準備で取得した値を設定し、以下のコマンドを打ちます
aws cloudformation deploy \
--template-file vpn-start-cloudformation.ym \
--stack-name my-vpn
15分〜20分 ほどで起動します。
クライアント側設定
https://ap-northeast-1.console.aws.amazon.com/vpc/home?region=ap-northeast-1#ClientVPNEndpoints:sort=clientVpnEndpointId から Download Client Configuration
を押下し、ovpn ファイルをダウンロードします。
ovpn ファイルの末尾に以下を追記します
echo "cert client.crt" >> downloaded-client-config.ovpn
echo "key private.key" >> downloaded-client-config.ovpn
downloaded-client-config.ovpn ファイルを 先程 クライアント証明書 を配置した keys/$USER と同じディレクトリに配置します。(複数作った場合は複数分)
このディレクトリ構成のまま接続するメンバーに共有していきます。
macOS の場合は、 Tunnelblick Windows の場合は OpenVPN GUI インストーラー を使ってインストールします。
接続し、 https://ifconfig.me などで 接続元 パブリックIP が 固定IP取得 で取得したものと同じであれば 問題ありません
VPN 停止
gist に置いている vpn-stop-cloudformation.yml をダウンロードします。
yaml ファイルの中で ACMArn
の Default 値 は適当な値を設定しているので準備で取得した値を設定し、以下のコマンドを打ちます
aws cloudformation deploy \
--template-file vpn-stop-cloudformation.yml \
--stack-name my-vpn
10分 ほどで終了します。
VPN 起動が必要になったときは サーバー側構築 の手順を実施します。(2回目の起動は10分ほどかかります)