がらくたネット

アフィリエイト広告を利用しています


vsftpdとMySQL

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 これがミソ:-D

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)