SECURE NFS VIA SSH TUNNELLING
                  John Bowman <bowman@math.ualberta.ca>
                 http://www.math.ualberta.ca/imaging/snfs
                              31 October 2002

                        INSTALLATION INSTRUCTIONS
                        
1. SETUP LOOPBACK NFS EXPORT ON REMOTE HOST.  
On each remote nfs server (which we will call REMOTE), export the desired
directories to itself, using the fully qualified REMOTE.domain hostname or
IP number. (You may export to localhost or localhost.localdomain or
127.0.0.1 but there have been past exploits of NFS based on exporting to
localhost, so this is not recommended).

Prevent other computers from directly accessing the nfs-mounted directories
you want to protect and re-export them; e.g. with exportfs -r. (You may
still export unsecured filesystems, but be warned that not only would this
expose the data, but in some cases the daemons themselves could then
possibly be exploited by an outsider to compromise the entire system, not
just the exported filesystems).

Ensure that conventional NFS is up and running: verify that you can mount
the exported directories on the same machine (on REMOTE; not on localhost).
If you want to prevent other hosts from accessing portmap, give authorization
allowing only REMOTE to read the portmap, by putting portmap: IP
in /etc/hosts.allow (here IP should be replaced by the IP number of REMOTE)
and ALL:ALL in /etc/hosts.deny.

2. BUILD AND INSTALL THE NECESSARY FILES.  
By default the executable files will be installed in /usr/local/bin.
Make sure that this directory is in your path. On both the remote and local
computers, in the top directory of sec_rpc do the following:

./configure
make install

3. CONFIGURE EACH CONNECTION TO REMOTE HOSTS.
On the local computer, create a configuration file for each REMOTE host.
This can be done easily with the command

snfshost REMOTE:MOUNTPROG

Here MOUNTPROG is a six-digit number chosen between 200000 and 249999
such that both MOUNTPROG and NFSPROG=MOUNTPROG+50000 are unassigned RPC program
numbers (e.g. MOUNTPROG=201000, NFSPROG=251000). A unique MOUNTPROG must be
assigned for each REMOTE host. The supplied template (TEMPLATE) is
set up for NFS version 3 by default but can easily be changed to version 2. 

4. PREPARE FILE SYSTEM TABLE.
For each REMOTE host and exported directory DIR: add an entry in /etc/fstab 
(here LOCAL.DOMAIN is the fully qualified local hostname, and
MOUNTPROG and NFSPROG are the six-digit numbers from step 3):

LOCAL.DOMAIN:/DIR /REMOTE/DIR nfs user,noauto,hard,intr,rsize=8192,wsize=8192,mountprog=MOUNTPROG,nfsprog=NFSPROG 0 0

Alternatively, you may wish to convert existing /etc/fstab nfs entries to use
snfs with the program snfsfstab. This will create a file /etc/fstab.snfs,
which you can use as a template for /etc/fstab changes or even rename to
/etc/fstab.

5. TEST THE SETUP.
Create a secure user snfs (e.g. uid=87, gid=87) on both machines.
On the local computer, create the mount directories and start the RPC
server (see the file NFS/FAQ and Step 9 for troubleshooting hints):

smkdirall
rpc_psrv -r -d /usr/local/etc/snfs/REMOTE

Enter REMOTE's root password when prompted. If you get the message
"ID String correctly read: RPC Proxy Client" then you are ready to mount:

mount /REMOTE/DIR
df

6. AUTOMATE THE SETUP.  
Set up passwordless ssh public key access from the account to be used to
initiate secure mounts on the local machine to an account on REMOTE, using
empty passphrases (e.g. user -> user). Verify that you can log into REMOTE
as this user, without a password.

If the secure mounts are to be initiated as root, rpc_psrv will be run as
user snfs; instead of making the connection root -> root, the connection
will be snfs -> snfs.

If the user names differ on the two machines, you may either give an
explicit user name in the SshCommand in /usr/local/etc/snfs/REMOTE
or add an appropriate Host/User entry in the ssh user config file.

In the top directory of sec_rpc on REMOTE, use the following command to
change the group of the installed program rpc_pcl to snfs, turn the setuid
bit on, and change the ownership of /usr/local/etc/snfs to snfs:

make setuid

To change ownership without making rpc_pcl setuid (in case you want HOST
to be only a client and not a secure NFS server), you may instead do this:

make ownership

7. CONGRATULATIONS.
You are ready to mount (and then unmount) the exported directory from REMOTE
on the local computer:

snfsmount /REMOTE/DIR
df
snfsumount /REMOTE/DIR

To mount/umount all secure nfs filesystems from REMOTE you can use the
commands:

smount REMOTE
df
sumount REMOTE

To mount/umount all secure nfs filesystems from REMOTE1 and REMOTE2 you can
use the commands:

smount REMOTE1 REMOTE2
df
sumountall

8. AMD (AUTOMOUNT DAEMON) SUPPORT (OPTIONAL).
SNFS has been integrated with amd, the AutoMount Daemon
(http://www.am-utils.org). For each remote REMOTE, include in /etc/amd.conf
an entry like this:

[ /REMOTE ]
map_name = amd.REMOTE
map_type = file

and create a file /etc/amd.REMOTE containing directory entries of the form

DIR \
        type:=program;\
        fs:=/a/REMOTE/DIR;\
        mount:="/usr/local/bin/snfsmount snfsmount ${fs}";\
        unmount:="/usr/local/bin/snfsumount snfsumount ${fs}"

Finally, change all mount points /REMOTE/DIR in /etc/fstab to /a/REMOTE/DIR and
execute the commands (assuming the automount directory /a):

mkdir /a
mv /REMOTE /a

Sample amd.conf and amd.REMOTE files can be found in the examples directory.

9. TROUBLESHOOTING.

To diagnose an error message, consult the file NFS/FAQ. 

To enable further debugging information, either call snfsmount with -d or
rpc_psrv with -d or or -b -d -e <psrv_debug_file>.
This will also cause rpc_pcl to log debugging information in the file
(e.g. /tmp/pcl_log) specified in the REMOTE configuration file. Some
error messages only go to syslog, so the default setting of LogToSyslog is yes.
To troubleshoot the ssh connection you can add -vv to the ssh command line
in the REMOTE configuration file.

To test the passwordless ssh authentication execute as root (for the snfs user)

su snfs; ssh REMOTE

If you get the error message 
Could not create directory
'/usr/local/etc/snfs/.ssh' this is because /usr/local/etc/snfs/ belongs to
root instead of snfs.  You can create the directory by hand, or use the
snfsuser command (snfsuser --create-user, or snfsuser --import, or snfsuser
--create-keys depending on your needs). Even if the .ssh directory exists
and is owned by snfs, another an error would also be encountered if no key
or a bad key exists in the .ssh directory. You can add the option -vv to
ssh to make it more verbose. You can use the snfsuser script with --import
(after snfsuser --export on a computer where the keys are good) to get the
keys from a secure floppy, etc. The same remarks apply for a user -> user
connection.

Notes:

1. Under RedHat-7.2 Linux, I found it necessary to start amd with the
command (in /etc/rc.d/init.d/amd):
        daemon --user=root $amd -F /etc/amd.conf $AMDOPTS $OPTIONS $MOUNTPTS

2. On laptop computers, to make suspend properly unmount SNFS file systems,
make sure that you set both NET_RESTART and NETFS_RESTART to yes in 
the apmd configuration file (e.g. /etc/sysconfig/apmd). Also add the line

/etc/rc.d/init.d/amd start

after the NFS mount command in /etc/rc.d/init.d/netfs and the lines

sig=-9
/usr/local/bin/sumountall -f
/etc/rc.d/init.d/amd stop

before the NFS unmount loop in netfs. On RedHat-7.2 Linux, I found that
occasional hanging problems on suspend or shutdown can be avoided by
backgrounding the /sbin/fuser command in the netfs NFS unmount loop like this:
		(/sbin/fuser -k -m $sig $remaining >/dev/null; sleep 5)&

3. File locking over NFS won't work nicely. It is possible to have file
locking, but only for the filesystems mounted from one and only one REMOTE 
nfs server. And in this case, status monitoring won't work, thus if the 
REMOTE nfs server reboots, there may be file corruption, and if the local 
client reboots there may be stale locks on the remote NFS server.

If you still need that feature, just add 100021,4 to the program,version 
specifications aasociated with the UdpForward directive in rpc_psrv config 
file. You may need another version number; check your nlockmgr program
versions (with rpcinfo -p).

You may redistribute it and/or modify this file under the terms of the GNU
General Public License (see the file LICENSE).