Bagaimana cara me-mount sshfs saat boot?

12

Menggunakan kotak NAS sebagai server file 24/7, saya ingin menggunakan sshfs untuk menghubungkannya dari desktop Ubuntu 9.04. Saat ini, saya memiliki baris ini di fstab 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

Saya dapat mengkonfirmasi itu berfungsi dengan mount /mnt/storage. Yang saya butuhkan adalah beberapa metode untuk memasangnya saat startup, tetapi setelah koneksi jaringan dibuat.

jldugger
sumber
Bagaimana Anda memiliki pengaturan otentikasi? Apakah Anda dimintai kata sandi saat memasang itu secara manual?
Zoredache
Keypair auth. Bukan yang paling aman, tetapi kemungkinan cukup.
jldugger

Jawaban:

8

Saat ini, pemula di Ubuntu tidak menghasilkan acara jaringan. Sebaliknya itu disebut sysvinit tradisional. Secara default NetworkManager diinstal dan dijalankan; alih-alih memancarkan kejadian jaringan untuk memulai, itu berisi dispatcher run-parts (/etc/NetworkManager/dispatcher.d/) yang dengan sendirinya hanya bergantung pada dispatcher run-parts ifupdown (/etc/network/*.d/). Khususnya Anda peduli tentang /etc/network/if-up.d/ dan /etc/network/if-down.d/

Pertama-tama atur ssh keypair yang tidak terenkripsi, sehingga Anda bisa memasang titik tanpa prompt. Tulis skrip, letakkan di /etc/network/if-up.d/ dan buat eksekusi. Berikut ini ditemukan di UbuntuForums dan cukup bagi saya:

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

Jika Anda memiliki wifi atau koneksi yang tidak dapat diandalkan, letakkan yang berikut ini di /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
sumber
2
Ini bekerja baik untuk saya. Saya akan mencatat bahwa saya mengubah echoperintah yang keluaran ke stdout ke logger -t mountsshfsperintah sebagai gantinya sehingga keluaran akan pergi ke syslog.
Matius
3

Pemula adalah metode yang disukai untuk menerbitkan skrip startup atau layanan di Ubuntu sekarang, meskipun pengeditan /etc/rc.localmasih berfungsi. Pemula memungkinkan Anda untuk mengontrol ketika layanan dijalankan, memastikan itu terjadi setelah memulai koneksi jaringan Anda.

Dimungkinkan juga untuk mengedit symlink di /etc/rc.Xd secara langsung, (gantikan X untuk run-level yang Anda gunakan) dan tambahkan nama seperti S99mount untuk memastikan bahwa symlink berjalan setelah pengaturan jaringan. Ini perlu menunjuk ke file skrip yang me-mount sshfs yang Anda minta.

Dave K.
sumber
3

_netdev sebagai opsi mount harus menyelesaikan ini, saya percaya

benjaminc
sumber
saya tahu, ubuntu dan centos tidak sama ... tetapi bagaimanapun juga centos, ini adalah cara yang benar untuk membuat /etc/init.d/netfs menangani sshfs mounts. yang akan dipanggil setelah jaringan dibesarkan.
anonim-satu
1

Hanya pemikiran, tetapi jika Anda menggunakan ini sebagai file server, mungkin NFS atau Samba akan menjadi solusi yang lebih baik daripada ssh.

Brian
sumber
0

Berikut adalah solusi lain jika Anda tidak memiliki sertifikat dari host jarak jauh dan harus menggunakan login / kata sandi. Saya menggunakan dalam contoh ini nama pengguna dan direktori yang sama yang digunakan oleh jldugger untuk menghindari kebingungan.

  1. Buat file yang berisi kata sandi Anda di direktori home Anda, dan amankan:

    echo 'YourRemoteUserPassword' > ~jldugger/.credentials
    chmod 600 ~jldugger/.credentials
    
  2. Edit /etc/rc.localfile Anda dan masukkan perintah berikut di bagian bawah, tetapi sebelum "keluar 0":

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