我已经使用以下说明安装了 vsftpd
http://www.camcloud.com/blog/setup-vsftpd-with-virtual-users-using-mysql
我试图在每个用户登录 ftp 服务器时自动/动态地创建目录。
我有以下/etc/pam.d/vsftpd
内容才不是自动创建目录。
静态目录配置代码
session optional pam_keyinit.so force revoke
auth required pam_mysql.so verbose=1 user=mydbusername passwd=mydbpass host=localhost db=mydb table=mydb_table usercolumn=username passwdcolumn=password crypt=0
account required pam_mysql.so verbose=1 user=mydbusername passwd=mydbpass host=localhost db=mydb table=mydb_table usercolumn=username passwdcolumn=password crypt=0
我的问题是如何正确使用pam_mkhomedir使用 mysql 的用户名创建目录。我找到了这个文档https://www.dalemacartney.com/2012/07/30/auto-creation-of-user-home-directories-in-linux/
我想知道这是否是正确的配置,我还想知道如何为目录设置他的用户名。我没有在代码中看到应用用户名的任何地方,或者这只是在幕后发生的事情?
动态目录配置代码
session optional pam_keyinit.so force revoke
auth required pam_mysql.so verbose=1 user=mydbusername passwd=mydbpass host=localhost db=mydb table=mydb_table usercolumn=username passwdcolumn=password crypt=0
account required pam_mysql.so verbose=1 user=mydbusername passwd=mydbpass host=localhost db=mydb table=mydb_table usercolumn=username passwdcolumn=password crypt=0
session required pam_mkhomedir.so skel=/etc/ftp/ umask=0022
答案1
session required pam_mkhomedir.so skel=/etc/ftp/ umask=0022
如您所见,pam_mkhomedir.so
作用于会议等级。这意味着它的作用后用户已(由设施auth
)进行身份验证。为此,它定义了以下 PAM 特定函数:
PAM_EXTERN
int pam_sm_open_session(pam_handle_t * pamh, int flags,
int argc, const char **argv);
正如我所说,当用户通过身份验证时会调用此函数。因此,当它检索 PAM 用户句柄时...
/* Determine the user name so we can get the home directory */
retval = pam_get_item(pamh, PAM_USER, (const void **)&user);
...它可以访问一个名称经过验证的,现有用户。有了这些信息,模块将能够通过简单的方法检索它需要的内容(主目录的路径)getpwnam(3)
图书馆电话:
/* Get the password entry */
pwd = getpwnam(user);
这将返回以下结构,其中填充有关用户的信息:
struct passwd {
char *pw_name; /* username */
char *pw_passwd; /* user password */
uid_t pw_uid; /* user ID */
gid_t pw_gid; /* group ID */
char *pw_gecos; /* user information */
char *pw_dir; /* home directory */
char *pw_shell; /* shell program */
};
现在,如果您想知道这些信息来自哪里,请查看/etc/nsswitch.conf
。这名称服务开关(NSS) 在此提供有关以下方面的信息名字一般来说(可以是用户名、别名、组、主机……参见nsswitch.conf(5)
更多细节)。如果您遵循的指南足够完整,它应该让您配置 PAM和NSS:第一个处理身份验证和帐户/会话管理,而另一个仅提供名称信息。换句话说,第一个可以执行读/写操作,而第二个是只读的。
一旦pam_mkhomedir.so
检索到用户主目录的路径,它所要做的就是检查它是否存在,如果不存在则创建它:
/* Stat the home directory, if something exists then we
* assume it is correct and return a success. */
if(stat(pwd->pw_dir, &st) == 0) return PAM_SUCCESS;
return create_homedir(..., pwd, ...);
该create_homedir
函数是由模块本身定义的,我将其粘贴到这里有点太长了。只把它看作一个大mkdir(2)
呼叫,它处理特定情况并确保一切顺利。如果您对更多细节感兴趣,请查看pam_mkhomedir.so
的源代码。我用了这个版本的对于我的回答(它是由贾森·冈索普,他的名字也出现在我的pam_mkhomedir.so
联机帮助页)。
现在,就我而言,我认为您遵循的指南有点不完整,或者至少,它让您创建的 MySQL 表是:
+----------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| username | varchar(30) | NO | UNI | NULL | |
| pass | varchar(50) | NO | | NULL | |
+----------+-------------+------+-----+---------+----------------+
该表可能足够详细,足以让 VSFTPd 正常工作。由于它配置了主根目录,因此可以轻松确定用户的主目录:$ftp_root/username
。这实际上是通过local_root
参数设置的:
local_root=/home/vsftpd/$USER
不过,pam_mkhomedir.so
不是VSFTPd。它不使用这种机制,而是依赖于NSS(通过getpwnam(3)
)。问题是:您的 MySQL 表没有为 NSS 提供足够的信息来填充struct passwd
我们之前看到的信息。为了让 NSS 使用 MySQL 作为源,您需要安装nss-mysql,这需要更大的 MySQL 表。这将需要调整 VSFTPd 配置,但让 VSFTPd 和 nss-mysql 共存应该没有问题。
这个目录给出了最小 nss-mysql 设置的示例。 MySQL用户表定义如下:
+-----------------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| username | varchar(255) | NO | | NULL | |
| username_canonical | varchar(255) | NO | UNI | NULL | |
| email | varchar(255) | NO | | NULL | |
| email_canonical | varchar(255) | NO | UNI | NULL | |
| enabled | tinyint(1) | NO | | NULL | |
| salt | varchar(255) | NO | | NULL | |
| password | varchar(255) | NO | | NULL | |
| last_login | datetime | YES | | NULL | |
| locked | tinyint(1) | NO | | NULL | |
| expired | tinyint(1) | NO | | NULL | |
| expires_at | datetime | YES | | NULL | |
| confirmation_token | varchar(255) | YES | | NULL | |
| password_requested_at | datetime | YES | | NULL | |
| roles | longtext | NO | | NULL | |
| credentials_expired | tinyint(1) | NO | | NULL | |
| credentials_expire_at | datetime | YES | | NULL | |
+-----------------------+--------------+------+-----+---------+----------------+
现在,您自己可能不需要所有这些字段,但请记住struct passwd
我们之前看到的结构,并确保 nss-mysql 有足够的数据来填充它:)此外,nss-mysql 配置文件足够灵活,可供您使用任何事物的默认值。