Edited at

EC2 IAM Role環境でSSE-KMS暗号化を使ってS3バケットにアクセスする(AWS SDK for Java)

More than 1 year has passed since last update.

先日、とあるイベントに参加して、

「そういえば、暗号化してS3バケットにアップロードする記事を書いたのに、認証にアクセスキーを使ってた!」(セキュリティ・ベストプラクティスに沿ってない)

ということに気づいたので、補足することにしました。

AWS SDK for Javaを使ってS3にアップロードするデータを暗号化/SSE-KMS編 の続きです。

※手順は全然難しくないのですが、私はCMKのキーユーザーにIAM Roleを割り当てるのを忘れて、小一時間悩みました。その場合でも、返ってくるHTTPレスポンスコードが「403」(Access Denied)なので、単純にS3の認証/認可が通らないケースと区別が付きません…。


1. EC2用のIAM Roleを設定する

・IAMで[新しいロールの作成]をクリックします。

01_iam1.png

「Amazon EC2」を選択します。

02_iam2.png

「AmazonS3FullAccess」にチェックを入れて[次のステップ]をクリックします。

03_iam3.png

ロール名を入れて[ロールの作成]をクリックします。

04_iam4.png

・S3暗号化に使う暗号化キーを選択します。

05_kms1.png

キーユーザー[追加]をクリックします。

06_kms2.png

作成したIAMロールを選択して[アタッチ]をクリックします。

07_kms3.png

・作成したIAMロールを、対象のEC2インスタンスに割り当てます。

08_ec2_1.png

IAMロール名を入力/選択して[適用]をクリックします。

09_ec2_2.png

・処理が成功したら、対象のEC2インスタンスを開始(起動)し、IAM Roleが適用されていることを確認します。

11_ec2_4.png


2. Javaコードの変更

Javaコードについては、単純にcredentialsの指定を外すだけでOKです。


変更点

public class S3Access {

private static final String ENDPOINT_URL = "https://s3-ap-northeast-1.amazonaws.com";
private static final String REGION = "ap-northeast-1";
// private static final String ACCESS_KEY = "【アクセスキー】";
// private static final String SECRET_KEY = "【シークレットキー】";
private static final String KMS_KEY_ID = "【KMSキーID】";

(中略)

//--------------------------------------------------
// クライアント生成
//--------------------------------------------------
private AmazonS3 getClient(String bucketName) throws Exception {

// // 認証情報
// AWSCredentials credentials = new BasicAWSCredentials(ACCESS_KEY, SECRET_KEY);

// クライアント設定
ClientConfiguration clientConfig = new ClientConfiguration();
clientConfig.setProtocol(Protocol.HTTPS); // プロトコル
clientConfig.setConnectionTimeout(10000); // 接続タイムアウト(ms)

// エンドポイント設定
EndpointConfiguration endpointConfiguration = new EndpointConfiguration(ENDPOINT_URL, REGION);

// クライアント生成
AmazonS3 client = AmazonS3ClientBuilder.standard()
// .withCredentials(new AWSStaticCredentialsProvider(credentials))
.withClientConfiguration(clientConfig)
.withEndpointConfiguration(endpointConfiguration).build();

(後略)


行頭の「//」でコメントアウトしている行を削除します。

※すでにコード内に認証情報を記述しない形にしていて、環境変数や実行ユーザのホームディレクトリ(Amazon Linuxにyumでtomcat8をパッケージインストールした場合は /usr/share/tomcat8/)直下に「.aws」ディレクトリを作成し、「credentials」ファイルにアクセスキーを記述して使用していた場合は、それらを削除すると、IAM Roleの認証/資格情報を使用することが可能です。