Windowsでsshfs(トラブルシューティング等)

はじめに

sshfsとは、リモートのsshサーバー上のディレクトリをローカルにマウントすることができるLinux(UNIX)用のソフトウェアです。Windowsでも同等の機能を持つSSHFS-Win(https://github.com/winfsp/sshfs-win)というソフトウェアがあるのですが、使うにあたっていくつかつまずいたポイントがあったので記事に残しておこうと思った次第です。

前提知識

sshを用いたリモートサーバーへの接続(鍵ペアの作成、sshのconfigの書き方など)に関してここでは解説しませんので、他の記事をご覧ください。この記事ではssh server1と打つ(&適宜、パスフレーズなどを入力する)ことでマウント対象のサーバー(server1)にアクセスできるようにconfigで設定してあることを前提にします。さらに、公開鍵認証を想定にし、パスワード認証に関しては扱いません(ただ、むしろ公開鍵認証でうまくいかないという投稿を多く見る気がするので、パスワード認証でも大きく変わらずできるとは思います)(コメントなどで要望があれば試してみるかもしれません)。あと、WSL関係も試していません(これも要望があればやるかも)。

なお、configで予め設定しておかなくてもSSHFS-Winにsshのオプションを渡すことはできるのですが、トラブルシューティング時の原因の切り分けが面倒になるので、configを設定してからSSHFS-Winの設定に進むことを強く推奨します。

使用ソフトウェアについて

前述の通りSSHFS-Winを使うのですが、他にも使えるソフトウェアがあるようです。まず名前がよく似ているwin-sshfs(https://github.com/feo-cz/win-sshfs)があります。SSHFS-Winのほうは(Windows上での仮想的なファイルシステムを提供するための)バックエンドとしてWinFsp(https://github.com/winfsp/winfsp)というのを使っているのですが、win-sshfsのほうはDokany(https://github.com/dokan-dev/dokany)(以前はDokanとして開発されていたもののフォーク)を使っている点が異なります。おそらくWinFspのほうがDokanyより後発で、win-sshfsは開発があまり活発でないようなので、今回は(WinFsp+)SSHFS-Winを使用することとします。なお、有料ソフトウェアですがExpandriveというのもこの目的に使えるようです。

インストール方法

WinFspとSSHFS-Winのインストールはいずれも容易です。配布されているmsiファイルを起動して指示に従えば、特に問題なくインストールできると思います。(デフォルトでは)SSHFS-Winの実行ファイル群(ssh.exe, sshfs.exe, sshfs-win.exeの3つ及び依存ライブラリのdll)はC:\Program Files\SSHFS-Win\binにインストールされます。

使用するコマンド、及びマウントポイントについて

SSHFS-Winの使い方に関する記事では、Windows標準コマンドのnetを使用するものや、sshfs-win.exeを使用するものが比較的多いと思います。しかし、これらは実際にはsshfs.exeを呼ぶための薄いラッパーであり、むしろsshfs.exeを直接呼ぶ方が見通しが良いため、この記事ではsshfs.exeコマンド(以下、混乱の恐れがない場合は単にsshfsと呼ぶ)のみを使います。

また、フォルダのマウント先に新規ドライブレター(X:のような)を使う解説例が多いと思うのですが、実は既存のドライブの中のディレクトリにマウントすることも可能です(これはnetコマンド経由ではできないようです)。となるとわざわざ貴重なドライブレターを消費する理由もないので、この記事ではディレクトリへのマウントを行うこととします。なお、sshfsが成功するためにはマウント先のディレクトリ(もちろん同名のファイルも)が存在しない状態である必要があります。ディレクトリはマウント時に作成され、sshfsの終了時に削除されます。これはマウントポイントが既に存在する空フォルダでなければならないLinuxとは異なるところなのでご注意ください。

コマンドラインオプション

sshfsの書式とオプションの全体は-hで確認できますが、この記事で使用するものをここで紹介しておきます。

  • -d デバッグ情報が出力されます。失敗しているときにConnection reset by peerとかしか出ないと何もわからないので、トラブルシューティング時は有効にしておくとよいです。正常動作中は大量のログが吐き出されるのでつけないほうがよさそうです。
  • -f デーモンとしてではなくフォアグラウンドで実行されます。わざわざtaskkillしなくてもCtrl+Cだけで停止できるので、頻繁に起動/終了するトラブルシューティング時にはつけた方が便利な気がします。
  • -o 様々なマウントオプションを指定します。たとえばtransform_symlinksを指定すると、リモートフォルダの中のシンボリックリンクを良い感じに変換してくれます。複数指定する場合はカンマで区切ります。

では、以下の2つのコマンドを(testdirというファイルやフォルダがない場所で)コマンドプロンプト上で実行してみてください。

set PATH=C:\Program Files\SSHFS-Win\bin;%PATH%
sshfs -f -o transform_symlinks server1:/ testdir

configなどが正しく設定できていれば、testdirというフォルダが作成され、server1のルートディレクトリの中身が見られるようになっているはずです(server1:/の最後のスラッシュがルートディレクトリを表している)。ちなみにtestdirの部分をX:などに変えれば新規ドライブレターへのマウントも可能です。

なお、この例ではSSHFS-WinのbinフォルダをPATHの先頭に追加しているのでsshfs.exeと同じ場所にあるSSHFS-Winのssh.exeが使われますが、Windows10の場合は標準でインストールされているOpenSSHのssh.exeもあるので、PATHを変えずにC:\Program Files\SSHFS-Win\bin\sshfs.exeを直接呼び出しても動作します。ただし後述のように多段sshを使う場合はうまく動作しないようなので注意してください。

問題1: 自分のユーザフォルダ等が見えない・ファイルを上書きできない

しかし実はここまでの設定だけだと問題があり、公開鍵認証が成功しているにもかかわらずなぜか自分自身のユーザフォルダの中身を見ることができません。言わば自分であることを証明できないような状態になっており、誰でも見ることができるファイルしか見れません。アクセスできないフォルダを開こうとすると、「このフォルダーにアクセスする許可がありません。[続行]をクリックすると、このフォルダーへの永続的なアクセスを取得します。」と言われてしまいます。

ここで[続行]を押すと見られるようになる場合もあるのですが、その過程でホームディレクトリのパーミッションが強制的に変更された結果sshログインが失敗するようになるというひどい目に遭ったので、押さないでください。押してしまった場合にchmodで直すために、該当サーバーにsshログイン済みのシェルを複数用意しておくことをお勧めします。cmdとかPowerShellだといつの間にか消えてることがある気がするので、Git Bashとかのほうがいいです(多分)。シェルがなくても、Windows上でアクセス権限を編集すれば元に戻せるかもしれませんが、やったことがないのでわかりません。あと元々701だったのを661に変えられたせいで(フォルダのアクセス権がなくなって)chmod 701 .ができなくなったことがあるのですが、cd ..で一つ上に移動してからchmod 701 usernameをすれば直せます(←蛇足ながら、本当に焦ったので一応書き残しておきました)。

で、どうすれば解決できるのかというと、-oでさらにオプションを追加するのですが、自分の知る限り有効なものが3つあります。ただし、これらの正確な機能やなぜそれでうまくいくのかなどは全く理解していません。

結論から言えば、(少なくとも自分の環境では)umask=0idmap=userの2つを指定しておけば十分そうでした。Microsoftアカウントと紐づけられていないアカウントの場合はumask=0を指定せずidmap=userだけでも大丈夫でしたが、紐づけられているアカウントの場合は、gid=0を指定すると自分の所属グループの権限で見れるはずのファイル、gid=0を指定しないと自分の権限で見れるはずのファイルがそれぞれ見えなくなりました。また、idmap=userだけだと、閲覧は問題なくできますが、既存ファイルへの上書きができなくなりました。より正確な情報はリンク先を読めば書いてあるかもしれません。

というわけで、実行時のコマンドは以下のようにしましょう。

sshfs -f -o transform_symlinks,umask=0,idmap=user server1:/ testdir

問題2: ポートフォワーディング(多段ssh)を使用すると失敗する

先ほども少し触れましたが、ポートフォワーディングを使用して、マウントしたいディレクトリがあるのとは別のsshサーバーを経由してsshfsを使う場合、そのままでは接続が失敗(Connection reset by peer)してしまいます。-dを有効にしてみると

/bin/sh: No such file or directory

というようなエラーが出ているのがわかります。解決策はhttps://github.com/winfsp/sshfs-win/issues/152#issuecomment-597087792に書いてあり、(busybox-w32)https://frippery.org/busybox/に同梱されているsh.exesshfs.exeと同じフォルダにコピーしてから同じコマンドを実行するといけました。 ちなみに当初はSSHFS-Winのssh.exeがいけないのかと思い、OpenSSHのssh.exeが呼ばれるようにしたところ多少改善した(パスフレーズ要求が一度も出ないところから二度出るまで行った)のですが、最終的にはやはりConnection reset by peerになってしまっていて、結局SSHFS-Winのssh.exeを使う上記の方法だけがうまくいきました。

おわりに

以上、Windowsでsshfsをする方法について解説しました。もしこの通りにやっても上手く行かない場合は、-dでの出力とともにコメントいただければ何かわかるかもしれません。