Benutzer-Werkzeuge

Webseiten-Werkzeuge


 [[anwenderwiki:usr2amp_thoschi]] 

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

anwenderwiki:usr2amp_thoschi [2013/12/10 23:51] (aktuell)
Zeile 1: Zeile 1:
 +{{tag> skripte apache mysql}}
 +
 +====== Einleitung ======
 +
 +Es kann notwendig sein, einzelnen oder mehreren Benutzern zu ermöglichen,​ eine Webseite zu erstellen oder mit einer Datenbank zu arbeiten.
 +
 +Da z.B. bei uns regelmäßig wechselnde Informatik-Kurse mit MySQL arbeiten, könnte man dies natürlich über lokale bzw. separate xAMP-Server realisieren.
 +
 +Das folgende Skript ermöglicht eine Alternative. Es legt für bestimmte Benutzer ein Verzeichnis in dessen Home an und gibt dieses im LAN oder global frei. Gleichzeitig wird für diesen Benutzer ein MySQL-Nutzer eingerichtet und eine Datenbank seines Namens.
 +
 +Man kann eine Nutzerliste sowohl als Textdatei oder ein sophomorix-Projekt übergeben. Daneben ist auch die manuelle Pflege der Benutzer möglich. Falls man mit Liste oder Projekt synchronisiert,​ kann man nur die (zusäzlichen) Nutzer anlegen oder nur die (nicht auf der Liste stehenden) Benutzer löschen. Außerdem ist eine vollständige Synchronisation mit einer Liste möglich.
 +
 +Damit sich diese Liste nicht mit vorhandenen Systembenutzern beißt, kann zum einen ein Präfix vergebene werden, welches diese Nutzer kennzeichnet (standardmäßig ''​lmn_''​),​ zum anderen können im Skript bestimmte Benutzernamen in einem Array für die Bearbeitung ausgeschlossen werden.
 +
 +Neben dem Standard-Betriebsmodus "​lmn",​ der für die Benutzer auf Sophomorix zurückgreift,​ gibt es einen Modus "​sys",​ der mit lokalen Linux-Benutzern arbeitet. Damit ist dieses Skript auch auf externen Servern einsetzbar.
 +
 +Die Benutzer-Webseiten können so eingeschränkt werden, dass sie nur am lokalen Rechner, nur vom LAN oder von beliebigen Rechnern (also bei Erreichbarkeit von außen auch über das Internet) erreichbar sind.
 +
 +<note warning>​Das Skript ist noch Beta und steht hier vor allem als Basis für Rückmeldungen und für den Fall, dass sich jemand Teile der Bash-Befehle herauskopieren mag.</​note>​
 +
 +====== Funktionsweise ======
 +
 +Aufgerufen wird das Skript entweder ohne Parameter (manuelle Bearbeitung der Benutzer) oder mit den Parametern ''​-f <​Dateiname>''​ (Textdatei, jede Zeile ein Nutzer) bzw. ''​-p <​Projekt>''​ (Sophomorix-Projekt). In den beiden letzteren Fällen stehen weitere Menüpunkt für die Synchronisierung zur Verfügung.
 +
 +Zunächst erstellt das Skript die aktuelle Nutzerliste und - falls übergeben - eine Liste der übergebenen Datei bzw. dem Projekt. Diese werden dann verglichen.
 +
 +Das diff wird dann abgearbeitet. Beim Anlegen wird jeweils:
 +* eine conf-Datei für Apache erstellt (mit den gewünschten Berechtigungen)
 +* ein HTML-Verzeichnis im Home der Benutzer erstellt (und mit den passenden Rechten versehen)
 +* ein Datenbankbenutzer (im lmn-Modus mit dem sophomorix-Initialpasswort) erstellt
 +* eine Datenbank mit dem Namen des Benutzers erstellt, für welche der Nutzer alle Rechte besitzt
 +
 +Beim Löschen wird jeweils:
 +* der HTML-Ordner NICHT gelöscht (das kann der Benutzer selbst tun)
 +* der Datenbank-Benutzer gelöscht
 +* die Datenbank auf Nachfrage gesichert und im Anshluss gelöscht. Das Backup wird ggf. im Home des Benutzers (mit Timestamp) gespeichert. Falls das Skript beim Anlegen eines Nutzers Backups findet, können diese sowohl vom Benutzer (z.B. per phpmyadmin) als auch vom Skript (per Auswahlmenü) eingelesen werden.
 +
 +Das Skript versucht, fehlerhafte Eingaben/​leere Liste, etc. abzufangen. Es kann aber sein, dass das nicht überall konsequent genug erfolgt. Bei Fehlern bitte eine Nachricht über die Liste oder im Forum - oder einfach selbst hier korrigieren!
 +
 +====== Quellcode ======
 +
 +<​code>​
 +
 +#!/bin/bash
 +
 +# mode kann "​sys"​ (es wird auf systembenutzer zurückgegriffen) "​lmn"​ (es wird auf linuxmuster-Benutzer/​sophomorix zurückgegriffen)
 +mode="​lmn"​
 +# das unterscheidet die skripterzeugten einträge von sonstigen - nicht leichtfertig ändern (-> Inkonsistenz)
 +prefix="​lmn_"​
 +# zur Sicherheit: Datenbanken/​Benutzer,​ die nicht vom Skript bearbeitet werden
 +exclude=( "​horde5"​ "​nagios3"​ )
 +apachedir="/​etc/​apache2/​conf.d"​
 +htmldir="​HTML"​
 +
 +# lokales netzwerk (bei manueller Änderung von /​etc/​networks muss hier nachgearbeitet werden)
 +localnet="​$(cat /​etc/​networks | grep localnet | sed "​s/​localnet//"​ | tr -d " \t"​)/​16"​
 +
 +# ein paar Fehler abfangen
 +[[ $mode == "​lmn"​ || $mode == "​sys"​ ]] || { echo "Modus nicht korrekt gesetzt - bitte Skript überprüfen!";​ exit 0; }
 +[[ -e $apachedir ]] || { echo "​apache-Dir existiert nicht - bitte Skript überprüfen!";​ exit 0; }
 +[[ "​${apachedir#​${apachedir%?​}}"​ == "/"​ ]] || apachedir+="/"​
 +
 +# grobes Abfangen des Parameters (ist es/​existiert die Datei)
 +if [[ $1 ]]; then
 +  [[ "​$1"​ == "​-f"​ || "​$1"​ == "​-p"​ && "​$mode"​ == "​lmn"​ ]] || { echo "​Fehlerhafte Parameter! Ich akzeptiere -f <​Dateiname>​ $([[ "​$mode"​ == "​lmn"​ ]] && echo "oder -p <​Projektname>"​) - bitte Eingabe prüfen";​ exit 0; }
 +  [[ "​$1"​ == "​-f"​ && ! -f $2 ]] && { echo "Die Datei wurde nicht gefunden - bitte Eingabe prüfen";​ exit 0; }
 +  [[ "​$1"​ == "​-p"​ && ! $2 ]] && { echo "Kein Projektname übergeben - bitte Eingabe prüfen";​ exit 0; }
 +  [[ "​$mode"​ == "​lmn"​ && "​$1"​ == "​-p"​ && "​$(sophomorix-project -i -p $2 | grep -c "not exist"​)"​ == "​1"​ ]] && { echo "Das Projekt existiert nicht - bitte Eingabe prüfen";​ exit 0; }
 +fi
 +
 +# nun definieren wir die Funktionen zum anlegen und löschen
 +create() {
 +
 +  # home bestimmen (je nach system) und anlegen
 +  [[ "​$mode"​ == "​lmn"​ ]] && home=$(sophomorix-user -u $1 | grep "/​home"​ | tr -d " " | cut -d ":"​ -f 2 | cut -d "​("​ -f 1
 +) || home=$(cat /etc/passwd | grep ":​$1:"​ | cut -d ":"​ -f 6)
 +  # wenn kein home - machen wir nicht weiter
 +  if [[ $home ]]; then
 +    [[ ! -d $home/​$htmldir ]] && mkdir $home/​$htmldir
 +    [[ "​$mode"​ == "​sys"​ ]] && chown $usr.$usr $home/​$htmldir
 +    [[ "​$mode"​ == "​lmn"​ ]] && chown $usr.teachers $home/​$htmldir
 +    # unter linuxmuster.net 6 ist www-data die Gruppe für die Lehrer-Homeverzeichnisse
 +    [[ "​$mode"​ == "​lmn"​ && "​$(echo "​$home"​ | cut -d "/"​ -f 3)" == "​teachers"​ ]] && chown $usr.www-data $home/​$htmldir
 +    chmod ugo+rwx $home/​$htmldir;​
 +    # Apache-Dateien anlegen
 +    echo -e "# Durch das Apache-Skript angelegte conf-Datei für den Benutzer $1\n"\
 +            "Alias /$1 $home/​$htmldir\n"​\
 +            "<​Directory $home/​$htmldir>​\n"​\
 +            " ​ Order allow,​deny\n"​\
 +            "$([[ "​$access"​ == "​1" ​ ]] && echo " ​ Allow from all\n"​)"​\
 +            "$([[ "​$access"​ == "​2" ​ ]] && echo " ​ Allow from $localnet\n"​)"​\
 +            "$([[ "​$access"​ == "​3" ​ ]] && echo " ​ Allow from 127\n"​)"​\
 +            " ​ AllowOverride Limit\n"​\
 +            " ​ DirectoryIndex index.html\n"​\
 +            "</​Directory>​\n\n<​IfModule mod_php5.c>"​\
 +            "​\n ​ php_value display_errors on\n</​IfModule>"​ >> /​etc/​apache2/​conf.d/​$prefix$usr.conf
 +
 +    # prüfe, ob nutzer oder db vorhanden
 +    if [[ "​$(mysql -e "SHOW DATABASES"​ | grep -c $1)" == "​0"​ && "​$(mysql -e "​SELECT user FROM mysql.user"​ | grep -c $1)" == "​0"​ ]]; then
 +      # hole erstpasswort aus sophomorix oder frage nach
 +      [[ "​$mode"​ == "​lmn"​ ]] && pass=$(sophomorix-user -u $1 -v | grep Pass | sed "​s/​$1.//"​ | tr -d " " | cut -d ":"​ -f 2) || pass=$(whiptail --inputbox "​Passwort eingeben: " 10 40 ""​ --title "​MySQL-Passwort"​ 3>&1 1>&2 2>&​3)
 +      # lege benutzer/db an
 +      mysql -e "​CREATE DATABASE $1;"
 +      mysql -e "​CREATE USER '​$1'​@'​localhost'​ IDENTIFIED BY '​$pass';"​
 +      mysql -e "GRANT ALL ON $1.* TO '​$1'​@'​localhost';"​
 +
 +      # zurückspielen von backups
 +      sqlmenu=(); for i in $(find $home -name "​$1*.sql"​ -printf "​%f\n"​);​ do sqlmenu=( "​${sqlmenu[@]}"​ "​$i"​ "​einlesen"​ ); done
 +      if [[ "​${#​sqlmenu[@]}"​ != "​0"​ ]]; then
 +        sqlfile=$(whiptail --title "​SQL-Restore"​ --menu "​Welche Datei soll wiederhergestellt werden?"​ $(tput lines) $(tput cols) $(expr $(tput lines) - 8) "​${sqlmenu[@]}"​ 3>&1 1>&2 2>&​3)
 +        [[ $sqlfile ]] && mysql $1 < $home/​$sqlfile
 +      fi
 +    else
 +      whiptail --title "​Hinweis"​ --msgbox "​Datenbank oder Benutzer $1 bereits vorhanden. Datenbank wird nicht angelegt!" ​ 10 40
 +    fi
 +  else
 +    whiptail --title "​Hinweis"​ --msgbox "Der Benutzer $1 hat keine Heimat. Abbruch!" ​ 10 40
 +  fi
 +}
 +
 +delete() {
 +  # löschen der apache-conf
 +  rm $apachedir$prefix$1.conf
 +  # löschen des HTML-Verzeichnisses,​ wenn leer (!)
 +  [[ "​$mode"​ == "​lmn"​ ]] && home=$(sophomorix-user -u $1 | grep "/​home"​ | tr -d " " | cut -d ":"​ -f 2 | cut -d "​("​ -f 1
 +) || home=$(cat /etc/passwd | grep ":​$1:"​ | cut -d ":"​ -f 6)
 +  [[ "$(ls -A $home/​$htmldir)"​ ]] || rmdir $home/​$htmldir
 +
 +  # prüfe, ob nutzer oder db vorhanden
 +  if [[ "​$(mysql -e "SHOW DATABASES"​ | grep -c $1)" == "​0"​ || "​$(mysql -e "​SELECT user FROM mysql.user"​ | grep -c $1)" == "​0"​ ]]; then
 +    whiptail --title "​Hinweis"​ --msgbox "​Datenbank oder Benutzer $1 nicht vorhanden. Es kann nichts gelöscht werden!" ​ 10 40
 +  else
 +    # löschen von DB und user (wenn etwas in der Datenbank, dump ins user-home)
 +    [[ "​$(mysql $1 -e "SHOW TABLES"​)"​ ]] && mysqldump $1 > $home/​${1}_$(date +%Y%m%d_%H%M).sql
 +    mysql -e "DROP DATABASE $1;"
 +    mysql -e "DROP USER '​$1'​@'​localhost';"​
 +    ​
 +  fi
 +}
 +
 +menu=( "​1"​ "Neuen Benutzer anlegen"​ \
 +       "​2"​ "Einen Benutzer loeschen"​ \
 +       "​3"​ "ALLE Benutzer loeschen"​ )
 +
 +[[ $1 ]] && { type=$([[ "​$1"​ == "​-f"​ ]] && echo "​Datei"​ || echo "​Projekt"​);​
 +              menu=( "​${menu[@]}"​ \
 +                     "​4"​ "​Nutzer nach $type anlegen"​ \
 +                     "​5"​ "​Nutzer nach $type löschen"​ \
 +                     "​6"​ "​Nutzer komplett mit $type synchronisieren"​ ); }
 +menu=( "​${menu[@]}"​ "​0"​ "​Ende"​ )
 +
 +while choice=$(whiptail --backtitle "$([[ $1 ]] && echo "$type übergeben: $2" || echo "keine Daten übergeben"​)"​ --title "Alles kleine Apachen"​ --menu "Was tun wir heute:"​ $(tput lines) $(tput cols) $(expr $(tput lines) - 8) "​${menu[@]}"​ 3>&1 1>&2 2>&​3);​ do
 +
 +  # Einlesen der aktuellen Liste und ggf. der übergebenen Datei (prefix und .conf werden enfernt - hier nur Nuternamen!
 +  conf_cur=( $(find $apachedir -name "​$prefix*.conf"​ -printf "​%f\n"​ | sed -e "​s/​$prefix//;​s/​.conf//"​) )
 +  [[ "​$1"​ == "​-f"​ ]] && conf_new=( $(cat $2) )
 +  [[ "​$1"​ == "​-p"​ ]] && conf_new=( $(sophomorix-project -p $2 -u | tail -n +6 | head -n -3 | cut -d '​|'​ -f 2) )
 +
 +  # filtern um ausgeschlossene Elemente
 +  for ((i=0;​i<​${#​conf_cur[@]};​i++));​ do for usr in ${exclude[@]};​ do
 +    [[ "​${conf_cur[$i]}"​ == "​$usr"​ ]] && unset conf_cur[$i]
 +    [[ $1 && "​${conf_new[$i]}"​ == "​$usr"​ ]] && unset conf_new[$i]
 +  done; done
 +
 +  case $choice in
 +    "​0"​)
 +      # Apache neu starten
 +      echo "​Apache neu starten";​ /​etc/​init.d/​apache2 restart > /dev/null
 +      exit 0
 +    ;;
 +    "​1"​)
 +      usr=$(whiptail --inputbox "​Benutzername:​ " 10 40 ""​ --title "​Benutzer anlegen"​ 3>&1 1>&2 2>&​3)
 +      exitstatus=$?;​ if [ $exitstatus = 0 ]; then
 +        # prüfen ob auf Sperrliste
 +        doit=1
 +        for testusr in ${exclude[@]};​ do
 +          [[ "​$testusr"​ == "​$usr"​ ]] && whiptail --title "​FEHLER"​ --msgbox "​Benutzername $usr ist gesperrt."​ 8 78 3>&1 1>&2 2>&3 && doit=0
 +        done
 +
 +        # prüfen ob schon vorhanden
 +        for testusr in ${conf_cur[@]};​ do
 +          [[ "​$testusr"​ == "​$usr"​ ]] && whiptail --title "​FEHLER"​ --msgbox "​Benutzername $usr existiert bereits."​ 8 78 3>&1 1>&2 2>&3 && doit=0
 +        done
 +        # welches Netz ist erlaubt
 +        if [[ "​$doit"​ == "​1"​ ]]; then
 +          access=$(whiptail --title "​Berechtigungen"​ --menu "Aus welchem Netz darf auf das Home zugegriffen werden?"​ $(tput lines) $(tput cols) $(expr $(tput lines) - 8) "​1"​ "​all"​ "​2"​ "LAN ($localnet)"​ "​3"​ "local (127.0.0.1)"​ 3>&1 1>&2 2>&​3)
 +          [[ $access ]] && create $usr
 +        fi
 +      fi
 +      ;;
 +    "​2"​)
 +      menu2=(); for i in "​${conf_cur[@]}";​ do menu2=( "​${menu2[@]}"​ "​$(echo $i | sed "​s/"​.conf"//"​)"​ "​loeschen"​ ); done
 +      if [[ "​${#​menu2[@]}"​ != "​0"​ ]]; then 
 +        usr=$(whiptail --title "​Nutzerliste"​ --menu "Wen loeschen wir heute:"​ $(tput lines) $(tput cols) $(expr $(tput lines) - 8) "​${menu2[@]}"​ 3>&1 1>&2 2>&​3)
 +        if [[ $usr ]]; then
 +          whiptail --title "​Warnung"​ --yesno "$usr wird geloescht\n\nSICHER?"​ 10 40
 +          exitstatus=$?;​ [[ $exitstatus = 0 ]] && delete $usr
 +        fi
 +         else
 +        whiptail --title "​Hinweis"​ --msgbox "Es gibt keine Einträge mit Prefix $prefix."​ 10 40
 +      fi
 +      ;;
 +    "​3"​)
 +      if [[ "​${#​conf_cur[@]}"​ != 0 ]]; then 
 +        whiptail --title "​Warnung"​ --yesno "ALLE Benutzer ($(echo ${conf_cur[@]})) werden geloescht\n\nSICHER?"​ 10 40
 +        exitstatus=$?; ​ [[ $exitstatus = 0 ]] && for i in "​${conf_cur[@]}";​ do delete $i; done
 +      else
 +        whiptail --title "​Hinweis"​ --msgbox "Es gibt keine Einträge mit Prefix $prefix."​ 10 40
 +      fi
 +      ;;
 +    *)
 +      # diff besti mmen
 +      diff_cre=( ); diff_crn=( ); diff_del=( ); diff_den=( )
 +      if [[ "​$choice"​ == "​4"​ || "​$choice"​ == "​6"​ ]]; then
 +        for usr in ${conf_new[@]};​ do 
 +          doit=1; for usrtest in ${conf_cur[@]};​ do [[ "​$usr"​ == "​$usrtest"​ ]] && doit=0; done
 +          [[ "​$doit"​ == "​1"​ ]] && diff_cre=( ${diff_cre[@]} $usr ) || diff_crn=( ${diff_crn[@]} $usr )
 +        done
 +      fi
 +      if [[ "​$choice"​ == "​5"​ || "​$choice"​ == "​6"​ ]]; then
 +        for usr in ${conf_cur[@]};​ do 
 +          doit=1; for usrtest in ${conf_new[@]};​ do [[ "​$usr"​ == "​$usrtest"​ ]] && doit=0; done
 +          [[ "​$doit"​ == "​1"​ ]] && diff_del=( ${diff_del[@]} $usr ) || diff_den=( ${diff_den[@]} $usr )
 +        done
 +      fi
 +      [[ "​$choice"​ == "​4"​ ]] && { whiptail --title "​Warnung"​ --yesno " Ich lege an: ${diff_cre[@]}\n$([[ "​${#​diff_crn[@]}"​ != "​0"​ ]] && echo "Ich ignoriere: ${diff_crn[@]} (ist vorhanden)"​)\n\nSICHER?"​ 10 40; exitstatus=$?;​ }
 +      [[ "​$choice"​ == "​5"​ ]] && { whiptail --title "​Warnung"​ --yesno " Ich lösche: ​ ${diff_del[@]}\n$([[ "​${#​diff_den[@]}"​ != "​0"​ ]] && echo "Ich ignoriere: ${diff_den[@]} (steht in Liste)"​)\n\nSICHER?"​ 10 40; exitstatus=$?;​ }
 +      [[ "​$choice"​ == "​6"​ ]] && { whiptail --title "​Warnung"​ --yesno " Ich lege an: ${diff_cre[@]}\nIch lösche: ${diff_del[@]}\n\nSICHER?"​ 10 40; exitstatus=$?;​ }
 +      if [[ $exitstatus = 0 ]]; then
 +        [[ "​$choice"​ == "​4"​ || "​$choice"​ == "​6"​ ]] && for i in "​${diff_cre[@]}";​ do create $i; done
 +        [[ "​$choice"​ == "​5"​ || "​$choice"​ == "​6"​ ]] && for i in "​${diff_del[@]}";​ do delete $i; done
 +      fi
 +      ;;
 +  esac
 +done
 +
 +</​code>​
  
 [[anwenderwiki:usr2amp_thoschi]] anwenderwiki/usr2amp_thoschi.txt · Zuletzt geändert: 2013/12/10 23:51 (Externe Bearbeitung)