How to build an NFS file sharing server on Ubuntu 16.04

NFS stands for Network File System (Network File System), which is a distributed file system protocol, which allows client hosts to access server-side files through the network like a local file system. That is, the remote server files can be directly mount (mounted) to the local file directory structure for access.

1. Software installation

The server side needs to install the nfs-kernel-server software package:

$ sudo apt-get update 
$ sudo apt-get install nfs-kernel-server

Two, server configuration

By default, if a shared directory is defined on the NFS server, all files in the directory and its subdirectories can be accessed.

For security considerations, any file operations on the client that require super user (ie root user, UID=0 & GID=0) permissions are mapped to UID=65534 and GID=65534 by default User, that is nobody:nogroup in Ubuntu system.

For example, when the client uses root privileges to create a file in a mounted shared directory, the owner and group of the file will automatically become nobody:nogroup instead of root: root.

  1. Create a shared directory on the server side
sudo mkdir -p /var/nfs/gernel 
sudo mkdir -p /var/nfs/public 
sudo chown nobody:nogroup /var/nfs/gernel
  1. Modify the exports file

In order to make the shared file defined by the NFS server accessible by the specified client host, you need to add the corresponding record in the /etc/exports file on the server side.

The format of the file is as follows:

Directory Host(Options ...) Host(Options) #comment For the detailed syntax and format of the /etc/exports file, please refer to man exports.

File example:

/var/nfs/gernel 192.168.56.0/24(rw,insecure,sync,no_subtree_check)/var/nfs/public*(ro,insecure,sync,no_subtree_check)/home/starky 192.168.56.1(rw,insecure,no_root_squash,sync,no_subtree_check)

The first record indicates that all hosts in the 192.168.56.0/24 subnet can mount the var/nfs/gernel directory and have read and write (rw) permissions

The second record indicates that all hosts can mount the /var/nfs/public directory and have read-only (ro) permissions

The third record indicates that the host with the client IP address 192.168.56.1 can mount the /home/starky directory and has read and write permissions, and any file with root permissions (UID=0, GID=0) Operations are not mapped to nobody:nogroup by default, and the owner (group) remains root (no_root_squash)

insecure option: allow remote access through any port

Sync option: Force the NFS server to write file changes to disk before responding to the request (emphasizes the consistency of the file content between the client and the server, but it will reduce the efficiency of file operations).

no_subtree_check option: Disable subtree_check. subtree_check is used to set the server to check whether the file is still available in the specified directory structure when receiving a request (this option will cause an error in some cases: when a file is renamed, the file is opened on the client side).

Three, the client mounts the shared directory

List shared directories on the nfs server

$ showmount -e 192.168.56.102
Exports list on 192.168.56.102:/home/starky            192.168.56.1/var/nfs/public*/var/nfs/gernel           192.168.56.0/24

Create mount point

sudo mkdir -p /mnt/nfs/gernel 
sudo mkdir -p /mnt/nfs/public 
sudo mkdir -p /mnt/nfs/starky

Mount remote directory

sudo mount 192.168.56.102:/var/nfs/gernel /mnt/nfs/gernel 
sudo mount 192.168.56.102:/var/nfs/public/mnt/nfs/public 
sudo mount 192.168.56.102:/home/starky /mnt/nfs/starky

Permission test

As shown in the screenshot:

nfs permission test

The permission setting of NFS is based on the permission management of the Linux file system, that is, after the client mounts the remote shared directory, it will treat them as a local disk directory, which is also based on the file owner (group) and the corresponding permission setting. Restrict access.

The owner (group) of the gernel directory is nobody:nogroup (65534:65534), so although the directory has read and write permissions, non-root users cannot perform new operations. The root user is automatically mapped to nobody:nogroup due to the default security mechanism of NFS.

Since I have a user named starky on the client and server, and their UID:GID is 1000:1000, the /home/starky directory on the server can be directly accessed by the starky user on the client. And because of the no_root_squash option, the owner of the file created by the sudo command is still root (and will no longer be mapped to nobody).

Of course, this will cause some security problems. For example, if multiple clients have users with a UID (GID) of 1000 at the same time (regardless of the user name), these users will share the file permissions in the /home/starky directory on the server .

Four, the shared directory is automatically mounted when the system starts

The /etc/fstab file can be edited to make the mount operation of mounting a shared directory a fixed configuration of the system (mount command entered manually is a temporary mount and will be automatically unmounted after restart), so that the system can be automatically mounted after restart Load remote file system. The sample content of the /etc/fstab file is as follows:

# filesystem          mountpoint    fstype flags            dump  fsck
192.168.56.102: /var/nfs/gernel /mnt/nfs/gernel nfs   rw,bg,intr,hard,nodev,nosuid 00192.168.56.102:/var/nfs/public/mnt/nfs/public nfs4  ro,bg,intr,soft,nodev,nosuid 00192.168.56.102:/home/starky   /mnt/nfs/starky nfs   rw,bg,intr,hard,nodev,nosuid 00
appendix:

appendix:

1. Host format in the /etc/exports file

The format of the /etc/exports file is: Directory Host(Options ...) Host(Options) #comment

The Host item is used to specify the host that can access the corresponding shared directory, and its format can be divided into the following types:

Single host

The Host item can be one or more individual TCP/IP host names or IP addresses

admin
admin.starky.net
192.168.56.101

IP subnet

10.0.0.0 /255.0.0.0172.16.0.0/255.255.0.0192.168.56.0/24

TCP/IP domain

By using wildcard, you can specify all or part of the hosts in a specific domain

*. starky.net
* craft.starky.net
???. starky.net

NIS group

You can specify the access permissions of all hosts in a certain NIS group, using @group

**2. Options ** in the /etc/exports file

Option Description
ro read-only access
rw Read and write permissions (default)
rw=list Specify a client host with write permission through list, and other hosts have read-only permission
root_squash Map UID 0 and GID 0 to anonuid and anongid (ie nobody and nogroup in Ubuntu system)
no_root_squash Allows file operations that require root permissions, there is a security risk
all_squash Map all UIDs and GIDs to their anonymous form, mainly for untrusted hosts
anonuid=xxx Specify the UID that needs to be mapped to the operation of the client's root authority (the default is 65534)
anongid=xxx Specify the GID that needs to be mapped to the operation of the client's root authority (the default is 65534)
insecure Allow remote access through any port
async The server can respond to client write requests before writing to the hard disk
wdelay Synchronize file updates from multiple clients by delaying
sec=flavor Specify the security authentication method of the shared directory, including sys (UNIX authentication), dh(DES), krb5i, krb5p and none (anonymous access)

3. NFS mount options

Option Description
rw Mount the file system in read-write mode (rw also needs to be defined on the server side)
ro Mount the file system in read-only mode
bg If the mount fails (the server does not respond), continue to try and execute other mount requests in the background
hard If the server does not respond, repeat the request until the server replies
soft If the server does not respond, repeat the request and return an error after a certain period of time without blocking all the time
intr Allow users to interrupt blocked file operations (and return an error)
nointr Do not allow users to interrupt client file operation requests
retrans=n In soft mode, specify the number of times to repeat the request before returning an error
timeo=n Set the time interval to repeat the request after timeout (unit 1/10 second)
rsize=n Set the read buffer size to n bytes
wsize=n Set the write buffer size to n bytes
sec=flavor Set the security verification method
proto=proto Set the transmission protocol, NFSv4 must be TCP

4. NFS protocol discussion

Transfer Protocol

The original NFSv2 used the UDP protocol for performance reasons. Although NFS added its own packet sequence reorganization and error checking functions, neither UDP nor NFS have the blocking control algorithm, so in large Lack of sufficient performance in the Internet environment.

NFSv3 provides a choice between UDP and TCP protocols. NFSv4 can only use the TCP protocol.

With the increase of CPU, memory and other hardware devices and network transmission speed, the initial preference for UDP protocol due to performance requirements becomes no longer necessary.

State

NFSv2 and NFSv3 are stateless connections. The server does not track the client's mounting of the shared directory, but uses "cookies" to record a successful mount. "Cookie" will not be deleted because the server restarts, and can be used to retain the client's connection information after the server is down.

NFSv4 is a state connection. Both the client and the server maintain file operation records and file lock status. So the use of "cookies" is no longer needed.

File lock

Earlier versions of the NFS protocol (v2 & v3) are stateless connections, and they don't know which hosts are using which files. But the realization of the file lock needs to obtain the status information. Therefore, the file lock in the early protocol is implemented independently of NFS.

NFSv4 integrates the implementation of file locks into the core protocol. Although this increases complexity, it also solves many problems in the earlier version.

But in order to be compatible with clients using V2 and V3 protocols, independent locked and statd daemons are still required.

Safety related

The NFS protocol initially did not pay attention to security when it was designed. NFSv4 strengthened the security of the protocol by introducing support for stronger security services and identity verification.

The traditional NFS protocol mostly uses AUTH_SYS authentication, based on UNIX user and group identification. In this way, the client only needs to send its UID and GID and compare them with the contents of the /etc/passwd file on the server to determine what permissions it has.

So when multiple clients have users with the same UID, these users will have the same file permissions. Furthermore, users with root privileges can switch to any UID login through the su command, and the server will give them the corresponding UID privileges.

In order to prevent the above problems, the server can choose to use a more robust authentication mechanism such as Kerberos combined with NFS PRCSEC_GSS.

The access control of NFS shared directories is based on the host name or IP address defined in the /etc/exports file. But the client can easily falsify its identity and IP address, which can also cause some security problems.

NFSv4 only uses TCP as its transmission protocol, and usually only opens port 2049 for data transmission. When configuring the firewall, in addition to letting go of the 2049 port limit, you must always pay attention to the source and destination addresses of data transmission.

5. Windows system mount shared directory

The win10 system cannot mount NFS shared directories by default. You need to enter the control panel-Programs-Programs and Features-enable or disable Windows functions, and check NFS Service.

Enable nfs service

Then you can use the mount command to mount the shared directory.

mount command to mount a shared directory

It's just that the Windows system does not use user management like Linux, so the mounted shared directory can only be read but not written.

Cannot write file

The solution is to create two DWORD values in the registry to be used as the UID and GID of the anonymous user.

The mount options under the default parameters, UID and GID are both -2:

Default mount options

You can enter regedit (regedit), navigate to HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\ClientForNFS\CurrentVersion\Default, create two new DWORDs named AnonymousUid and AnonymousGid (32-bit) value, change it to the number you need to use (I changed it to 0, which corresponds to the root user in the Linux system. If you need to change it to a number other than 0, pay attention to first convert it to 16).

The mount options at this time become:

Change UID and GID

If the change does not take effect, restart the computer.

Reference materials

UNIX and Linux System Administration Handbook, 4th Edition

How to Mount an NFS Share Using a Windows 10 Machine

The above is the whole content of this article, I hope it will be helpful to everyone's study.

Recommended Posts

How to build an NFS file sharing server on Ubuntu 16.04
How to build nfs service on ubuntu16.04
Build a file server on ubuntu
Teach you how to build a Git server on Ubuntu
How to install Bacula Server on Ubuntu 14.04
How to use Samba server on Ubuntu 16.04
How to install Zabbix on Ubuntu 16.04 Server
How to install Squid proxy server on Ubuntu 18.04
How to set up Shiny Server on Ubuntu 14.04
How to set static IP on Ubuntu 18.04 Server
How to set static IP on Ubuntu 18.04 Server
How to use Jenkins to build automatically on Ubuntu
How to run the parsing server on Ubuntu 14.04
How to set up a DNS server on Ubuntu 18.04
How to install and configure NFS server on CentOS 8
How to open https on nginx server under Ubuntu
How to install Ruby on Ubuntu 20.04
Build Nginx-RTMP live server on ubuntu
How to install Java on Ubuntu 20.04
How to install VirtualBox on Ubuntu 20.04
How to install Elasticsearch on Ubuntu 20.04
How to install Protobuf 3 on Ubuntu
How to install Nginx on Ubuntu 20.04
How to install Apache on Ubuntu 20.04
How to install Git on Ubuntu 20.04
How to install Node.js on Ubuntu 16.04
How to install Vagrant on Ubuntu 20.04
How to install Bacula-Web on Ubuntu 14.04
How to install PostgreSQL on Ubuntu 16.04
How to install Git on Ubuntu 20.04
How to install Anaconda3 on Ubuntu 18.04
How to install Memcached on Ubuntu 18.04
How to install Jenkins on Ubuntu 16.04
How to install MemSQL on Ubuntu 14.04
How to install Go on Ubuntu 20.04
How to install MongoDB on Ubuntu 16.04
How to install Mailpile on Ubuntu 14.04
How to install PrestaShop on Ubuntu 16.04
How to install Skype on Ubuntu 20.04
How to install Jenkins on Ubuntu 20.04
How to install KVM on Ubuntu 18.04
How to install KVM on Ubuntu 20.04
How to install opencv3.0.0 on ubuntu14.04
How to install Anaconda on Ubuntu 20.04
How to install Prometheus on Ubuntu 16.04
How to install Jenkins on Ubuntu 18.04
How to deploy Django on Ubuntu 14.04
How to install Apache on Ubuntu 20.04
How to install R on Ubuntu 20.04
How to set up an Apache virtual host on Ubuntu 16.04
How to install Moodle on Ubuntu 16.04
How to install Solr 5.2.1 on Ubuntu 14.04
How to set up an Apache virtual host on Ubuntu 20.04
How to install Teamviewer on Ubuntu 16.04
How to secure Nginx on Ubuntu 14.04
How to install MariaDB on Ubuntu 20.04
How to install Nginx on Ubuntu 20.04
How to install Mono on Ubuntu 20.04
How to install Go on Ubuntu 20.04
How to install Zoom on Ubuntu 20.04
How to uninstall software on Ubuntu