IPアドレスレンジが重複したVPC間の直接アクセス

当初予定の無かった、異なるプロジェクト上にあるVM間の直接接続依頼。
確認すると2つのVMはそれぞれ同じIPアドレスレンジを持つVPC上で起動されていた!
さて、どうしたものか。。

はじめに

お久しぶりです、エンジニアのよっしーです。
クラウド環境では開発環境、本番環境など、環境毎に異なるプロジェクトを作成することはよくある話。 そして、その配下に作成する VPC の IP アドレスレンジを
「共通にすると管理がしやすい!」と同じにしてしまうことありますね!

しかし開発期間中に「開発環境と本番環境のサーバ間を直接接続して、必要な時にすぐにファイル転送できるようにしたいんだけど」 と、開発チームから依頼が。。
通常なら、 「プロジェクト間の VPC peering」 で対応できるはずが、peering したい2つの VPC の IP アドレスレンジが重複。。

こんな時便利なのが、
「踏み台サーバのパブリックIPアドレス間での ssh port-forward」 の利用。
その方法についてお話しします。

1. 問題となった「IP アドレス重複」の構成

前述もしていますが、このクラウドの構成でのポイントを整理すると:

  • 各プロジェクト配下の VPC(subnet) に設定された IP アドレスレンジが同じ
    • common VPC : 10.0.0.0/16、 環境 VPC (prd, dev) : 10.2.0.0/16
  • プロジェクト内の VPC 間には VPC peering を設定 (10.0.0.0/16 <=> 10.2.0.0/16)
  • common VPC 内の「踏み台サーバ(bastion)」のみにパブリックIPアドレスを設定
  • 「踏み台サーバ(bastion)」以外のサーバにはセキュリティ対策のためパブリック IP の設定はなし
  • 各プロジェクトとも「踏み台サーバ(bastion)」からプロジェクト内の各サーバへの ssh 接続は許可

2. 通常は「プロジェクト間の VPC peering」が利用できますが。。

  • production (以下 prod) : prod (10.2.0.0./16) <=> development (以下dev) : dev (10.2.0.0/16) 間は IP アドレスレンジ重複のため プロジェクト間 VPC peering はできない
  • prod : common (10.0.0.0./16) <=> dev : common (10.0.0.0/16) 間は IP アドレスレンジ重複のためプロジェクト間 VPC peering できない
  • prod : prod (10.2.0.0./16) と prod : common (10.0.0.0./16) および、dev : common (10.0.0.0/16) と dev : dev (10.2.0.0./16) は 既に VPC peering しているため、下記のプロジェクト間 VPC peering もできない
    • prod : prod (10.2.0.0./16) <=> dev : common (10.0.0.0/16) 間
    • dev : dev (10.2.0.0/16) <=> prod : common (10.0.0.0/16) 間

3.「踏み台サーバ間の ssh port-forward」の登場

3-0) ssh port-forward の接続手順は「local」「remote」の2種類

前提として、Prod側の prd-admin サーバから、dev 側の dev-ap サーバへのssh 接続を確立したい時に、ssh port-forward の ssh 接続を確立させる向きとして、以下の2種類の接続手順がある。

3-0-1. local 接続

接続元 (prod) 側の bastion サーバ上で ssh port-forward コマンドを実行し、bastion (prod) → bastion (dev) 方向のssh port-forward 接続を確立させる手順。

3-0-2. remote 接続

接続先 (dev) 側の bastion サーバ上で ssh port-forward コマンドを実行し、
bastion (dev) → bastion (prod) 方向のssh port-forward 接続を確立させる手順。

3-1) 事前設定

ssh port-forward コマンドを実行する前に、以下の設定を実行。

3-1-1. ファイアウォール(セキュリティ グループ)の設定

  • prod 側
    • bastion (prod) にて prd-admin (10.2.107.152) から port 10022 へのアクセスを許可を追加
    • bastion (prod) にて bastion (dev) (35.239.152.87) から port 22 (ssh) へのアクセスを許可を追加 (Remote接続の場合)
  • dev 側
    • bastion (dev) にて bastion (prod) (35.188.136.120) から port 22 (ssh) へのアクセスを許可を追加 (Local接続の場合)

3-1-2. ssh port-forward 接続用の user を作成

以下の設定は例。user名、グループ名、ID 番号は任意に設定可能。

  • prod, dev 共通

    • bastion (prod) と bastion (dev) に共通の user, group を作成
    • User : sshfoward (30000), Group : sshportfoward (30000)
    $ sudo groupadd -g 30000 sshforward
    $ sudo useradd -d /home/sshforward -g 30000 -m -s /bin/bash -u 30000 sshforward
    

3-1-3. bastion (prod) <=> bastion (dev) 間の ssh 接続準備

上記で作成したssh port-forward 接続 user (sshforward) 用の ssh-key の準備

local 接続の場合

  • bastion (prod) 側
    • ssh 用 key を作成し、private key, public key を bastion (prod) に保存
  • bastion (dev) 側
    • bastion (prod) に配置した public key を含む authorized_keys を保存
  • 上記 ssh 用 key を設定後 bastion (prd) からbastion (dev) へ ssh 接続できることを確認

remote 接続の場合

  • dev 側
    • ssh 用 key を作成し、private key, public key を bastion (dev) に保存
  • prod 側
    • bastion (dev) に 配置した public key を含む authorized_keys を保存
  • 上記 ssh 用 key を設定後 bastion (dev) から bastion (prod) へ ssh 接続できることを確認

3-2) ssh port-forward の起動

3-2-1. local 接続の場合

  • ssh ポートフォワード のコマンドは下記の通り。bastion (prod) 上で実行
[sshforward@production/bastion:~]$ ssh -fNg -L 10022:10.2.65.113:22 35.239.152.87

コマンドの説明:

ssh -fNg -L port-forward接続元ポート番号(10022):接続先IPアドレス(dev-ap): 接続先ポート番号(ssh:22) port-forward接続先IPアドレス(bastion(dev):35.239.152.87)

オプション
-L : port-forward local 接続
-f : バックグラウンド実行
-N : リモートコマンドの実行なし
-g : ローカルホスト(bastion (prod)) 以外のホストからのport-forward接続元ポート(10022)への接続許可

3-2-2. remote 接続の場合

  • ssh コマンド実行前に、bastion(prod) 以外のホストからの port-forward 接続元ポート(10022)への接続許可場合は、 /etc/ssh/sshd_config ファイル中のGatewayPorts yesに設定する必要がある。(local 接続の -g オプション相当)
$ sudo  cat /etc/ssh/sshd_config | grep GatewayPorts
GatewayPorts yes
$ sudo systemctl reload sshd
  • ssh ポートフォワード のコマンドは下記の通り。bastion (dev) 上で実行
[sshforward@development/bastion:~]$ ssh -fN -R 10022:10.2.65.113:22 35.188.136.120

コマンドの説明:

ssh -fN -R port-forward接続元ポート番号(10022):接続先IPアドレス(dev-ap): 接続先ポート番号(ssh:22) port-forward接続元IPアドレス(bastion(prod):35.188.136.120)
 
オプション
-R : port-forward remote 接続
-f : バックグラウンド実行
-N : リモートコマンドの実行なし

4. 接続結果

prd-admin から dev-ap への ssh port-foward 経由での ssh 接続を実行。
(事前に prd-admin : user1 ユーザの ssh public-key を dev-ap : user1 ユーザの authorized_keys へ登録済み)

[user1@production/prd-admin:~]$ ssh 10.0.13.200 -p 10022
Last login: Thu Dec  9 07:45:36 2021 from prd-admin.asia-northeast1-a.c.xxx-production.internal
[user1@development/dev-ap: ~]$

5. ssh 以外の接続

ssh port-forward は tcp レベルでの接続をフォワードするため、ssh 以外(例:mysql:3306) の接続も可能

上図は prd-admin サーバから dev-db サーバへの mysql コマンドでの接続の例 ssh port-forward コマンドは以下の通り

# local 接続
bastion(prod):sshforward $ ssh -fNg -L 33306:10.2.65.122:3306 35.239.152.87

#remote 接続/Users/ysatoh/Desktop/変換された画像\ 2021-12-14\ 時刻\ 16.54.10 
bastion(dev):sshforward $ ssh -fN -R 33306:10.2.65.113:3306 35.188.136.120

実行結果

[user1@production/prd-admin:~]$ mysql -h 10.0.0.2 -P 33306 -u user1 -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2298
Server version: 5.7.12-log MySQL Community Server (GPL)

Copyright (c) 2000, 2021, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

user1@dev-db>

上記の例からも分かる通り、ssh port-forward 接続元サーバ側で使用するポート番号を変更することにより、 複数の ssh port-forward 接続を同時に起動することが可能

終わりに

今回の ssh port-forward を利用した接続は、できれば使いたくない「最後の手段」としてご紹介しました。 VPC の IP アドレスレンジ決めはプロジェクト立ち上げの初期の初期で設定が必要なものであり、後から変更できない仕様です。

できればこの手段のお世話になることなく、しっかりとしたクラウド環境設計ができるようにしていきましょう!