私の Java アプリケーションは、Amazon Elastic Compute Cloud (Amazon EC2) インスタンスで AWS SDK for Java を使用しています。しかし、"com.amazonaws.AmazonServiceException: The security token included in the request is expired (Service: AmazonSQS; Status Code: 403; Error Code: ExpiredToken; Request ID: 12a345b6-78cd-901e-fg23-45hi67890jkl)" というエラーメッセージが表示されます。
簡単な説明
すべてのアプリケーション API リクエストには、AWS が提供した認証情報を使用してデジタル署名する必要があります。アプリケーションが一時的な認証情報を使用して AWS クライアントを作成する場合、有効期限が切れる前にこれらの認証情報を更新する必要があります。認証情報の有効期限が切れている場合は、"security token included in the request is expired" というエラーが表示されます。
解決策
インスタンスに一貫した時間基準が設定されていることを確認する
認証情報が誤った時間を使用している場合は期限切れとなるため、サーバーが正確であることを確認してください。EC2 インスタンスには、一貫性のある正確な時刻と日付の基準が必要です。インスタンスで Amazon Time Sync Service または、その他の Network Time Protocol (NTP) ソースを設定します。詳細については、「インスタンスのタイムゾーンを変更する」を参照してください。
一時的な認証情報が期限切れになっていないことを確認する
一時的な認証情報を使用する場合は、有効期限が切れていないことを確認してください。一時的な認証情報の有効期限が切れた場合は、新しい一時的な認証情報セットを生成して使用する必要があります。一時的な認証情報は、有効期限が切れる 5 分前に更新するのがベストプラクティスです。
IAM 設定を確認する
インスタンスで実行されるアプリケーションでは、インスタンスに AWS Identity and Access Management (IAM) ロールを使用するのがベストプラクティスです。
IAM ロールを使用する場合は、必ずロールの認証情報をインスタンスプロファイルにのみ記載してください。IAM ロールでは、デフォルトのサービスコンストラクターがデフォルトの認証情報プロバイダーチェーンを使用して、次の順序で認証情報を検索します。
- システム環境変数 AWS_ACCESS_KEY_ID と AWS_SECRET_ACCESS_KEY 内。
- Java のシステムプロパティ aws.accessKeyId と aws.secretKey 内。
- デフォルトの認証情報ファイル内。
- IAM ロールに関連付けられたインスタンスメタデータのインスタンスプロファイル認証情報内。
インスタンスプロファイル以外の場所に認証情報を記述した場合、デフォルトのクライアントコンストラクターは、最初にそれらの認証情報を検索します。この設定により、IAM ロール認証情報はブロックされます。この問題を解決するには、他の場所で認証情報を確認してください。デフォルトの認証情報ファイルを確認するには、ご使用のオペレーティングシステム (OS) に応じて次の場所を確認してください。
- Linux、macOS、または Unix の場合は、* ~/.aws/credentials を確認してください。
- Windows の場合は、C:\Users\USERNAME\.aws\credentials を確認してください。
注: USERNAME は、実際のユーザー名に置き換えてください。
インスタンスプロファイル以外の場所に認証情報が見つかった場合は、それらを削除します。一時的な認証情報の設定の詳細については、「に一時的な認証情報を提供する AWS SDK for Java」を参照してください。
IAM ロールの認証情報を確認するには、ご使用の OS に応じて次のコマンドを実行します。必ず Windows PowerShell バージョン 3.0 以降を使用するか、または Linux シェルから実行してください。
Windows:
PS C:\> Invoke-RestMethod http://169.254.169.254/latest/meta-data/iam/security-credentials/examplerole
注: examplerole は、実際の IAM ロールの名前に置き換えてください。一時的な認証情報を使用する場合、前述のコマンドはインスタンスの最新の一時的な認証情報を表示します。
出力例:
Code : SuccessLastUpdated : 2016-07-18T18:09:47Z
Type : AWS-HMAC
AccessKeyId : AKIAIOSFODNN7EXAMPLE
SecretAccessKey : wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
Token : token
Expiration : 2016-04-27T22:39:16Z
Linux:
curl http://169.254.169.254/latest/meta-data/iam/security-credentials/examplerole
注: examplerole は、実際の IAM ロールの名前に置き換えてください。一時的な認証情報を使用する場合、前述のコマンドはインスタンスの最新の一時的な認証情報を表示します。上記のコマンドを実行して 404 エラーが表示された場合は、メタデータ IP アドレスの HTTP プロキシが無効化されていることを確認してくださいインスタンスプロファイルがインスタンスにアタッチされていることも確認してください。
出力例:
{ "Code" : "Success", "LastUpdated" : "2016-04-26T16:39:16Z",
"Type" : "AWS-HMAC",
"AccessKeyId" : "AKIAIOSFODNN7EXAMPLE",
"SecretAccessKey" : "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
"Token" : "token",
"Expiration" : "2016-04-27T22:39:16Z"
}
注: ロールの認証情報は、割り当てられた一時的な認証情報の有効期限が切れる 5 分前に自動的にローテーションまたは更新されます。
再試行を構成する
注: AWS コマンドラインインターフェイス (AWS CLI) コマンドの実行中にエラーが発生した場合は、「AWS CLI のエラーのトラブルシューティング」を参照してください。また、AWS CLI の最新バージョンを使用していることを確認してください。
問題が解決しない場合は、インスタンスが複数の同時リクエストを行っておらず、複数のセッションを並行して実行していないことを確認します。このシナリオでは、インスタンスメタデータサービス (IMDS) によるクエリのスロットリングが発生する場合があります。この問題を軽減するには、エクスポネンシャルバックオフパターンを使用して再試行します。
再試行を設定するには、AWS_METADATA_SERVICE_NUM_ATTEMPTS の値を増やして、Boto3 がインスタンスメタデータサービスから認証情報を取得する試行を再試行できるようにします。デフォルトでは、Boto3 はタイムアウトになる前に 1 回だけ試行します。また、AWS_METADATA_SERVICE_TIMEOUT の値を増やして、インスタンスメタデータサービスへの接続がタイムアウトするまでの秒数を増やしてください。デフォルトでは、接続は 1 秒後にタイムアウトします。
設定例:
AWS_METADATA_SERVICE_TIMEOUT = 10
AWS_METADATA_SERVICE_NUM_ATTEMPTS = 5
上記のオプションを設定するには、環境変数、~/.aws/config ファイル、またはユーザーの botocore セッションを使用します。手順については、Boto3 ドキュメント ウェブサイトの「Configuration」(設定) を参照してください。
Docker コンテナで curl コマンドを実行する場合は、次の AWS CLI コマンド modify-instance-metadata-options を実行してホップ制限を 2 に増やします。
aws ec2 modify-instance-metadata-options --instance-id instance --http-put-response-hop-limit 2 --http-endpoint enabled
注: instance は、実際のインスタンス ID に置き換えてください。詳細については、「インスタンスメタデータアクセス考慮事項」の「コンテナ環境では、再設定またはホップ制限を 2 に引き上げることを検討してください」を参照してください。
関連情報
AWS を使用した での認証 AWS SDK for Java 2.x
Amazon EC2 の IAM ロール
Add defense in depth against open firewalls, reverse proxies, and SSRF vulnerabilities with enhancements to the Amazon EC2 Instance Metadata Service (Amazon EC2 インスタンスメタデータサービスの機能強化による、オープンファイアウォール、リバースプロキシ、SSRF の脆弱性に対する詳細な防御の追加)