OS上にいないバーチャルユーザーを使ってFTP接続する | A Day In The Boy's Life

A Day In The Boy's Life

とあるエンジニアのとある1日のつぶやき。

ここではvsftpdを使って、OS上にいないユーザーでFTP接続をする方法を説明します。


vsfptdでは、anonymousに(だれかれ問わず)FTPを許可するというができますが、このanonymousもバーチャルユーザーです(OS上にanonymousというユーザーはデフォルトで存在しません)。

しかし、OSユーザーにFTP権限を与えたり、anonymousに許可することでアカウントの管理面やセキュリティ面で不安な要素があります。


・ FTP接続したいユーザーが増えた場合、OS上のユーザーを増やす必要がある
・ 上記に伴って、FTP以外の用途(SSHとか)でも使われる可能性があるため、そのための対策が必要となる
・ OS上のユーザーを使われると、権限まわりで不都合が生じる場合がある(※)
・ anonymousって・・・


※ ファイルをアップロードした場合に、そのアップロードしたユーザー権限となるため、後で権限変更が生じたり、それによってプログラムやファイルが見れない状況になる。


ようするに、純粋にFTPだけができ、わざわざOS上にユーザーを作らなくても良い方法はないものかということです。

vsftpdでバーチャルユーザーを使う場合、実際にはOSユーザーにマッピングされて接続されます。

つまり、バーチャルユーザーhogeで接続した場合、OSユーザーのfoo権限で接続するというようなイメージです。
この場合、ファイルをアップロードすると全てfooユーザーが所有者としてアップロードされます。

FTPのユーザーがたくさん必要なんだけどそれらのユーザーの権限は全て同一にしておきたいと言うような場合に便利です。


設定するにあたり、RedHatLinux5上のパッケージであるvsftpd-2.0.5を使用しています。



vsftpdのバーチャルユーザーの設定方法


1. バーチャルユーザーのリストを作成


まず、許可したいバーチャルユーザーとそのパスワードが書かれたテキストファイルを作成します。
こんな感じです。


user01
user01_password
user02
user02_password

もちろん、user01とuser02はOS上には存在しないユーザーです。



2. 1.のバーチャルユーザーリストをDB化


後に設定するPAMから、そのユーザーリスト(vsftpd_vuser_list.txt)を読み込めるように、DBファイルに変換します。

DBは、Berkeley DBのdb_loadコマンドを使います。


db_loadコマンドが存在しない場合は、db4-utilsというパッケージの中に入っていますので、それを事前にインストールしておきます。

yumコマンドでインストールするなら、こんな感じに。


# yum search db4-utils
Loading "rhnplugin" plugin
rhel-x86_64-server-5 100% |=========================| 1.4 kB 00:00
primary.xml.gz 100% |=========================| 1.8 MB 00:16
rhel-x86_6: ################################################## 5742/5742
Excluding Packages in global exclude list
Finished
db4-utils.x86_64 : Command line tools for managing Berkeley DB (version 4) databases.

# yum install db4-utils

そして、db_loadコマンドを使って先ほどのユーザーリストをDBファイルに変換。


# db_load -T -t hash -f /etc/vsftpd/vsftpd_vuser_list.txt /etc/vsftpd/vsftpd_login.db

次に権限を変更


# chmod 600 /etc/vsftpd/vsftpd_login.db


3. マッピング用のOSユーザーを作成


先ほども書いたとおり、バーチャルユーザーはOS上の特定のユーザーにマッピングされます。
そのOSユーザーを作っておきます。


# useradd -m -d /home/ftp_user -s /bin/bash ftp_user


4. vsftpdの設定ファイルの編集


vsfptdの設定ファイルである「/etc/vsftpd/vsftpd.conf」を編集し、FTP時の認証方法の変更やバーチャルユーザーの追加設定を行います。


# 匿名ユーザーのFTPを不許可
anonymous_enable=NO

# 個々のユーザーごとにホームディレクトリを設定し、上位ディレクトリに移動できないようにする設定を有効にする
chroot_list_enable=YES

# ユーザーごとの設定ファイルを定義できるようにし、その設定ファイルが置かれているディレクトリを指定する
user_config_dir=/etc/vsftpd/vsftpd_user_conf/

# ユーザーリストのファイル(/etc/vsftpd/user_list)に含まれるユーザーだけにFTPを許可し、含まれないユーザーを
# FTP不許可にする
userlist_enable=YES
userlist_deny=NO

# ログインするユーザーを全てバーチャルユーザーとみなす
guest_enable=YES

# バーチャルユーザーがマッピングされるOS上のユーザー
guest_username=ftp_user

# バーチャルユーザーがファイルアップロードする事を許可する
anon_upload_enable=YES

# バーチャルユーザーが新規にディレクトリを作成する事を許可する
anon_mkdir_write_enable=YES

# バーチャルユーザーがファイル名の変更やファイル削除をする事を許可する
anon_other_write_enable=YES

# World Readableなファイルのみをダウンロードできるというオプションを無効にする anon_world_readable_only=NO # バーチャルユーザー用のumask anon_umask=022 # バーチャルユーザーをマッピングしたOSユーザーと同等の権限にする virtual_use_local_privs=YES



5. PAMの設定を変更


FTPのユーザー認証として使われている、PAMの設定ファイル(/etc/pam.d/vsftpd)を編集します。

デフォルトでは、OS上のユーザーの存在とパスワードの突合せによって認証をチェックしていますが、今回はバーチャルユーザーとなっため、異なる認証方式を設定してあげる必要があります。


そこで、PAMの設定ファイル(/etc/pam.d/vsftpd)にデフォルトで書かれているユーザー認証の設定を全てコメントアウトし、新しく1.で作成したユーザーリストをPAMでの認証時に参照してもらうように設定します。


#%PAM-1.0
#session optional pam_keyinit.so force revoke
#auth required pam_listfile.so item=user sense=deny file=/etc/vsftpd/ftpusers onerr=succeed
#auth required pam_shells.so
#auth include system-auth
#account include system-auth
#session include system-auth
#session required pam_loginuid.so

auth required /lib/security/pam_userdb.so db=/etc/vsftpd/vsftpd_login account required /lib/security/pam_userdb.so db=/etc/vsftpd/vsftpd_login


※ 最後の「おまけ」にも書きましたが、64bit環境であれば「/lib64/security/pam_userdb.so」を指定します。



6. vsfptdデーモンの再起動


最後に、vsfptdデーモンを再起動させます。


- スタンドアロンな場合

# /etc/init.d/vsftpd restart

- xinetd経由の場合

# /etc/init.d/xinetd restart

これでバーチャルユーザーを使ってFTPに接続できます。
先ほどユーザーリストに記載したバーチャルユーザー(user01やuser02)でFTP接続をしてみましょう。



しかし・・・。
この設定には、一つ大きな問題が出てきたりします。
vsftpdの設定ファイルにて「guest_enable=YES」とすることで、FTP接続するユーザーが全てバーチャルユーザーとみなされ、OS上のユーザーでFTPできなくなります

私が探した限りでは、バーチャルユーザーとOSユーザーのどちらもFTPを許可する設定はありませんでした。

そこで、私のほうでは下記のような設定を加え、バーチャルユーザーの設定を活かしつつ、OS上のユーザーにもFTPを許可させてみました。

ここでは、vsfptdのバーチャル設定を活かしたままで、OS上に存在するhogeユーザーにFTPを許可するようにします。



vsfptdでバーチャルユーザーとOSユーザーの両方でFTP可能にする設定


1. バーチャルユーザーのリストを作成


まずは、バーチャルユーザーのリストに、OS上に存在する「hoge」ユーザーを追加します。


user01
user01_password
user02
user02_password
hoge
hoge_password

続いて、上記ユーザーリストのファイルをDBファイル化


# db_load -T -t hash -f /etc/vsftpd/vsftpd_vuser_list.txt /etc/vsftpd/vsftpd_login.db

次に権限を変更


# chmod 600 /etc/vsftpd/vsftpd_login.db


2. バーチャルユーザーごとの設定ファイルを作成


vsftpdの設定ファイル(/etc/vsftpd/vsftpd.conf)にて、ユーザーごとの設定ファイルを定義できるように設定しました。


- 該当箇所

user_config_dir=/etc/vsftpd/vsftpd_user_conf/

上記のvsftpd_user_confの下に、hogeユーザーのファイルを作成し、下記の内容を記載します。


guest_username=hoge

これだけでOKです。
要するにバーチャルユーザーであるhogeを、OSユーザーのhogeにマッピングしているという事になります。
パスワードが別管理にはなってしまいますが、FTP自体はOS上のhogeユーザーにマッピングされている為、同様の権限でFTP操作が可能です。

元のvsfptd.confにもguest_usernameのディレクティブがありますが、それをユーザーごとの定義ファイルで上書きしています。

ユーザーごとの定義ファイルを作成しなかった場合は、vsftpd.conf内で記載している「guest_username」が有効となります。



番外編 - エラー出力時の対処


1. エラーメッセージその1


Oct 24 13:27:40 vsftpd: pam_userdb(vsftpd:auth): user_lookup: could not open database `/etc/vsftpd/vsftpd_login.db': No such file or directory

明確な理由は不明なのですが、db_loadコマンドを使ってユーザーリストの再作成と権限変更で回避できたので、恐らくその辺りが問題だったのだと思います。



2. エラーメッセージその2


Oct 27 13:48:36 vsftpd: PAM unable to dlopen(/lib/security/pam_userdb.so)
Oct 27 13:48:36 vsftpd: PAM [error: /lib/security/pam_userdb.so: wrong ELF class: ELFCLASS32]
Oct 27 13:48:36 vsftpd: PAM adding faulty module: /lib/security/pam_userdb.so

64bit環境でテストした際に出て少しはまりました・・・。


pam_userdb.soモジュールの参照先が間違っていたので、正規のパスに直すことで回避できました。


- ○

auth required /lib64/security/pam_userdb.so db=/etc/vsftpd/vsftpd_login
account required /lib64/security/pam_userdb.so db=/etc/vsftpd/vsftpd_login


- ×

auth required /lib/security/pam_userdb.so db=/etc/vsftpd/vsftpd_login
account required /lib/security/pam_userdb.so db=/etc/vsftpd/vsftpd_login 


※ もしくは「auth required pam_userdb.so db=/etc/vsftpd/vsftpd_login」のように絶対パスをしてしなくても可。


参考サイトvsftpd - バーチャルユーザ運用する @ ごった煮