Ubuntu伺服器上配置NFS的一個坑
具體步驟沒什麼好說的,官方Wiki有詳細的文檔:SettingUpNFSHowTo - Community Help Wiki
我一路上設置下來也還順利。很快在client上就能看到mount的nfs了。cat一下沒有問題,然而試著touch一下突然就返回一個permission denied。。於是趕緊ls -l 查看了一下許可權,大概是這樣:
drwxrwxr-x not-me not-my-group 4096 Jul 12 2016 some-dirn
Owner 顯示的是另外一個用戶的用戶名,難怪沒有寫許可權。。我大概意識到可能是剛才沒有設置用戶mapping的緣故。然後稍微查了一下,找到了解決方案:
在server端:
# echo N > /sys/module/nfsd/parameters/nfs4_disable_idmappingn
在client端:
# echo N > /sys/module/nfs/parameters/nfs4_disable_idmappingn
(注意是nfs 和 nfsd 的區別)
然後兩邊分別:
# nfsidmap -cn# service idmapd restartn
如果還不正常的話,就restart service或者umount再mount。
之後再 ls -l
drwxrwxr-x me my-group 4096 Jul 12 2016 some-dirn
就正常啦。
於是又滿懷信心地 touch 了一下。。居然再次被 permission denied 。。
再次Google一番,終於找到問題,發現主要是出在NFS的安全機制上:
首先NFS的server要有一個host list (也就是在/etc/exports/里的),來限制可以訪問的client machine。但我們有時候並不希望所有client上的用戶都能訪問NFS,怎麼辦呢?NFS這時候採用AUTH_SYS的認證方式,也就是說,server和client端的UID和GID必須完全吻合,且對應ID在server上有訪問許可權才可以,否則就會被認為是路人(nobody)處理。
等一下,我們剛剛不是已經解決了ID mapping的問題了么?為什麼還是不行?
原因在於,我們剛剛解決的ID mapping的問題,只是限於NFS上層的,比如說,當你 ls 的時候,它會非常貼心地把原來並不match的username糾正過來。然而在NFS真正實現檢測是否有訪問許可權的底層RPC中,用的還是UID的數字值,不是用username!NFS底層用的是 rpc.gssd RPC協議,資料里很清楚地寫著:
It attempts to find credentials for the user (using only the UID) and calls rpcsec_gss routine authgss_create() to create an rpc context
所以其實剛才弄的ID mapping是白忙活了,因為認證還是得靠數值的UID。。NFSv4的mapping只是穿了個馬甲,並不解決問題。。
好了,最後說下解決方案:
- 如果你對server和client擁有完全的(root)控制,那麼你可以把所有機器上的UID和GID修改成一致的。但這個方法不是很靈活,而且改完UID/GID還得記得把所有相關文件的許可權順便修改了,我覺得太麻煩了,遂沒有採用。。
- 如果你明確知道自己想幹什麼,且NFS的訪問用戶是你trusted party,那麼你可以用all_squash選項,並且設置相應的anonuid,anongid,使得所有client獲得相應許可權。此方法的優點是比較省事,只需要在server上進行一點改動。缺點是client上的所有user都會獲得同等的許可權,因此僅適用於trusted network。
- 如果需要更嚴格的認證,可以用 Kerberos 配合NFS使用,只是設置會稍稍麻煩一點。
- 或者另闢蹊徑,使用Samba這樣的文件共享系統。(有跨平台需求的同學也可以用)
參考:
gssd(8) - Linux manual page
http://www.citi.umich.edu/projects/nfsv4/gssd/
18.8. Securing NFS
推薦閱讀:
※RHCE证书的含金量怎么样,这个证好不好考,考出来以后做关于Linux的哪方面工作,或者在公司能够做什么
※如何解決ubuntu筆記本續航不佳的問題?
※在使用coroutine+asio多線程框架的時候,如何維護連接池復用連接?
※Linux上有哪些操作是原子操作?