(ネタ)ngrok × 高火力DOKでSSH接続してみた

## はじめに

高火力 DOKにngrok経由でSSH接続する**ちょっとしたネタ記事**です。

本記事では高火力 DOKに「SSHをインストールしたDockerコンテナ」デプロイし、ngrokのトンネルを使って外部から操作できるようにします。開発中の一時的なデバッグや外部からの実験環境アクセスに便利です。

:::note warn
本記事ではセキュリティを厳密に考慮していません。  
rootログインの禁止設定や公開鍵認証、ファイアウォール制限などは省略しています。  
あくまで**一時的な開発・検証用途としての利用**を想定しています。本番環境や公開環境への応用は自己責任でお願いします。
:::

高火力 DOKは、さくらインターネットが提供するコンテナ型GPUサービスです。
https://www.sakura.ad.jp/koukaryoku-dok/

## 前提

この手順を試すには、以下のアカウントが必要です：

- 高火力 DOKのアカウントを持っている
  - 参考: [サービスを使い始めるには（公式マニュアル）](https://manual.sakura.ad.jp/cloud/koukaryoku-container/getting-started.html#id11)

- ngrokのアカウントを持っている
  - https://ngrok.com/ 　
  - ※**クレジットカードの登録が必要**です
- コンテナイメージをレジストリにアップロードできる環境
（例: Dockerhub, さくらのコンテナレジストリ）を持っている

## ngrokのトークンを取得
ngrokを利用するには、トークンが必要です。以下の手順で取得します。

https://dashboard.ngrok.com/ にアクセスし、サイドバーのYour Authtokenを選択します。
中央にあるYour Authtokenをメモしておきましょう。
![ngrok token.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282233/e1e53444-5485-62bb-c520-71a3fa8fab18.png)

## Dockerイメージのビルド&プッシュ

SSHとngrokを含んだDockerコンテナを作成するため、Dockerfileとentrypoint.shを準備します。
- ディレクトリの構成
```bash
.
├── Dockerfile
└── entrypoint.sh
```

-  Dockerfileの作成
```Dockerfile
FROM nvidia/cuda:12.5.1-runtime-ubuntu22.04
ENV DEBIAN_FRONTEND=noninteractive

# Build-time variables
ARG USERNAME=nguser
ARG PASSWORD='N9v#r3Tz!xQ7'

# 必要なパッケージをインストール
RUN apt-get update && \
    apt-get install -y openssh-server sudo curl

# SSHの初期設定
RUN mkdir /var/run/sshd && \
    sed -i 's/^#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config && \
    sed -i 's/^#PasswordAuthentication yes/PasswordAuthentication yes/' /etc/ssh/sshd_config && \
    echo 'PermitEmptyPasswords no' >> /etc/ssh/sshd_config

# 一般ユーザー作成 + sudo 権限
RUN useradd -m -s /bin/bash "$USERNAME" && \
    echo "$USERNAME:$PASSWORD" | chpasswd && \
    usermod -aG sudo "$USERNAME" && \
    echo "$USERNAME ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers

# ngrok インストール
RUN curl -sSL https://ngrok-agent.s3.amazonaws.com/ngrok.asc \
  | tee /etc/apt/trusted.gpg.d/ngrok.asc >/dev/null && \
  echo "deb https://ngrok-agent.s3.amazonaws.com buster main" \
  | tee /etc/apt/sources.list.d/ngrok.list && \
  apt-get update  && \
  apt-get install -y ngrok && \
  apt-get clean && \
    rm -rf /var/lib/apt/lists/*

# entrypoint.shのコピー
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh

# ポートを公開
EXPOSE 22

# コンテナ起動時にentrypoint.shを実行
CMD ["/entrypoint.sh"]

```

- entrypoint.shの作成
```
#!/bin/bash

# ngrok authtoken 設定（初回のみ必要）
ngrok authtoken "$NGROK_AUTHTOKEN"

# SSH 起動
/usr/sbin/sshd

# ngrok でトンネル開始（ポート22）
ngrok tcp 22 --log stdout
```

### イメージのビルド
```
docker build --platform linux/amd64 -t example.sakuracr.jp/cuda-ssh-ngrok:latest .
```

### イメージのプッシュ
```
docker push example.sakuracr.jp/cuda-ssh-ngrok:latest
```

## 高火力DOK
### コンテナの起動
高火力 DOKのダッシュボードにアクセスし、
サイドバーから「タスク」を選択したのち「新規作成」を選択します。
![dok tasks.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282233/0066efea-cb4f-6aa0-81fc-45c683fa081e.png)

タスク作成画面では、以下の情報を入力します。
| 項目 | 設定 |
|:-----------|:------------|
| イメージ    | example.sakuracr.jp/cuda-ssh-ngrok:latest|
| 環境変数   | NGROK_AUTHTOKEN:ngrokのトークン|

![dok_task.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282233/b6c3e7dc-4292-4c60-a8bb-dc7d3572512b.png)

作成ボタンを押し、コンテナが起動するまで待ちます。

状態が「実行中」になったら、「ログを表示」をクリックします。
![dok_log.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282233/63bea51c-0efa-49f5-b5c2-e276b09cd33e.png)


以下ログが見えたら起動完了です。
```
msg="started tunnel" obj=tunnels name=command_line addr=//localhost:22 url=tcp://0.tcp.jp.ngrok.io:11462
```
![スクリーンショット 2025-06-08 13.22.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282233/65a38032-e307-4aef-8094-d0b77ae7aac2.png)

## SSH接続
クライアントから、以下のようにSSHを行います。
```
ssh {USERNAME}@0.tcp.jp.ngrok.io -p <ポート>

例： 
$ ssh nguser@0.tcp.jp.ngrok.io -p 11462
nguser@0.tcp.jp.ngrok.io's password:
Welcome to Ubuntu 22.04.4 LTS (GNU/Linux 5.15.0-131-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/pro

This system has been minimized by removing packages and content that are
not required on a system that users do not log into.

To restore this content, you can run the 'unminimize' command.
Last login: Sun Jun  8 04:28:07 2025 from ::1
To run a command as administrator (user "root"), use "sudo <command>".
See "man sudo_root" for details.

nguser@05349b6a-a7a7-4f9d-a676-ccac19404012:~$
```

Yatta!!!🎉
あとは必要に応じて apt install で開発ツールを追加したり、
VSCode SSH接続などにも応用できます！

### 終わるとき
:::note warn
停止を忘れると従量課金されていくので忘れずに停止しましょう
:::
高火力 DOKのダッシュボードにアクセスし、
サイドバーから「タスク」を選択したのち、今回使用したタスクを選択します。
![dok task select.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282233/fc88942b-8275-d929-9f7b-ae2a14a8e2cc.png)
タスク詳細画面から「中断」を選択します。
![dok kill.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282233/36c21d9b-b3f3-a27d-a2c8-5c663a7be24b.png)

## まとめ
この記事では、高火力DOKにngrok経由でSSH接続する手順を説明しました。

ここまで読んでいただきありがとうございました


## 参考
- [SSH接続可能なDockerコンテナの作成方法](https://zenn.dev/hoshi_ophiuchus/articles/5a96de1a0fbf0f)
- [ローカルTCPサーバをインターネットからアクセス - ngrok](https://qiita.com/shokkaa/items/a33b089c082625557195)
- [高火力 DOK ドキュメント](https://manual.sakura.ad.jp/cloud/manual-koukaryoku-container.html)