¿Cómo monte sshfs en el arranque?

12

Usando una caja NAS como servidor de archivos 24/7, me gustaría usar sshfs para conectarme desde un escritorio Ubuntu 9.04. Actualmente, tengo esta línea en la fstab del escritorio:

sshfs#jldugger@storage:/mnt/HD_a2/    /mnt/storage    fuse   comment=sshfs,auto,users,exec,uid=1000,gid=1000,allow_other,reconnect,transform_symlinks,BatchMode=yes,fsname=sshfs#jldugger@storage/mnt/HD_a2/ 0 0

Puedo confirmar que funciona con montaje /mnt/storage. Lo que necesito es algún método para montarlo al inicio, pero una vez establecida la conexión de red.

jldugger
fuente
¿Cómo se configura la autenticación? ¿Se le solicita una contraseña cuando la monta manualmente?
Zoredache
Keypair auth. No es el más seguro, pero probablemente sea suficiente.
jldugger

Respuestas:

8

Actualmente, Upstart en Ubuntu no genera eventos de red. En cambio, se llama sysvinit tradicional. Por defecto, NetworkManager está instalado y ejecutándose; en lugar de emitir eventos de red para iniciar, contiene un despachador de partes de ejecución (/etc/NetworkManager/dispatcher.d/) que en sí mismo simplemente se basa en el despachador de partes de ejecución de ifupdown (/etc/network/*.d/). En particular, le interesan /etc/network/if-up.d/ y /etc/network/if-down.d/

Primero configure un par de claves ssh sin cifrar, para que pueda montar el punto sin un aviso. Escriba un script, colóquelo en /etc/network/if-up.d/ y haga que sea ejecutable. Lo siguiente fue descubierto en UbuntuForums y fue suficiente para mí:

#!/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"
:
                        echo "Not attempting to mount $mp as other user $mp_uid"
                fi
    fi
    # if not an sshfs line, do nothing
done </etc/fstab

wait

Si tiene una conexión wifi o no confiable, coloque lo siguiente en /etc/network/if-down.d/:

#!/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; }
jldugger
fuente
2
Esto funciono muy bien para mi. echoNotaré que cambié los comandos que salían a stdout a logger -t mountsshfscomandos en su lugar para que la salida fuera a syslog.
Mateo
3

Upstart es el método preferido para emitir scripts de inicio o servicios en Ubuntu ahora, aunque la edición /etc/rc.localaún funciona. Upstart le permite controlar cuándo se ejecuta el servicio, asegurándose de que ocurra después de iniciar su conexión de red.

También es posible editar los enlaces simbólicos en /etc/rc.Xd directamente (sustituya X por el nivel de ejecución que está utilizando) y agregue un nombre como S99mount para asegurarse de que se ejecuta después de la configuración de la red. Esto deberá apuntar a un archivo de script que monte los sshfs que está solicitando.

Dave K
fuente
3

_netdev como una opción de montaje debería resolver esto, creo

benjaminc
fuente
Lo sé, ubuntu y centos no son lo mismo ... pero en centos de todos modos, esta es la forma correcta de tener /etc/init.d/netfs manejar montajes sshfs. que se llamará después de que se haya creado la red.
anónimo uno
1

Solo una idea, pero si está usando esto como un servidor de archivos, tal vez NFS o Samba sería una mejor solución que ssh.

Brian
fuente
0

Aquí hay otra solución en caso de que no tenga un certificado de su host remoto y deba usar un nombre de usuario / contraseña. Estoy usando en este ejemplo el mismo nombre de usuario y directorios utilizados por jldugger para evitar agregar confusión.

  1. Cree un archivo que contenga su contraseña en su directorio de inicio y asegúrelo:

    echo 'YourRemoteUserPassword' > ~jldugger/.credentials
    chmod 600 ~jldugger/.credentials
    
  2. Edite su /etc/rc.localarchivo e inserte el siguiente comando en la parte inferior, pero antes de la "salida 0":

    sshfs -o password_stdin -o nonempty jldugger@storage:/mnt/HD_a2/ /mnt/storage < ~jldugger/.credentials
    
Celso Pires
fuente