hiyoko-programingの日記

プログラミングを勉強したてのひよっ子。   エンジニア目指して勉強中。

S3を使った画像をアップロード

投稿機能の動作確認

ローカル開発環境でChatSpaceを起動して、以下の全ての投稿がうまく行くことを確認する。

①テキストのみの投稿
②画像のみの投稿
③テキストと画像両方の投稿

ここできちんと確認しておけば、例えばデプロイ後に画像アップロードがうまくいかなかったとしても、ローカルではうまくいっていたと確証を持つことができる。

それによって、不具合の原因は「ローカルでの開発より後に行った作業」にある、とあたりをつけることができる。

 

セキュリティ対策を行う

まず最初に、S3を使用する上でどうなると被害が出るのか確認する。

悪意を持ったユーザーにAWSのIDとパスワードが漏れてしまうことで被害が発生する。

AWSは従量制のサービスのため、他人がなりすましでログインして膨大な処理を行うと、それに対する支払いが発生してしまう。

では、それをどのような手段で防ぐのか。

https://tech-master.s3.amazonaws.com/uploads/curriculums//ce57ea84a7b977a276f790e14a210f0b.png

下記の3つの手段を取る。

セキュリティ対策① 二段階認証

二段階認証は、あるサービスにログインする際に、通常パスワードに加えて、別の方法でも認証されないとログインできないようにする仕組み。

万が一パスワードが漏れたとしても、それだけでは乗っ取られないため安全性を高めることができる。

このレッスンでは、以下のログイン時に二段階認証がされるようにする。
- AWSへのルートユーザーでのログイン
- AWSへのIAMユーザーでのログイン

このIAMユーザーについては、次に確認する。

 Authyを使う準備をしよう

Authy二段階認証のためのアプリで、スマートフォン(iOS/Android)でもPCでも使うことができる。

Authyを起動するとパスワードが表示されるので、二段階認証の際にそれを入力する。パスワードは一定時間ごとに自動で変更されるため、漏洩のリスクが低くなっている。

Authyのインストール

Authyを自分のスマホにインストールする。自分が利用するスマホの種別に応じたものを導入する。

初期設定を行う

初めてアプリを起動すると「電話番号」と「メールアドレス」を聞かれるので登録。

電話番号は、ここで登録した番号にSMSで確認コードが来るので、自分のスマホの電話番号を登録する。

  • codeは+81 (Japan)
  • 最初の0を抜いた自分のスマホの電話番号

登録後に"GET ACCOUNT VERIFICATION VIA"のメッセージが表示されるので、確認コード送付方法として「SMS」を選択する。

届いた確認コードをAuthyに入力したら、初期設定が完了。

AWSでの二段階認証設定を行う

ヘッダー部分に表示されているアカウント名をクリックして、メニューの中から「マイセキュリティ資格情報」を選択する。

https://tech-master.s3.amazonaws.com/uploads/curriculums//7b208b36dfe528f1484f79d35b595ad5.png

モーダル画面が表示されたら、「Continue to Security Credentials」をクリック。
https://tech-master.s3.amazonaws.com/uploads/curriculums//9e440df08e49c03baf9103e62d0b1ddb.png

メニューの中の「多要素認証(MFA)」をクリックすると内容が展開されるので、「MFAの有効化」をクリック。
https://tech-master.s3.amazonaws.com/uploads/curriculums//104f6e5d836c4839cba9237bdddf3eca.png

モーダル画面の中から「仮想MFAデバイス」が選択されているのを確認して、続行をクリック。
https://tech-master.s3.amazonaws.com/uploads/curriculums//7e6fbd2e078c0bebe160fd4b74c7a71b.png

次の画面で「QRコードの表示」をクリックすると、QRコードが表示される。
https://tech-master.s3.amazonaws.com/uploads/curriculums//2bd0e9ca5824183320d09fb4ae6ffeb9.png

ここまでできたら、スマホでAuthyを開く。

AuthyにAWSアカウントを追加する

Authyを開いたら、「Accounts」にある「+」ボタンをタップする。
https://tech-master.s3.amazonaws.com/uploads/curriculums//6eb0de4925b045439a842058d2f12014.png

カメラが起動するので、先ほどのQRコードを読み取る。

設定画面を終了すると、二段階認証用のパスワードが表示される。
ワンタイムパスワードと呼ばれるもので、30秒経つと自動的にそのパスワードは無効になる。

このパスワードをAWSで入力する。

https://tech-master.s3.amazonaws.com/uploads/curriculums//e4f74d220f671a5a99a346365200ae1d.png

1つ目のパスワードを上の欄に、そのパスワードの次に表示されたパスワードを下の欄に入力。
最後に「MFA」の割り当てをクリックして設定は完了。

AWSのログイン時に追加でパスワードを求められるようになるので、Authyで表示されたパスワードを入力する。

セキュリティ対策② IAMユーザーの利用

IAMユーザーは、AWSのサービスの1つ。

最初にAWSで作ったアカウントはルートユーザーと呼ばれ、ルートユーザーでAWSにログインすると全ての機能を使うことができる。

そのため、万が一ルートユーザーのID・パスワードが漏洩し悪用されると、第三者が全ての機能を使えてしまう。

https://tech-master.s3.amazonaws.com/uploads/curriculums//8927be02e88f68c19cea0b29bd11bd5d.png

それを防ぐために、使える機能を制限したユーザーを作成し、通常の作業はそのユーザーでログインし行うようにする。

この機能を制限したユーザーを作成できる機能がIAM。

 IAMユーザーを作成する

ログイン後の以下のページの、検索のフォームにIAMと打ち込み、出てきた検索結果からIAMのページに飛ぶ。

https://tech-master.s3.amazonaws.com/uploads/curriculums//decc150c8e71774416fbc617619072ff.png

遷移先のページで、以下をクリック。

https://tech-master.s3.amazonaws.com/uploads/curriculums//3fa7374c90fda4f13d8acc3134ce506a.png

左上の「ユーザーを追加」を選択。

https://tech-master.s3.amazonaws.com/uploads/curriculums//cc09e386d0acce905ccad157b2c0ec36.png

作成するユーザーの名前を登録。

https://tech-master.s3.amazonaws.com/uploads/curriculums//b0760d72ba36ec167611e69acfbb4969.png

記入したら、「次のステップ」に進む。

次はアクセス権限を設定する。

「既存のポリシーを直接アタッチ」から「AmazonS3FullAccess」に設定する。

チェックを入れたら「次のステップ タグ」と書かれたボタンをクリック。

https://tech-master.s3.amazonaws.com/uploads/curriculums//4fe4da99773676f4e0d26017c5ef1b5e.png

次は何もせずに、「次のステップ: 確認」を押す。

https://tech-master.s3.amazonaws.com/uploads/curriculums//c76b55e264ff756cc24970fbb18b8517.png

最後に設定の確認をして、画像と同じ設定になっていればOK。「ユーザーの作成」をクリック。

この時「アクセス権限の境界:アクセス権限の境界が設定されていません」という表示が追加でされていることもあるが、設定に問題はない。

https://gyazo.com/c531d1646171d86e987df3a5b881127c

これでユーザーの作成が完了。

※忘れずに認証情報をダウンロードしておく!

https://tech-master.s3.amazonaws.com/uploads/curriculums//76a44ad92c6aa2c636bf1b226dcedbec.png

 IAMユーザーのパスワードを設定

IAMのメニューから作成したIAMユーザーをクリック。「認証情報」のタブをクリックすると以下のページに遷移するので「コンソールのパスワード」欄の管理 をクリックする。

https://tech-master.s3.amazonaws.com/uploads/curriculums//ad8b5888567834eb321863f966321016.png

そのまま下の画像のように「有効化」「自動生成パスワード」をクリック。

https://tech-master.s3.amazonaws.com/uploads/curriculums//fdf0f8846f359a34c16deb06bce029e4.png

ルートユーザーの時と同じく、認証情報はダウンロードしておく(ここではcsvファイルとしてダウンロードできる)。

https://tech-master.s3.amazonaws.com/uploads/curriculums//4a1f66eebc53f8cf282d64b59a78e860.png

 作成したIAMユーザーでログインする

作成したIAMユーザーでログインできることを確認。

まずルートアカウントのサインアウトを行う。

https://tech-master.s3.amazonaws.com/uploads/curriculums//6ffcdfbc294d6e8afe5ad6f38267ee45.png

続いて、先ほどダウンロードしたcredentialの情報を使ってログインする。

https://tech-master.s3.amazonaws.com/uploads/curriculums//eae149b54ab0ac8d89d6342265ea6a87.png

正常にログインできれば成功。

IAMユーザーも二段階認証に設定する

改めてログアウトし、ルートユーザーでログインしなおす。二段階認証になっていることに注意。

続いて、再びIAMのユーザー選択画面から先ほど作成したユーザー名を選択し遷移したページ先で、以下の「MFAデバイスの割当」をクリック。

https://tech-master.s3.amazonaws.com/uploads/curriculums//65e3da37fa1a84e61c70e051a656c228.png

あとは、ルートユーザーの時と同じように二段階認証の設定を行う。

セキュリティ対策③ git-secrets

ChatSpaceは、GitHubのpublicリポジトリソースコードをアップロードしている。
そのため、誤操作でパスワードをGitHubにpushしてしまうと誰でも見られる状態になってしまう。

git-secretsは、そのような誤操作を防いでくれるツール。pushしようとしたコードをチェックし、パスワードだと推定されるような文字列が含まれている場合は、そこで処理が中断される仕組み。

 git-secretsをインストール

ターミナルから、Homebrewを経由してgit-secretsを導入する。

ターミナル
1
2
$ cd ~/
$ brew install git-secrets

git-secretsが導入できたら、設定を適用したいリポジトリに移動して、git-secretsを有効化する。

ターミナル
1
2
$ cd chatspace
$ git secrets --install

これで、有効化を行なったリポジトリでgit-secretsを使用する準備が完了。

続いて、「どのようなコードのコミットを防ぐのか」を設定していく。この後の作業はChatSpaceのディレクトリで実行する。

 git-secretsの条件を設定

下記のコマンドを実行することで、secret_key, access_keyなど、アップロードしたくないAWS関連の秘密情報を一括で設定することができる。

ターミナル
1
$ git secrets --register-aws --global

現在のgit-secretsの設定は、下記のコマンドで確認することができる。

ターミナル
1
2
3
4
5
6
7
8
$ git secrets --list

secrets.providers git secrets --aws-provider
secrets.patterns [A-Z0-9]{20}
secrets.patterns ("|')?(AWS|aws|Aws)?_?(SECRET|secret|Secret)?_?(ACCESS|access|Access)?_?(KEY|key|Key)("|')?\s*(:|=>|=)\s*("|')?[A-Za-z0-9/\+=]{40}("|')?
secrets.patterns ("|')?(AWS|aws|Aws)?_?(ACCOUNT|account|Account)_?(ID|id|Id)?("|')?\s*(:|=>|=)\s*("|')?[0-9]{4}\-?[0-9]{4}\-?[0-9]{4}("|')?
secrets.allowed AKIAIOSFODNN7EXAMPLE
secrets.allowed wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY

これで、git secrets --installを行なったリポジトリでは、コミット時にAWSの秘密情報を含んだコードがないかチェックされるようになった。

「うっかりパスワードをGithubに載せてしまった」という事態を防ぐことができるので、必ず設定を行う。

 今後作成する全てのリポジトリにgit-secretsが適用されるようにする

ここまでの設定では、今後作成するリポジトリにはgit-secretsが適用されない。
特段の理由がなければ、以下のコマンドを実行して自動で適用されるようにする。

ターミナル
1
2
$ git secrets --install ~/.git-templates/git-secrets
$ git config --global init.templatedir '~/.git-templates/git-secrets'

 GitHub Desktopからgit secretsを利用できるようにする

GitHub Desktop経由でgit secretsを利用する場合は、追加の設定をする。
この時、Github Desktopがapplicationフォルダに存在している必要がある。

適宜移動しておく。

https://tech-master.s3.amazonaws.com/uploads/curriculums//14f3e6af77ec58b528f765b8c332c0db.png

引き続きGitHub Desktopを利用するため、以下を実行。

ターミナル
1
$ sudo cp /usr/local/bin/git-secrets /Applications/GitHub\ Desktop.app/Contents/Resources/app/git/bin/git-secrets

上記コマンドでNo such file or directoryのエラーがでる場合
以下のコマンドを実行。GitHub Desktopのバージョンが古い場合、上記のコマンドではなく、以下のコマンドでないと設定ができないことがあるため。

ターミナル
1
$ sudo cp /usr/local/bin/git-secrets /Applications/GitHub\ Desktop.app/Contents/Resources/git/bin/git-secrets

ここまでで、事前に行うセキュリティ対策の作業は終了。

S3で保存先を用意する

S3でファイルがアップロードされる領域を準備する。

バケットとは

S3で、実際にデータが格納される場所のことをバケットと呼ぶ。バケットの名前はアクセスするときのURLとして使用されるため、まだ誰も付けたことがない名前を使う必要がある。

 S3を利用してバケットを作成する

上のメニューバーに表示されている「サービス」をクリック、以下の「S3」をクリックする。

https://tech-master.s3.amazonaws.com/uploads/curriculums//436a3457610b5b64b6e31359cf0fa439.png

すると以下のページに遷移するので、左上の「バケットの作成」をクリック。

https://tech-master.s3.amazonaws.com/uploads/curriculums//11c3e5303fe5a3d9ed3f0ad7d3989824.png

バケットは、名前とリージョンを決めるだけで簡単に作成できる。

 リージョンとは

バケットが実際に存在しているサーバーの場所。以下の操作でバケットを作成する。

バケットの名前は任意で決めて大丈夫だが、他のユーザーと重複した名称は使えない。

なかなかユニークな名前を取得できない場合は、「付けたい名前 + 数値」例えば「ChatSpace2019」などを試してみるのがおすすめ。数値部分を変えることで重複を避けることがしやすくなる。

リージョンは 「アジアパシフィック(東京)」を選択する。入力できたら「次へ」をクリック。

https://tech-master.s3.amazonaws.com/uploads/curriculums//5d68b0cc8a920d7eca331ec8ec0b3557.png

次の画面では変更は必要ないので、そのまま「次へ」をクリック。

https://tech-master.s3.amazonaws.com/uploads/curriculums//c40f2b193125136c45c4902561107e21.png

続いてセキュリティの設定を行う。今回はバケットポリシーを使用してセキュリティ設定を行うので、下の2つにチェックを入れる。ここの設定が過っているとファイルのアップロードができなくなるので注意。正しく設定できたら「次へ」をクリック。

https://tech-master.s3.amazonaws.com/uploads/curriculums//76be8491536739d2e215cc0f51f46d52.png

 「システムのアクセス許可の管理」の設定

画面の一番下に、「システムのアクセス許可の管理」という設定項目が追加になっている。
デフォルトの「Amazon S3 ログ配信グループにこのバケットへの書き込みアクセス権限を付与しない」のままで進める。

 バケットポリシー

どのようなアクセスに対してS3への読み書きを許可するか決めることができる仕組み。今回は、作成したIAMユーザーからのアクセスのみを許可するよう設定していく。

ここは確認画面なので、問題なければそのまま次に進む。

https://tech-master.s3.amazonaws.com/uploads/curriculums//7a17089a7a1e407d62181bcf19611e8d.png

これからバケットポリシーの設定を行う。まずは先ほど作成したIAMユーザーの設定を確認。メニューの「サービス」をクリック。

https://tech-master.s3.amazonaws.com/uploads/curriculums//e76b5f6b38573e705c81a6df304d60f4.png

一覧から「IAM」を検索。
https://tech-master.s3.amazonaws.com/uploads/curriculums//7a63d5ebdaa5c8f50a59b1928fe9c919.png

「ユーザー」を選択。
https://tech-master.s3.amazonaws.com/uploads/curriculums//13be93b14e33405dccafb6c47b9c7428.png

「IAM」ユーザーの一覧から、先ほど作成したユーザーを選ぶ。

IAMユーザーの情報が表示されるので、必要な情報を取得する。後ほど 「ユーザーのARN」が必要になるので、一度エディタなどに保存しておく。

https://tech-master.s3.amazonaws.com/uploads/curriculums//226029511085e39efc5f24862f9c4fb0.png

次に、バケットポリシーの設定を行う。IAMの時と同じようにサービス一覧から S3を選ぶ。先ほど作成したバケットをクリックする。

https://tech-master.s3.amazonaws.com/uploads/curriculums//9fd8cd310f647e1d1ebdfc77e8aa41de.png

バケットポリシー」をクリックし、赤枠の欄にポリシーの入力をする。内容は下記を参照。

https://tech-master.s3.amazonaws.com/uploads/curriculums//61e3740751108bab8f0068b312a4352f.png

バケットポリシー
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
{
    "Version": "2012-10-17",
    "Id": "Policy1544152951996",
    "Statement": [
        {
            "Sid": "Stmt1544152948221",
            "Effect": "Allow",
            "Principal": {
                "AWS": "************①****************"
            },
            "Action": "s3:*",
            "Resource": "arn:aws:s3:::************②**********"
        }
    ]
}

上記の①に先ほどメモしておいた「ユーザーのARN」を、②に作成したバケット名」を記述する。

以下のように記述になっていることを確認。

バケットポリシー(例)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
{
    "Version": "2012-10-17",
    "Id": "Policy1544152951996",
    "Statement": [
        {
            "Sid": "Stmt1544152948221",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::123456789123:user/upload_user"
            },
            "Action": "s3:*",
            "Resource": "arn:aws:s3:::upload-app-test"
        }
    ]
}

これでS3のバケットの設定は完了。これによって、データを保存するための入れ物が用意できた状態になった。