Cloudflare Zero Trust Tunnel を利用して自宅の Ubuntu 機にインターネット経由で SSH 接続する
Cloudflare の Zero Trust Tunnel という機能を利用して、自宅の Ubuntu 機にインターネット経由で SSH 接続できるようにする。
Cloudflare が提供するネットワークに乗って VPN トンネルを作る感じになるので、昔ながらの「自宅サーバ」のようにルータ設定をいじくって22番ポートを開放したりする必要はない。
ただ、Cloudflare の設定画面などが頻繁に変わっており、ネット上のどの記事を参考にすれば良いか中々分かりづらかった。コマンドライン (cloudflared
コマンド) で設定を完結できそうではあるが、今回は Cloudflare の Web コンソールを使っての作業手順としてまとめる。
前提 : 所有ドメインの DNS を Cloudflare で管理するようにしておく
前提として、自分が所有する独自ドメインがあること。そしてそのドメインの DNS 設定を Cloudflare 上で行えるようにしておく必要がある。
自分の場合は Value-Domain で取得したドメインがあり、コレまでは Value-Domain の DNS 設定を利用していたので、Cloudflare の Web コンソールにて「ドメインの登録」というモノを行った。
具体的には、ブラウザで Cloudflare のダッシュボードにログインしたら、左メニューの「ドメイン登録」→「ドメインの登録」を選択する。
ココで所有するドメインを入力すると、自動的に現在の DNS 設定を引っ張ってきてくれる。
あとは Value-Domain 側に、Cloudflare 指定のネームサーバを2つ設定してやり、変更反映を待つ。そうすると DNS 設定を Cloudflare 上で出来るようになる。なお、Value-Domain の管理画面からは「DNS 設定」の項目が消える。
ココら辺は画面の指示に従ってやっていくだけですんなり実施できた。
サーバ側に cloudflared
をインストールする
まずは SSH 接続したい Ubuntu マシンに cloudflared
コマンドをインストールする。
$ sudo mkdir -p --mode=0755 /usr/share/keyrings
$ curl -fsSL https://pkg.cloudflare.com/cloudflare-main.gpg | sudo tee /usr/share/keyrings/cloudflare-main.gpg >/dev/null
$ echo "deb [signed-by=/usr/share/keyrings/cloudflare-main.gpg] https://pkg.cloudflare.com/cloudflared $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/cloudflared.list
$ sudo apt-get update && sudo apt-get install -y cloudflared
$ cloudflared --version
cloudflared version 2025.1.0 (built 2025-01-07-1219 UTC)
そしたら Zero Trust Tunnel を構築するためのログインを行う。
$ cloudflared tunnel login
ブラウザが開くと思うので、適宜 Cloudflare にログインする。
Web コンソールでトンネルを設定していく
この後、コマンドラインでは $ cloudflared tunnel create
したり config.yml
を書いたり $ cloudflared tunnel route dns
コマンドを叩いたり…という感じで進めていくのだが、ちょっとよく分からなくなったので、Cloudflare の Web コンソールで設定をやり直した。
- ブラウザで Cloudflare のダッシュボードにログインしたら、左メニューの「Zero Trust」を選ぶ
- 次に左メニューの「ネットワーク」→「Tunnels」と進み、「トンネルを作成する」ボタンを押す
- トンネルの種類は「cloudflared」を選ぶ
- トンネル名を適当に名付けて保存する
- 「コネクタをインストールして実行する」というところで、「Debian」向けの設定を確認する。「すでにマシンに cloudflared がインストールされている場合」というところに、おおよそ以下のようなコマンドが書かれているのでコレをまるっとコピーする
$ sudo cloudflared service install 【ランダムな文字列】
- このコマンドを SSH 接続したいマシンで実行し、Cloudflare とのトンネル接続を確立しておく
ココまでで初期設定は完了。
続いて、「パブリックホスト名の設定」で、どういうサブドメインにアクセスした時に SSH 接続するか、という設定を行う。
- サブドメイン : 任意
- ドメイン : 「前提」として Cloudflare 管理したドメイン名 (登録が成功していればプルダウンに自動的に表示される)
- タイプ : 「SSH」を選択する
- URL : ココが分かりにくかったが、「localhost:22」と指定すれば良い
その他の設定は変更不要。コレでパブリックホスト名を保存すれば OK。
最後にプライベートネットワークを指定しておく。自分は適当に 192.168.1.0/24
という CIDR で登録しておいた。正直よく分からん。w
以上で、トンネル設定が完了した。ココまでの設定で、DNS 設定の中に指定したサブドメインに対するレコードが自動的に追加されているはずだ。
アプリケーション設定を行う
引き続き、左メニューの「Access」→「アプリケーション」に進み、「アプリケーションを追加する」から設定を行っていく。
- 「セルフホスト」を選ぶ
- アプリケーション名 : 任意
- セッション時間 : 任意で設定する
- アプリケーションドメイン : 先程設定した「サブドメイン」と「ドメイン」を設定する
「次へ」と進み、各種設定を進める。
- 「ポリシー」タブ
- アクション : 「Allow」
- ルールを構成する … 包含 (Include) : セレクターで「Everyone」を選んでおく
- コレで保存する
- 「認証」タブ
- 特にイジらず
- 「設定」タブ
- ブラウザレンダリング : 「SSH」を選択する
最後の「ブラウザレンダリング」で SSH を選択しておくと、https://sub.example.com
にブラウザでアクセスした時に SSH 接続ができるようになる。
コレで、指定のサブドメインに対するアクセスの認証設定などが出来た。
クライアント PC から ssh
コマンドで接続を試してみる
さて、それではクライアント PC から ssh
コマンドで接続してみる。ちょっと面倒だが、クライアント PC にも cloudflared
コマンドのインストールが必要なので、そこだけ留意。今回は WSL Ubuntu で実施したので、前述のサーバ側でのインストール手順と同じモノを利用した。
cloudflared
コマンドがインストールできたら、~/.ssh/config
を次のように設定する。
Host sub.example.com
HostName sub.example.com
Port 22
User username
IdentityFile ~/.ssh/example
ProxyCommand /usr/local/bin/cloudflared access ssh --hostname %h
このように準備したら、$ ssh sub.example.com
コマンドで接続する。初回のみ、ProxyCommand
に書いたとおり cloudflared
コマンドを経由してログイン認証を求められるかと思うので、起動したブラウザに従ってログイン認証を行う。
コレで Cloudflare Zero Trust Tunnel 経由で SSH 接続ができるはずだ。
ブラウザレンダリングの SSH 接続を試してみる
最後に、ブラウザレンダリングの SSH 接続を試す。ココでちょっとつまづいた。
SSH 接続するサーバ側の、/etc/ssh/sshd_config
ファイルで次のように設定しておく。特に PubkeyAcceptedAlgorithms
がないと、秘密鍵・パスワードの形式が合わないとしてエラーになってしまうので入れておく。
# root ユーザでのログインを禁止する
PermitRootLogin no
# パスワード認証を無効にする
PasswordAuthentication no
# 公開鍵認証を有効にする
PubkeyAuthentication yes
# ssh-rsa 方式の公開鍵を許可する
PubkeyAcceptedAlgorithms +ssh-rsa
設定をしたら $ sudo systemctl restart ssh
で設定変更のため再起動する。
で、ブラウザで https://sub.example.com
にアクセスしてみると、Cloudflare が用意したログインページが開く。まずは SSH 接続したいユーザ名を入力する。
そして次の画面で、SSH 接続に利用する「SSH 秘密鍵」をペーストする。パスワード欄は、SSH 秘密鍵のパスフレーズを入れてなければ空欄で良い。
コレでブラウザレンダリングの SSH 接続ができるはずだ。
以上
いやー思ったよりも設定ダルかったな…。終わってしまえば仕組みは分かるけど、なかなか再現性のある手順でまとめるのはめんどくさい。w