知らないうちにrcloneのsshマウント機能が.sshを読めるようになってた: --sftp-sshオプションの使い方

この記事では2023年9月にrcloneに新しく追加された`--sftp-ssh`オプションの使い方を書く。

# この記事が書かれた経緯

かつてssh接続が利用できるリモートサーバーにおいて、特定のディレクトリをローカルにマウントしたい時はsshfsが使われていた。sshfsは`ssh`や`scp`コマンドと同じようなノリのインターフェースをしていて、`.ssh`ディレクトリの設定や鍵を利用して接続してくれた。

```console:sshfsを使ってリモートサーバーをマウントするコマンドの例
sshfs user@mycomputer:/remote/path /local/path
```

少し前にまたsshfsを使いたくなって検索したが、どうもsshfsは開発が終了していて使用が推奨されていないらしい。[Archwiki](https://wiki.archlinux.jp/index.php/SSHFS)では代替としてrcloneが提案されていたのでインストールして使ってみたが、rcloneでは独自に実装したsshクライアントを利用しているらしく、`.ssh/`ディレクトリ以下の設定や鍵とは別に設定を登録しなければならないようだった。そこまでしてやりたいことでもなかったので、リモートサーバーのマウントはあきらめていた。

最近調べ物をしていたら、今のrcloneには`.ssh/`の設定を利用できるようになる`--sftp-ssh`というオプションが追加されているという情報が見つかった。2023年9月に追加された機能らしい。

https://turgenev.hatenablog.com/entry/2024/05/04/194137

上の記事ではサラッと触れられているだけで、本題は別のことだった。`--sftp-ssh`を中心に取り上げた日本語情報がなさそうだったので、使い方をまとめることにした。

# rcloneのインストール

rcloneは[公式サイト](https://rclone.org/)からダウンロードできる。
`--sftp-ssh`オプションが使えるのは`1.64.0`以降で、2024年12月現在ではまだリリースから1年ちょっとしか経っていないため、適当に持ってきたrcloneでは古くて使えなかったりするので注意。

Ubuntu 22.04の場合はaptで落ちてくるrcloneのバージョンは`1.53.3`で、`--sftp-ssh`オプションが利用できない。`snap`では新しいバージョンが利用できるが、これはマウント機能が利用できないので今回の用途には使えない。

> ```
> Due to the strict permissions control of Snap,**rclone mount** feature currently not working in
>  snap. If you want to use mount feature, either install a precompiled binary or enable the > relevant
>  option when installing from source.
> ```
> ― snap info rcloneから抜粋

Goを使った開発をしていて最新版のGoが入っているなら`go install`を使うか、そうでなければコンパイル済みバイナリをホームページからダウンロードして手動で配置するのが一番簡単っぽい。

```console
$ curl -O https://downloads.rclone.org/rclone-current-linux-amd64.zip
$ unzip rclone-current-linux-amd64.zip
$ cp rclone-*-linux-amd64/rclone ~/.local/bin/
```

# ダミーの設定を作る

`--sftp-ssh`オプションをつけるとrclone側のssh設定は無視されるが、オプションを使うためには何かしらのsshリモートを指定しなければならない。設定の内容は無視されるので、ダミーとして空の設定を作る。

```console
$ rclone config
Current remotes:

Name                 Type
====                 ====

e) Edit existing remote
n) New remote
d) Delete remote
r) Rename remote
c) Copy remote
s) Set configuration password
q) Quit config
e/n/d/r/c/s/q> n

Enter name for new remote.
name> ssh

Option Storage.
Type of storage to configure.
Choose a number from below, or type in your own value.
<中略>
47 / SSH/SFTP
   \ (sftp)
<中略>
Storage> 47
```

ホスト名の設定は`--sftp-ssh`オプションをつけると無視されるが、デフォルト値が存在しないため何らかの値は入れなければならない。例示されている`example.com`にしておく。

```
Option host.
SSH host to connect to.
E.g. "example.com".
Enter a value.
host> example.com
```

しばらくデフォルト値の存在する設定項目が続く。空のままエンターキーを押して進めていく。

```
Option user.
SSH username.
Enter a value of type string. Press Enter for the default (kotet).
user>

Option port.
SSH port number.
Enter a signed integer. Press Enter for the default (22).
port>

Option pass.
SSH password, leave blank to use ssh-agent.
Choose an alternative below. Press Enter for the default (n).
y) Yes, type in my own password
g) Generate random password
n) No, leave this optional password blank (default)
y/g/n>

Option key_pem.
Raw PEM-encoded private key.
Note that this should be on a single line with line endings replaced with '\n', eg
    key_pem = -----BEGIN RSA PRIVATE KEY-----\nMaMbaIXtE\n0gAMbMbaSsd\nMbaass\n-----END RSA PRIVATE KEY-----
This will generate the single line correctly:
    awk '{printf "%s\\n", $0}' < ~/.ssh/id_rsa
If specified, it will override the key_file parameter.
Enter a value. Press Enter to leave empty.
key_pem>

Option key_file.
Path to PEM-encoded private key file.
Leave blank or set key-use-agent to use ssh-agent.
Leading `~` will be expanded in the file name as will environment variables such as `${RCLONE_CONFIG_DIR}`.
Enter a value. Press Enter to leave empty.
key_file>

Option key_file_pass.
The passphrase to decrypt the PEM-encoded private key file.
Only PEM encrypted key files (old OpenSSH format) are supported. Encrypted keys
in the new OpenSSH format can't be used.
Choose an alternative below. Press Enter for the default (n).
y) Yes, type in my own password
g) Generate random password
n) No, leave this optional password blank (default)
y/g/n>

Option pubkey_file.
Optional path to public key file.
Set this if you have a signed certificate you want to use for authentication.
Leading `~` will be expanded in the file name as will environment variables such as `${RCLONE_CONFIG_DIR}`.
Enter a value. Press Enter to leave empty.
pubkey_file>

Option key_use_agent.
When set forces the usage of the ssh-agent.
When key-file is also set, the ".pub" file of the specified key-file is read and only the associated key is
requested from the ssh-agent. This allows to avoid `Too many authentication failures for *username*` errors
when the ssh-agent contains many keys.
Enter a boolean value (true or false). Press Enter for the default (false).
key_use_agent>
```

鍵選択に関するオプション。たぶん今回の用途だと無視されるのでどっちでもいい。`1`にしておく。

```
Option use_insecure_cipher.
Enable the use of insecure ciphers and key exchange methods.
This enables the use of the following insecure ciphers and key exchange methods:
- aes128-cbc
- aes192-cbc
- aes256-cbc
- 3des-cbc
- diffie-hellman-group-exchange-sha256
- diffie-hellman-group-exchange-sha1
Those algorithms are insecure and may allow plaintext data to be recovered by an attacker.
This must be false if you use either ciphers or key_exchange advanced options.
Choose a number from below, or type in your own boolean value (true or false).
Press Enter for the default (false).
 1 / Use default Cipher list.
   \ (false)
 2 / Enables the use of the aes128-cbc cipher and diffie-hellman-group-exchange-sha256, diffie-hellman-group-exchange-sha1 key exchange.
   \ (true)
use_insecure_cipher> 1
```

またデフォルト値のある設定項目。エンターキーを押して進める。

```
Option disable_hashcheck.
Disable the execution of SSH commands to determine if remote file hashing is available.
Leave blank or set to false to enable hashing (recommended), set to true to disable hashing.
Enter a boolean value (true or false). Press Enter for the default (false).
disable_hashcheck>
```

sshのパスと引数。デフォルト値が存在するので読まずに進めてしまって気付いていなかったが、`--sftp-ssh`オプションに渡している値をここに書き込めば、毎回オプションで指定しなくても設定が使われるということかもしれない。記事を書くために読み返して気が付いた……
でも自分はsshの設定が`.ssh/`、`--sftp-ssh`、rclone設定の三か所に散らばるのが嫌なので空にして`--sftp-ssh`を使う。

```
Option ssh.
Path and arguments to external ssh binary.
Normally rclone will use its internal ssh library to connect to the
SFTP server. However it does not implement all possible ssh options so
it may be desirable to use an external ssh binary.
Rclone ignores all the internal config if you use this option and
expects you to configure the ssh binary with the user/host/port and
any other options you need.
**Important** The ssh command must log in without asking for a
password so needs to be configured with keys or certificates.
Rclone will run the command supplied either with the additional
arguments "-s sftp" to access the SFTP subsystem or with commands such
as "md5sum /path/to/file" appended to read checksums.
Any arguments with spaces in should be surrounded by "double quotes".
An example setting might be:
    ssh -o ServerAliveInterval=20 user@example.com
Note that when using an external ssh binary rclone makes a new ssh
connection for every hash it calculates.
Enter a value of type SpaceSepList. Press Enter to leave empty.
ssh>
```

以上で設定は終わり。設定を保存して終了する。

```
Edit advanced config?
y) Yes
n) No (default)
y/n>

Configuration complete.
Options:
- type: sftp
- host: example.com
Keep this "ssh" remote?
y) Yes this is OK (default)
e) Edit this remote
d) Delete this remote
y/e/d>

Current remotes:

Name                 Type
====                 ====
ssh                  sftp

e) Edit existing remote
n) New remote
d) Delete remote
r) Rename remote
c) Copy remote
s) Set configuration password
q) Quit config
e/n/d/r/c/s/q> q
```

# --sftp-ssh オプションを利用する

ダミーの設定を作ったので使っていく。

`--sftp-ssh`オプションは、rcloneの組み込みsshクライアントの代わりに外部のsshコマンドを利用するオプション。rclone側のホスト名、ポート、鍵等の設定はすべて無視され、外部のsshコマンドによる接続を利用する。

オプションには、sshでログインする時のコマンドを渡す。ログインプロンプトが出ずに即座にログインできる必要があるので、たぶんパスワード認証だとうまく動かない。NOTICEメッセージが表示されるが、これは`--sftp-ssh`によって設定が上書きされたという通知文なので問題ない。

`/path/to/remote`にはマウント対象となるリモートのパス、`/path/to/local`にはローカルのマウントポイントを指定する。

```console:基本の使い方
$ rclone mount --sftp-ssh 'ssh kotet@server.example' ssh:/path/to/remote /path/to/local
2024/11/27 20:42:52 NOTICE: ssh{Desz0}: --sftp-ssh is in use - ignoring user/host/port from config - set in the parameters to --sftp-ssh (remove them from the config to silence this warning)
```

踏み台サーバーだったり、ポート変更だったりも動く。

```console:基本の使い方
$ rclone mount --sftp-ssh 'ssh -p 1234 -J fumidai.example kotet@server.example' ssh:/path/to/remote /path/to/local
```

`.ssh/config`に設定があれば、当然それも利用できる。

```console:基本の使い方
$ rclone mount --sftp-ssh 'ssh server' ssh:/path/to/remote /path/to/local
```

普通にフォアグラウンドで実行した場合は ctrl-C で終了するとアンマウントされる。バックグラウンド実行だったり、正常に終了できなかった等でアンマウントされなかった場合は`fusermount`でアンマウントする必要がある。

# 自動マウント

rclone関係ない部分だが一応書いておく。systemdのユーザーサービスを作って、ログイン時に自動でマウントするようにしてみる。接続先が常時接続しても良いサーバーかどうかは考えて行う必要がある。

```:~/.config/systemd/user/rclone.service
[Unit]
Description=rclone mount

[Service]
Type=simple
ExecStart=/path/to/rclone mount --sftp-ssh 'ssh server' ssh:/path/to/remote /path/to/local
ExecStop=/usr/bin/fusermount -u /path/to/local
Restart=always

[Install]
WantedBy=default.target
```

```console
$ systemctl --user daemon-reload
$ systemctl --user enable --now rclone.service
```