VPN(IPsec)によるS3からGCSへのprivateデータ転送
インターネット(https)経由でのS3->GCSデータ連携パターンは
以下記事で実験したので
https://note.com/ucwork/n/n825ac1c96764
https://note.com/ucwork/n/n5fe04382409b
次はインターネットVPN(IPsec)経由でのデータ転送を実験してみる
全体的な流れ
こんなイメージ
1. AWS, GCP間をVPNで接続しprivate ipでアクセスできるようにする
2. GCSへのアクセスがprivateか確認する
3. S3へのアクセスもprivateにする
4. S3->GCSへのアクセスをprivateに実現!
とはいえVPN構成作ること自体初めてなので
ひとつひとつ学習しながら進めていく
今回の記事で出来上がった構成を雑に書くとこんな感じ
VPNで接続する
こちらの素敵記事があったので、そのまんま真似してみる
https://dev.classmethod.jp/articles/aws_gcp_vpn/
AWS側の設定
VPCを作成
とりあえず今回利用するVPCを作成
Virtual Private Gatewayを作成
VPN接続のためのVirtual Private Gatewayを作成
作成したVPCにattach
Route Propagationの設定
VPCのRoute Tableで、Virtual Private GatewayのRoute PropagationをYesに設定。
この設定でVirtual Private Gatewayのルーティング情報がRoute Tableに自動で反映される
Virtual Private GatewayにはBGPで学習した相手のルーティング情報を保持している感じ。きっと
GCP側の設定
VPCネットワークの作成
今回使用するVPCネットワーク、private用subnetを作成
後々GCSにprivate接続することを想定してsubnetでは「限定公開のGoogleアクセス」はオンにしておく
Cloud Router作成
作成したVPCを指定してCloud Routerの作成
これを作成することで、AWS側でGCP側のルート情報を知ることができる
Cloud VPN作成
公式では高可用性(HA)推奨だが
とりあえず検証したいのでコスト少なそうなClassicで
IPアドレスを作成指定、IPアドレスが指定されるので
トンネルは一旦スルーしてAWSの設定に戻る
AWSの作業に戻る
VPNの作成
GCPで作成したIPアドレスと指定したASNを設定し作成!
他のオプションは特に触らない
設定のダウンロード
作成したVPNを指定してDownload Configurationを押下
Genericを指定してDownload
GCPのVPN設定に戻る
AWSでダウンロードした情報を以下の通り入力
・リモートピアIPアドレス:IPSec Tunnel #1 > #3: Tunnel Interface Configuration > Outside IP Addresses > Virtual Private Gatewayを入力
・IKEバージョン:IKEv1を選択
・IKE事前共有キー:IPSec Tunnel #1 > #1: Internet Key Exchange Configuration > Pre-Shared Key
・ ルーティングオプション:動的(BGP)
・ クラウドルーター:作成したCloud Routerを指定
BGPセッションのペンボタンを押下して、AWSダウンロード情報を入力
・ピアASN:IPSec Tunnel #1 > #4: Border Gateway Protocol (BGP) Configuration > BGP Configuration Options > Virtual Private Gateway ASN
・Cloud Router のBGP IP:
IPSec Tunnel #1 > #3: Tunnel Interface Configuration > Inside IP Addresses > Customer Gateway(CIDRが指す対象のIPアドレスを指定)
・BGP ピア IP:
IPSec Tunnel #1 > #3: Tunnel Interface Configuration > Inside IP Addresses > Virtual Private Gateway
(同上)
うまく入力できていれば
VPNトンネルのステータス、BGPセッションのステータスが
それぞれ確立になりグリーンアイコンが表示される
※BGPセッションの入力内容間違えててなかなか確立しなかった😫
AWS側も以下の通りStatusがUPになって確立が確認できる
VPNのPrivate接続確認
AWS、GCPそれぞれにインスタンスを作成し、PrivateIP指定のpingが通ることを確認してみる
AWS側の設定
private想定のsubnetをVPCに作成
private subnetにEC2を作成
適当なAMI, Instance Typeを指定
作成したサブネットを指定
Security GroupのInbound指定
pingを受け付けられるようにICMPのInboundルールを追加
作成したprivate EC2に踏み台経由でssh接続
作成したEC2はprivateなので、踏み台用のpublicなEC2作成する
まずはVPCにpublic想定のsubnet作成
作成したpublic想定のsubnetにEC2作成
基本は上記でEC2作成した手順通りだが、サブネットを作成したもの指定
Public IPをEnableにする
お家からssh接続できるようにSecurity Group設定
SourceはMy IP選択すると接続中のGlobal IP設定される
作成したEC2にssh接続するためにはInternet Gatewayへのルートを設定した
Route Tableが必要なので新たに作成
作成したRoute tableのRouteにInternet Gatewayを追加
Route tableとsubnetを適切に関連付ける
Internet GatewayのRouteがあるRoute Tableをpublic想定のsubnetにセット
踏み台(Bastion)EC2経由でprivateなEC2に接続!
publicなEC2の「IPv4 Public IP」とprivateなEC2の「Private IPs」を指定してssh接続
$ ssh -o ProxyCommand='ssh -i ~/Downloads/ucwork.pem ec2-user@[bastion global ip] -W [target private ip]:22' -i ~/Downloads/ucwork.pem ec2-user@[target private ip]
...
__| __|_ )
_| ( / Amazon Linux AMI
___|\___|___|
https://aws.amazon.com/amazon-linux-ami/2018.03-release-notes/
4 package(s) needed for security, out of 8 available
Run "sudo yum update" to apply all updates.
[ec2-user@xxx ~]$
接続でけた!
GCP側にもインスタンス作成
インスタンス作成
作成したサブネットを指定してGCE作成
外部IPなしでprivateに設定
pingを受け付けられるようにICMPを受け入れるFW作成
privateなGCEに接続するために、publicなサブネットを作成
publicなサブネットに踏み台用GCE(Bastion)を作成
外部IP(エフェメラル)を指定
ssh接続できるようにtcp:22を許可するセキュリティグループ作成
publicなインスタンスに公開鍵登録
踏み台インスタンスからprivateインスタンスにSSH接続確認
$ ssh -o ProxyCommand='ssh -i ~/.ssh/id_rsa [ssh user name]@[bastion global ip] -W 10.4.1.2:22' -i ~/.ssh/id_rsa shintaro.uchiyama@10.4.1.2
...
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
...
Last login: Tue Jul 21 12:54:09 2020 from xxx
shintaro.uchiyama@ucwork-gce:~$
接続できた!!
AWS, GCPそれぞれprivate ip指定で接続確認
AWS
以下の通りEC2からGCEにping飛ばして疎通確認
$ ssh -o ProxyCommand='ssh -i ~/Downloads/ucwork.pem ec2-user@[bastion global ip] -W 10.1.1.47:22' -i ~/Downloads/ucwork.pem ec2-user@10.1.1.47
...
Last login: Thu Jul 23 13:10:44 2020 from 10.1.2.238
__| __|_ )
_| ( / Amazon Linux AMI
___|\___|___|
https://aws.amazon.com/amazon-linux-ami/2018.03-release-notes/
4 package(s) needed for security, out of 8 available
Run "sudo yum update" to apply all updates.
[ec2-user@ip-10-1-1-47 ~]$
[ec2-user@ip-10-1-1-47 ~]$ # インターネットには出れないこと確認
[ec2-user@ip-10-1-1-47 ~]$ ping -c 3 youtube.com
PING youtube.com (172.217.26.46) 56(84) bytes of data.
--- youtube.com ping statistics ---
3 packets transmitted, 0 received, 100% packet loss, time 2043ms
[ec2-user@ip-10-1-1-47 ~]$ # 出れない!privateや!
[ec2-user@ip-10-1-1-47 ~]$
[ec2-user@ip-10-1-1-47 ~]$ # GCPのprivateなGCEにping
[ec2-user@ip-10-1-1-47 ~]$ ping -c 3 10.4.1.2
PING 10.4.1.2 (10.4.1.2) 56(84) bytes of data.
64 bytes from 10.4.1.2: icmp_seq=1 ttl=63 time=8.46 ms
64 bytes from 10.4.1.2: icmp_seq=2 ttl=63 time=7.14 ms
64 bytes from 10.4.1.2: icmp_seq=3 ttl=63 time=6.98 ms
--- 10.4.1.2 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2002ms
rtt min/avg/max/mdev = 6.987/7.533/8.468/0.667 ms
[ec2-user@ip-10-1-1-47 ~]$ # 接続できてる!!
GCP
以下の通りGCEからEC2にping飛ばして疎通確認
$ ssh -o ProxyCommand='ssh -i ~/.ssh/id_rsa shintaro.uchiyama@[bastion global ip] -W 10.4.1.2:22' -i ~/.ssh/id_rsa shintaro.uchiyama@10.4.1.2
...
Last login: Fri Jul 24 01:27:21 2020 from 10.4.2.2
[user name]@ucwork-gce:~$
[user name]@ucwork-gce:~$ # インターネットには出れないこと確認
[user name]@ucwork-gce:~$ ping -c 3 youtube.com
PING youtube.com (172.217.25.206) 56(84) bytes of data.
--- youtube.com ping statistics ---
3 packets transmitted, 0 received, 100% packet loss, time 26ms
[user name]@ucwork-gce:~$ # 出れない!privateや!
[user name]@ucwork-gce:~$
[user name]@ucwork-gce:~$ # AWSのprivateなEC2にping
[user name]@ucwork-gce:~$ ping -c 3 10.1.1.47
PING 10.1.1.47 (10.1.1.47) 56(84) bytes of data.
64 bytes from 10.1.1.47: icmp_seq=1 ttl=253 time=8.10 ms
64 bytes from 10.1.1.47: icmp_seq=2 ttl=253 time=8.10 ms
64 bytes from 10.1.1.47: icmp_seq=3 ttl=253 time=7.01 ms
--- 10.1.1.47 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 5ms
rtt min/avg/max/mdev = 7.014/7.736/8.099/0.510 ms
[user name]@ucwork-gce:~$ # pingできてる!!
長かった。これでVPN接続してそれぞれpingでprivate ip宛に接続できた
S3へのアクセスをprivateにしてみる
当初の目的を忘れかけてきたが、S3からGCSにprivateでデータを送信することだった👶S3、GCSへのアクセスもprivateにする
S3へprivate接続するためにVPC Endpoint作成
対象のVPC、private subnetに関連したRoute Tableを指定して作成
S3へのprivate接続を確認
$ # privateなEC2に接続
$ ssh -o ProxyCommand='ssh -i ~/Downloads/ucwork.pem ec2-user@[bastion global ip] -W [target private ip]:22' -i ~/Downloads/ucwork.pem ec2-user@[target private ip]
...
__| __|_ )
_| ( / Amazon Linux AMI
___|\___|___|
https://aws.amazon.com/amazon-linux-ami/2018.03-release-notes/
4 package(s) needed for security, out of 8 available
Run "sudo yum update" to apply all updates.
[ec2-user@xxx ~]$
[ec2-user@xxx ~]$ ping -c 3 youtube.com
PING youtube.com (172.217.25.78) 56(84) bytes of data.
--- youtube.com ping statistics ---
3 packets transmitted, 0 received, 100% packet loss, time 2038ms
[ec2-user@xxx ~]$ # EC2からインターネットに接続できなさそう
[ec2-user@xxx ~]$
[ec2-user@xxx ~]$ aws s3 ls --region ap-northeast-1 --recursive s3://[bucket-name]/access_allow/
Unable to locate credentials. You can configure credentials by running "aws configure".
[ec2-user@xxx ~]$ # uge...認証せねばならぬみたい
[ec2-user@xxx ~]$
[ec2-user@xxx ~]$ aws configure
AWS Access Key ID [None]: [AWS Access Key ID]
AWS Secret Access Key [None]: [AWS Secret Access Key]
Default region name [None]: ap-northeast-1
Default output format [None]:
[ec2-user@xxx ~]$
[ec2-user@xxx ~]$ # s3への接続確認
[ec2-user@xxx ~]$ aws s3 ls --region ap-northeast-1 --recursive s3://[bucket-name]/access_allow/
2020-07-12 13:44:44 0 access_allow/
2020-07-12 13:47:02 14 access_allow/test.csv
S3のバケットにPrivateにアクセスできた!
S3アクセスのためのIAMポリシー周りの設定はこの辺見てちょ
https://note.com/ucwork/n/n5fe04382409b
GCSへのアクセスをprivateにする
private用subnet作成時に「限定公開のGoogleアクセス」を指定してるので
S3へのアクセスもprivateに行けるはず!
$ ssh -o ProxyCommand='ssh -i ~/.ssh/id_rsa [user name]@[bastion global ip] -W 10.4.1.2:22' -i ~/.ssh/id_rsa [user name]@10.4.1.2
...
Last login: Fri Jul 24 02:05:59 2020 from 10.4.2.2
[user name]@ucwork-gce:~$
[user name]@ucwork-gce:~$ ping -c 3 youtube.com
PING youtube.com (172.217.25.206) 56(84) bytes of data.
--- youtube.com ping statistics ---
3 packets transmitted, 0 received, 100% packet loss, time 27ms
[user name]@ucwork-gce:~$ # インターネットには接続できてない
[user name]@ucwork-gce:~$
[user name]@ucwork-gce:~$ gsutil ls
gs://xxx
[user name]@ucwork-gce:~$ # gcsに接続できた!!
S3からGCSへprivateデータ転送
VPC間をCloud VPNで接続、VPC(AWS)->S3、VPC(GCP)->GCSへのprivate接続はできたけど、
当初の目的を達成にするためには、VPC(AWS)->GCSへのprivate接続が必要なことにここめできて気づく👶
ググってみた感じこの記事が目的を達成してくれそう!
ざくっというとGCSやBigQueryなど*.googapis.comへのアクセスをVPN経由にして、GCS内からprivateアクセスされる感じ
*.googleapis.comをprivate.googleapis.com(199.36.153.8/30)へ向ける
普通にするとインターネット経由しないとアクセスできないGlobalIPに対してアクセスしようとする
$ dig bigquery.googleapis.com +short
172.217.161.74
VPN経由してprivateにGoogleリソースにアクセスするためには
private.googleapis.com(199.36.153.8/30)にリクエストをしなければいけないらしい
ということで、Route53でPrivateなHosted Zoneを作成して
*.googleapis.comを199.36.153.8/30にアクセスするようにする
以下4IPアドレスをAレコードとして登録
199.36.153.8, 199.36.153.9, 199.36.153.10, 199.36.153.11
しばらく待ってると、IPが変わる!
[ec2-user@ip-10-1-1-47 ~]$ dig bigquery.googleapis.com +short
172.217.161.74
[ec2-user@ip-10-1-1-47 ~]$
[ec2-user@ip-10-1-1-47 ~]$ dig bigquery.googleapis.com +short
199.36.153.8
199.36.153.9
199.36.153.10
199.36.153.11
199.36.153.8/30をVPNに向ける
作成していたCloud Routerを編集してカスタムルートを追加する
これにより、AWS側がこのルートを学習し、Route Tableに追加される
AWSのルートに追加されてる!
gsutilでのS3からGCSへのデータ転送確認
AWSからgsutilコマンド実行してデータ転送することを想定
ということで、privateなEC2にgsutilをインストールする!
NAT Gatewayを配置するpublicなsubnet作成
作成したsubnetを対象にNAT Gateway作成
privateなサブネットのRouteにNAT Gatewayを指定
これでprivate EC2からインターネット接続できるので
公式にならってgsutilコマンドをインストールする
サービスアカウント鍵のアップロード
権限を付与したサービスアカウント鍵をEC2にアップロードする
scp -o ProxyCommand='ssh -i ~/Downloads/ucwork.pem ec2-user@[bastion global ip] -W 10.1.1.47:22' -i ~/Downloads/ucwork.pem ~/Downloads/[credential file].json ec2-user@10.1.1.47:~/credential.json
AWS IAMのCredential情報を設定
S3アクセス間のあるIAM Credential情報を設定
[ec2-user@ip-10-1-1-47 ~]$ cat ~/.boto
[Credentials]
aws_access_key_id = [aws_access_key_id]
aws_secret_access_key = [aws_secret_access_key]
s3_host = s3-ap-northeast-1.amazonaws.com
データ転送検証
ついにきた!!データ転送検証確認
EC2がインターネットに接続できない状態で動作検証したいので
gsutilコマンドインストールのためにセットしたNAT GatewayへのRouteを削除して以下検証を行う!!!
[ec2-user@ip-10-1-1-47 ~]$ ping -c 3 youtube.com
PING youtube.com (172.217.175.238) 56(84) bytes of data.
--- youtube.com ping statistics ---
3 packets transmitted, 0 received, 100% packet loss, time 2054ms
[ec2-user@ip-10-1-1-47 ~]$ # インターネットには出れない状態
[ec2-user@ip-10-1-1-47 ~]$
[ec2-user@ip-10-1-1-47 ~]$ gsutil cp s3://[bucket-name]/access_allow/test.csv gs://[bucket-name]/test2.csv
Copying s3://[bucket-name]/access_allow/test.csv [Content-Type=text/csv]...
/ [1 files][ 14.0 B/ 14.0 B]
Operation completed over 1 objects/14.0 B.
[ec2-user@ip-10-1-1-47 ~]$ # 遅れていそうな雰囲気!
[ec2-user@ip-10-1-1-47 ~]$
[ec2-user@ip-10-1-1-47 ~]$ gsutil ls gs://[bucket-name]/
gs://[bucket-name]/test2.csv
データ転送できてたぁあぁああああああ!!!
まとめ
とにかく長かった。初めはVPN接続したことないからやってみようくらいの気持ちだったが。こんなに長くなってしまった。
業務で取り組むことがあれば、次は絶対Terraformでやって再現しやすいようにしよう👳
この記事が気に入ったらサポートをしてみませんか?