綾小路龍之介の素人思考

curlftpfsでftpサイトをマウントする(httpfsとかftpfs)

直接編集ということを考えるとこれらの選択肢も考えておかねばならないだろう。どちらもfuseを用いてhttpやftpのディレクトリをマウントしてローカルと同様に使えるようにしている。httpfsはそのプロトコル上の制約なのか読み込み専用のようだ、ftpfsは読み書きの両方が可能なようだ。編集という観点かれすれば書き込みが出来ないhttpfsは除くとしてもftpfsは魅力的な選択肢といえる。可能であればftpfsがもっとも良い選択肢だと思われる。これらの方法の問題点はマウントしなければ使えないという点だ。常にマウント可能、つまりftpfsの導入されたマシンがある、かどうかわからないのならftpfsという選択肢も消えてしまう。結局のところ編集用のcgiをつくっておいてブラウザ経由で編集するのが汎用性という観点からすればベストな回答なのかもしれない。

  1. FUSE: Filesystem in Userspace
  2. FUSEによる独自ファイルシステムの開発

curlftpfsパッケージの導入

debian lennyでftpfsを導入してみた。ftpfsに対応したパッケージはcurlftpfs。etch時代のcurlftpfsではマウントできてもファイルの編集や書き込みすると応答しなくなることがあったので、使うのをやめてしまったがlennyではこの問題は解決している。この記事のcurlftpfsはlennyパッケージのもの。

# aptitude -R install curlftpfs
# exit
$ curlftpfs --version
curlftpfs 0.9.1 libcurl/7.18.2 fuse/2.5

rootでマウント

で、一般ユーザで接続してみたが、失敗。

$ ls
infoseek
$ curlftpfs ftp.isweb.infoseek.co.jp infoseek/
Error connecting to ftp: Access denied: 530
$ curlftpfs ftp://ftp.isweb.infoseek.co.jp infoseek/
Error connecting to ftp: Access denied: 530
$ curlftpfs ftp://ftp.isweb.infoseek.co.jp/ infoseek/
Error connecting to ftp: Access denied: 530

rootでも試してみるが、失敗。

$ su -
Password:
# ls
infoseek
# curlftpfs ftp://ftp.isweb.infoseek.co.jp/ infoseek/
Error connecting to ftp: Access denied: 530
  1. ftp 530 - Google 検索
  2. FTPのレスポンスコード一覧

そりゃそうだ。匿名ログインは無理でしょ。再度ログイン名とパスワードを設定して一般ユーザでログイン試行するも失敗。

# exit
logout
$ curlftpfs -o user=username:password ftp://ftp.isweb.infoseek.co.jp/ infoseek/
fuse: failed to open /dev/fuse: Permission denied

どうやらこの一般ユーザは/dev/fuseの使用許可を持っていないようだ。rootになって再度チャレンジすると上手くマウント、アンマウントできた。

$ su -
Password:
# curlftpfs -o user=username:password ftp://ftp.isweb.infoseek.co.jp/ infoseek/
# ls infoseek/
index.html
# unmount infoseek/
# ls

再度マウントし、ディレクトリを作り、その中でファイルを作り、編集して、表示して、モードを変更してみる。出来たファイルにブラウザからアクセスすると正しく表示されている。

# curlftpfs -o user=username:password ftp://ftp.isweb.infoseek.co.jp/ infoseek/
# cd infoseek/
# mkdir cgi-bin
# touch test.cgi
# vi test.cgi
# cat test.cgi
#!/usr/bin/perl

print "Content-Type: text/html\n\n";
print "hoge";
# chmod 705 test.cgi

どうやら実用に足りそうだ。etch時代にあった書き込みが終了しない問題は解決されている。

  1. Debian -- lenny の curlftpfs パッケージに関する詳細
  2. ubulog: ftpの接続方法 curlftpfs編
  3. CurlFtpFS - A FTP filesystem based in cURL and FUSE
  4. id manpage - Google 検索
  5. Manpage of id

一般ユーザからftpfsをマウント、アンマウントする

root以外が読み書きできないといったが、正しく言えばこれは間違い。lsで/dev/fuseを確認するればわかるが、/dev/fuseを読み書きできるのは所有者(root)とfuseグループに属するユーザで、fuseグループに属さないユーザは/dev/fuseを読み書きできない。だから、ある一般ユーザで/dev/fuseを読み書きするには、そのユーザをfuseグループに所属させ、fuseグループに属するプロセスからcurlftpfsを走らせればよい。

$ ls -l /dev/fuse
crw-rw---- 1 root fuse 10, 229 2009-03-16 16:44 /dev/fuse

マウント、アンマウント、読み書きを行いたい一般ユーザ(hoge)が所属するグループを確認すると、groupsにfuseが含まれていないのでこのユーザで/dev/fuseは使えない。ついでにプロセスを使っているユーザのグループも見ておく。idコマンドでユーザ名を引数にとる場合、/etc/groupsから得た情報を基に所属グループを表示する。idコマンドで引数無の場合、現在のプロセスのユーザが所属するグループが表示される。この違いは結構重要。その理由は、「グループ情報は親プロセスから子プロセスに継承され、全てのプロセスのグループ情報は最も親のプロセス(ログインプロセス)から継承される」からだ。つまり、/etc/groupsの内容を基にプロセスのグループが再設定されるためには何らかの形でhogeユーザでログインしなければいけない。

$ id hoge
uid=1000(hoge) gid=1000(hoge) groups=1000(hoge),20(dialout),24(cdrom),25(floppy),29(audio),44(video),46(plugdev)
$ id
uid=1000(hoge) gid=1000(hoge) groups=20(dialout),24(cdrom),25(floppy),29(audio),44(video),46(plugdev),1000(hoge)
  1. id manpage - Google 検索
  2. Manpage of id

まずは、このユーザ(hoge)をfuseグループに所属させる。要は/etc/groupsとそのシャドウファイル/etc/gshadowを矛盾無く編集し、fuseグループに一般ユーザhogeを所属できればよい。方法はvigrとvigr -sを使う方法と、gpasswdを使う方法がある。今回は簡単な後者を使う。

$ su -
Password:
# gpasswd -a hoge fuse
# exit
  1. curlftpfs dev/fuse - Google 検索
  2. ssh, ftp, samba ファイルシステムをマウント - k3k1::log
  3. gpasswd - Google 検索
  4. Manpage of GPASSWD
  5. vigr - Google 検索

これで/etc/goupsと/etc/gshadowは正しく編集されたはずだ。idで確認すると、hogeの所属するグループにfuseが追加されていることがわかる。しかし、現在のプロセスが所属するグループにはfuseが含まれていない。そのため、このプロセスからではマウントできない。

$ id hoge
uid=1000(hoge) gid=1000(hoge) groups=1000(hoge),20(dialout),24(cdrom),25(floppy),29(audio),44(video),46(plugdev),104(fuse)
$ id
uid=1000(hoge) gid=1000(hoge) groups=20(dialout),24(cdrom),25(floppy),29(audio),44(video),46(plugdev),1000(hoge)

そこでsuコマンドを用いてhogeユーザとしてログインする。こうすると/etc/groupsから設定が読み込まれるので、su後のプロセスはfuseグループに所属する。

$ su hoge
Password:
$ id
uid=1000(hoge) gid=1000(hoge) groups=20(dialout),24(cdrom),25(floppy),29(audio),44(video),46(plugdev),104(fuse),1000(hoge)

プロセスの所属するグループにfuseが含まれているので、このプロセスからcurlftpfsを走らせればマウント、アンマウント出来るはずだ。確認のため、マウントの後、ファイルを作成、リネーム、編集、内容表示、削除、アンマウントしてみる。アンマウントはumountコマンドではだめ。

$ ls
infoseek/
$ curlftpfs username:password@ftp.isweb.infoseek.co.jp infoseek/
$ cd infoseek/
$ ls
cgi-bin  index.html
$ touch test.html
$ mv test.html test.txt
$ echo "テスト">>test.txt
$ cat test.txt
テスト
$ ls -la
total 20
drwxr-xr-x 1 root root 1024 1970-01-01 09:00 .
drwxr-xr-x 6 hoge hoge 4096 2009-02-21 07:45 ..
drwxr-xr-x 3 root root 4096 2009-03-24 18:35 cgi-bin
-rw-r--r-- 1 root root 4264 2009-03-23 15:59 index.html
-rw-r--r-- 1 root root   10 2009-03-24 23:48 test.txt
$ rm test.txt
$ cd ..
$ fusermount -u infoseek/

確認取れたのでfuseグループをもつプロセスを終了させる。

$ exit
$ id
uid=1000(hoge) gid=1000(hoge) groups=20(dialout),24(cdrom),25(floppy),29(audio),44(video),46(plugdev),1000(hoge)

くどいようだが、curlftpfsを呼び出すプロセスがfuseグループに属していないとマウントに失敗する。/etc/groupsのfuseグループにhogeユーザが追加されているので、新規のログインプロセスを走らせればその中でマウントアンマウントが可能である。したがって、よくわからなければログインセッションから抜けて、再度ログインして新たにシェルを起動する。そうすればそこから起動されるプロセスはすべてfuseグループに属するため、マウントアンマウントができる。それでもだめなら再起動しなさい、おとなしく。

  1. curlftpfs dev/fuse Permission denied - Google 検索
  2. sshfsを一般ユーザで利用する方法 - yohgaki's wiki
  3. curlftpfs - Google 検索
  4. ubulog: ftpの接続方法 curlftpfs編
  5. FTPのホストをファイルシステムとしてマウントするには - @IT

マウントした状態でpsするとユーザネームとパスワードが見える

マウントした状態でpsするとftpサイトのユーザネームとパスワードが丸見えなのは問題。この問題点に関する解決策は公式サイトのFAQにも書いてあり、~/.netrcファイルにftpサイトのアドレス、ユーザネーム、パスワードを記入し、ユーザネームとパスワードを指定しないでcurlftpfsを走らせればよい。

$ ps waxf | grep curlftpfs
 4683 ?        Ssl    0:01 curlftpfs username:password@ftp.isweb.infoseek.co.jp infoseek/
  1. netrc curlftpfs - Google 検索
  2. CurlFtpFS - A FTP filesystem based in cURL and FUSE
  3. Vine Linux 4.2 でcurlftpfsを使ってみる
  4. FTPクライアントでログインを自動化するには - @IT

~/.netrcを編集して、所有者以外の読み書きを禁止する。default行があるのはフールプルーフ。

$ vi ~/.netrc
$ chmod 600 ~/.netrc
$ ls ~/.netrc -la
-rw------- 1 hoge hoge 65 2009-03-25 01:09 /home/hoge/.netrc
$ cat ~/.netrc
machine ftp.isweb.infoseek.co.jp login username password password
default login anonymous password anonymous@localhost
  1. netrc - Google 検索
  2. Manpage of NETRC
  3. UNIXの部屋 コマンド検索:~/.netrc (*BSD/Linux)

再度curlftpfsでマウントするが、その際にユーザネームとパスワードを指定しない。psコマンドでユーザネームとパスワードが表示されないのを確認してアンマウント。

$ curlftpfs ftp.isweb.infoseek.co.jp infoseek/
$ ps wax | grep curlftpfs
16132 ?        Ssl    0:00 curlftpfs ftp.isweb.infoseek.co.jp infoseek/
$ fusermount -u infoseek/

この方法ではcurlftpfsのftpサイトアドレスと~/.netrcのmachineトークンとが合っている必要がある。考えられる問題は、同じftpサイトに異なるユーザでアカウントを持っていて、それらのアカウントにログインしたい場合はどうすればいいのかということ。

  1. FTPの.netrcについて - Linux Square

fstabに設定を書き込む

マウントポイントの所有者と所有グループを設定するために適当なユーザ(hoge)のgidとuidをidコマンドでチェックしておく。

# id hoge
uid=1000(hoge) gid=1000(hoge) groups=1000(hoge),20(dialout),24(cdrom),25(floppy),29(audio),44(video),46(plugdev)
# echo "curlftpfs#username:password@ftp.isweb.infoseek.co.jp /home/hoge/mnt/infoseek fuse rw,uid=1000,gid=1000,user,noauto 0 0">>/etc/fstab
# ps waxf | grep curlftpfs
 6321 ?        Ssl    0:00 curlftpfs username:password@ftp.isweb.infoseek.co.jp /home/hoge/mnt/infoseek -o rw,noexec,nosuid,nodev,uid=1000,gid=1000

psしたときにパスワードとユーザ名が見えることを除けばrootでマウントして編集パーミッション変更等できるので悪くない。悪くないのだが、結局マウントしたユーザのみが読み書きできて、設定したユーザやグループからは読み書き出来ないので、uidとgidの指定はほとんど無意味。/root/.netrcを作って正しく設定すればfstab経由でもパスワードとユーザをpsで表示させないように出来る。その場合のfstabは下のような感じ。

# grep "curlftpfs" /etc/fstab
curlftpfs#ftp.isweb.infoseek.co.jp /mnt fuse rw,uid=1000,gid=1000,user,noauto 0 0

結局この設定は使っていない。

問題点

問題を一つ発見。どうやら同期されるのに時間がかかるようで、タイミングによっては新しく作成されたファイルが見えなかったり、タイムスタンプが古くなることもあるようだ。しかし、本体は更新されている。そんな訳で、lsで見えないはずのファイルがcat出来てしまったりする。

また、ファイルの内容についてもキャッシュが効いているようで、tail -fとかしても正しくは変わらない。ということで、サーバ上で頻繁に書き換えられるようなファイルの内容は、その更新ペースが同期しない。もちろん、適当な時間が経過すれば同期されるので、待てば問題は無い。

ソーシャルブックマーク

  1. はてなブックマーク
  2. Google Bookmarks
  3. del.icio.us

ChangeLog

  1. Posted: 2008-05-15T17:23:54+09:00
  2. Modified: 2008-05-15T01:23:17+09:00
  3. Generated: 2017-03-31T23:09:25+09:00