[OpenBSD]

[索引] [第九章 - 转到OpenBSD] [第十一章 - X Window 系统]

10 - 系统管理


目录


10.1 - 为什么我想su到root时说我在错误的组中?

已经存在的用户必须手动添加到 "wheel"组中, 这是因为安全的原因, 您应该谨慎地赋予某个用户这项权限。在OpenBSD中wheel组的成员可以使用su(1)命令变成root, 而非wheel 组的用户无法使用su命令, 这里有一个例子, 修改/etc/wheel文件就可以将用户9971添加到"wheel"组。

如果您使用adduser(8)新添加一个用户, 您可以在系统询问"Invite user into other groups:"时将这个用户添加到wheel组, 系统会修改您的/etc/group文件, 看起来就像这样:

wheel:*:0:root, 9971

如果您仅想给用户有限的root权限但不想将他加入"wheel"组, 请使用 sudo(8) 命令。

10.2 - 如何复制文件系统?

复制文件系统使用 dump(8)restore(8) 命令, 例如复制目录 SRC 下的所有文件到目录 DST:

# cd /SRC; dump 0f - . | (cd /DST; restore -rf - )

设计dump是为了给您提供丰富的备份功能, 如果您只想复制一个目录或它的一部分的使用 tar(1) 可能会快一些。这个命令您可能很熟悉:

# cd /SRC; tar cf -  . | (cd /DST; tar xpf - )

10.3 - 我怎样让程序随系统启动?(概述rc(8))

OpenBSD使用 rc(8) 模式控制启动, 它是用一系列关键文件来控制启动过程。

rc(8)怎样工作?

系统管理员的需配置的主要文件集中在 /etc/rc.conf (或者 /etc/rc.conf.local ), /etc/rc.local/etc/rc.shutdown 想了解 rc(8) 的工作模式, 看下面:

系统内核启动后, 开始执行 /etc/rc :

运行OpenBSD自带的后台程序及服务

大多数系统自带的程序或服务可以通过修改 /etc/rc.conf 配置文件随系统启动。我们先看一下 /etc/rc.conf 文件。您会看到像这行:

ftpd_flags=NO           # for non-inetd use: ftpd_flags="-D" 

您会看到ftpd没有随系统启动(至少不是通过rc(8)启动的, 更多的信息请参看 Anonymous FTP FAQ。)。所有行的后面全有一个注释告诉您如何正确运行这些后台程序或服务。但是这并非说您必须使用这些注释的参数来运行程序或服务, 您可以参照这些后台程序或服务的用户手册, 用您需要的模式运行它们。例如, http(8)有一些附属的参数:

httpd_flags=NO          # for normal use: "" (or "-DSSL" after reading ssl(8))  

显然您看见了您可以不需要加任何参数来运行http(8), 也就是设置成: " httpd_flags=""" 。但是如果您想启用ssl支持(参考 SSL 用户手册或者 ssl(8) )您就要像这样:"httpd_flags="-DSSL""设定http的启动方式。

一个好建议是永远不要改动 /etc/rc.conf 文件, 而应该创建一个 /etc/rc.conf.local 文件, 将您在 /etc/rc.conf 文件里的需要改动的程序设定复制到这个文件里进行修改。这样会使今后的升级过程更加顺利——所有的用户设定全在一个文件里。

启动和配置本地后台程序

对那些拟通过packages或别的途径安装的用户程序包来说, 您需要使用 /etc/rc.local 文件, 例如, 我安装一个了程序位于 /usr/local/sbin/daemonx 目录。我想让它随系统启动。需要在 /etc/rc.local 文件里加入一些内容, 想这样:

if [ -x /usr/local/sbin/daemonx ]; then
             echo -n ' daemonx';       /usr/local/sbin/daemonx
fi

(如果这个程序没有随系统启动, 别忘了在命令行后面加上"&"。)

现在开始, 这个程序daemonx会随系统启动。您也许会看到一些错误提示, 如果没有错误, 程序启动后系统会显示一行内容像这样:

Starting local daemons: daemonx. 

rc.shutdown

/etc/rc.shutdown 是一个关机脚本。把您需要在关机前需要运行的任务全放在这个脚本里。如果您有apm, 您也可以使用 "powerdown=YES"命令, 它等同于 "shutdown -p"命令。

10.4 为什么OpenBSD拒绝远程用户的转发请求?

试试这样:

# grep relay-domains /etc/mail/sendmail.cf

屏幕输出可能像这样:

FR-o /etc/mail/relay-domain

如果没有这个文件, 您需要创建它。 您需要在这个文件中按下面的语法设定发送邮件的远程主机:

 .domain.com    #允许转发的主机域名domain.com。
 sub.domain.com #允许转发的主机子域名sub.domain.com, 以及所有允许转发的属于domain.com的子域。
 10.2           #在IP段10.2.*.*允许所有转发。

别忘记发送 'HangUP'信号给sendmail (这个信号可以让大多数后台运行的程序重新读取它们的配置文件):

# kill -HUP `head -1 /var/run/sendmail.pid`

更多信息请参看

10.5 - 我已经设置了POP服务器, 但我访问POP时怎么会有错误信息?

多数引起POP出问题的原因是临时文件和锁定文件。如果您的POP服务器发送了一条错误信息:

-ERR Couldn't open temporary file, do you own it?  

尝试这样设定一下您的许可权限:

permission in  /var
drwxrwxr-x   2 bin     mail     512 May 26 20:08 mail
permissions in  /var/mail
-rw-------   1 username   username        0 May 26 20:08 username  

另外需要检查的是用户是否具有自己的 /var/mail 文件的所有权。 您可能会说当然是这种情况了(例如 /var/mail/joe 的所有者应该是joe), 但是如果没有正确的设定就会引起这样的问题!

当然, 开启邮件用户组对 /var/mail 的写权限可能会引起一些未知的含混的安全问题。如果您不开起就不会出问题吗?实际上也会有安全问题!(特别是您有一个引人注目的网站、ISP等.....), 您可以从ports树中选择几种POP服务程序, 您也可以使用OpenBSD系统默认安装时已经带的popa3d, 或者您保留您POP的错误设定(像dot locking), 或者您改变您的锁定目录(尽管这些锁定仅对POP程序有效。)

说明: OpenBSD并不存在一个"mail"用户组, 如果您需要可以在 /etc/group 文件中创建它。加上一行像这样:

mail:*:6:

回答的很充分了吧。

10.6 - 为什么Sendmail忽略/etc/hosts?

默认情况下, Sendmail使用DNS进行域名解析而不是使用 /etc/hosts 文件。 您可以通过修改 /etc/mail/service.switch 文件进行设定。

如果您想让sendmail优先使用 /etc/hosts 文件进行域名解析, 您需要创建一个 /etc/mail/service.switch 文件, 让它包含下面的一行:

hosts       files dns

如果您只想让sendmail使用hosts 文件查询, 这样写:

hosts       files

发给sendmail 一个HUP信号:

kill -HUP `head -1 /var/run/sendmail.pid`

这些设定就会起作用了。

10.7 - 使用SSL(8)配置安全的HTTP服务器

OpenBSD提供了一个SSL功能的httpd以及RSA库。为了使用httpd(8) 您必须先先创建证书。它会保存在/etc/ssl/ 下的相应关键字/etc/ssl/private/目录里。下面的步骤摘自ssl(8)的用户手册, 更多的信息请直接参考手册。本FAQ仅涉及了如何为web服务器生成一个RSA证书, 如何生成DSA证书请参考ssl(8)的用户手册。

首先, 您需要创建您的server key并使用OpenSSL进行认证:

# openssl genrsa -out /etc/ssl/private/server.key 1024

或者, 您想让这个key有一个加密短语, 您需要在服务启动时输入

# openssl genrsa -des3 -out /etc/ssl/private/server.key 1024

下面用来生成证书的签发请求以便获得认证机构(CA)签署的证书, 用如下命令:

# openssl req -new -key /etc/ssl/private/server.key -out /etc/ssl/private/server.csr

这个server.csr文件可以提交给那些可以颁发key的认证权威机构。例如, CA就是一个Thawte认证机构, 您可以在http://www.thawte.com/上找到。

如果您无法获得key, 或者您想自己进行认证, 您可以是用下面的命令:

# openssl x509 -req -days 365 -in /etc/ssl/private/server.csr \
-signkey /etc/ssl/private/server.key -out /etc/ssl/server.crt 

如果存在/etc/ssl/server.crt/etc/ssl/private/server.key 这两个文件, 您就可以让httpd(8)使用 -DSSL 标签 (请参看 section about rc(8) ), 别忘了打开您的机器的443端口。

10.8 - 我使用vi(1)修改了/etc/passwd, 为什么不起作用?

如果您直接修改 /etc/passwd 文件, 您的修改不会生效。OpenBSD用pwd_mkdb(8)动态的生成/etc/passwd 密码文件。OpenBSD的密码文件是 /etc/master.passwd 。参考pwd_mkdb(8),


FILES
     /etc/master.passwd  current password file
     /etc/passwd         a 6th Edition-style password file
     /etc/pwd.db         insecure password database file
     /etc/pwd.db.tmp     temporary file
     /etc/spwd.db        secure password database file
     /etc/spwd.db.tmp    temporary file

传统的Unix中, 任何使用该系统的人都可以接触诸如/etc/passwd等密码文件(而这正是破解程序的首要攻击目标)。从BSD4.4开始引入了master.passwd文件, 这个文件采用一种扩展格式(提供了超越/etc/passwd密码文件的加密选项), 并且只有root用户可以读取。为了更快地存取数据, 库文件通常通过读取/etc/pwd.db 和 /etc/spwd.db调用这个数据。

OpenBSD的确提供了一个工具 vipw(8) 来修改您的密码文件, 它用vi(您也可以通过定义per $EDITOR来选择您喜欢的编辑器)来编辑 /etc/master.passwd 文件。当您每次编辑完成后, vipw 会重新生成 /etc/passwd、/etc/pwd.db 和 /etc/spwd.db 文件。Vipw还负责锁定这些密码文件, 所以如果任何人想同时修改这些文件, 他们将会被拒绝访问。

10.9 - 如何增加或者删除用户?

OpenBSD提供两个工具可以轻松地为系统添加用户:

您也可以使用vipw(8)来手动添加用户, 但是操作起来很麻烦。

在OpenBSD中最简单的添加用户方法是使用adduser(8) 脚本。您可以通过编辑 /etc/adduser.conf 文件配制 adduser(8) 脚本, adduser(8) 可以一致性检验 /etc/passwd/etc/group 和shell数据库, 它将生成用户的通行证和 $HOME 目录, 甚至可以发送一条欢迎信息给用户,本例中我们为系统添加一个测试用户testuser,他/她的 $HOME 目录为 /home/testuser , 属于guest组, 并且使用的shell是 /bin/ksh

# adduser
Use option ``-silent'' if you don't want to see all warnings and questions.
Reading /etc/shells
Reading /etc/login.conf
Check /etc/master.passwd
Check /etc/group
Ok, let's go.
Don't worry about mistakes. I will give you the chance later to correct any input.
Enter username []: testuser
Enter full name []: Test FAQ User
Enter shell csh ksh nologin sh [sh]: ksh
Uid [1002]: Enter
Login group testuser [testuser]: guest
Login group is ``guest''. Invite testuser into other groups: guest no 
[no]: no
Login class auth-defaults auth-ftp-defaults daemon default staff 
[default]: Enter
Enter password []: Type password, then Enter
Enter password again []: Type password, then Enter
Name:        testuser
Password:    ****
Fullname:    Test FAQ User
Uid:         1002
Gid:         31 (guest)
Groups:      guest
Login Class: default
HOME:        /home/testuser
Shell:       /bin/ksh
OK? (y/n) [y]: y
Added user ``testuser''
Copy files from /etc/skel to /home/testuser
Add another user? (y/n) [y]: n
Goodbye! 
删除用户您应使用rmuser(8)命令, 它可以删除该用户的所有文档。 它会删除该用户所有的crontab(1)条目、$HOME 目录(如果它属于该用户)、该用户的邮件。 当然它也会删除该用户的 /etc/passwd /etc/group 条目。下面的例子我们删除上例中新添加的用户。注意系统会提示您输入用户名, 还有是否删除该用户的home目录。
# rmuser
Enter login name for user to remove: testuser
Matching password entry:
testuser:$2a$07$ZWnBOsbqMJ.ducQBfsTKUe3PL97Ve1AHWJ0A4uLamniLNXLeYrEie:1002
:31::0:0:Test FAQ User:/home/testuser:/bin/ksh
Is this the entry you wish to remove? y
Remove user's home directory (/home/testuser)? y
Updating password file, updating databases, done.
Updating group file: done.
Removing user's home directory (/home/testuser): done.  

使用user(8)系列命令添加用户

这些命令没有像adduser(8)命令那样使用脚本可以提供许多交互式输入。

全套命令有:

实际添加用户

user(8)并非采用交互方式添加用户, 最简单有效的添加用户方法是使用adduser(8)命令。 实际使用的命令 /usr/sbin/user 仅是所有 /usr/sbin/user* 命令的一个前缀命令。所以, 添加用户时您可以使用 user add 或者 useradd, 您随便选择使用哪一个全有同样的功效。

在这个例子中, 我们添加一个与上例中具有相同特性的用户。 如果您在添加用户前熟悉了默认设定, useradd(8)还是方便得多。这些设定在文件 /etc/usermgmt.conf 里, 您可以用下面的方法显示它们:

$ user add -D
group           users
base_dir        /home
skel_dir        /etc/skel
shell           /bin/csh
inactive        0
expire          Null (unset)
range           1000..60000  

除非您用命令行进行更改否则上面的这些默认设定值将赋予新用。例如在这个例子中, 我们想把这用户设定在guest组而不是users组。 还有一个需要处理的就是在命令行手动设置密码, 这是一个经过加密处理的的密码, 所以您必须先用encrypt(1)命令创建它, 例如: OpenBSDd的默认加密密码是经过6次海豚算法生成的, 下面的例子为useradd(8)产生一个经过加密的密码。

$ encrypt -p -b 6
Enter string:
$2a$06$YOdOZM3.4m6MObBXjeZtBOWArqC2.uRJZXUkOghbieIvSWXVJRzlq 

现在我么已经有了加密的密码, 我们为用户添加这个密码。

# user add -p '$2a$06$YOdOZM3.4m6MObBXjeZtBOWArqC2.uRJZXUkOghbieIvSWXVJRzlq' -u 1002 \
-s /bin/ksh -c "Test FAQ User" -m -g guest testuser

说明: 别忘了为密码字串加上 ' ' (单引号), 而不是 " " (双引号), 因为shell会在发送给user(8)之前要先解释它。 如果您要创建用户的home目录和将 /etc/skel 下的文件复制过去需要使用 -m 选项。

可以使用下面的命令检查用户是否被正确地添加了:

$ ls -la /home
total 14
drwxr-xr-x   5 root      wheel   512 May 12 14:29 .
drwxr-xr-x  15 root      wheel   512 Apr 25 20:52 ..
drwxr-xr-x  24 9971      wheel  2560 May 12 13:38 9971
drwxr-xr-x   2 testuser  guest   512 May 12 14:28 testuser
$ id testuser
uid=1002(testuser) gid=31(guest) groups=31(guest)
$ finger testuser
Login: testuser                         Name: Test FAQ User
Directory: /home/testuser               Shell: /bin/ksh
Last login Sat Apr 22 16:05 (EDT) on ttyC2
No Mail.
No Plan.  

除了这些命令, user(8)还提供了自己的查看用户信息用命令 userinfo(8)。

$ userinfo testuser
login   testuser
passwd  *
uid     1002
groups  guest
change  Wed Dec 31 19:00:00 1999
class
gecos   Test FAQ User
dir     /home/testuser
shell   /bin/ksh
expire  Wed Dec 31 19:00:00 1999 

删除用户

使用user(8)系列命令中的userdel(8), 即使您没有使用过也会觉得很简单。 例如删除上例中的用户:

# userdel -r testuser

如果您希望同时删除用户的home目录这里必须使用 -r 选项。 如果您只想锁定用户帐号但不删除任何用户文件, 那么这里就不用 -r 选项而使用 -p 选项。

10.10 - 如何创建只能访问ftp的账号 (非匿名账号!)?

有几种方法, 但是最常用的方法是把诸如 "/usr/bin/false" 加入到 "/etc/shells"中, 然后您把ftp用户的shell设置成 "/usr/bin/false", 他们可以使用ftp功能但不能用交互式的方式登陆系统。您可能还需要将他们限制在自己的home目录内以限制对其余的目录的访问。

10.11 - 配置用户的磁盘限额

磁盘限额用来限制用户在硬盘上占用的空间。在您的硬盘较小时这个功能很有用。可以对用户或组进行限制。

配制磁盘限额首先您需要确认Kernel Configuration里有"option QUOTA", 标准内核里已经包含了这个选项。然后您需要在/etc/fstab里做标注以便启用磁盘限额功能。您需要使用关键字userquota 和 groupquota为每个需要限制的分区作磁盘限额标注。默认情况在限制分区的根目录下会产生quota.user 和 quota.group这两个文件, 它们保存了该分区的磁盘限额信息。您也可以通过修改/etc/fstab的参数设定以其它文件作为作为磁盘限额配置文件, 例如 "userquota=/var/quotas/quota.user"。下面的例子中/etc/fstab启用了一个分区的磁盘限额, 但是磁盘限额配置文件不在默认的位置:

/dev/wd0a / ffs rw, userquota=/var/quotas/quota.user 1 1 

现在我们使用edquota(8)命令设定用户的磁盘限额, 简单的用法就是 "edquota <user>"。如果默认编辑器没有被修改edquota(8)会使用vi(1)来编辑磁盘限额。例如:

# edquota 9971

您的屏幕输出像这样:

Quotas for user 9971:
/: KBytes in use: 62, limits (soft = 0, hard = 0)
        inodes in use: 25, limits (soft = 0, hard = 0) 

要进行限制, 编辑它, 比如:

Quotas for user 9971:
/: KBytes in use: 62, limits (soft = 1000, hard = 1050)
        inodes in use: 25, limits (soft = 0, hard = 0)  

注意限额配置以1K为单位。这个例子中我们设定softlimit为1000k, hardlimit为1050k。这里softlimit的意思是:当用户占用的磁盘空间超过这个设定值系统会在一个宽限期内给出警告信息直至用户占用的磁盘空间小于softlimit的设定值, 宽限期可以使用edquota(8)的 -t 选项进行设定。一旦超过了宽限期系统会按用户的hardlimit来处理softlimit, 这会导致用户的分配磁盘无法继续使用。

现在磁盘限额已经设定, 您需要起用它。使用quotaon(8)命令:

# quotaon -a

它将通过/etc/fstab启用分区的磁盘配额选项。现在我们已经启用了磁盘限额, 您可以通过quota(1)命令查看磁盘限额情况。使用命令"quota <user>" 可以查看该用户的磁盘限额情况。如果您没有对quota添加参数, 它会提供您的磁盘限额统计。例如:

# quota 9971

屏幕输出像这样:

Disk quotas for user 9971 (uid 1001): 
     Filesystem  blocks   quota   limit   grace   files   quota   limit   grace
              /      62    1000    1050              27       0       0   

默认情况下 /etc/fstab 设定的磁盘限额会在系统启动时生效。如果您想关闭它使用;

# quotaoff -aa

10.12 - 配置 KerberosV 客户端和服务器

KerberosV作为系统组件已经预安装在OpenBSD系统内。

想了解更多有关KerberosV的信息, 键入如下命令:

# info heimdal

10.13 - 配置匿名FTP服务器

匿名FTP允许用户通过FTP协议匿名访问您计算机上的文件。这里概述怎样建立匿名服务器和设定、日志等。

添加FTP账号

首先, 您需要在系统上添加一个ftp账号, 这个帐号没有有效的密码。我们设定登陆后的目录为 /home/ftp , 您也可以放到任何您喜欢的地方。当使用匿名FTP服务时, FTP程序将会将用户ftp限定在他的home目录里, 请参阅ftpd(8)chroot(2) 的用户手册。这个例子中我们用adduser(8)命令添加用户ftp, 我们也需要将/usr/bin/false 加入到 /etc/shells 中, 用户ftp的登陆属性会被设置为/usr/bin/false , 也就是不允许他登陆系统, 尽管用户ftp有一个空密码。您只需:

# echo /usr/bin/false >> /etc/shells
然后我们来添加用户ftp了:
# adduser
Use option ``-silent'' if you don't want to see all warnings and questions.
Reading /etc/shells
Reading /etc/login.conf
Check /etc/master.passwd
Check /etc/group
Ok, let's go.
Don't worry about mistakes. I will give you the chance later to correct any input.
Enter username []: ftp
Enter full name []: anonymous ftp
Enter shell csh false ksh nologin sh tcsh zsh [sh]: false
Uid [1002]: Enter
Login group ftp [ftp]: Enter
Login group is ``ftp''. Invite ftp into other groups: guest no 
[no]: no
Login class auth-defaults auth-ftp-defaults daemon default staff 
[default]: Enter
Enter password []: Enter
Set the password so that user cannot logon? (y/n) [n]: y
Name:        ftp
Password:    ****
Fullname:    anonymous ftp
Uid:         1002
Gid:         1002 (ftp)
Groups:      ftp
Login Class: default
HOME:        /home/ftp
Shell:       /usr/bin/false
OK? (y/n) [y]: y
Added user ``ftp''
Copy files from /etc/skel to /home/ftp
Add another user? (y/n) [y]: n
Goodbye!

建立目录

建立用户ftp时我们已经为它设置了自己的根目录/home/ftp, 但是对匿名FTP来说我们还要更改一些设置, 再提醒一下您应该参看ftpd(8)的用户手册。

不需要建立 /home/ftp/usr 或者 /home/ftp/bin 目录。

注意, 所有的目录全应该属于''root''. 您设置后的目录清单应该像这样。

# pwd
/home
# ls -laR ftp
total 5
dr-xr-xr-x  5 root  ftp    512 Jul  6 11:33 .
drwxr-xr-x  7 root  wheel  512 Jul  6 10:58 ..
dr-x--x--x  2 root  ftp    512 Jul  6 11:34 etc
dr-xr-xr-x  2 root  ftp    512 Jul  6 11:33 pub
ftp/etc:
total 43
dr-x--x--x  2 root  ftp    512 Jul  6 11:34 .
dr-xr-xr-x  5 root  ftp    512 Jul  6 11:33 ..
-r--r--r--  1 root  ftp    316 Jul  6 11:34 group
-r--r--r--  1 root  ftp  40960 Jul  6 11:34 pwd.db
ftp/pub:
total 2
dr-xr-xr-x  2 root  ftp  512 Jul  6 11:33 .
dr-xr-xr-x  5 root  ftp  512 Jul  6 11:33 ..  

启动服务和登陆

您可以选择用inetd(8) 或从 rc 脚本启动FTP服务器. 本例使用inetd.conf文件启动FTP。首先我们必须熟悉一下ftpd的参数。在 /etc/inetd.conf 中默认的FTP设定如下:

ftp             stream  tcp     nowait  root    /usr/libexec/ftpd       ftpd -US

这里ftpd的默认启动参数是 -US, 它将登陆信息记录在/var/log/ftpd, 并发连接数记录在/var/run/utmp。您使用who(1)命令查看连接数。可能因为一些原因, 您不想让本机用户登陆而只运行一个匿名FTP, 这样您就需要使用 -A 选项。下面的一行仅允许匿名登陆。它还是使用了 -ll 选项, 目的是在syslog内纪录每一次连接的信息, 命令get, retrieve等ftp命令的使用情况。

ftp             stream  tcp     nowait  root    /usr/libexec/ftpd       ftpd -llUSA

注意: 如果您的FTP服务器流量很大, 您不应该使用inetd.conf启动FTP服务器, 最好的方法是注视掉inetd.conf中的ftpd语句, 而使用rc.conf.local文件中的 ftpd_flag设置, 并添加上-D选项, 这样FTP服务器会以后台方式运行在系统上, 比从inetd启动节省很多资源。下面是从rc.conf.local启动FTP服务器的例子:

ftpd_flags="-DllUSA"           # for non-inetd use: ftpd_flags="-D"

当然, 如果您已经设置了用/etc/inetd.conf 启动FTP服务器, 您需要注视掉/etc/inetd.conf内的FTP服务器设定, 并让inetd重新读取自己的配置文件。

其他相关文件

10.14 - 在ftpd(8)中限制用户只能访问自己的目录

默认情况下, 用户登陆后可以访问系统的任何目录, 一些情况下我们不希望这样, 我们可以将用户限制(chroot)在自己的目录内。

如果您只允许被chrooted(仅能访问自己的目录)的用户登陆, 需要使用ftpd(8)-A 选项。

如果您想对这些用户友善一些也很简单, 请参阅 login capability infrastructureftpd(8)

添加用户时将 Login class 设置成 ftp-chroot , 系统就会自动chroot这个用户。另外您可以把用户名添加到/etc/ftpchroot里从而chroot这些用户。这两个方法中的任何一个全可以chroot用户。

10.15 - 在OpenBSD中安装补丁

即使是OpenBSD也同样存在bug, 一些bug导致系统可靠性问题(例如, 一些问题会导致系统丧失一些功能), 另一些bug则使系统产生安全漏洞(其他人可以"使用"您的电脑)。当发现一个危险的bug后, 开发者会修改当前版的源代码树, 会发行针对所支持的各种版本的补丁文件。这些补丁文件在罗列在勘误表上, 有的补丁可能是针对所有平台的, 有的则是针对一个或几个平台但不是所有平台。

注意, 这些补丁程序不会为系统添加新功能, 并且仅在系统发现重大的安全或可靠性漏洞必须马上修补时才会发布补丁(并非针对所有的系统, 取决于补丁的目的)。

有三种方式用补丁代码更新您的系统:

在强调一下, 第三种方法并非总是最简单的, 认真考虑一下是否更新到-stable (也称为"补丁") 分支的OpenBSD. 如果您掌握要领也可以混合使用这些方式, 但是新用户往往选择其中的一个方式, 并总是使用它。

勘误表上的补丁不同于CVS树是怎么回事?

所有勘误表上列出的补丁直接对应CVS上的特定版本。与CVS树对应的补丁也许您的系统并不需要。这点很重要;如果您安装了一个快照版, 在安装完成后效验您的源代码并且安装一个公布的补丁, 您可能发现无法应用补丁程序, 因为源代码已经变化了。

应用补丁。

OpenBSD系统的补丁发放采用"Unifed diffs"形式, 它们是字符各式的源代码。补丁不采用二进制格式发放。这意味着您如果要应用补丁必须有发行版的源代码文件。通常您可以得到这些文件。如果您购买了官方的CDROM, 这些源代码文件在第三张CD上, 您也可以通过FTP服务器下载这些源代码文件。这里假设您已经效验了源代码树。

我们下面这个例子将对OpenBSD 3.6应用patch 001, 处理磁带机st(4)驱动问题, 没有这个补丁从备份中恢复系统是相当困难的。 使用磁带机的用户需要这个补丁, 然而如果您不使用磁带机就不需要安装这个补丁。我们看看应用补丁的过程:

# more 001_st.patch
Apply by doing:
        cd /usr/src
        patch -p0 < 001_st.patch
Rebuild your kernel.
Index: sys/scsi/st.c
===================================================================
RCS file: /cvs/src/sys/scsi/st.c, v
retrieving revision 1.41
retrieving revision 1.41.2.1
diff -u -p -r1.41 -r1.41.2.1
--- sys/scsi/st.c       1 Aug 2004 23:01:06 -0000       1.41
+++ sys/scsi/st.c       2 Nov 2004 01:05:50 -0000       1.41.2.1
@@ -1815, 7 +1815, 7 @@ st_interpret_sense(xs)
        u_int8_t skey = sense->flags & SSD_KEY;
        int32_t info;
-       if (((sense->flags & SDEV_OPEN) == 0) ||
+       if (((sc_link->flags & SDEV_OPEN) == 0) ||
            (serr != 0x70 && serr != 0x71))
                return (EJUSTRETURN); /* let the generic code handle it */  
如您所见, 补丁文件的头部包含了应用补丁的简单介绍。我们假设您已经将补丁复制到了 /usr/src 目录, 这种情况下, 后续步骤是:
# cd /usr/src
# patch -p0 < 001_st.patch
Hmm...  Looks like a unified diff to me...
The text leading up to this was:
--------------------------
|Apply by doing:
|        cd /usr/src
|        patch -p0 < 001_st.patch
|
|Rebuild your kernel.
|
|Index: sys/scsi/st.c
|===================================================================
|RCS file: /cvs/src/sys/scsi/st.c, v
|retrieving revision 1.41
|retrieving revision 1.41.2.1
|diff -u -p -r1.41 -r1.41.2.1
|--- sys/scsi/st.c      1 Aug 2004 23:01:06 -0000       1.41
|+++ sys/scsi/st.c      2 Nov 2004 01:05:50 -0000       1.41.2.1
--------------------------
Patching file sys/scsi/st.c using Plan A...
Hunk #1 succeeded at 1815.              <-- 注意这条信息!
done

请注意上面的"Hunk #1 succeeded" 信息. 它说明补丁应用成功。许多补丁比这个复杂得多, 会包含很多的hunks 和文件, 这种情况下您需要确认所有文件的hunk全是succeeded(成功)的, 如果不是则说明您的源代码有问题, 您没有仔细参照使用说明进行操作, 或者您的补丁是有缺陷的。 补丁对"空格"很敏感, ——您在浏览器上拷贝和粘贴时可能会把tab字符带进补丁文件里, 或者改变了文件中的空格, 这种情况会导致补丁无法应用。

如果应用补丁成功, 这是您可以正常地构建系统内核, 安装新内核并重新启动系统。

并非所有的补丁全对内核进行了修改, 有些时候您只需重新编译单独的程序;另一些时候您可能需要重新编译所有静态链接到该补丁程序的库文件。请参照补丁头部的说明进行, 如果您不确定只能编译整个源代码。

通常情况下如果补丁不是针对您的系统, 您可以不安装。例如, 您没有磁带机, 您就不需安装上面的补丁。然而, 补丁认为自己是"按顺序"安装的 -- 很有可能后面的补丁依赖于前面的一个补丁。 请注意这一点, 如果您选择了其中的一个补丁, 自己也不清楚是否需要安装其余的补丁, 那请按顺序全部安装这些补丁。

10.16 - 告诉我chroot(2)的Apachee?

在OpenBSD里, Apache httpd(8) 服务器默认已经被chroot(2)ed。 大大提高了系统的安全性能, 如果您没有做好准备, 这可是一个很严重的安全问题。

什么是chroot?

一个被chroot(2)的程序会被锁定在一个特定的目录内, 而不能进入其余目录, 并且这个特定的目录就是这个程序的"/"(root)根目录。在这种情况下httpd(8)首先启动、打开自己的log文件、绑定在它的TCP端口(尽管还没有开始接收数据)、读取它的配置文件、然后放弃权力把自己锁定在 /var/www 目录内、最后开始接受请求。这意味着所有Apache的服务文件及使用的文件必须全在 /var/www 目录内。在OpenBSD中Apache的用户是www, 用户www只能访问 /var/www 目录内的文件, 并且这个目录内的所有文件对用户www 来说全是只读的。这样对安全有极大的帮助——这是Apache的一个严重的安全问题, 可能破坏仅限于一个"只读"的 /var/www 目录, 并且没有其余的资源会因此受到牵连。

 

这对管理员来说意味着什么?

直截了当地说, 多数其它操作系统默认并没有chroot Apache, 如果用户没有进行设定, 许多应用程序和系统配置并没有工作在chroot的环境中。此外, 不要忘记安全和方便常常是一对矛盾的目标, 在OpenBSD上运行Apache不会因为考虑功能性或"方便性"而忽视安全。

有些情况下您可以通过修改程序或配置文件使它可以工作在chroot环境中, 而另一些情况下您不得不在/etc/rc.conf中为httpd(8)加上 -u 选项关闭chroot功能。

chroot软件wwwcount的例子

这是让一个程序在chroot环境下工作的例子, 我们选择wwwcount, 这是一个简单的网页计数器, 可以通过packages获得。wwwcount是一个很有用的程序, 这个程序并未非为chroot进行了专门的设计, 默认情况下不能工作在chroot环境下。

首先, 我们安装 wwwcount package。我们配置并测试它, 发现它不能正常工作在chroot环境中, Apache显示一条信息"Internal Server Error", 首先我们先停止Apache, 再以 -u 选项重新启动它, 这样做的目的是确认wwwcount不能正常工作的原因是chroot而非其它的系统配置原因。

# apachectl stop
/usr/sbin/apachectl stop: httpd stopped
# httpd -u
完成上述步骤后, 我们发现计数器工作正常, 至少说明了是在我们改变了一个目录的所有权后Apache (和CGIs——现在可以正常运行了) 可以将所持内容写入一些文件。由此我们可以推断出是chroot引起wwwcount无法正常工作, 所以我们接下来停止并重新以默认的chroot方式启动Apache:
# apachectl stop
/usr/sbin/apachectl stop: httpd stopped
# httpd 

一个比较好的假设是 wwwcount 需要使用一些没放在chroot环境中的库和其它文件。我们使用ldd(1)命令找出CGI所依赖的动态目标文件:

# cd /var/www/cgi-bin/
# ldd Count.cgi
Count.cgi:
        Start    End      Type Ref Name
        00000000 00000000 exe   1  Count.cgi
        03791000 237ca000 rlib  1  /usr/lib/libc.so.30.3
        03db4000 03db4000 rtld  1  /usr/libexec/ld.so 
好了, 这正是问题所在, 有两个需要的文件没有在chroot(2)环境中。所以我们把它们拷贝过来:
# mkdir -p /var/www/usr/lib /var/www/usr/libexec
# cp /usr/lib/libc.so.30.3 /var/www/usr/lib
# cp /usr/libexec/ld.so /var/www/usr/libexec
让我们再试试这个计数器程序。

不错, 至少程序已经可以运行了, 但是直接给出了一条错误信息: "Unable to open config file for reading", 看来我们的工作还需要完善。配置文件正常情况下应该在 /var/www/wwwcount/conf, 但是chroot环境下它似乎应该在 /wwwcount/conf , 我们可以选择重新修改并编译程序让它在可以运行的地方工作, 或者我们移动一下它的数据库文件, 因为我们是从package安装的, 所以我们还是只移动数据库文件好了。为了使程序在chroot或非chroot环境下全可以工作, 我们使用一个符号链:

# mkdir -p /var/www/var/www
# cd /var/www/var/wwwc
# ln -s ../../wwwcount wwwcount  

请注意这个符号链是为工作在chroot环境下加上的。我们再测试一下, 结果又发现了新问题, 现在wwwcount抱怨说找不到 "strip image"文件, 它需要用这些文件显示信息。经过搜寻我们发现这些 "strip image"文件位于 /usr/local/lib/wwwcount , 所以我们同样再将这些文件拷贝过来。

# tar cf - /usr/local/lib/wwwcount | (cd /var/www; tar xpf - )
我们再试试... 终于它可以正常工作了!

请注意, 这里我们仅拷贝了哪些wwwcount运行必需的文件。通常情况下您应该把最少的文件拷贝进chroot环境中。(译者注:这句话的意思是如果程序可以正常工作不拷贝最好, 否则尽量少拷贝, 实在没办法再......, 应该是考虑了安全方面的因素。)

我应该使用chroot功能吗?

上例中的wwwcount程序很简单, 但我们还是遇到了各种问题。

并非所有程序全可以或者应该运行在chroot环境中。

在这里chroot的目的是保证web server的安全, chroot 仅仅是实现这个目的的一种工具而已, chroot本身并不是目的。请记住, chroot的Apache服务器的安全前提是您没有运行其它不明程序, 没有改变任何文件, 没有其他用户可以改动系统;如果这些前提不成立, 您的系统无论是chroot与否都不安全。

chroot有的程序很简单, 这样做还有意义;但是其余的很复杂, 要么不值得花费精力chroot它们, 要么需要将很多系统文件拷贝进chroot环境, 实际上这样做已经没有chroot的意义了, 例如, OpenWebMail需要在mail目录进行读写操作, 这个目录也是用户的home目录, 而且必须允许任何用户读写这个目录OpenMail才能正常工作, 如果要强行将它塞进chroot环境内是毫无意义的, 最后相当于您禁用了chroot的全部安全功能。即使是一个像上面wwwcount那样简单的程序, 它也需要对磁盘进行写操作(纪录其统计次数), 也已经丧失了一部分chroot的安全特性。

将任何需要root权限运行的程序放进chroot环境内是毫无意义的, 因为作为root可以轻松摆脱chroot的束缚。

别忘记, 如果您费了九牛二虎之力才把一个程序塞进chroot环境, 那您就别像平时一样没事就upgrade或update一下您的系统, 因为这样的折腾不仅不会使您的系统更容易维护, 而且可能导致chroot功能失效, 使系统的安全性能降低

10.17 - 我可以更改root的shell吗?

有时候人们会说永远不要改变root的shell, 尽管这在OpenBSD中并没有理由不这样做。

OpenBSD中root的默认shell是 ksh

传统的Unix原则上仅让root使用静态编译的shell, 因为系统进入单用户模式时, 非root分区不会被挂载并且动态连接的shell不能读取/usr分区下的库文件。这对OpenBSD来说不是什么大问题, 因为进入单用户模式时系统会询问您使用哪种shell, 并且默认就是sh。OpenBSD系统内三个标准shell(csh, sh ksh)全是静态连接的, 它们全能正常工作在单用户模式下。

10.18 - 我用ksh还能做什么?

OpenBSD中, ksh 就是 pdksh, the Public Domain Korn Shell, 和sh一样全是二进制的。

更喜欢在Linux下使用 bash 的用户会觉得 ksh 很熟悉, Ksh(1)提供了多数 bash 的通用功能, 包括tab完成、命令行编辑、箭头键浏览历史纪录以及CTRL-A/CTRL-E 光标跳到命令行首尾等。如果还有其它的 bash 功能吸引您, 您可以通过packagesports来安装。

通过设定 PS1 变量您可以方便地修改 ksh 的命令行提示符的内容, 让它显示更多的信息而不是默认的 "$ "。例如, 在 /etc/profile 文件内加入下面这行:

export PS1='$PWD $ '
提示符会变成如下的样子:
>/home/nick $
请参阅文件 /etc/ksh.kshrc, 它包含了很多特性和范例, 您也许可以打造一个自己的 .profile 风格。

OpenBSD中 ksh(1) 为基本提示符PS1增加了一些"特殊的字符" , 就像在bash中使用的那些。例如

\e - 插入一个ASCII码的转义字符。
\h - 主机名称, 减域名。
\H - 主机完整名称, 包含域名。
\n - 插入一行新字符。
\t - 当前时间, 24小时格式, 小时:分钟:秒。
\u - 当前用户名。
\w - 当前工作目录. $HOME 简化为 `~'。
\W - 当前工作目录的 basename 。
\$ - root显示 "#" , 非root显示 "$" 。

(还有很多特殊的字符!请参阅 ksh(1) 的用户手册以获得更多信息, 还需要注意双引号内的 "$" 字符具有特殊的含义, 请小心使用。)

有人也许喜欢用下面这样的的提示符:

export PS1="\n\u@\H\n\w \\$ "

提供了十分详细的信息, 但是只有一些您用得到。

10.19 - 目录服务,YP

OpenBSD可以在包含用户凭据、组信息、或其它网络相关的数据库中作为服务器或客户端。

10.19.1 - 可以提供哪种目录服务?

当然你可以在OpenBSD里面使用各式各样的目录服务, 但是只有YP可以直接访问使用诸如 getpwent(3), getgrent(3), gethostbyname(3) 等标准C库文件, 因此, 如果你的数据包存在一个 YP 数据库内, 例如系统用户鉴别, 你不需要事先将将它拷贝到本地的配置文件如 master.passwd(5) 就可以直接使用它。

YP是一个兼容NIS (Network Information System网络信息系统)的目录服务。 请参阅 yp(8) 的用户手册以便对它有总体的了解。 需要注意的是, 一些操作系统包含的目录服务具有相似的名称, 但是它们全与OpenBSD系统不兼容, 例如 NIS+。

如果要使用YP以外的目录服务, 你不是需要在本地设置配置文件就是需要将YP作为目录的前台服务。 例如, 你可以使用 sysutils或者login_ldap构架的port, 但同时你必须运行 ypldap(8) 进程。

对一些应用程序来说, 你可以简单地使用 cron(8), scp(1) 在一组计算机内同步一小部分配置文件或者用rsync(可以通过ports安装)构建一个简单强劲的稳定数据库。

10.19.2 - YP安全注意事项

由于兼容性的原因, 默认情况下YP执行时所有OpenBSD内置的安全特性全是关闭的。 即使这些安全特性全部开启, NIS协议也存在两个固有的不安全因素: 包括敏感的密码哈希值在内的所有数据全是以不加密的方式在网络中传送, 并且客户端和服务器都不能彼此进行可靠的验证。

因此, 在建立一个YP服务器前, 你需要考虑一下在你的环境中是否允许这些不安全因素。 特别是潜在的攻击可能直接访问你的网络时使用YP并不合适。 任何一台可以连接到YP通讯传送所在网段的计算机如果root密码泄漏, 可能导致非法用户连接到你的YP域并重新获得所需数据。 在某些情况下, 通过SSL或IPSec通道传送YP数据可能是一个不错的选择, 或者你应该考虑结合YP与kerberos(8)认证的组合。

10.19.3 - 建立一个YP服务器

一个YP服务器在一个"域"内为一组客户端提供服务。 你首先需要选择一个域名称; 它可以是任意的字符串但必须不能和DNS域名有任何关联。 随机选择一个名称例如"Eepoo5vi"可以稍微提高一点安全, 尽管作用不明显。 当你需要维护几个不同的YP域时, 最好用有意义的名称命名域例如"sales", "marketing" 和 "research" 以免因命名含义不清造成管理混乱。 还需要注意的是一些版本的SunOS需要使用主机的域名, 所以在这样主机所在的网络内选择域名称可能会受到限制。
  1. 使用 domainname(1) 工具可以设定域名 , 并将这个域名写入文件 defaultdomain(5) 内以便让系统启动时自动对其设置。
    echo "puffynet" > /etc/defaultdomain
    domainname `cat /etc/defaultdomain`
    
  2. 确定在哪里储存原始文件以生成YP映射, 默认位置 /etc 并不合适: 通常, 你不需要将所有的帐号的组保存在服务器或所有的客户端主机上, 尤其是不能提供root帐号, 将root的密码哈希保存在可靠的地方对提高系统的安全性很重要。 改变源目录会造成的唯一不便就是你不能用user(8)group(8)工具添加、删除、修改YP域内的用户和组, 而只能用一个文本编辑器编辑配置文件来完成这些操作。

    要定义定义源目录, 编辑文件 /var/yp/Makefile.yp 来更改里面的 DIR 变量, 例如

    DIR=/etc/yp/src/puffynet
    
    如果所有的客户端全运行的是OpenBSD或者FreeBSD, 通过设置 UNSECURE="" in /var/yp/Makefile.yp 在密码映射中排除加密的密码。

    在系统安装时一个备份的原始Makefile.yp模板保存在 /var/yp/Makefile.yp.dist , 如果你想恢复到一个普通配置时可以使用它。

  3. 创建原目录并用配置文件设置它你需要参阅 Makefile.yp(8) 以便学习哪种YP映射需要哪种源文件, 每个配置文件的格式请参考 passwd(5), group(5), hosts(5) 等, 并请参考 /etc 中的例子。

  4. 初始化 YP 服务器使用交互式命令

    ypinit -m
    
    这时还不需要指定从属服务器。 你可以稍后运行 ypinit(8) 加上 -u 选项来增加从属服务器。 每个域应该至少建立一个从属服务器, 这样即使主服务器宕机或无法连通也可以有效的避免服务中断, 特别是当客户端程序试图访问YP映射时可能发生无限期阻塞(等待)直到其获得请求的数据。 因此, YP服务中断会使客户机完全无法使用直到YP服务器恢复正常。

    注意运行 ypinit -m 后对 /var/yp/Makefile.yp 的修改不会起作用, 因为 ypinit -m 将模板拷贝到 /var/yp/`domainname`/Makefile 文件, 尽管多数位于/var/yp/`domainname`的数据库文件可以用这个新的 Makefile 简单重建, 但有一个例外: 文件 ypservers.db, 它列出了此域内主服务器和所有从属服务器, 它是直接由 ypinit -m 创建, 并且只能通过 ypinit -u 进行修改。 所以要特别小心, 不要损坏此文件, 否则你需要手动使用makedbm(8)重新产生它, 或者重新运行 ypinit -m 再安装server。

  5. YP 使用 rpc(3) (远程程序调用) 来与客户端通话, 因此必须启用 portmap(8), 启用portmap需要编辑 rc.conf.local(8) 然后设置 portmap=YES。 这样会在下次系统启动后启动 portmapper 。 你也可以不重新启动系统手动启用它:

    echo "portmap=YES" >> /etc/rc.conf.local
    portmap
    
  6. 考虑使用YP服务器进程的 securenet(5) 或者 ypserv.acl(5) 的安全特性时请注意, 这两者都只提供了基于IP的访问控制, 因此, 它们只能在潜在的攻击者不能物理接触传送YP数据的网段才能提供安全保障, 而且攻击者不能拥有任何可连接到该网段的计算机的root密码。
  7. 最后, 启动 YP 服务器进程:

    ypserv
    
    只要 /var/yp/`domainname` 存在, YP 服务器将在下次系统启动后启动。
  8. 测试新服务器, 可以将其作为自己的客户端, 参照下一小节第一部分的说明。 如果不想让服务器使用它自己的映射你可以在测试后使用如下命令禁用客户端部分:
    pkill ypbind
    rm -rf /var/yp/binding
    
  9. 如果你允许用户在客户端上更改他们的密码, 你必须启用 yppasswdd(8):
    echo 'yppasswdd_flags="-d /etc/yp/src/puffynet"' >> /etc/rc.conf.local
    rpc.yppasswdd
    
    如果你想将原始目录保留在默认的 /etc, 仅需使用 yppasswdd_flags="".
  10. 记住每次你通过YP映射改变一个文件的源时你都需要重新生成你的YP映射。
    cd /var/yp
    make
    

10.19.4 - 建立一个YP客户端

建立一个YP客户端包括两个不同的步骤。 首先, 你必须先运行YP客户端进程, 将你的客户端主机绑定到一台YP服务器上。 完全按照下列步骤将允许你从YP服务器重新获得数据, 但是这个数据还不能被系统使用:
  1. 像在服务器上一样, 你必须设置域名称并且启用 portmapper:
    echo "puffynet" > /etc/defaultdomain
    domainname `cat /etc/defaultdomain`
    echo "portmap=YES" >> /etc/rc.conf.local
    portmap
    
  2. 推荐的做法是在配置文件 /etc/yp/`domainname` 内提供一个YP服务器的清单, 否则YP客户端会会使用网络广播来查询自己域内的YP服务器。 明确地指定服务器既可以使服务更可靠还可以减少被攻击的可能性。 如果你没有设置从属服务器, 仅需将服务器的host name写入 /etc/yp/`domainname`.

  3. YP客户端进程是 ypbind(8). 要手动启动它需要建立目录 /var/yp/binding, 这样下次启动后YP客户端会自动启动。

    ypbind
    
  4. 如果一切进展顺利你就可以使用 ypcat(1) 向YP服务器查询并看到你的passwd映射被返回。

    ypcat passwd
    bob:*:5001:5000:Bob Nuggets:/home/bob:/usr/local/bin/zsh
    ...
    
    还有一些可用的YP设置调试工具, 例如 ypmatch(1)yptest(8).
配置YP客户端的第二个步骤包括为不同系统编辑特定的YP映射配置文件。 并非所有的服务器都提供操作系统支持的标准映射, 一些服务器还提供额外的非标准映射, 这并非要强迫你使用这些非标准映射, 客户端管理员可自己选择应该使用哪些映射或者因何使用这些映射。

Makefile.yp(8).里包含了一个标准映射的清单和其标准用法。 通常的使用情况包括:

[索引] [第九章 - 转到OpenBSD] [第十一章 - X Window 系统]


[back]www@openbsd.org
$OpenBSD: faq10.html, v 1.140 2008/11/12 02:59:41 nick Exp $