Tunneling NFS Through SSH
One method of encrypting NFS traffic over a network is to use the port-forwarding capabilities of ssh. However, as we shall see, doing so has a serious drawback if you do not utterly and completely trust the local users on your server.
The first step will be to export files to the localhost. For example, to export the /home partition, enter the following into /etc/exports:
/home 127.0.0.1(rw)
The next step is to use ssh to forward ports. For example, ssh can tell the server to forward to any port on any machine from a port on the client. Let us assume, as in the previous section, that our server is 192.168.0.42, and that we have pinned mountd to port 32767 using the argument -p 32767. Then, on the client, we’ll type:
# ssh root@192.168.0.42 -L 250:localhost:2049 -f sleep 60m # ssh root@192.168.0.42 -L 251:localhost:32767 -f sleep 60m
The above command causes ssh on the client to take any request directed at the client’s port 250 and forward it, first through sshd on the server, and then on to the server’s port 2049. The second line causes a similar type of forwarding between requests to port 251 on the client and port 32767 on the server. The localhost is relative to the server; that is, the forwarding will be done to the server itself. The port could otherwise have been made to forward to any other machine, and the requests would look to the outside world as if they were coming from the server. Thus, the requests will appear to NFSD on the server as if they are coming from the server itself. Note that in order to bind to a port below 1024 on the client, we have to run this command as root on the client. Doing this will be necessary if we have exported our filesystem with the default secure option.
Finally, we are pulling a little trick with the last option, -f sleep 60m. Normally, when we use ssh, even with the -L option, we will open up a shell on the remote machine. But instead, we just want the port forwarding to execute in the background so that we get our shell on the client back. So, we tell ssh to execute a command in the background on the server to sleep for 60 minutes. This will cause the port to be forwarded for 60 minutes until it gets a connection; at that point, the port will continue to be forwarded until the connection dies or until the 60 minutes are up, whichever happens later. The above command could be put in our startup scripts on the client, right after the network is started.
Next, we have to mount the filesystem on the client. To do this, we tell the client to mount a filesystem on the localhost, but at a different port from the usual 2049. Specifically, an entry in /etc/fstab would look like:
localhost:/home /mnt/home nfs rw,hard,intr,port=250,mountport=251 0 0
Having done this, we can see why the above will be incredibly insecure if we have any ordinary users who are able to log in to the server locally. If they can, there is nothing preventing them from doing what we did and using ssh to forward a privileged port on their own client machine (where they are legitimately root) to ports 2049 and 32767 on the server. Thus, any ordinary user on the server can mount our filesystems with the same rights as root on our client.
If you are using an NFS server that does not have a way for ordinary users to log in, and you wish to use this method, there are two additional caveats: First, the connection travels from the client to the server via sshd; therefore you will have to leave port 22 (where sshd listens) open to your client on the firewall. However you do not need to leave the other ports, such as 2049 and 32767, open anymore. Second, file locking will no longer work. It is not possible to ask statd or the locking manager to make requests to a particular port for a particular mount; therefore, any locking requests will cause statd to connect to statd on localhost, i.e., itself, and it will fail with an error. Any attempt to correct this would require a major rewrite of NFS.
It may also be possible to use IPSec to encrypt network traffic between your client and your server, without compromising any local security on the server; this will not be taken up here. See the FreeS/WAN home page for details on using IPSec under Linux.
If you enjoyed this post, please consider to leave a comment or subscribe to the feed and get future articles delivered to your feed reader.










Comments
No comments yet.
Leave a comment