ブログ一覧に戻る

【Cloudflare Tunnel】ポート開放不要のSSHセットアップ

9 min read
CloudflareTunnelsshInfra

はじめに

どうも、Caruです!

Cloudflare Tunnelを使うと、サーバーの22番ポートを外に公開せずにsshできるのでかなり便利です。 ここ最近は開発サーバーでコーディングエージェントを動かすのが割と流行ってきましたが、Tailscaleやポート開放など様々な方法を目にすると思います。 便利さ優先で雑に公開すると普通に危ないので、最初から安全にセットアップすることをおすすめします。

今回は、私が普段使っている「Cloudflare Tunnel前提のsshセットアップ」をまとめます。

全体像は次の図の通りで、クライアントとサーバーの間にCloudflareネットワークを挟む構成です。

Cloudflare Tunnel経由でSSH接続する構成図

まずはこの設定

Cloudflare OneでNetwork→Connectors→tunnelsでサーバーのTunnelを開いて、sshのホストをPublished application routesに追加します。

このとき、Tunnel側で ssh://localhost:22 のようにssh先へ到達する経路を作成します。

Tunnelのセットアップがまだの場合、Create a tunnelから、ガイドに従って作成します。

setup published route on cloudflare one

~/.ssh/config に以下を追加します。

Host dev-ssh
  HostName dev-ssh.example.com
  User user
  IdentityFile ~/.ssh/id_ed25519
  IdentitiesOnly yes
  ProxyCommand cloudflared access ssh --hostname %h

接続はいつも通り。

ssh dev-ssh

アクセス制御を設定(任意)

ポリシー設定

エンドポイントへのアクセス制御を行いたい場合、まずはポリシーから作成します。

  1. Access Controls→Policies→Add a policy から追加
  2. 画像のように設定
  3. メールアドレスは自分のものに変更
Set up policy on cloudflare one

アプリケーションの作成

Access Controls→Create Applications→Self Hostedから作成します。

Set up access control on cloudflare one

ブラウザでsshコンソールを表示できる機能を有効にする場合は、 Browser rendering(または同等の SSH terminal 項目)を Disabled から SSH に変更します。

毎回メール認証が面倒な場合は、OAuthログインを設定すると便利です。

ProxyCommand

Cloudflare Tunnel経由のsshは、普通のTCP直結ではなく、cloudflared が中継役になります。 ProxyCommand を指定することで、Cloudflareネットワーク経由での接続となるので、ポート公開が不要になります。

また、Cloudflare Accessの認可機能も利用できるので、sshを安全に公開できます。

設定は次の1行です。

ProxyCommand cloudflared access ssh --hostname %h
  • cloudflared access ssh: Cloudflare Accessを使ったssh用の接続
  • --hostname %h: HostName で指定したホスト名をそのまま渡す

この1行がないと、Cloudflare Tunnelにsshを正しく流せません。

各設定のポイント

HostName

Cloudflare側に生やしている公開ホスト名を指定します。

ssh. のような分かりやすい名前はスキャンノイズを受けやすいので、避けるのは有効です。 ただしこれは補助的な対策で、本質はAccessポリシーと鍵管理です。

例では dev-ssh.example.com です。

IdentityFile

普段使っている秘密鍵を明示しておくと、鍵の取り違えを防げます。 鍵を複数持っている環境では特に効果的です。 IdentitiesOnly yes も併用すると、指定した鍵以外を試さなくなるのでより安全です。

Host のエイリアス

Host dev-ssh のように短い名前を付けておくと、毎回長いホスト名を打たずに済みます。 日常運用ではこの差が地味に効きます。

ProxyCommand のパス

cloudflared がPATHに通っていれば、以下のようにコマンド名だけで動かせます。 環境差分を減らせるのでこの書き方がおすすめです。

ProxyCommand cloudflared access ssh --hostname %h

もしPATHに通っていない環境なら、絶対パス指定にしてください。

よくあるハマりどころ

cloudflared: command not found

ProxyCommand のパスが違うケースです。 which cloudflared で実体を確認して、~/.ssh/config に絶対パスで書くと安定します。

認証まわりで失敗する

Cloudflare Accessのルール次第です。 構成によっては追加認証なしでそのまま接続できますし、ポリシーによっては cloudflared access login <sshホスト> が必要になります。 「認証が必須」とは限らないので、まずは自分のAccessルールを確認してください。

鍵が違って弾かれる

IdentityFile を明示していないと、別の鍵が先に試されることがあります。 対象ホストごとに IdentityFile を固定し、IdentitiesOnly yes を付けるのがおすすめです。

REMOTE HOST IDENTIFICATION HAS CHANGED! が出る

known_hosts に保存されたホスト鍵と、今回接続先の鍵が一致しないと発生します。 接続先サーバーが正しいことを確認したうえで、対象エントリを削除して再接続してください。 (例: ssh-keygen -R ssh.example.com

GitHubで公開鍵を管理すると楽

複数サーバーを運用しているなら、公開鍵をGitHubで一元管理するとかなり楽です。

GitHub→Settings→SSH and GPG keys→New SSH keyで追加できます。

メリット

  • Ubuntu Serverの初期セットアップでインポート元として使用できる
  • ssh-import-id gh:<user-name> でGitHub上の公開鍵を取り込める
  • https://github.com/<user-name>.keys で公開鍵一覧をそのまま取得できる

サーバー初期セットアップ時に、authorized_keys へ手でコピペする作業を減らせます。

Tailscaleとの違い

「これ、Tailscaleでもよくない?」というのはかなり自然な疑問です。 実際どちらも便利なので、私は用途で使い分けています。

  • Cloudflare Tunnel: Accessポリシー付きで公開しやすい(クライアントの cloudflared とTunnelコネクタ運用は必要)
  • Tailscale: プライベートネットワークを組んで、メンバー内だけで閉じたsshをしやすい、WebUIが使いやすい

どちらが上というより、アクセスさせたい相手と運用ポリシーで選ぶのが正解です。

補足すると、Cloudflare Tunnelはクライアント配布が比較的シンプルです。 初回に cloudflared~/.ssh/config を設定すれば、あとは通常の ssh <alias> で接続できます。 VPNメッシュへの参加管理を減らしたいケースでは、この運用の軽さが利点になります。

まとめ

私が普段使っているsshセットアップを紹介しました。

Cloudflare Tunnel + ProxyCommand + 鍵管理(GitHub連携)まで含めてセットアップしておくと、普段の接続体験を落とさずに安全性を上げられます。

参考になったよという方は、Xのフォローやシェアをもらえると嬉しいです!

この記事を書いた人

Caru

Caru

エンジニアを目指す大学生。20歳。
東洋大学情報連携学部(INIAD)所属(28卒)。