目次
はじめに
こんにちは、ディーネットの牛山です。
AWS Client VPN相互認証を利用した、Amazon EC2へのprivate ipでssh接続してみたので紹介します。
AWS Client VPN側でスプリットトンネルを有効状態とし、AWS宛てのトラフィックのみVPNトンネルを通過するようにしています。
構成図
VPN用VPC、検証環境用VPC、本番環境用VPCの3つ用意している構成です。
VPN用VPCから検証環境用VPCと本番環境用VPCへピアリング接続をおこないVPC間の接続をおこなっています。
前置き
大まかな流れを次の通り示します。
- AWS Client VPNで利用するサーバ証明書やクライアント証明書を作成します。
- Terraformより、
1.
で作成した証明書を利用しAWS環境へAWS Client VPN、private EC2へssh接続する環境一式を展開します。 - AWS Client VPNに対してWindows環境から接続し、private EC2へssh接続できることを確認します。
- インターネット向けの通信は、AWSを介さずクライアントのネットワークを利用し接続することを確認します。
それでは実際におこなっていきます。
証明書関連の作成
簡単認証局 作成ツールインストール
easy-rsaと呼ばれるサーバ証明書やクライアント証明書を簡単に作成できるツールをインストールします。
インストールには、epelレポジトリが必要になりますので、epelパッケージがインストールされているかの確認をおこないます。
次のようにdnf repolistコマンド結果に出てこない場合は、dnf install epel-releaseコマンドでepelパッケージをインストールしてください。
# dnf repolist | grep epel
epel Extra Packages for Enterprise Linux 9 - aarch64
※出てこない場合、dnf repolist --enablerepo=epel | grep epelコマンドで念の為、確認するようにしてください。
その後、dnf install easy-rsaコマンドを使用し、easy-rsaをインストールします。
簡単認証局 作成ツール作成スクリプトの設置
easy-rsa設置ディレクトリを作成します。
# mkdir -pv /etc/openvpn/easyRsa
mkdir: created directory '/etc/openvpn'
mkdir: created directory '/etc/openvpn/easyRsa'
easy-rsaは/usr/share/easy-rsa/配下にインストールされていますので先ほど作成したディレクトリへコピーします。
# cp --preserve=all -vir /usr/share/easy-rsa/3.1.6/. /etc/openvpn/easyRsa
'/usr/share/easy-rsa/3.1.6/./easyrsa' -> '/etc/openvpn/easyRsa/./easyrsa'
'/usr/share/easy-rsa/3.1.6/./openssl-easyrsa.cnf' -> '/etc/openvpn/easyRsa/./openssl-easyrsa.cnf'
'/usr/share/easy-rsa/3.1.6/./x509-types' -> '/etc/openvpn/easyRsa/./x509-types'
'/usr/share/easy-rsa/3.1.6/./x509-types/COMMON' -> '/etc/openvpn/easyRsa/./x509-types/COMMON'
'/usr/share/easy-rsa/3.1.6/./x509-types/ca' -> '/etc/openvpn/easyRsa/./x509-types/ca'
'/usr/share/easy-rsa/3.1.6/./x509-types/client' -> '/etc/openvpn/easyRsa/./x509-types/client'
'/usr/share/easy-rsa/3.1.6/./x509-types/code-signing' -> '/etc/openvpn/easyRsa/./x509-types/code-signing'
'/usr/share/easy-rsa/3.1.6/./x509-types/email' -> '/etc/openvpn/easyRsa/./x509-types/email'
'/usr/share/easy-rsa/3.1.6/./x509-types/kdc' -> '/etc/openvpn/easyRsa/./x509-types/kdc'
'/usr/share/easy-rsa/3.1.6/./x509-types/server' -> '/etc/openvpn/easyRsa/./x509-types/server'
'/usr/share/easy-rsa/3.1.6/./x509-types/serverClient' -> '/etc/openvpn/easyRsa/./x509-types/serverClient'
証明書の有効期限を変更
EasyRSAツールに付属している、Easy-RSA設定の組み込み例が記載されている「vars.example」ファイル中にある「EASYRSA_CERT_EXPIRE」「EASYRSA_CRL_DAYS」設定を変更します。
設定ファイルのコピーおよびバックアップをおこないます。
# cp -p /usr/share/doc/easy-rsa/vars.example /etc/openvpn/easyRsa/vars
# cp -p /etc/openvpn/easyRsa/vars /etc/openvpn/easyRsa/vars.org
# cp -p /etc/openvpn/easyRsa/vars /etc/openvpn/easyRsa/vars_$(date +%Y%m%d)
有効期限変更をおこないます。
先ほどコピーしたvarsファイルの設定変更をおこないます。
- EASYRSA_CA_EXPIRE、認証局 (CA) 証明書の有効期間(日数)を10年にします。
- EASYRSA_CERT_EXPIRE、サーバー証明書やクライアント証明書などの個々の証明書の有効期間(日数)を10年にします。
- EASYRSA_CRL_DAYS、証明書失効リスト (CRL) の有効期間(日数)を10年にします。
※それぞれ、先頭に # コメントが付いていますので、アンコメントするようにします。
子細変更内容については以下に記載していますのでご参考にしてください。
# diff -u /etc/openvpn/easyRsa/vars.org /etc/openvpn/easyRsa/vars
--- /etc/openvpn/easyRsa/vars.org 2023-08-18 14:28:23.000000000 +0000
+++ /etc/openvpn/easyRsa/vars 2024-08-04 12:10:44.097867532 +0000
# In how many days should the root CA key expire?
#
-#set_var EASYRSA_CA_EXPIRE 3650
+set_var EASYRSA_CA_EXPIRE 36500
# In how many days should certificates expire?
#
-#set_var EASYRSA_CERT_EXPIRE 825
+set_var EASYRSA_CERT_EXPIRE 36500
# How many days until the next CRL publish date? Note that the CRL can still
# be parsed after this timeframe passes. It is only used for an expected next
# publication date.
#
-#set_var EASYRSA_CRL_DAYS 180
+set_var EASYRSA_CRL_DAYS 36500
# Random serial numbers by default.
# Set to 'no' for the old incremental serial numbers.
認証局 ( CA ) の作成
認証局作成のため初期化をおこないます。
cd /etc/openvpn/easyRsa/
でeasyRsaに移動します。
# ./easyrsa init-pki
Notice
------
'init-pki' complete; you may now create a CA or requests.
Your newly created PKI dir is:
* /etc/openvpn/easyRsa/pki
Using Easy-RSA configuration:
* /etc/openvpn/easyRsa/vars
IMPORTANT:
The preferred location for 'vars' is within the PKI folder.
To silence this message move your 'vars' file to your PKI
or declare your 'vars' file with option: --vars=<FILE>
新しい認証局(CA)を生成します。
ここでは、nopassを指定しパスフレーズなしで生成するようにしています。
「Common Name」を聞かれますので「aws.client.vpn
」(任意値)をタイプし、Enterキーを押し先に進みます。
# ./easyrsa build-ca nopass
Using Easy-RSA 'vars' configuration:
* /etc/openvpn/easyRsa/vars
・
・「中略」
・
Common Name (eg: your user, host, or server name)[Easy-RSA CA]:aws.client.vpn
Notice
------
CA creation complete. Your new CA certificate is at:
* /etc/openvpn/easyRsa/pki/ca.crt
サーバ証明書の作成
サーバ証明書をパスワードなしで、sanおよびコモンネームを指定し作成します。
# ./easyrsa --san=DNS:aws.client.vpn build-server-full aws.client.vpn nopass
※例:./easyrsa --san=DNS:{san名} build-server-full {コモンネーム名} nopass
Using Easy-RSA 'vars' configuration:
* /etc/openvpn/easyRsa/vars
・
・「中略」
・
Notice
------
Private-Key and Public-Certificate-Request files created.
Your files are:
* req: /etc/openvpn/easyRsa/pki/reqs/server.req
* key: /etc/openvpn/easyRsa/pki/private/server.key
You are about to sign the following certificate:
Request subject, to be signed as a server certificate
for '36500' days:
subject=
commonName = aws.client.vpn
X509v3 Subject Alternative Name:
DNS:aws.client.vpn
Type the word 'yes' to continue, or any other input to abort.
Confirm request details: yes
Using configuration from /etc/openvpn/easyRsa/pki/84b3a1ff/temp.1.1
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
commonName :ASN.1 12:'server'
Certificate is to be certified until Aug 2 12:54:47 2124 GMT (36500 days)
Write out database with 1 new entries
Data Base Updated
Notice
------
Certificate created at:
* /etc/openvpn/easyRsa/pki/issued/server.crt
Notice
------
Inline file created:
* /etc/openvpn/easyRsa/pki/inline/server.inline
クライアントサーバー証明書とキーを生成
クライアントから接続する為に必要な証明書を作成
次のコマンドで、クライアント証明書・秘密鍵(パスフレーズ認証なし)の作成します。
サーバ証明書の作成をした時、同様、途中、リクエスト内容の確認が求められますので「yes」をタイプし、Enterします。
# ./easyrsa build-client-full vpn_user nopass
Using Easy-RSA 'vars' configuration:
* /etc/openvpn/easyRsa/vars
・
・「中略」
・
Notice
------
Private-Key and Public-Certificate-Request files created.
Your files are:
* req: /etc/openvpn/easyRsa/pki/reqs/vpn_user.req
* key: /etc/openvpn/easyRsa/pki/private/vpn_user.key
You are about to sign the following certificate:
Request subject, to be signed as a client certificate
for '36500' days:
subject=
commonName = vpn_user
Type the word 'yes' to continue, or any other input to abort.
Confirm request details: yes
Using configuration from /etc/openvpn/easyRsa/pki/openssl-easyrsa.cnf
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
commonName :ASN.1 12:'vpn_user'
Certificate is to be certified until Aug 2 12:56:55 2124 GMT (36500 days)
Write out database with 1 new entries
Data Base Updated
Notice
------
Certificate created at:
* /etc/openvpn/easyRsa/pki/issued/vpn_user.crt
Notice
------
Inline file created:
* /etc/openvpn/easyRsa/pki/inline/vpn_user.inline
ここまで作成した各種証明書を確認します。
# find / -name vpn_user.crt -or -name vpn_user.key -or -name ca.crt -or -name server.crt -or -name server.key | sort
/etc/openvpn/easyRsa/pki/ca.crt
/etc/openvpn/easyRsa/pki/issued/server.crt
/etc/openvpn/easyRsa/pki/issued/vpn_user.crt
/etc/openvpn/easyRsa/pki/private/server.key
/etc/openvpn/easyRsa/pki/private/vpn_user.key
証明書一式のコピー
ここまでで以下証明書類ができあがります。
ファイル | 意味 |
---|---|
ca.crt | CA証明書 |
server.crt | サーバー証明書 |
vpn_user.crt | クライアント証明書 |
server.key | サーバー証明書鍵 |
vpn_user.key | クライアント証明書鍵 |
各種証明書を一式を証明書管理ディレクトリを作成し、コピーします。
# mkdir ~/certificate_manage
# cp -p /etc/openvpn/easyRsa/pki/ca.crt ~/certificate_manage/
# cp -p /etc/openvpn/easyRsa/pki/issued/server.crt ~/certificate_manage/
# cp -p /etc/openvpn/easyRsa/pki/issued/vpn_user.crt ~/certificate_manage/
# cp -p /etc/openvpn/easyRsa/pki/private/server.key ~/certificate_manage/
# cp -p /etc/openvpn/easyRsa/pki/private/vpn_user.key ~/certificate_manage/
コピー後、次の通りになっていることを確認します。
# ls -la ~/certificate_manage
total 40
drwxr-xr-x 2 root root 4096 Aug 4 13:06 .
drwxr-xr-x 1 root root 4096 Aug 4 13:06 ..
-rw------- 1 root root 1216 Aug 4 12:52 ca.crt
-rw------- 1 root root 4643 Aug 4 12:54 server.crt
-rw------- 1 root root 1704 Aug 4 12:54 server.key
-rw------- 1 root root 4509 Aug 4 12:56 vpn_user.crt
-rw------- 1 root root 1704 Aug 4 12:56 vpn_user.key
Terrafomを利用した環境一式展開
Terraformに主眼を置いていませんのでコードの子細説明はしません。
コード中にコメントを付与していますので参考にしてください。
種証明書一式をダウンロード
WinSCP等を利用し、先ほど作成したcertificate_manage配下のファイルを持ってきます。
Terraformから持ってきたファイルを読み込めるよう後ほど設定します。
server.crt、vpn_user.crt
を開き、「-----BEGIN CERTIFICATE-----」~「-----END CERTIFICATE-----」の記載箇所部分のみ残し保存します。
→※証明書部分に不要な記載があるため証明書部分のみ残す必要があります。
Terraformコード抜粋
今回、使用するTerraformコードは次からダウンロード可能です。
コード中にある、次の箇所で持ってきた各種証明書を読み込んでACM上にアップロードする内容です。
読み込むパスは各自環境に合わせてください。
# サーバー証明書のインポート
resource "aws_acm_certificate" "server_cert" {
private_key = file("certificate_manage/server.key")
certificate_body = file("certificate_manage/server.crt")
certificate_chain = file("certificate_manage/ca.crt")
tags = {
Name = "server-cert"
}
}
# クライアントルート証明書のインポート
resource "aws_acm_certificate" "client_root_cert" {
private_key = file("certificate_manage/vpn_user.key")
certificate_body = file("certificate_manage/vpn_user.crt")
certificate_chain = file("certificate_manage/ca.crt")
tags = {
Name = "client-root-cert"
}
}
キーペアについて
EC2インスタンスへssh接続する際に必要な公開鍵を準備し、Terraformから読み込めるようにします。
秘密鍵、公開鍵については各自用意してください。
ファイルパスは各自環境に合わせてください。
resource "aws_key_pair" "aws_key_pair_client-vpn-keypair" {
key_name = "client-vpn-keypair"
public_key = file("keypair/id_rsa.pub")
}
準備が完了したらTerraformからAWS環境へ展開します。
Client VPN、EC2、各種VPC、VPN用ログCloudWatchロググループ、VPCピアリング等ができあがります。
展開には時間を要しますので注意ください。
Client VPN OpenVPN設定ファイルダウンロード
展開先AWSアカウントマネージメントコンソールからVPCサービスページにいきます。
「仮想プライベートネットワーク (VPN)」タブにある「クライアントVPNエンドポイント」を開きます。
次のリンクから直接飛ぶことが可能です。
main-client-vpn
というエンドポイントがありますので、クリックし、「クライアント設定をダウンロード」を押します。
downloaded-client-config.ovpn
がダウンロードされますので開き、クライアント証明書とクライアント鍵を記載し保存します。
記載例を次の通り示します。
client
dev tun
proto udp
remote cvpn-endpoint-***.prod.clientvpn.ap-northeast-1.amazonaws.com 443
remote-random-hostname
resolv-retry infinite
nobind
remote-cert-tls server
cipher AES-256-GCM
verb 3
<ca>
-----BEGIN CERTIFICATE-----
ここにca.crtの内容が記載済み。
-----END CERTIFICATE-----
</ca>
<key>
-----BEGIN PRIVATE KEY-----
ここにvpn_user.key ( クライアントの秘密鍵 ) の内容をコピペ
-----END PRIVATE KEY-----
</key>
<cert>
-----BEGIN CERTIFICATE-----
ここにvpn_user.crt ( クライアント証明書 ) に内容をコピペ
-----END CERTIFICATE-----
</cert>
reneg-sec 0
verify-x509-name server name
動作確認
次のリンクからOpenVPNクライアントをダウンロードし、インストールします。
インストール後、downloaded-client-config.ovpn
をインポートし、AWS Client VPN
に接続します。
EC2への接続
接続完了後、展開先のAWSマネージメントコンソールからEC2サービスページにいきます。
production-ec2-instance、staging-ec2-instance
というEC2インスタンスがありますので、それぞれのEC2インスタンスの「プライベートIPv4アドレス」を指定しssh接続できればokです。
接続の際に、秘密鍵を指定する必要がありますので、キーペアの秘密鍵を指定します。
インターネット向け通信確認
ブラウザからIPアドレス確認ページにいき、IPアドレスの確認をおこないます。
自ネットワークのグローバルIPアドレスになっていることを確認できればokです。
まとめ
実際にAWS Client VPN
からプライベートにあるEC2インスタンスに対して接続することを確認できました。
VPCを跨いだ接続は、VPCピアリングよって接続でき、インターネット向けの通信はAWSを介さないことが確認できました。
プロフィール
AWSの設計・構築をメインにおこなっています。
運用・保守をおこなう部署におりましたが、最近、アーキテクト課に異動しました。
日々精進しております。
LINK
クラウドベリージャム:プロフィールページ