Results 1 to 10 of 139

Thread: SSHFS AUTOmount on Feisty

Threaded View

  1. #1
    Join Date
    Feb 2007
    Beans
    77

    Thumbs up SSHFS AUTOmount on Fesity, Gutsy, Hardy, Intrepid

    HOWTO: Automount sshfs filesystems as soon as the network becomes available.
    Ubuntu Version: Feisty or later


    If you are looking for a way to easily do remote backups or any other sort of mass network transfer, you have come to the wrong place. Sshfs is nice, but it tends to be unreliable under heavy load. You would be much better off looking into rsync or Unison, for example.

    Update: New Features!
    • Asynchronous mounting
      All sshfs mounts will be mounted at the same time, rather than waiting for each one to finish mounting before starting the next.
    • Works better when run as user
      Only attempts to mount your own shares.
    • Specify username rather than uid number
      e.g. uid=yourname. The script now handles both correctly.


    This isn't just a howto on writing fstab lines for sshfs shares. That's part of it, yes, but the idea here is that you want you be able to walk into a cafe somewhere, start up your laptop, connect to the nearest wireless network, and immediately have your sshfs shares available without having to do anything extra beyond connecting to the network.

    This howto looks long, but it really isn't; I'm just providing lots of background information for those that are interested, and for those that are not very familiar with fstab entries. A lot of this howto is a crash course in the salient points of fstab entries. If you already know these, you can skip down to the good stuff in step 3.

    REQUIREMENTS:
    Feisty Fawn! (or later) The versions of fuse in Edgy and earlier releases are incapable of handling sshfs lines in /etc/fstab If you don't want to upgrade to Feisty, another possible solution might be to install the fuse packages provided here. Your mileage may vary.

    Next requirement: Sshfs. Sshfs is the tool used to mount any remote folder that you can access via ssh as a filesystem. To install it,
    Code:
    sudo apt-get install sshfs
    That should also install any other dependencies, including Fuse, if they aren't already installed.

    Finally, and very importantly, you must have set up PASSWORDLESS login to the ssh host that you wish to mount. For details on how to set this up, go here. A non-automatic variation of this howto is possible without passowrdless logins.

    Also, you should already know how to mount your sshfs shares manually. There are plenty of howto's for this on these forums and elsewhere.

    PROCEDURE:
    Before you can automount your shares, you first have to mount them, and you have top set them up in your /etc/fstab so that they can be mounted with a simple command. So,

    STEP 1: Setting up fstab and fuse.conf.
    My source for this section is this page (the same one mentioned above). /etc/fstab is a critical system file, so naturally you will need administrator privileges to edit it:
    Code:
    gksu gedit /etc/fstab
    A typical sshfs fstab entry ready for automounting looks something like this:
    Code:
    # <file system>       <mount point>         <type>  <options>
    sshfs#myname@www.myhome.com:/home/myname    /mnt/sshfs/homebox    fuse    comment=sshfs,noauto,users,exec,uid=1000,gid=1000,allow_other,reconnect,transform_symlinks,BatchMode=yes 0 0
    If you're familiar with fstab entries, the only thing that should look new is the filesystem specification at the beginning of the line. If you're new at this, I'll provide a quick explanation. The first part determines the sshfs share. The syntax is the same as when you are using sshfs on the command line, except that it is prefixed by "sshfs#" to tell the mount program what kind of filesystem this is. (By the way,This kind of syntax probably works for other fuse filesystems as well, but I haven't tried it.) Also, make sure to put your username in, or else the system will not know which user to log in to the remote host as.

    The next part is the mount point. Again, you can simply use the same folder that you always use when you mount the share manually. The next part tells mount that this is a Fuse filesystem.

    The options are also the same options you use when you mount the share manually, with a few additions:
    • comment=sshfs
      This option is just what it says: a comment. We'll see later how the automount script uses this.
    • users
      This option allows anyone to mount this filesystem. Without this, you could only mount the filesystem using sudo. Allowing normal users to mount the share isn't strictly necessary for automatic operation, but it allows you to easily remount the share manually if something goes wrong during the automatic mount. (If you know how to edit the sudoers file, feel free to do that instead of using the "users" option; if you don't know what the sudoers file is, don't worry about it - The "users" option is good enough.)
    • uid and gid
      These two options are required because when the sshfs share is automounted, it won't be you running the mount program; it will be the system, and the system needs to know who the share belongs to. To find out your uid and gid, simply open a terminal and run "id". Use the numbers that it tells you, not the numbers given in the example above.
      noauto
      This tells the system not to mount the filesystem when it first boots. (because the network isn't up yet!)
    • BatchMode=yes
      This tells the sshfs process not to try asking for a password, because the automount script certainly isn't going to provide one. With this option, if you don't have passwordless logins working correctly, you'll know immediately; you won't have to waste time cancelling a password prompt.
      Secondly, this option tells ssh not to allow idle timeouts. Without this, your sshfs mounts will unmount if you don't touch them for a while.


    Next, you should put the following in /etc/fuse.conf (create the file if it doesn't exist):
    Code:
    user_allow_other
    STEP 2: Testing Your Fstab entries
    (If you already know how to do this, then go ahead and do it, then skip to step 3.)
    To see if your fstab entry works, open up a terminal and try to mount it like this (I will continue with the example above):
    Code:
    mount /mnt/sshfs/homebox
    Then see if your sshfs share has been successfully mounted, for example, by:
    Code:
    ls /mnt/sshfs/homebox
    If you see the contents of your remote share, then you're good to go.

    At this point, if you have not set up passwordless ssh logins, then mounting will still work, but you will have to provide your password on each mounting, and step 3 will not work for you.

    STEP 3: Automounting your shares when you connect to the internet
    Ok, now that your computer knows how to mount your shares, it's time to tell it when to mount them. Also, just as importantly, you need to tell your compute when to unmount them as well, because if you lose your network connection and forget to unmount the shares, any program that tries to access them will freeze indefinitely and will need to be killed.

    Accomplishing both of these is actually quite easy. You should have a pair of directories called /etc/network/if-up.d and /etc/network/if-down.d. Scripts in the first directory will be executed when the computer connects to the network, and scripts in the second one will be executes when it disconnects. Again, editing files in these directories requires administrator privileges. Create the following two files:
    /etc/network/if-up.d/mountsshfs
    Code:
    #!/bin/sh
    
    ## http://ubuntuforums.org/showthread.php?t=430312
    ## The script will attempt to mount any fstab entry with an option
    ## "...,comment=$SELECTED_STRING,..."
    ## Use this to select specific sshfs mounts rather than all of them.
    SELECTED_STRING="sshfs"
    
    # Not for loopback
    [ "$IFACE" != "lo" ] || exit 0
    
    ## define a number of useful functions
    
    ## returns true if input contains nothing but the digits 0-9, false otherwise
    ## so realy, more like isa_positive_integer 
    isa_number () {
        ! echo $1 | egrep -q '[^0-9]'
        return $?
    }
    
    ## returns true if the given uid or username is that of the current user
    am_i () {
    	[ "$1" = "`id -u`" ] || [ "$1" = "`id -un`" ]
    }
    
    ## takes a username or uid and finds it in /etc/passwd
    ## echoes the name and returns true on success
    ## echoes nothing and returns false on failure 
    user_from_uid () {
        if isa_number "$1"
        then
    		# look for the corresponding name in /etc/passwd
        	local IFS=":"
        	while read name x uid the_rest
        	do
            	if [ "$1" = "$uid" ]
    			then 
    				echo "$name"
    				return 0
    			fi
        	done </etc/passwd
        else
        	# look for the username in /etc/passwd
        	if grep -q "^${1}:" /etc/passwd
        	then
        		echo "$1"
        		return 0
        	fi
        fi
        # if nothing was found, return false
       	return 1
    }
    
    ## Parses a string of comma-separated fstab options and finds out the 
    ## username/uid assigned within them. 
    ## echoes the found username/uid and returns true if found
    ## echoes "root" and returns false if none found
    uid_from_fs_opts () {
    	local uid=`echo $1 | egrep -o 'uid=[^,]+'`
    	if [ -z "$uid" ]; then
    		# no uid was specified, so default is root
    		echo "root"
    		return 1
    	else
    		# delete the "uid=" at the beginning
    		uid_length=`expr length $uid - 3`
    		uid=`expr substr $uid 5 $uid_length`
    		echo $uid
    		return 0
    	fi
    }
    
    # unmount all shares first
    sh "/etc/network/if-down.d/umountsshfs"
    
    while read fs mp type opts dump pass extra
    do
        # check validity of line
        if [ -z "$pass" -o -n "$extra" -o "`expr substr ${fs}x 1 1`" = "#" ]; 
        then
            # line is invalid or a comment, so skip it
            continue
        
        # check if the line is a selected line
        elif echo $opts | grep -q "comment=$SELECTED_STRING"; then
        	
        	# get the uid of the mount
            mp_uid=`uid_from_fs_opts $opts`
            
            if am_i "$mp_uid"; then
    			# current user owns the mount, so mount it normally
    			{ sh -c "mount $mp" && 
    				echo "$mp mounted as current user (`id -un`)" || 
    				echo "$mp failed to mount as current user (`id -un`)"; 
    			} &
    		elif am_i root; then
    			# running as root, so sudo mount as user
    			if isa_number "$mp_uid"; then
    				# sudo wants a "#" sign icon front of a numeric uid
    				mp_uid="#$mp_uid"
    			fi 
    			{ sudo -u "$mp_uid" sh -c "mount $mp" && 
    				echo "$mp mounted as $mp_uid" || 
    				echo "$mp failed to mount as $mp_uid"; 
    			} &
    		else
    			# otherwise, don't try to mount another user's mount point
    			echo "Not attempting to mount $mp as other user $mp_uid"
    		fi
        fi
        # if not an sshfs line, do nothing
    done </etc/fstab
    
    wait
    /etc/network/if-down.d/umountsshfs
    Code:
    #!/bin/bash
    
    # Not for loopback!
    [ "$IFACE" != "lo" ] || exit 0
    
    # comment this for testing
    exec 1>/dev/null # squelch output for non-interactive
    
    # umount all sshfs mounts
    mounted=`grep 'fuse.sshfs\|sshfs#' /etc/mtab | awk '{ print $2 }'`
    [ -n "$mounted" ] && { for mount in $mounted; do umount -l $mount; done; }
    Now make both files executable and owned by root:
    Code:
    sudo chmod 755 /etc/network/if-up.d/mountsshfs /etc/network/if-down.d/umountsshfs
    sudo chown root:root /etc/network/if-up.d/mountsshfs /etc/network/if-down.d/umountsshfs
    That should be it! If your shares are configured as above, they should now automatically mount and unmount with your network. Try disconnecting and reconnecting.

    ADDITIONAL COMMENTS:
    As an added bonus, since these shares are in fstab, GNOME will automatically create desktop icons for them when they are mounted, so you will have easy access to them.

    Those more familiar with mount might point out that the -a option could be used in these scripts instead of loops and grep, awk, etc. Indeed, my first implementation used this. However, the current form of the scripts allows them to be executed successfully by any user.

    By the way, remember that comment option? Well, that's how the mounting script knows which filesystems to mount.

    The mounting script can also be run manually at any time to remount your shares. There is no need to use sudo. When run as a user, the script will only remount your shares.

    When, your computer boots, it may complain that the fstab lines that you entered are invalid, but nothing should go wrong.

    And lastly, like most of the open source/free software world, this guide comes with no warranty.

    UPDATE

    In Hardy Heron and above, there is a bug in sshfs that prevents non-root unmounting of sshfs. There is a workaround described in https://bugs.launchpad.net/ubuntu/+s...se/+bug/243298 that makes things work for now. You can try the following perl one-liner to automatically apply the workaround to your fstab, but I only guarantee that it worked for me:

    Code:
    sudo perl -lape 's/(sshfs#\S+)(\s+\S+\s+\S+\s+)(.*)/\1\2fsname=\1,\3/' -i /etc/fstab
    Thanks to conchyliferous for bringing this to my attention.
    Last edited by Darwin Award Winner; July 14th, 2010 at 09:21 PM. Reason: Updated Script; Warning when not to use; Hardy update

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •