Easy-RSA 3を使用したClient VPNのサーバー証明書更新
はじめに
こんにちは!
クラウド事業本部コンサルティング部のぐっさんです。
Client VPNの構築とともにEasy-RSA 3を使用したサーバー証明書の作成と更新を検証しています。
GitHubのリポジトリを見ていたところ、Easy-RSAの3.2.xの証明書更新時のコマンドが更新されていることを確認したため試してみました。
前提
- サーバー証明書のみの検証です。クライアント証明書やCAの更新は今回の検証スコープ外です。
- Client VPNはAD認証を使用しています。詳しい設定の説明などは記事の中で参考ブログを記載しますのでそちらをご確認ください。
- Easy-RSA 3は現在も開発が進められており今後のアップデートでコマンド等が変わる可能性もあります。その時の最新情報を確認ください。
- Client VPN自体の理解には、以下のブログを参照ください!
先に更新手順まとめ(忙しい方向け)
Easy-RSAバージョン3.2.xでのサーバー証明書更新手順を先にまとめておきます。
条件
- 初回作成時にPKI環境をZIPファイルでローカルに保存済み
- 既存のClient VPNエンドポイントが存在しそれに紐づくACM証明書ARNを把握済み
1. ZIPでまとめたPKIファイルをCloudShellにアップロード
ローカルに保管されているPKIファイルをCloudShellにアップロード
- CloudShellの「アクション」→「ファイルのアップロード」からローカルに保存済みのZIPファイル(ファイル名の例:easy-rsa-pki.zip)をアップロード
適宜ご自身のファイルの名称に置き換えてください。
アップロードしたファイルを解凍
cd ~
unzip easy-rsa-pki.zip
ls -l # easy-rsaディレクトリが復元されているか確認
2. Easy-RSAディレクトリに移動
cd easy-rsa/easyrsa3
pwd # 現在位置確認
/home/cloudshell-user/easy-rsa/easyrsa3
であること
3. 有効期限設定(変更する場合必要に応じて)
vi vars
EASYRSA_CERT_EXPIRE
の値を希望の日数に変更し保存
4. 証明書更新実行
./easyrsa renew server
確認プロンプトに「yes」で応答
5. 既存のACMにインポート
※必ずClient VPNに紐づいているACMのARNを指定する
証明書ファイルをまとめるためのカスタムフォルダの名称は任意の名前で構いません。
mkdir ~/custom_folder_$(date +%Y%m%d)
cp pki/ca.crt ~/custom_folder_$(date +%Y%m%d)/
cp pki/issued/server.crt ~/custom_folder_$(date +%Y%m%d)/
cp pki/private/server.key ~/custom_folder_$(date +%Y%m%d)/
cd ~/custom_folder_$(date +%Y%m%d)/
aws acm import-certificate \
--certificate fileb://server.crt \
--private-key fileb://server.key \
--certificate-chain fileb://ca.crt \
--certificate-arn <既存ACMの証明書ARN>
6. VPN接続テスト
- Client VPNで接続確認を実施
- ※証明書反映まで最大5時間かかる場合があるため一定時間後に確認が必要
7. 古い証明書の失効(※VPN接続確認後)
cd ~/easy-rsa/easyrsa3
./easyrsa revoke-renewed server
確認プロンプトに「yes」で応答
8. 更新後のPKI環境をローカルに保存・CloudShellから削除
PKI環境をZIPでまとめる
ファイル名は任意の名前で構いません。
cd ~
zip -r easy-rsa-pki-$(date +%Y%m%d).zip easy-rsa/
ls -l easy-rsa-pki-*.zip # ZIPファイル作成確認
ZIPファイルをローカルPCにダウンロードし安全な場所に保管
- CloudShellの「アクション」→「ファイルのダウンロード」から作成したZIPファイルをダウンロード
- 個別のファイルパスにzipファイル名を入力してダウンロード
- ファイル名例:easy-rsa-pki-20250820.zip
- ローカルにファイルがダウンロードされたことを確認し適切な場所に保管する
CloudShellから作業ファイルを削除(※必ずローカルにzipファイルを保管したことを確認の上実施)
rm -rf easy-rsa/
rm -rf custom_folder_*/
rm easy-rsa-pki-*.zip
ls -l # クリーンアップ確認
9. 作業完了
- ローカルに最新のPKI環境が保存完了であること
- CloudShellはクリーンな状態に復旧済みであること
- 次回更新時は手順1から繰り返し実施
以上です。
以降の記事は、実際にClient VPNを構築しながら証明書の初回構築や動作確認なども実施していますので参考までにどうぞ!
Easy-RSA 概要
Easy RSAは、PKI(Public Key Infrastructure)を簡単に構築・管理するためのツールです。
PKIとは公開鍵基盤と呼ばれる、デジタル証明書と公開鍵暗号を管理するためのフレームワークです。
PKIの詳細説明などはこの記事では割愛させて頂きます。
- リポジトリはこちら
Client VPNにおいて、サーバー証明書は接続先のVPNサーバーの身元確認に使用します。
クライアントからVPN接続を試みる時に、「本当に意図した接続先(会社)のサーバーなのか?」の確認のために使用します。
Client VPNでは設定時にサーバー証明書を指定し、クライアントに配布する設定ファイル内でVPNエンドポイントの指定や特定のCA(認証局)のみを信頼する設計になっているため設定ファイルが適切に管理・配布され、アプリケーションを正しく使用していれば偽サーバーにアクセスしてしまう等のインシデントは大幅に軽減されます。
サーバー証明書の作成
Client VPNのドキュメントに記載されたコマンドの実行で作成が可能です。
ドキュメントは「相互認証」とありますが、ユーザーベースの認証方法でもサーバー証明書は必要となるためこの設定手順をそのまま流用出来ます。
CloudShellを起動
今回はAWSコンソールから使用可能なCloudShellを使って証明書を作成します。
どのサービスの画面でも構いませんが、AWSコンソール左下の「CloudShell」を押下します。
cloudshell-userのシェルが起動します。
Easy RSAのコードをCloudShellへcloneする
現在のClient VPNのドキュメントに記載のcloneコマンドをそのまま実行するとGitHubのmasterブランチのコード(開発中の最新コード)を取得可能です。
※大抵動作に支障はありませんが、厳密には開発中の最新ブランチでは不具合発生の可能性もあるため、リリース版を使用する場合はリリースタグを指定してcloneすることも可能です。
2025年8月現在、最新リリースタグの付いたバージョンはv3.2.3のようです。
- 最新ブランチをそのままcloneする場合
git clone https://github.com/OpenVPN/easy-rsa.git
- リリース版のタグを指定する場合
git clone --branch v3.2.3 --single-branch https://github.com/OpenVPN/easy-rsa.git
clone完了後、easy-rsaディレクトリが作成されていればOKです。
~ $ ls -l
total 4
drwxr-xr-x. 10 cloudshell-user cloudshell-user 4096 Aug 13 09:14 easy-rsa
easyrsa3のディレクトリへ移動
cd easy-rsa/easyrsa3
必要に応じてvarsファイルを作成して設定を行う
証明書の有効期限などをここでカスタマイズ出来ます。
vars.exampleという設定項目の例が記述されたファイルがあるためファイル名「vars」でコピーして編集します。
easyrsa3 $ cp -ip vars.example vars
easyrsa3 $ ls -l
total 220
-rwxr-xr-x. 1 cloudshell-user cloudshell-user 184674 Aug 13 09:14 easyrsa
-rw-r--r--. 1 cloudshell-user cloudshell-user 5145 Aug 13 09:14 openssl-easyrsa.cnf
-rw-r--r--. 1 cloudshell-user cloudshell-user 9039 Aug 13 09:14 vars
-rw-r--r--. 1 cloudshell-user cloudshell-user 9039 Aug 13 09:14 vars.example
drwxr-xr-x. 2 cloudshell-user cloudshell-user 4096 Aug 13 09:14 x509-types
easyrsa3 $ vi vars
設定箇所の例
変数EASYRSA_CERT_EXPIRE
はサーバー証明書の有効期限です。デフォルトでは825日でおよそ2年となっています。
#set_var EASYRSA_CERT_EXPIRE 825
変更する場合はコメントアウトを外して希望の日数に設定して保存します。(以下は365日とする場合)
set_var EASYRSA_CERT_EXPIRE 365
その他、EASYRSA_CA_EXPIRE
はCA(認証局)自体の有効期限です。デフォルトは3650日(10年)となっています。
新しいPKI(Public Key Infrastructure/公開鍵基盤)環境を初期化
./easyrsa init-pki
新しい証明機関 (CA) をパスワードなしで構築
./easyrsa build-ca nopass
実行すると以下のようなプロンプトでCNの入力を求められるため任意の名称(今回は「server」)と入力
CN(Common Name)は証明機関(CA/認証局)の識別子です。
※CNは基本的に更新時も同じ名前を使用する想定のため事前に決めておきます。
CNを後から変更する場合、後述するサーバー証明書の更新コマンドでシンプルな更新が出来ないため注意です。
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Common Name (eg: your user, host, or server name) [Easy-RSA CA]:server ★ここにCNを入力
以下プロンプトが返れば成功。
Build-ca completed successfully.
サーバー証明書とキーを生成
./easyrsa --san=DNS:server build-server-full server nopass
san=DNSの値にCNと同じ名称を追加し、サーバー証明書と秘密鍵をまとめて作成します。
以下のような確認プロンプトが表示されます。
Requested CN
にCAを構築した際に設定した名称が表示され、Valid for:
の値は有効期限となっており、varsで設定した日数になっていることがわかります。
続行する場合は「yes」応答します。Linuxに慣れていると「y」応答しそうですが注記の通りyes以外だと中止されてしまうので注意です。
Notice
------
Private-Key and Public-Certificate-Request files created.
Your files are:
* req: /home/cloudshell-user/easy-rsa/easyrsa3/pki/reqs/server.req
* key: /home/cloudshell-user/easy-rsa/easyrsa3/pki/private/server.key
You are about to sign the following certificate:
Requested CN: 'server'
Requested type: 'server'
Valid for: '365' days
subject=
commonName = server
X509v3 Subject Alternative Name:
DNS:server
Type the word 'yes' to continue, or any other input to abort.
Confirm requested details: yes ★yesで応答する
以下のプロンプトが返ってくればOKです。
Certificate created at:
* /home/cloudshell-user/easy-rsa/easyrsa3/pki/issued/server.crt
作成したサーバー証明書とキーファイルをまとめて一つのフォルダに格納
デフォルトだと各crtファイルとkeyファイルが異なるディレクトリに作成されるため、
ACMにインポートしやすくするために一つのフォルダにファイルをまとめます。
mkdir ~/custom_folder/
cp pki/ca.crt ~/custom_folder/
cp pki/issued/server.crt ~/custom_folder/
cp pki/private/server.key ~/custom_folder/
cd ~/custom_folder/
ACMにファイルをインポート
まとめたファイルをCLIでインポートします。
aws acm import-certificate --certificate fileb://server.crt --private-key fileb://server.key --certificate-chain fileb://ca.crt
以下のプロンプトが返って来ればOKです。
{
"CertificateArn": "arn:aws:acm:ap-northeast-1:<アカウントID>:certificate/<証明書ID>"
}
コンソールで確認するとACMにインポートされているのがわかります。
Client VPN構築
インポートしたサーバー証明書を使用してClient VPNを構築し、接続確認を行います。
以下の記事を参考に、EC2(Windows Server 2022)ベースのADとAD Connectorを使用し、AD認証を行うユーザーベースの認証方法で構築しました。
以下はコンソールからのClient VPNの構築手順に絞って記載します。
作成した証明書を指定して認証情報を追加
ユーザーベースの認証でアクティブディレクトリ認証を選ぶと既存のAD ConnectorのIDを選択出来る
必要に応じてログ出力設定(CloudWatch Logsのロググループは事前に作成する必要有り)
ネットワーク設定などを行う(DNSサーバーのIPアドレスはADとなるEC2のプライベートIPを指定)
その他オプションの設定
- クライアントルート強制のサポートについて
- オプション設定の詳細ドキュメント
VPNエンドポイント作成
各種設定後、Nameタグに名前が入っていることを確認してエンドポイントを作成します。
ターゲットネットワークの関連付け
作成直後は状態が「Pending-associate」となります。
エンドポイントに紐づくサブネットを設定する必要があります。
ターゲットネットワークとなるサブネットには複数の要件があるためそちらに沿って設定したサブネットを紐付けます。
クライアント VPN ターゲットネットワークの要件
- エンドポイントIDを選択して詳細画面へ遷移後、「ターゲットネットワークを関連付ける」を選択
- 要件に見合うサブネットを関連付ける
- 関連付けの状態が「Associating」となる(関連付け完了までに5分ほど時間がかかるため待機中に次の承認ルールの設定などを行なっておく)
- 状態が「Associated」になれば使用可能
承認ルールの設定
「承認ルール」タブから承認ルールを設定します。この設定で、VPCやサブネットなどAWSのネットワークへのアクセス許可制御が可能です。例えばEC2インスタンスのIPアドレスのみへのアクセス許可も設定出来ます。
今回のアクセス稼働確認はEC2インスタンスへのRDPを行うため、インスタンスのプライベートIPのみへのルールを追加してみます。
環境設定補足
-
Client VPNの認証用ユーザー
- 構築時に参照した記事の内容と同様に、EC2内でAD認証用のドメインユーザー(cm-test)を作成済みです。
-
VPN接続後のVPC内リソースへの疎通確認
- EC2(ADサーバー)にリモートデスクトップ接続可能かどうかを確認します。
- EC2のセキュリティグループのインバウンドルールで、Client VPNエンドポイントのセキュリティグループからのRDP接続(3389ポート)を許可しています。
接続確認
クライアントアプリケーション準備
以下のページからAWS公式のVPNクライアントアプリケーションをインストールします。
使用しているPCのOSに適したものを使用します。
クライアント設定ファイルのダウンロード
VPNエンドポイントの詳細画面もしくは、一覧画面で対象エンドポイントを選択して「クライアント設定をダウンロード」を押下します。ローカルの任意のフォルダに設定ファイルを格納します。検証のみであればダウンロードフォルダに置いたままでも構いません。
- ダウンロードボタンを押下
- 確認画面が出るためダウンロード実行
アプリケーションの設定
デフォルトでMacOSの場合、「アプリケーション」配下にインストールされている「AWS VPN Client.app」をクリックして起動します。
- 起動
- プロファイル設定
MacOSの場合、VPNのウインドウが出力され画面左上にメニューが表示されます。
「ファイル」から「プロファイルを管理」を押下します。
- プロファイル追加
プロファイル用のウインドウで「プロファイルの追加」を押下します。
- 任意のプロファイル名を入力してローカルにダウンロードした設定ファイルを選択
- 管理画面に追加されたことを確認し「完了」を押下
- 対象の設定が表示されていることを確認(※この時点ではまだ接続されていません)
接続確認
- 対象のプロファイル名の「接続」を押下
- AD認証のためドメインユーザー名・パスワードを入力
- 「接続済み」になっていればVPN接続が確立中
インターネットに接続できない状態になっているはずです。
リモートデスクトップを試す
「Windows App」を使用してEC2へのリモートデスクトップを試します。
- デバイスからPCを追加
- EC2のプライベートIPを入力して「Add」
- 対象PCの「•••」から「Connect」を選択
- リモートデスクトップ権限のあるユーザーでEC2にログイン
- デスクトップにアクセスできれば成功
- EC2はサインアウトし、VPNの接続を解除
ここまでで一連のVPN設定・稼働確認は完了です。
サーバー証明書の更新
それではサーバー証明書を更新してみます。
まず既存の証明書を確認し、有効期限が1年後の日付になっていることを確認できます。
(※証明書の作成を別日に実施したため、残り364日になっています。)
概要
Client VPNに記載のドキュメントでは、Easy-RSAの3.2.xの場合以下のようなコマンドで更新を行うとありました。
- 期限切れにした上で署名を実施
./easyrsa expire server
./easyrsa --san=DNS:server sign-req server server
Easy-RSAの3.2.0では、それまで3.1.xで使われていた「renew」コマンドが使えなかったようですが
GitHubのドキュメントを見ると、3.2.1以降ではこのコマンドが復活したようです。
またrenewコマンドはEasy-RSAのバージョンによって挙動が異なり、最新のEasy-RSAの3.2.1以降では
renewバージョン4ということでより効率的に証明書の更新が行えるように改修されているようです。
expire
とsign-req
を行う方法は、一部の証明書属性を更新できるようですが、Client VPNのサーバー証明書という用途であればバージョン4のrenewコマンドを使用し有効期限を伸ばすのみで十分かと思います。
ただ、バージョン4の更新コマンドは証明書ファイルのみを更新して秘密鍵の更新までは行いません。
本番利用や組織のポリシー、不正アクセスや鍵の漏洩によるインシデント発生などで秘密鍵まで更新が必要な場合は、最新のrenewコマンドではなく「rebuild」コマンドを使う必要があります。
セキュリティポリシー等によって更新方法を決める必要があります。
今回は新バージョンのrenewコマンドで証明書更新を行なってみます。
更新実行
CloudShellでeasyrsa3ディレクトリに移動します。
更新準備
- ディレクトリ移動
cd /home/cloudshell-user/easy-rsa/easyrsa3
pwd
- 設定変更
有効期限を変更してみます。
vi vars
EASYRSA_CERT_EXPIRE
の値を365から1にして保存します。
更新実行
構文は以下となります。3.1.xで使用されていた「nopass」オプションは不要になりました。
以前の一部のrenewバージョンでは秘密鍵も更新していましたが証明書ファイルのみの更新に変わったためかと思います。
- 構文
./easyrsa renew <証明書ファイル名(拡張子なし)>
- 実際の実行コマンド
./easyrsa renew server
- 設定読み込みと更新確認が出力されるため「yes」で応答
主に、server.crtが「renewed」ディレクトリにアーカイブ保存されることがわかります。
easyrsa3 $ ./easyrsa renew server
Using Easy-RSA 'vars' configuration:
* /home/cloudshell-user/easy-rsa/easyrsa3/vars
WARNING: This process is destructive!
These files will be MOVED to the 'renewed' sub-directory:
* /home/cloudshell-user/easy-rsa/easyrsa3/pki/issued/server.crt
These files will be DELETED:
All PKCS files for commonName: server
The inline credentials files:
* /home/cloudshell-user/easy-rsa/easyrsa3/pki/inline/server.inline
* /home/cloudshell-user/easy-rsa/easyrsa3/pki/inline/private/server.inline
The CA attibutes file will be set to 'unique_subject = no'.
Required to create a new certificate with an existing name.
Type the word 'yes' to continue, or any other input to abort.
Continue with 'renew' ? yes ★yesで応答する
- さらに設定内容(有効期限やCN)の確認が出力されるため「yes」で応答
Valid for
の値が「1」に変わっています。
You are about to sign the following certificate:
Requested CN: 'server'
Requested type: 'server'
Valid for: '1' days
subject=
commonName = server
X509v3 Subject Alternative Name:
DNS:server
Type the word 'yes' to continue, or any other input to abort.
Confirm requested details: yes ★yesで応答する
- 以下のようにプロンプトが返って来ればOK
Notice
------
Certificate created at:
* /home/cloudshell-user/easy-rsa/easyrsa3/pki/issued/server.crt
Notice
------
Renew was successful.
* IMPORTANT *
Renew has created a new certificate, to replace the old one.
To revoke the old certificate, once the new one has been deployed,
use command 'revoke-renewed server'
「IMPORTANT」の部分に、新しい証明書がデプロイされたら「revoke-renewed server」コマンドを使用して古い証明書を失効させるようにとの注意書きがあります。
これを最後に行わないと、次回更新作業を行う際に「renewed」ディレクトリに古い証明書が残存したままとなりエラーになるため注意です。
- 証明書ファイルの確認
「pki/renewed」ディレクトリ配下に古いserver.crtが移動され、「pki/issued」配下に新規の証明書ファイルが出来上がっています!
easyrsa3 $ ls -l pki/renewed/issued/
total 8
-rw-------. 1 cloudshell-user cloudshell-user 4587 Aug 13 09:55 server.crt
easyrsa3 $ ls -l pki/issued/
total 8
-rw-------. 1 cloudshell-user cloudshell-user 4587 Aug 14 07:56 server.crt
easyrsa3 $
新たな証明書をACMへインポート
作成時と同様にカスタムフォルダを作成し、まとめてインポートします。
- ファイルをまとめる
mkdir ~/custom_folder2
cp pki/ca.crt ~/custom_folder2/
cp pki/issued/server.crt ~/custom_folder2/
cp pki/private/server.key ~/custom_folder2/
cd ~/custom_folder2/
- 既存の(Client VPNに紐づいている)ACMのARNを引数にしてインポート
aws acm import-certificate \
--certificate fileb://server.crt \
--private-key fileb://server.key \
--certificate-chain fileb://ca.crt \
--certificate-arn <既存ACMの証明書ID>
ACMのARNが返って来ればOK。
コンソールを確認すると、有効期限が0日になり失効間近となっています。
接続確認
引き続きVPNの接続確認を行い、接続可能なことを確認できます。
ただし以下ドキュメントに、エンドポイント側での証明書更新が最大5時間かかるとの注記があります。
このため、5時間以上後に再度アクセス可能か確認しました。
※Client VPNは接続がなくてもエンドポイントが存在しているだけで時間課金になるため検証の際は注意が必要です。
クライアント VPN サービスで使用されている証明書が更新されると、ACM 自動ローテーション、
新しい証明書の手動インポート、または IAM アイデンティティセンターへのメタデータ更新のいずれによっても、
クライアント VPN サービスは Client VPN エンドポイントを新しい証明書で自動的に更新します。
これは、最大 5 時間かかる自動プロセスです。
- 参考
本当はログ等で厳密にどの証明書を使用して接続しているかなどが確認できれば良いのですが、CNの名前やRSAの鍵長くらいしか確認できませんでした。
※上記はクライアントアプリケーションのログ/Users/username/.config/AWSVPNClient/logs
配下のログを確認しました。
もし他に確認可能な方法があれば知りたいところです。
- 参考
古い証明書の失効手続き
次回更新時にエラーとならないよう、新しい証明書でのVPN接続確認ができたら古い証明書は失効しておきましょう。
「revoke-renewed server」コマンドを使用します。
- ディレクトリ移動
cd /home/cloudshell-user/easy-rsa/easyrsa3
pwd
- 失効コマンドを実行
./easyrsa revoke-renewed server
実行すると確認メッセージが出ますが、特に以下の「revoked」ディレクトリが作成されて「renewed」ディレクトリから移動する旨を確認します。
These files will be MOVED to the 'revoked' sub-directory:
* /home/cloudshell-user/ssl/easy-rsa/easyrsa3/pki/renewed/issued/server.crt
- 以下メッセージが出るため「yes」応答
Please confirm that you wish to revoke the certificate
with the following subject:
subject=
commonName = server
serial-number = <証明書のシリアル番号>
Reason: None given
Type the word 'yes' to continue, or any other input to abort.
Continue with revocation: yes ★yesで応答する
- 以下のプロンプトが返ってくればOKです。
* IMPORTANT *
Revocation was successful. You must run 'gen-crl' and upload
a new CRL to your infrastructure in order to prevent the revoked
certificate from being accepted.
なお、「gen-crl」の実行を行いCRL(証明書失効リスト)を更新しましょうと出ますが今回サーバー証明書のみの更新でCRLは作成していないので実施しません。
クライアント証明書の更新でCRLを管理している場合には必要になってきます。
この後、作成したPKI環境をCloudShellからローカルPCへダウンロードし保管します。以下、運用時の注意をご確認ください。
運用時の注意
今回、CloudShellで作業を実施していますが通常CloudShellのHomeディレクトリのデータは最後のセッションから120日経過後に削除されるようになっています。
実際の運用の際は作成したPKI環境のプロジェクトをZIPでまとめてローカルに厳重に保管しておき、更新が必要な際に再度アップロード・解凍をして作業を行う必要があります。
ZIP化や解凍に関してはこの記事の最初の「先に更新手順まとめ(忙しい方向け)」に記載がありますので参考にしていただけたらと思います。
初回のPKI構築後は手順「8. 更新後のPKI環境をローカルに保存・CloudShellから削除」の手順でローカル環境に保存し、更新の際は手順1から実施します。
最後に
以上、新しいバージョンでサーバー証明書更新を試してみました。
日々更新が行われているのでソースの確認をするのは面白いですね。
誰かの検証に役立てたら幸いです!