Hallo,
wer (wie ich) öfters mal die USB-Platte wechselt, bzw. mehrere an einem Hub wechselnd an- und ausschaltet, dem hilft das mounten der usb-Platten nach uStor## herzlich wenig (weil sich die Zahl ändert, bzw. unterschiedliche Medien die gleiche Zahl erhalten).
Der autorun/autoend Mechanismus ist dagegen so genial, dass er sich leicht verwenden lässt, um Platten zu ihrer UUID zu mounten, auch wenn diese (im Vorfeld) garnicht bekannt ist.
Für die FTP-Benutzer habe ich folgenden Zugriff umgesetzt:
Alle Verzeichnisse der ersten Ebene der Festplatte können individuell erlaubt werden.
Alle FTP-Benutzer haben unter /home ein persönliches Verzeichnis.
Beim Einschalten der Platte werden die Verzeichnisse, für die der Benutzer zugelassen ist unter seinem home-Verzeichnis angelegt und anschließend wird das entsprechende Verzeichnis der FTP-Platte dort eingebunden.
Schreib- und Leseberechtigung können über die Verzeichnisrechte eingestellt werden. Verzeichnisse, die mehreren Benutzern zugeordnet werden sollten das Sticky-Bit erhalten.
In der Benutzer-VW fürs WebIF kann bei einem neuen Benutzer jedes Verzeichnis per Mausklick zugeordnet werden.
Dazu hilft folgende autorun.sh im Wurzelverzeichnis der Platte
In rc.local (auch im Wurzelverzeichnis der Platte) lassen sich jetzt Verzeichnisse ins lokale Filesystem mounten, indem man den übergebenen Pfad verwendet.
Das (für mich) angenehme ist, dass der Mechanismus auch noch nach dem Klonen der Platte (jetzt mit neuer UUID) weiter funktioniert.
Fehlt noch die autoend.sh
Hier (m)eine rc.local:
//update:
rc.local derart geändert, dass Benutzer und deren FTP-Verzeichnisse aus einer separaten Datei eingelesen werden, die auch im Wurzelverzeichnis der einzubindenen Platte liegt.
//2. update:
rc.local wurde um Benutzer-VW erweitert
Die Datei der FTP-Benutzer sieht wie folgt aus (pro Benutzer eine Zeile):
Trennzeichen der Felder einer Zeile ist ';'
Aufbau einer Zeile:
Ok, zumindest in 1.13 wird autoend.sh wohl nicht automatisch beim umount-Befehl ausgeführt, d.h. es fehlt noch ein kleiner Kick. Ich habe mir beholfen, indem ich unter ./root/bin (in der FW-Entwicklungsumgebung) eine Datei "unmount" mit folgendem Inhalt erzeugt habe (selbstverständlich muss diese noch ausführbar gemacht werden):
Damit wird die Platte duch einschalten eingebunden und kann via webIF oder einem "unmount /dev/sda1" wieder freigegeben und anschließend ausgeschaltet werden.
Vielleicht kann's ja der eine oder andere brauchen.
Gruß Gero
wer (wie ich) öfters mal die USB-Platte wechselt, bzw. mehrere an einem Hub wechselnd an- und ausschaltet, dem hilft das mounten der usb-Platten nach uStor## herzlich wenig (weil sich die Zahl ändert, bzw. unterschiedliche Medien die gleiche Zahl erhalten).
Der autorun/autoend Mechanismus ist dagegen so genial, dass er sich leicht verwenden lässt, um Platten zu ihrer UUID zu mounten, auch wenn diese (im Vorfeld) garnicht bekannt ist.
Für die FTP-Benutzer habe ich folgenden Zugriff umgesetzt:
Alle Verzeichnisse der ersten Ebene der Festplatte können individuell erlaubt werden.
Alle FTP-Benutzer haben unter /home ein persönliches Verzeichnis.
Beim Einschalten der Platte werden die Verzeichnisse, für die der Benutzer zugelassen ist unter seinem home-Verzeichnis angelegt und anschließend wird das entsprechende Verzeichnis der FTP-Platte dort eingebunden.
Schreib- und Leseberechtigung können über die Verzeichnisrechte eingestellt werden. Verzeichnisse, die mehreren Benutzern zugeordnet werden sollten das Sticky-Bit erhalten.
In der Benutzer-VW fürs WebIF kann bei einem neuen Benutzer jedes Verzeichnis per Mausklick zugeordnet werden.
Dazu hilft folgende autorun.sh im Wurzelverzeichnis der Platte
Code:
#!/bin/sh
mp=$(dirname $0)
dev=$(mount | grep $mp)
dev=${dev%% *}
tmp=$(/usr/sbin/blkid -s UUID $dev)
tmp=${tmp##*=\"}
tmp=${tmp%%\"*}
logger autorun "dev [$dev] has uuid [$tmp]"
mkdir -p /var/media/$tmp
mount $mp /var/media/$tmp -o bind
[ -x $mp/rc.local ] && source rc.local start /var/media/$tmp
In rc.local (auch im Wurzelverzeichnis der Platte) lassen sich jetzt Verzeichnisse ins lokale Filesystem mounten, indem man den übergebenen Pfad verwendet.
Das (für mich) angenehme ist, dass der Mechanismus auch noch nach dem Klonen der Platte (jetzt mit neuer UUID) weiter funktioniert.
Fehlt noch die autoend.sh
Code:
#!/bin/sh
mp=$(dirname $0)
dev=$(mount | grep $mp)
dev=${dev%% *}
tmp=$(/usr/sbin/blkid -s UUID $dev)
tmp=${tmp##*=\"}
tmp=${tmp%%\"*}
logger autoend "dev [$dev] has uuid [$tmp]"
[ -x $mp/rc.local ] && source rc.local stop /var/media/$tmp
umount /var/media/$tmp
rmdir /var/media/$tmp
Hier (m)eine rc.local:
//update:
rc.local derart geändert, dass Benutzer und deren FTP-Verzeichnisse aus einer separaten Datei eingelesen werden, die auch im Wurzelverzeichnis der einzubindenen Platte liegt.
//2. update:
rc.local wurde um Benutzer-VW erweitert
Code:
#!/bin/sh
myself=$0
mode=$1
base=$2
fusers="$base/ftpusers.local"
verify_user() {
local user=$1
local pentry=$2
local sentry=$3
logger "$myself: verify user [$user]"
grep -l $user /etc/passwd || echo "$pentry" >> /etc/passwd
grep -l $user /etc/shadow || echo "$sentry" >> /etc/shadow
mkdir -p /home/$user 2>/dev/null
chown $user:ftpuser /home/$user
}
attach_dir() {
local user=$1
local dir=$2
mkdir -p /home/$user/$dir
mount $base/$dir /home/$user/$dir -o bind
}
detach_dir() {
local user=$1
local dir=$2
umount /home/$user/$dir
}
processUsers() {
local IFS=';'
cat $fusers | while read user pentry sentry rest; do
[ "x$mode" = "xstart" ] && verify_user $user $pentry $sentry
for dir in $rest; do
if [ "x$mode" = "xstart" ]; then
attach_dir $user $dir
else
detach_dir $user $dir
fi
done
done
}
createUserPage() {
local base=$1
local fusers="$base/ftpusers.local"
local dirlist=$(ls -l $base | grep "^d" | grep -Ev "log|lost|System" | awk '{ print $9; }')
echo -n '<div id="userlist" class="chapter"><div class="title">'
echo -n 'Liste der FTP-Benutzer'
echo -n '</div><br/><br/><table><tr valign="top"><td class="title">'
echo -n 'Benutzer'
echo -n '</td><td class="title">'
echo -n 'Verzeichnisse'
echo -n '</td></tr>'
local IFS=';'
local uid=1001 gid=100
cat $fusers | while read user pentry sentry rest; do
echo -n "<tr valign=\"top\"><td class=\"data\">$user</td><td class=\"data\">"
IFS=':'
set -- $pentry
uid=$3
gid=$4
for dir in $rest; do
echo "$dir<br/>"
done
IFS=';'
echo -n "</td></tr>"
done
unset IFS
let uid="uid+1"
echo -n '<tr><td colspan="2" class="title">'
echo -n 'neuer Benutzer:'
echo -n '</td></tr><tr valign="top"><td><table><tr><td>'
echo -n 'Name:'
echo -n '</td><td><input type="text" name="new_ftp_user" size="20" maxlength="30"/></td></tr><tr><td>'
echo -n 'Kennwort:'
echo -n '</td><td><input type="text" name="new_ftp_pass" size="20" maxlength="30"/></td></tr></table></td><td>'
echo -n '<input type="hidden" name="new_ftp_uid" value="'$uid'"/>'
echo -n '<input type="hidden" name="new_ftp_gid" value="'$gid'"/>'
local n=0
for dir in $dirlist; do
echo "<input type=\"checkbox\" name=\"ftpdir$n\" value=\"$dir\"/>$dir<br/>"
let n="$n+1"
done
echo -n '</td></tr><tr><td> </td><td><input type="submit" value="Anlegen"/></td></tr>'
echo '</table></div>'
}
addUser() {
local ftpuser=$(echo "$FORM_new_ftp_user" | sed 's/\([a-z_0-9]*\).*/\1/')
local ftppass=$(echo "$FORM_new_ftp_pass" | sed 's/\([a-z_0-9]*\).*/\1/')
local ftpuid=$(echo "$FORM_new_ftp_uid" | sed 's/\([0-9]*\).*/\1/')
local ftpgid=$(echo "$FORM_new_ftp_gid" | sed 's/\([0-9]*\).*/\1/')
local allowed=${FORM_new_ftpdirs}
local dirlist=$(ls -l $base | grep "^d" | grep -Ev "log|lost|System" | awk '{ print $9; }')
local ftpdirlist=''
for n in $(seq 0 99); do
if [ ! -z "$FORM_ftpdir$n" ]; then
ftpdirlist="$ftpdirlist $FORM_ftpdir$n"
fi
done
if [ -z $user ] || [ -z $pass ] || [ -z $ftpuid ] || [ -z $ftpgid ]; then return; fi
if [ $ftpuid -lt 1000 ] then let ftpuid="ftpuid+1000"; fi
grep "$ftpgid" /etc/group
if [ $? = 1 ]; then
ftpgid=$(grep users /etc/group)
ftpgid=${ftpgid#users:x:}
ftpgid=${ftpgid%:.*}
fi
local pass=$(mkpasswd -m md5 $ftppass)
local entry="$user"
entry="$entry;$user:x:$ftpuid:$ftpgid:ftp user,,,:/home/$user:/bin/sh"
entry="$entry;$user:$pass:14789:0:99999:7:::"
for dir in $dirlist; do
echo $ftpdirlist | grep $dir && entry="$entry;$dir"
done
echo $entry
}
logger "rc.local: 0[$myself] 1[$mode] 2[$base]"
case $mode in
start)
addgroup -g 139 ftpuser 2>/dev/null
[ -s $fusers -a -r $fusers ] && processUsers
;;
stop)
[ -s $fusers -a -r $fusers ] && processUsers
;;
manage)
createUserPage $(dirname $0)
;;
adduser)
addUser
;;
*) logger error "[$myself]: invalid mode! only start/stop supported, [$mode] given!"
;;
esac
Die Datei der FTP-Benutzer sieht wie folgt aus (pro Benutzer eine Zeile):
Code:
userA;userA:x:1001:139:public ftp user,,,:/home/userA:/bin/sh;userA:$a$very$secret$password:14772:0:99999:7:::;public
Aufbau einer Zeile:
Code:
Benutzer-name
Zeile für den Benutzer in /etc/passwd
Zeile für den Benutzer in /etc/shadow
Verzeichnis-1 [; ... Verzeichnis-n]
Ok, zumindest in 1.13 wird autoend.sh wohl nicht automatisch beim umount-Befehl ausgeführt, d.h. es fehlt noch ein kleiner Kick. Ich habe mir beholfen, indem ich unter ./root/bin (in der FW-Entwicklungsumgebung) eine Datei "unmount" mit folgendem Inhalt erzeugt habe (selbstverständlich muss diese noch ausführbar gemacht werden):
Code:
#!/bin/sh
dev=$1
if [ -z $dev ]; then
echo "need a special device to unmount - typically an usb-drive"
exit 1
elif [ ! -b $dev ] && [ ! -c $dev ]; then
echo "need a special device to unmount - typically an usb-drive"
exit 2
else
chkdev=$(mount | grep $dev | head -n 1 | awk '{ print $1; }')
if [ $dev != $chkdev ]; then
echo "special dev [$dev] not mounted"
exit 3
fi
mp=$(mount | grep $dev | head -n 1 | awk '{ print $3; }')
logger unmount "should umount device [$dev] from [$mp]"
[ -x $mp/autoend.sh ] && $mp/autoend.sh
umount $mp
exit 0
fi
Damit wird die Platte duch einschalten eingebunden und kann via webIF oder einem "unmount /dev/sda1" wieder freigegeben und anschließend ausgeschaltet werden.
Vielleicht kann's ja der eine oder andere brauchen.
Gruß Gero
Zuletzt bearbeitet: