7
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【AWS】【GCP】AWSとGCP間のキーなし認証を試みる(1) GCP→AWS

Last updated at Posted at 2022-08-22

1. はじめに

AWSとGCP、マルチクラウド間の接続に悩まされたことはありませんか?

もしこのような業務要件を聞かれたときに、最初はAWS側のIAM Userでアクセスキーを発行して、それをGCP側に渡して、GCP側がこのアクセスキーのを使ってAWSのサービスを接続するということを思い浮かびませんか?

もちろんこのやり方ではできるですが、アクセスキーの漏洩リスクがあり、それでセキュリティの低下や、運用上の煩雑に繋がりそうなので、極力アクセスキーを発行しないかわりに、ロールを使うことはクラウドのベストプラクティスになります。

そこで、なんとGCPとAWS間は非常によいお友達であることを発見し、AWSのIAMロールでGCPとキーなし認証できます!

2. 早速ネタバレ

AWS側IAMのウェブアイデンティティで、GCP側のサービスアカウントを指定することできます。それで、GCP→AWSでは、AWSのIAM Roleを使って、STSでGCPへ接続することができます。
image.png

3. 構成図

では早速下記の構成図のように、GCP→AWS間で、IAM Role経由でSTS接続を行います!

  • IAM側にIAM Roleを発行作成し、GCP側のService Accountと連携します。
  • GCP側のService Accountを、Compute Engineと連携します。
  • Compute Engineから、AWS Cliコマンドを使って、AWS側のS3を作成します。
    3 (1).png

4.GCP側構築

上記構成図を元に構築していきます。

  1. Service Account作成
    サービスアカウントを作成をクリックします。
    image.png

  2. サービスアカウント名サービスアカウントIDを入力の上、完了を押下します。
    gcp_01.png

  3. Compute Engineを作成し、作成時に上記作成したサービスアカウントを選択します。
    image.png

  4. Compute Engine作成後に、下記のミドルウェア等をCompute Engine内にインストールしておきます。

$ sudo yum install -y python3-pip
$ sudo yum install unzip -y
$ curl -L -o gcp-to-aws.zip https://github.com/cevoaustralia/gcp-sa-to-aws-iam-role/archive/master.zip
$ unzip gcp-to-aws.zip
$ cd gcp-sa-to-aws-iam-role-master/gcp
$ sudo pip3 install -r requirements.txt

上記インストール完了後に、aws --versionコマンドを叩いて、AWS Cliがインストールされたことを確認します。

[xxxxxxxx@instance-1 gcp]$ aws --version
aws-cli/1.24.10 Python/3.6.8 Linux/3.10.0-1160.71.1.el7.x86_64 botocore/1.26.10

上記確認できていればOK。
5. Service Account画面に戻り、上記の作成したService Accountの一意のIDをメモっておきます。
gcp_02.png

5.AWS側構築

  1. IAMの作成画面に遷移し、ウェブアイデンティティを選択の上、アイデンティティプロパイダーGoogleを選択します。Audienceに上記手順のService Accountの一意のIDを入力します。
    截屏2022-08-22 22.06.43.png

  2. 今回はS3を作成することをターゲットにしているため、AmazonS3FullAccess権限を付与します。
    截屏2022-08-22 22.10.50.png

  3. ロール名を入力の上、作成しておきます。
    截屏2022-08-22 22.12.50.png

  4. 作成後に、当IAMロールのARNをメモっておきます。
    截屏2022-08-22 22.26.24.png

6.GCP上のCompute Engineでの操作

1.ディレクトリ~gcp-sa-to-aws-iam-role-master/gcpに遷移していることを確認します。

[xxxxxxxxx@instance-1 gcp]$ pwd
/home/xxxxxxxxxx/gcp-sa-to-aws-iam-role-master/gcp

もしほかのディレクトリ配下にいれば、gcp-sa-to-aws-iam-role-master/gcpに遷移してください。

2.llコマンドを叩いて、get_aws_creds.pyファイルが存在していることを確認します。

[xxxxxxxxx@instance-1 gcp]$ ll
total 8
-rwxr-xr-x. 1 xxxxxxx xxxxxxx  1400 Mar 30  2021 get_aws_creds.py
-rw-rw-r--. 1 xxxxxxx xxxxxxx    22 Mar 30  2021 requirements.txt

こちらのget_aws_creds.pyファイル中身を見てみると、AWS側のSTSトークンを取得してきて、それを最終的に~/.aws/credentialsに格納しにいきます。AWS Cliは~/.aws/credentialsに認証情報を取得してアクセスする動作になります。

[xxxxxxxx@instance-1 gcp]$ cat get_aws_creds.py 
#!/usr/bin/env python3
#
# This code must run on a VM instance with a service account associated with it.
# The service account must be granted the 'Service Account Token Creator' IAM Role

import os
import sys
from os import path
import requests
import boto3

role = sys.argv[1]

# Set up the URL to request
SERVICE_ACCOUNT = os.getenv("SERVICE_ACCOUNT", "default")
BASE_URL = 'http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/'
AUDIENCE = 'potato'
FORMAT = 'full'
METADATA_HEADERS = { 'Metadata-Flavor': 'Google' }

# Construct a URL with the audience and format
url = BASE_URL + SERVICE_ACCOUNT + "/identity?audience=" + AUDIENCE + "&format=" + FORMAT

# Get the service token
r = requests.get(url, headers=METADATA_HEADERS)
token = r.text

# Turn the token into AWS credentials
sts = boto3.client('sts')
res = sts.assume_role_with_web_identity(
        RoleArn=role,
        WebIdentityToken=token,
        RoleSessionName='example')

creds = res['Credentials']

key = str(creds['AccessKeyId'])
secret = str(creds['SecretAccessKey'])
token = str(creds['SessionToken'])

output = "[default]\naws_access_key_id=%s\naws_secret_access_key=%s\naws_session_token=%s\n" % (key, secret, token)

try:
    os.mkdir(path.join(os.getenv('HOME'), '.aws'))
except:
    pass

with open(path.join(os.getenv('HOME'), '.aws', 'credentials'), 'w') as fp:
        print(output, file=fp)

出典:https://github.com/cevoaustralia/gcp-sa-to-aws-iam-role
※最初は自分でスクリプトを書こうと思ったら、すでにGithub上で私が書いたスクリプトより良さそうなものがあったので、それで今回そちらを使うことになりました。
なお、当スクリプトは一点不足しており、AWSリージョン情報を定義しておらず、興味のある方は~/.aws/configにリージョンを定義してください。

3.pythonシェルを実行
下記のように実行します。上記手順内でメモっていたARNを後ろに代入してください。

[xxxxxxxxx@instance-1 gcp]$ ./get_aws_creds.py arn:aws:iam::xxxxxxxxxxxx:role/aws-allow-gcp-access

上記実行後、aws sts get-caller-identityコマンドを叩くと、Assumeロールベース認証が確認できています。

[xxxxxxxxxx@instance-1 gcp]$ aws sts get-caller-identity
{
    "UserId": "xxxxxxxxxxxxxx:example",
    "Account": "xxxxxxxxxx",
    "Arn": "arn:aws:sts::xxxxxxxxxx:assumed-role/aws-allow-gcp-access/example"
}

さらに、~/.aws/credentials認証情報をみると、STSトークンが発行されていることを確認できます。

[xxxxxxxxxxx@instance-1 gcp]$ cat ~/.aws/credentials 
[default]
aws_access_key_id=ASIAXXXXXXXXXX6LNI6UI
aws_secret_access_key=nVW2D1J11+XXXXXXXXXXXXxeDIfSk2LTUgvbJ8U
aws_session_token=FwoGZXIvYXdzEA8aDCE1V5NUr2Ee6xDvJiLQAVeNoH8gU2vUxmRL7UNM8xvYvYsfuCg5bPgYQal1E/AM/7wNr9rzrzqV2j7lJ5BVY4mhqn0IuZ5jg5+ST208xyzHc/GK2yo+ZiismMYalF47tfCfERgC/7kh61+u0LaEhohfSLciwF0R59VZHZiQyy00saNPY9zQa8JLjdg4shpxL+xSY12dysEmXDJMKMAZYcIMLvZIf0pJ5JoKPnvc6BPgNU+nTB6MLHOU+g+a3A8f2TxmLP7CP4R4KiWoyWFJc7I0wSLNKiQrOKwogr+xikgol4eOmAYyWK6QH+VxXXXXXXXXXXXXXXXXXXXx4x6cLuOecFFBgnEY1e2H0Jqq5uWaJjjoKuwH8VRhIaw5yuAqnra+2flOwwMYwyugHc1w9ama+qJgP97EJC2MwmgK5I=

STSトークンであるため、下記のコマンドをもう一回叩くと、STSトークンが新しく発行されることを確認できますよ〜

[xxxxxxxxx@instance-1 gcp]$ ./get_aws_creds.py arn:aws:iam::xxxxxxxxxxxx:role/aws-allow-gcp-access
[xxxxxxxxx@instance-1 gcp]$ cat ~/.aws/credentials 
[default]
aws_access_key_id=ASIAXXXXXXXXXXXXUTGNA
aws_secret_access_key=iOPfLGkRQrzFM4BXXXXXXXXXXXXxO2piRHHwpCwUX
aws_session_token=FwoGZXIvYXdzEA8aDP4YPD/LaisLZnoufiLQARoaMPZx7u4I46VtKIW0zk67iVteo61FAmSwMhSR53wtuMB3wNwev6PL4sz7bpMotuXv0ZlLx49OSX5TV3xApcIr+JbJim8KyA7sM+zx16lehlTi1bBlTIFYnYh46a4PqcOyCBBtYD/qNRoydTJOR/cHBb5Lv3pGbu6TUNVJoqEdtRx/ERVtcddLS3O6F3ejiVmRt3QNreog2hJSDOZTdmJq53kO5IbxjW8gH2aNsK/JxNbsXD/yregYnspCTNHi7EyBHkpOLiFPWEMW9ib1SIEo+I+OmAYyWAfKVxXXXXXXXXXXXXXXXXXXXx4rYGYshuellrsC4puSmw3VFonPc06E3Oz0VvtaB+Bnk9rejj7cFmt6dRyXXd6sLbW485EPzGHrTibHUek9+6mjAFYk=

7. S3を作成してみます

AWSのIAM RoleにS3FullAccessの権限を付与したため、S3を作成することができると予想されます。

[xxxxxxxxx@instance-1 gcp]$ aws s3 mb s3://sdfhskgshkdfhkw48XXXX
make_bucket: sdfhskgshkdfhkw48XXXX
[xxxxxxxxx@instance-1 gcp]$ aws s3 ls
2022-08-22 13:45:56 sdfhskgshkdfhkw48XXXX

上記のように、S3が作られたことを確認できました。

8. STSトークンのセッション時間について

デフォルトは一時間になっていますが、AWS側のIAMロールのところで、セッション時間を最大12時間まで指定することができます。
截屏2022-08-22 22.49.38.png

9. AWSとGCP間の通信

もしAWSとGCP間のパブリック通信を懸念している方がいたら、GCPとAWS間に専用線とかのルーティングを設定して、AWSのSTS用VPC Endpointsにルーティングできれば良いです。

10. 参考資料

1.キーなしの API 認証 - サービス アカウント キーを必要としない Workload Identity 連携によるクラウド セキュリティの向上

2.AWS IAM Role を GCP から STS 認証で利用する設定例

3.GCP Service Account を AWS から STS 認証で利用する設定例

4.gcp-sa-to-aws-iam-role

7
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?