IAM Role Anywhereの構築を行ったあと、AWS CLIの設定をする際にWindowsの証明書ストアにある証明書をつかうまでに少し悩んだのでその設定方法を書いておきます。
具体的には .aws/config
の書き方および aws_signing_helper
のオプションです。
以下の記事にあるように aws_signing_helper
が証明書ストアをサポートしたので証明書ストアから読み込んでAWS CLIで使います。
証明書ストアのサポートは 1.0.5
からのようですが、今回設定したのは 1.1.1
です。
参考になれば幸いです。
今回 CA は ADCS です。クラスメソッドさんの記事が参考になりますが、aws_signing_helperが証明書ストアを使用できるようになったため、証明書テンプレートでエクスポート可能にする必要はありません。
環境構築 (トラストアンカー、プロファイル、ロール)
CloudFormationで行いました。証明書はそれぞれの環境に合わせてください。
AWSTemplateFormatVersion: '2010-09-09'
Resources:
IAMRoleAnywhereTrustAnchor:
Type: AWS::RolesAnywhere::TrustAnchor
Properties:
Name: "MY-TRUST-ANCHOR"
Enabled: true
Source:
SourceData:
X509CertificateData: |
-----BEGIN CERTIFICATE-----
PEM OF ADCS
-----END CERTIFICATE-----
SourceType: "CERTIFICATE_BUNDLE"
IAMRoleAnywhereRole:
Type: AWS::IAM::Role
Properties:
RoleName: "AnywhereRole"
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Principal:
Service: "rolesanywhere.amazonaws.com"
Action:
- "sts:AssumeRole"
- "sts:TagSession"
- "sts:SetSourceIdentity"
Condition:
ArnEquals:
"aws:SourceArn": !GetAtt IAMRoleAnywhereTrustAnchor.TrustAnchorArn
ManagedPolicyArns:
- arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess
IAMRoleAnywhereProfile:
Type: AWS::RolesAnywhere::Profile
Properties:
Enabled: true
Name: "AnywhereProfile"
RoleArns:
- !GetAtt IAMRoleAnywhereRole.Arn
Outputs:
RoleArn:
Description: "The ARN of the RoleAnywhere Role"
Value: !GetAtt IAMRoleAnywhereRole.Arn
ProfileArn:
Description: "The ARN of the RoleAnywhere Profile"
Value: !GetAtt IAMRoleAnywhereProfile.ProfileArn
TrustAnchorArn:
Description: "The ARN of the RoleAnywhere TrustAnchor"
Value: !GetAtt IAMRoleAnywhereTrustAnchor.TrustAnchorArn
セレクタの設定
ここから aws_signing_helper
の話になります。
cert-selector flag の章をみると 証明書ストアから証明書を選ぶには --cert-selector
を使用して指定するようです。
--cert-selector Key=x509Subject,Value=CN=Subject Key=x509Issuer,Value=CN=Issuer Key=x509Serial,Value=15D19632234BF759A32802C0DA88F9E8AFC8702D
file:
でファイルを指定する方式もあるようですが今回はコマンドラインオプションに指定します。
またセレクタの指定に x509Serial
があるのでそれを使用することにします。1
--cert-selector
を確認するのに sign-string
コマンドが便利なのでそちらをつかって確認しましょう。
sign-string
ではAWS側でIAM Role Anywhereの設定をしなくても --cert-selector
で証明書ストアから読み込めたかを確認できます。
まず certmgr.msc
を開いて使用する証明書のシリアル番号を調べます。(ちなみにこの証明書は鍵をエクスポートできない証明書です)
このシリアル番号を使用して、実行してみます。
>aws_signing_helper sign-string --format text --cert-selector \
Key=x509Serial,Value=2b000381af26496a4d5cd390ff0000000381af
865984511f956149088dfdebca3d839545995f1609f99a4de040ee10d57756c
...(中略)...
cb5e76da5a089827f112d36ca7d9f4c40e10ee3bf1e0e04a571c75b9b015a71
54f7123f
よさそうです。
また見つからなかった場合は 2024/06/25 10:48:03 no matching certs found in cert store
となりました。
実はx509Issuer
での指定も試してみたのですがうまくいきませんでした。
以下のようにIssuerが CNだけではなく、DCなども含んでいたためではないかと思っていますが、
いくつか試してみましたが、どのように指定するのかわかりませんでした。
aws_signing_helper read-certificate-data
で一覧が取得でき、cert-selectorも表示されるようなのですが、自分の証明書ストアだと一意に決まらないセレクタも提供されていました。
実用上はx509Serial
で十分な気もしますが、知っている方いれば教えてください。
(だいぶ理解できたので追記を書きました)
CN = EXAMPLE-CA
DC = example
DC = com
--cert-selector
がわかったのでこれを用いて .aws/config
を設定します。
見やすさの為、改行していますが、実際には1行で書いています。
[profile anywhere]
region = ap-northeast-1
output = json
credential_process = aws_signing_helper credential-process \
--cert-selector "Key=x509Serial,Value=2b000381af26496a4d5cd390ff0000000381af" \
--trust-anchor-arn "<YOUR_TRUST_ANCHOR_ARN>" --profile-arn "<YOUR-PROFILE-ARN>" \
--role-arn "<YOUR-ROLE-ARN>"
aws s3 ls --profile anywhere
として実行できます。
ADCSを使用する場合、できればエクスポート不可な証明書テンプレートでやりたいですよね。
これでエクスポート不可にしてもつかえますね。
追記 : x509Subject, x509Issuer の書き方
READMEにも書いてありましたが、RFC2253 に従って書くようです。ただし、手で書くには厳しい内容だなと思いました。
例えば、PowerShellなどで以下のようなSubjectの証明書があるとします。
実際にはADCSの既定の証明書テンプレート ユーザー
で作ったものでした。(メアドやドメインなど変えています)
Get-Item cert:\CURRENT_USER\My\xxxxxxxx | fl Subject
Subject : E=who@example.com, CN=xxxxxx, OU=Employees, DC=example, DC=com
read-certificate-data
の出力は以下のようになります。
1) fd6aa358da7c8ed80125ceb3adace70e805ae01d "CN=xxxxxx,OU=Employees,1.2.840.113549.1.9.1=#0c1377686f406578616d706c652e636f6d,0.9.2342.19200300.100.1.25=#130a6578616d706c65,0.9.2342.19200300.100.1.25=#1305636f6d"
aws_signing_helper read-certificate-data
ではSubjectを取得して表示していますので、これをx509Subject
のセレクタとして使用できます。
[
{ "Key" : "x509Subject",
"Value" : "CN=xxxxxx,OU=Employees,1.2.840.113549.1.9.1=#0c1377686f406578616d706c652e636f6d,0.9.2342.19200300.100.1.25=#130a6578616d706c65,0.9.2342.19200300.100.1.25=#1305636f6d"
}
]
でも1.2.840.113549.1.9.1
, 0.9.2342.19200300.100.1.25
って何? ってなりますね。
よくわからない数字の羅列 1.2.840.113549.1.9.1 はASN.1で記載されているOID (Object ID) です。
E(emailAddrss), 0.9.2342.19200300.100.1.25 はDC (domainComponent)を示しています。
また値となる文字列は #以降でおよそUTF-8の16進表現となっています。(ただし先頭数文字は文字数?が付与されているようです。)
ですのでこの謎の部分は、以下の表現となります。
1.2.840.113549.1.9.1=#0c1377686f406578616d706c652e636f6d : E=who@example.com
0.9.2342.19200300.100.1.25=#130a6578616d706c65 : DC=example
0.9.2342.19200300.100.1.25=#1305636f6d: DC=com
たしかにSubjectに記載の内容ですが、何をOIDで指定するのか? 順番はどうなるのか? など不明瞭な点が多いです。
ASN.1とかLDAPに詳しい方はわかるのかもしれませんが、これを気軽に書くのは無理かなと思いました。
特にSubjectは read-certificate-dataで取得できますが、Issuerはどうするのさという気分にはなります。
x509Serialとx509Issuerで証明書を一意にしたいと私は思うのですが、現状ではx509Serialだけで指定するのが無難かなと思います。
-
PowerShellだと
cert:\CURRENT_USER\MY\${Thumbprint}
で指定するのでserialじゃなくてThumbprintの方がうれしいなぁとか若干思いました。 ↩