Cloudflareを使ってポート開放せずにSSHする

# まえがき

この記事は https://qiita.com/advent-calendar/2023/nihon-u の記事です。

記事名にもある通り、Cloudflareを用いてSSHできるようにしていきます。
これを用いれば、ポート開放できない方もSSHを行うことができます。

CloudflareのZero Trustという機能を使用します。

# 実際にやってみる

必要なものは以下の通りです。

- Cloudflareのアカウント
- 自分のドメイン

ドメインはお名前ドットコム等で数百円で取れます。

今回はEC2のインスタンスで設定を行います。

## Cloudflareにドメイン登録

Cloudflareのページのホームに行きます。

https://dash.cloudflare.com/

すでにWebサイトというタブにいると思います。

そしたら、右のほうにある「サイトを追加する」を押して取得したドメインを追加します。

ドメインを入力して続行を押すとプランが表示されると思いますが、下のほうにあるFreeで続行します。

そしたら、DNSレコードを確認すると出ます。そのまま続行すると、ネームサーバーを変更するとでるので、案内通りに設定を行います。今回はお名前ドットコムでドメインを取得したので、お名前ドットコムでDSNレコードの設定を行います。

お名前ドットコムの場合は以下を参考してください。

https://www.onamae.com/guide/p/67#:~:text=%E4%BB%96%E7%A4%BE%E3%83%AC%E3%83%B3%E3%82%BF%E3%83%AB%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC%E3%83%BB%E3%81%8A%E5%AE%A2%E6%A7%98%E7%8B%AC%E8%87%AA%E3%81%AE%E3%83%8D%E3%83%BC%E3%83%A0%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC%E3%81%AB%E3%81%A6%E9%81%8B%E7%94%A8%E3%81%99%E3%82%8B%E5%A0%B4%E5%90%88

設定したら、そのまま画面を進めてください。
クイックスタートで常にHTTPSを有効にしておきましょう。

設定の反映まで時間がかかることがありますが、待ちます。

## Zero Trustの設定

反映されたらダッシュボードに戻って、Zero Trustのタブに移動します。

Access->TunnelsでCreate a tunnelを押します。

名前を決めて案内通りに進めると、Cloudflaredのインストールとその設定を促されるので、自分の環境を選択してそのままコマンドをコピペします。

今回はAmazon Linux2023なので、RedHatのコマンドで行いました。

```
$ curl -L --output cloudflared.rpm https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-x86_64.rpm &&

sudo yum localinstall -y cloudflared.rpm &&

sudo cloudflared service install eyJhIjoiN2I1M2FlY2I2ZjVmZDY3MDJmYTQ1ODk1OWM2OWU1NWIiLCJ0IjoiYzFkMjFhYjktM2U1Ny00Mjk4LWFiOWYtZjQ1YjU3NmQ3ZDdmIiwicyI6Ik9HWTVaV00xTkRRdE16azJNUzAwT1RjNUxXRmpZV1V0TVRnME5qUTFZVEkzTkROaSJ9
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
100 16.8M  100 16.8M    0     0  10.8M      0  0:00:01  0:00:01 --:--:-- 21.1M
Last metadata expiration check: 0:01:40 ago on Thu Nov 16 18:11:33 2023.
Dependencies resolved.
========================================================================================================================
 Package                      Architecture            Version                       Repository                     Size
========================================================================================================================
Installing:
 cloudflared                  x86_64                  2023.10.0-1                   @commandline                   17 M

Transaction Summary
========================================================================================================================
Install  1 Package

Total size: 17 M
Installed size: 35 M
Downloading Packages:
Running transaction check
Transaction check succeeded.
Running transaction test
Transaction test succeeded.
Running transaction
  Preparing        :                                                                                                1/1
  Installing       : cloudflared-2023.10.0-1.x86_64                                                                 1/1
  Running scriptlet: cloudflared-2023.10.0-1.x86_64                                                                 1/1
  Verifying        : cloudflared-2023.10.0-1.x86_64                                                                 1/1

Installed:
  cloudflared-2023.10.0-1.x86_64

Complete!
2023-11-16T18:13:14Z INF Using Systemd
2023-11-16T18:13:16Z INF Linux service for cloudflared installed successfully
```

できたら、以下のようなPublic Host Nameを追加します。ドメインは先ほど登録したものを入れます。
サブドメイン(とパス)はお好みで。

![スクリーンショット 2023-11-17 035619.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2919041/a1782a2f-710b-77be-0104-1e00776afbd1.png)

これが設定できた時点で、とりあえずSSHはできます。

ただし、パスワードでのSSHを許可する必要があります。

```bash
$ vim /etc/ssh/sshd_config
```

```diff
- PasswordAuthentication no
+ PasswordAuthentication yes
```

```bash
$ systemctl reload sshd
```

## クライアントの設定

まず、cloudflaredをインストールします。

https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/downloads/

そしたら起動します。

```bash
# 起動
systemctl start cloudflared

# 自動起動有効化
systemctl enable cloudflared

# 確認
systemctl status cloudflared
```

.ssh/configに以下のような設定をします。

```
Host {なんでも}
  User {ユーザー名}
  HostName {さっき決めたドメイン}
  ProxyCommand /opt/homebrew/bin/cloudflared access ssh --hostname %h
```

ProxyCommandのcloudflaredのパスを自分の環境のものに合わせます。

以下のコマンドで探せます。

```bash
which cloudflared
# AURからインストールの場合
/usr/sbin/cloudflared
```

これでパスワードからのsshができるようになりました。

```bash
ssh {なんでも}
```

## セキュリティについて

さて、ここで勘のいい~~ガキ~~方はパスワード認証だけで大丈夫？と感じたことでしょう。

ここで、もうひと手間設定します。

まず、Zero Trustのページ内でAccess->ApplicationsタブでAdd an applicationをクリックします。

そしたらSelf-hostedを選択、Application nameを適当に決めて、先程と同じApplication domainを入力します。
Nextを押したら、適当にPolicy nameを決めて、認証を送信するメールアドレスを入力します。

![スクリーンショット 2023-11-17 035907.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2919041/5c420bea-7297-5acb-a621-05d5257678ba.png)

Add includeでGitHub等の認証を追加できます。(後々、補足します)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2919041/16976739-8099-e03f-3124-0496636d9e3d.png)

Nextを押し、Additional settingsを次のようにしたら、アプリケーションを追加して終了です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2919041/ea6412a9-5074-b0cf-d74e-3a676b20f29e.png)

すこし反映に時間がかかります。

反映されると、SSHするときに以下のようになります。

```
~
❯ ssh ec2-zt
Please open the following URL and log in with your Cloudflare account:

https://ec2.example.com/cdn-cgi/access/cli?aud=a1b64a2b0e691ab24172076c79fe47eed824bebfc250b49380dbfa8ecc68538a&edge_token_transfer=true&redirect_url=https%3A%2F%2Fec2.runfunrun.info%3Faud%3Da1b64a2b0e691ab24172076c79fe47eed824bebfc250b49380dbfa8ecc68538a%26token%3Do8KSr9h-Tjmg0CCSRzh2aW5Gt412A8xjH3akNb8G608%253D&send_org_token=true&token=o8KSr9h-Tjmg0CCSRzh2aW5Gt412A8xjH3akNb8G608%3D

Leave cloudflared running to download the token automatically.
```

ここのリンクにアクセスして、認証したらパスワードが入力できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2919041/c36404c8-e9ab-154e-66f1-f77ecfdb8aef.png)

```
~
❯ ssh ec2-zt
Please open the following URL and log in with your Cloudflare account:

https://ec2.example.com/cdn-cgi/access/cli?aud=a1b64a2b0e691ab24172076c79fe47eed824bebfc250b49380dbfa8ecc68538a&edge_token_transfer=true&redirect_url=https%3A%2F%2Fec2.runfunrun.info%3Faud%3Da1b64a2b0e691ab24172076c79fe47eed824bebfc250b49380dbfa8ecc68538a%26token%3Do8KSr9h-Tjmg0CCSRzh2aW5Gt412A8xjH3akNb8G608%253D&send_org_token=true&token=o8KSr9h-Tjmg0CCSRzh2aW5Gt412A8xjH3akNb8G608%3D

Leave cloudflared running to download the token automatically.
ec2-user@example.com password:
   ,     #_
   ~\_  ####_        Amazon Linux 2023
  ~~  \_#####\
  ~~     \###|
  ~~       \#/ ___   https://aws.amazon.com/linux/amazon-linux-2023
   ~~       V~' '->
    ~~~         /
      ~~._.   _/
         _/ _/
       _/m/'
Last login: Thu Nov 16 18:52:03 2023 from 127.0.0.1
[ec2-user@ip-172-31-12-8 ~]$

```

このように設定することで、パスワードを知られたとしても、不正なアクセスは防げます。

ちなみにこの設定を行うと、先ほど設定したドメインにブラウザでアクセスすれば、ブラウザ上でターミナルが開けてしまいます。

もし心配な方がいれば、以下の記事を参考に鍵の設定をしてみてください。

https://developers.cloudflare.com/cloudflare-one/identity/users/short-lived-certificates

## 補足: GitHub等で認証するには

Zero Trust内のSettingにあるAuthenticationタブから追加できます。Add newでログインメソッドを追加してください。わかりやすい案内がついているので、簡単にできると思います。

追加したら、Applicationsタブで設定を変えてください。該当アプリケーションをクリックするとConfigureと出ますので、その中のPoliciesのConfigureから再設定できます。

# おわりに

自分はこの方法で、メイン環境(Arch Linux on WSL2)に外出先でMacBookからSSHしています。
たまに動作が鈍いですが、cloudflaredを再起動するのがおすすめです。コーティングならVSCodeからSSHするのがおすすめです。

また、Zero Trustはポートの転送がメインの機能だと思うので、気軽にセルフホスト等を行えて非常に便利ですので、SSH以外の機能も使ってみてはいかがでしょうか？

最後までお読みいただき、ありがとうございました。