Come posso montare sshfs all'avvio?


12

Usando una scatola NAS come file server 24/7, mi piacerebbe usare sshfs per connettermi ad esso da un desktop Ubuntu 9.04. Attualmente, ho questa linea nel fstab del desktop:

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

Posso confermare che funziona con mount /mnt/storage. Ciò di cui ho bisogno è un metodo per montarlo all'avvio, ma dopo aver stabilito la connessione di rete.


Come si configura l'autenticazione? Ti viene richiesta una password quando la monti manualmente?
Zoredache,

Autenticazione Keypair Non il più sicuro, ma probabilmente sufficiente.
jldugger,

Risposte:


8

Attualmente, Upstart in Ubuntu non genera eventi di rete. Invece chiama sysvinit tradizionale. Per impostazione predefinita, NetworkManager è installato e in esecuzione; piuttosto che emettere eventi di rete per l'avvio, contiene un dispatcher di parti run (/etc/NetworkManager/dispatcher.d/) che si basa semplicemente sul dispatcher di parti run di ifupdown (/etc/network/*.d/). In particolare ti interessa /etc/network/if-up.d/ e /etc/network/if-down.d/

Innanzitutto imposta una coppia di chiavi ssh non crittografata, in modo da poter montare il punto senza un prompt. Scrivi uno script, inseriscilo in /etc/network/if-up.d/ e rendilo eseguibile. Quanto segue è stato scoperto su UbuntuForums ed è stato sufficiente per me:

#!/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

Se si dispone di una connessione wifi o altrimenti inaffidabile, inserire quanto segue in /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; }

2
Questo ha funzionato alla grande per me. echoNoterò che ho cambiato i comandi che stavano trasmettendo a stdout in logger -t mountsshfscomandi invece che l'output andasse su syslog.
Matteo,

3

Upstart è il metodo preferito per l'emissione di script o servizi di avvio in Ubuntu ora, sebbene l'editing funzioni /etc/rc.localancora. Upstart ti consente di controllare quando viene eseguito il servizio, assicurandoti che accada dopo aver avviato la connessione di rete.

È anche possibile modificare direttamente i collegamenti simbolici in /etc/rc.Xd (sostituire X per il livello di esecuzione che si sta utilizzando) e aggiungere un nome come S99mount per assicurarsi che venga eseguito dopo l'installazione di rete. Questo dovrà puntare a un file di script che monta gli sshfs che stai richiedendo.


3

_netdev come opzione mount dovrebbe risolvere questo, credo


lo so, ubuntu e centos non sono gli stessi ... ma in centos comunque, questo è il modo corretto per far sì che /etc/init.d/netfs gestisca i mount di sshfs. che verrà chiamato dopo che la rete è stata aperta.
anonymous-one

1

Solo un pensiero, ma se lo stai usando come file server, forse NFS o Samba sarebbe una soluzione migliore di ssh.


0

Ecco un'altra soluzione nel caso in cui non si disponga di un certificato dal proprio host remoto e si debba invece utilizzare un login / password. In questo esempio sto usando lo stesso nome utente e le stesse directory utilizzate da jldugger per evitare di aggiungere confusione.

  1. Crea un file contenente la tua password nella tua home directory e proteggila:

    echo 'YourRemoteUserPassword' > ~jldugger/.credentials
    chmod 600 ~jldugger/.credentials
    
  2. Modifica il tuo /etc/rc.localfile e inserisci il seguente comando in fondo, ma prima di "exit 0":

    sshfs -o password_stdin -o nonempty jldugger@storage:/mnt/HD_a2/ /mnt/storage < ~jldugger/.credentials
    
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.