先日、とあるイベントに参加して、
「そういえば、暗号化してS3バケットにアップロードする記事を書いたのに、認証にアクセスキーを使ってた!」(セキュリティ・ベストプラクティスに沿ってない)
ということに気づいたので、補足することにしました。
AWS SDK for Javaを使ってS3にアップロードするデータを暗号化/SSE-KMS編 の続きです。
※手順は全然難しくないのですが、私はCMKのキーユーザーにIAM Roleを割り当てるのを忘れて、小一時間悩みました。その場合でも、返ってくるHTTPレスポンスコードが「403」(Access Denied)なので、単純にS3の認証/認可が通らないケースと区別が付きません…。
1. EC2用のIAM Roleを設定する
・**「AmazonS3FullAccess」にチェックを入れて[次のステップ]**をクリックします。
・ロール名を入れて**[ロールの作成]**をクリックします。
・作成したIAMロールを選択して**[アタッチ]**をクリックします。
・作成したIAMロールを、対象のEC2インスタンスに割り当てます。
・IAMロール名を入力/選択して**[適用]**をクリックします。
・処理が成功したら、対象のEC2インスタンスを開始(起動)し、IAM Roleが適用されていることを確認します。
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の認証/資格情報を使用することが可能です。