どーしてもFTPサーバを立てなければいけない時に使う、使い捨てFTPサーバ

「最近ブログ書かないんですか?」と客先で聞かれることがあったので、生存確認の意味でブログを書いてみたいと思います。


FTPといえば、最近着目を浴びたプロトコルですね。FTPは、そもそもセキュアではないプロトコルです。追い撃ちをかけるように、FTPクライアントがローカルに保存したパスワードを盗むコンピュータウイルスが発生しました。ローカル保存されたパスワードが盗まれたことについては、FTPというプロトコル自体の責任ではありません。しかし、世間でのFTPの印象は悪くなったようです。僕も、普段はFTPを使うことはありません。


しかし、外部の方とやりとりする場合に、「どどどーーしてもFTPじゃないとヤダー!!!」と言われるケースがあります。そのような場合、FTPサーバを必要なときのみだけ起動するという方法を取ることができます。具体的には、以下のような方法ですね。

  • ファイルの受け渡しをしたいという連絡を電話などで受ける。
  • ftpサーバを立ち上げる。
  • ファイルをftp経由でアップロードしてもらう。
  • 完了次第ftpサーバを葬る。

しかし、僕がいままで経験したことのあるFTPサーバの設定は、
意外と面倒くさく、しかも柔軟性に欠けたものしか行えない印象があります。
ちょっとだけのファイルの受け渡しのためだけに、
普段使わない上にメンドクサイFTPサーバ設定をする気なんて起きねー!


このような、生存期間が短いFTPサーバをカンタンに作ることができる、pyftpdlibというものがあります。
Windows/Linux/Mac OS X全てで動作する、ラクラクFTPサーバ作成ライブラリです。
今回は、このpyftpdlibの使い方について簡単な解説を試みます。


なお、実行のためにはプログラミング言語Pythonの実行環境が必要となります。
最近のLinuxディストリビューションだったら標準で実行環境が入っていると思います。

pyftpdlibのダウンロード

pyftpdlib、何がすごいって「ファイル1個だけのライブラリ」ということです。扱いが楽ですね。(2013年3月26日追記:pyftplibバージョン1.0.0以降は、ファイルが複数に別れています。バージョン0.7.0を使う前提で以下記述されています。)


ダウンロードは、
http://code.google.com/p/pyftpdlib/
から行うことができます。


ダウンロードしたパッケージは、インストールする必要がありません。
動作に必要となるのは、解凍して得られる「pyftpdlib-x.x.x/pyftpdlib/ftpserver.py」という1ファイルのみです。
これをカレントディレクトリに置いてください。

anonymous ftpを立てる

全てのIPアドレスの10021番ポートにて、
/var/ftp/以下のディレクトリをanonymous ftpにて公開するのは、
以下のように書けます。

#!/usr/bin/python
import ftpserver

FTP_ROOT = "/var/ftp/"
ADDRESS = ("0.0.0.0", 10021)

authorizer = ftpserver.DummyAuthorizer()
authorizer.add_anonymous(FTP_ROOT)

ftp_handler = ftpserver.FTPHandler
ftp_handler.authorizer = authorizer

ftpd = ftpserver.FTPServer(ADDRESS, ftp_handler)
ftpd.serve_forever()

ADDRESSというタプルの1つめの要素に"0.0.0.0"を指定すると、
全てのIPアドレスで接続を待ち受けます。
ポート番号が1024未満でFTPサーバを立ち上げたい場合には、管理者権限が必要となります。


認証が存在しないため、anonymousユーザはファイルの読み込みしかできないようになっています。
実際に使うことはあまりないでしょう。

ユーザを追加する

pyftpdlibは、ユーザを複数追加することができます。ユーザごとにhomeディレクトリや権限を指定することもできます。


FTP_ROOT以下すべてにアクセスできるgunyaというユーザを作成してみましょう。
パスワードは「password_de_gozaimasu」です。


先ほどの、

authorizer.add_anonymous(FTP_ROOT)

という1行を、以下のようにadd_user関数に置換しましょう。

authorizer.add_user("gunya", "password_de_gozaimasu", FTP_ROOT,
                    perm="elradfmw")

add_user関数の引数は、それぞれユーザ名・パスワード・homeディレクトリ・権限です。
権限について、それぞれの文字は以下のような意味を持ちます。

  • e: ディレクトリ変更
  • l: ファイル一覧の取得
  • r: ファイルのダウンロード
  • a: 既存のファイルへの追記
  • d: ファイルの削除
  • f: ファイル名変更
  • m: ディレクトリ作成
  • w: ファイルのアップロード

今回は、権限が全て付与されたユーザを作成したことになります。


もちろん、add_user関数を複数呼べば、複数のユーザを作成することができます。

パスワードを動的に変更

pyftpdlibのいいところは、Pythonというプログラミング言語上で動作するということです。
たとえば、起動のたびに違ったパスワードを設定することもできます。


先ほどのユーザ「gunya」のパスワードを、「password」と「年月日」を連結した文字列にしてみましょう。


まずは、日付・時刻を扱うライブラリを読み込みます。

import ftpserver

の次の行に、

from datetime import datetime

を追記します。


そして、add_user関数の第二引数を変えることにより、「password」と「年月日」を連結した文字列をパスワードとして設定します。

authorizer.add_user("gunya",
                    "password" + datetime.now().strftime('%Y%m%d'),
                    FTP_ROOT, perm="elradfmw")

これで、立ち上がった日付によって違ったパスワードを要求するFTPサーバができました。
もちろん、ユーザIDだって動的に生成することができます。

他にも

  • FTPS
  • 帯域制限
  • IPごとの接続制限
  • IPv6対応

などと機能盛りだくさんなpyftpdlib。
詳しくは、以下のチュートリアルをご覧ください。
http://code.google.com/p/pyftpdlib/wiki/Tutorial

すぐ殺すFTPサーバに使うのには勿体ないともいえます。ぜひ使ってみてください!


僕が持っているWebカメラには写真を定期的にアップロードしてくれる機能があり、
留守中の猫画像をアップロードしたいな!と思ったにもかかわらず、
その機能が対応しているプロトコルFTPだけだった、けどFTPサーバなんて立てるのはメンドクセー、
という経緯の副産物のエントリでした。