IAM Roles AnyWhere で オンプレサーバ → KinesisFirehose → S3にデータ転送

オンプレサーバからAWSクレデンシャルを使わずにKinesisFirehose → S3にデータを転送したメモです。

- オンプレサーバ : CentOS7
- リージョン：us-east-1


## 1. [S3バケットを作成](https://s3.console.aws.amazon.com/s3/bucket/create)

バケット名を入力してリージョンを選択したら他はデフォルトのままバケットを作成します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1246630/50b422b1-3355-fced-90c4-3176e5f093b8.png)

## 2. [Kinesis Firehoseを作成](https://us-east-1.console.aws.amazon.com/firehose/home?region=us-east-1#/create)

- SourceはDirect-PUTを選択
- DestinationはAmazon S3を選択
- Delivery stream nameを設定
- S3 bucketは手順.1で作成したバケットを選択
- 他はデフォルトのまま「Create delivery stream」

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1246630/a21fc402-e639-b222-1af9-d3b2fd3e2b96.png)

## 3. [IAM Roleを作成](https://console.aws.amazon.com/iamv2/home?region=us-east-1#/roles/create)

- ユースケースはRoles Anywhereを選択して「次へ」

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1246630/7fcbd7cc-0943-64ed-7ad6-918b54198320.png)

- 許可ポリシーはAmazonKinesisFirehoseFullAccessとAmazonS3FullAccessを選択して「次へ」
※検証目的なのでFullAccessを使ってます。

- ここで選択した許可ポリシーがオンプレサーバ側で許可されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1246630/40c1505b-5e45-9787-a686-cc80a9e95928.png)

- ロール名を入力して「ロールを作成」

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1246630/421db8ad-9cf5-37b4-9b1a-fa6589d34a66.png)

## 4. オンプレサーバで証明書を作成

[こちらの手順](https://yomon.hatenablog.com/entry/2022/07/aws_iam_role_anyware_openssl)で作成させていただきます。

- Root CA
```
# mkdir -p /opt/pki/RootCA
# mkdir /opt/pki/configs
# cd /opt/pki/RootCA
# mkdir newcerts
# echo "01" > serial
# echo "00" > crlnumber
# touch index.txt

# cat <<'EOF' > /opt/pki/configs/openssl_sign.cnf
[ ca ]
default_ca      = CA_default

[ CA_default ]
dir             = ./
certs           = $dir/certs
crl_dir         = $dir/crl
database        = $dir/index.txt
new_certs_dir   = $dir/newcerts
serial          = $dir/serial
crlnumber       = $dir/crlnumber
crl             = $dir/crl.pem
RANDFILE        = $dir/.rand

name_opt        = ca_default
cert_opt        = ca_default

default_days    = 365
default_crl_days= 30
default_bits    = 2048
default_md      = sha256
preserve        = no
policy          = policy_match

[ policy_match ]
countryName             = match
stateOrProvinceName     = match
organizationName        = match
organizationalUnitName  = optional
commonName              = supplied
emailAddress            = optional

[ v3_ca ]
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer
basicConstraints=CA:true
keyUsage = cRLSign,keyCertSign

[ v3_client ]
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = clientAuth
crlDistributionPoints = URI:http://127.0.0.1:8200/v1/pki/crl
EOF

# openssl genrsa -out RootCA_key.pem -aes256 -passout pass:rootcaprivkeypass 2048

# openssl req -new \
  -subj "/C=JP/ST=Tokyo/O=EXAMPLE/CN=EXAMPLE Root CA" \
  -out RootCA_csr.pem \
  -key RootCA_key.pem \
  -passin pass:rootcaprivkeypass

# openssl ca -config ../configs/openssl_sign.cnf  -batch -extensions v3_ca \
 -out RootCA_crt.pem \
 -in RootCA_csr.pem \
 -selfsign \
 -keyfile RootCA_key.pem \
 -passin pass:rootcaprivkeypass

# openssl x509 -in RootCA_crt.pem -out RootCA_crt.pem

# cat RootCA_crt.pem
-----BEGIN CERTIFICATE-----
xxx
(信頼アンカーで使用するのでメモしておく)
xxx
-----END CERTIFICATE-----
```

- クライアント証明書
```
# cd /opt/pki/RootCA
# openssl genrsa -out my-key.pem 2048
# openssl req -new \
  -subj "/C=JP/ST=Tokyo/O=EXAMPLE/CN=EXAMPLE Client" \
  -out my-csr.pem  \
  -key my-key.pem
# openssl ca -config ../configs/openssl_sign.cnf  \
  -batch -extensions v3_client \
  -out my-crt.pem \
  -in my-csr.pem \
  -cert RootCA_crt.pem \
  -keyfile RootCA_key.pem \
  -passin pass:rootcaprivkeypass
# openssl x509 -in my-crt.pem -out my-crt.pem
```

## 5. [信頼アンカーを作成](https://console.aws.amazon.com/rolesanywhere/home/trust-anchors/create?region=us-east-1)

- 信頼アンカー名を入力
- 外部証明書バンドルを選択
- 外部証明書バンドルに手順.4で作成したRoot CAの内容を貼り付け
- 信頼アンカーを作成する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1246630/77b09179-629b-c14a-547a-2b9c71f74b14.png)

## 6. [プロファイルを作成](https://us-east-1.console.aws.amazon.com/rolesanywhere/home/profiles/create)

- プロファイル名を入力
- 手順.3で作成したRoleを選択
- プロファイルを作成

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1246630/524b456f-9da2-210b-ac2e-4f7305d2e047.png)

## 7. オンプレサーバ(CentOS7)にAWS CLIをインストール
```
# curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
# unzip awscliv2.zip
# ./aws/install
# aws --version
aws-cli/2.7.13 Python/3.9.11 Linux/3.10.0-1160.71.1.el7.x86_64 exe/x86_64.centos.7 prompt/off
```

## 8. オンプレサーバ(CentOS7)にaws_signing_helperをインストール
```
# mkdir -p /opt/aws
# curl --output /opt/aws/aws_signing_helper https://s3.amazonaws.com/roles-anywhere-credential-helper/CredentialHelper/latest/linux_amd64/aws_signing_helper
# chmod +x /opt/aws/aws_signing_helper
```

## 9. 一時クレデンシャルの取得

```
# ANCHOR_ARN={信頼アンカーARN}
# PROFILE_ARN={プロフィルARN}
# ROLE_ARN={ロールARN}
# /opt/aws/aws_signing_helper credential-process \
  -certificate /opt/pki/RootCA/my-crt.pem \
  -private-key /opt/pki/RootCA/my-key.pem \
  -trust-anchor-arn ${ANCHOR_ARN} \
  -profile-arn ${PROFILE_ARN} \
  -role-arn ${ROLE_ARN} 
{"Version":1,"AccessKeyId":"XXXXXXXXXX","SecretAccessKey":"XXXXX","Expiration":"2022-07-10T06:18:31Z"}
```

信頼アンカーARN、プロファイルARN、ロールARNは以下で確認できるのでARNをコピーして使用

- 信頼アンカーARN
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1246630/bc0c58a4-356f-87ca-93ab-cfa8b4e9b958.png)

- プロファイルARN
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1246630/e020c84d-5c06-7ba6-809d-fc8468524773.png)

- ロールARN
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1246630/0312d43a-8793-bc87-3839-4b75ed6561b4.png)

## 10. AWS CLIの設定

```
# mkdir ~/.aws
cat <<EOF > ~/.aws/config
[profile anywhere]
    credential_process = /opt/aws/aws_signing_helper credential-process -certificate /opt/pki/RootCA/my-crt.pem -private-key /opt/pki/RootCA/my-key.pem -trust-anchor-arn ${ANCHOR_ARN} -profile-arn ${PROFILE_ARN} -role-arn ${ROLE_ARN} 
EOF
```

## 11. Kinesis Firehoseにデータ送信

```
# echo "anywhere-test-data" | base64
YW55d2hlcmUtdGVzdC1kYXRhCg==

# aws firehose put-record --delivery-stream-name anywhere-firehose --record '{"Data":"YW55d2hlcmUtdGVzdC1kYXRhCg=="}' --profile anywhere
```

## 12. S3にデータ転送されたか確認

FirehoseからS3にデータが転送されるまで5分程度待ってから確認します。

- ファイル確認
```
# aws s3 ls s3://anywhere-bucket --recursive --profile anywhere
2022-07-10 14:41:27         19 2022/07/10/05/anywhere-firehose-1-2022-07-10-05-36-25-15eecd9b-162b-4b0e-93b7-1f1bef4466cf
```

- ファイルの中身を確認
```
# aws s3 cp s3://anywhere-bucket/2022/07/10/05/anywhere-firehose-1-2022-07-10-05-36-25-15eecd9b-162b-4b0e-93b7-1f1bef4466cf - --profile anywhere
anywhere-test-data ← 手順.11で送信したデータがS3に転送されています。
```

オンプレサーバからクレデンシャルを設定せずにAWS CLIでFirehoseにデータを送信することが確認できました。

次回はaws-kinesis-agentでのデータ送信を試みてみたいと思います。(すでにaws-kinesis-agentのIAM Roles Anywhere対応は試みたのですが設定が悪いせいなのかクレデンシャルなしでの送信はまだ出来ていいません。。)