2018年7月25日水曜日

AWS Data Pipeline をジョブスケジューラとして使える(S3のシェルを実行)


AWS Data Pipeline でS3に置いたシェルを実行できるらしい。

ジョブの依存関係も設定可能。

スケジュール起動も可能。

ジョブの異常は、SNSでメール通知。

ジョブのログはS3に格納できる。

[AWS Data Pipeline]S3上の任意のシェルを実行しジョブを連携させる

2018年7月18日水曜日

aws-cli でリトライさせる設定


~/.aws/models/_retry.json を用意すると aws-cli でエラーの再試行ができるらしい。

boto3でリトライの設定を変更する



2018年7月14日土曜日

シェルで urlencode したいとき


最近は、どのOSにも python が入っているので、python を使用します。

function urlencode
{
    echo "$1" \
        | python -c 'import sys,urllib; sys.stdout.write(urllib.quote_plus(raw_input()))'
}

urlencode "xxxxx"

AWSコンソールの貸し出しURL作成


フェデレーションユーザーに対して AWS マネジメントコンソール へのアクセスを許可する URL の作成(カスタムフェデレーションブローカー)」を参考にして、貸し出し用のAWSコンソールURLを作ってみます。

貸し出し用のURLでは、以下ができるようにします。
・認証不要。ただし、1時間(変更可能)しか使用できない。
・特定のロール(ReadOnlyなど)を割り当て、操作を制限する。

なお、URL作成時には、aws-cli を使用し、MFA必須とします。


1. URL作成用のIAMユーザを作成


「貸し出し用URL」を作成するIAMユーザを用意します。
今回作成するIAMユーザの名称は、"ops" とします。

[アクセス権限]タブで、[インラインポリシーの追加]をクリックし、インラインポリシーを作成します。
貸し出しURL作成に必要な権限だけ付与しています。


[認証情報]タブで、[MFAデバイスの割り当て]を実施します。
また、[アクセスキーの作成]ボタンでアクセスキーを作成します。


アクセスキーは、「貸し出しURL」を作成するマシンに設定します。
今回は、以下のようにしています。
[root@centos701 ~]# cat ~/.aws/credentials
[default]
aws_access_key_id = <アクセスキー>
aws_secret_access_key = <シークレットアクセスキー>

[ops]
aws_access_key_id = <上記で作成したアクセスキー>
aws_secret_access_key = <上記で作成したシークレットアクセスキー>

[root@centos701 ~]# cat ~/.aws/config
[default]
output = text
region = us-east-1

[profile ops]
output = text
region = us-east-1


2.AWSコンソールに割り当てるロールを作成


今回は、EC2の参照権限しかないロールを作成します。
今回作成するロールの名称は、"EC2ReadOnly" とします。
[アクセス権限]タブで AmazonEC2ReadOnlyAccess ポリシーを割り当てます。


[信頼関係]タブで、[信頼されたエンティティ]に上記1で作成した opsユーザを指定し、MFA必須にします。
[信頼関係の編集]ボタンをクリックして、以下のように設定します。
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::12345678:user/ops"
      },
      "Action": "sts:AssumeRole",
      "Condition": {
        "Null": {
          "aws:MultiFactorAuthAge": "false"
        }
      }
    }
  ]
}


ちなみに、[最大 CLI/API セッション期間]に表示されてる時間が、AWSコンソールを操作できる最大時間になります。この時間を過ぎると自動的にログアウトします。


3.URL作成用のスクリプトを作成


今回作成したスクリプトは以下のとおり。
ファイル名は awsurl.sh とします。

#!/bin/bash

PROF=ops
SERIAL_NUMBER=arn:aws:iam::12345678:mfa/${PROF}
AWS_FED_URL=https://signin.aws.amazon.com/federation
AWS_CONSOLE_URL=https://console.aws.amazon.com/
DURATION=3600 #sec

function urlencode
{
    echo "$1" \
        | python -c 'import sys,urllib; sys.stdout.write(urllib.quote_plus(raw_input()))'
}

if [ $# -ne 2 ]; then
    echo "usage: $(basename $0) <role name> <code>"
    exit 1
fi

role=$1
code=$2

arn=$(aws iam list-roles \
    --query "Roles[?RoleName == '${role}'].Arn" \
    --profile ${PROF} \
    --output text)

if [ "${arn}" == "" ]; then
    echo "${role} is not found."
    exit 1
fi

key=$(aws sts assume-role \
    --role-arn "${arn}" \
    --role-session-name OneTimeSession \
    --query "Credentials.[AccessKeyId,SecretAccessKey,SessionToken]" \
    --profile ${PROF} \
    --serial-number ${SERIAL_NUMBER} \
    --token-code ${code} \
    --output text)

access_key=$(echo "${key}" | awk -F"\t" '{printf("%s",$1)}')
secret_access_key=$(echo "${key}" | awk -F"\t" '{printf("%s",$2)}')
session_token=$(echo "${key}" | awk -F"\t" '{printf("%s",$3)}')

if [ "${access_key}" == "" ]; then
    echo "assume-role failed."
    exit 1
fi

json="{\"sessionId\":\"${access_key}\",\"sessionKey\":\"${secret_access_key}\",\"sessionToken\":\"${session_token}\"}"

token=$(curl -s "${AWS_FED_URL}?Action=getSigninToken&SessionDuration=${DURATION}&Session=$(urlencode ${json})" \
    | jq -r .SigninToken)

if [ "${token}" == "" ]; then
    echo "get signin token failed."
    exit 1
fi

url="${AWS_FED_URL}?Action=login&Issuer=&Destination=$(urlencode ${AWS_CONSOLE_URL})&SigninToken=$(urlencode ${token})"

echo ${url}

exit 0

4.動作確認


EC2の参照しかできないAWSコンソールのURLを作ってみます。
上記3で作成したスクリプトの引数に、「ロール名」、「opsユーザ用MFAのパスコード」を指定して実行すると、URLが表示されます。
[root@centos701 awscli]# ./awsurl.sh EC2ReadOnly 160335
https://signin.aws.amazon.com/federation?Action=login&Issuer=&Destination=https%3A%2F%2Fconsole.aws.amazon.com%2F&SigninToken=RHe2_m5aLBqK0Ci7_XXmp05OSMj0wGiFp1el48SI-qqR8WZV3qqTvYvBZQw7UrEHUUa5BOaH9IderXxzwtkicg9LGEJO0239ih8psYfidXoC_QHTeW_7DKBTIHGoU1NlU-xYXhcmDbidSE8LKZS4ZqjI0uxbzLuTnCU6iVHUdPAt4iqsLXpKa4oPTfUAexY52MnBZhZElNxXK4DVOyNEkCYWTUNisR9ufxAyf3GoC1f-7UbE4Dt_vdYkKOlED4k7FAaoUMo5OazE0mr-IJiYS7rnwYVUMcVnd7y-01CarUU4OdFt8rIiPfs6UprHBbpCOCqJdFf4jXFUy4olKdLtnorh6waDfO8wSmyQlPHu2P0QJDTzsvPekux06dDPzyRgEk3Uw9bHOxX6DpRO4Sqgev9t09t7VH5fkNshUZbF8SB2m4J7vNcWG7v0YDGGmdNd2QWKI47yZ1luN_C9MQS84IePpGfGicK9Uoda-mjXWvBAVBxA-4uA3qSzUsb0bLpXNAEx_lo14XY2p-I9RgLM_i3DDvx2WP6_kg9L0JZrTVU4zmTF19bORYPde6w854gTlpUXWKVWVMwqg7Tid-T2l7AYapkduA7KYLcBd2m0-wIqBVcc6liZYUEv7bs6gmobwH3vaLlCgTHF7x98JXlF5B0AT845_FP-Ng-BJwiKmpcyIg50_8f4W-V3vl7zRq0n9VKED53jJBYmABRuDc_QRoLUrW7Qa3qBQzMJ6Gq7-A0_CkhL3vBM8ax0I_WHcxkICCIUegh9hoIbsg41O9RJZkwsXCM3BsmTasKta_vosHdPYWzNw5_Dy2otHEUzM88s

このURLをブラウザにペーストして、AWSコンソールを開きます。
認証なしで下図にように画面が表示されます。
表示されるログイン名は、[EC2ReadOnly/OneTimeSession] です。
ロール名と、スクリプトの assume-role(awscli) で指定したセッション名が表示されています。


EC2は、下図のように参照できます。


S3を参照しようとすると、権限がないので、エラーになります。






2018年7月7日土曜日

sshd_config の AuthorizedKeysCommand を設定して IAMユーザのSSH公開キーでログインする


下記の記事を見て、ssh の AuthorizedKeysCommand を知りました。
AuthorizedKeysCommand にコマンドを指定すると、コマンドの実行結果として公開鍵を渡すことができるらしい。
OpenSSH 6.2を使って公開鍵認証もLDAPで行いたい。

そこで、AWSのIAMユーザにSSH公開鍵を登録して、その鍵で、SSHログインできるか試してみました。

1.IAMユーザにssh公開鍵を登録


まず、キーペアを作成します
[root@centos701 ~]# ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:yU9NjtIMq8a9LJhNboxtZ2gxcEcLQTFNROj3ETvlMBU root@centos701
The key's randomart image is:
+---[RSA 2048]----+
|     .=O+  .E.   |
|      o.o + .    |
|     . o.. B.    |
|    . o.+*+=.    |
|     o oS.=oo    |
|     .+o +.      |
|     X++. .      |
|    +.@.o.       |
|     + +o        |
+----[SHA256]-----+

~/.ssh に公開鍵(id_rsa.pub)と秘密鍵(id_rsa)ができます。
[root@centos701 ~]# ls ~/.ssh/id*
/root/.ssh/id_rsa  /root/.ssh/id_rsa.pub

AWSコンソールでIAMユーザに上記で作成した公開鍵を登録します。
今回使用するIAMユーザは user01 です。
IAMユーザの[認証情報]タブで、[SSH公開キーのアップロード]ボタンをクリックします。
下図のように、作成した公開鍵をコピー&ペーストして、[SSH公開キーのアップロード]ボタンをクリックします。


下図のようにSSH公開鍵が登録されます。


2.SSH公開鍵取得スクリプトの用意


IAMユーザのSSH公開鍵を取得するスクリプトを用意します。
AuthorizedKeysCommand に設定して、sshd から実行されると、引数にユーザが渡されます。
スクリプト名は、/usr/local/sbin/aws_ssh_key.sh とし、内容は以下のようにしました。
テスト環境が、VirtualBoxなのでアクセスキーを設定していますが、
EC2インスタンスにロールを設定すれば、アクセスキーの設定は不要です。

[root@centos701 ~]# cat /usr/local/sbin/aws_ssh_key.sh
#!/bin/bash

export AWS_ACCESS_KEY_ID=<アクセスキー>
export AWS_SECRET_ACCESS_KEY=<シークレットアクセスキー>
export AWS_DEFAULT_REGION=ap-northeast-1

LOG=/tmp/debug.log
exec > >(tee ${LOG}) 2>&1

user=$1

id=`aws iam list-ssh-public-keys \
    --user-name "${user}" \
    --query "SSHPublicKeys[?Status=='Active'].[SSHPublicKeyId]" \
    --output text`

aws iam get-ssh-public-key \
    --user-name ${user} \
    --ssh-public-key-id "${id}" \
    --encoding SSH \
    --query "SSHPublicKey.SSHPublicKeyBody" \
    --output text


実行権限をつけます。
[root@centos701 ~]# chmod +x /usr/local/sbin/aws_ssh_key.sh

試しに動かしてみます。
以下のように、引数に user01 を指定して、上記1で登録した公開鍵が表示されたらOKです。
[root@centos701 ~]# /usr/local/sbin/aws_ssh_key.sh user01
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDFcuCzHvzR3epwYjydZ+ge0mpXLfjV69fG9JbS2xAdfh5LGKOXnUKyFPFzZHIS31yg0wQBgzISaR4r3uPJ6WePh2Kx3LgX/cJoUCeKfVWPngoxyvu7f4wOlgehP8RCQ4Fs3OoCIlaT56zJYLR+r6hirdGoAdi3gq5Tp42628V5aMSyWCFn2k3LGZJOsUfEfjHWWeOQsujKjv/XlXoBFIf5p4kwClzV31KOtMex5CeuM0QPmJM2syjONmJ1WqARVRZgLuuXMkdD0cYlBSQd2gMf4ujf/CIuXirYNuyG3BY4tJFbFRHCKsXqzc1FvvVaU2+fJBwxsq/jtBGEXdFeCcp9

3. sshd_config の設定


/etc/sshd/sshd_config を下記のように修正します。
CentOS7の場合は、コメントアウトされていたので、# を削除して設定します。
AuthorizedKeysCommand /usr/local/sbin/aws_ssh_key.sh
AuthorizedKeysCommandUser nobody

sshd を reload します。
[root@centos701 ~]# systemctl reload sshd


4. ssgログインの動作確認 


サーバには、IAMユーザと同じ名称でユーザを用意します。
user01の公開鍵は、サーバには設定していません。
[root@centos701 home]# id user01
uid=1000(user01) gid=1000(user01) groups=1000(user01)
[root@centos701 home]# ls -al /home/user01
合計 20
drwx------  2 user01 user01  92  2月 25 00:18 .
drwxr-xr-x. 5 root   root    47  2月 25 00:20 ..
-rw-------  1 user01 user01  15  2月 25 00:18 .bash_history
-rw-r--r--  1 user01 user01  18  9月  7  2017 .bash_logout
-rw-r--r--  1 user01 user01 193  9月  7  2017 .bash_profile
-rw-r--r--  1 user01 user01 231  9月  7  2017 .bashrc
-rw-r--r--  1 user01 user01 334  9月 20  2017 .emacs

上記1で作成した、秘密鍵でログインします。
[root@centos701 ~]# ssh -i .ssh/id_rsa -l user01 localhost
Last login: Sat Jul  7 20:27:09 2018 from localhost

AWSに公開鍵を取りに行くので、ログインに、少し、時間がかかります。

下記の記事と、組み合わせると、いいかもしれない。
AuthorizedKeysCommandを使うと、記事の authorized_keysの作成は不要になります。
IAMで踏み台ホストのユーザーとSSH公開鍵を一元管理する