仮想MFAデバイスを使ってAWSのAPIにアクセスする

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

仮想MFAデバイス

以前、認証デバイスを使ってAWSにログインする方法を紹介しましたが、今回はAPIへのアクセスに認証デバイスが使えるようになったという新機能についてご紹介します。認証デバイスにはハードウェアがよく用いられていますが、最近ではソフトウェアで実現するものもあります。今回はGoogle Authenticatorを使います。

AWS Multi-Factor Authenticationでvirtual MFA devicesとしてGoogle Authenticatorを利用

IAMアカウントの作成

まずは、MFA-Protected API Accessの権限を持ったIAMアカウントを作成します。まずはグループを作成しましょう。

このグループにMFA-Protected API Accessの権限を記述します。このグループの下にユーザとしてmfatestを作成しました。

次にmfatestユーザ内でMFAデバイスの設定を行います。今回は、Virtual MFA deviceを指定します。

これでMFAデバイスを使う準備ができました。mfatestユーザのAccessKeyとSecretKeyをメモっておいてください。

Security Token Service

MFAデバイスを使ってAWSのAPIにアクセスするためには、アクセス権限を持ったユーザを使います。さらにMFAデバイスから発行されるトークンコードとユーザのシリアルナンバーを用います。トークンコードは一定時間で更新されてしまうためセキュアです。Security Token Service(STS)によって発行されるユーザは、統合ID(Federated User)ユーザか一時利用(Temporary)ユーザとなります。MFA-Protected API Accessで使えるのは一時利用ユーザだけです。

Temporary Security Credentials

一時利用ユーザは、その名の通り1時間など時間制限付きの証明書(Credentials)です。通常の証明書と同じようにリージョンを指定してEC2インスタンスを操作するなど可能です。

MFA-Protected API Access with Temporary Security Credentials

一連の流れをコードで表しました。コマンドラインからトークンコードを入力してEC2インスタンス一覧を表示します。

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.AWSSessionCredentials;
import com.amazonaws.auth.BasicSessionCredentials;
import com.amazonaws.auth.PropertiesCredentials;
import com.amazonaws.services.ec2.AmazonEC2;
import com.amazonaws.services.ec2.AmazonEC2Client;
import com.amazonaws.services.ec2.model.DescribeInstancesResult;
import com.amazonaws.services.ec2.model.Instance;
import com.amazonaws.services.ec2.model.Reservation;
import com.amazonaws.services.securitytoken.AWSSecurityTokenServiceClient;
import com.amazonaws.services.securitytoken.model.Credentials;
import com.amazonaws.services.securitytoken.model.GetSessionTokenRequest;
import com.amazonaws.services.securitytoken.model.GetSessionTokenResult;

public class AwsConsoleApp {

	public static void main(String[] args) throws Exception {
		
		//TokenCode from Console
		BufferedReader stdReader = new BufferedReader(new InputStreamReader(System.in));
		System.out.print("TokenCode : ");
		String line = stdReader.readLine();
		stdReader.close();

		//IAM Account with MFA-Protected API Access Policy
		AWSCredentials credentials = new PropertiesCredentials(
				AwsConsoleApp.class.getResourceAsStream("AwsCredentials.properties"));

		// Security Token Service
		AWSSecurityTokenServiceClient stsClient = new AWSSecurityTokenServiceClient(credentials);
		GetSessionTokenRequest stsRequest = new GetSessionTokenRequest();
		stsRequest.setDurationSeconds(3600);
		stsRequest.setSerialNumber("arn:aws:iam::XXXXXXXXXXXX:mfa/mfatest");
		stsRequest.setTokenCode(line);

		//Temporary Security Credentials
		GetSessionTokenResult stsResult = stsClient.getSessionToken(stsRequest);
		Credentials stsCredentials = stsResult.getCredentials();

		AWSSessionCredentials awsCredentials = new BasicSessionCredentials(
				stsCredentials.getAccessKeyId(),
				stsCredentials.getSecretAccessKey(),
				stsCredentials.getSessionToken());

		AmazonEC2 ec2 = new AmazonEC2Client(awsCredentials);
		ec2.setEndpoint("ap-northeast-1.ec2.amazonaws.com");

		//describe Instance count
		DescribeInstancesResult describeInstancesRequest = ec2.describeInstances();
		List<Reservation> reservations = describeInstancesRequest.getReservations();
		Set<Instance> instances = new HashSet<Instance>();

		for (Reservation reservation : reservations) {
			instances.addAll(reservation.getInstances());
		}

		System.out.println("You have " + instances.size() + " Amazon EC2 instance(s) running.");
	}
}

まとめ

あるユーザからAWSのAPIへアクセスするとき、個人を特定してアクセスしたい場合は、MFAデバイスを用いることでより信頼のある利用が可能になります。例えば、インスタンスをTerminateする時だけトークンコードを入力してもらうなどの手間を入れることができます。ということで、今回は動的なトークンコードとシリアルナンバーを指定することで、プログラムからAWSのAPIへのアクセスを制御できることが分かりました!API操作時にトークンを用いるってのは、かなり実践的ですよね。益々セキュアになるAWSに今後も期待大です。

参考資料

Configuring MFA-Protected API Access

AWS Multi-Factor Authenticationでvirtual MFA devicesとしてGoogle Authenticatorを利用