SSHFS
SSHFS on failisüsteemiklient mis lubab SSH protokollile toetudes haakida kaug-kaustu.
Eeldused
Antud artikkel eeldab, et kasutaja teab mis on SSH ning oskab võtmefaili abil kaugühenduda. Lisaks oleks hea teada mis on haakimine. Kurssi viimiseks saab lugeda artikleid OpenSSH: võtmega autentimine ja Mount.
Vajalik tarkvara
Linux
Linuxi all läheb vaja programmi sshfs. Selle paigaldamine Debianil baseeruvates linuxites:
sudo apt update && sudo apt install sshfs && sudo apt clean
Haakimine
Kui kasutaja on kursis SSH ja haakimisega, siis on üle SSH haakimise süntaks vägagi intuitiivne.
sshfs kasutaja@kuhutahanyhenduda.ee:/kaust/mida/yhendan /haakepunkt/kuhu/yhendan
Lahtihaakimiseks
fusermount -u /haakepunkt/kuhu/yhendatud
Probleemid
Katsetamisel esines selline probleem, et haagitud kaust pani hanguma programmid millega üritasin vaadata kausta, kus haakepunkt asus. Hangusid nii Nemo, kui ka terminal. Viimane küll vaid juhul, kui üritasid tab'i kasutades failinime lõpetada. Muudes kaustades sai vabalt liigelda. Selline olukord tekkis, kui sülearvuti oli olnud mõnda aega uneseisundis, aga tegu võis olla ka muude faktoritega. Kõige tõenäolisemalt on hangumise põhjuseks võrguühenduse katkemine[1]. Kui selline olukord tekkis, tapsin "sshfs" nimelise protsessi ja sain seejärel seadme lahti haakida. Protsesside tapmisest loe lähemalt artiklist Signaalid ja kill. Katsed kinnitavad, et probleemiks on võrguühenduse katkemine.
Haakimine käivitamisel[1]
/etc/fstab ja /etc/fuse.conf
Esiteks tuleb lisada /etc/fstab faili kirje:
sshfs#kasutaja@kuhutahanyhenduda.ee:/kaust/mida/yhendan /haakepunkt/kuhu/yhendan fuse comment=sshfs,noauto,users,exec,uid=1000,gid=1000,allow_other,reconnect,transform_symlinks,BatchMode=yes 0 0
Kokkuvõtvalt kasutame sama süntaksit, mida käsurealt haakimisel ainukese vahega, et prefiks "sshfs#" näitab ära failisüsteemi tüübi.
Parameetrid
comment=sshfs
Lihtsalt kommentaar. Seda läheb hiljem skriptis vaja.
users
Lubab failisüsteemi tavakasutajana haakida. Probleemi korral ei pea alati adminn sekkuma.
uid ja gid
Need kaks parameetrit on vajalikud, sest automaatse haakimise puhul ei käivita haakimisprogrammi mitte kasutaja, vaid süsteem. Kasutades neid parameetreid, anname süsteemile teada kes on kausta omanik. Oma uid ja gid saad teada, trükkides terminali "id". Kasuta enda numbreid, mitte näites antud numbreid.
noauto
Keelab failisüsteemi haakimise operatsioonisüsteemi käivumisel, sest võrguühendus pole sel hetkel veel üleval.
BatchMode=yes
Ütleb sshfs protsessile, et ärgu parooli küsigu, sest automaatse haakimise skript seda sisse trükkima ei hakka. Kasuta võtmetega autentimist. Teiseks lubab see parameeter ssh ühenduse jõudeseisundit. Ilma selleta haagitaks kaust lahti, kui seal mõnda aega liiklust ei toimu.
Järgnevaks ava fail /etc/fuse.conf (loo see fail, kui seda ei eksisteeri) ja lisa sinna järgmine rida:
user_allow_other
/etc/fstab haakimise testimine
mount /haakepunkt/kuhu/yhendan
Ja vaata kas kaustale tekib sisu.
Automaatne haakimine
Normaalse kasutamise saavutamiseks on vajalik, et kaust võrguühenduse kadumisel lahti haagitakse, ja võrguühenduse taastumise korral tagasi külge haagitakse.
Arvutis peaksid olema kaustad nimega /etc/network/if-up.d ja /etc/network/if-down.d. Nende sees olevad skriptid käivitatakse vastavalt kas siis kui arvuti võrku ühendub, või võrguühenduse kaotab. Loo administraatoriõigustes kaks faili:
/etc/network/if-up.d/mountsshfs
#!/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
#!/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; }
Siis anna mõlemale failile käivitusõigused ja sea nende omanikuks root:
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
Nüüd peaks kõik ilusasti töötama.
Kokkuvõte
Ehkki esmapilgul tundub SSHFS tööle saamine väga pikk ja keeruline protsess, siis tegelikult oli see üpriski lihtne. Vähemalt senikaua kuni antud automaatse haakimise-lahtihaakimise skriptid töötavad.
Lahendus on elgantne ja kordades mugavam kui pidevalt läbi SFTP ühenduda. Samas selle artikli põhiallikaks olev Ubuntu foorumi postitus väidab, et SSHFS kahjuks suuremahuliste andmete ülekandmiseks, varudamiseks ja muudeks suure koormusega tegevusteks siiski hästi ei sobi, kuna kipub taolistes olukordades ebastabiilseks.
Autorid
Henri Paves, AK21, 2018, v1.0