AWS上のEC2インスタンスへSSH接続する際、社内VPNを都度接続させたり、セキュリティグループで接続元IP(オフィスや自宅)をホワイトリスト登録して管理するのが従来の一般的なアプローチでした。
しかし、リモートワークや外出先からの接続では「クライアントPCのグローバルIPが変動するたびセキュリティグループの更新が必要」「クライアントPC用に高価な固定IPを契約・手配するのが難しい」「全社VPNの運用コストや接続トラブル、帯域逼迫がつらい」といった課題がつきまといます。
そこで、VPN機器や専用回線、クライアントPC側の固定IPを一切不要にする代替ソリューションとして極めて有効なのが、Cloudflare Tunnel と Cloudflare Access(Zero Trust) を組み合わせたSSH接続アーキテクチャです。
クライアントPCの接続元IPアドレスを問わず、ブラウザ認証(IdPやワンタイムパスコード)による強力な認証基盤をそのままSSHの門番として利用できます。
本記事では、EC2のインバウンド22番ポートを完全に閉じた状態で、クライアントからブラウザ認証を経てセキュアにSSHログインする環境の構築手順と、実際の実装時にハマりやすいトラブルシューティングを解説します。
1. 全体構成とアーキテクチャ
本構成の最大の特徴は、「クライアントPCの固定IPが不要」かつ「EC2側のインバウンドポートを一切開放しない」点です。

- ローカルPC: 固定IPは一切不要(動的IP・自宅・カフェどこからでもOK)。OpenSSHの ProxyCommand 経由で cloudflared を呼び出し、Cloudflareエッジで認証をパスしたセッションを通じて通信します。
- Cloudflare Zero Trust: 接続要求時にブラウザがポップアップし、メールOTPやIdP(Google / Microsoft等)による多要素認証を実施。
- EC2インスタンス: cloudflared デーモンが常駐し、EC2内部からCloudflareエッジへ向けて外向き(アウトバウンド: TCP 443)の暗号化トンネルを常時確立。
- セキュリティグループ: インバウンドの22番ポートは不要(全閉鎖可能)。アウトバウンド(HTTPS 443)のみ疎通していれば動作します。
2. 構築手順
Step 1: Cloudflare Zero Trust 側の設定
1. トンネル(Cloudflare Tunnel)の作成
- Cloudflare Zero Trustダッシュボードから Networks > Tunnels(コネクタ)を開きます。
- Add a tunnel を選択し、Connector Type に「Cloudflared」を選びます。
- トンネル名(例: aws-ec2-tunnel)を入力し、生成されたインストールコマンド内のトークン(cloudflared service install <YOUR_TUNNEL_TOKEN>)を控えておきます。
- Public Hostname タブで公開設定を追加します:
- Subdomain: aws-ssh
- Domain: 対象ドメイン(例: example.com)
- Type: SSH(※HTTPではなく必ずSSHを選択)
- URL: localhost:22
2. アプリケーション(Cloudflare Access)の保護
- Access > Applications から Add an application > Self-hosted を選択します。
- 設定項目を入力します:
- Application name: AWS EC2 SSH
- Application domain: aws-ssh.example.com
- Policies(ポリシー) を追加します:
- Action: Allow
- Include: セレクターに Emails を選び、許可する開発者・管理者のメールアドレスを指定(Google WorkspaceやAzure ADなどのIdP連携も可能)。
- 設定を保存します。

Step 2: EC2 インスタンス側の設定(Amazon Linux 2023 / AL2)
EC2内部で cloudflared をインストールし、常駐サービスとして起動します。
1. インストール
Bash
sudo yum install -y
https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-x86_64.rpm
2. トンネルサービスの登録と起動
Step 1 で取得した <YOUR_TUNNEL_TOKEN> を指定してサービスを登録します。
<YOUR_TUNNEL_TOKEN> の取得・再確認方法
ダッシュボードのトンネル管理画面で 「コネクターを追加(Add a connector)」 を押すと、インストーラーおよびコマンド表示画面が開き、コマンド内の cloudflared service install eyJh… に続くトークン文字列を確認・コピーできます。
Bash
# トークンを指定してサービス登録
sudo cloudflared service install <YOUR_TUNNEL_TOKEN>
# サービスの起動と自動起動設定
sudo systemctl enable –now cloudflared
# 状態確認
sudo systemctl status cloudflared
Active: active (running) と表示されれば、EC2とCloudflare間のトンネル確立は成功です。
Step 3: クライアントPC(Windows)の設定
クライアント端末にも cloudflared をインストールし、OpenSSH の設定を行います。
1. cloudflared の導入
Windows(winget)の場合:
PowerShell
winget install –id Cloudflare.cloudflared
2. SSH 設定ファイル(~/.ssh/config)の構成
C:\Users\<ユーザー名>\.ssh\config に以下を追記します。
コード スニペット
Host aws-ssh.example.com
ProxyCommand cloudflared access ssh –hostname %h
User ec2-user
IdentityFile ~/.ssh/id_rsa_ec2.pem
3. 接続テストとメール認証の流れ
PowerShellから接続コマンドを実行します。
PowerShell
ssh aws-ssh.example.com
【認証が求められるタイミングと流れ】
- ブラウザの自動起動: コマンドを実行した直後、cloudflared が既定のWebブラウザを自動的にポップアップ起動します(ターミナルにも認証URLが表示されます)。
- メールアドレス入力: ブラウザ上にCloudflare Accessのログイン画面が表示されるので、Step 1 で許可設定したメールアドレスを入力してコード送信(Send code)を押します。
- PINコード入力: 受信トレイに届いた認証コード(ワンタイムパスコード)をブラウザに入力してサインインします。
- 接続完了: ブラウザに「Success! You may close this window.」と表示され、PowerShell側に自動的に制御が戻り、EC2のログインプロンプト([ec2-user@… ~]$)が表示されます。
Tips: 2回目以降の接続について
一度ブラウザ認証を完了すると、ローカル端末内にセッショントークンがキャッシュされます(有効期間はポリシー設定に依存、標準では24時間など)。有効期間内であればブラウザは開かず、コマンド実行だけで即座にSSH接続されます。
3. 実践で直面しやすいトラブルシューティング
実際に環境構築を行う際につまずきやすいポイントと解決策をまとめました。
Q1. トンネル作成後にトークン(YOUR_TUNNEL_TOKEN)を再確認したい場合は?
初期セットアップ完了後、トンネルが正常接続(HEALTHY)になると、ダッシュボードの概要画面が「コネクタの稼働ステータス一覧」に切り替わり、初期インストール用コマンドが表示されなくなります。
トークンを再確認したい場合は、「コネクターを追加」 機能を利用します。
- Cloudflare Zero Trustダッシュボードの Networks > Tunnels(コネクタ)から対象トンネルを選択します。
- 画面内にある 「コネクターを追加(Add a connector)」 ボタンをクリックします。
- 「コネクターのインストールと実行」画面が開き、各OS向けのセットアップコマンドが表示されます。
- コマンド欄に記載されている cloudflared.exe service install <TOKEN>(または cloudflared service install <TOKEN>)の eyJh… から始まる英数字の文字列 をコピーすることで、いつでもトークンを再確認できます。
Q2. EC2側で yum install がタイムアウトする
EC2上で curl や yum が Connection timed out になる場合、EC2のアウトバウンド通信が成立していません。
Cloudflare Tunnelは「EC2から外向き(443ポート)への接続」をトリガーにするため、以下を確認してください:
- パブリックIP / NATゲートウェイの有無: プライベートサブネットにある場合はNATゲートウェイ、パブリックサブネットにある場合はパブリックIPv4(またはElastic IP)が関連付けられているか。
- ルートテーブル: 0.0.0.0/0 の宛先がインターネットゲートウェイ(IGW)またはNATゲートウェイに向いているか。
- セキュリティグループ: アウトバウンドルールで HTTPS (443) または すべてのトラフィック が 0.0.0.0/0 宛てに許可されているか。
4. 最後に:セキュリティグループの22番ポートを閉鎖する
トンネル経由での接続が確認できたら、AWSマネジメントコンソールまたはAWS CLIから、EC2のセキュリティグループにあるインバウンドのSSHルール(Port 22)を削除します。
Bash
# インバウンドSSH許可ルールを削除
aws ec2 revoke-security-group-ingress \
–group-id sg-xxxxxxxxxxxxxxxxx \
–protocol tcp \
–port 22 \
–cidr 0.0.0.0/0
ポート22を外部から完全に遮断した状態でも、ssh aws-ssh.example.com で問題なくログインできるはずです。
まとめ:VPNや固定IPの制約から脱却し、ゼロトラストなインフラ運用へ
本記事では、Cloudflare Tunnel と Cloudflare Access を連携させ、EC2のインバウンド22番ポートを完全に閉鎖したセキュアなSSHアクセス環境を構築しました。
従来のSSH運用では、「接続元クライアントの固定IP手配・管理」や「全社VPN装置のコスト・運用負荷」が大きな課題になりがちでした。しかし、本構成を導入することで以下のような運用改善が実現します。
本ソリューションの導入メリット
- セキュリティリスクの劇的な低減(インバウンド完全遮断)
EC2側で外部に公開する待ち受けポートがゼロになるため、インターネット上の無差別ポートスキャンやブルートフォース攻撃を物理的に排除できます。
- クライアント側の固定IP不要・VPNレス運用
自宅や出張先、モバイル環境など動的IPの端末からでも、Cloudflare Accessのブラウザ認証(メールOTPや既存のIdP連携)によって安全にセッションを確立できます。
- 運用・インフラコストの圧縮
踏み台サーバー(Bastion)の常時稼働やVPN専用ライセンスが不要となり、メンテナンス工数とクラウドアカウントの維持費用を削減できます。
構築時の重要ポイントのおさらい
- トークンの再確認: コネクタ接続後にトークンを確認したい場合は、トンネル詳細画面で 「コネクターを追加」 をクリックして表示させる。
- 仕上げのポート閉鎖: トンネル経由の疎通確認を終えた段階で、セキュリティグループのインバウンド22番ルールを速やかに削除する。
Cloudflare Zero Trustは、Webアプリケーションの保護だけでなく、内部サーバーやインフラの管理アクセスをモダナイズする上でも非常に強力です。セキュアで柔軟なリモートアクセス環境づくりの一環として、ぜひ本構成をご活用ください。
株式会社DOMOでは、Cloudflare Zero Trustの設計・導入支援から運用サポートまで幅広く対応しております。詳細な構成や運用設計についてもお気軽にお問い合わせください。

