Используя NAS в качестве файлового сервера 24/7, я хотел бы использовать sshfs для подключения к нему с рабочего стола Ubuntu 9.04. В настоящее время у меня есть эта строка в fstab рабочего стола:
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
Я могу подтвердить, что он работает с креплением /mnt/storage
. Что мне нужно, так это какой-то способ установки его при запуске, но после установления сетевого подключения.
В настоящее время Upstart в Ubuntu не генерирует сетевые события. Вместо этого он вызывает традиционный sysvinit. По умолчанию NetworkManager установлен и запущен; вместо того, чтобы отправлять сетевые события для выскочки, он содержит диспетчер частей выполнения (/etc/NetworkManager/dispatcher.d/), который сам просто полагается на диспетчер частей выполнения ifupdown (/etc/network/*.d/). В частности, вы заботитесь о /etc/network/if-up.d/ и /etc/network/if-down.d/
Сначала настройте незашифрованную пару ключей ssh, чтобы вы могли подключить точку без запроса. Напишите сценарий, поместите его в /etc/network/if-up.d/ и сделайте исполняемым. На UbuntuForums было обнаружено следующее, и мне было достаточно:
#!/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
Если у вас есть Wi-Fi или другое ненадежное соединение, поместите следующее в /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; }
_netdev в качестве варианта монтирования должен решить эту проблему, я считаю
Выскочка в настоящее время является предпочтительным методом выпуска сценариев запуска или служб в Ubuntu, хотя редактирование /etc/rc.local
до сих пор работает. Upstart позволяет вам контролировать, когда служба запускается, убедившись, что это происходит после инициации вашего сетевого подключения.
Также возможно редактировать символические ссылки в /etc/rc.X.d напрямую (заменив X на уровень выполнения, который вы используете) и добавить имя, такое как S99mount, чтобы гарантировать его запуск после настройки сети. Это должно будет указать на файл сценария, который монтирует запрашиваемые вами sshfs.
Просто подумайте, но если вы используете это как файловый сервер, возможно, NFS или Samba будут лучшим решением, чем ssh.
Вот еще одно решение на случай, если у вас нет сертификата от удаленного хоста и вместо этого вам нужно использовать логин / пароль. В этом примере я использую то же имя пользователя и каталоги, которые использует jldugger, чтобы избежать путаницы.
Создайте файл, содержащий ваш пароль, в вашем домашнем каталоге и защитите его:
echo 'YourRemoteUserPassword' > ~jldugger/.credentials
chmod 600 ~jldugger/.credentials
Отредактируйте свой /etc/rc.local
файл и вставьте следующую команду внизу, но перед "exit 0":
sshfs -o password_stdin -o nonempty jldugger@storage:/mnt/HD_a2/ /mnt/storage < ~jldugger/.credentials