vsftpdとMySQL
※2022/06/13現在、pam_mysqlモジュールの一部SQL機能がサポートされなくなり動作しません
有志によるパッチが提供されている様子ですが、手元環境では正しくインストールできていません
別の方法を検討する必要があります
vsftpdのユーザ認証をMySQLのDBで実施する方法
vsftpdの仮想ユーザ機能を使う。
仮想ユーザ機能などについては/usr/share/doc/vsftpd-X.X.X以下にドキュメントがあるのでまずは読んでみよう。
あと、vsftpd.confの日本語MANも参考になる。 ここ
MySQL側は最低限のユーザ情報だけを保存するDBにしているが各種情報を持たせることは可能で、 pam_mysql側の設定でどんなテーブル状況にも応じられそう。
pam_mysqlのドキュメントは/usr/share/pam_mysql-X.X.Xにあるので一読する価値あり。
必要なもの
- vsftpd 当然(笑
- MySQL 当然(笑
- pam_mysql これがミソ
pam_mysqlはepelリポジトリに落ちてるのでリポジトリを追加してyumインストールすればOK
データベースの準備
MySQLに認証ユーザ用データベースを作成する。
DB名はvsftpdとしてユーザ情報用のテーブルusersとログ用のテーブルlogsを作成。
ここでは省略しているけど、vsftpdデータベースにのみ接続可能なユーザを作成しておいた方が当然ながらよろしい。(笑
mysql -u root -p mysql> create database vsftpd; mysql> use vsftpd; mysql> create table users ( id int AUTO_INCREMENT NOT NULL, name char(128) binary NOT NULL, passwd char(128) binary NOT NULL, primary key(id) ); mysql> create table logs ( msg varchar(255), user char(128), pid int, host char(128), rhost char(128), logtime timestamp );
サンプルの挿入
認証ユーザ情報を設定する。usersテーブルのnameとpasswdに値を設定するのみ。 パスワード文字列はMySQLのpassword関数を利用して暗号化して設定する。
mysql> insert into users (name,passwd) values('test1@test.local',password('test1')); mysql> insert into users (name,passwd) values('test2@test.local',password('test2')); mysql> select * from users; +----+---------------------+-------------------------------------------+ | id | name | passwd | +----+---------------------+-------------------------------------------+ | 1 | test1@test.local | *4266488C892EA7950486FEC0A1CFFC1BD9543F7B | | 2 | test2@test.local | *94BDCEBE19083CE2A1F959FD02F964C7AF4CFC29 | +----+---------------------+-------------------------------------------+ ※ここで注意! passwdカラムが16バイト文字列で先頭が*(アスタリスク)以外の場合はMySQL3互換形式の暗号化が利用されていることになる。 この場合、後述のPAM設定部分を変更する必要がある。 基本的にはMySQL3互換形式は利用しないほうが望ましい。 MySQLがどの形式を利用しているかはmy.cnfにold_password=1があるかどうかで判断できる。 あればMySQL3互換形式となる。
PAMの設定
vsftpdが利用するPAM /etc/pam.d/vsftpdをpam_mysqlが利用できるように修正する。
vsftpdの記述を全てコメントアウトして以下を追加する。(ちょっと長いけど…全部で2行です)
auth required pam_mysql.so user=root passwd=******** host=localhost db=vsftpd table=users usercolumn=name passwdcolumn=passwd crypt=2 sqllog=1 logtable=logs logmsgcolumn=msg logusercolumn=user logpidcolumn=pid loghostcolumn=host logrhostcolumn=rhost logtimecolumn=logtime account required pam_mysql.so user=root passwd=******** host=localhost db=vsftpd table=users usercolumn=name passwdcolumn=passwd crypt=2 sqllog=1 logtable=logs logmsgcolumn=msg logusercolumn=user logpidcolumn=pid loghostcolumn=host logrhostcolumn=rhost logtimecolumn=logtime
オプションの意味
user | MySQLに接続するユーザ名 |
---|---|
passwd | MySQLに接続するユーザのパスワード |
host | MySQLサーバーホスト |
db | vsftpdで利用するデータベース名 |
table | vsftpdで利用するテーブル名 |
usercolumn | ユーザ名のカラム |
passwdcolumn | パスワードのカラム |
crypt | 暗号化方法 |
0はplain | |
1はcryptを利用 | |
2はMySQLのPASSWD()関数を利用 | |
3はMD5を利用 | |
4はSHA1を利用 | |
use_323_passwd | ture※MySQLのPASSWD()関数がv3互換の場合trueにする。規定値はfalse |
sqllog | ログ出力の指定。1は出力 |
logtable | ログ保存テーブル名 |
logmsgcolumn | メッセージ保存カラム |
logusercolumn | ユーザ名保存カラム |
logpidcolumn | PID番号保存カラム |
loghostcolumn | ホスト名保存カラム |
logrhostcolumn | リモートホスト名保存カラム |
logtimecolumn | 時間保存カラム |
vsftpdの設定
/etc/vsftpd/vsftpd.confを修正する。
仮想ユーザが利用できるように設定する。追加でOKかと…
virtual_use_local_privs=YES guest_enable=YES local_root=/home/virtual/$USER hide_ids=YES guest_username=virtual user_sub_token=$USER
オプションの意味
virtual_use_local_privs=YES | 仮想ユーザの権限はローカルユーザと同様となる。既定ではanonymousユーザと同様となる。 |
---|---|
guest_enable=YES | 全てのユーザはguestとして扱われる。guest_usernameの設定によりリアルユーザ名が決められる。 |
local_root=/home/virtual/$USER | ログインユーザをchroot環境にした際のrootパス |
hide_ids=YES | 全てのユーザとグループ情報はftpと表示される |
guest_username=virtual | 全てのユーザのリアルネームをvirtualとする |
user_sub_token=$USER | それぞれの仮想ユーザのホームディレクトリパスをテンプレートに基づき自動的に作成する。 |
user_sub_tokenについて色々調べた結果、この設定でホームディレクトリを自動的に作成すると記述があるけど、 実際にはディレクトリが作成されるのではなく、ホームディレクトリパスの文字列を生成するのみと判明。
従って、仮想ユーザがFTPログインした際に設定されるホームディレクトリがファイルシステム上に 実際作成されていなければログインしてもchrootができないためにエラーとなる。
OS側の設定
vsftpd.confのguest_usernameで設定したユーザ名をOS上に作成して、仮想ユーザ用のホームディレクトリを作成する。
ホームディレクトリにはguest_usernameで設定したユーザ名で接続することとなるのでディレクトリパーミッションを適切に設定しておく必要がある。
useradd virtual mkdir ~virtual/test1@test.local mkdir ~virtual/test2@test.local chown -R virtual ~virtual/test1@test.local chown -R virtual ~virtual/test2@test.local
いざ、テスト!
これで、テスト接続してみるのだ。 ポイントとしてはログ情報
- vsftpdのログを確認(/var/log/vsftpd.log)
- MySQLのクエリログを出力しておいてクエリを確認(/var/log/query.log等、my.cnfで設定する)
- 認証ログを確認(/var/log/audit/audit.log)