Matthew(黑夜编码人)
我想大多数的UNIX网络管理员或多或少的都有过类似于这样的麻烦:一个用户要在多台不同的UNIX系统上工作,要在不同的UNIX上登录,保存他们的文档等,而管理员就要在每一台UNIX系统上为他建立帐号,设置密码,设置组信息,建立目录,以便他能在所有的机器上正常工作。同时还要建立一台FTP服务器,每次用户必须将它的文件保存在这台FTP服务器上,然后当他登录到另外一台UNIX系统上的时候再从FTP服务器上取回他所需要的文件。这样不但麻烦,而且管理起来非常不便,因为一旦某天某个员工离职了,管理就要到每一台UNIX系统上去删除他的帐号和文件,来保证他不能在那些机器上登录。而且对于一些系统信息的管理也非常不便,比如每台机器上的hosts文件,你必须要在每台机器上建立一份相同hosts文件,以保证所有的机器的机器名和IP地址的对应都是正确的。可一但某天有哪台机器需要更改IP地址,这时管理员又只有为每一台UNIX机器更改它的hosts文件。
从上面的这些问题我们可以看到其实我们所更改的这些东西大部分都是完全相同的,相同的帐号,相同的目录和相同的hosts文件,如果机器少还没有什么,一旦你管理的机器超过200台,那么可能你这一整天的时间都会花在做这些重复的事上面。
也许你要问,那么那些大网络的UNIX管理员们是使用什么方法来解决这些问题的呢?当然他们不可能是为每一台机器更改这些设置,他们使用的就是今天我们要介绍的NIS和NFS服务。
下面我们就向你介绍在FreeBSD中建立NIS和NFS服务的思路及方法。
(注:下面为我们的实验环境)
cat.mydomain.nis OpenBSD3.3 NIS和NFS客户端
dog.mydomain.nis FreeBSD4.8 NIS主服务器和NFS服务器 (保存网络中所有用户的帐号信息,组信息和用户文件)
bee.mydomain.nis FreeBSD4.5 NIS辅服务器
1、使用NIS共享系统信息
NIS是Sun Microsystem开发的用于在UNIX系统间共享用户数据、组数据、主机数据、协议等数据的服务系统,它最早被命名为Yello Page,后来由于商标冲突被Sun重新命名为NIS,但很是有很多地方以YP来称乎它。由于NIS的出现对UNIX网络管理起到很大的推进,所以现在几乎所有的UNIX系统都对它提供了支持。当然FreeBSD系统也不例外,FreeBSD当前提供的主要是NIS v2,同时也提供了对NIS v1的兼容支持。
我们可以看到,如果一个用户要在多台UNIX系统上工作,他们大都使用相同的用户名、属于相同的组、使用相同的密码。那么我们可以将这些信息存放在一台机器上来统一进行管理,其它机器都从这台机器上来获得这些信息,一但要更改某个用户的信息,管理员就只需要在存放这些信息的机器上进行更改,其它机器就自动的收到更改后的信息,而不再需要管理员一一的进行设置了,这就是NIS工作的基本方式。
NIS使用域来管理那些需要共享的信息,这些信息就够成了NIS数据库,所有拥有相同域名的机器就可以共同使用所在域名的数据库。这些数据库被存放在一台机器上,这台机器就是NIS的主服务器,其它机器就都通过它来查询NIS数据库,但有时为了稳定性的考虑,也可以建立一台或多台NIS辅服务器,它们保持与NIS主服务器的数据同步,当主服务器出现故障时承担主服务器的任务。
下面就让我们来看看,如何在FreeBSD中建立NIS主服务器。
首先,因为NIS是基于域来管理的,所以就要为服务器设定域名,你可以通过domainname来查看你现在的域名(注意:这里的域名与DNS的域名没有任何关系,它只起来将一个网络划分为几个部分的作用,因而它可以为任何值,当然你也可以将它设置成你的DNS域名):
dog# domainname
mydomain.nis
如果上面显示为空,则表明你还没有设置你的域名,你同样可以通过domainname来设置和更改你的域名:
dog# domainname mydomain.nis
域名设置好以后,就开始进入后面的工作。
默认情况下,FreeBSD将每个域的NIS数据库存放在/var/yp/yourdomainname下面,你需要将你要共享的信息如master.passwd复制到/var/yp下面,这里需要提醒的是,因为FreeBSD默认使用MD5来加密用户口令,因而,如果你是在一个有多种UNIX系统的网络中,而且某些UNIX不支持MD5加密的话,你就需要更改你的密码加密方式为这些UNIX都支持的加密方法(如DES),否则用户将无法在那些机器上登录。
更改FreeBSD默认加密方式的方法如下:
dog# vi /etc/login.conf
然后编辑用户所在的类(通过如果没有指定的话就是default类),在其后加入:passwd_format=des:\(其中des代表DES加密,md5代表MD5加密,blf代表Blowfish加密),例如:
default:\
:passwd_format=des:\
:datasize=infinity:\
...
保存退出后,需要使用使用cap_mkdb来生成BD(Berkeley Database)格式的数据库文件:
dog# cap_mkdb /etc/login.conf
这样便会在/etc目录下更新(或生成)login.conf.db文件。
现在我们只是更改了密码的默认加密方式,而真正的密码还没有改变,因而需要使用passwd命令来更改每一个需要共享出来的用户的口令,然后将master.passwd复制到/var/yp目录下,为了安全应该更改一下master.passwd文件的权限:
dog# cp /etc/master.passwd /var/yp/master.passwd
dog# chmod 0600 /var/yp/master.passwd
同样考虑到安全的因素,最好删除那些你不需要和不应该共享的用户(比如:root用户和系统默认用户bin,daemon等)
现在我们就可以初始化我们的NIS主服务器了,初始化使用ypinit(8)命令:
dog# cd /var/yp
dog# ypinit -m mydomain.nis
这里-m表示生成主服务器,而mydomain.nis是你的域名。
在初始化过程中,你会被提及一些问题:
Do you want this procedure to quit on non-fatal errors? [y/n: n] 直接选择n
然后就是设置NIS服务器的名字,包括主服务器和辅服务器,因为这里我们只有一台主服务器,因而直接按Ctrl-D退出,如果你打算再建几台辅服务器的的话就输你的NIS辅服务器的名字。然后会显示你的服务器信息:
The current list of NIS servers looks like this:
dog.mattcell.com
Is this correct? [y/n: y] 如果没有错误的话,就选择y
接下来就开始进入初始化过程,这个过程中会产生一些出错信息,不过不用理它,这是因为你的NIS服务进程(ypserv)还没有启动的原因造成的。完成后会提示:
dog.mattcell.com has been setup as an YP master server without any errors.
这表示你的NIS主服务器已经初化完成。
现在要需要启动我们的NIS守护进程:ypserv(8)了,因为ypserv使用了RPC服务,所以需要先运行portmap(8)来使用它的RPC服务,同时如果用户需要在客户机上更改密码的话,我们就需要在NIS服务器上运行rpc.yppasswdd(8)守护进程:
dog# portmap
dog# ypserv
dog# rpc.yppasswdd
为了让这些命令在系统启动的时候就自动启动,这需要在/etc/rc.conf中加入以下设置:
portmap_enable="YES"
nisdomainname="mydomain.nis"
nis_server_enable="YES"
nis_yppasswdd_enable="YES"
现在我们的NIS主服务器就已经跑起来了,你可以通过以下命令来测试它的工作情况:
dog# ypbind 启动NIS客户端支持程序
dog# ypcat passwd 查询NIS服务器上的/etc/passwd信息
dog# ypcat master.passwd 查询NIS服务器上的/etc/master.passwd信息
dog# ypcat group 查询NIS服务器上的/etc/group信息
dog# ypcat hosts 查询NIS服务器上的/etc/hosts信息
dog# ypcat networks 查询NIS服务器上的/etc/networks信息
dog# ypcat netgroup 查询NIS服务器上的/etc/netgroup信息
dog# ypcat services 查询NIS服务器上的/etc/services信息
dog# ypcat protocols 查询NIS服务器上的/etc/protocols信息
dog# ypcat ypservers 查询NIS服务器信息
dog# killall -9 ypbind 关闭NIS客户端支持程序
下面我们来看看如何从客户端共享这些信息。
首先要保证客户端的NIS域名与NIS服务器的域名要一致。因为在客户端要对NIS服务器上的信息进行查询,所以需要在客户端启动一个守护进程ypbind(8)来提供对NIS的支持,同样,ypbind也使用RPC服务,所以需要在运行它之前运行portmap(8)进程:
cat# domainname mydomain.nis
cat# portmap
cat# ypbind
这里cat这台机器就会向网络上发出一个广播,来寻找NIS主服务器。同样,你也可以将这些信息加入rc.conf中让它们自动运行:
nisdomainname="mydomain.nis"
portmap_enable="YES"
nis_client_enable="YES"
nis_client_flags="-S mydomain.nis, dog.mydomain.nis, bee.mydomain.nis"
这里nis_client_flags是设置NIS域名为mydomain.nis,以及设置NIS服务器列表:dog.mydomain.nis, bee.domain.nis,这样对那些远程的用户有帮助,因为这种情况下如果依靠ypbind使用广播来查找服务器的话比较困难。
下面就需要设置系统使用NIS来接受用户信息,这需要在/etc/master.passwd的最后加入:
+:::::::::
这样,如果一个用户在该台机器(cat.mydomain.nis)这台机器上登录,login将先查找本地是否有该用户的帐号信息,如果有就使用本地信息,如果没有的话就通过NIS来获取。
同样的方法,如果要共享group信息,就需要在/etc/group最后一行加入:
+:*::
也可以共享NIS服务器上的hosts信息,这需要在/etc/host.conf中增加nis查询选项:
# $FreeBSD: src/etc/host.conf
# First try the /etc/hosts file
hosts
# Second use YP/NIS
nis
# Now try the DNS
bind
这样当你试图查询一台机器的IP地址的时候,系统将先在/etc/hosts中寻找相就的记录,如果没有找到就通过NIS来查询NIS主服务器上的hosts文件,如果还没有找到就使用DNS来查找。
(注意:/etc/host.conf在FreeBSD5.0之后已经使用/etc/nsswitch.conf来代替了)
现在你就可以使用dog.mydomain.nis服务器上的帐号来登录cat.mydomain.nis这台机器了:
FreeBSD (i386)
Login: matthew
Passwd:注意,因为我们在cat.mydomain.nis上没有为matthew这个用户建立HOME目录,所以这时会提示没有找到HOME目录,不必理会它,因为我们将在后面解决这个问题。
如果在客户端想更改你在NIS服务器上的口令,你可以使用yppasswd(1)来更改(需要服务器上运行rpc.yppasswdd守护进程):
matthew@cat$ yppasswd
Changing NIS passwd for matthew on dog.mydomain.nis.
Old Password:
New Password:
Retype new passwd: NIS password has been changed on dog.mydomain.nis.
下面让我们来看看如何改新NIS服务器上的NIS数据库
如果我们更改了NIS服务器上的某些数据(如:增加了用户,增加了组等。注意:更改了master.passwd后必须将/etc/master.passwd再次复制到/var/yp目录下,将删除不必要的用户)后,NIS客户端并不能立即使用更改的数据,因为NIS数据库是存放在/var/yp/yourdomainname下面的,所以我们需要更新NIS数据库:
dog# cd /var/yp
dog# make
这时make就会根据Makefile自动更新NIS数据库,注意,因为NIS数据库是实时查询,所以我们不需要重新启动ypserv守护进程。
建立NIS辅服务器
如果你担心你的NIS主服务器工作会为稳定而造成用户无法登录,那么你可以再建立一台或数台NIS辅服务器,它的建立方法就比较简单了。
首先还是进行初始化,不过因为它的NIS数据库直接从主服务器上取得,所以就直接在你要作为辅服务器的机器上执行:
bee# cd /var/yp
bee# ypinit -s dog.mydomain.ns mydomain.nis
其中-s指定NIS主服务器的名字,后面的mydomain.nis表示要初始化的NIS域名(即辅服务器的NIS域名)。
然后再修改辅服务器上的/etc/rc.conf以便NIS服务能够自动运行,同时为了当主服务器上的数据在发生变更的时候,辅服务器能够自动保持同步,就需要启动NIS同步进程rpc.ypxfrd:
portmap_enable="YES"
nisdomainname="mydomain.nis"
nis_server_enable="YES"
nis_yppasswd_enable="YES"
nis_ypxfrd_enable="YES"
同时为了支持同步数据传送,需要在主服务器上更改一点设置,因为主服务器默认情况下的设置只考虑了一台NIS服务器的情况。
我们需要将/var/yp/Makefile中的NOPUSH = "True"注释掉:
# NOPUSH = "True"
如果你在之前初始化主服务器的时候没有准备安装辅服务器,所以没有输入辅服务器的名字,而你现在又要使用辅服务器,那么你可以通过以下方法来增加你的辅服务器:
dog# cd /var/yp
dog# vi ypservers
加入你的辅服务器名,这里我们的辅服务器名为bee.mydomain.nis:
dog.mydomain.nis dog.mydomain.nis
bee.mydomain.nis bee.mydomain.nis
现在你的辅服务器在每次主服务器更新之后就会自动保证数据同步了。
NIS的高级设置上面的例子中,我们是允许所有的NIS主服务器上的用户在NIS客户端(这时为cat)上登录,那么我们可不可以只允许某些用户登录,或者不允许某些用户呢?
答案是肯定的,当我们要允许某个用户登录的时候,可以在master.passwd中加入如下内容:
+matthew:::::::::
这表示允许(+)NIS服务器上的matthew在这台机器上登录,如果+号后面没有指定用户名的话系统就默认允许所有的用户登录,这就是我们上面的那种情况。
如果要禁止某个用户登录:
-badman:::::::::
这就表示禁止(-)NIS服务器上的badman在这台机器上登录,注意,因为系统处理master.passwd的时候是从第一行开始匹配的,一但某行匹配了,就不是对后面的行进行处理了,所以如果你要禁止某些用户登录而允许其它所有的用户登录就一定要将-user:::::::::写在+:::::::::之前,否则该用户还是可以登录系统:
-badman:::::::::
-hacker:::::::::
+:::::::::
上面的设置就使得除NIS服务器上的badman和hacker不能在这些机器登录外,其它的用户都可以登录。
还有一钟情况就是,我只允许某些用户登录我的系统,不允许其它用户登录,但又要保证用户信息与NIS服务器上的服务信息一至,以便使用id等使用的时候能正确的显示出用户的用户名和组名,这也可以使用以下方法来实现,在客户机的/etc/master.passwd后面加入:
+matthew:::::::::
+guest::::::::/home/ftp:
+:::::::::/sbin/nologin
上面的设置使得matthew可以在这台机器上登录,guest也可以登录,但其HOME目录将被到/home/ftp下,而其它用户的shell都被改成/sbin/nologin,所以其它用户都不能登录,但同时又使得这些用户的信息可以与NIS服务器同步。
2、使用NFS共享目录
NFS同样是由Sun Microsystem开发一用于UNIX系统之间共享文件的网络服务系统,与NIS一样,它也得到大多数的UNIX系统的支持。
在文章最开始的时候,我们提到用户需要每次都从FTP下载文件的问题,现在我们就可以用NFS来解决这个问题了,我们可以将某台机器的某个文件(文件夹)共享出来供其它机器使用。
在上面讲NIS的时候我们注意到,当我们使用NIS主服务器上的用户登录到其它UNIX机器的时候会被提示找不到用户的HOME目录,那么我们就利用NFS来将NIS主服务器上的/home目录共享出来,然后在每个UNIX客户端将其mount到本机的/home上,这样就可以解决找不到用户HOME目录问题了,并且无论用户在哪台机器登录,都可以直接进入自己的工作环境,使用自己的文件。
下面就让我们来实施具体的工作。
首先根man nfsd我们可以知道nfsd(8)只是处理NFS协议,真正的远程mount(共享)功能是由mountd(8)来完成的,而mountd是通过/etc/exports来设置共享目录的。exports(5)里的每一行表示第一个共享设置,第一行中都有以下三个部分:
第一部分是设置要共享出去的目录或目录列表,当要共享多个目录的时候使用空格分隔每个目录。
第二部分是共享参数,比如设置只读共享,对帐号的映射等。
第三部分是设置可以访问该共享的主机或主机列表,多个主机使用空格分隔。
我们就以共享NIS服务器(dog.mydomain.nis)上的/home目录为例,向大家说明exports的配制方法:
dog# cat /etc/exports
/home -maproot=daemon -network 192.168.7.0 -mask 255.255.255.0
其中/home为我们要共享出来的目录,-maproot=daemon是共享参数,表示当本地UNIX系统使用远程的/home目录时,将本地的root帐号的uid映射为远程机器上的daemon,gid映射为空,也就是说当我们以root身份访问dog上的/home目录时,我们的身份会被转换成远程主机dog上的daemon的身份。后面的-netmask=192.168.7.0 -mask=255.255.255.0设置可能访问该些共享资源的主机为192.168.7.0/255.255.255.0这个子网内的所有机器。
还有很多共享参数可以设置,比较有用的有:-mapall=将所有的本地帐号映射为远程主机上的某个指定帐号,-ro以只读共享该文件夹(默认为可读写)其它参数你可以通过man exports得到,这里就一一列举了。
现在我们的共享资源已经通过/etc/exports设置好了,接下来就是启动NFS守户进程nfsd和远程共享进程mountd了,由于NFS同NIS一样也使用RPC,所以要在启动NFS之前行启动portmap进程:
dog# portmap 如果已经启动就不再需要这一步了
dog# nfsd -n 5
dog# mountd
其中nfsd -n 5中的-n参数是指定同时建立多少个服务副本,可能选择4-6,这有助于提供NFS系统性能,但也不过太高,否则会占用大量资源。现在NFS就已经启动成功了,你可以通过showmount(8)来查询你的共享资源:
dog# showmount -e localhost
/home 192.168.7.0
这表明我们的NFS服务器已经正确启动了,接下来就要在客户端设置了。
在客户端我们使用mount_nfs来将远程主机共享的目录mount到本地上,因为在本例中我们是希望将远程主机(dog)上的/home目录mount到客户端(cat)的/home目录以保证系统用户的数据同步,所以我们进行以下操作:
cat# mount_nfs dog:/home /home
现在远程的共享目录/home就已经mount到本地的/home目录中了,我们可以看到mount_nfs与其它mount命令不同,它不是使用设备名(如/dev/ad0s1)而是使用hostname:/sharedir的方式来表示mount源,其中hostname是远程主机的主机名或IP地址。
现在我们再次使用matthew这个帐号(该帐号在NIS服务器dog.mydomain.nis上存在),在cat.mydomain.nis登录:
FreeBSD (i386)
Login: matthew
Passwd:
matthew $ pwd
/home/matthew现在我们可以看到,我们在dog这台机器上的文件,现在在cat上全部可以看到了,当然以前的那个找不到用户HOME目录的错误信息现在也没有了。
可以看到,通过NIS和NFS可以使管理员管理UNIX网络中的用户帐号等信息非常方便,因为所有的修改都只需要在一台机器上进行,而其它机器自动的就会改变。同时对用户来说,他们可以只使用一个帐号而在任何一台主机上登录,而且不用再使用麻烦的FTP在不同的主机间传递文件,用户在每台机器上的文件都会自动保持更新。
由于作者水平有限,文中难免有错误之处,欢迎来信讨论。
参考
《FreeBSD使用大全》第二版 (作者:王波)
FreeBSD Man Pages:
ypserv(8)、rpc.yppasswdd(8)、ypinit(8)、passwd(5)、group(5)、host.conf(5)
nfsd(8) 、ountd(8)、showmount(8)、exports(5)、mount_nfs(8)