2021/07/19

AWS CLI を使用した TLS 証明書の取得

ダニエル先生の 資料 を見ていて、証明書ストア(CertStore.nsf)の「DNS プロバイダ設定」文書で「種類」に"コマンド"を選ぶことで AWS Route 53 を使って TLS 証明書を取得することができるらしいことを知りました。

私はこの「種類」に "コマンド" を選択した事がありませんでした。

そもそも、ヘルプには「DNS プロバイダ設定」文書をインポートする方法について書かれてはいるものの、文書をいちから作成することを想定した項目ごとの説明が現状ありません。


とは言え、できるらしいことがわかったので試してみることにしました。

そして TLS 証明書の取得に成功しました。

以下、設定の内容です。

※「ACME アカウント・プロファイルを構成する」の手順を実施しておく必要があります


CertStore.nsf の「DNS プロバイダ設定」文書の[操作]タブで「種類」に"コマンド"を選択すると、「DNS 追加コマンド式」と「DNS 削除コマンド式」の2つの入力欄が現れます。

※2022/2/8 追記:「種類」の選択肢にある "コマンド" と "エージェント" は現状サポートされていない、とメーカーサポートから聞きました。ただ、多様なDNS側の実装のすべてにREST API できるわけでは無いことと、"コマンド"を利用して実現可能であることは確認しているとして、ケースバイケースでの対応となるようです。"エージェント"は実装が不十分とのことで私も検証の時間を無駄に使ってしまいました。


"式"とあるように、ここには DNS へ TXT レコードを追加/削除するコマンドを生成するための式を記述します。

Route 53(AWS の DNS プロバイダサービスの名称)で管理するホストゾーンへ DNS レコードを追加する方法のひとつとして、AWS CLI(別途インストール必要)を利用できます。AWS CLI コマンドを「DNS追加コマンド式」「DNS削除コマンド式」へ記述しておくと、CertMgr が DNS-01 チャレンジの中でコマンドを実行します。


下は Route 53 へ TXT レコードを追加するためのコマンド(AWS CLI)のサンプルです。サンプルを見やすくするために改行とインデントを追加していますが、実際のコマンドではどちらも削除して1行のコマンドにしています。

※CLI で IAM ユーザーを使い分けている場合は --profile オプションを追加します

aws route53 change-resource-record-sets
--hosted-zone-id <DnsZoneID>
--change-batch=
{
    \"Comment\":"\"Create TXT Record\"",
    \"Changes\":[
        {
            \"Action\":\"CREATE\",
            \"ResourceRecordSet\":{
                \"Name\":\"<DnsTxtName>\",
                \"Type\":\"TXT\",
                \"TTL\":120,
                \"ResourceRecords\":[
                    {
                        \"Value\":\"\\\"<DnsTxtValue>\\\"\"
                    }
                ]
            }
        }
    ]
}

赤色で示した3つの項目 <DNSZoneID>、<DnsTxtName>、<DnsTxtValue>は、式の中で値を置換するものです。

"--change-batch=" 以降には JSON 文字列を指定します。ダブルコーテーション等を円記号(※バックスラッシュで見えているかもしれません)でエスケープします。

なお、Action にある "CREATE" を "DELETE" に変えると DNS レコードを削除できます。また "CREATE" を "UPSERT" に変えると、TXTレコードが無ければ作成、既存ならば上書きされます。テスト等で作成したTXTレコードを消し忘れても UPSERT ならコマンド発行時にエラーになりませんね...

赤色で示した3つの項目を適切な値に置き換えた文字列を、Windows のコマンドプロンプトから投入して追加に成功すると、次のようなレスポンスがあります。

{
   "ChangeInfo": {
       "Id": "/change/C0555976HW63RRSAMPLE",
       "Status": "PENDING",
       "SubmittedAt": "2021-07-17T01:26:57.282Z",
       "Comment": "Create TXT Record"
   }
}

レスポンスにある Status が "PENDING" の間は、DNS への変更をすべての Route 53 権威DNS サーバーに伝搬中らしいのですが、通常は 60 秒以内に伝搬するとのこと。※ここを参照


これらを踏まえて作成した「DNS プロバイダ設定」文書が次のスクショです。

(円記号を式の中で使うためにエスケープが必要なのでさらに円記号が増えてます...こうなると読みづらいですね)


「DNS 追加コマンド式」の中では、コマンドの内容を正しく指定するために次のフィールド名を使用しています。

cfg_DnsZone証明書ストア(CertStore.nsf)に作成した「DNS プロバイダアカウント」文書の「DNS ゾーン」フィールドの値を参照する
param_DnsTxtNameCA(Let's Encrypt)から指定された TXT レコード名。ホスト名の頭に "_acme-challenge." が付いた文字列
param_DnsTxtValueCA(Let's Encrypt)から指定された TXT レコードにセットするDNS チャレンジダイジェスト


「ステータス式」には、レスポンスの JSON からステータスを抽出して、正常なら200、異常なら400を返す、という内容の式を記述しました。

CertMgrは、JSON形式のレスポンスを retJSON_Command というフィールドにセットします。このフィールドにセットされている、ステータスの値がセットされているポインタ ChangeInfo.Status から値を取り出したいので、ステータス式の@If文で「retJSON_Command.ChangeInfo.Status」と指定しています。

Route 53 では、コマンド投入時に通常は "PENDING" と返すらしいのですが、万が一伝搬完了を示す "INSYNC" を返しても成功としたいので、どちらを返しても成功(=200)としました。

【メモ】

ステータス式は、「DNS 追加コマンド式」と「DNS 削除コマンド式」のどちらにも共通で使われます。ステータス式の中で、それが実行されているタイミングが「追加」の後か「削除」の後なのかを判断することはできないとのこと。追加と削除のレスポンスが異なる場合は工夫が必要です。

【メモ】

コマンド式に指定するコマンドにバッチファイルを指定する場合、バッチファイルが出力する結果を JSON 形式にすることによって、ステータス式からは retJSON_Command という変数でアクセスできるようです。

 

それから DNS 追加コマンドの投入後、すべての Route 53 権威 DNS サーバーには通常 60 秒以内に伝搬するとのことなので「DNS プロバイダ遅延」には 60 をセットしました。こうすることで CertMgr は DNS へ TXT レコードを追加した後、次の動作まで 60 秒間待機します。

【メモ】

「DNS プロバイダ遅延」の値は、指定しない場合のデフォルト値が20(秒)となり、20より小さい値を指定しても20にセットされるとのこと。つまりは最小値が20らしい。なお最大値は設定されていないとのこと。


この「DNS プロバイダ設定」文書の[基本]タブの「設定名」に "Route 53" として保存します。

【メモ】

今回使用しなかった「Cmd environment formula」では、追加/削除コマンドの実行に使用するために環境変数へセットする、といった用途で使えるようです。"name:value" のように「パラメータ名:値」という式で設定できるらしい(未確認)  


次に作成する「DNS プロバイダアカウント」文書では、[基本]タブにある「登録済みドメイン」には Route53 に作成したホストゾーンのドメイン名を指定して、「DNSプロバイダ設定」には上で作成した "Route 53" を選択、「DNS ゾーン」には Route 53 で自身が管理するホストゾーンの「ホストゾーン ID」をそれぞれ指定します。ちなみに私のホストゾーンでは、ホストゾーン IDが20桁の英数字でした。


そして「TLS 証明書」文書を作成します。指定した項目は下のスクショのとおりですが、ここでは「キーリングファイル」を空のままにしています。またこれはテストなので ACME アカウントには "LetsEncryptStaging" を選択しています。

「ホスト名」に指定したドメイン部分が一致する DNS ドメインの文書があれば証明書をDNS-01 チャレンジで取得する、という挙動をするようです。

「TLS 証明書」文書を作成したら文書上部にあるアクションボタン [要求の送信] をクリックします。しばらくすると CertMgr が証明書取得を行い(成功すれば)この文書内に証明書が格納されます。


証明書が取得ができたら、サーバー文書などの「TLSキーファイル名」に指定されている keyfile.kyr といったファイル名はホスト名に書き換えます。そうすると CertStore.nsf の「TLS 証明書」文書に格納されている証明書を参照するようになります。



最後に、今回作成しました Route 53 用の「DNS プロバイダ設定」文書をエクスポートしたもの(DXL ファイル)をこちらへアップロードしました。

「DNS プロバイダ設定」文書は DXL ファイルからのインポートすることで作成可能です。

DXL ファイルの内容について私が個別にサポートすることはできませんが、設定の参考にしていただければ幸いです。

もし Route 53 で管理するドメインをお持ちでしたら、Domino V12 の CertMgr と AWS CLI を使って TLS 証明書管理の機能を試してみてはいかがでしょうか。


【2021/7/26 追記】

Domino を Windows サービスで起動すると、CertMgr が AWS CLI コマンドの実行した時にコンソールに次のメッセージが表示されるようになり、コマンド実行が失敗するようになりました。

Unable to locate credentials. You can configure credentials by running "aws configure".

Windows サービスで Domino を起動するときの実行ユーザーは、指定しなければローカルシステムアカウントになりますが、このアカウントが認証情報(クレデンシャル)を探せないことが、メッセージを表示する理由でした。

【メモ】

認証情報(クレデンシャル)は通常、ログインユーザーに固有のパス(windows なら C:\Users\User_Name\.aws\credentials)に格納されています

 

【メモ】

認証情報のうち「アクセスキーID」は IAMユーザー作成後もマネジメントコンソールで確認できますが「シークレットアクセスキー」は作成時に表示されるため、それが分からなくなった場合[アクセスキーの作成]ボタンで作成しないといけないようです

認証情報は環境変数で指定することが可能です。環境変数を経由して認証情報を渡すために「DNS プロバイダ設定」文書の「Cmd environment formula」を利用できます。ここに「"名前:値"」といったように指定していきます。

認証情報として環境変数で指定したいものは「AWS_ACCESS_KEY_ID」と「AWS_SECRET_ACCESS_KEY」の2つです。これらを「Cmd environment formula」へ

「"AWS_ACCESS_KEY_ID:<値>":"AWS_SECRET_ACCESS_KEY:<値>"」

のように指定します。

ここで、例えばドメインごとに認証情報を変えたいといった場合には、上の様に式の中に認証情報の値を直接埋め込むと不都合なこともあると思います。そういったときは「DNSプロバイダアカウント」文書の「許可キー」「認証トークン」「カスタム値」といった使っていないフィールドを活用し、それらのフィールドに設定した値を参照するような設定が可能です。

下は「DNSプロバイダアカウント」文書の「許可キー」に AWS_ACCESS_KEY_ID の値、「カスタム値」に AWS_SECRET_ACCESS_KEY の値をそれぞれ設定している前提で「DNSプロバイダ設定」文書の「Cmd environment formula」に指定する式のサンプルです。

「("AWS_ACCESS_KEY_ID:"+cfg_AuthKey):("AWS_SECRET_ACCESS_KEY:"+cfg_CustomValue)」

こうすることで CLI が環境変数から認証情報を参照するようになります。環境変数は CertMgr が処理の中で追加と削除を自動で行います。

上の式を含む DXL ファイルをこちらへアップロードしました。※ファイル名に「1.1」を含むファイルです。「1.1」の DXL ファイルを使う場合は「DNSプロバイダアカウント」文書の「許可キー」と「カスタム値」に認証情報を追加してください。

0 件のコメント:

コメントを投稿