使用 OpenBSD 3.8 系统自带的 FTPD 搭建 FTP 服务器,远比大多数人想象中要简单,不过其中仍有一些容易被忽略的细节值得注意。OpenBSD 的 ftpd 有一个显著特点:它没有传统的配置文件,所有功能调整都必须通过启动时传入的参数来完成。换句话说,只要理解了这些参数的含义,整个服务器的行为就完全处于你的掌控之下。
关于 ftpd 的详细参数说明,可以通过 man 手册直接查阅:
$ man ftpd
启动 ftpd 主要有三种方式,每种方式在不同场景下各有优劣。
启动方式的三种选择
方式一:inetd 方式
这是最经典的做法。在 /etc/inetd.conf 文件中,有一行专门用于启动 FTP 服务:
ftp stream tcp nowait root /usr/libexec/ftpd ftpd -US
这里的 -US 就是传递给 ftpd 的参数,当然你也可以根据实际需求自由组合。采用这种方式还需要确保 inetd 服务本身已经启动。OpenBSD 默认开启了 inetd,可以在 /etc/rc.conf 中确认 inetd_flags 变量的值。
方式二:"rc" 方式
如果你希望系统启动时自动加载 FTP 服务,那就配置 /etc/rc.conf 或 /etc/rc.conf.local 文件。设置好 ftpd_flags 变量,并确保该行没有被注释。需要注意的是,这种修改需要重启系统才会生效。
方式三:命令行直接启动
这种方式最为灵活,修改参数后即时生效,无需重启任何服务:
# /usr/libexec/ftpd -4DllUS
至于如何停止 ftpd,也非常简单:要么在 /etc/rc.conf 中注释掉 ftpd_flags,要么直接用 ps 找到进程 ID 然后 kill 掉。
核心参数解读
ftpd 的参数虽然很多,但实际常用的只有这几个。掌握了它们,剩下的组合不过是按需拼装而已。
- -4:配合
-D使用时,强制 ftpd 只监听 IPv4 地址。 - -6:与 -4 类似,但强制使用 IPv6。
- -A:只允许匿名登录,除非同时指定了
-n选项。 - -D:以守护进程方式运行,自行监听端口并 fork 子进程处理连接。在高负载服务器上,这种方式比 inetd 更节省资源。
- -d:将调试信息通过 LOG_FTP 写入 syslog。
- -l:记录每次 FTP 会话的成功或失败。如果重复指定两次,则还会记录 get、put、delete 等操作详情。
- -U:将每个并发会话记录到
/var/run/utmp,输出格式类似 who 命令。 - -n:禁止匿名登录。未指定时默认允许匿名访问。
- -S:记录匿名用户的下载情况到
/var/log/ftpd(前提是该文件存在)。 - -T maxtimeout:设置连接超时时间,默认是 2 小时。
- -u mask:强制设置 umask,覆盖
/etc/login.conf中的配置(通常是 022),并且禁止用户使用 chmod。
掌握这些参数后,组合出符合自身需求的启动配置就水到渠成了。
场景一:只允许系统帐号登录
如果只想让系统用户通过 FTP 访问资源,配置其实很简单。匿名登录需要系统中存在名为 ftp 的帐户,而 OpenBSD 默认不带这个帐户,所以即便设置允许匿名登录,实际上也无法成功。因此,只需在 /etc/rc.conf 中将 ftpd_flags 设为 -D 即可。当然,你也可以加上其他参数,比如:
ftpd_flags="-4DllUSn"
参考上面各参数的含义,这组配置代表什么应该一目了然。
场景二:允许匿名用户访问
如果需要对外开放匿名 FTP 资源,那就需要手动创建一个特殊用户——ftp。匿名用户登录后,实际上是以 ftp 用户的身份进行操作。出于安全考虑,这个用户需要被设置成最低权限:没有可用的密码,没有可用的 shell,并且登录后被 chroot。
添加 ftp 帐户
首先,在 /etc/shells 中添加两个不可实际使用的 shell:
# echo '/sbin/nologin' >>/etc/shells # echo '/usr/bin/false' >>/etc/shells
这样做的目的是让 ftp 用户无法通过 shell 登录系统。
接下来,用 adduser 命令创建用户。推荐使用 -shell 参数指定 shell:
# adduser -shell /sbin/nologin Enter username []: ftp Enter full name []: anonymous ftpd user Enter shell bash csh ksh nologin sh [/sbin/nologin]:
如果不加 -shell 参数,系统会拒绝使用 /sbin/nologin 作为 shell:
# adduser Enter username []: ftp Enter full name []: anonymous ftpd user Enter shell bash csh ksh nologin sh [bash]: /sbin/nologin /sbin/nologin: is not allowed!
下面是一个完整的添加示例,将 ftp 用户的 home 目录设为 /var/ftp:
# adduser -shell /sbin/nologin -home /var ... Enter username []: ftp Enter full name []: anonymous ftpd user Enter shell bash csh ksh nologin sh [/sbin/nologin]: ENTER Uid [1001]: ENTER Login group ftp [ftp]: ENTER Login group is "ftp". Invite ftp into other groups: guest no [no]: ENTER Login class daemon default staff [default]: ENTER Enter password []: ENTER # 直接按回车,设置一个不可用的密码 Set the password so that user cannot logon? (y/n) [n]: y ... Added user "ftp" Copy files from /etc/skel to /var/ftp Add another user? (y/n) [y]: n Goodbye!
用户添加完成后,记得把从 /etc/skel 复制过来的那些 "dot files" 删掉,因为这些文件的第一行通常会暴露系统信息。比如 ~/.cshrc 中就有类似 $OpenBSD: dot.cshrc,v 1.5 ... 的标记。删除它们:
# rm -f /var/ftp/.*
目录权限设置
安全的核心在于权限控制。下面几个目录的设置至关重要:
~ftp 目录(/var/ftp):owner 设为 root,权限设为任何人都不可写(555):
# chown -R root:wheel /var/ftp # chmod -R 555 /var/ftp
~ftp/bin 目录:可选。如果需要匿名用户执行一些命令,可以把命令复制到此目录下,权限设为只执行(111)。不过,除非有明确的必要,否则不推荐创建这个目录。
# mkdir /var/ftp/bin # chown -R root:ftp /var/ftp/bin # chmod -R 111 /var/ftp/bin/*
~ftp/etc 目录:同样可选,且不推荐创建。详细的说明可以参考 ftpd 的 man 手册。
~ftp/pub 目录:这才是真正存放公开资源的地方。权限设为 555:
# chown -R root:ftp /var/ftp/pub # chmod -R 555 /var/ftp/pub
对于大多数人来说,只创建 ~ftp/pub 目录并设置好权限就足够了。
chroot 匿名用户
ftpd 在启动时会读取 /etc/ftpchroot 文件,将该文件中列出的用户全部 chroot 到各自的 home 目录。只需要将 ftp 用户名加到这个文件中即可:
# file : /etc/ftpchroot ftp bibby
这样一来,ftp 用户登录后,能看到的就只有自己的 home 目录,无法触及系统其他部分。
其他相关文件
- /etc/ftpusers:列出所有被禁止登录 FTP 的用户。
- /etc/ftpwelcome:用户登录时显示的欢迎信息。
- /etc/motd:如果
/etc/ftpwelcome不存在,则使用此文件作为欢迎信息。 - .message:可放置在
~ftp下的任何子目录中,用户进入该目录时显示其内容。
上述步骤走完,一个兼具安全性和功能性的 OpenBSD FTP 服务器就搭建完成了。合理设置参数,谨慎控制权限,匿名服务也可以很可靠。
