はじめに
インターネット環境に接続可能なクライアント端末からIBM Cloud VPC環境に接続してクラウドを利用する際は、仮想的な暗号通信を実現するClient VPN for VPC機能を利用します。この機能を利用するにはVPN Serverの他、シークレットと呼ばれる機密情報(各種証明書等)を管理するSecrets Managerを利用します。
Secrets Managerの各種機能は、クラウドコンソールの他、API/CLI/SDKからも制御する事が可能であり、今までv1/v2が併用利用可能であったが、2023年10月31日のv1のサポート終了に伴い早期にSecrets Manager API v2 へのマイグレーションの移行を推奨しております。
本稿では、クライアントVPN環境で利用されるSecrets Manager上の証明書をこれらAPI v2機能を用いて、管理する方法についてご紹介します。
本稿で利用する環境
クライアント端末を除く他の全ての機能をIBM Cloud上で構築します。これらの各コンポーネントの設定に関しては、Qiita上に多々存在する為、参考になる記事をご紹介しながら環境を準備します。
- VPN Server(VPN通信を受信するサーバ)
- Secrets Manager(シークレット情報の保管管理)
- Trusted Profile(本機能の利用により、VPC内のサーバから簡易な認証でAPI機能を利用する)
- Linuxサーバ(API アクセス用として利用)
- VPNクライアント端末(OpenVPNクライアントソフトを利用
Client VPN for VPC環境準備
こちらの記事を参考にClient VPN for VPC環境を構築し、お手元の端末にインストールしたOpenVPNクライアントソフトからVPN接続を実施します。
事前に作成したサーバ証明書や鍵ファイルは、Secrets Managerにて登録管理し、VPN Serverと連携します。
同じく作成したクライアント証明書と鍵ファイルは、VPNクライアント端末に保存して証明書ログイン認証に利用します。
Trusted Profile環境準備
こちらの記事を参考にTrusted Profile環境を準備します。通常API/CLI利用する際は、ID/PasswordやAPI Key等を用いた認証のやり取りを行いますが、本機能はセキュリティを維持した上で、これらの認証処理を簡略化します。VPC内の特定のサーバ間及びIBM Kuvernetes ServiceやRed Hat Openshift on IBM CloudのService AccountからTrusted Profile経由でアクセスする事で、認証のやり取りをせずにIBM CloudのIAM Tokenを取得します。
VPNサーバ証明書運用
VPNサーバ証明書は、Secrets Manager上にて管理します。サーバ証明書の有効期限の初期設定はセキュリティ的観点より、段々と短くなってきております(最近は13ヶ月が多いと思います)。管理対象の証明書が多い場合運用負荷も高くなる為、Secrets Managerで証明書(有効期限)管理を実施し、有効期限が切れる前にAPI等による自動化で有効期限の更新を実施する事で運用負担権限を図る事ができます。
Secrets Managerでは、証明書の期限管理を下記のように実施可能であり、Slack等を利用して期限が近い事を通知する事も可能です。
VPN Server側でもSecrets Manager側の証明書情報をもとに以下のように期限が近い事を表示します。
証明書は、更新期限が近くないと更新不可能な為、証明書作成の際にEasyrsaのvarファイルの設定を変更して有効期限を短くしております。
pki % cat vars | grep EASYRSA_CERT
#set_var EASYRSA_CERT_EXPIRE 825
set_var EASYRSA_CERT_EXPIRE 4
issued % cat vpn-server.crt
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
69:76:44:3b:1b:57:d3:1e:bb:96:7e:af:9c:26:da:7c
Signature Algorithm: sha256WithRSAEncryption
Issuer: CN=Easy-RSA CA
Validity
Not Before: Sep 21 07:23:43 2023 GMT
Not After : Sep 25 07:23:43 2023 GMT
Subject: CN=vpn-server
この状態でクライアント端末からOpenVPNで接続できる事を確認しておきます。
サーバ証明書を更新
以下のコマンドでサーバ証明書を更新します。
easyrsa3 % ./easyrsa renew vpn-server nopass
サーバ証明書が更新された事を確認します。Serial Numberや有効期限が変更になってます。
issued % cat vpn-server.crt
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
a6:52:09:c0:bb:e1:f4:f8:f2:8e:c8:6b:73:f9:7c:bb
Signature Algorithm: sha256WithRSAEncryption
Issuer: CN=Easy-RSA CA
Validity
Not Before: Sep 21 09:38:22 2023 GMT
Not After : Sep 25 09:38:22 2023 GMT
Subject: CN=vpn-server
pemファイルを作成します。
easyrsa3 % openssl x509 -in ./pki/issued/vpn-server.crt -out ./pki/issued/vpn-server.pem
easyrsa3 % ls -l ./pki/issued
total 24
-rw------- 1 masaharu staff 4572 9 21 18:38 vpn-server.crt
-rw-r--r-- 1 masaharu staff 1237 9 21 18:48 vpn-server.pem
このpemファイルをAPIアクセス用のLinuxサーバに転送し、そこからSecrets Manager上のサーバ証明書をTrusted Profileを活用してAPIで更新します。
Secrets Manager API(v2)によるVPNサーバ証明書更新
Secrets ManagerのAPIについては、こちらのIBM Cloud Docをご参照ください。Create a new secret version
メソッドの中のRequest Bodyとして、ImportedCertificateVersionPrototype
を利用します。
以下のコマンドでSecrets Managerにサーバ証明書をアップロードします。
curl -X POST --location --header "Authorization: Bearer {iam_token}" --header "Accept: application/json" --header "Content-Type: application/json" --data '{"certificate": "{pem}"' "{base_url}/api/v2/secrets/{secret_id}/versions"
{base_url
{secret_id}
は、各Secrets
のDetails
の中のActions...
でShow snippet
を選択すると各種情報を確認する事ができます。{iam_token}
に関しては、前述したClient VPN for VPC環境準備を参照ください。
{pem}
に関しては、先ほど証明書からpem形式に変換しましたが、このままでは使えないので改行/n
が入った一行表示に以下のコマンドで変換します。
awk 'NF {sub(/\r/, ""); printf "%s\\n",$0;}' vpn-server.pem
上記awk
コマンドで変換すると最後の-----END CERTIFICATE-----\n
に\n
が残ってしまいます。削除して、POSTしてください。
私の環境では以下のCurlコマンドでリクエストするとこのような結果になります。(iam_tokenはセキュリティ上そのままです)
[root@sm-bastion ~]# curl -X POST --location --header "Authorization: Bearer $iam_token" --header "Accept: application/json" --header "Content-Type: application/json" --data '{"certificate": "-----BEGIN CERTIFICATE-----\nMIIDZTCCAk2gAwIBAgIRAKZSCcC74fT48o7Ia3P5fLswDQYJKoZIhvcNAQELBQAw\nFjEUMBIGA1UEAwwLRWFzeS1SU0EgQ0EwHhcNMjMwOTIxMDkzODIyWhcNMjMwOTI1\nMDkzODIyWjAVMRMwEQYDVQQDDAp2cG4tc2VydmVyMIIBIjANBgkqhkiG9w0BAQEF\nAAOCAQ8AMIIBCgKCAQEAugIbHB1ZNcMOy+bmX+BWL1F+b/nRH8NfKxltuf8EwNyL\nWLGDE7bP7AYYpNZ8tcxCneobiDBgMAGkNVi9iDZ5ZSN2nNe+GnuUTsxpRP7DhRj1\nor2phqHH097jOQHLhqKy8BHGu6JXlSr21NBoC8xje5iFTvPFCDHwQRXHb22egeFc\nef86L7H3+IExg20fVgFmYe7Pao7mLVgjkn/L+so9TSBWksuDyaoTrBH25gsSTFvh\nrSDWFgQ2xDxwUSNTQ+ty6nKX7XvQVI2EX4SzmWGMlVHFuvqlWFT+4tIJYEYNvWxS\nD+TR9eEUSd+nSjdTh5yhIsW5FRfl0skTzBhbxQGILwIDAQABo4GuMIGrMAkGA1Ud\nEwQCMAAwHQYDVR0OBBYEFHno0h7ps25FiXWX2UgLDjbqmafUMEYGA1UdIwQ/MD2A\nFDz/1CKn4b4Cz+dviYLz4xoK2zw1oRqkGDAWMRQwEgYDVQQDDAtFYXN5LVJTQSBD\nQYIJAM5q2IrTnek9MBMGA1UdJQQMMAoGCCsGAQUFBwMBMAsGA1UdDwQEAwIFoDAV\nBgNVHREEDjAMggp2cG4tc2VydmVyMA0GCSqGSIb3DQEBCwUAA4IBAQB75wRy7ino\nXKN7UblEhN8o5DvGgTd35IQhTr1i2LZ9troZQWK3KrsNEd4InrzJKqIHRpMKDsTz\nsqwIyS/IJcPODR/iU7mHl7+J+4n2oHGBldKcxe7HCjS+EkEoM4X/Wfgl180iZ2oQ\nvcXkdUUCOVv4UwWW39PM5HArDhyvd1ox+90fPtTDOGFYBU/d6E9ljjdUfWrtq7US\nRoEki5pmFRB84WFGTt2mKBAHOXJ9vt3HOJXGfDYRNn9nCD3FXL4VjJynph4Cuxhe\nMZ8EoJMDC73o0Ed8cb3f38nlTklz1LiNaal7/d0wrDEEYRiOmum2S2M2m5jpLeEs\n2Y35ouMuNx5/\n-----END CERTIFICATE-----"}' "https://3fb12463-4d6b-4029-8335-727bf02d0c8b.jp-tok.secrets-manager.appdomain.cloud/api/v2/secrets/5b9681aa-95cf-d24e-6634-6164d7a0f09b/versions" |jq
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 3156 0 1881 100 1275 1293 877 0:00:01 0:00:01 --:--:-- 1294
{
"alias": "current",
"certificate": "-----BEGIN CERTIFICATE-----\nMIIDZTCCAk2gAwIBAgIRAKZSCcC74fT48o7Ia3P5fLswDQYJKoZIhvcNAQELBQAw\nFjEUMBIGA1UEAwwLRWFzeS1SU0EgQ0EwHhcNMjMwOTIxMDkzODIyWhcNMjMwOTI1\nMDkzODIyWjAVMRMwEQYDVQQDDAp2cG4tc2VydmVyMIIBIjANBgkqhkiG9w0BAQEF\nAAOCAQ8AMIIBCgKCAQEAugIbHB1ZNcMOy+bmX+BWL1F+b/nRH8NfKxltuf8EwNyL\nWLGDE7bP7AYYpNZ8tcxCneobiDBgMAGkNVi9iDZ5ZSN2nNe+GnuUTsxpRP7DhRj1\nor2phqHH097jOQHLhqKy8BHGu6JXlSr21NBoC8xje5iFTvPFCDHwQRXHb22egeFc\nef86L7H3+IExg20fVgFmYe7Pao7mLVgjkn/L+so9TSBWksuDyaoTrBH25gsSTFvh\nrSDWFgQ2xDxwUSNTQ+ty6nKX7XvQVI2EX4SzmWGMlVHFuvqlWFT+4tIJYEYNvWxS\nD+TR9eEUSd+nSjdTh5yhIsW5FRfl0skTzBhbxQGILwIDAQABo4GuMIGrMAkGA1Ud\nEwQCMAAwHQYDVR0OBBYEFHno0h7ps25FiXWX2UgLDjbqmafUMEYGA1UdIwQ/MD2A\nFDz/1CKn4b4Cz+dviYLz4xoK2zw1oRqkGDAWMRQwEgYDVQQDDAtFYXN5LVJTQSBD\nQYIJAM5q2IrTnek9MBMGA1UdJQQMMAoGCCsGAQUFBwMBMAsGA1UdDwQEAwIFoDAV\nBgNVHREEDjAMggp2cG4tc2VydmVyMA0GCSqGSIb3DQEBCwUAA4IBAQB75wRy7ino\nXKN7UblEhN8o5DvGgTd35IQhTr1i2LZ9troZQWK3KrsNEd4InrzJKqIHRpMKDsTz\nsqwIyS/IJcPODR/iU7mHl7+J+4n2oHGBldKcxe7HCjS+EkEoM4X/Wfgl180iZ2oQ\nvcXkdUUCOVv4UwWW39PM5HArDhyvd1ox+90fPtTDOGFYBU/d6E9ljjdUfWrtq7US\nRoEki5pmFRB84WFGTt2mKBAHOXJ9vt3HOJXGfDYRNn9nCD3FXL4VjJynph4Cuxhe\nMZ8EoJMDC73o0Ed8cb3f38nlTklz1LiNaal7/d0wrDEEYRiOmum2S2M2m5jpLeEs\n2Y35ouMuNx5/\n-----END CERTIFICATE-----",
"created_at": "2023-09-21T11:54:03Z",
"created_by": "iam-Profile-ff6fc304-51fc-4cd0-a8d2-8901e5d8e945",
"expiration_date": "2023-09-25T09:38:22Z",
"id": "6f63a501-0322-3224-5729-2b53d6337aed",
"intermediate": "",
"payload_available": true,
"private_key": "",
"secret_group_id": "2c553c09-194d-309f-ad8e-814edd1fa785",
"secret_id": "5b9681aa-95cf-d24e-6634-6164d7a0f09b",
"secret_name": "vpn-secret",
"secret_type": "imported_cert",
"serial_number": "a6:52:09:c0:bb:e1:f4:f8:f2:8e:c8:6b:73:f9:7c:bb",
"validity": {
"not_after": "2023-09-25T09:38:22Z",
"not_before": "2023-09-21T09:38:22Z"
},
"version_custom_metadata": {}
}
serial_number
validity
の有効期限が先ほど更新したサーバ証明書に置き換わっている事が確認できました。また、サーバ証明書更新後も更新前と遜色なくVPNクライアント端末から接続する事ができました。
まとめ
Secrets Manager上の証明書をAPIを利用して更新する方法をご紹介しました。ご紹介したAPIを自動化環境に組み込み運用負荷を軽減して頂ければと思います。ご紹介したIBM Cloud Docには、他のAPIも紹介されてますので、ご自身の環境にあったものをご利用頂ければと思います。
当初、VPNサーバ関連の一連のAPI運用について記載していたら、原稿が長くなってしまいました。分割した別投稿のClient VPN for VPCにおけるAPI CRL管理(VPN Server)編もご参照頂ければ幸いです。