我有一个运行 sftpd 的 Ubuntu 服务器,其中/var/data/chroot/
是来自远程中央 NFS 服务器的 NFS 安装,每个 sftpd 用户的 chroot home 是,/var/data/chroot/<username>/
并且每个用户都有一个日志设备/var/data/chroot/<username>/dev/log
,我使用 syslog-ng 成功读取该日志设备:
source s_chroot_<username> { unix-stream("/var/data/chroot/<username>/dev/log" optional(yes) ); };
destination d_sftp_<username> { file("/var/log/sftp/<username>.log"); };
现在我有第二个并行的 sftpd 服务器,具有相同的用户数据库,也/var/data/chroot/
通过 NFS 挂载,并且具有相同的 syslog-ng 配置,因此每个用户都可以在一台服务器或另一台服务器上登录。这是为了高可用性。到目前为止这有效。
现在不工作的是 sftpd 日志记录: sftp 用户的日志仅在一sftp 服务器独占,这是 syslog-ng 启动最少的服务器,因为据我了解,它为每个用户的 .sftp 文件获取独占的 unix 套接字文件锁/dev/log
。
因此,如果用户登录到 syslog-ng 启动最少的第一台服务器,则该用户的 sftp 活动将记录在第一台服务器上。但是,如果用户在第二台服务器上登录,则无论是在第二台服务器上还是在第一台服务器上,都不会记录其 sftp 活动。
如果随后在第二台服务器上重新启动 syslog-ng,则 sftp 用户的活动仅在第二台服务器上以独占方式记录,并且仅用于在第二台服务器上的登录。
当用户登录到该服务器时,如何让 sftp 用户的活动记录在每个 sftp 服务器上,而用户的主页通过 NFS 在两台服务器上共享?
答案1
我的解决方法如下:
创建一个当地的在其下创建用户子目录的目录:
sudo mkdir /var/data/dev
对于每个用户名<username>
和用户的主要组,<groupname>
请执行以下操作:
sudo mkdir /var/data/dev/<username>
sudo chmod 550 /var/data/dev/<username> # This restrictive permission is a requirement I think
sudo chgrp <groupname> /var/data/dev/<username> # so the user can read the directory
/var/data/chroot/<username>/dev
所以新目录与现有目录(位于 nfs mount 上)完全相同/var/data/chroot/
。
那么 现在mount --bind /var/data/dev/<username> /var/data/chroot/<username>/dev
这样做/var/data/chroot/<username>/dev
实际上是在 sftp 服务器上进行本地操作,而不是在 nfs 挂载上进行。
然后更改 syslog-ng 配置
从
source s_chroot_<username> { unix-stream("/var/data/chroot/<username>/dev/log" optional(yes) ); };
到
source s_chroot_<username> { unix-stream("/var/data/dev/<username>/log" optional(yes) ); };
(这不是严格需要的,但我认为 syslog-ng 现在肯定只从本地文件读取,保证不再从 nfs 挂载,这是很好的)
无论用户登录一台 sftp 服务器还是另一台 sftp 服务器,syslog-ng 现在都可以在受影响的 sftp 服务器上记录 sftp 会话。
虽然我非常想避免多个(在我的例子中是数百个)绑定挂载,但我认为这种解决方法是可以接受的,因为影响仅限于日志记录功能而不是 sftp 服务本身。说起来,如果绑定安装出现问题,影响只是没有 sftp 会话日志记录。而且,这非常简单、统一、清晰。