OCI Bastion 経由でプライベート・サブネット内のインスタンスに SSH で接続

Oracle Cloud Infrastructure (OCI) には、 Bastion(バスティオン)という、パブリックIPを持たないインスタンスに外から安全に接続するための完全無料のマネージドサービスが用意されています。

日本語では 要塞 と訳されています。

手元の PC からこの Bastion(踏み台の役割)を経由させることで、インスタンス自体にパブリックIPを一切持たせないまま、手元の PC のターミナルから直接 SSH 接続できるようになります。

設定には、ネットワーク(VCN)の構築段階からいくつか重要なポイント(ルーターやセキュリティ・リストの設定など)があり、結構はまったのでメモとして残しておきます。

仕組みとメリット

  • 完全無料で、自分で踏み台用のサーバー(EC2など)を1台管理・維持する必要がありません。
  • 接続が必要なときだけ、手元のPCから「3時間だけ有効な一時的な接続セッション(トンネル)」を発行して侵入します。時間が経てば自動で完全に閉じられるため、セキュリティが非常に強固です。

環境

  • ホストPC: Ubuntu 22.04
  • インスタンス: Oracle Linux 9
📝 注記

インスタンスが Oracle Linux の場合と、Ubuntu などの他の OS の場合とで方法が一部異なります。
今回は Oracle Linux 9 の場合で、Ubuntu についてはまた別で書きます。

Step1: VCN とサブネットの作成

まずは土台となる仮想クラウド・ネットワーク(VCN)を作成します。
手動で細かく作ることもできますが、「VCNウィザード」を使うのが一番簡単で確実です。
インターネットに出るための「インターネット・ゲートウェイ」だけでなく、プライベートVMがアップデート等で外と通信するための「NATゲートウェイ」や「サービス・ゲートウェイ」も自動で作成・紐付けされます。

OCIコンソールメニューから 「ネットワーキング」 > 「仮想クラウド・ネットワーク」 に移動します。

アクションから「VCNウィザードの起動」 をクリックします。

「インターネット接続性を持つVCNの作成」 を選択し、「VCNウィザードの起動」をクリックします。

以下の情報を入力・確認して「次へ」進み、作成します。

項目内容
VCN名任意の名前(例: my-bastion-vcn)
VCNの構成 CIDRブロック10.0.0.0/16(デフォルトのままでOK)
パブリック・サブネットのCIDR10.0.0.0/24
プライベート・サブネットのCIDR10.0.1.0/24

Step2: インスタンスの作成

次に、パブリックIPを持たない接続先のインスタンスを作成します。
「コンピュート」 > 「インスタンス」 から 「インスタンスの作成」 をクリックします。
インスタンスの作成については別記事でも書いているので詳細は割愛しますが、イメージは Oracle Linux 9 を選びます。

そして、ネットワーキングセクションで以下を選択します。

  • プライベート・サブネット(Step 1で作成したもの)を選択。
  • 「パブリックIPアドレスの割当て」 で 「パブリックIPなし」 を選択。

SSHキーのセクションでは、ご自身のPCで作成した公開鍵(.pub)をアップロード、または新規で生成して秘密鍵を保存してください。

設定したら「作成」をクリックします。

Stes3: Bastion プラグインの有効化 (Oracle Linux の場合のみ)

作成したインスタンスの詳細画面に入り、管理タブの「Oracle Cloud エージェント」で要塞を探し、有効化します。

要塞のステータスが停止済となります。
OSの内部でプログラムのダウンロードや配置が行われており、ステータスが「実行中」になるまでには5分〜10分ほどかかることがあります。

📝 注記

ここで要塞を有効にしておかないと、後述の管理対象SSHセッションの作成で API エラーとなります。

Step4: Bastionの作成

「アイデンティティとセキュリティ」 > 「要塞」(Bastion)に移動します。

「要塞の作成」 をクリックし、以下のように設定します。

項目内容
要塞名任意の名前
ターゲット仮想クラウド・ネットワークStep 1で作成したVCN
ターゲット・サブネットターゲットVMがいる「プライベート・サブネット」 を選択します。
CIDRブロックの許可リスト0.0.0.0/0 (特定のIPだけに絞るとより安全です)

「要塞の作成」をクリックします(アクティブになるまで数分かかります)。

Step5: セッションの作成

作成した Bastion の詳細画面に入り、「セッションの作成」 をクリックします。

以下のように設定します。

項目内容
セッション・タイプOracle Linux の場合は 管理対象SSHセッション を選択します。
ユーザー名Oracle Linux の場合は opc です。
ターゲット・コンピュート・インスタンスStep2 で作成したプライベートVMを選択します。
SSHキーご自身のPCにある SSH 公開鍵をアップロード or ペーストするか、新規に生成します。VM作成時に使ったものと同じ、またはペアになるものをアップロードしても OK です(後述)。

「セッションの作成」をクリックします。
状態が作成中となり、しばらく経つとアクティブになります。

Step6: SSH接続の実行

セッションが「アクティブ」になったら、いよいよ接続です。 作成したセッションの右側にある「3つの点」メニューから 「SSHコマンドのコピー」 をクリックします。

コピーされるコマンドは以下のような形をしています。

ssh -i <privateKey> -o ProxyCommand="ssh -i <privateKey> -W %h:%p -p 22 ocid1.bastionsession.oc1..." opc@10.0.1.x

<privateKey> 2箇所ありますので、それぞれ VM インスタンス作成時の秘密鍵、Bastion セッション作成時の秘密鍵のパスに変更して実行します。

# 例
ssh -i ~/.ssh/VM用の秘密鍵 -o ProxyCommand="ssh -i ~/.ssh/Bastion用の秘密鍵 -W %h:%p ..." opc@10.0.1.x
📝 注記

セッション作成時の SSH キーを VM 作成時と同じものにした場合は、2箇所とも同じ秘密鍵のパスを指定します。

📝 注記

Linux のルールとして、秘密鍵の権限が緩いままだとSSH接続が拒否されてしまいます。この場合、以下のコマンドでパーミッションを変更します。
chmod 600 ssh-key-xxxx.key

実行すると、Bastionを経由してパブリックIPのないプライベートVMに直接SSHログインが完了します。

SSH キーについての補足

セッション作成時のSSHキーはVM作成時と同じでも別のものでも大丈夫です。

OCI の Bastion サービスは、接続時に「2枚の壁(認証)」を通過するイメージになります。

Bastionセッション作成時のSSHキー(壁1:入口の鍵)

  • ローカルPCから、OCIのBastionサービス(要塞)に侵入するための鍵です。
  • Bastionサービス自体が「あなたは本当にこのセッションを作った本人ですか?」を確かめるために使います。

VM作成時のSSHキー(壁2:奥の部屋の鍵)

  • Bastionを通り抜けたあと、ターゲットのプライベートVMにログインするための鍵です。
  • VM(OS)側が「あなたはログインを許可されたユーザーですか?」を確かめるために使います。

このように鍵の役割が独立しています。
ただ、「同じ鍵」を使った場合と「別の鍵」を使った場合で、最後に実行するSSHコマンドの書き換え方が少し変わります。

① 同じ鍵を使った場合(一番シンプル)

すべて1つの秘密鍵(例: id_rsa)で開くので、コピーしたコマンド内の2箇所の <privateKey> に同じ秘密鍵のパスを指定すればOKです。

ssh -i ~/.ssh/id_rsa -o ProxyCommand="ssh -i ~/.ssh/id_rsa -W %h:%p ..." opc@10.0.1.x

② 別の鍵を使った場合(それぞれ指定が必要)

コマンドの「前半」と「後半」で、それぞれの秘密鍵を指定する必要があります。

  • 前半の -i: VM作成時の秘密鍵を指定
  • 中間の ProxyCommand内の -i: Bastionセッション作成時の秘密鍵を指定
ssh -i ~/.ssh/VM用の秘密鍵 -o ProxyCommand="ssh -i ~/.ssh/Bastion用の秘密鍵 -W %h:%p ..." opc@10.0.1.x

管理やコマンドの書き換えをシンプルにしたい場合は、「同じ鍵(ペア)」を使ってしまうのが一番迷わなくてラクです。

セキュリティ的な問題は?

個人開発や一般的な社内検証環境レベルであれば、同じ鍵を使い回しても実用上のセキュリティリスクは非常に低い(実質的に問題ない)と言えます。

ただし、厳格なエンタープライズ(企業)の運用基準や、セキュリティの理想論(ベストプラクティス)の観点から見ると、いくつか「知っておくべきリスクと理由」があります。
なぜ分けるのが理想とされるのか、その理由は以下です。

1. 鍵が漏洩した際の影響範囲(爆発半径)が広がる

これが最も大きな理由です。

鍵を分けている場合: もしBastion用の鍵が外部に漏れても、攻撃者はBastionの入り口までしか来られません。ターゲットVMの鍵が無事なら、中のデータにはアクセスできません。

同じ鍵を使っている場合: その1つの秘密鍵が漏洩した瞬間、Bastionの突破からターゲットVMへのログインまで、すべての防御壁が同時に崩壊します。

ひとつの鍵にすべての権限を持たせることは、セキュリティの世界で嫌がられる「単一障害点(Single Point of Failure)」を作ることになってしまいます。

2. 「誰が・どこに」アクセスしたかの監査(ログ)が曖昧になる

本番環境やチーム開発において重要な視点です。

Bastion(要塞)の本来の目的は、「いつ、誰が、どのサーバーに入ったか」を厳密に記録・コントロールすることです。

  • Bastion用の鍵: 「あなたがクラウド環境のネットワークに入った」ことを証明する
  • VM用の鍵: 「あなたが特定のサーバーの opc ユーザーとしてログインした」ことを証明する

これらを同じ鍵にしてしまうと、鍵の管理者が同一人物である前提になってしまい、「Bastionを通過した人と、実際にVMを操作した人が本当に同一人物か?」という厳密なトレース(監査ログの信頼性)が担保しにくくなります。

参考

Hugo で構築されています。
テーマ StackJimmy によって設計されています。