OpenVPNの証明書作成 (Easy RSA)

Posted on 2025/03/20

ToC

OpenVPNの証明書の有効期限が切れました

2015年にクラウド開発をおこなう機会に恵まれ、それ以降はクラウドインフラを中心に開発をしています。 ちょうど10年ということで普通であればめでたいことなのですが、クラウドネットワークに接続する際に 利用しているOpenVPNの証明書が、3650日の有効期限を満了して見事にクラウドに繋がらなくなりました🙄。

インフラの調査

OpenVPNサーバーも少しずつバージョンが上がっていますが、サーバーのアプリケーションは時折バージョンアップを していました。はじめは、「同じ調子でやれば良いかな」と思っていたのですが、なんとOSがCentOSでした。 IP制限しているのと、開発用途に使っているだけで、OSまでは正直あまり気にしていなかったというのもあって、 今回はちょうどいい機会なので、OSのバージョンアップも含めて実施しました。

OSもついでにバージョンアップ

トピックとはズレますが、せっかくAWS上で利用しているので、今回はOSはAmazonLinux2023を、 さらにコストが安いGravitonのCPUを選択しました。AmazonLinux2023は、AmazonLinux2とは異なりepelが利用できず、RPMパッケージでインストールできる 選択肢が少ないので少し心配しましたが、OpenVPNはサポートされていました。 少し前にサポートされたようでタイミングは良かったです。

証明書の発行

またとないチャンスなので、証明書の期間更新をすることも考えましたが、残念ながら必要なCA認証局の鍵 (勿論、オレオレです)が見つからず、世の中の記事と同じように再発行のプロセスになってしまいました。 まぁ、影響範囲も非常に限定的なので、良しとしましょう。

Easy RSAのインストール

証明書の発行は、Easy RSAを利用して実施します。
発行した時点では、バージョン3.2.2が最新でした。GitHubから取得するだけで利用できるため簡単です。
その後に、初期化処理を実施します。初期化処理をするとデフォルトでは pki というディレクトリが作られます。

git clone https://github.com/OpenVPN/easy-rsa.git -b "v3.2.2"
easy-rsa/easyrsa3/easyrsa init-pki

認証局証明書の発行

はじめに自己認証局証明書を作成します。
認証局証明書は、他の証明書(例: サーバー証明書やクライアント証明書)の信頼性を保証するために 使用されます。なお、デフォルト値で発行できる証明書の有効期間が短いので、環境変数に値を設定しておくと 期間の長い証明書を作成できます。(今回も10年の証明書を作成しました)
OpenVPNサーバーでは、パスワードなしのファイルが必要なためnopassの引数を渡して証明書を作成します。
(環境変数の詳細は、公式ドキュメントに記載があります)

$ export EASYRSA_REQ_CN=foo.bar
$ export EASYRSA_CA_EXPIRE=3650
$ export EASYRSA_CERT_EXPIRE=3650

$ easy-rsa/easyrsa3/easyrsa build-ca nopass

〜メッセージ〜

Common Name (eg: your user, host, or server name) [Easy-RSA CA]:

Notice
------
CA creation complete. Your new CA certificate is at:
* /opt/local/pki/ca.crt

Create an OpenVPN TLS-AUTH|TLS-CRYPT-V1 key now: See 'help gen-tls'

Build-ca completed successfully.

$ openssl x509 -in /opt/local/pki/ca.crt -noout -dates
notBefore=Mar 19 22:47:00 2025 GMT
notAfter=Mar 17 22:47:00 2035 GMT

OpenVPNに必要なファイルの作成

OpenVPNサーバーでは、クライアントとサーバー間で安全にセッション鍵を生成するためにDiffie-Hellman(DH) パラメータとTLS認証キー(TLS Authentication Key)が必要なためこれを作成します。 DHパラメータのビット長は2048ビットがデフォルトでしたが、必要に応じて4096ビット長のものを作成することも可能です。

$ easy-rsa/easyrsa3/easyrsa gen-dh

〜メッセージ〜

DH parameters of size 2048 created at:
* /opt/local/pki/dh.pem

$ openvpn --genkey secret ta.key

サーバー証明書を作成

OpenVPNサーバーに設定する証明書を作成します。
はじめに、証明書署名要求 (CSR)と秘密鍵 (Private Key)を作成して、その後でサーバー証明書を発行します。

$ easy-rsa/easyrsa3/easyrsa gen-req server nopass

〜メッセージ〜

Private-Key and Public-Certificate-Request files created.
Your files are:
* req: /opt/local/pki/reqs/server.req
* key: /opt/local/pki/private/server.key

$ easy-rsa/easyrsa3/easyrsa sign-req server server nopass

〜メッセージ〜

Certificate created at:
* /opt/local/pki/issued/server.crt

クライアント証明書を作成

クライアント証明書の作成は、サーバー側とほぼ同じです。
これで、OpenVPNに必要なファイル群の作成は完了です。

$ easy-rsa/easyrsa3/easyrsa gen-req client nopass

〜メッセージ〜

Your files are:
* req: /opt/local/pki/reqs/client.req
* key: /opt/local/pki/private/client.key

$ easy-rsa/easyrsa3/easyrsa sign-req client client nopass

〜メッセージ〜

Certificate created at:
* /opt/local/pki/issued/client.crt

最終的に作成されるファイル群を下記に記載しておきます。
🟥は、サーバー側に配置が必要となるファイルで、🔵はクライアント側に配置するファイルです。

pki/
├── ca.crt 🟥 🔵
├── certs_by_serial
│   ├── 12345678901234567890123456789012.pem
│   └── ABCDEFGHIJKLMNOPQRSTUVWXYZ123456.pem
├── dh.pem 🟥
├── index.txt
├── index.txt.attr
├── index.txt.attr.old
├── index.txt.old
├── inline
│   └── private
│       ├── README.inline.private
│       ├── client.inline
│       └── server.inline
├── issued
│   ├── client.crt 🔵
│   └── server.crt 🟥
├── private
│   ├── ca.key
│   ├── client.key 🔵
│   └── server.key 🟥
├── reqs
│   ├── client.req
│   └── server.req
├── revoked
│   ├── certs_by_serial
│   └── private_by_serial
├── serial
├── serial.old
└── vars.example
ta.key 🟥

OpenVPNの設定ファイルについては、また別の機会に記載したいと思います。
兎にも角にも、また、次回10年後の証明書更新まで利用できそうで良かったです。


参照