Elastic Beanstalk/EC2メタデータ取得時に401エラー
概要
- Elastic Beanstalk によって起動された EC2インスタンスにログインし、OSからインスタンスメタデータ(meta-data)にアクセスしました。しかし、以下の 401エラーが発生しました。
- 本現象は、Elastic Beanstalk によって起動された EC2 だけでなく、通常のEC2インスタンスにおいても発生する可能性があります。
$ curl http://169.254.169.254/latest/meta-data/instance-id
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>401 - Unauthorized</title>
</head>
<body>
<h1>401 - Unauthorized</h1>
</body>
</html>
401エラーの原因
- 今回の 401エラーは、IMDSv1 と IMDSv2 の使用方法が異なるため発生しています。
- 起動中の EC2 インスタンスからインスタンスメタデータにアクセスする場合は、次のいずれかのメソッドを使用しています。
- インスタンスメタデータサービスバージョン 1 (IMDSv1) – リクエスト/レスポンスメソッド
- インスタンスメタデータサービスバージョン 2 (IMDSv2) – セッション志向メソッド
- EC2 のデフォルト設定は、IMDSv1,v2両方のメソッドが使用できます。IMDSv2 の使用を必須に変更した場合、IMDSv1 は機能しなくなります。
- IMDSv2 は、SSRF(Server Side Request Forgery)の脆弱性を利用した米金融大手の情報漏えいが発端となっている様です。米金融大手の情報漏えいの詳細は、こちらpiyolog を参照。
IMDSv1,v2 有効化の設定
EC2 の場合
- IMDSv2 の使用を必須にする設定は、EC2 の場合インスタンス作成時に、「高度な詳細」の「メタデータのバージョン」によって設定可能です。
- 「メタデータのバージョン」のデフォルトは、「V1 および V2 (トークンはオプション)」であり、「V2 (トークンは必須)」に変更すると、IMDSv2 の使用が必須になります。
Elastic Beanstalk の場合
- Elastic Beanstalk の場合、デフォルトは、「V2 (トークンは必須)」の状態です。
- カスタマイズする場合は、環境を選択し、「設定」→「インスタンス」の「編集」を押します。
- 以下の「インスタンスメタデータサービス (IMDS)」の「無効」をチェック外すと、 IMDSv1 と IMDSv2 の両方が有効になります。
IMDSv2 設定時のメタデータアクセス方法
IMDSv2 設定時のコマンド
- 先ず、以下のコマンドを使用してトークンを生成します。このコマンドは、PUTリクエストを使って、6時間 (21,600秒) のセッショントークンを作成しています。
TOKEN=`curl -X PUT “http://169.254.169.254/latest/api/token" -H “X-aws-ec2-metadata-token-ttl-seconds: 21600″`
- 次に、以下のコマンドを使用します。トークンを使って、メタデータを取得しています。
curl -H “X-aws-ec2-metadata-token: $TOKEN" -v http://169.254.169.254/latest/meta-data/
- 上記2つのコマンドを組み合わせて、使用することができます。
TOKEN=`curl -X PUT “http://169.254.169.254/latest/api/token" -H “X-aws-ec2-metadata-token-ttl-seconds: 21600″` \
&& curl -H “X-aws-ec2-metadata-token: $TOKEN" -v http://169.254.169.254/latest/meta-data/
実行結果サンプル
- 以下、実行結果サンプルです。
$ TOKEN=`curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"`
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 56 100 56 0 0 9333 0 --:--:-- --:--:-- --:--:-- 9333
$ curl -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/instance-id
i-12345678901234567