AWSの仮想MFAデバイスの再登録の方法(シークレット設定キーを使う)

AWSの仮想MFAデバイスとしてスマホを利用している場合、機種変更する時などにはMFAの再登録をしなければなりません。 例えば、破損や紛失ではなく前のスマホが正常に使える場合は、 旧MFAでログイン … 続きを読む

カテゴリー 未分類 | タグ

AWSコンソールのログイン用アカウントをIAMのベストプラクティスに従って作成してみた(設定編 …

はじめに. AWSチームのすずきです。 1つのAWSアカウントを複数の関係者で利用する環境で、AWSコンソールのログイン用アカウント(IAMユーザ)をAWSが公開しているベストプラクティスに従って作成する機会がありました。 多要素認証(MFA)や接続元IPアドレス制限などによる不正なログインの抑止と、 管理者権限が行使 … 続きを読む

カテゴリー 未分類 | タグ

AWS WorkspacesでGoogle Authenticationを使う – Qiita

AWS WorkspacesでGoogle Authenticationを使う – Qiita. 概要 AWS WorkspaceでMFAを実現する方法です。 本稿では、パスワード、クライアント証明書、Google Auth… 続きを表示 概要 AWS WorkspaceでMFAを実現する方法です。 本稿では、パスワード、クライアント証明書、Google Authentication (OTP) の3要素で … 続きを読む

~/.aws/(config|credentials) の設定から assume roleするラッパーをgolangで実装して、goreleaserでリリースしてみた

最近のgolangのCI周りを勉強する目的で、fujiwaraさんのaswrap – ~/.aws/(config|credentials) で定義した AssumeRole 定義から一時キーを取得してコマンドを起動してくれる wrapperをgolangで再実装してみた。

-> https://github.com/masahide/assumer

まだMFA対応のtodoが残ってたり本家より劣化しているところはありますが、一時キーのキャッシュ保存に対応させたり、rpm,deb,brewのパッケージを作成したので導入が簡単なところぐらいが少ない取り柄

今回やりたかったこと/やったこと

  • goreleaserを使ってrpm,deb,homebrewのパッケージのリリースを自動化
  • codecov.ioでカバレッジの可視化
  • gometalinterで行単位でのignore設定

goreleaser

golang製のソフトウェアのリリース処理を全部引き受けてくれてる便利なツールです。具体的には・・

  • goのクロスコンパイル
  • バイナリのtar.gzアーカイブやrpm,debパッケージ、dockerイメージの作成
  • github.comのGithub Releasesへの添付
  • dockerhubへの登録
  • homebrewのFormula作成
    などかなり幅広く対応しています。

使い方に関しては、 goreleaserを使ってGoで書いたツールのバイナリをGithub Releasesで配布する
を参考にしつつ、goreleaser自身の.travis.yml.goreleaser.ymlがとても参考になるのでこの辺りを真似ながらで基本的に問題ないかと。

codecov.ioでカバレッジの可視化

以前、 golangの静的解析,カバレッジ解析,バイナリリリースをCircleCIで簡単に整えるで使ったcoverallsより導入が簡単だった。
事前にcodecov.ioでトークンを取得して、travisのenvにCODECOV_TOKENとして設定しておいて、あとは、基本的にはこちらもgoreleaserの.travis.ymlを参考にしましたが

.travis.yml
after_success:
  - bash <(curl -s https://codecov.io/bash)

これだけで良いみたいですね。

gometalinterで行単位でのignore設定

gometalinterで様々な静的解析が走るけどその解析ツール毎にignoreを設定するのは大変だなぁと思ってたんですが・・・

https://github.com/masahide/assumer/blob/master/cmd/assumer/main.go#L170

defer cf.Close() // nolint errcheck

のように行単位で// nolint <解析ツール名> でチェックを除外できるようです。
comment-directives に記載されてます。

続きを読む

Cognitoユーザープールからの送信メールをカスタマイズする

サービスの認証にCognitoユーザープールを使用する際、確認コードや、初回ログインパスワードなどをメールでお知らせする場合があると思います。

Cognitoのデフォルト設定だとこんなメールが届きます。

Your confirmation code is 927173
Your username is xxxx and temporary password is xxxxxx.

このメールタイトル、本文をカスタマイズする方法です。

カスタムメッセージが設定できるイベント

公式ドキュメントからの抜粋です。
以下がカスタムメッセージが設定できるイベントの一覧です。

AWS Lambda トリガーのリクエストおよびレスポンスパラメータ

triggerSource 値 トリガーイベント
CustomMessage_AdminCreateUser カスタムメッセージ – 新規ユーザーに一時パスワードを送信するため.
CustomMessage_ResendCode カスタムメッセージ – 既存ユーザーに確認コードを再送するため.
CustomMessage_ForgotPassword カスタムメッセージ – 忘れたパスワードのリクエスト用の確認コードを送信するため.
CustomMessage_UpdateUserAttribute カスタムメッセージ – ユーザーの E メールまたは電話番号が変更されると、このトリガーは確認コードをそのユーザーに自動的に送信します。他の属性には使用できません。
CustomMessage_VerifyUserAttribute カスタムメッセージ – ユーザーが手動で新しい E メールや電話番号の認証コードをリクエストすると、このトリガーからユーザーに認証コードが送信されます。
CustomMessage_Authentication カスタムメッセージ – 認証時に MFA コードを送信するため.

今回はtriggerSource値がCustomMessage_AdminCreateUserの場合(Cognitoユーザープールのポリシーに「管理者のみにユーザーの作成を許可する」を設定していて、管理者がユーザーを作成した際にユーザーに送信されるメール)のカスタマイズを例にします。

手順

  1. Lambdaファンクションの作成
  2. Cognitoユーザープールに1.で作成したファンクションを登録

1. Lambdaファンクションの作成

Python3.6での例です。
ファンクションのIAMロールにはCloudwatchログ出力権限の付与だけでOKです。以下IAMポリシーの例です。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "logs:CreateLogGroup",
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ],
            "Resource": [
                "*"
            ],
            "Effect": "Allow"
        }
    ]
}

Lambdaファンクションで受け取るイベントをログ出力するとこのような感じ。

{
    "version": "1",
    "region": "ap-northeast-1",
    "userPoolId": "ap-northeast-1_xxxxxxxxx",
    "userName": "hogee",
    "callerContext": {
        "awsSdkVersion": "aws-sdk-js-2.176.0",
        "clientId": "CLIENT_ID_NOT_APPLICABLE"
    },
    "triggerSource": "CustomMessage_AdminCreateUser",
    "request": {
        "userAttributes": {
            "sub": "bf6e9c66-0a69-476e-bfd8-724d38e6555f",
            "cognito:email_alias": "hoge@example.com",
            "email_verified": "True",
            "cognito:user_status": "FORCE_CHANGE_PASSWORD",
            "name": "hoge",
            "email": "hoge@example.com"
        },
        "codeParameter": "{####}",
        "usernameParameter": "{username}"
    },
    "response": {
        "smsMessage": "None",
        "emailMessage": "None", # ここをカスタムした本文に変える
        "emailSubject": "None" # ここをカスタムしたタイトルに変える
    }
}

このイベントをそのままreturn eventとするとデフォルト設定が適用されたメールが送られます。カスタマイズするにはresponseのフィールド内をカスタマイズしたい内容に書き換えてリターンします。

cognito_custom_message.py
# -*- coding:utf-8 -*-

def handler(event, context):
    if event['triggerSource'] == 'CustomMessage_AdminCreateUser':
        customed_event = custom_message_admin_create_user(event)

    return customed_event


def custom_message_admin_create_user(event):

    email_message = '''
{username} 様
<br>
<br>
管理者から招待されました。
<br>
<br>
ログインメールアドレス:{mail}
<br>
初回ログインパスワード:{password}
'''.format(username='{username}',
           mail=event['request']['userAttributes']['email'],
           password='{####}')

    event['response']['emailSubject'] = '仮パスワード発行のお知らせ'
    event['response']['emailMessage'] = email_message

    return event

{username}にユーザーネーム、{####}にパスワードが入ってメールが送信されることになります。
triggerSourceによって本文に含めなくてはいけないコードパラメータは異るため先ほどの公式ドキュメントで確認してください。
triggerSourceがCustomMessage_AdminCreateUserの場合、メッセージ本文に{username}{####}が入っていないとエラーになります。

もし追加で他のカスタムメッセージイベントにも対応したい場合、handler()

    elif event['triggerSource'] == 'CustomMessage_ForgotPassword':
        customed_event = custom_message_forgot_password(event)

とやると対応できます。

2. Cognitoユーザープールに1.で作成したファンクションを登録

Lambdaファンクション作成後はCognitoユーザープールのコンソールにいき、トリガーカスタムメッセージから作成したLambdaファンクションを指定します。

スクリーンショット 2018-02-03 20.03.27.png

serverless frameworkではこのようになります。

serverless.yml
<略>
functions:
  cognitoCustomMessage:
    handler: functions/cognito_custom_message.handler
    role: CognitoCustomMessageRole
    events:
      - cognitoUserPool:
          pool: UserPool
          trigger: CustomMessage
resources:
  Resources:
    CognitoUserPoolUserPool:
      <以下略>

設定後、アプリケーションからユーザーを登録してみると、

スクリーンショット_2018-02-03_20_27_35.png

カスタマイズされたメールが届きました。

以上です。

続きを読む

AWS IAM勉強まとめ

・Identity and Access Management
AWS操作をセキュアに行うための認証・認可・アクセスポリシーの仕組み

「IAM ユーザー」単位に発行できるアクセスキーは最大2個
3個目を発行しようとすると “Cannot exceed quota for AccessKeysPerUser: 2” とエラーになる

・ユーザ
5000ユーザまで作成可能

・グループ
100グループまで作成可能

・MFA(Multi-Factor Authentication)
多要素認証

・ルートアカウントは極力利用しない

Credential Report
認証情報のレポート

・パスワードローテーション
パスワードの有効期限設定可能

管理ポリシー
独立したポリシー。AWS管理ポリシーカスタマー管理ポリシーが存在
→再利用可能。変更管理の一元化。複数のIAMエンティティにアタッチあk脳

インラインポリシー
従来のIAMポリシー。1つのポリシーを共有できない

・デフォルトdeny

・ポリシーはユーザーベースとリソースベースで設定可能
特定のIPからのみ接続可能のような設定も可能

・CloudTrailでユーザのアクティビティのログ収集。S3上に保管

・最小限の特権。Service Ladr Accessed Data
未使用または最近使われてないユーザとサービスを特定。グループに分ける

・IAMロール
サービスやアプリケーションなどのエンティティに操作権限を付与
ユーザやグループに紐付かない
認証情報は自動的にローテーション
認証情報はSTSで作成
→EC2に認証情報がないため、安全
SDK, CLIに対応

・AWSアカウント: ドアキー
IAMユーザ: 従業員カード
Temporary Security Credential, IAM Role: ホテルキー

・クロスアカウントアクセス

・ID連携
LDAP認証したユーザにはS3権限を与えるなど。
ユーザにはTemporaryキーを与える
SAML2.0(Security Assertion Markup Language)と互換性

・SAML認証
ユーザ→Idpに認証情報リクエスト→認証情報受け取り→AWS STS(Security Token Service)に問い合わせ→一時的な認証情報受け取り→AWSサービスにアクセス

・SSOエンドポイントを利用
サインインURLをクライアントに返答
→クライアントはリダイレクトでコンソールにアクセス
コンソールが使用できる時間や時間帯を制御可能

・既存のIdpを利用
IdpとSTSで通信。ユーザはコンソールへリダイレクトできる

・ルートアカウントは使用しない
・個々のIAMユーザ作成
・ユーザへのアクセスはグループ
・最小限の特権
・強度の高いパスワードポリシー
・特権ユーザにはMFA
・認証情報を共有せず、ロールを使用
・監視も大事に

参考URL:
https://www.slideshare.net/AmazonWebServicesJapan/aws-black-belt-online-seminar-aws-identity-and-access-management-aws-iam

続きを読む

[AWS,EC2]初期設定(インスタンス作成,SSH接続,料金のモニタリング)

AWSのアカウントを作成

https://qiita.com/Hikery/items/b919ae9e35f0f66e6a95

インスタンス作成

Step1 サービス > EC2 を選択

ec2.jpg

Step2 localの変更

time.jpg

Step3 マシーンイメージの選択

insutance.jpg

Step4 インスタンスタイプの選択

i_type.jpg

Step5 セキュリティグループの設定

・インスタンス設定
・ストレージ追加
はそのままで
・タグの追加 は適当にtagをつける。

セキュリティグループの設定 は HTTP を追加する。
security.jpg

Step6 キーペアを選択する

key2.jpg

鍵をDownloadして、インスタンスの作成をする。

SSH で繋いでみる

Step1 –

接続をおす
i_ssh_1.jpg

スタンドアロン SSH クライアント
i_ssh_1.jpg

Step2 – .pem fileを .ssh配下に配置する

terminal
$ mv /Users/[user name]/Downloads/***.pem /Users/[user name]/.ssh
$ chmod 600 football_chant.pem
$ ssh -i "***.pem" ec2-user@ec2-**-***-**-***.ap-northeast-1.compute.amazonaws.com
The authenticity of host 'ec2-**-***-**-***.ap-northeast-1.compute.amazonaws.com (**.***.**.***)' can't be established.
ECDSA key fingerprint is SHA***:*******************************************.
Are you sure you want to continue connecting (yes/no)?

yesを選択する。

terminal
Warning: Permanently added 'ec2-**-***-**-****.ap-northeast-1.compute.amazonaws.com,**.***.**.***' (ECDSA) to the list of known hosts.

       __|  __|_  )
       _|  (     /   Amazon Linux AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-ami/2017.09-release-notes/

環境によっては

terminal
$ sudo yum update

料金をモニターする

画面で料金を確認

右上のアカンウトクリック > 請求ダッシュボード
https://console.aws.amazon.com/billing/home#/
こんな感じで見れます。
price2.jpg

使用した料金をメールで受け取る。

https://console.aws.amazon.com/billing/home#/preference
とりあえず、全部受け取るようにする。
setting.jpg

請求アラートを管理する

“請求アラートを管理する”にLinkする。

アラート.jpg

アラームを作成

make.jpg

メトリック設定

メトリック : 請求
チェック : USD
時間 : 6時間
setting2.jpg

アラームの定義

0$を超えた時、0$に戻った時を指定します。
setting6.jpg

また心配であれば5ドルや10ドルを超えた時点でもアラートを出すと良いかと思います。

参考

AWSアカウントの保護

アカウントのセキュリティ保護のために下記の記事を参考に、
MFAデバイス認証をいれました。

https://qiita.com/tmknom/items/303db2d1d928db720888

料金

初心者なので、これは気をつけようと思いました。参考になります。
https://qiita.com/mochizukikotaro/items/a0e98ff0063a77e7b694

RDSでMySQLを起動させ、EC2のインスタンスにつなぐ

下記を参考にした。
https://qiita.com/na0AaooQ/items/7c69a88c80f1efb4cad3
https://qiita.com/hiroshik1985/items/6643b7323183f82297b2

続きを読む