Tunneling NFS over SSH
This recipe is for tunneling NFS traffic over SSH. This adds encryption and Public Key authentication to otherwise insecure NFS traffic.
For this recipe to work, requires NFSv4. Earlier versions were not tested, but I expect not all the functionality to work.
server configuration
Install packages:
- nfs-kernel-server
- ncat or netcat-openbsd
Configure /etc/exports
. Add a line:
/export/path 127.0.0.1(insecure,... other options...)
/export/path
: File system to export127.0.0.1
: Loopback address, we only allow local connections.insecure
: Normally, the NFS server only allows connections from ports less than 1024. This option removes that restriction. We need this because thessh
traffic is running as a normal user.
Additional NFS export options:
rw
: Allow read/write accesssync
: sync I/O (recommended to prevent data loss)no_subtree_check
: When exporting full filesystem, this remove the subtree checks. This has to do with the fact thatNFS
usesinodes
. This check is needed to make sure that theinode
is within the exported filesystem sub-tree. However if you are exporting the entire filesystem, there should never be the case that aninode
falls outside thesubtree
.no_root_squash
: allow root accessmountpoint=/mount/path
: Only export if a filesystem is mounted on/mount/path
Obtain a public/private key. Either use ssh-keygen
or copy it from elsewhere.
Install authorized_keys
on the account to be used for SSH/TCP forwarding:
command="nc -N localhost 2049",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty ssh-rsa ...
This account does not need to be root
. The additional settings make sure that this
key can only be used for forwarding traffic.
client configuration
This is for Ubuntu. Other distros may need different packages and/or approaches.
Install packages:
- nfs-common
- ncat (netcat-openbsd is not enough, ncat needs to support -e or -c)
Make sure the NFS server is in the SSH forwarder's known_hosts
file. Use this command
to make sure this happens:
ssh -n -i $ssh_key -T \
-o StrictHostKeyChecking=accept-new \
-o BatchMode=yes \
-o ConnectTimeout=10 \
$nfs_server
In this approach we are using ncat
to implement SSH
forwarder. Run this
command from the /etc/rc.local
file:
lport=4096
ssh_key=/path/to/ssh/private/key
ssh_opts="-o BatchMode=yes -o ConnectTimeout=10 -a -C"
nfs_srv=nfs-server
( ncat -l $lport -k --allow localhost -c "exec ssh -i $ssh_key $ssh_opts $nfs_srv" ) &
Options:
-a
: disable agent forwarding-C
: request compression-T
: disable pty
An alternative to this is to use inetd.conf
or use systemd.
At this point we are ready to mount NFS filesystems:
mount -t nfs \
-o nfsvers=4,nolock,nosuid,nodev,port=4096,sec=sys,tcp,soft,intr,fg \
localhost:/export/nfs/path \
/mnt
Options:
nfsvers=4
: make sure we are running NFSv4nosuid
: disable SUID executablesnodev
: disable device filessec=sys
: traditional UNIX security modestcp
: use TCP protocolsoft,intr
: how we handle CTRL+C and other errors
Caveats
showmount
command does not show NFSv4 information.- I have not tried to use this with
autofs
.autofs
configure for NFS shares is in/etc/autofs/auto.net
, but it usesshowmount
command, so it probably would not work out of the box.
Notes
Some implementations of the nc
command supports a -p source_port
option. This would
remove the need to use the insecure
option from the nfs export options. However this
requires netcat to run as root.
References: