it-swarm-es.com

¿Cómo se monta sshfs en el arranque?

Usando un cuadro 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 el fstab del escritorio:

sshfs#[email protected]:/mnt/HD_a2/    /mnt/storage    Fuse   comment=sshfs,auto,users,exec,uid=1000,gid=1000,allow_other,reconnect,transform_symlinks,BatchMode=yes,fsname=sshfs#[email protected]/mnt/HD_a2/ 0 0

Puedo confirmar que funciona con mount /mnt/storage. Lo que necesito es algún método para montarlo al inicio, pero después de que se establezca la conexión de red.

12
jldugger

Actualmente, Upstart en Ubuntu no genera eventos de red. En cambio, llama sysvinit tradicional. De forma predeterminada, NetworkManager está instalado y en ejecución; en lugar de emitir eventos de red para advenedizos, contiene un despachador de piezas de ejecución (/etc/NetworkManager/dispatcher.d/) que a su vez simplemente se basa en el despachador de piezas de ejecución de ifupdown (/etc/network/*.d/). En particular, te preocupas por /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 mensaje. Escriba un script, colóquelo en /etc/network/if-up.d/ y hágalo ejecutable. Lo siguiente se descubrió 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; }
8
jldugger

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

3
benjaminc

pstart es el método preferido para emitir scripts o servicios de inicio en Ubuntu ahora, aunque editando /etc/rc.local todavía funciona. Upstart le permite controlar cuándo se ejecuta el servicio, asegurándose de que suceda después de iniciar su conexión de red.

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

3
Dave K

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

1
Brian

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

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

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

    sshfs -o password_stdin -o nonempty [email protected]:/mnt/HD_a2/ /mnt/storage < ~jldugger/.credentials
    
0
Celso Pires