個人的に使用しているadblockアプリのブログにて、 QUICプロトコルに対応したと言う内容を見かけたのでQUICについて調べていた所、 QUICプロトコルを通してSSH接続を行うという方法を見かけたので実際に試して思った事等を紹介。
ネットワークに詳しくないのでQUICについて詳しく説明が出来ないが、 QUICは低遅延でデフォルトで暗号化に対応している事、また接続の再開機能やパケットロスへの耐性を持っているプロトコル。 SSHは接続の再開機能やパケットロスに弱いのでSSHの接続時にQUICプロトコルを通す事でその問題点を解決しようと考えられている模様。
moshで良くない?
切断耐性を持つ手段としてはmoshがあるが、~/.ssh/configで設定したProxyCommandが利用出来ない為、多段sshを行う際の簡略化が行えない、sshを利用したポートフォワーディングが利用出来ない。
個人的にはVSCodeでリモートアクセスもしているが、moshを使ってのアクセスは出来ない為VSCodeでは通常のSSHでアクセスをするしかなくなってしまう。
更には接続先でもmoshサーバーを実行する為、接続先のポートとして60000~いくつかのポートを空けておく必要がある等、手間と利便性に欠ける。
今回利用するquicssh-rsではProxyCommandを使うので空けるポートは適当な一つで良いのと、ProxyCommandを利用するので、多段SSHも簡単に行える、VSCodeのSSHアクセスでも使用可能、という利点を利用出来る。
(moshはサーバーとのアクセスが不安定な場合でもクライアントで予測入力が使えたり等便利な固有機能はある)
実際に試す
今回は踏み台に利用するので、接続元と踏み台、目的のサーバーの三つを用意した。
- 接続元
- macOS 14.2.1 23C71 arm64
- OpenSSH_9.6p1, OpenSSL 3.2.1 30 Jan 2024
- quicssh-rs 0.1.4+autopublish
- 踏み台
- Ubuntu 22.04.4 LTS aarch64
- OpenSSH_8.9p1 Ubuntu-3ubuntu0.6, OpenSSL 3.0.2 15 Mar 2022
- quicssh-rs 0.1.4+autopublish
- 接続先
- macOS 14.2.1 23C71 arm64
- OpenSSH_9.4p1, LibreSSL 3.3.6
Rustの導入(オプション)
quicssh-rsはRust製の為、Rustが未導入であれば導入する必要がある。
また、sshでアクセスする元と接続先(この場合接続元と踏み台)の双方にquicssh-rsを入れる必要がある為、両方にRustを入れる事。
今回自身はbrewやaptは使わずrustup.rsを使用した。
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
基本はこのコマンドでEnter押し続けていれば必要な物は入る。
quicssh-rsのビルド
quicssh-rsはcargoで公開されているので、自前でビルドをして導入を行う。
cargo install quicssh-rs
自分の環境ではmacはあまり時間もかからずに終わったが、OrangePi3Bでは10分程かかった。 -V
オプションでバージョンの確認が出来れば導入出来ている。
設定
以降接続元と接続先はmacOS、踏み台はUbuntuを前提に説明しています。
踏み台
導入後以下のコマンドでquicssh-rsがサーバーモードで起動します。
quicssh-rs server
デフォルトで使用するポートは8625になっています。
また、サーバー側のsshは127.0.0.1:22がデフォルトでは想定されています。
クライアントからアクセスするポートを変える場合オプションで-l 0.0.0.0:8888
といった具合で設定を、
sshの設定を変えていて22番ポート以外で受け付けている場合-p 127.0.0.1:8022
といった具合で設定出来ます。
起動したらフォアグラウンドで実行状態になるので接続テストを終えるまではそのままで放置。
接続元
quicssh-rsは~/.ssh/config
のProxyCommandで使用する想定の為こちらも設定していきます。
まず最初にquicssh-rsのPATHを調べておきます。
which quicssh-rs
sshconfigの書き方に関してはこちらの記事が説明してくれているので参考にすると良いです。
~/.ssh/configについて
ここで書いた設定に追加でProxyCommandの行を追加します。(サンプルはGithubのREADME.mdから引用)
ProxyCommand /Users/ouyangjun/code/quicssh-rs/target/release/quicssh-rs client quic://%h:%p
ProxyCommandを設定したsshの接続を行ってみて、問題無く接続先に繋がれば成功。
サーバー側で実行しているquicssh-rsにもログが出る筈。
quicssh-rs serverのサービス化
流石にフォアグラウンドで実行し続ける事や、再起動の度手動で実行するのは手間なのでsystemdサービスとして登録を行う。 /etc/systemd/system/
以下に任意の名前.service
でサービスを作成する。
sudo vi /etc/systemd/system/quic-over-ssh.service
quic-over-ssh.serviceは例、既存の物と重複していなければ何でも良い。
中身はこんな感じ
[Unit]
Description=SSH over QUIC Server
[Service]
ExecStart=<踏み台のquicssh-rs実行コマンドを書く>
Restart=always
[Install]
WantedBy=multi-user.target
この時ExecStartに書くquicssh-rsはフルパスで書く必要があるっぽいので注意。
作成を終えたら以下のコマンドでサービスの起動と再起動後の自動起動を設定。
sudo systemctl start quic-over-ssh.service
sudo systemctl enable quic-over-ssh.service
以下のコマンドで実行されているか確認出来る。Active
の項目でactive(running)と表示されていれば実行されている。
sudo systemctl status quic-over-ssh.service
これで再起動後も問題無くサーバーモードで実行される。
懸念点
自身だけかもしれないが、Ubuntuのインストール時にCloudinitの設定により/etc/ssh/sshd_config.d/50-cloud-init.conf
内で、PasswordAuthentication yes
が設定されていた。
quicssh-rsは仕組み上、設定しているサーバーへのアクセスはQUICとなっており、そこから行われるsshはssh localhost
と同様の動作となっている。
公開鍵認証を強制していても、PasswordAuthenticationが有効の場合localhostではパスワード認証が出来てしまう為確認した方が良い。
もしも第三者がquicssh-rsを使用している事に気付くと総当たり攻撃が成立する状態になるので、Cloudinitが設定されている場合は関連ファイルでパスワード認証が有効になる設定が別途存在しないか確認した方が良さそう。