Chinaunix首页 | 论坛 | 博客
  • 博客访问: 512554
  • 博文数量: 119
  • 博客积分: 5054
  • 博客等级: 大校
  • 技术积分: 1305
  • 用 户 组: 普通用户
  • 注册时间: 2010-01-03 13:13
文章分类

全部博文(119)

文章存档

2011年(4)

2010年(115)

我的朋友

分类: 服务器与存储

2010-01-03 19:47:25

摘自《LINUX系统管理技术手册》

简介

网络文件系统(Network File System)通常叫做NFS,它可以在计算机间共享文件系统。NFS对用户几乎是透明的,并且是“无状态的”,这意味着当NFS服务器崩溃是不会丢失任何信息。客户机只是等着服务器恢复正常,然后就好像什么也没有发生过一样继续工作。
NFS有Sun Microsystem公司在1985年推出。实现它原本是作为无盘客户机的一种替代文件系统,但这种协议经证实设计的很好,作为一种通用的文件共享解决方案非常有效。NFS运行在Sun的RPC(Remote Procedure Call,远程过程调用)协议上,该协议定义一种与系统无关的方法来实现进程的网络通信。这种体系结构的一个优点就是既可以用UDP也可以用TCP作为下层的传输协议。

fhc2007@fhc2007-desktop:~$ netstat -a |grep nfs
tcp 0 0 *:nfs *:* LISTEN
udp 0 0 *:nfs *:*

安全性与NFS

NFS提供了一种访问网络上文件的便利途径,因此它引导安全问题的可能性很大。
对NFS卷的访问是由一个名为/etc/exports的文件来批准的,这个文件枚举了若干系统的主机名(或IP地址),这些系统应该有权访问服务器上的文件系统。遗憾的是,这在安全上是一种很薄弱的形式,因为服务器相信客户机告诉它是谁。客户机很容易向服务器撒谎,所以这种机制不是完全可信的。然而,你应该只向你信任的客户机导出文件系统,而且你应该一直检查,保证没有把文件系统向整个世界导出。
和对本地文件系统一样,对NFS文件系统的文件级访问控制是按照UID、GID和文件权限来管理的。但是NFS服务器依然会客户机告诉它的,谁正在访问文件的消息。如果mary和bob在两台不同的客户机上都有同样的UID,那他们就可以访问到彼此的NFS文件。此外,在系统上有root权限的用户还可以把UID改成他们想要的任何值,服务器都会乐于赋予它们对相应文件的访问权限。处于这些原因,强烈建议到处都使用唯一的UID,而且使用root_squash选项。

root访问与nobody帐号

即使应该赋予用户对各处相同的访问权限,但传统上都会避免root在通过NFS安装的文件系统上随便运行。默认情况下,Linux的NFS服务器截获以 UID 0 名义传来的请求,将其改变成好像是来自某些别的用户。这种修改称为“squashing root(压制root)”。因此root帐号不是完全关闭的,但会限制root只拥有普通用户的访问权限。
特意定义了一个占位帐号nobody,它是一个远程的root在NFS服务器上假装的“用户”。传统上给nobody的UID是65534(-2的补码)。你可以使用导出选项anonuid和anongid改变root默认的UID和GID映射。你可以使用all_squash选项将所有客户的UID映射到服务器的同一个UID。这样的配置消除了用户之间的一切区别,带来了一种对文件系统的公共访问。
在另一个极端,no_root_squash选项关闭了root的UID映射。有时需要这个选项来支持无盘客户机或者要求对文件有root访问权限的软件。一般而言,关闭这项功能不是个好主意,因为它能让在客户机上有root权限的用户修改正常情况下受到保护的文件。不过,确实是有这么一个选项。

服务器端NFS

当服务器让某个目录能为其他计算机所使用时,通常说这个服务器“导出(export)”了一个目录。
在NFS第3版中,客户机安装文件系统所用的过程完全不同于访问文件所用的过程。这两种操作使用不同协议,请求由不同的守护进程来提供服务:mountd服务于安装请求,而nfsd服务于实际的文件服务。
在NFS服务器上,mountd和nfsd都应该在启动系统的同时启动,而且只要系统开着就让它们保持运行。如果你已经做了“导出(exports)”配置,那么系统启动脚本一般会自动启动这些程序。
mountd和nfsd共享一个访问控制数据库,该数据库说明了哪些文件系统应该被导出,而哪些客户机有可能会安装它们。除了内核内部的表之外,这个数据库的运行副本通常还保存在一个称为/usr/lib/nfs/xtab的文件中。因为xtab并不是供普通人阅读的,所以你要用一条辅助命令来添加修改其中的项:exportfs。要从导出表里删除项,可以使用exportfs -u。
在大多数系统上,/etc/exports是导出目录的说明清单,普通人可以直接阅读。在默认情况下,/etc/exports中的所有文件系统都可以在系统引导时被导出。你可以使用exportfs -a命令手工导出/etc/exports中列出的全部文件系统,这应该在你对exports文件进行过修改之后运行。你还可以在每次导出文件系统的时候直接在exportfs的命令行上指出客户机、路径和选项。

exports文件

/etc/exports文件列举出通过NFS导出的文件系统,以及可以访问每个文件系统的客户机。客户机列表和文件系统之间以空白分隔,每个客户机之后紧跟着用括号括起来、以逗号分隔的一系列选项。用反斜线可以续行。
下面是这个文件格式的样子:

fhc2007@fhc2007-desktop:~$ cat /etc/exports
# /etc/exports: the access control list for filesystems which may be exported
#		to NFS clients.  See exports(5).
#
# Example for NFSv2 and NFSv3:
# /srv/homes       hostname1(rw,sync) hostname2(ro,sync)
#
# Example for NFSv4:
# /srv/nfs4        gss/krb5i(rw,sync,fsid=0,crossmnt)
# /srv/nfs4/homes  gss/krb5i(rw,sync)
/home/fhc2007/share		192.168.18.0/24(rw,sync,no_root_squash)

虽然有些客户机的说明实际上指的是多台主机,但没有办法为一组选项列出多台客户机。表16.2列出了exports文件里可以出现的4中类型的客户机说明。

表16.3给出了最常用的导出选项。

Linux的NFS服务器有个不寻常的特性,它允许已被导出的目录的子目录以不同的选项再被导出。它还提供了noaccess选项,不导出你不想共享的子目录。例如,配置:

/home   *.toadranch.com(rw)
/home/boggs     (noaccess)

能够让toadranch.com域内的主机可以访问/home下除/home/boggs之外的所有内容。在第二行没有客户机的名字出现,说明这个选项适用于所有主机,这样或许会更安全一些。
不要忘记在更新了/exports文件之后运行exportfs -a让你所做的改动起作用。

nfsd:提供文件服务

一旦mountd证实客户机的安装请求是合法的,那么客户机就可以请求各种文件系统操作了。这个些请求在服务器端由nfsd处理,nfsd是NFS的运行守护进程。除非客户机要导出自身的文件系统,否则NFS的客户机不必运行nfsd。
nfsd需要一个数值参数来指定它应该派生出多少个服务器线程。选择适当数目的nfsd很重要,遗憾的是,这个一件没准头的事情。如果数目太低或太高,NFS的性能就会受到影响。
一般而言,对一台使用不频繁的服务器来说,有8个nfsd线程就够了,而且数目少的话,就不会出现性能问题。在一台生产服务器上,12~20个nfsd是比较好的数目。随着nfsd数目的增加,你将发现平均负载会上升(正如uptime所报告的那样),说明nfsd的数目太多,应该从这个阈值处稍微减少一点。你还应该定期运行一下nfsstat,检查nfsd线程的数量可能引发的性能问题。
在带有许多UDP客户机的一台NFS服务器上,当所有nfsd线程都在使用,而此时又有请求到达的时候,就会发生UDP套接口溢出。你可以使用netstat -s命令监测溢出数目。增加更多的nfsd直到UDP套接口溢出数目降为0。溢出表明服务器提供的守护进程数量不足,所以增加的nfsd要比通过这种方法测量出来的数目多几个。
要改变nfsd进程的数量,你可以编辑/etc/init.d下恰当的启动脚本,或者在手工启动nfsd的时候在命令行指定。

客户端NFS

安装NFS文件系统和安装本地磁盘上的文件系统非常相似。mount命令能够理解hostname:directory这样的记法代表主机hostname上的目录directory。和本地文件系统一样,mount会把远程主机hostname上的目录directory映射到本地文件树上的一个目录。在完成安装之后,就可以像本地文件系统一样访问以NFS方式安装的文件系统。
在一个NFS文件系统能够被安装之前,它必须正确导出。为了从客户机的角度来核实一台服务器已经正确地导出了它的文件系统,你可以使用客户机的showmount命令:

fhc2007@fhc2007-desktop:~$ showmount -e fhc2007-desktop
Export list for fhc2007-desktop:
/home/fhc2007/share 192.168.18.0/24

这个例子指出服务器fhc2007-desktop上的目录/home/fhc2007/share已经被导出给192.168.18.0子网上的所有客户机。如果服务器上已经正确地导出了目录,但是showmount返回了一条出错消息,或者返回的列表为空,你可能需要复查一下服务器上所有必须的进程是否都在运行(portmap、mountd、nfsd、statd和lockd),hosts.allow和hosts.deny文件是否允许访问那些守护进程,以及你是否处在正确的客户机系统上。
要实际安装这个文件系统,你应该使用类似这样的一条命令:

# mount -o rw,hard,intr,bg fhc2007-desktop:/home/fhc2007/share /mnt/nfs

在-o之后的选项指出了文件系统应该以读写方式来安装,操作应该是可以中断的,而且重试应该在后台完成。这些标志相当标准,表16.4列出了其他的常用标志。

以hard(硬)方式安装的文件系统(这是默认情况)在它们的服务器宕机时会导致进程挂起。

在启动时安装远程文件系统

你可以用mount命令建立暂时的网络安装,但应该在/etc/fstab文件中列出是系统永久配置一部分的安装,以便在启动时可以自动安装它们。另外,安装可由一种自动安装服务(如autofs)处理。
下面的fstab配置项从主机coyote和inura安装文件系统/home和/usr/local:

# filesystem    mountpoint      fstype  flags   dump    fsck
coyote:/home    /coyote/home    nfs     rw,bg,intr,hard,nodev,nosuid    0      0
inura:/usr/local	/usr/local	nfs	ro,bg,intr,soft,nodev,nosuid	0	0

当你给fstab加上配置项的时候,要确保用mkdir创建适当的目录作为安装点。你可以通过运行mount -a -t nfs,安装fstab中所有的nfs类文件系统,让改动立即起作用(不需要重新启动)。/etc/fstab中的flags(标志)域指定了NFS安装的选项,这些选项和你要在mount命令行中指定的选项是一样的。

nfsstat:转储NFS统计信息

nfsstat命令显示NFS系统保留的各种统计信息。nfsstat -s显示NFS服务器进程的统计信息,nfsstat -c显示与客户端操作相关的信息。例如:

fhc2007@fhc2007-desktop:~$ nfsstat -s
Server rpc stats:
calls      badcalls   badauth    badclnt    xdrcall
1          0          0          0          0

Server nfs v3:
null         getattr      setattr      lookup       access       readlink
1       100% 0         0% 0         0% 0         0% 0         0% 0         0%
read         write        create       mkdir        symlink      mknod
0         0% 0         0% 0         0% 0         0% 0         0% 0         0%
remove       rmdir        rename       link         readdir      readdirplus
0         0% 0         0% 0         0% 0         0% 0         0% 0         0%
fsstat       fsinfo       pathconf     commit
0         0% 0         0% 0         0% 0         0%

fhc2007@fhc2007-desktop:~$ nfsstat -c
Client rpc stats:
calls      retrans    authrefrsh
0          0          0

(ps:这个是查看我本机上的NFS的统计信息,由于没有别的客户系统安装本机导出的文件系统,故所有的参数几乎是0)
偶尔运行一下nfsstat和netstat命令,熟悉一下它们的输出,有助于系统管理员比普通用户早发现NFS出现的问题。

自动安装

在文件/etc/fstab中列出各个文件系统,一次安装一个的做法,在大型网络上会引起多种问题。
首先,维护几百台机器上的/etc/fstab文件就是很枯燥乏味的。而且每个文件都有点儿区别,需要逐个维护。
其次,如果是从许多不同主机上安装文件系统的,当其中有台服务器崩溃时,就会引发混乱。访问安装点的每条命令都会被挂起,不予执行。
第三,当一台重要的服务器崩溃时,会致使用户无法访问一些重要分区,如/usr/share/man。在这种情况下,如果能从备份服务器上暂时安装这些分区的一个副本,那就最好不过了。
自动安装守护进程在文件系统被访问到时就安装文件系统,而不再需要文件系统时,就卸装它们。这一过程减少了活动安装点的数目,而且对用户几乎是透明的。大多数自动安装程序还可以提供一系列“复制的”(等同的)文件系统,这样一来,当一台主服务器不能使用时,网络仍能继续工作。
为了完成幕后的安装和卸装功能,自动安装程序在每个被指定为自动安装的目录中安装一个虚拟文件系统驱动程序。过去,自动安装程序假装成NFS服务器来完成这一任务,但这种方法存在若干明显的限制而很少在目前的系统中使用。现在使用的是一种驻留内核的文件系统驱动程序autofs。自动安装程序按照你在它的配置文件中列出的说明构成一个文件系统的层次结构来代替对实际的文件系统作镜像。当用户要访问自动安装程序的虚拟文件系统中的某个目录时,自动安装程序就会截获这次访问,并安装用户想访问的实际文件系统。

automount:根据需要安装文件系统

automount是一个后台进程,它为autofs配置一个安装点,autofs是linux的自动安装工具在内核中的部分。启动脚本/etc/init.d/autofs分析一个master(主控)文件(通常是/etc/auto.master),并且为列出的每个安装点执行automount命令。一般会看到,已经配置的每个自动安装点都有一个正在运行的automount实例。
你很少需要直接运行automount命令,因为几乎所有对自动安装程序的管理工作都是通过/etc/init.d/autofs这个脚本来完成的。和大多数启动脚本一样,autofs脚本可以在命令行接受一个参数,它可以是start、stop、reload、restart或者status。只要对自动安装工具的配置做了改动,你就必须运行autofs reload来让改动起作用。autofs status会提供你有关现有automount的状态。
auto.master文件把一个安装点和一个“映射(map)”关联起来。一个映射把被访问的目录名——称为“键(key)”——转换为mount可以用来执行实际安装操作的命令行。一个映射可以是一个文本文件、一个可执行程序或者一个NIS或者LDAP数据库。
当一个用户访问到已经用autofs内核文件系统模块安装的某个目录时,它就通知这次访问的用户级automount进程。automount进程通过参考一个映射文件或者程序,判断出要安装哪个文件,然后执行安装操作,再把控制权交还个启动这次查找的用户。

autofs的安装

以在ubuntu系统中为例

fhc2007@fhc2007-desktop:~$ sudo apt-get install autofs
[sudo] password for fhc2007:
正在读取软件包列表... 完成
正在分析软件包的依赖关系树
读取状态信息... 完成
下列【新】软件包将被安装:
  autofs
共升级了 0 个软件包,新安装了 1 个软件包,要卸载 0 个软件包,有 0 个软件未被升级。
需要下载 0B/114kB 的软件包。
操作完成后,会消耗掉 487kB 的额外磁盘空间。
选中了曾被取消选择的软件包 autofs。
(正在读取数据库 ... 系统当前总共安装有 146801 个文件和目录。)
正在解压缩 autofs (从 .../autofs_4.1.4+debian-2.1ubuntu1_i386.deb) ...
正在设置 autofs (4.1.4+debian-2.1ubuntu1) ...

Creating config file /etc/auto.master with new version

Creating config file /etc/auto.misc with new version

Creating config file /etc/auto.net with new version

Creating config file /etc/auto.smb with new version

Creating config file /etc/default/autofs with new version
Starting automounter: loading autofs4 kernel module, no automount maps defined.

主控文件

主控(master)文件列出了应该由autofs文件系统安装到它们上面的目录,并且给每个目录关联了一个映射。除了给映射和映射名提供根目录之外,你还能以mount命令使用的“-o”格式来指定其他选项。这些选项会应用到映射中的每一项上(master文件的选项是叠加到map(映射)文件的选项之上的,两组选项都要交给mount)。
一个简单的主控文件类似于下面的样子,它利用了下面的一节中给出的映射文件:

# Directory	Map	Options
/chimchim	/etc/auto.chim	-secure,hard,bg,intr

主控文件可以用一个通过NIS共享的版本来替换或者扩展。系统的automount信息来源由/etc/nsswitch.conf文件中的automount域来指定。

映射文件

映射(map)文件(在其他系统上也叫做“间接映射”)自动把几个文件系统安装到一个公共的目录下。目录路径是在主控(master)文件中,而不是在映射文件里指定的。例如,安装在/chimchim下的文件系统(对应于上面的例子)的映射文件可能看起来像是下面这样:

users	chimchim:/chimchim/users
devel	-soft,nfsproto=3 chimchim:/chimchim/devel
info	-ro chimchim:/chim/info

第一列给出了子目录的名字,每个自动安装的目录都应该安装在这个目录下,后面的几项列出了安装点、文件系统的源路径。这个例子(保存在/etc/auto.chim)告诉automount,它能从主机chimchim安装/chimchim/users、/chimchim/devel和/chimchim/info目录,info为只读安装、devel用NFS协议第三版以soft(软)方式安装。
在这一配置中,chimchim上的各个路径同本地主机上的各个路径是一样的。不过,并不要求一定有这种对应关系。

可执行的映射文件

如果一个间接映射文件是可执行的,它应该是个脚本或者程序,能动态地产生自动安装信息。代之以读取文本文件形式的映射关系,自动安装程序会带参数(“key”)来执行它,参数指出了用户试图访问哪一个子目录。脚本负责输出适用的映射项,如果指定的键(key)无效,那么脚本仅仅是退出而已,并不输出任何东西。(ps:不大明白)
这项功能非常强大,它弥补了自动安装工具相当奇怪的配置系统中许多潜在的缺陷。实际上,它能让你很轻松地以你自己的格式定义一个适用全站范围的自动安装配置文件。你可以编写一个简单的Perl脚本来解读每台机器上的全局配置。有些系统自带一个/etc/auto.net,它是一个方便的可执行映射文件,它把主机名作为键(key),安装那台机器上所有导出的文件系统。
/etc/auto.net文件的内容如下:

fhc2007@fhc2007-desktop:~$ cat /etc/auto.net
#!/bin/bash

# $Id: auto.net,v 1.8 2005/04/05 13:02:09 raven Exp $

# This file must be executable to work! chmod 755!

# Look at what a host is exporting to determine what we can mount.
# This is very simple, but it appears to work surprisingly well

key="$1"

# add "nosymlink" here if you want to suppress symlinking local filesystems
# add "nonstrict" to make it OK for some filesystems to not mount
opts="-fstype=nfs,hard,intr,nodev,nosuid,nonstrict,async"

# Showmount comes in a number of names and varieties.  "showmount" is
# typically an older version which accepts the '--no-headers' flag
# but ignores it.  "kshowmount" is the newer version installed with knfsd,
# which both accepts and acts on the '--no-headers' flag.
#SHOWMOUNT="kshowmount --no-headers -e $key"
#SHOWMOUNT="showmount -e $key | tail -n +2"

for P in /bin /sbin /usr/bin /usr/sbin
do
	for M in showmount kshowmount
	do
		if [ -x $P/$M ]
		then
			SMNT=$P/$M
			break
		fi
	done
done

[ -x "$SMNT" ] || exit 1

# Newer distributions get this right
SHOWMOUNT="$SMNT --no-headers -e $key"

$SHOWMOUNT | LC_ALL=C cut -d' ' -f1 | LC_ALL=C sort -k 1 |
	awk -v key="$key" -v opts="$opts" -- '
	BEGIN	{ ORS=""; first=1 }
		{ if (first) { print opts; first=0 }; print " nt" $1, key ":" $1 }
	END	{ if (!first) print "n"; else exit 1 }
	' | sed 's/#/#/g'

值得一提的是,自动安装工具有一个容易混淆的特性:对于被自动安装的文件系统,当你要列出其父目录的内容时,无论那里已经安装了多少文件系统,该目录都显示为空。在图形用户界面的文件浏览器里,看不到自动安装的目录。例如:

$ ls /portal
$ ls /portal/photos
art_class_2004	florissant_1003	rmnp03

文件系统photos准确无误地自动安装在/portal下,用完整的路径名能够访问到它。不过,查看/portal目录却看不到它。如果是通过/etc/fstab文件或者手工执行mount命令安装的这个文件系统,那么它就可以和其他任何目录一样,能看到是父目录下的一个子目录。
有一种变通方法,能解决上述看不到子目录问题,这就是创建一个影子目录,其中包括链到自动安装点的符号链接。例如,如果/automounts/photos是一个符号链接,它链接到了/portal/photos上,那么就可以用ls /automounts命令看到photos是一个自动安装的目录。访问/automounts/photos仍然会经过自动安装工具处理,且访问结果正确。遗憾的是,需要维护这些符号链接,除非用一个脚本定期重新生成它们,否则会使之与实际的自动安装目录情况不能保持同步和一致。

阅读(1570) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~