Java
AWS
AWS-S3
aws-sdk

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の認証/資格情報を使用することが可能です。