

前回の記事はこちら
前回はALBでmTLS認証する方法を紹介しましたが、クライアント証明書の失効リストを反映させる方法が少し手間でしたので、手順を簡略化、例えばCRL取得、変換、AWSにアップロード、トラストストアに反映が自動化する方法を考えました。
手間がかかりそうなところを自動化してみます。処理する内容は次のとおりです。
このうち、CRLダウンロードはcurlコマンド、CRLのPEM変換はOpenSSLを使うのでAmazon Linux 2023上で実現できます。そのあとのAWSの操作はAWS CLIを使えばできそうです。
そこで、作業用のAmazon Linux 2023を構築して実現してみます。構成は下記のとおりです。AL2023を使ってCRL取得・変換・S3アップロード・トラストストア反映
作業用AL2023の作り方は省略しますが、Webサーバーと同じようにセキュリティグループを作成してインバウンドで社内からのみSSHアクセスを許可するように設定して、NetAttest -1a-subかNetAttest-1c-subのサブネット上に構築してください。
AL2023ではAWS CLIがインストール済みですが、これを使えるようにするにはIAMでAWS CLI用のアカウント作成とアクセスキーの生成、並びにAL2023にアクセスキーの反映が必要です。またこのユーザーに対して操作範囲を作成したロードバランサー及びS3バケットに絞るようにポリシーを設定します。
ポリシーで許可対象はARN formartで記載しますので、まずはトラストストアとS3バケットのARNを調べます。
トラストストアのARNはEC2ダッシュボードにて「ロードバランシング」→「トラストストア」にて作成した「NetAttest-ts」を開いて「トラストストアARN」の値を控えます。
S3バケットのARNはAmazon S3の「汎用バケット」で作成した「netattest-s3」を開き、「プロパティ」タブの「バケットの概要」に記載されています。
トラストストア及びS3バケットに対して必要な操作は次の通りとなります。
サービス | 許可するアクション |
elasticloadbalancing | RemoveTrustStoreRevocations AddTrustStoreRevocations |
s3 | PutObject |
この情報を元にロールを作成します。
アクション許可欄で「書き込み」で「AddTrsutRevocations」と「RemoveTrustRevocations」にチェックを入れ、リソース欄で「ARNを追加」をクリックします。
リソースARN欄に控えていたトラストストアのARNを入力すると、リソースのリージョン、Resource trust store name、Resource trust storeの値が自動で入りますので、「ARNの追加」をクリックします。
Resource bucket nameに「netattest-s3」を入力して、Resouce object nameの「任意のobject name」にチェックをいれて、「ARNを追加」をクリックします。
「許可のオプション」にて「ポリシーを直接アタッチする」にチェックを入れて、許可ポリシーで「NetAttest-Policy」を選択して「次へ」をクリックします。
「コマンドラインインターフェイス(CLI)」にチェックを入れ「上記のレコメンデーションを理解し、アクセスキーを作成します。」にチェックを入れて「次へ」をクリックします。
アクセスキーとシークレットアクセスキーを控えて「完了」をクリックします。
注)「完了」をクリックするとシークレットキーは二度と表示されませんのでご注意ください。控えそこねた場合には、再度アクセスキーを作成し直してください。
作業用マシンのAWS CLIをNetAttest-crlUploaderユーザーでAWSを操作するように設定します。
現在の作業マシンのAWS CLIの状態は次の通りです。
$ aws --version
aws-cli/2.23.11 Python/3.9.21 Linux/6.1.130-139.222.amzn2023.x86_64 source/x86_64.amzn.2023
$ aws configure list
Name Value Type Location
---- ----- ---- --------
profile <not set> None None
access_key <not set> None None
secret_key <not set> None None
region ap-northeast-1 imds
「aws configure」を実行すると対話形式でAWS Secret Access Keyを求められますので、NetAttest-crlUploaderユーザーのアクセスキーのシークレット値を入力します。
$ aws configure
AWS Access Key ID [None]: <アクセスキー名>
AWS Secret Access Key [None]: <アクセスキーのシークレット>
Default region name [None]:
Default output format [None]:
$ aws configure list
Name Value Type Location
---- ----- ---- --------
profile <not set> None None
access_key ****************GMSO shared-credentials-file
secret_key ****************BitW shared-credentials-file
region ap-northeast-1 imds
これで作業マシンでAWS CLIを実行するとAWSをNetAttest-crlUploaderユーザーとして操作されます。
既にIAMのポリシー設定でS3バケットを操作できる様になっていますが、S3バケット側でもNetAttest-crlUploaderユーザーでの操作を許可するポリシーを作成する必要があります。
下記を設定して「Add Statement」をクリックします。
項目 | 値 |
Select Type of Policy | S3 Bucket Policy |
Effect | Allow |
Principal | NetAttest-crlUploaderユーザーのARN値 |
Action | GetObject ObjectOwnerOverrideToBucketOwner PubObject |
Amazon Resource Name (ARN) | 「netattest-s3のARN値」/* |
「バケットポリシーを編集」に戻って、AWS Policy Genenaterで生成した値で上書きして「変更を保存」をクリックします。
AWS CLI及びS3バケットへのアクセス権の付与ができましたので、実際にコマンドを使ってCRL取得からトラストストアへの反映までを行っていきます。
AL2023にて「curl -O <CRLのURL>」を実行します。
$ curl -O http://<OneGateのテナントURL>/certs/<数字>/certs.crl
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 16792 100 16792 0 0 372k 0 --:--:-- --:--:-- --:--:-- 381k
$ ls
certs.crl
既に紹介済みですが、OpenSSLコマンドをで変換します。
$ openssl crl -inform DER -outform PEM -in certs.crl -out certs_pem.crl
$ ls
certs.crl certs_pem.crl
AWS CLIを使ってS3にCRLをアップロードします。アップロードするにはS3 URIで指定します。
S3 URIはAmazon S3にて「汎用バケット」の「netattest-s3」の「certs_pem.crl」を開いてS3 URLの値を控えます。
S3にアップロードするには「aws s3 cp <アップロードするファイル> <アップロード先URL>」を実行します。
$ aws s3 cp certs_pem.crl s3://netattest-s3/certs_pem.crl
upload: ./certs_pem.crl to s3://netattest-s3/certs_pem.crl
トラストストアにCRLを反映するにはトラストストアのARN、CRLが保存されているS3バケット名、S3バケットにアップロードしたcerts_pem.crlのキー名が必要です。
この情報を元に「aws elbv2 add-trust-store-revocations --trust-store-arn <トラストストアのARN> --revocation-contents S3Bucket=<S3バケット名>,S3Key=<キー名>,RevocationType=CRL」を実行します。
$ aws elbv2 add-trust-store-revocations --trust-store-arn arn:aws:elasticloadbalancing:ap-northeast-xxxxxxxx:truststore/NetAttest-ts/xxxxxxxxx --revocation-contents S3Bucket=netattest-s3,S3Key=certs_pem.crl,RevocationType=CRL
{
"TrustStoreRevocations": [
{
"TrustStoreArn": "arn:aws:elasticloadbalancing:ap-northeast-xxxxxxxx:truststore/NetAttest-ts/xxxxxxxxx",
"RevocationId": 6,
"RevocationType": "CRL",
"NumberOfRevokedEntries": 333
}
]
}
これでトラストストアにCRLが反映しました。
ただGUIでトラストストアを確認してみると前のCRLの情報も残っているので、これを削除します。
aws elbv2 add-trust-store-revocationsコマンドのレスポンスに「"RevocationId" : <ID番号>」が含まれており、トラストスアに反映したCRLのID番号がわかります。
この番号の1つ前が先に反映させたCRLなので、を「aws elbv2 remove-trust-store-revocations --trust-store-arn <トラストストアのARN> --revocation-ids <ID番号から1を引いた数字>」を実行します。
$ aws elbv2 remove-trust-store-revocations --trust-store-arn arn:aws:elasticloadbalancing:ap-northeast-xxxxxxxx:truststore/NetAttest-ts/xxxxxxxxx?--revocation-ids 5
いままでの流れをシェルスクリプトにしてみました。トラストストアARNなどが長いので一部を変数化してありますので、変数を自分の環境の値に置き換えてご利用ください。
#!/bin/bash
# 【変数】ご自身の環境に合わせて書き換えてご利用ください
# OneGateのCRL配布ポイントのURL
cdp="http://<SOGのテナントURL>/certs/<数字>/certs.crl"
# CRLファイルをアップロードするS3バケットのURL
S3URL="s3://netattest-s3"
# CRLがアップロードされているS3バケット名
Bucket="netattest-s3"
# S3バケットのCRLファイルのキー名
CRLKey="certs_pem.crl"
# トラストストアのARN
TrustStoreARN="arn:aws:elasticloadbalancing:ap-northeast-xxxxxxxx:truststore/NetAttest-ts/xxxxxxx"
# 【シェル本編】
# 前回のシェルスクリプトを実行したときのローカルから消しそこねたたCRLファイル本体があれば削除
if [ -f ./certs.crl ]; then
rm ./certs.crl
fi
if [ -f ./certs_pem.crl ]; then
rm ./certs_pem.crl
fi
# OneGateからCRLファイルをダウンロード
curl -O $cdp
# ダウンロードしたCRLをDER形式からPEM形式に変換
openssl crl -inform DER -outform PEM -in certs.crl -out certs_pem.crl
# S3バゲットにアップロード
aws s3 cp certs_pem.crl $S3URL
# EC2トラストストアに反映、コマンドの結果ををcrl_no.tmpに格納
aws elbv2 add-trust-store-revocations --trust-store-arn $TrustStoreARN --revocation-contents S3Bucket=$Bucket,S3Key=$CRLKey,RevocationType=CRL > crl_no.tmp
# JSONから値を抜き出すjqコマンドを使ってcrl_no.tmpからRevocationIdの値をCRL_No変数に代入
CRL_No=$(cat crl_no.tmp | jq '.TrustStoreRevocations[].RevocationId')
# CRL_Noの値から1を引いて、前回反映させた失効情報をトラストストアから削除
aws elbv2 remove-trust-store-revocations --trust-store-arn $TrustStoreARN --revocation-ids $((--CRL_No))
# 生成されたファイルたちを削除
rm -f ./certs.crl
rm -f ./certs_pem.crl
rm -f ./crl_no.tmp
こちらの内容を記載したファイルをcrl_upload.shとして保存して、実行権限をつけて実行してみます。
$ chmod 755 crl_upload.sh
$ ./crl_upload.sh
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 16792 100 16792 0 0 613k 0 --:--:-- --:--:-- --:--:-- 630k
upload: ./certs_pem.crl to s3://netattest-s3/certs_pem.crl
エラーが表示されなければスクリプトの完成です。
こちらを利用すれば、クライアント証明書がインポートした端末が紛失等にあってアクセスをブロックしたい場合に下記の流れで実施することで、証明書失効反映が比較的簡単になります。
crl_upload.shを定期的に自動実行できれば、端末紛失時などはOneGateで失効・CRL更新だけ行えばAWSに反映させることも可能です。
Linuxで定期実行するのはcronを使うのが一般的でしたが、Amazon Linux2023ではsystemdのtimerを使用して定期実行するようになりましたので、systemdで10分おきにcrl_upload.shを実行する方法を紹介します。
serviceファイルは実行内容を記載ファイルになります。今回は/home/ec2-user/crl_upload.shファイルを実行する内容にします。
$ sudo vi /etc/systemd/system/crlupload.service
[Unit]
Description=execute crl_upload.sh
[Service]
ExecStart=/usr/bin/sh /home/ec2-user/crl_upload.sh
User=ec2-user
WorkingDirectory=/home/ec2-user
timerファイルはserviceファイルを実行する間隔を指定します。今回は10分おきに実行させます。
$ sudo vi /etc/systemd/system/crlupload.timer
[Unit]
Description=execute crl_upload.sh
[Timer]
OnCalendar=*-*-* *:00/10:00
[Install]
WantedBy=timers.target
$ systemd-analyze calendar "*-*-* *:00/10:00"Normalized form: *-*-* *:00/10:00 Next elapse: Tue 2025-04-01 05:10:00 UTC From now: 21s left
作成したcrlupload.timerを自動起動有効にして起動します。
$ sudo systemctl enable crlupload.timer
Created symlink /etc/systemd/system/timers.target.wants/crlupload.timer → /etc/systemd/system/crlupload.timer
$ sudo systemctl is-enabled crlupload.timer
enabled
$ sudo systemctl start crlupload.timer
$ systemctl status crlupload.timer
● crlupload.timer - execute crl_upload.sh
Loaded: loaded (/etc/systemd/system/crlupload.timer; enabled; preset: disabled)
Active: active (waiting) since Tue 2025-04-01 05:35:58 UTC; 35s ago
Trigger: Tue 2025-04-01 05:40:00 UTC; 3min 25s left
Triggers: ● crlupload.service
Apr 01 05:35:58 ip-192-168-2-116.ap-northeast-1.compute.internal systemd[1]: Started crlupload.timer - execute crl_upload.sh.
※設定ファイルの記載を変更した場合などは「sudo systemctl daemon-reload」を実行してから「sudo systemctl restart crlupload.timer」を実行してください。
これで10分おきにCRLを取得してトラストストアに反映させることができます。
動作を確認するにはAWSのトラストストアで「失効ID」が増えているか、もしくは「journalctl -u crlupload.*」を実行して動作ログをご確認ください。