RasPiに外部ネットワークからSSH接続する方法

## 概要

研究で使うRaspberry Pi，フィールドに置くことが多いんだけど，測定中にネットワーク越しに接続したい。
3台までならRealVNC(<https://www.realvnc.com/en/>)がお手軽でとても良いのだけれど，それを超えると結構な額の継続出費になる。
TeamViewerはなんだか安定動作しないし，そもそも個人利用でない場合はこれも有償。

そこで色々と探していった結果，Cloudflared Zero Trust Tunnelにたどり着いた。ドメインとかレンタルサーバーとか考えると有償なんだけれども，上記のサービスに比べるとだいぶリーズナブルな気がする。

なお，素人による備忘録なので，下記手順が最も効率的かどうかは保証しない。

## ふわっとした理解

ドメインを取得し，DNSをCloudflaredのサーバーに設定する。
その上で，接続したい端末にてCloudflared Tunnelをホスト名（上記ドメインのサブドメイン）とともに設定しておくと，Cloudflared側で名前解決をしてくれて，外部ネットワークから接続できるようになる。

ただし，実際には，外部ネットワークから端末に向けて接続をしているのではなくて，端末から外部ネットワークに向けて接続しているので，ファイアウォール等を突破できる。このあたりの仕組みはTeamViewerと同じ。

## ドメイン取得

ともかくドメインの取得。サーバーも必要。

素人の私は，業界最大手という名に負けてXServerでレンタルサーバーもドメインも合わせて契約。分けるのも面倒だし。10日間の無料期間があるので（時期によって違うかもしれない），その間に動作確認可能。無料期間が終了したらスタンダードプランで1000円/月程度。

https://www.xserver.ne.jp/

ちなみに，`jtagu.net`というドメインを取得してみた。
目的としては，`koguma.jtagu.net`というアドレスで，Raspberry Piに接続したい。

## Cloudflare アカウント取得／DNS設定

ここからサインアップ。

https://www.cloudflare.com/ja-jp/

「ドメインを追加」で上記のドメインを選ぶと，DNSのアドレスが出てくるので，それをXServerのドメイン管理ページの「ネームサーバー設定」に打ち込む。

この設定が反映されるまで，数時間かかる。

## Zero Trust 設定

Cloudflareのサイトのタブに「Zero Trust」というのがあるので，そこからアカウントを設定する。

ちなみにZero Trustに入るともはや日本語サイトは消え失せる。

とりあえずは無料の「Free」で良いと思われる。ただし，0円でも支払方法の登録（＝クレジットカードの登録）が必要。

下の図はRaspberry Piを1台登録した後のスクショなので，もしかして，もしかしなくてもFreeで50台まで登録できるのだろうか…？ちなみにStandardプランだと$7/seat/month，となっている。（この価格ならRealVNCの方が良いと思う）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3617623/b07e8a3a-f345-6e18-c1fd-793dfb939f0e.png)

## Tunnel 設定

Raspberry Pi本体で，下記手順を行う。
なお，大前提として，SSHを有効にしておく必要がある。（これを忘れると，tunnelで接続した際に，真っ黒な画面が出る。エラーは出ないので原因に気づきにくい。）

https://zenn.dev/kmiura55/articles/cloudflare-connect-raspberrypi

基本このままだけど，一応手順を書いておく。

### Cloudflared をインストール

<https://github.com/cloudflare/cloudflared/releases>を確認して，`wget`，`apt install`

```bash
wget https://github.com/cloudflare/cloudflared/releases/download/2023.3.1/cloudflared-linux-armhf.deb
sudo apt install ./cloudflared-linux-armhf.deb
```

### ログイン認証

以下のコマンドでCloudflareにログインし，登録してあるドメインを選択する。

```bash
cloudflared tunnel login
```

### トンネル作成

以下のコマンドでトンネル`kumatunnel`が作成される

```bash
cloudflared tunnel create kumatunnel
```

また，すでに作成されたtunnelについて確認するには以下のコマンド

```bash
cloudflared tunnel list
```


これを行うと，`~/.cloudflared/hinna-hinna-uma-uma.json`の様なファイルが生成される。これがトンネルの認証情報で，`hinna-hinna-uma-uma`の部分がトンネルのID。

既存のtunnelについてcredentials(`foo.json`)を作成するときには，次のようにする

```bash
cloudflared tunnel token --cred-file foo.json kumatunnel
```


そうしたら，`~/.cloudflared/config.yml`という設定ファイルを作成する。

```yaml
tunnel: kumatunnel
credentials-file: /home/hoge/.cloudflared/hinna-hinna-uma-uma.json

ingress:
        - hostname: koguma.jtagu.net
          service: ssh://localhost:22
        - service: http_status:404
```

で，tunnelとDNSを紐づけて，走らせる。

```bash
cloudflared tunnel route dns kumatunnel koguma.jtagu.net
cloudflared tunnel run kumatunnel
```

これで，ターミナルで`kumatunnel`が走って，（下記の適切な設定が出来ていれば，）`koguma.jtagu.net`からアクセスできる。

ただし，この方法では，ターミナルでコマンドを実行しない限り，待ち状態にはならない。
公式で，サービスとして登録する方法が登録されている。

```bash
sudo cloudflared --config /home/hoge/.cloudflared/config.yml service install
```

ここで，`config`オプションで`config.yml`の位置を指定しているのがポイント。
次いで，以下のコマンドでサービスに登録できる。

```bash
sudo systemctl start cloudflared
```

## ブラウザからSSHできる様にする

これもまんまココのやり方を踏襲。

https://zenn.dev/kmiura55/articles/cloudflare-connect-raspberrypi


### アプリケーションの追加

Zero Trust -> Access -> アプリケーション -> +アプリケーションを追加する

セルフホストを選択

### 基本設定

- 基本情報
    - アプリケーション名: koguma
    - セッション時間: 24 hours
    - パブリックホスト名
        - 入力方法: デフォルト
        - サブドメイン: koguma
        - ドメイン: jtagu.net
        - パス: 空欄
- Access ポリシー
    - 既存のポリシーを選択
    - （初めての時には新しいポリシーを作成）

以降はデフォルトで「次へ」

### エクスペリエンス設定

- アプリケーションの外観: デフォルト
- タグ: デフォルト
- カスタムページ: デフォルト

「次へ」

### 詳細設定

- CORC設定
    - Access-Control-Allow-Origin: 全てのオリジンを許可する
    - Access-Control-Allow-Method: 全てのメソッドを許可する
- Cookie設定: デフォルト
- ブラウザレンダリング設定: ssh

これで，「保存」

### Access groups 設定

上記のサイトでは省略されているけど，先にアクセス可能なグループを定義しておかないといけない。

Cloudflare Zero Trust の `Access -> Access groups` から， `Add a Group` を押して，適当なグループを作成する。
とりあえず，メールアドレス定義で，自分だけ入ったグループを作成した。

### Applications 設定

完全にここの通りなので省略

https://zenn.dev/kmiura55/articles/cloudflare-connect-raspberrypi


## できた！

とりあえずできた！
あとは，Tunnelをサービス登録しておくことと，セキュリティ周りのアレコレを確認しておくこととかかな。

費用はレンタルサーバー・ドメインの分だけ！

SSHが出来るということはRDPもできるということなので，まあそれは今後考えましょう。

## VNC接続はできるのか？

結論：まだ出来ていない。

ココを参照してラズパイのVNCを許可

https://qiita.com/kanamekun/items/100b815741c8eefaa5ec#5-windows-pc%E3%81%8B%E3%82%89vnc%E6%8E%A5%E7%B6%9A%E3%81%AE%E3%83%86%E3%82%B9%E3%83%88

`sudo raspi-config`で設定画面を出して，

"3 Interface Options" -> "P3 VNC" -> "Yes" -> "OK" -> "Finished"

それから，`sudo nano /etc/vnc/config.d/common`で設定ファイルを開いて，`Authentication=VncAuth`を追記。
`sudo vncpasswd -service`でパスワードを設定して，`sudo reboot`で再起動。

で，`tightvncserver`を入れて，サービスとして立ち上げる。

tunnelの`config.yml`にこのサービスを追記すればよい，と思うんだけどうまくいかない。

## データのやり取り

Rcloneがよいのか？

https://qiita.com/ytetsuo/items/686c9b80aafbf4077222