DebianをWindows10上で動かす その6: Linuxとファイルを共有する

前回はWindows Subsystem for Linux (WSL)上にインストールしたDebian GNU/LinuxにSSHで接続する方法を紹介しました。

今回はネットワーク上にあるLinuxとファイルを共有する方法を紹介します。

前提となるネットワーク構成

私が普段作業してる環境は、ファイルサーバとして動かしているLinuxがあり、Windows10上から共有フォルダとしてLinux上のファイルを見えるようにしています。

つまりLinuxにはSambaが導入されていることになります。

現時点でのネットワーク構成

ここでWindows10にWSLでDebianを導入したので、このDebianからファイルサーバ(Linux)のHDDを見たいというのが私の希望です。

特に、ファイルサーバのLinuxのホームディレクトリには各種設定ファイルやデータがあるので、できればこのホームディレクトリをWSLのホームディレクトリとして使いたいところです。

実現したいネットワーク構成

ファイル共有の方法

ファイル共有の方法としては大きく分けて二つの方法がありそうです。

  1. WSLがWindows10経由でファイルサーバ(Linux)にアクセスする
  2. WSLから直接ファイルサーバ(Linux)にアクセスする

とりあえず試行錯誤してみたいと思います。

Windows10経由でファイルサーバにアクセス

WSLにはWindows10のディスクドライブをマウントする「drvfs」という機能があります。

従って、ファイルサーバの共有フォルダをネットワークドライブに割り当てていれば、drvfsでマウントすることができるはずです。

イメージとしてはこんな感じです。

Windows10経由

例えば、共有フォルダをネットワークドライブとして「z:」に割り当ててあったとします。

この場合は次のようにマウントすればOKです。

$ sudo mkdir -p /mnt/z
$ sudo mount -t drvfs z: /mnt/z

これで/mnt/z以下にファイルサーバの共有フォルダが見えるようになります。

しかし試してみたところ次のような問題がありました。

  1. 全てのファイルパーミッションが「777」となってしまう
  2. ファイルやディレクトリの名前は見えるが、中身が見えない (permission deniedになる)
  3. なぜかtouchコマンドを使うと空ファイルの作成だけはできる

ちょっとこれでは実用は難しそうです。

WSLではHDD等の固定ディスクはデフォルトで/mnt以下にマウントされていますが、ネットワークドライブがマウントされていないのはこのせいかもしれません。

WSLのアップデートに期待しましょう。

ネットワークドライブを使わなくても直接共有フォルダをマウントすることもできるようです。

$ sudo mount -t drvfs '\\サーバ名\共有フォルダ名' /mnt/z/

ただ、状況はネットワークドライブをマウントしたときと同じ状況でした。

直接ファイルサーバにアクセス

WSL上で動いているといるとはいえLinuxはLinuxです。

Linuxのネットワークファイルシステムといわれる仕組みと使うと、ファイルサーバのLinuxとファイル共有ができる可能性があります。

いくつかのネットワークファイルシステムを試してみたいと思います。

NFS → 失敗

Linux間でネットワークでファイルを共有する際の定番なのはNFSです。

私も最初はNFSを使おうと思っていました。

しかし、WSLがサポートしているファイルシステムをチェックしてみるとNFSが入っていません。

$ cat /proc/filesystems
nodev   sysfs
nodev   rootfs
nodev   bdev
nodev   proc
nodev   tmpfs
nodev   binfmt_misc
nodev   debugfs
nodev   sockfs
nodev   usbfs
nodev   pipefs
nodev   anon_inodefs
nodev   devpts
ext3
ext2
ext4
nodev   ramfs
nodev   hugetlbfs
vfat
msdos
iso9660
fuseblk
nodev   fuse
nodev   fusectl
yaffs
yaffs2
nodev   overlayfs
nodev   overlay
nodev   mqueue

これではNFSは使えません。

ためしに使ってみたところ「No such deivce」になってしまいました。

$ sudo mount -t nfs 192.168.10.1:/home /mnt/nfs/
mount.nfs: No such device

SMB/CIFS → 失敗

ファイルサーバではSMB/CIFSサーバであるSambaが動いています。

従って、WSLのDebianがSMB/CIFSクライアントになればファイルサーバとファイルを共有できるはずです。

しかしWSLがサポートしているファイルシステムには「cifs」が含まれていないので、そのままではWSLはSMB/CIFSクライアントにはなれません。

そこでFUSEというシステムでSMB/CIFSクライアントになることができる、「fusesmb」を試してみます。

SMB/CIFSの利用

まずはインストールです。

$ apt-get install fusesmb

私の場合は依存しているパッケージがたくさんあって、27個のパッケージがインストールされました。

インストールが完了したら設定ファイルを作ります。

まずサンプルをコピーしてパーミッションを設定します。

$ mkdir .smb
$ cp /usr/share/doc/fusesmb/examples/fusesmb.conf.ex .smb/fusesmb.conf
$ chmod 600 .smb/fusesmb.conf

そしてこのファイルを編集して、最後に次のような内容を付け加えます。

[/ファイルサーバの名前/共有フォルダ名]
username=ファイルサーバでのアカウント名
password=ファイルサーバでのパスワード

ここまできたらfusesmbを使ってみます。

$ fusesmb mnt/
fuse: device not found, try 'modprobe fuse' first

残念ながらエラーが出てしまいました。

動作状況を確認してみると/dev/fuseのオープンに失敗していることがわかります。

$ strace fusesmb mnt/
execve("/usr/bin/fusesmb", ["fusesmb", "mnt/"], [/* 18 vars */]) = 0
省略
open("/dev/fuse", O_RDWR)               = -1 ENOENT (No such file or directory)
write(2, "fuse: device not found, try 'mod"..., 50fuse: device not found, try 'modprobe fuse' first
) = 50
exit_group(0)                           = ?
+++ exited with 0 +++

どうも /dev/fuse がなくて止まっているようです。

そこで手動で/dev/fuseを作成してみます。Linuxカーネルのドキュメントを見るとメジャー番号は10、マイナー番号は229とのことです。

そこで下記のコマンドで/dev/fuseを作成します。

$ sudo mknod -m 0666 /dev/fuse c 10 229

これで再度fusesmbを使ってみます。

$ fusesmb mnt/
fuse: device not found, try 'modprobe fuse' first

結果は・・・同じく「device not found」でエラーになってしまいました。

WSLのfuseは完全に実装されていないのかもしれません。

調べてみるとfuse実装の希望はかなり上がっていますが・・・

Please add FUSE (Filesystem in Userspace) interface /dev/fuse into WSL (Windows Subsystem for Linux). With FUSE, we can access from WSL to file storages regula...

SSH → 可能

SSHはリモートログインするためのプロトコルです。

しかし、SSHにはscpやsftpというようなファイル転送の機能もあります。この機能を使うとファイルサーバ(Linux)のファイルをWSLから取得したり、WSLのファイルをファイルサーバ(Linux)に送信することができます。

SSHの利用

本当はこのSSHのファイル転送機能を使ってSSHサーバをファイルシステムとしてマウントできるsshfsという仕組みがあります。

しかし、このsshfsはfuseという仕組みをベースとしているので現時点でのWSLでは動作しません

今回はscpコマンドのを使えるところまで設定してみます。ただし、ファイルサーバ(Linux)では既にSSHサーバが起動しているものとします。

まず、WSLのDebianにSSHクライアントをインストールします。

$ sudo apt-get install openssh-client

続いてWSLで秘密鍵と公開鍵のペアを作成します。

$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/foo/.ssh/id_rsa): ← リターンキーを入力
Enter passphrase (empty for no passphrase):  ← パスフレーズを入力 (不要な場合は単にリターンを入力)
Enter same passphrase again:  ← パスフレーズの再入力 (不要な場合は単にリターンを入力)
Your identification has been saved in /home/foo/.ssh/id_rsa.
Your public key has been saved in /home/foo/.ssh/id_rsa.pub.
以下省略

パスフレーズで保護した方が安全ですが、パスフレーズがない方が利便性が高くなります。私はパスフレーズはなしにしました。

これでホームディレクトリの.sshディレクトリにid_rsa.pubという公開鍵ファイルが作成されているはずです。

このファイルの中身をファイルサーバのLinuxの「ホームディレクトリ/.ssh/authorized_keys」に追記します。WSLのターミナル画面に中身を表示させてコピペをすれば良いでしょう。

ここまできたら接続できることを確認して見ます。

$ ssh ユーザ名@ホスト名(IPアドレス)

これでパスワードの入力なしに接続できればOKです。

あとはscpコマンドでファイルをコピーするだけです。

scpコマンドの使い方は下記のようになります。

$ scp ユーザ名@サーバ名:ファイルパス ファイルパス     (サーバからWLSにコピーする場合)
$ scp ファイルパス ユーザ名@サーバ名:ファイルパス ファイルパス     (WLSからサーバにコピーする場合)

例えば、ファイルサーバ(192.168.10.1)のユーザfooのホームディレクトリにあるtest.txtをWSLに持ってくる場合は下記のようになります。

$ scp foo@192.168.10.1:~/test.txt .

ちなみにファイルサーバとWSLのユーザ名が一致していれば「foo@」の部分も省略することができます。

ファイルシステムとしてマウントしたときのように手軽には使えませんが、とりあえずこれでファイルサーバとファイルをやりとりをできるようになります。

scpコマンドが動くので、rsyncコマンドなどでファイルの同期も可能となります。

まとめ

今回はWindows Subsystem for Linuxとネットワーク上にあるLinuxファイルサーバ間でファイルを共有する方法を紹介しました。

本当はWSLからファイルサーバのディスクをマウントして使う方法を模索していたのですが、残念ながら今のWSLでは見つけることができませんでした。

現時点ではscpを使うのが現実的と思います。

WSLがfuseをサポートするとこの状況はかなり変わってくると思います。WSLの更新を期待したいところです。

次回はWSLとしてインストールしたDebian GNU/LinuxでGUIを使ってみます。