/etc/exports 设定档的语法与参数

/etc/exports 设定档的语法与参数

在开始 NFS 伺服器的设定之前,您必须要瞭解的是,NFS 会直接使用到核心功能,所以你的核心必须要有支援 NFS 才行。 万一如果你的核心版本小于 2.2 版,或者重新自行编译过核心的话,那么就得要很注意啦! 因为你可能会忘记选择 NFS 的核心支援啊!

还好,我们 CentOS 或者是其他版本的 Linux ,预设核心通常是支援 NFS 功能的, 所以你只要确认你的核心版本是目前新的 2.6.x 版,并且使用你的 distribution 所提供的核心, 那应该就不会有问题啦!

至于 NFS 伺服器的架设实在很简单,你只要编辑好主要设定档 /etc/exports 之后, 先启动 portmap ,然后再启动 nfs ,你的 NFS 就成功了! 不过这样的设定能否对用户端生效?那就得要考虑你权限方面的设定能力了。 废话少说,我们就直接来看看那个 /etc/exports 应该如何设定吧! 某些 distributions 并不会主动提供 /etc/exports 档案,所以请您自行手动建立他吧。
[root@linux ~]# vi /etc/exports
/tmp 192.168.1.0/24(ro) localhost(rw) *.ev.ncku.edu.tw(ro,sync)
# [分享目录] [第一部主机(权限)] [可用主机名] [可用万用字元]
您看看,这个设定档有够简单吧!每一行最前面是要分享出来的目录,注意喔!是以目录为单位啊! 然后这个目录可以依照不同的权限分享给不同的主机,像鸟哥上面的例子说明是: 要将 /tmp 分别分享给三个不同的主机或网域的意思。记得主机后面以小括号 () 设计权限参数, 若权限参数不止一个时,则以逗号 (,) 分开。且主机名与小括号是连在一起的喔! 在这个档案内也可以利用 # 来注解呢。

至于主机名称的设定主要有几个方式:
  • 可以使用完整的 IP 或者是网域,例如 192.168.1.10 或 192.168.1.0/24 ,或 192.168.1.0/255.255.255.0 都可以接受!

  • 可以使用主机名称,这个主机名称要在 /etc/hosts 内或使用 DNS 可以被找到才行啊!重点是可找到 IP 就是了。如果是主机名称的话,那么他可以支援万用字元,例如 * 或 ? 均可接受。
至于权限方面 (就是小括号内的参数) 常见的参数则有:
  • rw:read-write,可读写的权限;

  • ro:read-only,唯读的权限;

  • sync:资料同步写入到记忆体与硬碟当中;

  • async:资料会先暂存于记忆体当中,而非直接写入硬碟!

  • no_root_squash:
    登入 NFS 主机使用分享目录的使用者,如果是 root 的话,那么对于这个分享的目录来说,他就具有 root 的权限! 这个项目『极不安全』,不建议使用!

  • root_squash:
    在登入 NFS 主机使用分享之目录的使用者如果是 root 时,那么这个使用者的权限将被压缩成为匿名使用者,通常他的 UID 与 GID 都会变成 nobody(nfsnobody) 那个系统帐号的身份;

  • all_squash:
    不论登入 NFS 的使用者身份为何, 他的身份都会被压缩成为匿名使用者,通常也就是 nobody(nfsnobody) 啦!

  • anonuid:
    anon 意指 anonymous (匿名者) 前面关于 *_squash 提到的匿名使用者的 UID 设定值,通常为 nobody(nfsnobody),但是您可以自行设定这个 UID 的值!当然,这个 UID 必需要存在于您的 /etc/passwd 当中!

  • anongid:同 anonuid ,但是变成 group ID 就是了!
这是几个比较常见的权限参数,如果你有兴趣玩其他的参数时,请自行 man exports 可以发现很多有趣的资料。 接下来我们利用上述的几个参数来实际思考一下几个有趣的小习题:

  • 思考一:让 root 保有 root 的权限
    我想将 /tmp 分享出去给大家使用,由于这个目录本来就是大家都可以读写的,因此想让所有的人都可以存取。 此外,我要让 root 写入的档案还是具有 root 的权限,那如何设计设定档?
    [root@linux ~]# vi /etc/exports
    # 任何人都可以用我的 /tmp ,用万用字元来处理主机名称,重点在 no_root_squash
    /tmp *(rw,no_root_squash)
    
    参考前面的主机名称设定说明,我们可以利用万用字元的。这表示无论来自哪里都可以使用我的 /tmp 这个目录。 再次提醒,『 *(rw,no_root_squash) 』这一串设定值中间是没有空白字元的喔!而 /tmp 与 *(rw,no_root_squash) 则是有空白字元来隔开的!特别注意到那个 no_root_squash 的功能!在这个例子中,如果你是用户端,而且您是以 root 的身份登入您的 Linux 主机,那么当您 mount 上我这部主机的 /tmp 之后,您在该 mount 的目录当中,将具有『root 的权限!』 

  • 思考二:同一目录针对不同范围开放不同权限
    我要将一个公共的目录 /home/public 公开出去,但是只有限定我的区域网路内 192.168.0.0/24 这个网域可以读写,其他人则只能读取:
    [root@linux ~]# vi /etc/exports
    /tmp *(rw,no_root_squash)
    /home/public 192.168.0.0/24(rw) *(ro)
    # 继续累加在后面,注意,我有将主机与网域分为两段 (用空白隔开) 喔!
    
    上面的例子说的是,当我的 IP 是在 192.168.0.0/24 这个网段的时候,那么当我在 Client 端挂载了 Server 端的 /home/public 后,针对这个被我挂载的目录我就具有可以读写的权限~ 至于如果我不是在这个网段之内,那么这个目录的资料我就仅能读取而已,亦即为唯读的属性啦!

    需要注意的是,之前鸟哥将主机名称的万用字元与 IP 网段搞错了! 万用字元仅能用在主机名称的分辨上面,IP 或网段就只能用 192.168.0.0/24 的状况, 不可以使用 192.168.0.* 喔!

  • 思考三:仅给某个单一主机使用的目录设定
    我要将一个私人的目录 /home/test 开放给 192.168.0.100 这个 Client 端的机器来使用,那么我就必需这么写:
    [root@linux ~]# vi /etc/exports
    /tmp *(rw,no_root_squash)
    /home/public 192.168.0.0/24(rw) *(ro)
    /home/test 192.168.0.100(rw)
    # 只要设定 IP 正确即可!
    
    这样就设定完成了!而且,只有 192.168.0.100 这部机器才能对 /home/test 这个目录进行存取喔!

  • 思考四:开放匿名登入的情况
    我要让 *.linux.org 网域的主机,登入我的 NFS 主机时,可以存取 /home/linux ,但是他们存资料的时候,我希望他们的 UID 与 GID 都变成 40 这个身份的使用者, 假设我 NFS 伺服器上的 UID 40 已经有设定妥当:
    [root@linux ~]# vi /etc/exports
    /tmp *(rw,no_root_squash)
    /home/public 192.168.0.0/24(rw) *(ro)
    /home/test 192.168.0.100(rw)
    /home/linux *.linux.org(rw,all_squash,anonuid=40,anongid=40)
    # 如果要开放匿名,那么重点是 all_squash,并且要配合 anonuid 喔!
    
    特别注意到那个 all_squash 与 anonuid, anongid 的功能!如此一来,当 test.linux.org 登入这部 NFS 主机,并且在 /home/linux 写入档案时,该档案的所有人与所有群组,就会变成 /etc/passwd 里面对应的 UID 为 40 的那个身份的使用者了!

    上面四个案例的权限如果依照前一小节的存取设定权限来思考的话, 那么权限会是什么情况呢?让我们来检查一下:

  • 用户端与主机端具有相同的 UID 与帐号:
    假设我在 192.168.0.100 登入这部 NFS (IP 假设为 192.168.0.2) 主机,并且我在 192.168.0.100 的帐号为 dmtsai 这个身份,同时,在这部 NFS 上面也有 dmtsai 这个帐号, 并具有相同的 UID ,果真如此的话,那么:
    1. 由于 192.168.0.2 这部 NFS 主机的 /tmp 权限为 -rwxrwxrwt ,所以我 (dmtsai 在 192.168.0.100 上面) 在 /tmp 底下具有存取的权限,并且写入的档案所有人为 dmtsai ;
    2. 在 /home/public 当中,由于我有读写的权限,所以如果在 /home/public 这个目录的权限对于 dmtsai 有开放写入的话,那么我就可以读写,并且我写入的档案所有人是 dmtsai 。但是万一 /home/public 对于 dmtsai 这个使用者并没有开放可以写入的权限时, 那么我还是没有办法写入档案喔!这点请特别留意!
    3. 在 /home/test 当中,我的权限与 /home/public 相同的状态!还需要 NFS 主机的 /home/test 对于 dmtsai 有开放权限;
    4. 在 /home/linux 当中就比较麻烦!因为不论您是何种 user ,您的身份一定会被变成 UID=40 这个帐号!所以,这个目录就必需要针对 UID = 40 的那个帐号名称,修改他的权限才行!
  • 用户端与主机端的帐号并未相同时:
    假如我在 192.168.0.100 的身份为 vbird ,但是 192.168.0.2 这部 NFS 主机却没有 vbird 这个帐号时,情况会变成怎样呢?
    1. 我在 /tmp 底下还是可以写入,但是写入的档案所有人变成 nobody 了;
    2. 我在 /home/public 里面是否可以写入,还需要视 /home/public 的权限而定,不过,反正我的身份就被变成 nobody 了就是;
    3. /home/test 的观点与 /home/public 相同!
    4. /home/linux 底下,我的身份就被变成 UID = 40 那个使用者就是了!
  • 当用户端的身份为 root 时:
    假如我在 192.168.0.100 的身份为 root 呢? root 这个帐号每个系统都会有呀!权限变成怎样呢?
    1. 我在 /tmp 里面可以写入,并且由于 no_root_squash 的参数,改变了预设的 root_squash 设定值,所以在 /tmp 写入的档案所有人为 root 喔!
    2. 我在 /home/public 底下的身份还是被压缩成为 nobody 了!因为预设属性里面都具有 root_squash 呢!所以,如果 /home/public 有针对 nobody 开放写入权限时,那么我就可以写入,但是档案所有人变成 nobody 就是了!
    3. /home/test 与 /home/public 相同;
    4. /home/linux 的情况中,我 root 的身份也被压缩成为 UID = 40 的那个使用者了!
    这样的权限讲解之后,您可以瞭解了吗?这里是最重要的地方,如果这一关通过了,底下的咚咚就没有问题啦! ^_^! 当然啦,您还是得要回到前一小节NFS 的档案存取权限好好的瞧一瞧, 才能解决 NFS 的问题喔!

启动 NFS

设定档搞定后,当然要开始来启动才行啊!而前面我们也提到过,NFS 的启动还需要 portmap 的协助才行啊! 所以赶紧来启动吧!
[root@linux ~]# /etc/init.d/portmap start
# 如果 portmap 本来就已经在执行了,那就不需要启动啊!
[root@linux ~]# /etc/init.d/nfs start
# 有时候可能会出现如下的警告讯息:
exportfs: /etc/exports [3]: No 'sync' or 'async' option specified
for export "192.168.0.100:/home/test".
Assuming default behaviour ('sync').
# 上面的警告讯息仅是在告知因为我们没有指定 sync 或 async 的参数,
# 则 NFS 将预设会使用 sync 的资讯而已。你可以不理他,也可以加入 /etc/exports。
[root@linux ~]# vi /etc/exports
/tmp *(rw,no_root_squash,sync)
/home/public 192.168.0.0/24(rw,sync) *(ro,sync)
/home/test 192.168.0.100(rw,sync)
/home/linux *.linux.org(rw,all_squash,anonuid=40,anongid=40,sync)
[root@linux ~]# /etc/init.d/nfs restart
那个 portmap 根本就不需要设定!只要直接启动他就可以啦!启动之后,会出现一个 port 111 的 sunrpc 的服务,那就是 portmap 啦!至于 nfs 则会启动至少两个以上的 daemon 出现!然后就开始在监听 Client 端的需求啦!你必须要很注意萤幕上面的输出资讯, 因为如果设定档写错的话,萤幕上会显示出错误的地方喔!

此外,如果你想要增加一些 NFS 伺服器的资料一致性功能时,可能需要用到 rpc.lockd 及 rpc.statd 等 RPC 服务, 那么或许你可以增加一个服务,那就是 nfslock
[root@linux ~]# /etc/init.d/nfslock start
启动之后,请赶快到 /var/log/messages 里面看看有没有被正确的启动呢?
[root@linux ~]# vi /var/log/messages
Sep 22 00:01:37 linux nfs: Starting NFS services: succeeded
Sep 22 00:01:37 linux nfs: rpc.rquotad startup succeeded
Sep 22 00:01:37 linux nfsd[1050]: nfssvc_versbits: +2 +3 +4
Sep 22 00:01:37 linux nfs: rpc.nfsd startup succeeded
Sep 22 00:01:37 linux nfs: rpc.mountd startup succeeded
Sep 22 00:01:37 linux rpcidmapd: rpc.idmapd -SIGHUP succeeded
在确认没有问题之后,接下来我们来瞧一瞧那么 NFS 到底开了哪些埠口?
[root@linux ~]# netstat -ultn
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:2049 0.0.0.0:* LISTEN -
tcp 0 0 0.0.0.0:803 0.0.0.0:* LISTEN 1047/rpc.rquotad
tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN 32503/portmap
tcp 0 0 0.0.0.0:819 0.0.0.0:* LISTEN 1064/rpc.mountd
udp 0 0 0.0.0.0:2049 0.0.0.0:* -
udp 0 0 0.0.0.0:800 0.0.0.0:* 1047/rpc.rquotad
udp 0 0 0.0.0.0:816 0.0.0.0:* 1064/rpc.mountd
udp 0 0 0.0.0.0:111 0.0.0.0:* 32503/portmap
注意看到上面喔!总共产生了好多的 port 喔!真是可怕!不过主要的埠口是:
  • portmap 启动的 port 在 111;
  • NFS 启动的 port 在 2049;
  • 其他 rpc.daemons 启动的 port 则是随机产生的,因此需向 port 111 注册。
好了,那我怎么知道每个 RPC 服务的注册状况?没关系,你可以使用 rpcinfo 来处理的。
[root@linux ~]# rpcinfo [-p] [IP|hostname]
参数:
-p :显示出所有的 port 与 porgram 的资讯;
范例一:显示出目前这部主机的 RPC 状态
[root@linux ~]# rpcinfo -p localhost
program vers proto port
100000 2 tcp 111 portmapper
100000 2 udp 111 portmapper
100011 1 udp 800 rquotad
100011 2 udp 800 rquotad
100011 1 tcp 803 rquotad
100011 2 tcp 803 rquotad
100003 2 udp 2049 nfs
100003 3 udp 2049 nfs
100003 2 tcp 2049 nfs
100003 3 tcp 2049 nfs
100005 1 udp 816 mountd
100005 1 tcp 819 mountd
100005 2 udp 816 mountd
100005 2 tcp 819 mountd
100005 3 udp 816 mountd
100005 3 tcp 819 mountd
# NFS版本 埠口 服务名称
仔细瞧瞧,上面出现的资讯当中除了程式名称与埠口的对应可以与 netstat -tlunp 输出的结果作比对之外,还需要注意到 NFS 的版本支援!新的 NFS 版本传输速度较快, 由上表看起来,我们的 NFS 至少支援到第 3 版,应该还算合理啦! ^_^! 如果你的 rpcinfo 无法输出,那就表示注册的资料有问题啦!可能需要重新启动 portmap 与 nfs 喔!


NFS 的连线观察

在你的 NFS 伺服器设定妥当之后,我们可以先自我测试一下是否可以连线喔! 就是利用 showmount 这个指令来查阅!
[root@linux ~]# showmount [-ae] [hostname|IP]
参数:
-a :显示目前主机与用户端的 NFS 连线分享的状态;
-e :显示某部主机的 /etc/exports 所分享的目录资料。
范例一:请显示出刚刚我们所设定好的相关 exports 资讯
[root@linux ~]# showmount -e localhost
Export list for localhost:
/tmp *
/home/linux *.linux.org
/home/public (everyone)
/home/test 192.168.0.100
很简单吧!所以,当您要扫瞄某一部主机他提供的 NFS 分享的目录时,就使用 showmount -e IP (或hostname) 即可!非常的方便吧!这也是 NFS client 端最常用的指令喔!

事实上 NFS 关于目录权限设定的资料非常之多!我们可以检查一下 /var/lib/nfs/etab 就知道了!
[root@linux ~]# tail /var/lib/nfs/etab
/home/public *(ro,sync,wdelay,hide,nocrossmnt,secure,root_squash,no_all_squash,
subtree_check,secure_locks,mapping=identity,anonuid=-2,anongid=-2)
# 上面是同一行,可以看出除了 ro, sync, root_squash 等等,
# 其实还有 anonuid 及 anongid 等等的设定!
/tmp *(rw,sync,wdelay,hide,nocrossmnt,secure,no_root_squash,no_all_squash,subtr
ee_check,secure_locks,mapping=identity,anonuid=-2,anongid=-2)
# 同样的,在 /tmp 也有很多的权限相关的参数喔!
上面仅仅是一个小范例,只是....怎么 anonuid 会是 -2 啊? 其实那个数值是 65536-2 啦!所以得到 65534 ,比对 /etc/passwd , 会发现 CentOS 出现的是 nfsnobody 啦!这个帐号在不同的版本都可能会不一样的! 另外,如果有其他用户端挂载了你的 NFS 档案系统时, 那么该用户端与档案系统资讯就会被记录到 /var/lib/nfs/xtab 里头去的!

另外,如果你想要重新处理 /etc/exports 档案,当重新设定完 /etc/exports 后需不需要重新启动 nfs ? 不需要啦!如果重新启动 nfs 的话,要得要向 RPC 注册!很麻烦~ 这个时候我们可以透过 exportfs 这个指令来帮忙喔!
[root@linux ~]# exportfs [-aruv]
参数:
-a :全部挂载(或卸载) /etc/exports 档案内的设定
-r :重新挂载 /etc/exports 里面的设定,此外,亦同步更新 /etc/exports
及 /var/lib/nfs/xtab 的内容!
-u :卸载某一目录
-v :在 export 的时候,将分享的目录显示到萤幕上!
范例一:重新挂载一次 /etc/exports 的设定
[root@linux ~]# exportfs -arv
exporting 192.168.0.100:/home/test
exporting 192.168.0.0/24:/home/public
exporting *.linux.org:/home/linux
exporting *:/home/public
exporting *:/tmp
范例二:全部都卸载
[root@linux ~]# exportfs -auv
要熟悉一下这个指令的用法喔!这样一来,就可以直接重新 exportfs 我们的记录在 /etc/exports 的目录资料
 

[root@linux ~]# showmount -e 192.168.0.2
Export list for 192.168.0.2:
/tmp         *
/home/linux  *.linux.org
/home/public (everyone)   <==这是等一下我们要挂载的目录
/home/test   192.168.0.100
 
[root@linux ~]# mkdir -p /home/nfs/public
 
[root@linux ~]# mount -t nfs -o nolock 192.168.0.2:/home/public /home/nfs/public
# 注意一下挂载的语法!『 -t nfs 』指定档案系统类型,
# IP:/dir 则是指定某一部主机的某个提供的目录!
 
[root@linux ~]# df
Filesystem    1K-blocks      Used Available Use% Mounted on
....中间省略....
192.168.0.2:/home/public
               10080512   2135072   7433344  23% /home/nfs/public
 
[root@linux ~]# umount /home/nfs/public
posted @ 2017-07-02 16:40  百衲本  阅读(4130)  评论(0编辑  收藏  举报
cnblogs_post_body { color: black; font: 0.875em/1.5em "微软雅黑" , "PTSans" , "Arial" ,sans-serif; font-size: 15px; } cnblogs_post_body h1 { text-align:center; background: #333366; border-radius: 6px 6px 6px 6px; box-shadow: 0 0 0 1px #5F5A4B, 1px 1px 6px 1px rgba(10, 10, 0, 0.5); color: #FFFFFF; font-family: "微软雅黑" , "宋体" , "黑体" ,Arial; font-size: 23px; font-weight: bold; height: 25px; line-height: 25px; margin: 18px 0 !important; padding: 8px 0 5px 5px; text-shadow: 2px 2px 3px #222222; } cnblogs_post_body h2 { text-align:center; background: #006699; border-radius: 6px 6px 6px 6px; box-shadow: 0 0 0 1px #5F5A4B, 1px 1px 6px 1px rgba(10, 10, 0, 0.5); color: #FFFFFF; font-family: "微软雅黑" , "宋体" , "黑体" ,Arial; font-size: 20px; font-weight: bold; height: 25px; line-height: 25px; margin: 18px 0 !important; padding: 8px 0 5px 5px; text-shadow: 2px 2px 3px #222222; } cnblogs_post_body h3 { background: #2B6695; border-radius: 6px 6px 6px 6px; box-shadow: 0 0 0 1px #5F5A4B, 1px 1px 6px 1px rgba(10, 10, 0, 0.5); color: #FFFFFF; font-family: "微软雅黑" , "宋体" , "黑体" ,Arial; font-size: 18px; font-weight: bold; height: 25px; line-height: 25px; margin: 18px 0 !important; padding: 8px 0 5px 5px; text-shadow: 2px 2px 3px #222222; } 回到顶部 博客侧边栏 回到顶部 页首代码 回到顶部 页脚代码