#!/usr/bin/perl -w # Originally written by James Strandboge in # the article "Encrypted NFS with OpenSSH and Linux" found here: # http://www.samag.com/documents/s=4072/sam0203d/sam0203d.htm # # Recommended fstab setup: # master.foo.com:/home /mnt/home nfs rw,hard,intr 0 0 # # Read Firewall HOWTO for info on "pinning" RPC daemons to specific portnumbers: # http://nfs.sourceforge.net/nfs-howto/security.html # # TODO: Use getopts and configfile # Figure out a way to automount # Figure out a way to automount through PAM use strict; use File::Basename; ## CONFIGURATION my $nfs_server = "nfs1"; # the nfs server to connect to my $nfs_server_user = "james"; # a valid username on the nfs server my $use_version = "2"; # nfs-user-server uses 2, otherwise 3 # would be better. Check output of # 'rpcinfo -p ' my $nfsd_client_port = "2818"; # we will port forward nfsd here my $mountd_client_port = "3045"; # we will port forward mountd here my $sleep_length = "86400"; # how long to sleep before restarting # 86400 secs is one day. Note # this is overridden if a command is # specified in the server's # authorized_keys2 file # need to keep '-f', can also specify encryption algorithm, the ssh version # and the id key my $ssh_opts = "-f -c blowfish -2 -i /home/james/.ssh/id_dsa_nfs"; my %rpcinfo_col = ( # change as per output of rpcinfo -p 'program' => '0', 'version' => '1', 'protocol' => '2', 'port' => '3', 'daemon' => '4' ); ## END CONFIGURATION # not much should need to change below here my $prog_name = basename($0); my $nfsd_server_port = ""; my $mountd_server_port = ""; # for signals $SIG{INT} = sub { die "$0 interrupted and dying (does not kill ssh)\n" }; my $first_time = 1; while (1) { if ($first_time) { print "$prog_name: Starting ssh/nfs forwarding—\n"; $first_time = 0; } else { print "$prog_name: Restarting ssh/nfs forwarding—\n"; } # first, get the rpcinfo my @rpcinfo = `rpcinfo -p $nfs_server`; print "My rpcinfo =\n @rpcinfo"; # now get the nfsd and mountd port numbers foreach (@rpcinfo) { my @line = split; if ($line[$rpcinfo_col{"version"}] eq $use_version && $line[$rpcinfo_col{"daemon"}] eq "nfs" && $line[$rpcinfo_col{"protocol"}] eq "tcp") { $nfsd_server_port = $line[$rpcinfo_col{"port"}]; print (" nfsd port = $nfsd_server_port"); } elsif ($line[$rpcinfo_col{"version"}] eq $use_version && $line[$rpcinfo_col{"daemon"}] eq "mountd" && $line[$rpcinfo_col{"protocol"}] eq "tcp") { $mountd_server_port = $line[$rpcinfo_col{"port"}]; print (", mountd port = $mountd_server_port\n"); } } # now run ssh (if this fails, we get the error message and # retry). This should run all the time. This also won't die # unless the nfs mount is done. `/usr/bin/ssh $ssh_opts -L \ $nfsd_client_port:$nfs_server:$nfsd_server_port -L \ $mountd_client_port:$nfs_server:$mountd_server_port -l \ $nfs_server_user $nfs_server /bin/sleep $sleep_length`;