Dokumentation des Schulservers
Letzte
Änderung:
Copyright © 2001, 2002, 2003, 2004 Andreas Dangel <adabolo@adabolo.de>
Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in the section entitled "GNU Free Documentation License".
Inhaltsverzeichnis
Kapitel 1. Allgemeines zum Netzwerk 2
1.1. Topologie 2
1.2. Technik 2
1.3. Eingesetzte Hardware 2
1.4. IP-Adressen 2
Kapitel 2. Installation des Servers 3
2.1. Debian installieren 3
2.1.1. Debian besorgen 3
2.1.2. Installation starten 3
2.1.3. Partitionierung 3
2.1.4. Weiterer Verlauf 3
2.2. Kernel machen 4
2.3. Software-RAID 6
2.3.1. Voraussetzungen 7
2.3.2. Schritt für Schritt-Anleitung 7
2.3.3. Fehlerfall 13
2.4. APC SmartUPS (USV) 13
2.4.1. Zweck 13
2.4.2. Möglichkeiten ohne Treiber 13
2.4.3. Installation des Treibers 14
2.4.4. Anzeigetools 16
2.5. Netzwerkkarten konfigurieren 16
2.6. T-DSL einrichten 18
2.6.1. Logdatei 19
2.7. PPP-Filter 20
2.8. apt-get konfigurieren 20
2.8.1. apt-get verwenden 21
Kapitel 3. Dienste 22
3.1. Grundlegende Dienste 22
3.1.1. DNS-Server 22
3.1.2. dhcp-Server 24
3.1.3. Mail Transfer Agent (SMTP/UUCP) 25
3.1.3.1. uucp einrichten 25
3.1.3.2. exim (MTA) einrichten 28
3.1.3.3. Regelmäßig Mails abholen 29
3.2. Fernwartung 30
3.2.1. SSH-Server 30
3.2.2. dyndns 31
3.3. Dienste für Clients 32
3.3.1. Webserver 32
3.3.2. pop3-Server 35
3.3.3. Proxy und Filter 35
3.3.3.1. squid 35
3.3.3.2. squidGuard 36
3.3.4. Drucker 39
3.3.5. Samba 40
3.3.5.1. Logdateien 44
3.3.5.2. Tägliches Neustarten 45
3.4. Sicherheit 46
3.4.1. Firewall 46
3.4.2. inetd 47
3.4.3. netstat und nmap 47
3.4.3.1. netstat 47
3.4.3.2. nmap 48
3.4.4. Backup 49
3.4.5. sudoers 50
3.5. Zusätzliches 51
3.5.1. Homepage hochladen 51
3.5.2. Quota 52
3.5.3. ntpdate 53
3.5.4. Transparenter Proxy 53
3.5.5. SMART 54
Kapitel 4. Verwaltung und Wartung 56
4.1. Benutzerverwaltung 56
4.1.1. Benutzer 56
4.1.2. Gruppen 57
4.2. Benutzermanager 57
4.2.1. Benutzer löschen 57
4.2.2. Passwort ändern 58
4.2.3. Rechte eines Benutzers ändern 58
4.2.4. Benutzer sperren bzw. freigeben 59
4.2.5. Neuer Benutzer erstellen 59
4.2.6. Informationen über die Benutzer sammeln 60
4.3. proxymanager 61
4.3.1. Logdatei 63
4.4. Info-Tools 63
4.4.1. Festplattenplatz 63
4.4.2. uptime 63
4.5. Weitere CGI-Scripte 63
4.5.1. Passwort ändern 64
4.5.2. Mail-Weiterleitung konfigurieren 64
4.5.3. Benutzerverzeichnisse 64
Kapitel 5. Clients 65
5.1. Windows 98SE 65
5.1.1. Zusammenarbeit mit dem Netzwerk und Samba 65
5.1.1.1. Netzwerk 65
5.1.1.2. Computer-Name 65
5.1.1.3. Netz-Logon 67
5.1.2. Netzwerkinstallation von best. Programmen 68
5.1.3. Partitionsmanager 68
5.1.4. Windows beschränken 70
Kapitel 6. Linux-Grundlagen 74
6.1. Einloggen/Ausloggen 74
6.2. Linux herunterfahren (shutdown) 74
6.3. Dateiverwaltung 74
6.3.1. Dateien auflisten 74
6.3.2. Datei/Verzeichnis erstellen 76
6.3.3. Verzeichnis wechseln 76
6.3.4. Datei/Verzeichnis löschen 76
6.3.5. Dateien kopieren 76
6.3.6. Dateien verschieben 76
6.3.7. Textdateien anzeigen 76
6.4. Benutzerverwaltung 77
6.4.1. Benutzer erstellen 77
6.4.2. Benutzer bearbeiten 77
6.4.3. Benutzer löschen 77
6.4.4. Gruppe erstellen 77
6.4.5. Gruppe löschen 77
6.5. Paketverwaltung 78
6.6. Editor 78
6.6.1. Datei öffnen bzw. neue Datei erstellen 78
6.6.2. Dateien bearbeiten und speichern 78
6.7. Prozessmanagement 78
6.8. Linux Support 78
Kapitel 7. Anhang 80
7.1. Firewall-Script 80
7.2. proxy-manager 85
7.2.1. squid-redirector 93
7.2.2. internet/index.cgi 94
7.2.3. inactive.cgi 98
7.3. mail-config/index.cgi 98
7.3.1. Hilfsprogramm change-aliases 100
7.4. passwd/index.cgi 101
7.5. admin/adduser.cgi 104
7.5.1. make_mozilla_config.pl 109
7.6. generate-apache-auth 110
7.7. homepage/mirror.cgi 111
7.7.1. homepage/index.html 112
7.7.2. Hilfsprogramm mirror-hp.sh 113
7.8. usermanager3.cgi 113
7.8.1. Hilfsprogramm user-status3 136
7.9. benutzer 138
7.10. netzstatus.cgi 139
7.10.1. Hilfsprogramm ping.pl 140
7.11. smbstatus.cgi 141
7.12. samba-logger.cgi 141
Kapitel 8. GNU Free Documentation License 147
8.1. English (original) version 147
8.2. Inoffizielle deutsche Übersetzung 155
Vorwort
Diese Dokumentation beschreibt den Aufbau des Netzwerkes am Gymnasium Münsingen. Der Schwerpunkt liegt beim Linux-Server. Um die Dokumentation umsetzen zu können, sind Erfahrungen mit Linux notwendig. Möglicherweise hilft auch das sehr, sehr knapp gehaltene Kapitel über Linux-Grundlagen weiter.
Sternförmig
Technik: Ethernet
Hub in R104; Netzdrucker in R104; Weitere Rechner in: R23 (Lehrerarbeitsraum), Sekretariat, R24 (mit Beamer), Biologie-, Physik- und Chemie-Sammlung; Weitere lokale (nicht im Netz verfügbare) Drucker; ...
Netzwerk |
192.168.0.0 |
Netzmaske |
255.255.255.0 (kurz: /24) |
Broadcast |
192.168.0.255 |
Server-IP |
192.168.0.1 |
Netzdrucker R104 |
192.168.0.254 |
Oki-Page Netzwerkdrucker R023 |
192.168.0.139 |
Farblaserdrucker Minolta R023 |
192.168.0.138 |
Servername |
server |
Domain |
gm.rt.schule-bw.de |
Auf dem Server soll Debian 3.0 ("Woody") installiert werden. Die Debian-Linux-Distribution wird komplett unter der GNU GPL 2 entwickelt. Daher lassen sich auch die CDs ganz legal aus dem Internet herunterladen. Wo und wie das geht, steht auf http://www.debian.de. Insgesamt müssen 7 CDs heruntergeladen werden.
Um die Installation zu starten, muss von der ersten CD gebootet werden. Im Bootmenü der CD bf24 eingeben und die Eingabetaste drücken. So wird der 2.4-Kernel gebootet. Dieser wird benötigt, damit wir das neue ReiserFS-Dateisystem verwenden können.
Debian wird auf die erste Festplatte installiert. Diese muss allerdings noch partitioniert werden. Es wird von einer 80 GB großen Festplatte ausgegangen. Auf dieser werden drei primäre Partitionen benötigt:
/dev/hda1: die root-Partition (/); ca. 70 GB; Dateisystem: ReiserFS
/dev/hda2: die var-Partition (/var); ca. 10 GB; Dateisystem: ReiserFS; hier liegen verschiedene Daten, z.B. Emails.
/dev/hda3: die swap-Partition; ca. 500 MB
Einfach den Anweisungen am Bildschirm folgen. Spezielle Module (= Treiber) brauchen nicht installiert werden. lilo kann in den MBR der ersten Festplatte installiert werden. Nach einem Neustart geht die Installation weiter. Wir verwenden keine MD5 verschlüsselte Passwörter, da wir die Benutzerdatenbank des alten Servers weiterverwenden wollen. Danach kommt die Frage nach dem root-Passwort; dieses Passwort unbedingt sehr gut merken. Einen normalen Benutzer legen wir nicht an. Die Programme tasksel und dselect verwenden wir nicht. Wir installieren die Programme, die benötigt werden, bei Bedarf. So haben wir eine minimalste Software-Auswahl und keine unnötige Programme. Wenn die Konfiguration des Mail-Servers exim kommt, die Option 5 wählen: Wir konfigurieren den Mail-Server später.
Nachdem die Installation vorüber ist, installieren wir zunächst noch einige wichtige Programme: less, vim, bzip2 und aptitude. less dient zum Anzeigen von Dateien, vim ist ein einfacher Editor, mit bzip2 lassen sich Dateien komprimieren und aptitude ist ein einfach zu bedienendes Installationsprogramm für die Debian-Pakete. Die Installation dieser Pakete funktioniert als root mit apt-get install less vim bzip2 aptitude.
Um als root bei der Ausgabe von ls Farben zu erhalten, muss die Datei /root/.bashrc geändert werden. Es müssen lediglich die Kommentar-Zeichen vor einigen Zeilen entfernt werden, sodass die Datei ungefähr so aussieht:
#
#
/root/.bashrc
#
[...]
# You may uncomment the
following lines if you want 'ls' to be
# colorized:
export
LS_OPTIONS='--color=auto'
eval `dircolors`
alias ls='ls
$LS_OPTIONS'
alias ll='ls $LS_OPTIONS -l'
alias l='ls
$LS_OPTIONS -lA'
[...]
Hier wird beschrieben, wie ein Kernel aus den Quellcodes gemacht wird. Dazu werden mehrere Schritte benötigt.
Zunächst einmal muss dafür gesorgt werden, dass
die benötigten Programme und Bibliotheken installiert sind. Wenn der
Kernel zum ersten Mal nach der Installation von Debian gemacht wird,
sind noch folgende Programme nachzuinstallieren: binutils,
cpp, g++,
gcc, make,
patch, libncurses5-dev.
Das geht mit folgendem Befehl in einem Rutsch (als root):
bash# apt-get install binutils
cpp g++ gcc make patch libncurses5-dev
Jetzt muss der Kernel noch besorgt werden. Den aktuellen Quellcode gibt's unter http://www.kernel.org. Die Datei heißt z.B. linux-2.4.21.tar.bz2 und ist ca. 30 MB groß.
Um den Hardware-Sensor (Temperaturanzeige)
anzusteuern, werden noch extra Treiber benötigt. Der Kernel muss
gepatcht werden. Die dafür notwendigen Dateien sind unter http://secure.netroedge.com/~lm78/
zu finden. Es werden zwei Dateien benötigt. Sie heißen etwa i2c-2.8.0.tar.gz und lm_sensors-2.8.0.tar.gz.
Außerdem wird ein Patch benötigt, damit Quota unter dem
ReiserFS-Dateisystem funktioniert. Mit Quota lässt sich die
Festplattenbenutzung pro Benutzer begrenzen. Patches für aktuelle
Kernel sind unter ftp://ftp.suse.com/pub/people/mason/patches/data-logging/
zu finden. Im Verzeichnis 2.4.21/ sind
verschiedene Patches für den Kernel der Version 2.4.21 vorhanden. Für
Quota werden nur 07-quota-v2-2.4.21.diff.gz, 08-reiserfs-quota-28.diff.gz und 09-kinoded-8.diff.gz benötigt. Näheres steht in
der README-Datei.
Nachdem jetzt alle benötigten Quellcodes
zusammen sind, muss der Kernel zuerst mal entpackt werden. Das
geschieht am besten in einem Unterverzeichnis im Homeverzeichnis von root (/root/kernel/) mit
diesen Befehlen:
bash# cd /root
bash# mkdir kernel
bash# cd kernel
bash# tar xfjv /root/linux-2.4.21.tar.bz2
Dabei wird angenommen, dass alle Dateien, die heruntergeladen wurden,
sich im Homeverzeichnis von root (/root/) befinden.
Nun kommen die Patches für den Hardware-Sensor dran. Folgende Schritte
sind auszuführen, um die Treiber zu entpacken und den Kernel
anschließend zu patchen:
bash# cd /root/kernel
bash# tar xfzv /root/i2c-2.8.0.tar.gz
bash# cd i2c-2.8.0
bash# mkpatch/mkpatch.pl . ../linux > ../i2c-patch
bash# cd ../linux
bash# patch -p1 -E < ../i2c-patch
bash# cd /root/kernel
bash# tar xfzv /root/lm_sensors-2.8.0.tar.gz
bash# cd lm_sensors-2.8.0
bash# mkpatch/mkpatch.pl . ../linux > ../lm_sensors-patch
bash# cd ../linux
bash# patch -p1 -E < ../lm_sensors-patch
Jetzt muss noch der ReiserFS-Quota-Patch verwendet werden. Das geht mit
folgenden Befehlen:
bash# cd /root/kernel/linux
bash# zcat /root/07-quota-v2-2.4.21.diff.gz | patch -p1
bash# zcat /root/08-reiserfs-quota-28.diff.gz | patch -p1
bash# zcat /root/09-kinoded-8.diff.gz | patch -p1
Jetzt kann der Kernel endlich konfiguriert
werden. Das Konfigurationsprogramm wird mit make
menuconfig im Verzeichnis /root/kernel/linux/
gestartet.
Bei der Konfiguration muss sichergestellt werden, dass unter
„Multi-device support (RAID and LVM)“ „RAID-1 (mirroring) mode“ fest in
den Kernel eingebunden wird. Für Software-RAID siehe auch 2.3. Software-RAID.
Wichtig ist außerdem auch noch, dass unter „File systems“ das
ReiserFS-Dateisystem fest eingebunden wird. Die Treiber für die
Netzwerkkarten werden als Module ausgewählt: Unter „Network device
support“, „Ethernet (10 or 100Mbit)“ die Karten „EtherExpressPro/100
support (e100...“ und unter „3COM cards“ „3c590/3c900 series...“
auswählen.
Nach der Konfiguration kann der Kernel mit den Modulen compiliert werden. Einfach make dep bzImage modules modules_install eingeben.
Der neue Kernel muss jetzt noch installiert werden. Mit cp /root/kernel/linux/arch/i386/boot/bzImage /boot/vmlinuz-2.4.21 das Kernel-Image an die richtige Stelle kopieren. Danach muss /etc/lilo.conf bearbeitet werden: Die erste Zeile, die mit "image=" anfängt, muss in "image=/boot/vmlinuz-2.4.21" abgeändert werden. Danach mit lilo lilo neu installieren und den Computer anschließend neu starten.
Nach dem Neustart können mit modconf die erstellten Module so konfiguriert werden, dass sie beim nächsten Neustart automatisch geladen werden. Wichtige Module sind hier die Module für den Hardware-Sensor (i2c-isa, w83..d), die Netzwerkkarten (e100, 3c59x) und das Modul für APM (Advanced Power Management; apm). Damit die Treiber für den Hardware-Sensor einen Sinn ergeben, wird noch das Paket lm-sensors benötigt. Es wird mit apt-get install lm-sensors installiert. Wenn die Treiber geladen sind, kann mit sensors die aktuelle Temperatur angezeigt werden.
Software-RAID dient zur besseren Sicherheit der Daten auf dem Server. RAID kann in verschiedenen Modi betrieben werden. Der Modus, der weiter unten eingerichtet wird, heißt RAID-1. Dabei befinden sich im Server zwei Festplatten annähernd gleicher Kapazität. Der Software-RAID-Treiber von Linux sorgt dann dafür, dass sich auf beiden Festplatten exakt der gleiche Inhalt befindet. Die Festplatten werden sozusagen gespiegelt. Fällt eine Festplatte aus, so ist die andere immer noch voll funktionsfähig.
Die Anleitung weiter unten beschreibt, wie ein vorhandenes Linux-System nachträglich in ein RAID-1-System umgewandelt werden kann. Bei modernen Linux-Distributionen kann man möglicherweise schon bei der Installation Software-RAID einrichten; dann kann dieser Abschnitt komplett übersprungen werden.
Um Software-RAID einzurichten, werden zunächst einmal die raidtools in der Version 0.9 oder höher benötigt; ob die raidtools bereits installiert sind, lässt sich mit mkraid -V herausfinden. Das passende Debian-Packet zum Nachinstallieren heißt raidtools2. Dann muss sehr wahrscheinlich noch ein neuer Kernel der Version 2.4.x gemacht werden; dieser Vorgang ist genauer in 2.2. Kernel machen beschrieben.
Natürlich werden auch zwei Festplatten benötigt, die ungefähr die gleiche Größe haben sollten. Diese sind - sofern IDE-Festplatten - idealerweise jeweils als Master angeschlossen und als /dev/hda und /dev/hdc ansprechbar.
Die Ausgangssituation ist folgende: Auf der ersten Festplatte (/dev/hda) ist bereits ein Linux-System installiert. Dabei ist es nicht wichtig, dass es konfiguriert ist, denn das lässt sich später noch genau so gut konfigurieren. Es ist sogar eher noch besser, wenn Software-RAID vor der eigentlichen Konfiguration des Systems eingerichtet wird. Die Anleitung bezieht sich auf die Linux-Installation, die weiter oben beschrieben ist.
Alle folgenden Schritte werden als Superuser (root) durchgeführt.
Zuerst muss ein frischer Kernel gemacht werden.
Dabei sind folgende Einstellungen zu machen:
"Multi-device support (RAID and LVM)"
[y] Multiple devices driver support (RAID and LVM)
[y] RAID support
[y] RAID-1 (mirroring) mode
Wichtig ist hier, dass der RAID-Treiber fest im Kernel ist und keine
Module erstellt werden.
Eine genaue Anleitung für die Erstellung und Installation des neuen
Kernels ist in 2.2. Kernel
machen beschrieben.
Jetzt muss der neue Kernel getestet werden, d.h. es muss mit dem neuen Kernel gebootet werden. Wenn alles soweit funktioniert hat, kann mit dem nächsten Schritt weitergemacht werden. Übrigens: Der Kernel kann auch später nochmal aktualisiert werden; spezielle Hardware kann also später eingerichtet werden.
Nach dem Neustart kann mit cat
/proc/mdstat überprüft werden, ob der neue Kernel auch
tatsächlich RAID unterstützt. Dabei sollte in der ersten Zeile
folgendes erscheinen:
Personalities : [raid1]
Als nächstes muss die zweite Festplatte so wie
die erste Festplatte partitioniert werden. Dabei dürfen die Partitionen
auf der zweiten Festplatte auf keinen Fall größer sein als die
Partitionen auf der ersten Festplatte. Sie müssen entweder gleich groß
oder kleiner sein.
Die Partitionierung kann z.B. mit dem Programm cfdisk vorgenommen
werden. Am besten speichert man die Partitionstabelle der ersten
Festplatte mit cfdisk -P t /dev/hda >
hda-table in die Datei hda-table. Das
sieht dann so aus:
Partition Table for /dev/hda
Wichtig sind die zwei letzten Spalten (Start Sector und
Number of Sectors). Mit cfdisk /dev/hdc
wird die zweite Festplatte partitioniert; es müssen genau die gleichen
Partitionen erstellt werden. Das geht am einfachsten über die
Sektor-Anzahl. Wenn das Programm nach der Größe fragt, einfach 12345S eingeben, also die Anzahl der Sektoren mit
angehängtem S. Zum Schluss müssen die
Partitionstabellen der beiden Festplatten nocheinmal verglichen werden,
damit auch kein Fehler unterlief; also: Partitionstabelle der zweiten
Festplatte wie oben in eine Datei speichern.
---Starting--- ----Ending---- Start Number of
# Flags Head Sect Cyl ID Head Sect Cyl Sector Sectors
-- ----- ---- ---- ---- ---- ---- ---- ---- --------- ---------
1 0x80 1 1 0 0x83 15 63 1023 63 135742257
2 0x00 15 63 1023 0x83 15 63 1023 135742320 19531008
3 0x00 15 63 1023 0x82 15 63 1023 155273328 1028160
4 0x00 0 0 0 0x00 0 0 0 0 0
Hier sollte dann auch auf der zweiten Festplatte gleich das Bootflag
gesetzt werden (auf /dev/hdc1). Außerdem
müssen alle Partitionen außer der swap-Partition den Partitionstyp fd (Linux raid autodetect)
haben.
Jetzt muss die Konfigurationsdatei für den
Software-RAID-Treiber geschrieben werden. Diese steht in /etc/raidtab. Im Moment ist dabei die erste
Festplatte (/dev/hda) als fehlerhaft zu
markieren.
#
# /etc/raidtab
#
# /dev/md0 ist die root-Partition
raiddev /dev/md0
raid-level 1 # RAID-1 (mirroring)
nr-raid-disks 2
nr-spare-disks 0
persistent-superblock 1
chunk-size 32
device /dev/hdc1
raid-disk 0
# dies ist die erste Festplatte, die hier zunächst als fehlerhaft
# markiert ist
device /dev/hda1
failed-disk 1
# /dev/md1 ist die var-Partition
raiddev /dev/md1
raid-level 1 # RAID-1 (mirroring)
nr-raid-disks 2
nr-spare-disks 0
persistent-superblock 1
chunk-size 32
device /dev/hdc2
raid-disk 0
# die erste Festplatte ist hier genauso als fehlerhaft markiert
device /dev/hda2
failed-disk 1
Danach können die raid-Geräte gemacht werden:
bash# mkraid /dev/md0
bash# mkraid /dev/md1
Mit cat /proc/mdstat kann nachgeschaut
werden, ob die Geräte registriert sind. Die erste Festplatte ist hier
als fehlerhaft eingetragen.
Anschließend können die raid-Geräte formatiert
und gemountet werden. Da die erste Festplatte ja als fehlerhaft
markiert ist, wird sie nicht formatiert, sondern nur die zweite
Festplatte. Die Daten auf der ersten Festplatte bleiben also vorhanden.
Das Formatieren funktioniert so:
bash# mkreiserfs /dev/md0
bash# mkreiserfs /dev/md1
Für das Mounten der Dateisysteme müssen folgende Befehle ausgeführt
werden:
bash# mount /dev/md0 /mnt
bash# mkdir /mnt/var
bash# mount /dev/md1 /mnt/var
Jetzt können die Dateien der ersten Festplatte
auf die zweite Festplatte kopiert werden. Das geht ganz einfach mit
folgenden Befehlen:
bash# cd /
bash# find . -xdev -name "*" -o -name ".*" | cpio -pmv /mnt
bash# cd /var
bash# find . -xdev -name "*" -o -name ".*" | cpio -pmv /mnt/var
Danach muss wieder getestet werden. Wir
aktualisieren dafür zuerst folgende Datei:
#
# /mnt/etc/fstab
#
/dev/md0 / reiserfs defaults 0 0
/dev/md1 /var reiserfs defaults 0 0
[...]
Wir ersetzen also /dev/hda1 mit /dev/md0 und /dev/hda2
mit /dev/md1.
Beim nächsten Start mit dem neu eingerichteten RAID werden so die
raid-Geräte automatisch verwendet.
Nun muss noch eine Bootdiskette erstellt werden.
Dazu wird eine leere, formatierte und fehlerfreie Diskette benötigt.
Die Diskette in Laufwerk A: einlegen und folgende Befehle ausführen:
bash# dd if=/boot/vmlinuz-2.4.21 of=/dev/fd0
bs=18k
Auf der so erstellten Bootdiskette ist der neue Kernel mit
Software-RAID-Unterstützung (/boot/vmlinuz-2.4.21
ist das Kernel-Image). Diese Bootdiskette kann später vielleicht mal
sehr wichtig werden, z.B. wenn der Server aus irgendeinem Grund nicht
mehr von der Festplatte booten kann. Deshalb sollte die Bootdiskette
gut aufbewahrt werden und bei jedem Kernel-Update auch aktualisiert
werden.
bash# rdev /dev/fd0 /dev/md0
bash# rdev -r /dev/fd0 0
bash# rdev -R /dev/fd0 1
Jetzt kann der Server neu gestartet werden. Dazu
müssen aber erst die raid-Geräte gestoppt werden:
bash# umount /mnt/var
Wenn die Bootdiskette eingelegt wurde, kann mit shutdown -r
now der Server neu gestartet werden.
bash# umount /mnt
bash# raidstop /dev/md0
bash# raidstop /dev/md1
Nach dem Neustart muss geprüft werden, ob alle Daten auf die zweite Festplatte kopiert wurden. Wenn der Server ohne Probleme neugestartet ist, sollte dies der Fall sein. Wenn nicht, kann der Server immer noch ohne Diskette von der ersten Festplatte gestartet werden. Dann müssen wie in Punkt 7 beschrieben die raid-Geräte wieder gemountet werden, damit eventuell vergessene Dateien kopiert werden können.
Wir haben von der Diskette gebootet. Jetzt muss
die erste Festplatte, die im Moment ja noch als fehlerhaft markiert
ist, dem raid-Array hinzugefügt werden. Dabei gehen alle Daten auf
dieser Festplatte verloren!
Als erstes müssen mit cfdisk /dev/hda die
Partitionstypen der Partitionen auf der ersten Festplatte zu fd (Linux raid autodetect)
geändert werden (die swap-Partition
bleibt swap). Auch das Bootflag sollte nochmal frisch auf /dev/hda1 gesetzt werden.
Dann muss in der Datei /etc/raidtab zweimal failed-disk durch raid-disk
ersetzt werden.
Und schließlich wird mit folgenden Befehlen die erste Festplatte dem
raid-Array hinzugefügt:
bash# raidhotadd /dev/md1 /dev/hda2
bash# raidhotadd /dev/md0 /dev/hda1
Mit cat /proc/mdstat kann der Fortschritt
der Synchronisation angezeigt werden.
Während der Synchronisationsvorgang noch läuft,
kann das System schon bootfähig gemacht werden. Dazu muss /etc/lilo.conf editiert werden. Die Datei sieht
dann so aus:
#
# /etc/lilo.conf
#
boot=/dev/md0
raid-extra-boot=/dev/hda,/dev/hdc
read-only
prompt
timeout=50
root=/dev/md0
image=/boot/vmlinuz-2.4.21
label=Linux
Jetzt muss noch lilo auf beiden Festplatten installiert werden. Dies
geschieht einfach durch Aufruf von lilo.
Schließlich muss noch die swap-Partition auf der
zweiten Festplatte eingerichtet werden. Dazu muss /etc/fstab
verändert werden:
#
# /etc/fstab
#
[...]
/dev/hda3 none swap sw,pri=1 0 0
/dev/hdc3 none swap sw,pri=1 0 0
Außerdem muss die swap-Partition noch mit mkswap
/dev/hdc3 formatiert werden. Beim nächsten Neustart sind dann
beide swap-Partitionen aktiviert.
Wenn der Synchronisationsvorgang beendet ist,
kann neu gestartet werden, um die Installation zu testen.
Falls das Booten von der Festplatte nicht funktioniert, kann immer noch
auf die Bootdiskette zurückgegriffen werden.
Fällt einmal tatsächlich eine Festplatte aus, muss diese ersetzt werden. Im Folgenden wird angenommen, dass die erste Festplatte (/dev/hda) ausfällt. Die einzelnen Schritte sind dann wie folgt:
Erst muss der Server heruntergefahren werden, wenn er noch läuft.
Dann kann die defekte Festplatte ausgetauscht werden.
Jetzt muss gebootet werden. Wenn der Server nicht automatisch von der zweiten (intakten) Festplatte bootet, muss eine Bootdiskette verwendet werden (siehe voriger Abschnitt, Punkt 10).
Die neue Festplatte muss nun partitioniert werden. Die swap-Partition nicht vergessen: Mit mkswap /dev/hda3 die swap-Partition formatieren.
Mit dem Befehl raidhotadd den
Synchronisationsvorgang starten:
bash# raidhotadd /dev/md1 /dev/hda2
bash# raidhotadd /dev/md0 /dev/hda1
Mit lilo lilo neu installieren.
Nach dem Synchronisationsvorgang kann von der Festplatte neu gebootet werden.
Hinweis: Falls das BIOS nicht von der zweiten Festplatte booten kann, wird unbedingt eine Bootdiskette benötigt.
Eine USV (Unterbrechungsfreie Stromversorgung) soll, wie der Name schon sagt, die Stromversorgung sicherstellen. Dabei kann man sich die USV als einen sehr großen Akku vorstellen. Fällt der Strom aus, dann wird der Server weiterhin mit Strom versorgt – aus dem Akku. Außerdem schützt die USV den Server vor Überspannung.
Wenn die USV einfach so, ohne Treiber an den Server angeschlossen wird, dann springt sie automatisch ein, wenn der Strom ausfällt. Wenn der Akku leer ist, fällt der Strom komplett aus; der Server wird nicht heruntergefahren! Die USV ohne Treiber ist also nur für kurze Stromausfälle geeignet.
Wenn der Treiber installiert ist, meldet die USV den Stromausfall. Dann kann der Server entsprechend reagieren. Reagiert er nicht, dann fährt die USV den Server herunter, sobald die Akkuladung einen kritischen Wert erreicht hat. Der Server kann aber auch reagieren und z.B. nach 60 Sekunden herunterfahren. Dadurch kann verhindert werden, dass der Akku beim möglicherweise etwas langen Herunterfahren versagt.
Die USV wird über die erste serielle Schnittstelle (COM1) an den Server angeschlossen. Zur Installation des Treibers wird das Programmpaket nut benötigt. Die Version, die bei Debian Woody (Stable) dabei ist, ist offenbar zu alt und funktioniert nicht richtig. Deshalb verwenden wir eine neuere Version. Unter http://www.logic.at/debian/i386/ gibt es neuere Versionen für Woody. Hier die Dateien nut_1.4.2-2woody1_i386.deb und nut-cgi_1.4.2-2woody1_i386.deb (o.ä. je nach Versionsnummer) herunterladen. Diese Dateien lassen sich mit dpkg -i *.deb installieren. Dann ist die neue Version installiert.
Konfiguriert wird der Treiber über mehrere Dateien. In /etc/nut/ups.conf müss zunächst folgende Zeilen hinzugefügt werden:
[myups]
driver = apcsmart
port = /dev/ttyS0
cable
= 940-0095B
Danach muss mit chown root.nut /dev/ttyS0 dem Treiber den Zugriff auf die COM1-Schnittstelle erlaubt werden. Dann muss /etc/nut/upsd.conf bearbeitet werden: Die Zeile mit "#ACCESS grant master localhost [<upsmon-password>]" suchen und ändern in:
ACCESS grant master
localhost passwort
Damit wird dem Monitorprogramm erlaubt, den Treiber zu befragen. Dabei wird das Passwort "passwort" verwendet. Der Treiber und das Monitorprogramm müssen aber auf demselben Rechner laufen, sodass das Passwort nicht so sicherheitsrelevant ist.
In der Datei /etc/nut/upsmon.conf muss im ersten Abschnitt noch folgende Zeile ergänzt werden:
MONITOR myups@localhost 1
username passwort master
In /etc/nut/upsd.users wird noch ein Benutzer definiert:
[username]
password =
passwort
allowfrom = localhost
upsmon master
Damit ist die einfache Konfiguration abgeschlossen. Mit /etc/init.d/nut start wird der Treiber geladen.
Damit der Server nach einer bestimmten Zeit nach dem Stromausfall automatisch herunterfährt, ist weitere Arbeit nötig. In der Datei /etc/nut/upsmon.conf müssen in den entsprechenden Abschnitten folgende Zeilen hinzugefügt werden:
NOTIFYCMD /sbin/upssched
NOTIFYFLAG ONLINE
SYSLOG+EXEC
NOTIFYFLAG ONBATT
SYSLOG+WALL+EXEC
Wenn der Strom ausfällt (ONBATT) oder wieder da ist (ONLINE) wird das Programm /sbin/upssched ausgeführt. Jetzt muss die Datei /etc/nut/upssched.conf mit folgendem Inhalt erstellt werden:
#
#
/etc/nut/upssched.conf
#
CMDSCRIPT
/usr/local/sbin/go-down
PIPEFN /var/run/upssched.pipe
AT ONBATT
* START-TIMER onbattwarn 40
AT ONLINE * CANCEL-TIMER onbattwarn
Mit dieser Konfiguration wird bei Stromausfall (ONBATT) ein 40-Sekunden-Timer gestartet, der nach Ablauf das Script /usr/local/sbin/go-down ausführt. Wird die Stromversorgung vor Ablauf des Timers wiederhergestellt (ONLINE), wird der Timer abgebrochen.
Das Script /usr/local/sbin/go-down sieht so aus:
#!/bin/sh
#
#
/usr/local/sbin/go-down
#
upsmon -c fsd
Die Zugriffsrechte für dieses Script werden mit chmod 700 /usr/local/sbin/go-down richtig gesetzt. Mit /etc/init.d/nut restart wird die neue Konfiguration verwendet. Damit sit die Konfiguration komplett abgeschlossen.
Jetzt sollte die USV noch getestet werden. Wird das Stromkabel an der USV herausgezogen, sollte in /var/log/syslog eine Meldung erscheinen. Nach 40 Sekunden sollte der Server herunterfahren.
Die Anzeigetools sind CGI-Programme für einen Webserver. Sie können also erst richtig genutzt werden, wenn ein Webserver läuft. Trotzdem können sie auch schon jetzt eingerichtet werden.
Mit apt-get install nut-cgi werden die Programme installiert. Zur Konfiguration muss zunächst die Datei /etc/nut/hosts.conf erstellt werden:
#
#
/etc/nut/hosts.conf
#
MONITOR myups@localhost "Local UPS"
Weiter muss die Datei /etc/nut/upsset.conf erstellt werden. Diese Datei ist nötig, um dem upsset.cgi-Programm mitzuteilen, dass die CGI-Programme auf dem Webserver gesichert sind und nur vom internen Netzwerk zu erreichen sind. Das muss bei der späteren Konfiguration des Webserver beachtet werden! Die Datei hat folgenden Inhalt:
#
#
/etc/nut/upsset.conf
#
I_HAVE_SECURED_MY_CGI_DIRECTORY
Die CGI-Scripte liegen in /usr/lib/cgi-bin/nut/ und sollten, wenn der Webserver konfiguriert ist, in ein entsprechendes cgi-bin-Verzeichnis kopiert werden.
Im Server sind zwei Netzwerkkarten. Eine für das Netzwerk und die andere für den DSL-Anschluss. Damit die Netzwerkkarten konfiguriert werden können, müssen zunächst einmal die Treiber geladen sein. Der Befehl ifconfig -a gibt Aufschluss über die installierten Netzwerk-Geräte:
bash# ifconfig -a
eth0 Link
encap:Ethernet HWaddr 00:10:DC:CD:61:59
BROADCAST
MULTICAST MTU:1500 Metric:1
[...]
eth1 Link
encap:Ethernet HWaddr 00:50:DA:90:8E:A9
BROADCAST
MULTICAST MTU:1500 Metric:1
[...]
lo Link
encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
UP LOOPBACK RUNNING MTU:16436 Metric:1
[...]
Hier sind also zwei Ethernet-Netzwerkkarten (eth0 und eth1) und ein loopback-Gerät installiert (lo). eth0 ist die Netzwerkkarte onboard, also die mit dem Treiber e100. Dieser Treiber wurde vor dem der zweiten Netzwerkkarte eth1 geladen (3c59x).
Zur Konfiguration: Die Einstellungen wie IP-Adresse stehen in der Datei /etc/network/interfaces. Diese muss so aussehen:
#
#
/etc/network/interfaces
#
auto lo
iface lo inet
loopback
auto eth0
iface eth0 inet static
address 192.168.0.1
netmask 255.255.255.0
network 192.168.0.0
broadcast 192.168.0.255
auto
eth1
iface eth1 inet static
address 192.168.22.1
netmask 255.255.255.0
network 192.168.22.0
broadcast 192.168.22.255
Der Server erhält also die IP-Adresse 192.168.0.1. Die zweite Netzwerkkarte (eth1) wird mit einer fiktiven IP-Adresse konfiguriert, die nie wirklich benutzt wird. Sie ist vielmehr ein Platzhalter. Über diese zweite Netzwerkkarte läuft später der DSL-Verkehr.
Um die Konfiguration zu übernehmen muss noch der Befehl /etc/init.d/networking restart ausgeführt werden. Beim nächsten Neustart wird die Konfiguration automatisch übernommen.
Zunächst muss das DSL-Modem mit der zweiten Netzwerkkarte verbunden werden. Die zweite Netzwerkkarte ist bereits wie oben beschrieben konfiguriert (IP-Adresse: 192.168.22.1). Um den DSL-Anschluss zu konfigurieren, werden drei Pakete benötigt, die mit apt-get install pppoe pppoeconf pppstatus installiert werden.
Eine weitere Voraussetzung für den DSL-Zugang sind bestimmte Treiber, die als Kernel-Module geladen werden können. Es wird auf jeden Fall das Modul ppp_async benötigt. Das Modul pppoe wird nicht benötigt; die Aufgabe dieses Treibers wird von der DSL-Software übernommen.
Nach der Installation der Software-Pakete startet automatisch das Programm pppoeconf; falls nicht, muss es manuell gestartet werden: einfach pppoeconf eingeben. Im ersten Dialog sollten beide Netzwerkkarten (eth0 und eth1) zu sehen sein. Das Programm sucht dann an beiden Netzwerkkarten automatisch nach einem DSL-Modem. Einfach den Schritten auf dem Bildschirm folgen.
Der Benutzername für die DSL-Einwahl wird aus den Daten von T-Online aufgebaut:
Anschlusskennung: 0001111111111
T-Online-Nummer: 22222222222
Mitbenutzer-Suffix: 0001
Daraus ergibt sich der Benutzername: 0001111111111222222222220001@t-online.de. Dann wird natürlich noch das Passwort benötigt. Die Frage, ob /etc/resolv.conf beim Verbindungsaufbau mit DNS-Servern vom Provider gefüllt werden soll, ist mit nein zu beantworten. Wir verwenden später unseren eigenen DNS-Server. Nach einigen weiteren Fragen, die wie empfohlen beantwortet werden sollten, ist die Konfiguration abgeschlossen.
Mit dem Programm pppstatus kann der Status der DSL-Verbindung abgefragt werden. Mit pon dsl-provider wird eine Verbindung aufgebaut, mit poff wieder abgebaut.
Um "dial on demand" einzurichten, also die Einwahl bei Bedarf, muss die Datei /etc/ppp/peers/dsl-provider bearbeitet werden. In "Section 2" müssen folgende zwei Zeilen stehen:
demand
idle 120
Dann wird die Verbindung bei Bedarf aufgebaut und wenn 120 Sekunden lang keine Daten gesendet oder empfangen werden, wird die Verbindung getrennt.
Damit der ppp-Dämon bei Systemstart geladen wird und somit die Internetverbindung verfügbar ist, muss im Verzeichnis /etc/ppp/ mit dem Befehl ln -s ppp_on_boot.dsl ppp_on_boot ein symbolischer Link erstellt werden. Außerdem sollte in der Datei /etc/ppp/ppp_on_boot.dsl die Variable INTERFACE mit eth1 belegt sein; dies ist gegebenenfalls anzupassen.
Soll mitgeloggt werden, wann der Server online geht und wann wieder offline, muss in /etc/ppp/ip-up.d/ und /etc/ppp/ip-down.d/ jeweils ein Script installiert werden. Das erste Script heißt /etc/ppp/ip-up.d/log und muss mit folgendem Inhalt erstellt werden:
#!/bin/sh
#
#
/etc/ppp/ip-up.d/log
#
logfile="/var/log/dsl-einwahl"
date=`date`
echo
$date up >> $logfile
Das zweite Script heißt /etc/ppp/ip-down.d/log und muss mit folgendem Inhalt erstellt werden:
#!/bin/sh
#
#
/etc/ppp/ip-down.d/log
#
logfile="/var/log/dsl-einwahl"
date=`date`
echo
$date down >> $logfile
Beide Scripte werden mit chmod 755 /etc/ppp/ip-*.d/log ausführbar gemacht. In der Datei /var/log/dsl-einwahl steht dann, wann sich der Server entweder eingewählt oder ausgewählt hat.
Damit die Logdatei nicht ins Unendliche anwächst, kann noch logrotate konfiguriert werden. Dafür wird die Datei /etc/logrotate.d/dsl-einwahl mit folgendem Inhalt erstellt:
/var/log/dsl-einwahl {
rotate 7
weekly
compress
missingok
notifempty
}
Jetzt wird jede Woche die Logdatei "rotiert", d.h. die Datei wird umbenannt und komprimiert. Es werden maximal 7 Dateien behalten, also man kann die DSL-Einwahl 7 Wochen zurückverfolgen.
Der Internet-Zugang ist oben so konfiguriert worden, dass sich der Server automatisch (bei Bedarf) einwählt und wenn 120 Sekunden lang keine Daten mehr gesendet oder empfangen wurden, beendet er die Verbindung wieder. Das Problem dabei sind heute die sogenannten Peer-to-Peer-Tauschbörsen wie eDonkey. So kommen relativ oft unerwünschte Pakete über den T-Online-Zugang am Server an. Sie stellen zwar kein Sicherheitsrisiko dar, zählen aber trotzdem zum Traffic. Linux registriert, dass Daten empfangen wurden und beendet die Verbindung nicht. Um dieses Szenario zu verhindern, muss Linux so eingerichtet werden, dass es nur noch ausgehende Datenpakete zählt. Da aber die Pakete trotzdem empfangen werden, reagiert Linux normalerweise mit einer Fehlerpaket als Antwort; dies muss später noch mit einer Firewall verhindert werden.
Um den Filter einzurichten, muss am Ende der Datei /etc/ppp/options folgende Zeile hinzugefügt werden:
active-filter 'outbound'
Mit dem Befehl /etc/init.d/ppp restart wird diese Konfiguration übernommen.
Hinweis: Dabei wird eine bestehende Internetverbindung getrennt.
Das Programm apt-get wird immer benutzt, wenn neue Software installiert werden soll. Da wir über eine DSL-Verbindung ins Internet verfügen, kann apt-get so eingerichtet werden, dass es die neue Software automatisch aus dem Internet lädt. Somit entfällt das lästige CD-Einlegen. Außerdem lässt sich so das Debian-System einfach aktuell halten.
Zunächst löschen wir die alte Konfiguration: rm /etc/apt/sources.list. Dann rufen wird das Setup-Programm auf: apt-setup. Hier wählen wir bei der ersten Frage http aus. Die nächste Frage beantworten wir mit No (wir wollen keine Software verwenden, die nicht frei ist). Im nächsten Dialog wählen wir den Mirror-Server aus: Germany, ftp.de.debian.org. Die nächste Frage kann vorerst unbeantwortet bleiben. Wir verwenden im Moment noch keinen Proxy-Server. Später, wenn der Proxy-Server eingerichtet ist, sollte apt-setup nochmal aufgerufen werden und als Proxy-Server sollte http://localhost:3128 eingegeben werden. Danach wollen wir keine weiteren Quellen mehr hinzufügen (No). Die letzte Frage bezieht sich auf Sicherheitsupdates. Sie sollte unbedingt mit Yes beantwortet werden.
Ein weiteres, sehr nützliches Programm ist aptitude. Mit diesem Programm kann man herausfinden, welche Software-Pakete zur Verfügung stehen und welche Software upgedatet werden kann. Falls es noch nicht installiert ist, kann dies mit apt-get install aptitude nachgeholt werden.
Mit apt-get update werden die Paketlisten neu heruntergeladen. Mit apt-get upgrade werden alle auf dem System installierten Pakete auf die aktuelle Version gebracht. (Davor sollte immer apt-get update aufgerufen werden.) Mit apt-get install paketname wird das Programmpaket mit dem Namen "paketname" heruntergeladen und installiert. Mit apt-get remove paketname wird ein Programmpaket wieder entfernt (deinstalliert). Mit apt-get check wird überprüft, ob sich irgendwelche Unstimmigkeiten in den Paketen finden, z.B. Abhängigkeitsprobleme. Diese können dann wahrscheinlich mit apt-get -f install behoben werden.
Der Domain-Name-Service (dns) ist für die Umwandlung von Internetadressen (z.B. www.debian.org) in numerische IP-Adressen (198.186.203.20) zuständig. Auch die umgekehrte Richtung ist möglich. Ohne diesen Dienst müsste man immer die IP-Adresse des Servers kennen, auf den man z.B. beim Surfen zugreifen will. Zusätzlich zur IP-Adresse kann der dns-Server auch den Mailserver, der für eine Domain zuständig ist, speichern (sog. MX-Record). Weitere Infos wie Hardware-Ausstattung sind auch möglich, aber eher unüblich. Jede Domain ist in mindestens zwei dns-Servern eingetragen. Welche das sind, kann mit dem Programm whois herausgefunden werden.
Der gebräuchlichste dns-Server für Linux heißt bind. Mit apt-get install bind9 wird Version 9 installiert. Der Server selber wird mit der Datei /etc/bind/named.conf konfiguriert. Im options-Abschnitt müssen folgende Zeilen hinzugefügt werden:
options {
forwarders {
217.237.151.161;
194.25.2.129;
};
allow-query {
127.0.0.0/8;
192.168.0.0/24;
};
allow-transfer {
none;
};
listen-on {
127.0.0.1;
192.168.0.1;
};
};
Damit ist der dns-Server nur vom internen Netzwerk erreichbar. Schließlich ist er auch nur für das interne Netzwerk zuständig. Am Ende von /etc/bind/named.conf müssen noch folgende Zeilen hinzugefügt werden:
zone "gm.rt.schule-bw.de"
IN {
type master;
file
"gm.rt.schule-bw.de-zone";
};
zone
"0.168.192.in-addr.arpa" IN {
type master;
file "192.168.0-zone";
};
Jetzt müssen noch die sogenannten Zonen-Dateien erstellt werden. In diesen Dateien liegen die eigentlichen Informationen, die der dns-Server zur Umandlung von Domains in IP-Adressen benötigt. Zuerst erstellen wir die Datei /var/cache/bin/gm.rt.schule-bw.de-zone:
;
;
/var/cache/bind/gm.rt.schule-bw.de-zone
;
$TTL 2D
@ IN SOA dns root.gm.rt.schule-bw.de. (
2003081201 ; serial JJJJMMTTNN
8H ; refresh rate
2H ; retry rate
1W ; expiration date
2D
) ; minimum ttl
IN NS dns
IN MX 10 mail
dns IN A 192.168.0.1
mail IN A 192.168.0.1
pop IN A 192.168.0.1
news IN A 192.168.0.1
server IN A 192.168.0.1
proxy IN A 192.168.0.1
www IN NS dns1.belwue.de.
; www.gm.rt.schule-bw.de. wird von unserem
; dns-server nicht verwaltet, aber von belwue.
Diese Datei sorgt für die Auflösung eines Namens in seine IP-Adresse. Die andere Zonen-Datei ist für die umgekehrte Richtung da. /var/cache/bin/192.168.0-zone muss folgenden Inhalt haben:
;
;
/var/cache/bind/192.168.0-zone
;
$TTL 2D
@ IN SOA dns.gm.rt.schule-bw.de. root.gm.rt.schule-bw.de. (
2003081201 ; serial JJJJMMTTNN
8H ; refresh rate
2H ; retry rate
1W ; expiration date
2D ) ; minimum ttl
IN NS dns.gm.rt.schule-bw.de.
1 IN PTR server.gm.rt.schule-bw.de.
Mit /etc/init.d/bind reload wird die neue Konfiguration übernommen.
Damit unser Server seinen eigenen dns-Server auch benutzt, muss noch die Datei /etc/resolv.conf bearbeitet werden. Sie muss folgenden Inhalt haben:
#
# /etc/resolv.conf
#
search
gm.rt.schule-bw.de
nameserver 192.168.0.1
Damit ist die Konfiguration des dns-Servers abgeschlossen.
Mit dem dhcp-Protokoll lassen sich die Clients automatisch konfigurieren. Da unser Netz die Adresse 192.168.0.0 hat und 192.168.0.1 und 192.168.0.254 schon belegt sind (Server und Netzdrucker), bleibt für die Clients im Prinzip der Adressbereich 2-253 übrig. Um aber für besondere Fälle (z.B. weitere Netzdrucker) noch einige Adressen frei zu haben, sollten die Clients nur folgenden Bereich nutzen: 140-253.
Zuerst muss der dhcp-Server wahrscheinlich installiert werden. Das geht mit dem Befehl apt-get install dhcp. Die Konfigurationsdatei heißt /etc/dhcpd.conf. Sie muss folgenden Inhalt haben:
#
#
/etc/dhcpd.conf
#
default-lease-time 604800; # 7
days
max-lease-time 2592000; # 30 days
option
domain-name "gm.rt.schule-bw.de";
option
domain-name-servers dns.gm.rt.schule-bw.de;
option
lpr-servers server.gm.rt.schule-bw.de;
option
netbios-name-servers server.gm.rt.schule-bw.de;
option
time-servers server.gm.rt.schule-bw.de;
option
smtp-server mail.gm.rt.schule-bw.de;
option pop-server pop.gm.rt.schule-bw.de;
option www-server server.gm.rt.schule-bw.de;
option subnet-mask
255.255.255.0;
option broadcast-address 192.168.0.255;
subnet
192.168.0.0 netmask 255.255.255.0 {
range 192.168.0.140
192.168.0.253;
}
In der Datei /etc/default/dhcp steht, auf welchen Netzwerkkarten der dhcp-Server aktiv ist. Hier muss folgende Zeile stehen:
INTERFACES="eth0"
Mit /etc/init.d/dhcp restart wird die Konfiguration übernommen.
In diesem Abschnitt wird die Konfiguration des Mailsystems beschrieben. Zunächst muss uucp eingerichtet werden. uucp wird zum Abholen der Mails vom Provider verwendet (in unserem Fall: belwue). Dann muss der eigentliche MTA (Mail Transfer Agent) eingerichtet werden, der SMTP-Server. Dieser Server erhält über uucp die Mails der Domain gm.rt.schule-bw.de und verteilt diese an die Benutzer. Andererseits nimmt der SMTP-Server neue Mails von den Clients an und versendet sie über uucp.
Zunächst einmal muss die uucp-Software installiert werden: apt-get install uucp. Alle Konfigurationsdateien liegen in /etc/uucp/. Am besten werden in diesem Verzeichnis zuerst alle Konfigurationsdateien gelöscht.
Wir bearbeiten zuerst die Datei call. Hier werden drei Informationen benötigt: Der Systemname des Providers (hier: belwue), Login-Name und Passwort.
#
# /etc/uucp/call
#
#
Format:
# system login passwd
belwue loginname passwort
"loginname" und "passwort" müssen natürlich noch ersetzt werden.
Die nächste Datei heißt config. Hier steht der UUCP-Name des lokalen Rechners.
#
# /etc/uucp/config
#
nodename
loginname
Auch hier muss "loginname" ersetzt werden.
In der Datei sys werden die bekannten Systeme beschrieben, die verwendet werden sollen. Diese Datei sollte folgenden Inhalt haben:
#
# /etc/uucp/sys
#
###
#
Globale Einstellung für alle Systeme
# Loginnamen und
Passwort aus der Datei 'call' lesen
call-login *
call-password
*
# Keine Einschränkung der Zugriffszeit
time any
###
# Systemspezifische Einstellungen
system
belwue
called-login loginname
commands rnews rmail rsmtp rcsmtp crsmtp
myname loginname
port type tcp
address news.belwue.de
Hier muss wieder "loginname" ersetzt werden.
In der Datei /etc/hosts muss noch eine Zeile ergänzt werden:
129.143.4.4 news.belwue.de
belwue
Neue Mails werden dann letztendlich mit folgendem Befehl abgeholt: uucico -r1 -sbelwue -f.
Die Konfiguration kann natürlich auch getestet werden. Dazu die folgenden Befehle eingeben; die Ausgabe sollte ähnlich sein.
server:~# su –
uucp
uucp@server:~$ /usr/lib/uucp/uuchk
Local node name
loginname
Spool directory /var/spool/uucp
Public directory
/var/spool/uucppublic
Lock directory /var/lock
Log file
/var/log/uucp/Log
Statistics file /var/log/uucp/Stats
Debug
file /var/log/uucp/Debug
Global debugging level
uucico -l will
strip login names and passwords
uucico will strip UUCP protocol
commands
Start uuxqt once per uucico invocation
System:
belwue
Caller must log in as loginname
Will use loginname as
name of local system
Call out using a specially defined port
The port is defined as:
Port name system belwue port
Port
type tcp
TCP service uucp
Characteristics:
eight-bit-clean reliable end-to-end fullduplex
Remote address
news.belwue.de
Chat script "" \r\c
ogin:-BREAK-ogin:-BREAK-ogin: \L word: \P
Chat script timeout 10
Chat script incoming bytes stripped to seven bits
Login name
loginname
Password passwort
At any time may call if any work
May retry the call up to 26 times
May make local requests when
calling
May make local requests when called
May send by local
request: /
May send by remote request: ~
May accept by local
request: ~
May receive by remote request: ~
May execute rnews
rmail rsmtp rcsmtp crsmtp
Execution path /bin /usr/bin
/usr/local/bin /usr/sbin
Will leave 50000 bytes available
Public directory is /var/spool/uucppublic
Will use any known
protocol
Eine weitere Möglichkeit, die Konfiguration zu testen, ist, die Mails abzuholen und dabei Debug-Ausgaben erzeugen zu lassen. Das geht mit uucico -r1 -x9 -sbelwue -f recht einfach. In /var/log/uucp/Debug stehen die ausführlichen Debug-Ausgaben. Die Datei /var/log/uucp/Log wird immer erweitert, wenn uucp benutzt wird.
Exim ist wahrscheinlich schon installiert. Mit eximconfig wird das Konfigurationsprogramm aufgerufen. Bei der ersten Frage muss Option 1 ausgewählt werden (Internet site). Die Antwort auf die nächste Frage ("visible mail name of your system") lautet gm.rt.schule-bw.de. Dann noch vier mal "none" also Antwort verwenden und die grobe Konfiguration ist abgeschlossen.
Jetzt kommt die feinere Konfiguration in der Datei /etc/exim/exim.conf. Um uucp mit exim verwenden zu können, müssen im Abschnitt Transports folgende Zeilen hinzugefügt werden:
######################################################################
# TRANSPORTS CONFIGURATION #
######################################################################
# ORDER DOES NOT MATTER #
# Only one appropriate transport is called for each
delivery. #
######################################################################
uucp_pipe:
driver = pipe
command = "uux - -a$sender_address -r
$host\!rmail ($local_part@$domain)"
pipe_as_creator
restrict_to_path
path = "/usr/bin:/bin"
return_output
Im Abschnitt Router müssen folgende Zeilen am Anfang des Abschnitts hinzugefügt werden (die Reihenfolge spielt eine Rolle):
######################################################################
# ROUTERS CONFIGURATION #
# Specifies how remote addresses are handled #
######################################################################
# ORDER DOES MATTER #
# A remote address is passed to each in turn until it is
accepted. #
######################################################################
uucp:
driver = domainlist
transport = uucp_pipe
route_list = "*
belwue byname"
Damit wird die ausgehende Mail zuerst über uucp verschickt.
Im ersten Abschnitt (main configuration settings) muss die Variabel "trusted_users" gesucht werden. Folgendes muss geändert werden:
trusted_users = mail:uucp
trusted_groups = uucp
Im selben Abschnitt müssen noch zwei Optionen gesucht und geändert werden:
host_accept_relay =
127.0.0.1 : 192.168.0.0/24
never_users = root
Damit können alle Computer im Netzwerk über den Server als SMTP-Server Nachrichten versenden mit beliebigen Absender und Empfänger. Die zweite Option verhindert, dass dem Benutzer root (also dem Systemadministrator) direkt Mails zugestellt werden. Die Mails an root müssen an einen anderen Benutzer weitergeleitet werden. Das passiert im nächsten Absatz.
Zur Mailkonfiguration gibt es noch eine zweite, sehr wichtige Datei: /etc/aliases. Hier können z.B. Weiterleitungen definiert werden. eximconfig hat schon eine neue Datei erstellt. Am Ende dieser Datei sollten folgende Zeilen hinzugefügt werden:
info: verwaltung, homepage
homepage: thomas, alexander,
jmueller, bohn, andreas
verwaltung: root
sekretariat: poststelle@xxxxxxxx.schule.bwl.de,
\sekretariat
proxymaster: root
root: andreas
# Anmerkung: Hier könnten noch Weiterleitungen
von Mail an externe Adressen
# eingerichtet werden, zum Beispiel
für Lehrer
andreas: a.dangel@gmx.de, \andreas
Die letzte Zeile ist ein Beispiel für eine externe Weiterleitung.
Soll der Server regelmäßig neue Mails abholen, muss der cron-Dienst entsprechend konfiguriert werden. In der Datei /etc/cron.d/getEmail steht eine neue cron-Konfiguration. Sie muss folgenden Inhalt haben:
#
# /etc/cron.d/getEmail
#
#
min hour(s) day month dow user command
0
7,10,13,15,17,19,21 * * * root /usr/local/sbin/getEmail
Die Datei /usr/local/sbin/getEmail sieht so aus:
#!/bin/sh
#
#
/usr/local/sbin/getEmail
#
# Internetverbindung aufbauen:
ping an news.belwue.de
ping -c 5 129.143.4.4 > /dev/null
#
Mailqueue abarbeiten
/usr/sbin/exim -q
# neue Mails
holen
/usr/sbin/uucico -r1 -sbelwue -f
Mit chmod 700 /usr/local/sbin/getEmail wird das Script ausführbar gemacht.
Standardmäßig wird die Mail-Warteschlange von exim alle 15 Minuten ausgeführt. Dies ist unnötig und verursacht nur häufige Internet-Einwahlen. Die Mail-Queue wird im Script /usr/local/sbin/getEmail auch ausgeführt (exim -q). Wir deaktivieren deshalb die Standardeinstellung. Dazu wird der Eintrag in der vierten Zeile in /etc/cron.d/exim mit einem "#" auskommentiert.
Wenn ein ssh-Server installiert ist, kann man sich über das Netzwerk auf den Server einloggen. Dabei ersetzt ssh den alten telnet-Dienst; ssh verwendet im Gegensatz zu telnet eine Verschlüsselung. ssh-Clients gibt es für Linux und für Windows. Ein guter Client für Windows heißt "putty".
Mit apt-get install ssh wird der Server installiert. In /etc/ssh/ liegen die Konfigurationsdateien. Die Datei sshd_config ist für den ssh-Server zuständig; die wichtigste Option lautet PermitRootLogin; sie sollte auf "no" gestellt sein. Damit kann sich zwar root nicht mehr direkt einloggen (was erstens ein Sicherheitsrisiko ist und zweitens nicht nötig ist), aber als normaler Benutzer wird man mit su zum root (natürlich nach Eingabe des root-Passwortes).
Um weiter an Sicherheit zu gewinnen (der ssh-Zugang ist, wenn der Server online ist, im ganzen Internet verfügbar...), sollte noch der Standard-Port geändert werden. Das geschieht in der Datei /etc/ssh/sshd_config mit der Option Port. Der Standard-Port ist 22, wir verwenden aber ab jetzt den Port 1222.
Die Konfiguration wird mit /etc/init.d/ssh reload übernommen. Mit ssh -p 1222 user@server kann man sich nun über das Netzwerk auf den Server einloggen.
Bei jeder Einwahl über den T-DSL-Anschluss von T-Online bekommt der Server eine andere IP-Adresse, über die er im Internet erreichbar ist. Damit aber trotzdem Fernwartung über das Internet möglich ist, muss die IP-Adresse bekannt sein. Der kostenlose dyndns-Dienst stellt einen DNS-Eintrag zur Verfügung, der bei jeder Einwahl aktualisiert wird. Somit ist der Server dann immer über den gleichen Hostnamen erreichbar.
Mit apt-get install ddclient wird die dazu notwendige Software installiert. Die Konfigurationsdatei heißt /etc/ddclient.conf und sollte folgenden Inhalt haben:
#
#
/etc/ddclient.conf
#
pid=/var/run/ddclient.pid
protocol=dyndns2
wildcard=yes
use=if,
if=ppp0
server=members.dyndns.org
login=loginname
password=passwort
host.dyndns.org
"loginname", "passwort" und "host.dyndns.org" müssen natürlich noch angepasst werden.
Damit die IP-Adresse bei jeder Einwahl auch aktualisiert wird, muss noch /etc/default/ddclient angepasst werden. Die zwei entscheidenden Einträge lauten:
run_ipup="true"
run_daemon="false"
Jetzt muss noch dafür gesorgt werden, dass der Server regelmäßig online geht. Zum Beispiel kann der Server regelmäßig neue Mails herunterladen. Wie das Einzurichten ist, steht in 3.1.3.3. Regelmäßig Mails abholen.
Der Webserver ist quasi die komfortable Bedienoberfläche für das Schulnetz. Über diesen Server werden einzelne CGI-Scripte ausgeführt, mit denen man zum Beispiel einen neuen Benutzer anlegen kann. Ansonsten lässt sich die Homepage der Schule anschauen und jeder Benutzer kann im Ordner public_html/ in seinem Homeverzeichnis seine eigenen Seiten im Schulnetz veröffentlichen.
Als Webserver wird apache verwendet. Falls apache noch nicht installiert ist, lässt sich dies mit apt-get install apache nachholen. Die Konfigurationsdatei heißt /etc/apache/httpd.conf. Diese muss an einigen stellen angepasst werden. Der folgende Ausschnitt aus der Konfigurationsdatei soll einen Anhaltspunkt geben, was gegenüber der Standardkonfigurationsdatei von Debian verändert werden muss:
#
#
/etc/apache/httpd.conf
#
### Section 1: Global
Environment
# Keine Änderungen nötig
### Section
2: 'Main' server configuration
ServerAdmin
webmaster@gm.rt.schule-bw.de
ServerName
server.gm.rt.schule-bw.de
DocumentRoot
"/usr/local/httpd/htdocs"
<Directory />
AuthUserFile /etc/apache/passwd
AuthGroupFile /etc/apache/group
Order allow,deny
Options None
AllowOverride None
</Directory>
#
# This should be
changed to whatever you set DocumentRoot to.
#
<Directory
/usr/local/httpd/htdocs/>
Options Indexes FollowSymLinks
AllowOverride None
Order allow,deny
Allow from
all
</Directory>
# Einzelne Verzeichnisse
<Directory
/usr/local/httpd/htdocs/admin/>
AllowOverride None
Options ExecCGI FollowSymLinks Indexes
DirectoryIndex
index.html index.cgi
AuthType Basic
AuthName
"Systemverwaltung"
AuthUserFile /etc/apache/passwd
AuthGroupFile /etc/apache/group
require group
admin
</Directory>
<Directory
/usr/local/httpd/htdocs/internet/>
AllowOverride None
Options ExecCGI FollowSymLinks
DirectoryIndex index.html
index.cgi
AuthType Basic
AuthName
"Internet-Einwahl"
AuthUserFile /etc/apache/passwd
AuthGroupFile /etc/apache/group
require group
internet
</Directory>
<Directory
/usr/local/httpd/htdocs/organisation/>
AllowOverride None
Options Indexes
DirectoryIndex index.html index.htm
AuthType Basic
AuthName "Organisation"
AuthUserFile /etc/apache/passwd
AuthGroupFile
/etc/apache/group
require group
lehrer
</Directory>
<Directory
/usr/local/httpd/htdocs/passwd/>
AllowOverride None
Options ExecCGI FollowSymLinks
DirectoryIndex index.html
index.cgi
AuthType Basic
AuthName
"Passwortaenderung"
AuthUserFile /etc/apache/passwd
AuthGroupFile /etc/apache/group
require group users
</Directory>
<Directory
/usr/local/httpd/htdocs/mail-config/>
AllowOverride None
Options ExecCGI FollowSymLinks
DirectoryIndex index.html
index.cgi
AuthType Basic
AuthName
"Mail-Weiterleitung"
AuthUserFile /etc/apache/passwd
AuthGroupFile /etc/apache/group
require group users
</Directory>
<Directory
/usr/local/samba/homepage/>
AllowOverride None
Options Indexes FollowSymLinks
Order allow,deny
Allow
from all
</Directory>
ScriptAlias /cgi-bin/
/usr/local/httpd/cgi-bin/
<Directory /usr/lib/cgi-bin/>
AllowOverride None
Options ExecCGI
Order allow,deny
Allow from all
</Directory>
<IfModule
mod_mime.c>
AddHandler cgi-script .cgi .sh
.pl
</IfModule>
<IfModule mod_userdir.c>
UserDir /home/public_html
</IfModule>
<Directory
/home/public_html/*/>
AllowOverride FileInfo AuthConfig
Limit
Options MultiViews Indexes SymLinksIfOwnerMatch
IncludesNoExec
<Limit GET POST OPTIONS PROPFIND>
Order allow,deny
Allow from all
</Limit>
<Limit PUT DELETE PATCH PROPPATCH MKCOL COPY MOVE LOCK UNLOCK>
Order deny,allow
Deny from all
</Limit>
</Directory>
Es wurden für einige Verzeichnisse die Zugriffsrechte gesetzt. Oft muss man sich erst anmelden (AuthType Basic), wenn man so ein Verzeichnis betreten will.
Mit /etc/init.d/apache restart wird die neue Konfiguration übernommen. Jetzt wird noch ein Script benötigt, das die Dateien /etc/apache/passwd und /etc/apache/group erzeugt. Diese sind für eine Anmeldung notwendig. Das Script mit dem Dateinamen /usr/local/sbin/generate_apache_auth ist im Anhang zu finden.
Dieses Script wird mit chmod 700 /usr/local/sbin/generate_apache_auth ausführbar gemacht. Jedesmal, wenn ein neuer Benutzer angelegt wird, wenn ein Benutzer gelöscht wird oder wenn ein Passwort geändert wurde, muss dieses Script ausgeführt werden.
Über einen POP3-Server können sich die Benutzer ihre Mail komfortabel über einen Mailclient (z.B. Mozilla-Mail, Outlook Express) abholen. Der POP3-Server verwendet die Mailboxen der lokalen Benutzer auf dem Server. Mit apt-get install qpopper wird ein einfacher POP3-Server installiert. Die Standardkonfiguration genügt; dieser Server muss nicht konfiguriert werden. Falls doch: Die Konfigurationsdatei heißt /etc/qpopper.conf.
Über den Proxy-Server squid erhalten die Clients Zugang zum Internet. Alle Rechner im Schulnetz greifen also nicht direkt auf das Internet zu, sondern nur auf den Proxy-Server, der dann die gewünschten Daten liefert. Zuerst muss die Software installiert werden: apt-get install squid. Die Konfigurationsdatei heißt /etc/squid.conf. In der Datei müssen einige Einstellungen angepasst werden. Hier sind die wichtigen Einstellungen:
#
# /etc/squid.conf
#
ftp_user
webmaster@gm.rt.schule-bw.de
# ACCESS CONTROLS
#
---------------
[...]
# INSERT YOUR OWN RULE(S) HERE...
acl
schulnetz src 192.168.0.0/255.255.255.0
acl server dst
192.168.0.1
http_access allow schulnetz
append_domain
.gm.rt.schule-bw.de
always_direct allow server
Mit /etc/init.d/squid restart wird die Konfiguration übernommen.
Der Filter, der als Jugendschutzfilter eingerichtet werden kann, sperrt bestimmte Internetadressen. Aktuelle Listen erhält man unter http://www.squidguard.org/blacklist/.
Die Filtersoftware heißt squidguard und wird mit apt-get install squidguard installiert. Damit der Filter im Proxy integriert wird, muss /etc/squid.conf bearbeitet werden. Es müssen folgende zwei Einträge existieren:
#
#
/etc/squid.conf
#
[...]
redirect_program
/usr/bin/squidGuard
redirect_children 5
Dann müssen neue Blacklisten unter der oben genannten Adresse heruntergeladen werden. Mit cd /var/lib/squidguard/db; tar xfzv ~/blacklists.tar.gz wird das Archiv ins richtige Verzeichnis entpackt. Danach muss noch chmod -R 777 /var/lib/squidguard/db/blacklists ausgeführt werden. Die Konfigurationsdatei heißt /etc/squid/squidGuard.conf. Sie muss folgenden Inhalt haben:
#
#
/etc/squid/squidGuard.conf
#
logdir /var/log/squid
dbhome
/var/lib/squidguard/db
src localnet {
ip 127.0.0.0/8
ip 192.168.0.0/24
}
dest ads {
domainlist blacklists/ads/domains
urllist blacklists/ads/urls
}
dest aggressive {
domainlist blacklists/aggressive/domains
urllist blacklists/aggressive/urls
}
dest audio-video {
domainlist blacklists/audio-video/domains
urllist blacklists/audio-video/urls
}
dest drugs {
domainlist blacklists/drugs/domains
urllist blacklists/drugs/urls
}
dest gambling {
domainlist blacklists/gambling/domains
urllist blacklists/gambling/urls
}
dest hacking {
domainlist blacklists/hacking/domains
urllist blacklists/hacking/urls
}
dest mail {
domainlist blacklists/mail/domains
}
dest porn {
domainlist blacklists/porn/domains
urllist blacklists/porn/urls
#expressionlist blacklists/porn/expressions
}
dest proxy {
domainlist blacklists/proxy/domains
urllist blacklists/proxy/urls
}
dest violence {
domainlist blacklists/violence/domains
urllist blacklists/violence/urls
#expressionlist blacklists/violence/expressions
}
dest warez {
domainlist blacklists/warez/domains
urllist blacklists/warez/urls
}
acl {
localnet {
pass !aggressive !porn !violence all
redirect
http://server/cgi-bin/blocked.cgi?clientaddr=%a&url=%u
}
default {
pass none
redirect
http://server/cgi-bin/blocked.cgi?clientaddr=%a&url=%u
}
}
Damit werden die Adresslisten "aggressive", "porn" und "violence" abgeblockt. Wer eine solche Seite aufruft, bekommt das Script blocked.cgi zu sehen. Dieses Script gibt eine Fehlermeldung aus oder, wenn der Filter eine Bilddatei blockiert (z.B. Werbung), dann wird /usr/local/httpd/htdocs/blocked.gif angezeigt. Das Script blocked.cgi muss noch im Verzeichnis /usr/local/httpd/cgi-bin/ erstellt werden:
#!/usr/bin/perl
#
#
/usr/local/httpd/cgi-bin/blocked.cgi
#
use CGI;
$q = new
CGI;
$clientaddr = "";
$url="";
$clientaddr
= $q->param('clientaddr') if
defined($q->param('clientaddr'));
$url = $q->param('url') if
defined($q->param('url'));
if ($url =~
/\.(gif|jpg|jpeg|mpg|mpeg|avi|mov)$/i) {
print "Content-type:
image/gif\n";
($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =
gmtime($time);
printf "Expires: %s, %02d-%s-%02d
%02d:%02d:%02d GMT\n\n", $day[$wday],
$mday,$month[$mon],$year,$hour,$min,$sec;
open(GIF,
"$ENV{'DOCUMENT_ROOT'}/blocked.gif");
while (<GIF>)
{
print;
}
close(GIF);
} else {
print "Content-type: text/html\n";
printf "Expires:
%s, %02d-%s-%02d %02d:%02d:%02d GMT\n\n", $day[$wday],
$mday,$month[$mon],$year,$hour,$min,$sec;
print <<EOF;
<html>
<head>
<title>403 Forbidden - Zugriff
verweigert</title>
</head>
<body>
<center>
<h1>403
Forbidden - Zugriff verweigert</h1>
Der Zugriff wurde Ihnen
aus einem der folgenden Gründe verweigert:
<table
border="0">
<tr><td>
<ul>
<li>Ihre IP-Adresse ist nicht aus dem Bereich des
Schulnetzes</li>
<li>Der Jugendschutzfilter ist
aktiviert. Die Filterkategorien sind:
<ul>
<li>aggressive</li>
<li>porn</li>
<li>violence</li>
</ul>
</ul>
</td></tr>
</table>
Wenn
diese Seite zu Unrecht gesperrt wurde, schreiben Sie eine Mail
an<br>
<a
href="mailto:proxymaster\@gm.rt.schule-bw.de">
proxymaster\@gm.rt.schule-bw.de</a>
</center>
</body>
</html>
EOF
}
exit
0;
Mit chmod 755 /usr/local/httpd/cgi-bin/blocked.cgi wird das Script ausführbar gemacht. Damit squidGuard später schneller startet, wird squidGuard -C all einmal ausgeführt. Dabei werden die Adresslisten in ein Datenbankformat konvertiert. Mit /etc/init.d/squid restart wird der Filter letztendlich aktiviert.
Damit der Netzwerkdrucker später über Samba den Windows-Clients zur Verfügung gestellt werden kann, muss der Netzwerkdrucker (der übrigens auch lokal am Druckerport des Servers angeschlossen sein könnte) zunächst auf dem Server eingerichtet werden. Dazu wird das "Common UNIX Printing System" benötigt, das mit apt-get install cupsys cupsys-client noch nachinstalliert werden muss. Konfiguriert wird das Druck-System über einen Webbrowser. Als Text-Browser eignet sich lynx. Möglicherweise muss dieser mit apt-get install lynx nachinstalliert werden. Mit /etc/init.d/cupsys start wird das Druck-System gestartet.
Mit lynx http://localhost:631/ wird der Webbrowser zur Konfiguration gestartet. Hier muss zunächst Manage Printers ausgewählt werden, danach Add Printer. Der Browser fragt nun nach einem Benutzernamen. Einfach "root" und das root-Passwort verwenden. Auf der nächsten Seite muss der Freigabe-Name eingegeben werden, also z.B. "netzdrucker". Location und Description sind weniger wichtig. Mit Continue geht's weiter. Auf der folgenden Seite muss jetzt als Device "AppSocket/HP JetDirect" ausgewählt werden. Im Feld Device URI auf der nächsten Seite muss "socket://192.168.0.254:9100" eingetragen werden. Model/Driver ist "Raw" und "Raw Queue (en)". Das bedeutet, dass die Druckdaten genau so an den Drucker weitergeleitet werden, wie der Windows-Client sie verschickt. Unter Windows muss also noch ein passender Druckertreiber installiert werden. Das war's soweit. Der Rest muss unter Samba konfiguriert werden.
Samba stellt den Windows-Clients Speicherplatz zur Verfügung: Ein Homeverzeichnis, ein Verzeichnis für temporäre Daten, ein öffentliches Verzeichnis und ein Verzeichnis für Windows-Programme. Für bestimmte Benutzergruppen gibt es weitere Verzeichnisse: Homepage und Admin beispielsweise. Außerdem gibt es noch ein sogenannten "netlogon-script", das beim Anmelden bei Samba auf dem Client gestartet wird und die Verzeichnisse automatisch einbindet. Zusätzlich gibt Samba noch den Drucker frei, der im vorigen Abschnitt eingerichtet wurde.
Zunächst muss samba installiert werden; das geht mit apt-get install samba. Die Konfigurationsdatei heißt /etc/samba/smb.conf. Sie hat folgenden Inhalt:
#
#
/etc/samba/smb.conf
#
[global]
workgroup = WORKGROUP
netbios name = server
server string = Samba Server
comment = Samba Server
hosts allow = 192.168.0.
load printers = yes
printcap name = cups
printing =
CUPS
guest account = nobody
#log file =
/var/log/samba/log.%m # für jede Maschine eine eigene Logfile
log file = /var/log/samba/log.smb
log level = 1
max
log size = 1000 # in KB
syslog = 0
security =
user
encrypt passwords = yes
smb passwd file =
/usr/local/samba/private/smbpasswd
passwd program =
/usr/bin/passwd %u
unix password sync = yes
socket
options = TCP_NODELAY
keepalive = 30
interfaces =
eth0
local master = yes
os level = 65
domain
master = yes
preferred master = yes
domain logons =
yes
logon script = logon.bat
# für Roaming
Profiles (WinNT)
#logon path = \\SERVER\%U\profile
#
für Roaming Profiles (Win9X)
#logon home =
\\SERVER\%U\profile
wins support = yes
# alles
in eine Zeile!
invalid users = root daemon bin sys sync games
man lp mail news uucp proxy
postgres www-data backup
operator list irc gnats identd sshd gdm telnetd
ftp nut
faxmaster partimag mysql homepage internet
valid users =
+users nobody
admin users = +admin
[printers]
comment = All Printers
path = /var/spool/samba
browseable = no
public = yes
guest ok = yes
writeable = no
printable = yes
[netlogon]
path =
/usr/local/samba/netlogon
write list = +admin
guest ok
= yes
[homes]
comment = Heimatverzeichnis von %U
# wegen public_html: www-data
force group = www-data
read only = no
create mask = 0755
browseable =
no
[tmp]
comment = Temporaere Dateien
path =
/usr/local/samba/temp
force group = users
read only =
no
create mask = 0664
directory mask = 0775
guest ok = yes
[pub]
comment = Oeffentliches
Verzeichnis
path = /usr/local/samba/pub
write list =
+lehrer
force group = lehrer
create mask = 0664
force create mode = 0664
directory mask = 0775
force
directory mode = 0775
guest ok = yes
[homepage]
comment = Gymnasium-Muensingen Homepage
path =
/usr/local/samba/homepage
write list = +homepage
force
group = homepage
create mask = 0664
force create mode =
0664
directory mask = 0775
force directory mode =
0775
[programme]
comment = Programme fuer Windows
path = /usr/local/samba/programme
write list = +admin
force group = admin
create mask = 0664
force create
mode = 0664
directory mask = 0775
force directory mode
= 0775
guest ok = yes
[programdata]
comment =
Programm-Daten
path = /usr/local/samba/programdata
#
jeder darf schreiben (Windows-Programme brauchen das ;-)
write
list = +users nobody
force group = users
create mask =
0664
force create mode = 0664
directory mask = 0775
force directory mode = 0775
guest ok = yes
[admin]
comment = Admin-Verzeichnis
path = /usr/local/samba/admin
valid users = +admin
force group = admin
read only =
no
create mask = 0660
force create mode = 0660
directory mask = 0770
force directory mode = 0770
Die angegebenen Verzeichnisse müssen natürlich existieren (alles unter /usr/local/samba/). Außerdem müssen für diese Verzeichnisse die passenden Zugriffsrechte gesetzt sein. Mit /etc/init.d/samba restart werden die Einstellungen übernommen.
Für die Druckfunktion muss das Verzeichnis /var/spool/samba existieren. Außerdem muss es den Mitglieder der Gruppe "users" erlaubt sein, in dieses Verzeichnis zu schreiben (sonst dürfen diese Benutzer nicht drucken). Dies ist zu erreichen mit den folgenden zwei Befehlen:
chgrp users /var/spool/samba
chmod g+wx /var/spool/samba
Hier ist das Netlogon-Script. Es verbindet einige Netzlaufwerke, sodass diese im Explorer zur Verfügung stehen. Außerdem wird die Uhrzeit des Clients nach der Server-Uhr gestellt. Damit es keine Probleme mit Mozilla-Profilen gibt, wird eine Datei bei jedem Einloggen auf den Client kopiert; in dieser Datei steht, dass das Mozilla-Profil unter "H:\Mozilla" zu finden ist.
@echo off
net use h:
\\arktur\homes /yes
net use i: \\arktur\homepage /yes
net use
v: \\arktur\pub /yes
net use t: \\arktur\tmp /yes
net use p:
\\arktur\progs /yes
net time \\arktur /set /yes
rem
Mozilla-Profil-Konfiguration:
copy \\arktur\netlogon\registry.dat
C:\WINDOWS\Anwendungsdaten\Mozilla /Y
Samba benützt drei Logdateien: In /var/log/samba/log.nmbd protokolliert der nmbd-Dämon seine Zugriffe. In /var/log/samba/log.smbd steht, wann der smbd-Dämon gestartet wurde. Und in /var/log/samba/log.smb steht, wer auf irgendwelche Freigaben zugegriffen hat. Diese Logdateien sollen auch mit logrotate rotiert werden. Damit dies zuverlässig klappt, wird vor dem Rotieren der Samba-Dämon gestoppt und danach wieder gestartet.
Die Datei /etc/logrotate.d/samba muss folgenden Inhalt haben:
/var/log/samba/log.smb {
weekly
missingok
rotate 7
prerotate
/etc/init.d/samba stop || true
killall -q smbd || true
endscript
compress
notifempty
}
/var/log/samba/log.smbd {
weekly
missingok
rotate 7
prerotate
/etc/init.d/samba stop || true
killall -q smbd || true
endscript
compress
notifempty
}
/var/log/samba/log.nmbd {
weekly
missingok
rotate 7
prerotate
/etc/init.d/samba stop || true
killall -q nmbd || true
endscript
postrotate
/etc/init.d/samba start
endscript
compress
notifempty
}
Da es offenbar öfters vorkommt, dass der Samba-Server, nachdem er ein paar Tage ununterbrochen lief, nicht mehr reagierte, wird der Samba-Server nun mittels eines Cron-Jobs täglich neugestartet. Dazu wird im Verzeichnis /etc/cron.daily/ die Datei samba-restart erstellt:
#!/bin/sh
/etc/init.d/samba
stop
sleep 4
/etc/init.d/samba start
sleep 4
#
überprüfen, ob nmbd läuft
ps `cat
/var/run/samba/nmbd.pid` > /dev/null
if [ $? -eq 1 ]; then
# nmbd läuft nicht...
/etc/init.d/samba stop
sleep 4
/etc/init.d/samba start
fi
Die Datei muss noch mit chmod 755 /etc/cron.daily/samba-restart ausführbar gemacht werden.
Ein Computer ist umso sicherer, je weniger Dienste auf ihm laufen. Dann hat er eine geringere Angriffsfläche. Am besten ist es, wenn die nicht benötigten Dienste ganz deaktiviert werden und man sich nicht komplett auf die Firewall verlässt. Außerdem nützt die Firewall gar nichts, wenn der verwendete Server eine Sicherheitslücke hat. Daher sollte in regelmäßigen Abständen die Software upgedatet werden.
Die Firewall, die auf dem Server eingerichtet werden soll, schützt den Server zum einen vor dem Internet und zum anderen vor dem lokalen Netzwerk. Immer wenn der Server online ist, ist er auch im Internet sichtbar - und daher auch angreifbar. Die Firewall soll so konfiguriert sein, dass sie nur die unbedingt benötigten Dienste erlaubt. Alles andere wird blockiert.
Das Firewall-Script wird hier nicht abgedruckt. Es ist aber im Anhang zu finden. Zunächst einmal wird das Script nach /usr/local/sbin/firewall kopiert. /etc/init.d/firewall ist ein symbolischer Link darauf. Und /etc/rc[2345].d/S10firewall sind ebenfalls symbolische Links, aber relative mit ../init.d/firewall als Ziel.
Jetzt ist das Firewall-Script fertig installiert. Beim Systemstart wird es automatisch geladen. Manuell kann dies mit /etc/init.d/firewall start nachgeholt werden. Die Firewall kann mit /etc/init.d/firewall stop komplett deaktiviert werden.
Die Firewall besteht unter Linux aus mindestens zwei Teilen: INPUT und OUTPUT. Ein ankommendes Paket kommt immer nach INPUT, ein vom Server generiertes und ihn verlassendes Paket durchläuft immer die Firewallregeln in OUTPUT. Für beide Teile kann eine Standardreaktion eingestellt werden, wenn keine Firewallregel zutrifft. Bei INPUT werden alle Pakete verworfen und bei OUTPUT wird alles erlaubt.
Die Firewall startet mit sich gleich den Proxy-Manager (/usr/local/sbin/proxy-manager). Der Proxy-Manager verwaltet die Internet-Freigabe und schreibt in die Datei /var/state/internet-freigabe, welche Computer bis zu welchem Zeitpunkt freigeschaltet sind. Das selbstgeschriebene squid-redirector-Script (/usr/local/sbin/squid-redirector) benutzt diese Information und leitet entweder zur richtigen Internet-Adresse weiter (genauer: zu squidGuard) oder zeigt eine Fehlermeldung an. Siehe auch 4.3. proxymanager.
Über den speziellen Server "inetd" werden bei Bedarf weitere Server gestartet. Da viele Dienste gar nicht benötigt werden, sollten sie ganz deaktiviert werden. Die Konfigurationsdatei zu "inetd" heißt /etc/inetd.conf. Mit einem "#" am Anfang der Zeile werden bestehende Einträge auskommentiert. Mindestens zwei Einträge sollten aber belassen werden: der smtp-Dienst und der pop3-Dienst. Ohne diese Dienste können die Clients keine Mails mehr verschicken und empfangen. Eine minimale Konfigurationsdatei sieht daher so aus:
#
# /etc/inetd.conf
#
smtp stream tcp nowait mail /usr/sbin/exim exim
-bs
pop-3 stream tcp nowait root /usr/sbin/tcpd /
sr/sbin/in.qpopper -f /etc/qpopper.conf
Mit /etc/init.d/inetd restart wird die Konfiguration übernommen.
netstat und nmap sind zwei Tools, mit denen die Sicherheit ein wenig ausgelotet werden kann. nmap muss gegebenenfalls mit apt-get install nmap nachinstalliert werden.
netstat zeigt aktuelle Netzwerkverbindungen und geöffnete Ports an. Dazu muss netstat -tuanp aufgerufen werden. "-t" steht dabei für das Protokoll TCP, "-u" für UDP, "-a" zeigt alle Einträge an (nicht nur bestehende Verbindungen) und "-n" zeigt alle Ports und IP-Adressen numerisch an. "-p" zeigt zusätzlich - wenn vorhanden - das Server-Programm an.
Active Internet connections
(servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0
0.0.0.0:37 0.0.0.0:* LISTEN 201/inetd
tcp 0 0 0.0.0.0:9 0.0.0.0:* LISTEN 201/inetd
tcp 0 0 0.0.0.0:139 0.0.0.0:* LISTEN 213/smbd
tcp 0 0 0.0.0.0:13 0.0.0.0:* LISTEN 201/inetd
tcp 0 0 0.0.0.0:110 0.0.0.0:* LISTEN 201/inetd
tcp 0 0 0.0.0.0:79 0.0.0.0:* LISTEN 201/inetd
tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN 113/portmap
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 240/apache
tcp 0 0
0.0.0.0:113 0.0.0.0:* LISTEN 201/inetd
tcp 0 0 0.0.0.0:21 0.0.0.0:* LISTEN 201/inetd
tcp 0 0 0.0.0.0:631 0.0.0.0:* LISTEN 206/cupsd
tcp 0 0 0.0.0.0:23 0.0.0.0:* LISTEN 201/inetd
tcp 0 0 0.0.0.0:25 0.0.0.0:* LISTEN 201/inetd
udp 0 0 0.0.0.0:517 0.0.0.0:* 201/inetd
udp 0 0 0.0.0.0:518 0.0.0.0:* 201/inetd
udp 0 0
192.168.0.3:137 0.0.0.0:* 208/nmbd
udp 0 0 0.0.0.0:137 0.0.0.0:* 208/nmbd
udp 0 0 0.0.0.0:9 0.0.0.0:* 201/inetd
udp 0 0 192.168.0.3:138 0.0.0.0:* 208/nmbd
udp 0 0 0.0.0.0:138 0.0.0.0:* 208/nmbd
udp 0 0 0.0.0.0:111 0.0.0.0:* 113/portmap
Bei TCP steht unter State "LISTEN", das heißt, dass hier ein Dienst auf neue Verbindungen wartet.
nmap ist ein sogenannter Portscanner. Er kann zum Beispiel dazu benutzt werden, eine Firewall zu testen. nmap zeigt dabei dann alle offene Ports an. Am besten wird nmap von verschiedenen Rechnern im Intranet und Internet ausgeführt. Ein Beispielaufruf:
server:~# nmap
192.168.0.1
Starting nmap V. 2.54BETA31 (
www.insecure.org/nmap/ )
Interesting ports on
server.adabolo.homelinux.net (192.168.0.1):
(The 1545 ports
scanned but not shown below are in state: closed)
Port State Service
22/tcp open ssh
25/tcp open smtp
37/tcp open time
53/tcp open domain
80/tcp open http
139/tcp open netbios-ssn
444/tcp open snpp
4557/tcp open fax
4559/tcp open hylafax
Nmap run completed -- 1
IP address (1 host up) scanned in 1 second
Auf den angezeigten Ports ist eine Verbindung möglich. Das heißt, dass dieser Dienst erreichbar ist.
Um die Datensicherheit des Servers zu verbessern (wenn Software-RAID eingerichtet wurde, besteht schon eine Sicherheit), soll wöchentlich ein Backup der Home-Verzeichnisse (alles unterhalb von /home/) erstellt werden. Dieses Backup kann dann auf ein externes Medium gesichert werden (z.B. DVD).
Zuerst muss das Script /usr/local/sbin/userdir-backup.sh erstellt werden:
#!/bin/sh
# Liste der alten
Backup-Dateien erstellen...
filelist=`ls
/usr/local/samba/admin/userdir-backup/userdir-backup-*`
tmpfile=`mktemp
/tmp/backup-filelist.XXXXXX`
echo 'Backup home-directories
(/home) ...'
echo
tar cv /home 2> $tmpfile | bzip2 | split
-b 2047m - \
/usr/local/samba/admin/userdir-backup/userdir-backup-`date
+%Y%m%d`.tar.bz2.
if [ $? -ne 0 ]; then
# es ist ein
Fehler aufgetreten
cat $tmpfile
else
# kein Fehler
# jetzt die (ganz) alten Backups löschen
rm
/usr/local/samba/admin/userdir-backup/old/*
# die alten Backups
verschieben
mv $filelist
/usr/local/samba/admin/userdir-backup/old/
fi
echo `cat
$tmpfile | wc -l` files backup up.
rm $tmpfile
df -h
Zunächst muss dieses Script noch mit chmod 700 /usr/local/sbin/userdir-backup.sh ausführbar gemacht werden. Wenn dieses Script ausgeführt wird, dann werden unterhalb von /usr/local/samba/admin/userdir-backup/ (also im Verzeichnis "userdir-backup" in der Samba-Freigabe "admin") mehrere Dateien erstellt, die eine maximale Größe von 2 GB haben (2047 MB). Die Namen der Dateien sind folgendermaßen aufgebaut: userdir-backup-%datum.tar.bz2.%endung. Datum ist z.B. "20031019", also zuerst das Jahr, der Monat und dann der Tag. Die Endung wird hochgezählt und beginnt mit "aa". Die erste Datei hat also die Endung "aa", die zweite "ab", die dritte "ac" usw.
Um das Backup zurückzusichern müssen diese Dateien zunächst wieder zu einer sehr großen einzelnen Datei zusammengeführt werden. Diese Datei ist aber möglicherweise zu groß, deshalb werden - wie beim Sichern - mehrere Befehle auf einmal angewandt: Mit cat userdir-backup-%datum.tar.bz2.* | bunzip2 | tar xv kann das Backup zurückgesichert werden. Diese Befehlskette muss aber im Root-Verzeichnis (/) ausgeführt werden oder man muss das entpackte Home-Verzeichnis entsprechend verschieben.
Damit das Backup-Script nun wöchentlich ausgeführt wird, muss ein sogenannter Crontab-Eintrag erstellt werden. Mit folgendem Crontab-Eintrag wird das Script jeden Sonntag (5. Wert: 0) um 04:00 Uhr (2. Wert: 4; 1. Wert: 0) als Benutzer "root" ausgeführt.
0 4 * * 0 root
/usr/local/sbin/userdir-backup.sh
Dieser Eintrag wird der Datei /etc/crontab als letzte Zeile hinzugefügt. Damit ist das Backup-Script fertig installiert.
Da Linux ein Multiuser-Betriebssystem ist, haben gewöhnliche Benutzer nur wenige Rechte. Im Gegensatz dazu hat der Superuser, der Administrator oder "root", alle Rechte. So darf beispielsweise nur der Administrator das Passwort eines x-beliebigen Benutzers ändern. Manche CGI-Programme für die Weboberfläche benötigen genau dieses Recht (Passwort ändern oder Passwort zurückstellen). Damit dies trotzdem realisierbar ist, gibt es ein Programm, mit dessen Hilfe man andere Programme als root ausführen kann. Dieses Programm heißt "sudo" und muss wahrscheinlich mit apt-get install sudo noch nachinstalliert werden.
Alle CGI-Programme laufen unter dem Benutzer www-data. Diesem Benutzer soll nun erlaubt werden, einige Programme als root auszuführen. Mit visudo wird die Konfigurationsdatei /etc/sudoers bearbeitet. Sie muss folgenden Inhalt haben:
#
# /etc/sudoers
#
#
Host alis specification
Host_Alias LOCAL = 127.0.0.1,
192.168.0.1
# User alias specification
User_Alias WWW =
www-data
# Runas alias specification
Runas_Alias USERS =
root, homepage
# Cmnd alias specification
Cmnd_Alias
COMMANDS = /usr/sbin/usermod, /usr/local/sbin/generate_apache_auth,\
/usr/bin/smbpasswd,
/usr/local/sbin/change-aliases,\
/usr/local/sbin/proxy-manager, /usr/local/sbin/firewall,\
/usr/local/sbin/mirror-hp.sh, /usr/sbin/groupadd,\
/usr/sbin/useradd, /bin/chown, /bin/ln,
/bin/mkdir,\
/usr/sbin/setquota,\
/usr/local/sbin/make_mozilla_config.pl,
/usr/bin/passwd,\
/usr/local/sbin/chpw.pl,
/usr/local/sbin/rmusr.pl,\
/usr/local/sbin/user-status, \
/usr/local/sbin/user-status3, /usr/sbin/userdel, \
/usr/sbin/groupdel, /bin/rm, /bin/mv
# User privilege
specification
root ALL = (ALL) ALL
WWW LOCAL = (USERS)
NOPASSWD: COMMANDS
#www-data ALL=(ALL) NOPASSWD: ALL
Der Benutzer "www-data" kann jetzt mit sudo /usr/sbin/useradd neuer_benutzer zum Beispiel einen neuen Benutzer hinzufügen, was sonst nur root durfte.
Zunächst befindet sich die Homepage im Laufwerk "Homepage" unter Samba. Und dort genauer im Ordner "intranet". Alles was sich in diesem Ordner befindet, wird hochgeladen. Das Programm zum Hochladen heißt weex und wird mit apt-get install weex nachinstalliert. Damit der Server die Homepage halbautomatisch hochladen kann (nach dem Passwort wird noch gefragt), wird ein Benutzer mit dem Namen "homepage" erstellt. Sein Homeverzeichnis ist /home/homepage/. Die Konfigurationsdatei für weex heißt /home/homepage/.weex/weexrc. Sie muss mit folgendem Inhalt erstellt werden:
#
#
/home/homepage/.weex/weexrc
#
[Belwue]
FtpPassive =
true
HostName = www.belwue.de
LoginName = loginname
SrcDir =
/usr/local/samba/homepage/intranet
DestDir =
/htdoc
IgnoreLocalFile = FINDER.DAT
IgnoreLocalDir =
RESOURCE.FRK
IgnoreRemoteDir = {
/htdoc/wusage
/htdoc/stat
}
IgnoreRemoteFile =
/htdoc/homepage.count
[default]
Monochrome = True
"loginname" muss natürlich noch ersetzt werden.
Der Superuser (root) kann mit su -c '/usr/bin/weex Belwue' - homepage die Homepage updaten. Dabei wird er nach dem FTP-Passwort gefragt.
Wenn Quota aktiviert ist, dann kann man den freien Speicherplatz für jeden Benutzer einzeln begrenzen. Dabei protokolliert das Quota-System in einer Datei mit, wieviel Plattenplatz ein beliebiger Benutzer verbraucht.
Um Quota einzurichten, müssen zunächst zwei Programmpakete installiert werden: apt-get install quota quotatool. Außerdem muss der Kernel quota unterstützen. Im Standardkernel ist bisher nur Unterstützung für das Dateisystem ext2fs enthalten. Um mit ReiserFS Quota zu benützen, muss der Kernel gepatcht werden. Näheres steht in 2.2. Kernel machen.
Sind die Grundvoraussetzungen (Software und Kernel) vorhanden, muss die Datei /etc/fstab verändert werden. In der Zeile, die mit "/dev/md0" beginnt, muss noch die Mount-Option usrquota ergänzt werden. Die Zeile sieht dann so aus:
/dev/md0 / reiserfs
defaults,usrquota 0 0
Nach einem Neustart muss mit init S in den Single-User-Mode gewechselt werden. Hier kann dann die Quota-Protokoll-Datei mit quotacheck -avu -F vfsold erstellt werden. Anschließend kann mit init 2 wieder in den normalen Runlevel zurückgewechselt werden. Quota ist nun aktiviert.
Mit dem Programm setquota kann die Begrenzung des Festplattenplatzes für einen bestimmten Benutzer verändert werden. Die Aufruf-Syntax des Programms ist folgende:
setquota -u user <limit> <limit> 0 0 /dev/md0
Mit "limit" ist die Begrenzung in Kilobytes (1 KB = 1024 Bytes) gemeint.
Mit ntpdate lässt sich die Server-Uhr nach einer Atomuhr im Internet stellen. Zuerst muss mit apt-get install ntpdate das Programm installiert werden. Bei der Installation wird nach einem NTP-Server gefragt. Einfach nichts eingeben.
Am besten ist es, wenn bei jeder Internet-Einwahl die Uhr neu gestellt wird. Dazu wird die Datei /etc/ppp/ip-up.d/ntpdate erstellt:
#!/bin/sh
#
#
/etc/ppp/ip-up.d/ntpdate
#
ntpdate -s ntp1.ptb.de
hwclock
-w
Die Datei muss mit chmod 755 /etc/ppp/ip-up.d/ntpdate noch ausführbar gemacht werden.
Damit mitgebrachte Computer (z.B. Notebooks) einfach das Internet über den Server nutzen können, wird ein sogenannter Transparenter Proxy eingerichtet. Dazu braucht der Client nur über DHCP konfiguriert werden. Im Browser muss kein Proxy-Server eingestellt werden, und trotzdem funktioniert der Internet-Zugriff. Die Anfragen an das Internet werden über die Firewall automatisch dem Proxy-Server zugespielt und dieser geht dann ins Internet und holt die Daten ab und schickt sie wieder zurück zum Client. Transparent heißt das deshalb, weil der Benutzer davon überhaupt nichts mitbekommt.
Um den Transparenten Proxy einzurichten, muss zuerst die DHCP-Server-Konfiguration angepasst werden. Der DHCP-Server soll nämlich den Client so konfigurieren, dass der Server das Default-Gateway wird. In der Datei /etc/dhcpd.conf muss noch folgende Zeile eingefügt werden:
option routers 192.168.0.1;
Da sich normale HTTP-Anfragen und Proxy-Anfragen unterscheiden, muss noch der Proxy-Server konfiguriert werden. Die Clients wissen ja nicht, dass sie mit einem Proxy-Server kommunizieren und verwenden daher normale HTTP-Anfragen.
In der Datei /etc/squid.conf müssen an der entsprechenden Stelle folgende Zeilen eingefügt werden:
httpd_accel_host
virtual
httpd_accel_port 80
httpd_accel_with_proxy
on
httpd_accel_uses_host_header on
Mit /etc/init.d/dhcp restart und /etc/init.d/squid restart wird die neue Konfiguration übernommen.
Jetzt muss noch die Firewall angepasst werden, damit sie die Pakete, die normalerweise an Port 80 gesendet werden, an den Proxy-Port 3128 weiterleitet. Im Firewall-Script muss folgende Zeile (alles in einer Zeile) ergänzt werden:
iptables -t nat -A
PREROUTING -i eth0 -p tcp -d ! 192.168.0.1 --dport 80 -j REDIRECT
--to-port 3128
Mit /etc/init.d/firewall restart die Firewall neu starten.
Jetzt sollte ein Browser auch ohne Proxy-Konfiguration ins Internet kommen.
Das S.M.A.R.T.-System dient zur Überwachung der Festplatten. Dabei protokollieren die Festplatten selber verschiedene Aktionen mit, sodass sie mehr oder weniger sichere Voraussagen machen können, wann sie kaputt gehen werden. Um dieses Feature der Festplatten nutzen zu können, muss zuerst das Paket smartsuite mit apt-get install smartsuite installiert werden. Dann können mit dem Befehl smartctl verschiedene Eigenschaften der Festplatten abgefragt werden. Beispiel:
server:~# smartctl -a
/dev/hda
Device: WDC WD800JB-00CRA1 Supports ATA Version 5
Drive
supports S.M.A.R.T. and is enabled
Check S.M.A.R.T.
Passed.
[...]
Vendor Specific SMART Attributes with
Thresholds:
Revision Number: 16
Attribute Flag Value Worst Threshold Raw Value
( 1)Raw Read Error Rate 0x000b 200 200 051 0
( 3)Spin Up Time 0x0007 096 096 021 4291
( 4)Start Stop Count 0x0032 100 100 040 35
( 5)Reallocated Sector Ct 0x0033 199 199 140 1
( 7)Seek Error Rate 0x000b 200 200 051 0
( 9)Power On Hours 0x0032 090 090 000 7995
( 10)Spin Retry Count 0x0013 100 253 051 0
( 11)Calibration Retry Count
0x0013 100 253 051 0
( 12)Power Cycle Count 0x0032 100 100 000 35
(196)Reallocated Event Count
0x0032 199 199 000 1
(197)Current Pending Sector 0x0012 200 200 000 0
(198)Offline Uncorrectable 0x0012 200 200 000 0
(199)UDMA CRC Error Count 0x000a 200 253 000 0
(200)Unknown Attribute 0x0009 200 200 051 0
SMART Error Log:
SMART Error
Logging Version: 1
No Errors Logged
Hier kann man sehen, dass die Festplatte /dev/hda schon 7995 Stunden insgesamt lief („Power On Hours“). Sie wurde bisher 35 Mal angeschaltet („Power Cycle Count“). Ganz am Schluss wieder protokollierte Fehler aufgelistet werden, aber noch gibt es keine („No Errors Logged“).
Ganz am Anfang steht übrigens, ob die Festplatte denkt, dass sie noch weiterhin fehlerfrei laufen wird: „Check S.M.A.R.T. Passed“. Das ist ein gutes Zeichen. Diesen Test kann man auch im BIOS aktivieren, sodass man dann gleich im BIOS gewarnt wird, wenn die Festplatte möglicherweise nicht mehr korrekt funktionieren wird.
Linux ist im Gegensatz zu Windows 9x/ME ein Mehrbenutzerbetriebssystem. Es gibt verschiedene Benutzer, die verschiedene Rechte haben können. Unter Windows hat jeder Benutzer alle Rechte, d.h. er darf z.B. alle Dateien löschen oder die Dateien, die ein anderer Benutzer angelegt hat, selber öffnen und bearbeiten - oder auch löschen. Auch unter Linux gibt es ein Benutzer, der alles darf: Der Administrator (Superuser). Er heißt "root" und für ihn gelten nicht die üblichen Grenzen.
Neben den Benutzern gibt es auch noch verschiedene Gruppen. Jeder Benutzer ist Mitglied in mindestens einer Gruppe. Durch verschiedene Gruppen ist es möglich, gleiche Rechte für eine ganze Reihe von Benutzern zu gewähren. Dadurch lässt sich z.B. Teamarbeit realisieren: Man erstellt eine neue Gruppe und jedes Teammitglied wird Gruppenmitglied. Dann gewährt man dieser Gruppe (und nur dieser) Zugriff auf bestimmte Dateien.
Die Einhaltung der Rechte erfolgt unter Linux fast ausschließlich über Dateien: Jede Datei hat einen Besitzer und eine Gruppe, die diese Datei besitzt. Man kann für den Besitzer der Datei, der Gruppe und dem Rest (also allen anderen Benutzern) jeweils eigene Rechte zuteilen. Es gibt für Dateien drei Arten von Zugriffsrecht: Ausführen (eXecute), lesen (Read) und Schreiben (Write). Die Rechte einer Datei kann man mit dem Befehl ls -l datei anzeigen lassen. Ein Beispiel:
andreas@server:~$ ls -l
Makefile
-rw-r--r-- 1 andreas andreas 411 Oct 21 18:05
Makefile
\_/\_/\_/ | |
| | | | Gruppe
| | | Besitzer
| | Rechte für
alle anderen Benutzer (außer Besitzer und Gruppe)
| Rechte für die Gruppe
Rechte des Besitzers
In diesem Beispiel gehört die Datei "Makefile" dem Benutzer andreas. Die Datei gehört auch der Gruppe mit dem Namen andreas. Der Besitzer darf die Datei lesen (r) und bearbeiten, d.h. schreiben (w). Die Mitglieder der Gruppe dürfen die Datei nur lesen (r). Alle anderen Benutzer dürfen die Datei auch nur lesen (r).
Alle Benutzer haben eine Nummer, die sogenannte User-ID. Der Administrator (root) hat immer die UID 0. Benutzer mit UIDs unter 100 sind Systembenutzer, d.h. keine realen Benutzer. Diese Systembenutzer werden für bestimmte Dienste benötigt. Zum Beispiel läuft der Webserver als Benutzer www-data (UID 33). Auch alle CGI-Scripte laufen dann unter diesem Benutzer. Das ist sinnvoll, denn wenn alle Programme unter root laufen, hätten die Programme auch alle Rechte. Am Schluss der Skala gibt es noch einen Benutzer nobody (UID 65534). Dieser Benutzer wird für den Gastzugang unter Samba verwendet. Ab UID 500 kommen die realen Benutzer.
Durch eine Mitgliedschaft in einer Gruppe bekommen die Benutzer mehr Rechte unter Linux. Wie bei den Benutzern gibt es zunächst eine Gruppe root (Gruppen-ID 0) und dann weitere Systemgruppen. Es existiert auch die Gruppe nogroup (GID 65534), was die Entsprechung zum Benutzer nobody darstellt. Zusätzlich gibt es jetzt eine Gruppe users (GID 100). In dieser Gruppe ist jeder reale Benutzer Mitglied. Alle Mitglieder der Gruppe internet (GID 101) dürfen das Internet aktivieren. Die Mitglieder der Gruppe admin (GID 102) haben unter Samba Administratoren-Rechte, d.h. sie dürfen jede Freigabe beschreiben. Jeder Schüler ist in der Gruppe schueler (GID 103) und jeder Lehrer in der Gruppe lehrer (GID 104). Jeder Benutzer, der die Homepage bearbeiten darf, muss Mitglied der Gruppe homepage (GID 105) sein.
Zusätzlich existiert für jeden einzelnen Benutzer eine eigene Gruppe, die denselben Namen wie der Benutzername trägt (GID und UID müssen nicht identisch sein).
Der Benutzermanager ist ein CGI-Programm für den Webserver. Es ist in Perl geschrieben und wird vom Browser aus angewendet. Die Bedienung ist selbsterklärend. Der Quellcode ist im Anhang abgedruckt. Hier werden nur die Befehle genannt, die im Benutzermanager jeweils ausgeführt werden.
Jeder Benutzer existiert als Benutzer unter Linux und als Samba-Benutzer. Zunächst wird der Benutzer aus der Samba-Benutzerdatenbank gelöscht:
$ smbpasswd -x $login
Als nächstes wird das public_html-Verzeichnis des Benutzer gesichert werden. Es wird einfach in das Verzeichnis "oldhomes" auf dem Webserver verschoben. Außerdem müssen die richtigen Rechte gesetzt werden:
$ mv
/home/public_html/$login /usr/local/httpd/htdocs/oldhomes/
$ chown -h -f -R
root.www-data /usr/local/httpd/htdocs/oldhomes/$login
$ chmod -R 755
/usr/local/httpd/htdocs/oldhomes/$login
Danach kann der Benutzer, sein Homeverzeichnis und seine Gruppe gelöscht werden:
$ userdel -r $login
$ groupdel $login
Zum Schluss muss noch eine neue Passwort-Datei für apache erstellt werden, damit der Benutzer auch hier nicht mehr existiert.
$
/usr/local/sbin/generate_apache_auth
Das Passwort eines Benutzers muss an drei Stellen geändert werden: In der Linux-Benutzerdatenbank, bei Samba und dann in der apache-Passwort-Datei. Drei Befehle müssen dazu ausgeführt werden. Bei den ersten beiden muss das neue Passwort zweimal eingegeben werden.
$ passwd $login
$ smbpasswd -a $login
$
/usr/local/sbin/generate_apache_auth
Zu den Rechten zählen zum einen die verschiedenen Gruppen, in denen der Benutzer Mitglied ist und zum andern die Quota-Einstellung, die angibt, wieviel Festplattenplatz der jeweilige Benutzer verbrauchen darf. Neben den Rechten kann auch noch die Login-Shell eingestellt werden: Ist die Shell /bin/bash, dann darf sich der Benutzer direkt (bzw. über das Netzwerk) am Server einloggen. Soll das verhindert werden, dann muss /bin/false eingestellt werden. Sinnvollerweise sollten sich nur Administratoren direkt einloggen dürfen. Die Gruppen können eine Kombination der folgenden Liste sein: schueler, lehrer, internet, admin, homepage.
Gruppenzugehörigkeit und Shell ändern:
$ usermod -s $shell -G
users,$gruppen,$login $login
Quota ändern - $limit muss in KB angegeben werden:
$ setquota $login /dev/md0
$limit $limit 0 0
Zum Schluss muss wieder die apache-Passwort-Datei neu erstellt werden:
$
/usr/local/sbin/generate_apache_auth
Ein Benutzer kann gesperrt werden und wieder freigegeben werden. Wenn ein Benutzer gesperrt ist, kann er sich nicht mehr einloggen. Sein Zugang ist deaktiviert. Um einen Benutzer zu sperren, müssen drei Befehle ausgeführt werden:
$ passwd -l $login
$ smbpasswd -d $login
$
/usr/local/sbin/generate_apache_auth
Um einen Benutzer, der gesperrt ist, wieder freizugeben, müssen auch drei Befehle ausgeführt werden:
$ passwd -u $login
$ smbpasswd -e $login
$
/usr/local/sbin/generate_apache_auth
Als erster Schritt muss eine neue Gruppe erstellt werden, die den gleichen Namen trägt wie der Benutzer, den man einrichten will:
$ groupadd $login
Danach kann der Benutzer erstellt werden. Ist der Benutzer ein Schüler, so ist sein Homeverzeichnis /home/schueler/$login; bei Lehrern heißt das Homeverzeichnis /home/lehrer/$login. "$name" ist der vollständige Name, "$login" ist der Login-Name. "$groups" ist eine Kombination aus schueler, lehrer, internet, admin, homepage. Dieser Befehl legt auch gleich das Homeverzeichnis an und kopiert alles aus /etc/skel/ hinein. In /etc/skel/ liegt ein halbkonfiguriertes Mozilla-Profil im Ordner mozilla.
$ useradd -c "$name"
-d $home -g $login -G users,$groups,$login \
-s $shell -m $login
Außerdem wird mit dem zweiten Befehl gleich das Passwort gesetzt.
$ passwd $login
Danach wird das "public_home"-Verzeichnis eingerichtet:
$ mkdir -m 0755
/home/public_html/$login
$ chown $login.$login
/home/public_html/$login
ln -s
/home/public_html/$login $home/public_html
Anschließend wird der Benutzer für Samba erstellt. Dabei muss das Passwort gleich gesetzt werden.
$ smbpasswd -a $login
Jetzt muss noch der Quota-Wert gesetzt werden. Ein gewöhnlicher Benutzer darf maximal 50 MB benutzen:
$ setquota $login /dev/md0
51200 51200 0 0
Damit der Benutzer über den Webserver sein Passwort ändern kann, muss die apache-Passwortdatei neu generiert werden:
$
/usr/local/sbin/generate_apache_auth
Zum Schluss muss die Mozilla-Konfiguration angepasst werden. Hier werden der Name des Benutzer und seine EMail-Adresse eingerichtet. Und zwar ersetzt das Script in der Datei prefs.js die Zeichenfolge %user% mit dem vollständigen Namen des Benutzers und %login% mit dem Login-Namen. Bei der Erstellung einer Mozilla-Profil-Vorlage für /etc/skel/ muss also immer %user% und %login% verwendet werden.
$
/usr/local/sbin/make_mozilla_config.pl $home/Mozilla "$login"
"$name"
Mit passwd -S $login erfährt man, ob ein Benutzer gesperrt ist oder nicht und wann der das letzte Mal sein Passwort geändert hat:
$ passwd -S andreas
andreas P 03/02/2003 0 99999
7 -1
Hier ist der Benutzer nicht gesperrt. Bei einem gesperrten Benutzerkonto würde statt dem "P" ein "L" stehen (locked). Mit quota -v $login erfährt man den benutzen Festplattenplatz des Benutzers. Mit groups $login sieht man, in welchen Gruppen der Benutzer Mitglied ist.
Wer sich lieber die Informationen ohne Hilfe bestimmter Programme besorgen möchte, kann auch die Benutzerdatenbank von Linux direkt anschauen. Sie besteht aus drei Textdateien: In /etc/passwd stehen die verschiedenen Benutzer mit UID, vollständiger Name, Homeverzeichnis, Login-Shell. Das Passwort steht in der Datei /etc/shadow. Die Gruppenmitgliedschaft ist in der Datei /etc/group festgehalten.
Der Proxymanager regelt den Zugriff auf das Internet: Bevor ein Benutzer das Internet benutzen kann, muss er es zuerst freischalten. Das passiert über den Webserver mit dem Browser. Dabei wird das Internet nicht für diesen Benutzer speziell freigeschalten, sondern für diesen Computer. Die Computer werden anhand ihrer IP-Adresse unterschieden.
Die Computer greifen nie direkt auf einen Webserver im Internet zu. Alle Anfragen gehen über den Server, genauer über den Proxyserver (Der Server ist also kein Router). So wie der Proxserver in 3.3.3. Proxy und Filter eingerichtet wurde, werden alle Anfragen gefiltert. Wir müssen nun diesen Filter erweitern. Dazu verwenden wir einen selbstgeschriebenen Filter. Da das Schulnetz nicht besonders groß ist, spielt Geschwindigkeit keine so große Rolle und wir können Perl als Programmiersprache verwenden.
Das Filterprogramm ist im Anhang zu finden und heißt /usr/local/sbin/squid-redirector. Es überprüft mit Hilfe des proxymanager-Programms, das weiter unten beschrieben wird, ob das Internet für die IP-Adresse des anfragenden Rechners freigeschaltet ist. Wenn das Internet nicht freigeschaltet ist, wird im Browser eine Fehlermeldung angezeigt ("Internet ist nicht aktiviert"). Diese Fehlermeldung ist in Wirklichkeit ein CGI-Programm. Wenn das Internet aktiviert ist, wird die Anfrage an den Inhaltsfilter squidGuard weitergeleitet.
Das proxymanager-Programm ist in /usr/local/sbin/proxy-manager zu finden. Es ist auch ein Perl-Programm. Das Programm kann mit verschiedenen Parametern aufgerufen werden:
$ /usr/local/sbin/proxy-manager
-h
Syntax: proxy-manager [-hdocak] [login] [ip-adresse]
[zeitsekunden]
-h Dieser Hilfetext
-d der
eigentliche proxy-manager wird im Hintergrund gestartet
-o öffnet eine Verbindung für "ip-adresse" und
schließt sie
automatisch, wenn "zeitsekunden"
erreicht sind
-c schließt die Verbindung für
"ip-adresse" manuell
-a prüft, ob für
"ip-adresse" eine Verbindung besteht
-k beendet
den proxy-manager und löscht alle Verbindungen
-t tested, ob der proxy-manager im Hintergrund läuft
(siehe /var/run/proxy-manager.pid).
[login]
Der Benutzer, der eine Verbindung öffnet, etc. wird geloggt.
[ip-adresse]
Jede beliebige Form ist erlaubt:
Beispiel: 192.168.0.168
Es kann auch 'all' verwendet
werden.
[zeitsekunden]
Anzahl der vergangenen
Sekunden seit seit 00:00:00, Jan 1, 1970.
Zu ermitteln
z.B. durch "date +%s".
Hinweise:
Falls
Fehler beim Start des proxy-managers auftreten
sollten: die
Zugriffsrechte überprüfen:
/var/log/internet-freigabe
/var/state/internet-freigabe
proxy-manager 1.2 (2003-08-20)
(c) 2001 Thomas Bleher
<ThomasBleher@gmx.de>
(c) 2002,2003 Andreas Dangel
<adabolo@adabolo.de>
proxy-manager comes with
ABSOLUTELY NO WARRANTY.
This is free software, and you are
welcome to redistribute it
under certain conditions; see the
GNU GPL.
Im Firewall-Script wird der Proxymanager mit proxy-manager -d als Hintergrundprozess gestartet. Das ist nötig, denn das Internet kann immer nur für eine bestimmte Zeit freigeschaltet werden. Der Hintergrundprozess prüft jede Minute, ob für einen freigeschalteten Computer die Zeit abgelaufen ist und deaktiviert gegebenenfalls das Internet. Alle weiteren Parameter sind ja im Hilfetext erklärt. Das CGI-Programm, mit dem man das Internet letztendlich aktivieren kann, ruft ebenfalls den Proxymanager auf, z.B. mit proxy-manager -o andreas 192.168.0.140 1067188761. Daraufhin schreibt der Proxymanager in die Datei /var/state/internet-freigabe folgende Zeile:
192.168.0.140:1067188761
Der Hintergrundprozess überprüft dann, ob der angegbene Zeitpunkt vorbei ist und entfernt die Zeile gegebenenfalls wieder.
Damit der Proxyserver (squid, siehe 3.3.3. Proxy und Filter) unseren neuen Filter auch verwendet, muss die Datei /etc/squid.conf bearbeitet werden. Folgender Eintrag muss abgeändert werden:
redirect_program
/usr/local/sbin/squid-redirector
Mit /etc/init.d/squid restart wird unser neuer Filter verwendet.
Alle hier erwähnten Programme sind im Anhang zu finden.
Die Logdatei für den Proxymanager heißt /var/log/internet-freigabe. Hier wird mitgeloggt, wer das Internet jeweils freischaltet. Damit diese Datei nicht ins Unendliche anwächst, wird wieder logrotate konfiguriert: Die Datei /etc/logrotate.d/internet-freigabe muss mit folgendem Inhalt existieren:
/var/log/internet-freigabe {
rotate 7
weekly
compress
missingok
notifempty
}
Um den vebrauchten und den noch freien Festplattenplatz zu erfahren, wird df verwendet. df steht für "Disk free". Mit der Option "-h" werden die Angaben besser verständlich formatiert; es werden Angaben in MB und GB gemacht. Hier ein Beispielaufruf von df -h:
$ df -h
Filesystem Size Used Avail Use% Mounted on
/dev/md0 65G 24G 41G 37% /
/dev/md1 9.3G 237M 9.0G 3% /var
Wie lange der Server seit dem letzten Neustart schon läuft, erfährt man mit dem Befehl uptime:
$ uptime
12:46am up 3 days, 4:31, 0 users, load average: 0.00, 0.00, 0.00
Der Server läuft hier also seit 3 Tagen, 4 Stunden und 31 Minuten. Außerdem zu sehen ist die durchschnittliche Auslastung (load average). Ein Wert von 0 bedeutet, dass der Server überhaupt nicht ausgelastet ist.
Alle CGI-Scripte sind im Anhang zu finden. Beim Installieren ist zu beachten, dass die CGI-Scripte ausführbar sein müssen. Es müssen also gegebenenfalls die Attribute mit chmod 755 script.cgi angepasst werden.
Damit jeder Benutzer sein Passwort ändern kann, gibt es ein CGI-Script. Es ist mit dem Browser über den Webserver erreichbar. Das Script wird unter /usr/local/httpd/htdocs/passwd/index.cgi installiert.
Jeder Benutzer hat ja eine Mailadresse der Form: login@gm.rt.schule-bw.de. Alle Mails, die an diese Adresse geschickt werden, können auch an eine externe Mailadresse (z.B. gmx.de oder web.de) weitergeleitet werden. Mit dem CGI-Script, das unter /usr/local/httpd/htdocs/mail-config/index.cgi installiert wird, kann dies jeder Benutzer selber einrichten.
Mit diesem CGI-Script lassen sich die verschiedenen public-html-Verzeichnisse der Benutzer anschauen. Diese Verzeichnisse sind über die Adresse http://server/~login/ erreichbar. Das Script wird unter /usr/local/httpd/cgi-bin/benutzer installiert.
In der Schule verwenden wir Windows 98 SE als Client-Betriebssystem. Windows 98 besitzt noch einen DOS-Modus, sodass ältere DOS-Programme auch weiterhin benutzt werden können. Außerdem kann so der Linux-basierte Partitionsmanager verwendet werden, der die Partition sichert und bei Bedarf wieder zurückkopiert.
Zunächst
muss der Windows-Rechner ins Netzwerk eingebunden werden, d.h. er
muss eine passende IP-Adresse besitzen. Diese erhält er über
DHCP ("IP-Adresse
automatisch beziehen"). Zu dieser Option kommt man
über: Rechtsklick auf "Netzwerkumgebung"
und "Eigenschaften"
wählen. Dann im Register "Konfiguration"
Doppelklick auf "TCP/IP".
Hier ist die Option im Register "IP-Adresse"
zu finden.
Um
die Samba-Logdateien etwas übersichtlicher zu gestalten erhält
jeder Computer einen eindeutigen Namen im Windows-Netzwerk. Die
Bennenung erfolgt so: RXXX-PC#. "XXX"
steht für die Raum-Nummer, sie ist immer dreistellig (z.B.
R023). "#"
ist die Nummer des PCs im Raum. Die Rechner werden im Raum einfach
durchgezählt (Bsp. R023-PC2
oder R104-PC15). Zu
dieser Option kommt man über: Rechtsklick auf "Netzwerkumgebung"
und "Eigenschaften"
wählen. Dann zum Register "Identifikation"
wechseln. Hier den Computernamen eintragen. Die Arbeitsgruppe heißt
"workgroup".
Damit sich ein Benutzer beim Start von Windows
einloggen kann und damit das Passwort vom Linux-Server bestätigt
wird, ist auch eine spezielle Einstellung nötig. Zur dieser
Option kommt man über: Rechtsklick auf "Netzwerkumgebung"
und "Eigenschaften"
wählen. In diesem Dialog muss die "Primäre
Netzwerkanmeldung" auf "Client
für Microsoft-Netzwerke" stehen. Außerdem
muss dieser "Client für
Microsoft-Netzwerke" mit einem Doppelklick
konfiguriert werden. Im sich neu geöffneten Dialog wird "An
Windows NT-Domäne anmelden" aktiviert. Die
Windows NT-Domäne heißt "workgroup".
Bestimme Programme, wie z.B. StarOffice, bieten von sich aus eine Netzwerkinstallation an. Hier muss einfach als Installationspfad P:\Programmname gewählt werden. Meistens geht dies auch mit jedem anderen Programm, bei dem man den Installationspfad selber wählen kann. Eine etwas flexiblere Lösung ist die, dass man als Installationspfad //server/programme/Programmname wählt. Dann werden die Symbole (Icons) im Startmenü bzw. auf dem Desktop entsprechend erstellt und wenn sich der Benutzer unter Windows nicht einloggt, sondern "Abbrechen" drückt, dann kann er die Programme trotzdem mit Doppelklick starten.
Die Programme, die im Netzwerk verfügbar sein sollen, werden also unter //server/programme installiert. In dieser Freigabe hat jeder Benutzer alle Rechte, d.h. ein x-beliebiger Schüler könnte hier alles löschen. Es ist also dringend ein Backup dieser Freigabe zu empfehlen.
Der Partitionsmanager ist in Wirklichkeit ein Mini-Linux-System. Es wird mit dem Linuxloader LoadLin im DOS-Modus gestartet. Alle Programme sind auf einer Startbaren RAMDisk. Mit speziellen Argumenten, die man schon LoadLin mit auf den Weg gibt, kann die Partition z.B. vollautomatisch zurückgesichert werden. Das Programm, das die eigentliche Arbeit leistet, heißt partimage. Hier ein paar Aufruf-Beispiele:
C:\PARTIMG>
loadlin bzimage root=/dev/ram initrd=initrd.gz rw manual
Hier wird ein Interaktivmodus gestartet ("manual"). Man kann hier z.B. manuell eine Netzwerkverbindung aufbauen, etc.
C:\PARTIMG>
loadlin bzimage root=/dev/ram initrd=initrd.gz rw restore sicher.img
Hier wird das Image mit dem Dateinamen sicher.img zurückkopiert. Das Image liegt auf dem Laufwerk D: (unter Linux: /dev/hda5); das ist das erste logische Laufwerk. Zurückkopiert wird das Image auf das Laufwerk C: (/dev/hda1). Laufwerk C: wird also wiederhergestellt. Nach Abschluss des Vorgangs wird der Rechner automatisch neugestartet.
C:\PARTIMG>
loadlin bzimage root=/dev/ram initrd=initrd.gz rw store sicher.img
Mit diesem Befehl wird ein Image von Laufwerk C: erstellt. Es wird unter D:\SICHER.IMG gespeichert. Der Rechner wird danach ebenfalls neugestartet.
C:\PARTIMG>
loadlin bzimage root=/dev/ram initrd=initrd.gz rw update
http://192.168.0.1/images/sicher.img sicher.img
Dies ist ein Befehl und er muss in einer Zeile geschrieben werden. Das Image wird dann von der angegebenen URL heruntergeladen. Es wird dann auf den Rechner kopiert und auf dem Laufwerk D: gespeichert. Diese Funktion arbeitet möglicherweise nicht ganz ordnungsgemäß; ausprobieren. Als dritter Parameter muss der Dateiname des heruntergeladenen Images angegeben werden. Existiert das Image auf Laufwerk D: schon, wird es zuerst gelöscht und dann heruntergeladen.
Wenn ein Image schnell verteilt werden muss, dann kann im Netlogon-Script ein Befehl wie
copy \\server\pub\sicher.img
D:\SICHER.IMG
eingefügt werden. Anschließend muss man sich nur noch unter Windows anmelden und das Image wird auf den jeweiligen Rechner kopiert.
Um das Zurückspielen des Images, das auf Laufwerk D: liegt, kann der entsprechende Befehl in eine Stapel-Datei (Batch-Datei) geschrieben werden. Danach muss C:\CONFIG.SYS bearbeitet werden. (Die Datei ist möglicherweise schreibgeschützt und/oder versteckt.) Die Datei muss ungefähr folgenden Inhalt haben:
[menu]
menuitem=W98, Windows 98
starten
menuitem=PART, Image
zurückspielen
menudefault=W98,5
[W98]
DEVICE=C:\WINDOWS\setver.exe
device=C:\WINDOWS\COMMAND\display.sys
con=(ega,,1)
Country=049,850,C:\WINDOWS\COMMAND\country.sys
[PART]
shell=c:\command.com
/C C:\PARTIMG\RESTORE.BAT
[COMMON]
Damit erscheint bei jedem Windows-Start ein Menü ("Windows 98 Startmenü"). Wenn der Benutzer nach 5 Sekunden nichts ausgewählt hat, wird automatisch Windows gestartet. Wählt der Benutzer den Menüpunkt "Image zurückspielen" wird das Mini-Linux gestartet und der Computer wiederhergestellt.
Das Programm ist auf der CD zu finden.
Damit nicht jeder Benutzer in der Systemsteuerung herumspielt und etwas umstellt, wird diese deaktiviert. Das geschieht einfach mit einer Registrierungsdatei. So wird das Startmenü ein wenig kleiner und die Anzeige-Eigenschaften sind nicht mehr erreichbar. Es kann also kein Benutzer ein Bildschirmschonerpasswort setzen. Mit einer zweiten Registrierungsdatei können die Restriktionen wieder rückgängig gemacht werden. Die Registrierungsdateien können ganz bequem über einen Doppelklick eingelesen werden und sind nach einer Neuanmeldung aktiv.
Hier die Datei restrict.reg.
REGEDIT4
[HKEY_USERS\.DEFAULT\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer
"NoSetFolders"=dword:00000001
"NoSetTaskbar"=dword:00000001
"NoFolderOptions"=dword:00000001
"NoSetActiveDesktop"=dword:00000001
"NoWindowsUpdate"=dword:00000001
"NoRecentDocsMenu"=dword:00000001
"NoRecentDocsHistory"=dword:00000001
"ClearRecentDocsOnExit"=dword:00000001
"NoFavoritesMenu"=dword:00000001
"NoPrinterTabs"=dword:00000001
"NoDeletePrinter"=dword:00000001
"NoAddPrinter"=dword:00000001
"NoSaveSettings"=dword:00000001
[HKEY_USERS\.DEFAULT\Software\Microsoft\Windows\CurrentVersion\Winlogon]
"DontDisplayLastUserName"=dword:00000001
[HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\Network]
"DisablePwdCaching"=dword:00000001
[HKEY_USERS\.DEFAULT\Software\Microsoft\Windows\CurrentVersion\Policies\Network]
"HideSharePwds"=dword:00000001
"DisablePwdCaching"=dword:00000001
"NoNetSetup"=dword:00000001
"NoNetSetupIDPage"=dword:00000001
"NoNetSetupSecurityPage"=dword:00000001
[HKEY_USERS\.DEFAULT\Software\Microsoft\Windows\CurrentVersion\Policies\System]
"DisableRegistryTools"=dword:00000001
"NoDispCPL"=dword:00000001
"NoDispBackgroundPage"=dword:00000001
"NoDispScrSavPage"=dword:00000001
"NoDispAppearancePage"=dword:00000001
"NoDispSettingsPage"=dword:00000001
"NoProfilePage"=dword:00000001
"NoSecCPL"=dword:00000001
"NoPwdPage"=dword:00000001
"NoAdminPage"=dword:00000001
"NoProfilePage"=dword:00000001
"NoDevMgrPage"=dword:00000001
"NoConfigPage"=dword:00000001
"NoFileSysPage"=dword:00000001
"NoVirtMemPage"=dword:00000001
[HKEY_USERS\.DEFAULT\Software\Microsoft\Windows\CurrentVersion\Explorer\User
Shell
Folders]
"Personal"="H:\"
Hier die Datei unrestrict.reg.
REGEDIT4
[HKEY_USERS\.DEFAULT\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer
"NoSetFolders"=dword:00000000
"NoSetTaskbar"=dword:00000000
"NoFolderOptions"=dword:00000000
"NoSetActiveDesktop"=dword:00000000
"NoWindowsUpdate"=dword:00000000
"NoRecentDocsMenu"=dword:00000000
"NoRecentDocsHistory"=dword:00000001
"ClearRecentDocsOnExit"=dword:00000001
"NoFavoritesMenu"=dword:00000000
"NoPrinterTabs"=dword:00000000
"NoDeletePrinter"=dword:00000000
"NoAddPrinter"=dword:00000000
"NoSaveSettings"=dword:00000001
[HKEY_USERS\.DEFAULT\Software\Microsoft\Windows\CurrentVersion\Winlogon]
"DontDisplayLastUserName"=dword:00000001
[HKEY_USERS\.DEFAULT\Software\Microsoft\Windows\CurrentVersion\Policies\Network]
"HideSharePwds"=dword:0000001
"DisablePwdCaching"=dword:00000001
"NoNetSetup"=dword:00000000
"NoNetSetupIDPage"=dword:00000000
"NoNetSetupSecurityPage"=dword:00000000
[HKEY_USERS\.DEFAULT\Software\Microsoft\Windows\CurrentVersion\Policies\System]
"DisableRegistryTools"=dword:00000000
"NoDispCPL"=dword:00000000
"NoDispBackgroundPage"=dword:00000000
"NoDispScrSavPage"=dword:00000000
"NoDispAppearancePage"=dword:00000000
"NoDispSettingsPage"=dword:00000000
"NoProfilePage"=dword:00000000
"NoSecCPL"=dword:00000000
"NoPwdPage"=dword:00000000
"NoAdminPage"=dword:00000000
"NoProfilePage"=dword:00000000
"NoDevMgrPage"=dword:00000000
"NoConfigPage"=dword:00000000
"NoFileSysPage"=dword:0000000
"NoVirtMemPage"=dword:00000000
[HKEY_USERS\.DEFAULT\Software\Microsoft\Windows\CurrentVersion\Explorer\User
Shell
Folders]
"Personal"="H:\"
Außerdem werden hier kleinere Feineinstellungen an Windows vorgenommen. So wird z.B. das Verzeichnis "Eigene Dateien" so konfiguriert, dass es auf das Homeverzeichnis (H:\) auf Samba zeigt. Da wird Windows so eingestellt, dass es beim Login-Dialog den Namen des vorigen Benutzers löscht. Außerdem wird der Passwort-Cache deaktiviert. Ist diese Funktion aktiv, dann speichert Windows in C:\WINDOWS für jeden Benutzer eine PWL-Datei, in der das Passwort gespeichert ist. Mit ein paar Hilfsprogrammen aus dem Internet kann mit dieser Datei das Passwort rekonstruiert werden.
Nachdem linux hochgefahren ist, erscheint ein Text-basierter Login-Bildschirm:
Debian GNU/Linux 3.0 server
tty1
server login:
Hier kann man dann seinen Benutzernamen eingeben. Danach wird nach dem Passwort verlangt. Ist man eingeloggt, sieht der Bildschirm ungefähr so aus:
Last login: Sun Nov 9 09:35:49
2003 on tty1
Linux server 2.4.22 #1 Sun Aug 17 16:51:06 CEST 2003
i686 unkown
Most of the programs included with the Debian
GNU/Linux system are
freely redistributable; the exact
distribution terms for each program
are described in the
individual files in /usr/share/doc/*/copyright
Debian
GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted
by applicable law.
You have mail.
andreas@server:~$
Die letzte Zeile ist die Eingabeaufforderung. Hier können jetzt Befehle eingegeben werden.
Will man sich wieder ausloggen, so muss man den Befehl logout ausführen. Es erscheint dann wieder der Login-Bildschirm.
Linux herunterfahren kann nur der Superuser. Man muss also als Benutzer root eingeloggt sein. Jetzt kann man mit init 0 oder halt Linux sofort herunterfahren. Mit shutdown -h +15 fährt Linux in 15 Minuten herunter.
Will man Linux neustarten, so muss man init 6 bzw. reboot ausführen. Auch mit Shutdown geht das Neustarten: shutdown -r +15 startet Linux in 15 Minuten neu.
Mit dem Befehl ls werden Dateien aufgelistet (ls = LiSt). Dieser Befehl entspricht dem DOS-Befehl dir. Mit bestimmten Parametern kann die Ausgabe variiert werden: ls -l gibt eine detailreichere Liste aus (-l für long). Dabei gibt der Befehl zunächst mal das aktuelle Verzeichnis aus. Will man ein anderes Verzeichnis sehen, muss man z.B. ls /home aufrufen. Hier ein paar Beispiele:
$ ls
CD-ROOT source
CD-ROOT-Inhalt.txt source-20031015-214838.tar.bz2
Makefile source-20031016-214533.tar.bz2
archiv1.tar.bz2 source-20031018-120615.tar.bz2
html source-20031018-150309.tar.bz2
passw?rter.out source-20031018-184430.tar.bz2
passw?rter.pdf source-20031020-191948.tar.bz2
server-docu-sicherung.pdf source-20031021-183556.tar.bz2
server-docu-sicherung.ps source-20031023-191929.tar.bz2
[...]
$ ls -l
total
7944
drwxr-xr-x 3 andreas andreas 4096 Aug 18 19:48
CD-ROOT
-rw-r--r-- 1 andreas andreas 3081 Aug 19 16:03
CD-ROOT-Inhalt.txt
-rw-r--r-- 1 andreas andreas 411 Oct
21 18:05 Makefile
-rw-r--r-- 1 andreas andreas 7079 Aug 19
14:55 archiv1.tar.bz2
drwxr-xr-x 3 andreas andreas 8192
Nov 8 20:25 html
-rw-r--r-- 1 andreas andreas 0 Sep 3
22:14 passw?rter.out
-rw-r--r-- 1 andreas andreas 7940 Sep 3 22:14 passw?rter.pdf
-rw-r--r-- 1 andreas andreas 214374
Oct 15 21:02 server-docu-sicherung.pdf
-rw-r--r-- 1 andreas
andreas 9991 Oct 15 21:48 source-20031015-214838.tar.bz2
[...]
$
ls /home
andreas ftp samba
Die erste Spalte in der Ausgabe von ls -l zeigt die Rechte an: Das erste Zeichen stellt den Typ das ("-" ist eine normale Datei, "d" ein Verzeichnis). Die nächsten drei Zeichen stellen die Rechte für den Besitzer der Datei/des Verzeichnisses dar. "r" heißt Leserecht, "w" Schreibrecht und "x" Ausführrecht. Die folgenden drei Zeichen stellen die Rechte für die Gruppe dar, der diese Datei gehört. Die letzten drei Zeichen sind die Rechte, die jeder andere Benutzer des Systems an der Datei hat.
In der dritten Spalte steht der Besitzer und in der vierten Spalte die Gruppe. In der fünften Spalte steht die Größe der Datei in Bytes. Danach kommt das Datum der letzten Änderung und schließlich der Dateiname.
Mit touch dateiname kann eine leere, 0-Bytes-große Datei erstellt werden. Ein Verzeichnis erstellt man mit mkdir verzeichnisname.
Das aktuelle Verzeichnis erfährt man mit pwd (Print Working Directory). Mit cd neues_verzeichnis wechselt man das aktuelle Arbeitsverzeichnis.
Mit rm dateiname wird eine Datei gelöscht. Ein leeres Verzeichnis kann man mit rmdir verzeichnis löschen. Ist das Verzeichnis noch nicht leer, kann das Verzeichnis mit dem ganzen Inhalt gelöscht werden: rm -r verzeichnis.
Hinweis: Gelöschte Dateien sind in der Regel nicht mehr wiederherstellbar!
Mit cp quelle ziel kann man Dateien kopieren. Der Befehl funktioniert wie der DOS-Befehl "copy". Wird als Quelle eine Datei angegeben, so kann das Ziel ebenfalls eine Datei sein oder ein Verzeichnis, in das die Datei hineinkopiert werden soll. Ist die Quelle ein Verzeichnis, so kann das Ziel auch nur ein Verzeichnis sein, in welches dann das Quellverzeichnis hineinkopiert wird.
Hinweis: Vorhandene Dateien werden ohne Nachfrage überschrieben!
Mit mv quelle ziel kann man Dateien verschieben. Der Befehl funktioniert wie der DOS-Befehl "move". Quelle und Ziel können wie beim "cp"-Befehl entweder Dateien sein oder Verzeichnisse.
Auch hier werden vorhandene Dateien ohne Nachfrage überschrieben.
Mit less textdatei kann man eine Textdatei (z.B. ein Konfigurationsdatei) bequem anschauen. Mit den Cursor-Tasten scrollt man durch den Text. Mit einem Tastendruck auf "q" verlässt man den Datei-Anzeiger.
Die Benutzer unter Linux werden in einer Datenbank verwaltet. Diese Datenbank besteht aus mehreren Textdateien: In /etc/passwd stehen die Benutzer, deren Homeverzeichnisse, die jeweilige Shell. Die dazugehörigen Passwörter stehen in der Datei /etc/shadow. Sie sind verschlüsselt. Mit dem Befehl mkpasswd lassen sich solche verschlüsselten Passwörter von Hand herstellen. In /etc/group stehen die Gruppen, die es gibt. In /etc/gshadow stehen Passwörter für die einzelnen Gruppen; diese Datei wird in der Regel nicht benötigt. Mit dem Befehl vipw lässt sich /etc/passwd bearbeiten. Mit vigr lässt sich /etc/group bearbeiten. Allerdings muss man dazu das Dateiformat kennen.
Um einen neuen Benutzer anzulegen, verwendet man den Befehl useradd. useradd neuer_user legt beispielsweise den Benutzer neuer_user an. useradd --help gibt Auskunft über die verschiedenen Argumente, die man dem Befehl geben kann. Nachdem der Benutzer mit diesem Befehl angelegt wurde, muss noch das Homeverzeichnis unterhalb von /home/ erstellt werden. Außerdem sollte mit passwd neuer_user noch ein Passwort gesetzt werden.
Ein vorhandener Benutzer wird mit usermod bearbeitet. Mit usermod -s /bin/bash user erhält der Benutzer user als Shell /bin/bash. usermod --help gibt auch hier wieder Auskunft über die verschiedenen Argumente.
Mit userdel user wird der Benutzer user gelöscht. Sein Homeverzeichnis bleibt erhalten. Mit userdel -r user wird auch sein Homeverzeichnis gelöscht. Es gibt keine Möglichkeit, die Daten wiederherzustellen!
Um eine neue Gruppe anzulegen, wird der Befehl groupadd gruppe verwendet.
Mit groupdel gruppe wird die Gruppe gruppe gelöscht.
Hierzu steht schon einiges unter 2.8.1. apt-get verwenden.
Da unter Linux fast alle Konfigurationsdateien Textdateien sind, sollte man wenigstens einen Texteditor beherrschen. In diesem Abschnitt wird der Texteditor vim vorgestellt. Er ist ganz anders als ein Editor aus der Windows- bzw. DOS-Welt zu bedienen, aber vim ist sehr verbreitet.
Um die Datei /etc/hosts zu bearbeiten, wird einfach vim /etc/hosts ausgeführt. Die Datei wird dann geöffnet. Existiert die angegebene Datei nicht, dann wird sie erstellt. So lassen sich also auch neue Dateien erstellen.
Nach dem Öffnen muss man vim erstmal in den Editiermodus umschalten. Das geht einfach, indem man die Taste "i" drückt. In der untersten Zeile steht dann "-- INSERT --". Jetzt kann man wie gewohnt den Text eingeben. Die Tasten "Pos1", "Ende", "Einfg" und "Entf" funktionieren wie erwartet. Ist man mit dem Editieren fertig, verlässt man den Editiermodus mit der "Esc"-Taste. Die letzte Zeile wird wieder leer. Jetzt muss man einfach ":w" eingeben und mit der Eingabetaste bestätigen. In der letzten Zeile wird der Befehl übrigens angezeigt. Will man den Editor beenden, gibt man ":q" und Eingabetaste ein. Speichern und gleichzeitiges Beenden geht mit ":x" und Eingabetaste.
Mit ps awx erfährt man, welche Prozesse im Moment laufen. Außerdem wird die Prozess-ID (PID) angezeigt. Mit kill $PID kann man den Prozess mit der Nummer $PID beenden. Funktioniert das nicht, hilft vielleicht kill -9 $PID weiter.
Zu fast jedem Befehl gibt es unter Linux eine Handbuchseite (Manual Page). Diese Seite lässt sich mit man befehl ansehen. Manchmal ist auch info befehl aufschlussreicher.
Außerdem bietet fast jeder Befehl selber eine kleine Hilfestellung an. Diese erhält man mit dem Argument "--help" oder "-h": befehl --help.
Unter /usr/share/doc/ gibt es für jeden Programmpaket ein Unterverzeichnis. In diesem Verzeichnis ist manchmal auch eine Dokumentation enthalten.
Im Internet unter http://www.tldp.org gibt es u.a. auch sogenannte HOWTOs. Das sind Kurzanleitungen, die einen ganz bestimmten Themenbereich erklären. Meistens sind es praxisnahe Anleitungen.
Es ist unter /usr/local/sbin/firewall zu finden.
#!/bin/sh
#
#
/etc/init.d/firewall -> /usr/local/sbin/firewall
#
/etc/rc[2345].d/S10firewall -> ../init.d/firewall
#
#
Tool iptables vorhanden?
iptables=/sbin/iptables
test -x
$iptables || exit 5
# ip_tables-Modul laden
modprobe ip_tables
|| exit
5
##############################################################
#
FUNKTIONEN
##############################################################
function
firewall_config() {
# 1. Interfaces
# extern ->
Internet
ext_int="ppp+" ## nicht eth1, das wird
quasi nicht verwendet...
# intern -> Intranet
int_int="eth0"
# loopback
lo_int="lo"
# 2. IP-Adressen
# server externe adresse
server_ext="0/0" # ist egal, s.o.: auf ppp+ kommen nur
pakete an,
# die für den comp. bestimmt
sind
# server interne adresse
server_int="192.168.0.1"
# intranet adress-bereich
lan="192.168.0.0/24"
# 3. Ports
# alle privilegierten ports
priv_ports="0:1023"
# alle unprivilegierten ports
unpriv_ports="1024:65535"
}
function
firewall_init() {
# Alle regeln und chains löschen
$iptables -F
$iptables -t nat -F
$iptables -X
# default policy
$iptables -P INPUT DROP
$iptables -P
FORWARD DROP
$iptables -P OUTPUT ACCEPT
# loopback
interface aktivieren
$iptables -A INPUT -i $lo_int -j ACCEPT
# Schutz vor SYN Flooding
for f in
/proc/sys/net/ipv4/conf/*/rp_filter; do
echo "1"
> $f
done
# IP Forwarding deaktivieren
echo "0" > /proc/sys/net/ipv4/ip_forward
#
chains
$iptables -N intranet
$iptables -N internet
# spezielle regeln:
# spezielles dhcp-broadcast-paket
$iptables -A INPUT -i $int_int -d 255.255.255.255 -p udp --dport
67 -j ACCEPT
# spezielles
smb-broadcast-paket...nötig??
$iptables -A INPUT -i
$int_int -d 192.168.0.255 -p udp --sport 138 –dport 138 -j
ACCEPT
$iptables -A INPUT -i $int_int -d 192.168.0.255 -p udp
--sport 137 –dport 137 -j ACCEPT
$iptables -A INPUT -i
$int_int -d 192.168.0.255 -p udp --dport 138 -j ACCEPT
$iptables -A INPUT -i $int_int -d 255.255.255.255 -p udp --dport 138
–sport 138 -j ACCEPT
# allgemeine regeln mit
userdefined chains
$iptables -A INPUT -i $int_int -s $lan -d
$server_int -j intranet
$iptables -A INPUT -i $ext_int -j
internet
# erlaube ankommende Pakete von bestehenden
Verbindungen
$iptables -A INPUT -p tcp -m state --state
ESTABLISHED -j ACCEPT
$iptables -A INPUT -p udp -m state
--state ESTABLISHED -j ACCEPT
# logging:
$iptables
-A INPUT -j LOG --log-prefix "firewall: " -m
limit
}
function firewall_intranet () {
#leere chain
intranet
$iptables -F intranet
# icmp pakete in
# see /usr/include/netinet/ip_icmp.h
$iptables -A intranet
-p icmp --icmp-type 0 -j ACCEPT
$iptables -A intranet -p icmp
--icmp-type 3 -j ACCEPT
$iptables -A intranet -p icmp
--icmp-type 4 -j ACCEPT
$iptables -A intranet -p icmp
--icmp-type 8 -j ACCEPT
$iptables -A intranet -p icmp
--icmp-type 12 -j ACCEPT
# erlaube ssh (tcp,1222) in
$iptables -A intranet -p tcp --sport $unpriv_ports --dport 1222 -j
ACCEPT
# erlaube smtp (tcp,25) in
$iptables -A intranet
-p tcp --sport $unpriv_ports --dport 25 -j ACCEPT
# erlaube
domain (udp,53) in
$iptables -A intranet -p udp --sport
$unpriv_ports --dport 53 -j ACCEPT
# erlaube dhcp (udp,67/68)
in
$iptables -A intranet -p udp --sport $unpriv_ports --dport
67 -j ACCEPT
$iptables -A intranet -p udp --sport 68 --dport
67 -j ACCEPT
# erlaube httpd (tcp,80) in
$iptables -A
intranet -p tcp --sport $unpriv_ports --dport 80 -j ACCEPT
#
erlaube pop3 (tcp,110) in
$iptables -A intranet -p tcp --sport
$unpriv_ports --dport 110 -j ACCEPT
# erlaube smb
(tcp/udp,137:139) in
$iptables -A intranet -p udp --sport 137
--dport 137 -j ACCEPT
$iptables -A intranet -p udp --sport 138
--dport 138 -j ACCEPT
$iptables -A intranet -p tcp --sport
$unpriv_ports --dport 139 -j ACCEPT
# erlaube swat (tcp/901)
in
$iptables -A intranet -p tcp --sport $unpriv_ports --dport
901 -j ACCEPT
# reject smb (tcp/445) in
$iptables -A
intranet -p tcp --dport 445 -j REJECT
# webmin (tcp/10000) in
$iptables -A intranet -p tcp --dport 10000 -j ACCEPT
### proxy – internet-freigabe
$iptables -A intranet -p
tcp --sport $unpriv_ports --dport 3128 -j ACCEPT
#
proxy-manager aufrufen
/usr/local/sbin/proxy-manager -d
# transparent proxy (nur für http)
$iptables -t nat -A
PREROUTING -i eth0 -p tcp -d ! $server_int --dport 80 -j
REDIRECT
--to-port 3128
}
function firewall_internet () {
#
leere chain internet
$iptables -F internet
#
richtige adresse? -- prüfung entfällt (s.o.), da nur pakete
ankommen,
# die auch für dem comp.
bestimmt sind.
#$iptables -A internet -d ! $server_ext -j
RETURN
### provided services! in
# icmp pakete in
$iptables -A internet -p icmp -d $server_ext --icmp-type 0 -j
ACCEPT
$iptables -A internet -p icmp -d $server_ext
--icmp-type 3 -j ACCEPT
$iptables -A internet -p icmp -d
$server_ext --icmp-type 4 -j ACCEPT
$iptables -A internet -p
icmp -d $server_ext --icmp-type 8 -j ACCEPT
$iptables -A
internet -p icmp -d $server_ext --icmp-type 12 -j ACCEPT
#
erlaube ssh (tcp,1222) in
$iptables -A internet -p tcp -d
$server_ext --dport 1222 –sport
$unpriv_ports -j ACCEPT
# erlaube http (tcp,80) in
#$iptables -A internet -p tcp -d
$server_ext --dport 80 –sport
$unpriv_ports -j
ACCEPT
}
function firewall_stop () {
# proxy-manager
beenden
/usr/local/sbin/proxy-manager -k
# alle
chains leeren
$iptables -F
$iptables -t nat -F
#
alle userdefined chains löschen
$iptables -X
#
default policies
$iptables -P INPUT ACCEPT
$iptables -P
OUTPUT ACCEPT
$iptables -P FORWARD
ACCEPT
}
##############################################################
runfile=/var/run/firewall
case
"$1" in
start)
if [ -e $runfile ]; then
echo "Firewall already running..."
echo "see: $runfile"
exit 1;
fi
echo "Starting firewall..."
firewall_config
echo "config: ext_int: $ext_int"
echo " int_int: $int_int"
echo " server_ext: $server_ext"
echo " server_int: $server_int"
firewall_init
firewall_intranet
firewall_internet
touch
$runfile
echo "...done"
;;
stop)
if [ ! -e $runfile ]; then
echo
"Firewall is not running..."
exit 1;
fi
echo -n "Stopping firewall..."
firewall_stop
rm $runfile
echo "done"
;;
restart)
$0 stop
$0 start
;;
status)
/usr/local/sbin/proxy-manager -t
echo -n "Checking for firewall..."
if [
-e $runfile ]; then
echo "running"
else
echo "not running!"
fi
;;
*)
echo "Usage: $0
{start|stop|status|restart}"
exit 1
;;
esac
exit 0
Der Proxy-Manager verwaltet die Internet-Freigaben und wird vom Firewall-Script aus gestartet.
Dateiname: /usr/local/sbin/proxy-manager.
#!/usr/bin/perl -w
#
#
/usr/local/sbin/proxy-manager
#
# proxy-manager Programm zum
Verwalten der Internetfreigaben
#
# (c) 2001 Thomas Bleher
<ThomasBleher@gmx.de>
# (c) 2002,2003 Andreas Dangel
<adabolo@adabolo.de>
#
# This program is free software;
you can redistribute it and/or modify
# it under the terms of the
GNU General Public License as published by
# the Free Software
Foundation; either version 2 of the License, or
# (at your option)
any later version.
#
# This program is distributed in the hope
that it will be useful,
# but WITHOUT ANY WARRANTY; without even
the implied warranty of
# MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the
# GNU General Public License for more
details.
#
# You should have received a copy of the GNU
General Public License
# along with this program; if not, write to
the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
#
use Fcntl; # for
sysopen, file modes
use Fcntl qw(:flock);
use strict;
##
Konfiguration
my $version = "1.2 (2003-08-21)";
my
$pidfile = '/var/run/proxy-manager.pid';
my $logfile =
'/var/log/internet-freigabe';
my $iptables = '/sbin/iptables';
my
$actives = '/var/state/internet-freigabe';
my $lockfile =
'/var/lock/proxy-manager.lck';
my $lockfile2 =
'/var/lock/proxy-manager2.lck';
my
$pid;
#########################
##### SUBPROCEDURES
#####
#########################
sub usage() {
print
<<EOF;
Syntax: $0 [-hdocak] [login] [ip-adresse]
[zeitsekunden]
-h Dieser Hilfetext
-d der
eigentliche proxy-manager wird im Hintergrund gestartet
-o öffnet eine Verbindung für "ip-adresse" und
schließt sie
automatisch, wenn "zeitsekunden"
erreicht sind
-c schließt die Verbindung für
"ip-adresse" manuell
-a prüft, ob für
"ip-adresse" eine Verbindung besteht
-k beendet
den proxy-manager und löscht alle Verbindungen
-t tested, ob der proxy-manager im Hintergrund läuft
(siehe /var/run/proxy-manager.pid).
[login]
Der Benutzer, der eine Verbindung öffnet, etc. wird geloggt.
[ip-adresse]
Jede beliebige Form ist erlaubt:
Beispiel: 192.168.0.168
Es kann auch 'all' verwendet
werden.
[zeitsekunden]
Anzahl der vergangenen
Sekunden seit seit 00:00:00, Jan 1, 1970.
Zu ermitteln
z.B. durch "date +%s".
Hinweise:
Falls
Fehler beim Start des proxy-managers auftreten
sollten: die
Zugriffsrechte überprüfen:
$logfile
$actives
proxy-manager $version
(c) 2001 Thomas
Bleher <ThomasBleher\@gmx.de>
(c) 2002,2003 Andreas
Dangel <adabolo\@adabolo.de>
proxy-manager comes
with ABSOLUTELY NO WARRANTY.
This is free software, and you
are welcome to redistribute it
under certain conditions; see
the GNU GPL.
EOF
exit;
}
sub log() {
my $data = shift;
chomp($data);
my $datum =
localtime(time);
open(S, ">>$lockfile");
flock(S, LOCK_EX);
open(LOG, ">>$logfile");
print LOG "$datum: $data\n";
close(LOG);
close(S);
}
sub open_proxy() {
&log("open_proxy()");
}
sub close_proxy() {
&log("close_proxy()");
}
sub
kill_proxymanager() {
&close_proxy();
unlink
$actives;
system("touch $actives");
unlink($pidfile);
exit;
}
sub open_connection()
{
my $login;
my $ip;
my $time;
if (not
(($login, $ip, $time) = @_)) {
&log("open_connection():
missing arguments!");
return;
}
if ($ip
=~ /[^\w.]/) {
&log("open_connection(): invalid
argument! $ip");
return;
}
&log("open_connection(): $login: $ip, $time");
&add_actives($ip, $time);
}
sub active_connection()
{
my $ip;
if (not ($ip = shift)) {
&log("active_connection(): missing arguments!");
return;
}
if ($ip =~ /[^\w.]/) {
&log("active_connection(): invalid argument! $ip");
return;
}
return
&find_actives($ip);
}
sub close_connection() {
my $ip;
if (not ($ip = shift)) {
&log("close_connection(): missing arguments!");
return;
}
if ($ip =~ /[^\w.]/) {
&log("close_connection(): invalid argument! $ip");
return;
}
&log("close_connection()
for $ip");
&remove_actives($ip);
}
sub
check_daemon() {
if (-e $pidfile) {
return 0;
}
return 1;
}
sub start_daemon() {
if (not
defined($pid = fork)) {
die "Couldn't fork!";
}
if ($pid) { #parent
exit;
} else { #child
sysopen(PIDFILE, $pidfile, O_WRONLY | O_CREAT |
O_EXCL) || die "Instance
of proxy-manager already running!
See $pidfile";
print PIDFILE $$;
close
PIDFILE;
while(1) {
sleep(60);
my $time = time;
&remove_actives_by_time($time);
}
}
}
sub
add_actives() {
my $ip = shift;
my $time = shift;
open(S, ">>$lockfile2");
flock(S,
LOCK_EX);
open(FILE, "<$actives");
my
@data = <FILE>;
close(FILE);
push @data,
"$ip:$time";
open(FILE, ">$actives");
print FILE join("\n", @data);
close(FILE);
close(S);
}
sub find_actives() {
my $ip =
shift;
#&log("find_actives() for $ip");
open(S, ">>$lockfile2");
flock(S,
LOCK_EX);
open(FILE, "<$actives");
my
@data = <FILE>;
close(FILE);
my @found =
grep(/$ip/, @data);
my @found2 = grep(/all/, @data);
push(@found, @found2);
close(S);
if (@found != 0)
{
my @fields = split(/:/, $found[0]);
return
$fields[0];
}
return;
}
sub
remove_actives() {
my $ip = shift;
open(S,
">>$lockfile2");
flock(S, LOCK_EX);
open(FILE, "<$actives");
my @data = <FILE>;
close(FILE);
my @data_new = grep(!/$ip/, @data);
open(FILE, ">$actives");
print FILE join("\n",
@data_new);
close(FILE);
close(S);
}
sub
remove_actives_by_time() {
my $time = shift;
open(S, ">>$lockfile2");
flock(S, LOCK_EX);
open(FILE, "<$actives");
my @data = <FILE>;
close(FILE);
my @data_new;
my $line;
while ($line = shift @data) {
chomp($line);
my
@fields = split(/:/, $line);
my $time2 = $fields[1];
if ($time >= $time2) {
# nicht mehr hinzufügen
&log("remove_actives_by_time: $fields[0]");
} else {
push(@data_new, $line);
}
}
open(FILE, ">$actives");
print FILE
join("\n",@data_new);
close(FILE);
close(S);
}
sub handler {
my $sig = shift;
&log("Caught SIG$sig...");
&kill_proxymanager();
exit 0;
}
$SIG{'TERM'} =
\&handler;
########################
##### MAIN PROGRAM
#####
########################
# Argumente prüfen
if
(@ARGV < 1) {
&usage();
}
if ($ARGV[0] eq
"-h") {
&usage();
}
if
($ARGV[0] eq "-d") {
die "Instance of
proxy-manager already running! see $pidfile" if
(&check_daemon()
== 0);
&open_proxy();
&start_daemon();
}
elsif ($ARGV[0] eq "-o") {
die "missing
arguments! try \"$0 -h\"" if (@ARGV != 4);
if (&check_daemon() == 1) {
die "no instance of
proxy-manager running! see \"$0 -h\"";
}
&open_connection($ARGV[1], $ARGV[2], $ARGV[3]);
} elsif
($ARGV[0] eq "-c") {
die "missing arguments!
try \"$0 -h\"" if (@ARGV != 2);
if
(&check_daemon() == 1) {
die "no instance of
proxy-manager running! see \"$0 -h\"";
}
&close_connection($ARGV[1]);
} elsif ($ARGV[0] eq "-a")
{
die "missing arguments! try \"$0 -h\""
if (@ARGV != 2);
if (&check_daemon() == 1) {
die "no instance of proxy-manager running! see \"$0
-h\"";
}
if (my $ret =
&active_connection($ARGV[1])) {
print $ret;
}
} elsif ($ARGV[0] eq "-k") {
if
(&check_daemon() == 1) {
die "no instance of
proxy-manager running! see \"$0 -h\"";
}
# sending SIGTERM(15)
my $opid = `cat $pidfile`;
kill 15, $opid;
#&kill_proxymanager();
}
elsif ($ARGV[0] eq "-t") {
if (&check_daemon()
== 0) {
print "Der proxy-manager läuft...\n";
exit 0;
} else {
print "Der
proxy-manager läuft nicht...\n";
exit 1;
}
} else {
&usage();
}
exit;
Dateiname: /usr/local/sbin/squid-redirector.
#!/usr/bin/perl
use
FileHandle;
use IPC::Open2;
use Fcntl qw(:flock);
$|=1;
##
Konfiguration
my $squidGuard = "/usr/bin/squidGuard";
my
$proxymanager = "/usr/local/sbin/proxy-manager";
my
$redirecturl = "http://server/cgi-bin/inactive.cgi";
my
$logfile = "/var/log/squid/squid-redirector";
my
$pid = open2(*Reader, *Writer, $squidGuard);
&log("[$$,$pid]
started");
while (<>) {
my $request = $_;
my @fields = split / /, $request;
my @fields2 = split /\//,
$fields[1];
my $ip = $fields2[0];
chomp($request);
chomp($ip);
#&log("request: $request ($ip)");
print &check_ip($ip, $request) .
"\n";
}
&log("[$$,$pid] stopped");
exit
0;
sub log {
my $msg = shift;
my $date =
localtime(time);
chomp($msg);
system("echo \"$date
$msg\" >> $logfile");
}
sub check_ip {
my $ip = shift;
my $request = shift;
if ($ip eq
"127.0.0.1") {
return;
}
my $active
= `$proxymanager -a $ip`;
#&log("proxymanager:
$active");
if ($active eq "") {
return "$redirecturl";
}
print Writer
"$request\n";
my $response = <Reader>;
chomp($response);
return $response;
}
Das ist das Front-End zum proxy-manager. Damit kann man das Internet freischalten usw.
Dateiname: /usr/local/httpd/htdocs/internet/index.cgi.
#!/usr/bin/perl -w
#
#
/usr/local/httpd/internet/index.cgi
#
# browser-frontend für
proxy-manager
#
# (c) 2001 Thomas Bleher
<ThomasBleher@gmx.de>
# (c) 2002 Andreas Dangel
#
#
This program is free software; you can redistribute it and/or
modify
# it under the terms of the GNU General Public License as
published by
# the Free Software Foundation; either version 2 of
the License, or
# (at your option) any later version.
#
#
This program is distributed in the hope that it will be useful,
#
but WITHOUT ANY WARRANTY; without even the implied warranty of
#
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
#
GNU General Public License for more details.
#
# You should
have received a copy of the GNU General Public License
# along
with this program; if not, write to the Free Software
#
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
use strict;
use CGI;
my $q = new CGI;
my
$login;
my $user;
my $lehrer;
my $ip;
my $welche;
my
$dauer;
my $status1;
my $status2;
my $status3;
$login
= $q->remote_user;
if (not $user = (getpwnam($login))[6]) {
die "Unauthorized access to internet/index.cgi! Username:
$login";
}
$lehrer = ((getgrnam('lehrer'))[3] =~
/\b\Q$login\E\b/);
$ip = $ENV{REMOTE_ADDR} or die "No
REMOTE_ADDR!";
if ($q->param()) {
if
($q->param('aktivieren')) {
if ($lehrer) {
if ($q->param('welche') eq 'alle') {
$welche
= 'all';
} else {
$welche = $ip;
}
} else {
$welche = $ip;
}
$dauer = $q->param('dauer');
$dauer += 0; # In Zahl umwandeln
if (($dauer < 1) or
($dauer > 180)) {
$dauer = 45;
}
$dauer *= 60;
$dauer += time;
system("/usr/bin/sudo /usr/local/sbin/proxy-manager -o $login
$welche $dauer"); # IPs freischalten
} elsif
($q->param('deaktivieren')) {
if ($lehrer) {
if ($q->param('welche') eq 'alle') {
$welche = 'all';
} else {
$welche =
$ip;
}
} else {
$welche =
$ip;
}
system("/usr/bin/sudo
/usr/local/sbin/proxy-manager -c $welche");
}
} else
{
# keine Parameter gegeben:
}
$status1 =
`/usr/bin/sudo /usr/local/sbin/proxy-manager -a $ip`;
$status2 =
`/usr/bin/sudo /usr/local/sbin/proxy-manager -a all`;
`/usr/bin/sudo
/usr/local/sbin/firewall status > /dev/null 2>&1`;
$status3
= $?;
#######################
##### AUSGABEN
########
#######################
print $q->header;
if
( $status3 != "0" ) {
print
$q->start_html( -title=>'Internet-Einwahl - Internet
aktiviert',
-author=>'webmaster@gm.rt.schule-bw.de'),
$q->h1('Internet-Einwahl - Internet aktiviert'),
"Da
die Firewall deaktiviert ist, ist das Internet
<strong>immer</strong>
und für <strong>jeden</strong> Computer
aktiviert!!";
} elsif ($status1 eq $ip) {
print
$q->start_html( -title=>'Internet-Einwahl - Internet
aktiviert',
-author=>'webmaster@gm.rt.schule-bw.de'),
$q->h1('Internet-Einwahl - Internet aktiviert'),
$q->p,
$q->startform,
$q->em("Hallo $user, der
Internetzugang ist <b>für diesen Computer
aktiviert</b>.");
if ($status2 eq "all")
{
print $q->br, $q->em("Außerdem ist der
Internetzugang <b>für alle aktiviert</b>.");
}
print $q->p;
if ($status2 &&
$lehrer) {
print $q->popup_menu('welche',['eigener',
'alle'], 'eigener'), 'Computer';
} elsif (not $lehrer) {
print $q->popup_menu('welche',['eigener'], 'eigener'),
'Computer';
}
print $q->br,
$q->submit(-name=>'deaktivieren', -value=>'Zugang
deaktivieren');
} elsif ($status2 eq "all") {
print
$q->start_html( -title=>'Internet-Einwahl -
Internet für alle aktiviert',
-author=>'webmaster@gm.rt.schule-bw.de'),
$q->h1('Internet-Einwahl - Internet für alle aktiviert'),
$q->p, $q->startform,
$q->em("Hallo
$user, der Internetzugang ist <b>für alle
aktiviert</b>.");
if ($lehrer) {
print $q->p;
print $q->popup_menu('welche',
['alle'], 'alle'), 'Computer';
print $q->br,
$q->submit(-name=>'deaktivieren', -value=>'Zugang
deaktivieren');
}
} else {
print
$q->start_html( -title=>'Internet-Einwahl - Internet
deaktiviert',
-author=>'webmaster@gm.rt.schule-bw.de'),
$q->h1('Internet-Einwahl - Internet deaktiviert'),
$q->p, $q->startform,
$q->em("Hallo $user,
der Internetzugang ist nicht aktiviert."),
$q->p;
print "<br>Dauer: ",
$q->popup_menu('dauer',
[5,10,15,20,30,45,60,75,90,120,150,180],45),"min.";
print $q->br;
if ($lehrer) {
print
$q->popup_menu('welche',['eigener', 'alle'], 'eigener'),
'Computer';
} else {
print
$q->popup_menu('welche',['eigener'], 'eigener'), 'Computer';
}
print $q->br,$q->submit(-name=>'aktivieren',
-value=>'Zugang aktivieren');
}
print
'<p><strong>Zurück zur <a
href="../">Startseite</a></strong>';
print
<<HERE;
<hr><strong>Anmerkung zum
Internetzugang</strong>: Dass der Internetzugang
eingeschaltet
ist bedeutet nicht notwendigerweise, dass eine
Verbindung ins
Internet besteht. Vielmehr wird die Verbindung nur
aufgebaut, wenn
Daten aus dem Internet angefordert werden und die
Verbindung wird
nach einiger Zeit der Inaktivität (zur Zeit 120
Sekunden)
von selbst wieder abgebaut. Die Zeitangabe gibt an, wie lange
der
Internetzugang maximal aktiv sein darf, bevor er zwangsweise beendet
wird.
Er kann natürlich auch früher beendet
werden.
HERE
print $q->endform,
$q->end_html;
Dieses Programm wird angezeigt, wenn das Internet nicht freigeschaltet sein sollte.
Dateiname: /usr/local/httpd/cgi-bin/inactive.cgi.
#!/usr/bin/perl
print
"Expires: Fri, 31 Dec 1990 23:59:59 GMT\n";
print
"Cache-Control: no-cache\n";
print "Content-type:
text/html\n\n";
print "<html>\n";
print
"<head>\n";
print " <title>Internet
nicht aktiviert!</title>\n";
print "</head>\n";
print
"<body>\n";
print "<h1>Das Internet ist
nicht aktiviert!</h1>\n";
print "<h3><a
href=\"http://server/\">Zurück zur
Startseite</a></h3>\n";
print "</body>\n";
print
"</html>\n";
Dieses Programm dient dazu, die Mail-Weiterleitung zu ändern.
Dateiname: /usr/local/httpd/htdocs/mail-config/index.cgi.
#!/usr/bin/perl -wT
# (C) 2001
Thomas Bleher (ThomasBleher@gmx.de) under the GNU GPL
#
#
Erlaubt Benutzern, eine Mail-Weiterleitung anzugeben
# Letzte
Änderung: 19.01.2001
use strict;
use CGI;
use
CGI::Carp;
# Initialization
$ENV{'PATH'} =
'/bin:/usr/bin';
delete @ENV{'IFS', 'CDPATH', 'ENV',
'BASHENV'};
$ENV{'SHELL'} = '/bin/sh' if exists $ENV{'SHELL'};
my
$login = ($ENV{'REMOTE_USER'} =~ /^([-\w.]+)$/)[0];
my $user =
(getpwnam($login))[6]; # untainting ???
my ($alias, $qlogin,
$qalias, $cmdline);
my $q = new CGI;
print $q->header,
$q->start_html('eMail-Weiterleitung'),
$q->h1('eMail-Weiterleitung'), $q->start_form;
if
(defined ($alias = $q->param('alias'))) {
if ($alias !~
/^([-\w.]+\@[-.a-zA-Z0-9]+)?$/) { # entweder ungültige Mail-
adresse oder gar keine
print <<HERE;
<h1
style="color:#FF0000;">Ungültige
eMail-Adresse!</h1>
<p>Ihre eMail-Adresse ($alias)
scheint ungültig zu sein! Sollte es sich
tatsächlich
um eine gültige Adresse handeln, setzen sie sich bitte
mit
dem <a
href="mailto:sysadmin\@gm.rt.schule-bw.de">Administrator</a>
in
Verbindung, damit ihre Adresse manuell eingetragen werden
kann!
HERE
} else {
# construct commandline
# $qlogin
= quotemeta($login);
# $qalias = quotemeta($alias);
# $cmdline
= 'undef $/; $_ = <>;
s/^'.$qlogin.':.*?\\\\'.$qlogin.'$/'.$qlogin.':
'.$qalias.', \\\\'.$qlogin.'/m
or $_ .= "\n'.$qlogin.':
'.$qalias.', \\\\'.$qlogin.'"; print;
system
"/usr/bin/newaliases > /dev/null 2>&1";';
# some magic here ...
system
'/usr/bin/sudo','/usr/local/sbin/change-
liases',$login,$alias;
# or
die 'Error while executing /usr/local/sbin/change-aliases';
if
($alias) {
print <<HERE;
<p><b>Mail-Weiterleitung
erfolgreich geändert; eMail an
<i>$login\@gm.rt.schule-bw.de</i> wird ab sofort an
<i>$alias</i>
weitergeleitet.</b>
HERE
}
else {
print <<HERE;
<p><b>Mail-Weiterleitung
erfolgreich gelöscht.</b>
HERE
}
}
}
else {
# bestimme aktuellen Alias
open INPUT,
'</etc/aliases';
my $input = join '', <INPUT>;
close
INPUT;
$alias = ($input =~
/^\s*?$login:\s*?([-\w.]+\@[-.a-zA-Z0-9]+),
s*?\\$login\s*?$/m)[0]
|| '';
print <<HERE;
<p>Hallo <b>$user</b>.
Ihre aktuelle eMail-Adresse ist
<i>$login\@gm.rt.schule-bw.de</i>.
Hier können sie eine zusätzliche
externe
eMail-Adresse angeben (zum Beispiel bei GMX, T-Online, ...), um
ihre
eMails auch außerhalb der Schule zu empfangen. Alle
eMails an ihre
Schuladresse werden automatisch an ihre externe
Adresse weitergeleitet.
<p>eMail-Weiterleitung an: <input
type="text" name="alias" value="$alias"
size="40">
<p><input type="submit"
value="Mail-Weiterleitung ändern">
<hr><p>Bei
Problemen melden sie sich bitte beim <a
href="mailto:sysadmin\@gm.rt.schule-bw.de">Systemadministrator</a>
HERE
}
print
'<p>Zurück zur <a href="/">Startseite</a>';
print
$q->end_form, $q->end_html;
__END__
Dateiname: /usr/local/sbin/change-aliases.
#!/usr/bin/perl -w -i.orig
my
($login, $alias) = @ARGV;
@ARGV = ('/etc/aliases');
my $qlogin
= quotemeta $login;
my $qalias = quotemeta $alias;
if (not
$alias) {
while (<>)
{
s/^$qlogin:.*?\\$qlogin$//o;
print;
}
} else
{
while (<>) {
s/^\s*?$qlogin:.*?\\$qlogin\s*?$/$login:
$alias, \\$login/o and
$done = 1;
print;
print
"\n$login: $alias, \\$login" if eof and not
$done;
}
}
#system '/usr/bin/newaliases > /dev/null
2>&1';
exit(0);
Dieses Programm dient dazu, sein eigenes Passwort zu ändern.
Dateiname: /usr/local/httpd/htdocs/passwd/index.cgi.
#!/usr/bin/perl -wT
# (C) 2001
Thomas Bleher <ThomasBleher@gmx.de> under the GNU GPL
#
Zuletzt geändert am 22.01.2001
use CGI;#
qw(:standard);
use CGI::Carp qw(fatalsToBrowser);
#use
Crypt::Cracklib;
# Konfiguration:
$PASSWORD_STRENGTH_CHECK
= 0; # soll Passwort auf Sicherheit überprüft werdem?
# 1: Ja; 0: Nein
# Konfiguration
Ende
my $q = new CGI;
my $login = ($ENV{REMOTE_USER} =~
/^([-\w.]+)$/)[0]; # untaint me
my $user = ((getpwnam($login))[6]
=~ /^([- \wäöüß]+)$/i)[0]; # me too (accents
berücksichtigen?)
delete @ENV{'IFS', 'CDPATH', 'ENV',
'BASH_ENV'};
$ENV{'PATH'} = '/bin:/usr/bin:/usr/local/bin';
my
%errors = (
'difference' => 'Die beiden eingegebenen
Passwörter waren leider
nicht identisch! :-( ',
'too
short' => 'Das Passwort ist leider zu kurz! Es muss mindestens 5
Zeichen lang sein! ',
'too long' => 'Das Passwort ist leider
zu lang! Es darf höchstens 8 Zeichen lang sein!
',
'ungueltig' => 'Das Paswort enthält ungültige
Zeichen! Erlaubt sind die Zeichen <b>a-z</b>,
<b>A-Z</b>,
<b>0-9</b> sowie <b>#*,;:._-+$%&/|?
[()]}</b>! ',
'too easy' => 'Das Passwort ist zu leicht
erratbar! Wählen sie
ein schwierigeres Passwort!!!
Genauer Fehler: ',
);
print $q->header,
$q->start_html(
-title=>'Passwortänderung',
-author=>'webmaster@gm.rt.schule-bw.de'),
$q->h1('Passwortänderung'),
"Hallo
Benutzer <b>$user</b> ($login)! (Wenn Sie nicht Benutzer
<b>$user</b> sind, melden sie sich bitte beim <A
HREF=\"mailto:webmaster\@gm.rt.schule-bw.de\">Systemadministrator</A>!)",
$q->p,
$q->startform;
if ($q->param()) { # Passwort
aendern
$pw1=$q->param('pw1');
$pw2=$q->param('pw2');
#
Error-checking
$pw1 ne $pw2 &&
fehler($errors{'difference'});
length($pw1) < 5 &&
fehler($errors{'too short'});
length($pw1) > 8 &&
fehler($errors{'too long'});
$pw1 =~
m@[^-\w#*,;:.+!$%&/|?{[()]}]@ &&
fehler($errors{'ungueltig'});
if ($PASSWORD_STRENGTH_CHECK)
{
my $fehler = fascist_check($pw1,
'/usr/lib/cracklib_dict');
$fehler !~ /^ok$/ &&
fehler($errors{'too easy'}.
<b>"'.$fehler.'"</b>');
}
#
change passwd
# my $pw = ($pw1 =~
m@^([-\w#*,;:.+!\$\%&/|?{\[()\]}]+)$@)[0]; # untaint me
my
$pw = ($pw1 =~ /(.+)/)[0]; # was already checked
$enc_passwd =
crypt($pw,join('',('.','/',0..9,'A'..'Z','a'..'z')[rand 64,
rand
64]));
system('sudo','/usr/sbin/usermod','-p',$enc_passwd,$login);
fehler_bei_aenderung()
if ($! or
$?);
system('sudo','/usr/local/sbin/generate_apache_auth');
open
PIPE, "|sudo smbpasswd -a -s $login > /dev/null"
or
fehler_bei_aenderung();
print PIPE $pw,"\n",$pw,"\n"
or fehler_bei_aenderung();
close PIPE or
fehler_bei_aenderung();
print "<p><strong>Passwort
erfolgreich geändert!</strong>";
sub
fehler_bei_aenderung {
print "<p><strong>Bei
der Passwortänderung ist leider etwas
schiefgegangen.
(Fehlermeldung: $!). Bitte melden sie den
Fehler dem
<a
href=\"mailto:webmaster\@gm.rt.schule-bw.de\">Systemadministrator
</a>!</strong>";
ende();
}
}
else {
print <<HERE;
Hier haben sie die
Möglichkeit, ihr Passwort zu ändern.
Geben Sie es
bitte zweimal ein, damit sichergestellt ist, dass sie sich
nicht
vertippt haben.
<p><strong>Achtung:</strong> Ihr
Passwort muss zwischen 5 und 8 Zeichen lang
sein und darf die
Buchstaben <b>a-z</b>, <b>A-Z</b>, die Zahlen
<b>0-9</b>
sowie die Zeichen
<b>#*,;:._-+!\$\%\&/|?{[()]}</b> enthalten.
<p
style="color:red"><strong>Wählen sie
ein
Passwort, das nicht leicht zu erraten ist! Die
Sicherheit ihrer
Daten hängt entscheidend von der
Sicherheit ihres Passworts
ab!</strong>
<p style="color:red">Ihr
Passwort sollte nicht nur Kleinbuchstaben, sondern
auch
Großbuchstaben,
Zahlen und Sonderzeichen
beinhalten!
<p>Passwort eingeben:<br>
HERE
print
$q->password_field(-name=>"pw1",-size=>"8",-maxlength=>"8"),$q->br;
print
$q->password_field(-name=>"pw2",-size=>"8",-maxlength=>"8"),$q->br;
print $q->submit(-name=>"eingeben",-value=>'Passwort
verändern');
ende();
}
sub fehler {
my
$fehler = shift;
print <<HERE;
<h1>Fehler</h1>
<p><strong
style="color:#FF0000;">$fehler</strong>
<p>Geben
Sie entweder die Passwörter noch einmal ein oder gehen sie
zurück zur <a
href="/">Startseite</a>.
<p><strong>Achtung:</strong>
Ihr Passwort muss zwischen 5 und 8 Zeichen lang
sein und darf die
Buchstaben <b>a-z</b>, <b>A-Z</b>, die Zahlen
<b>0-9</b>
sowie die Zeichen
<b>#*,;:._-+!\$\%\&/|?{[()]}</b> enthalten.
<p>
HERE
print
$q->password_field(-name=>"pw1",-size=>"8",-maxlength=>"8"),$q->br;
print
$q->password_field(-name=>"pw2",-size=>"8",-maxlength=>"8"),$q->br;
print $q->submit(-name=>"eingeben",-value=>'Passwort
verändern');
ende();
}
sub ende {
print
'<p>Zurück zur <a href="/">Startseite</a>';
print
$q->endform, $q->end_html;
exit;
}
Dieses Programm dient dazu, neue Benutzer anzulegen.
Dateiname: /usr/local/httpd/htdocs/admin/adduser.cgi.
#!/usr/bin/perl -w
#
adduser.cgi: a utility to add users to the system
#
# Copyright
(C) 1994 Ian A. Murdock <imurdock@shell.portal.com>
#
Heavily modified by Thomas Bleher <thomas@gm.rt.schule-bw.de>
#
#
This program is free software; you can redistribute it and/or
modify
# it under the terms of the GNU General Public License as
published by
# the Free Software Foundation; either version 2 of
the License, or
# (at your option) any later version.
#
#
This program is distributed in the hope that it will be useful,
#
but WITHOUT ANY WARRANTY; without even the implied warranty of
#
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
#
GNU General Public License for more details.
#
# You should
have received a copy of the GNU General Public License
# along
with this program; if not, write to the Free Software
#
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
use
CGI;
use CGI::Carp qw(fatalsToBrowser);
my $q = new
CGI;
print
$q->header,$q->start_html(-title=>'Benutzereinrichtung');
if
(not $q->param) {
# noch keine Daten eingegeben
print
$q->h1('Benutzereinrichtung');
print $q->p,'Hier
können Sie neue Benutzer einrichten. ';
&erzeuge_eingabefeld();
print <<'HERE';
<hr
/><h2>Anmerkungen</h2>
<p><em>Vollständiger
Name</em>: Hier sollte der wirkliche Name angegeben
werden,
erlaubt sind alle Zeichen.</p>
<p><em>login-Name</em>:
Unter diesem Namen muss sich der Benutzer am System
anmelden.
Erlaubt sind die Buchstaben a-z, A-Z, die Zahlen 0-9 sowie
die
Zeichen ".", "-" und "_". Erstes
Zeichen muss ein Buchstabe sein.</p>
<p><em>Passwort</em>:
Das Passwort ist auf 8 Zeichen beschränkt. Aus
Gründen
der Systemsicherheit muss es mindestens 5 Zeichen lang
sein.
Voreingestellt ist
"<i>passwort</i>".
Erlaubt sind alle Zeichen.</p>
HERE
print
$q->end_html;
} else { # es wurden schon Daten eingegeben
$login=$q->param('login');
$name=$q->param('fullname');
$passwd=$q->param('passwort');
@rechte=$q->param('rechte');
create_user();
if
(%fehler) {
print
"<h1>Fehlerhafte
Eingabe!</h1>",
"<p>Der Benutzer konnte
leider nicht eingerichtet werden, da ihre Eingaben ",
"fehlerhaft
waren. Korrigieren Sie bitte ihre Eingabe und versuchen sie es noch
",
"einmal.</p>",
"<hr
/>",
"<h2>Fehler:</h2>",
"<strong>";
foreach
(keys %fehler) {
print $_,"<br>\n";
}
print
'</strong>';
# Fehlermeldung: Format ungueltig
erzeuge_eingabefeld();
} else {
print
"<h1>Erfolgreiche Benutzereinrichtung!</h1>
<p>Der
Benutzer <strong>$name</strong> wurde
erfolgreich
eingerichtet!\n";
print $q->p;
$rechte
= '';
foreach (keys %rechte) {
$rechte .= "$_
";
}
$rechte = 'Schüler' if (not
$rechte);
print
<<HERE;
<h2>Daten</h2>
<table>
<tr><td>Vollständiger
Name</td><td>$name</td></tr>
<tr><td>Login-Name</td><td>$login</td></tr>
<tr><td>Passwort</td><td>$passwd</td></tr>
<tr><td>Home-Verzeichnis</td><td>$dhome</td></tr>
<tr><td>Rechte</td><td>$rechte</td></tr>
<tr><td>e-Mail-Adresse</td><td>$login\@gm.rt.schule-bw.de</td></tr>
</table>
HERE
$url=$q->url(-relative=>1);
print
"<p><a href=\"$url\">Neuen Benutzer
einrichten</a><p>";
print
$q->a({-href=>'/'},'Zurück zur Hauptseite');
print
$q->end_html;
}
}
sub erzeuge_eingabefeld {
print $q->start_form(-action=>$ENV{SCRIPT_NAME});
print
"\n",$q->p,'<table><tr><td>Vollständiger
Name: </td><td>',$q-
textfield(-name=>'fullname',
-default=>'',
-size=>'30',
-maxlength=>'60');
print "\n</td></tr><tr><td>login-Name:
</td><td>",$q->textfield
-name=>'login',
-default=>'',
-size=>'16',
-maxlength=>'32');
print "\n</td></tr><tr><td>Passwort:
</td><td>",$q->password_field
-name=>'passwort',
'-value'=>'passwort',
-size=>'8',
-maxlength=>'8');
print
"\n</td></tr></table><p><strong>Rechte:
</strong>",$q->br,$q-
checkbox_group(-name=>'rechte',
-values=>['Lehrer','Systemadministrator']);
print
"\n",$q->p,$q->submit('send','Benutzer erzeugen');
print $q->end_form;
}
sub
create_user {
use English;
use
File::Copy;
$dhome="/home";
$login =
$q->param('login');
$name = $q->param('fullname');
$passwd
= $q->param('passwort');
@rechte_a =
$q->param('rechte');
foreach (@rechte_a) {
$rechte{$_}=1;
}
# Plausibilitaetspruefung:
if
(length($passwd) > 8) {$fehler{'Passwort zu lang'}=1};
if
(length($passwd) < 5) {$fehler{'Passwort zu kurz'}=1};
if
($login !~ /^[a-zA-Z][-a-zA-Z0-9._]+$/) {$fehler{'login-Name
nicht
gültig'}=1};
if ($login eq '')
{$fehler{'login-Name zu kurz'}=1};
if ($name eq '') {$fehler{'Name
zu kurz'}=1};
if (length($login) > 16) {$fehler{'login-Name zu
lang'}=1};
if (length($name) > 60) {$fehler{'Name zu
lang'}=1};
if (getpwnam $login) {$fehler{'Benutzer existiert
schon'}=1};
if (%fehler) {return()};
# And now the program
begins:
# Checkboxen auswerten (in Hash
umwandeln?)
#Home-Verzeichnis
if (defined
$rechte{'Lehrer'}) {$dhome .= "/lehrer/";}
else {$dhome .= "/schueler/";}
$dhome .= $login;
#
Gruppenzugehörigkeit
$add_groups =
$login;
add2group('users');
# $add_groups = 'users';
if
(defined $rechte{'Lehrer'}) {
add2group('lehrer');
add2group('internet');
} else {
add2group('schueler');
}
if
(defined $rechte{'Systemadministrator'}) {
add2group('admin')
}
$output = `sudo /usr/sbin/groupadd
$login 2>&1`;
#print "Gruppe erzeugt
(Output:\n$output\n)";
$enc_passwd = crypt ($passwd,
join('',('.','/', 0..9, 'A'..'Z', 'a'..'z')[rand
64, rand
64]));
setgrent;
eval {
local $SIG{ALRM} = sub { die
"Gruppe konnte nicht eingerichtet werden!
(Timeout)\n"
};
alarm 120;
while (not defined($gid = getgrnam $login))
{endgrent;setgrent;} #warten,
bis die group vom System erkannt
wird...
# Gefahr eines Deadlocks?
alarm 0;
};
endgrent;
if
($@) {$fehler{"$@"}=1; return();};
#print "User
existiert\n";
$output = `sudo /usr/sbin/useradd -c \'$name\'
-d $dhome -g $gid -G $add_groups
-p $enc_passwd -s \'/bin/false\'
-m $login 2>&1`;
#print "useradd-output:\n$output\n";
if
($?) {$fehler{'<i>useradd</i> funktioniert nicht
richtig!'}=1; return();}
#print "Benutzer
erzeugt(Output:\n$output)\n";
system("sudo mkdir -m 0755
/home/public_html/$login");
eval {
local $SIG{ALRM} = sub
{ die "Benutzer konnte nicht eingerichtet werden!
(Timeout)\n"
};
alarm 120;
while (not defined($uid = getpwnam $login))
{}
alarm 0;
};
if ($@) {$fehler{"$@"}=1;
return();};
#print "Benutzer existiert\n";
system("sudo
chown $uid:$gid /home/public_html/$login");
system("sudo
ln -s /home/public_html/$login /$dhome/public_html");
#system("sudo
mkdir /usr/local/samba/profiles/$login");
#quotas
setzen
system("sudo /usr/sbin/setquota $login 51200 51200 0 0
/dev/md0");
#print "Verzeichnisse erzeugt\n";
open
PIPE, "|sudo smbpasswd -s -a $login > /dev/null" or
$fehler
"<i>smbpasswd</i> funktioniert nicht
richtig (on PIPE-Open) ($!)"}=1, return();
print PIPE
$passwd,"\n",$passwd,"\n" or
$fehler{"<i>smbpasswd</i> funktioniert
nicht
richtig (on passwd-print) ($!)"}=1, return();
close PIPE; # or $fehler{"<i>smbpasswd</i> funktioniert
nicht
richtig (on PIPE-
lose) ($!)"}=1, return();
#print
"Samba-Passwort\n";
system "sudo
/usr/local/sbin/generate_apache_auth";
system "sudo
/usr/local/sbin/make_mozilla_config.pl $dhome/Mozilla
\'$login\'
\'$name\'";
#print "Rest erzeugt!";
}
sub
add2group {
$add_groups .= ','.$_[0];
}
__END__ of
adduser.cgi
Dateiname: /usr/local/sbin/make_mozilla_config.pl.
#!/usr/bin/perl -w
use
File::Find;
my ($path,$login,$user) = @ARGV;
if (not $user)
{$user =(getpwnam($login))[6]};
if (not $path) {die "Pfad
nicht gültig";}
File::Find::find(\&change_files,$path);
sub
change_files {
my $file = $_;
return unless -f
$_;
open(FILE, "<$file") or return;
my $data =
join('', <FILE>);
close(FILE);
my $orig = $data;
$data
=~ s/\%user\%/$user/g;
$data =~ s/\%login\%/$login/g;
if
($data ne $orig) {
open FILE, ">$file" or
return;
print FILE $data;
close FILE;
}
}
Das Programm dient dazu, die Dateien /etc/apache/passwd und /etc/apache/group zu generieren. Diese Dateien dienen zur Authentifizierung auf dem Webserver und werden u.a. dazu gebraucht, sein eigenes Passwort zu ändern.
Dateiname: /usr/local/sbin/generate_apache_auth.
#!/usr/bin/perl -w
#
#
/usr/local/sbin/generate_apache_auth
#
# WARNING: will run as
root!!!
# Copyright (C) 1999 Thomas Bleher
<thomas@gm.rt.schule-bw.de>
# under the GNU
GPL
#
umask(0027);
%valid_users = map {$_ => 1} split
/ /, (getgrnam('users'))[3];
open(DATEI,
'/etc/shadow');
@passwords = <DATEI>;
close DATEI;
open
DATEI, '>/etc/apache/passwd';
foreach (@passwords) {
@user = split(/:/, $_);
if (defined($valid_users{$user[0]})) { ## nur normale user (Sicherheit)
print DATEI
"$user[0]:$user[1]\n";
}
}
close DATEI;
open
DATEI, '/etc/group';
@groups = <DATEI>;
close
DATEI;
open DATEI, '>/etc/apache/group';
foreach
(@groups) {
@user = split(/:/, $_);
$user[3] =~ s/,/
/g;
$user[3] =~ s/root//g;
print DATEI "$user[0]:
$user[3]";
}
close DATEI;
$uid = 0; #
root
$gid = 33; # www-data
chown $uid, $gid,
'/etc/apache/passwd', '/etc/apache/group';
Das Programm dient dazu, die Homepage zu spiegeln, d.h. auf den Belwue-Server zu kopieren.
Dateiname: /usr/local/httpd/htdocs/admin/homepage/mirror.cgi.
Die Zugriffsrechte für das Verzeichnis /usr/local/httpd/htdocs/admin/homepage/ sehen so aus, damit die Log-Dateien darin erstellt werden können:
drwxrwx--- 2 root www-data 9312 Jul 15 12:05 homepage
mirror.cgi:
#!/usr/bin/perl -w
# This is an
experimental version ...
use strict;
use CGI;
use
CGI::Carp;
use POSIX 'setsid';
# use Time::localtime;
my
($logfile,$index);
my $q = new CGI;
if (not
$q->param('ftp-pw')) {
print $q->header,
$q->start_html('Fehler: Zu wenig Daten'),
$q->h1('Fehler:
Zu wenig Daten'),
'<p>Tja... wenigstens das Passwort
sollte ich haben ... :-(',
'<p>Zurück zur <a
href="/">Startseite</a>',
$q->end_html;
exit;
}
my
$pw = $q->param('ftp-pw');
my ($min, $hour, $day,
$month, $year) = (localtime())[1..5];
$year += 1900; # we want to
be Y2K-compliant, don't we ...
$month++;
my $i = 1;
$i++
while -e ($logfile = sprintf
'log-%04u.%02u.%02u-%
.txt',$year,$month,$day,$i);
$index =
sprintf '<a href="%s">%02u.%02u.%04u
%02u.%02u
Uhr</a>',$logfile,$day,$month,$year,$hour,$min;
#
um das ganze etwas interessanter zu machen ...
my $pid;
if
(not defined ($pid = fork)) {
print $q->header,
$q->start_html('Interner Fehler (Cannot fork)'),
$q->h1('Interner Fehler (Cannot fork)'),
'<p>Tja...
da weiss ich auch nicht weiter ...
:-(',
$q->end_html;
exit;
}
if ($pid) { #
parent
print $q->header, $q->start_html('Homepage-Spiegelung
- Übertragung
gestartet'),
$q->h1('Homepage-Spiegelung
- Übertragung gestartet'),
'<p>Tja... noch etwas
warten, dann ist es soweit ... :-)',
$q->end_html;
exit;
# print
CHILD $pw, "\n";
# close CHILD; # or ...
# hope we
don't have to wait on the child ...
} else { # child
open
STDIN, '/dev/null';
open STDOUT, ">>$logfile";
setsid;
open
STDERR, '>&STDOUT';
open CMD, '| /usr/bin/sudo
/usr/local/sbin/mirror-hp.sh' or die "Cannot
open
pipe";
print CMD $pw,"\n" or die "Cannot
write to pipe";
close CMD;
system("perl -i -pe
's:<ul>:<ul>\\n<li>$index</li>:i;'
index.html");
}
Dateiname: /usr/local/httpd/htdocs/admin/homepage/index.html.
Diese Datei hat folgende Zugriffsrechte, damit sie vom cgi-script verändert werden kann:
-rw-rw---- 1 www-data www-data 15714 Jul 15 12:05 index.html
index.html:
<html>
<head>
<title>Homepage-Spiegelung</title>
</head>
<body>
<h1>Homepage-Spiegelung</h1>
<p>Hier
können sie die Homepage-Spiegelung von
<tt>I:\intranet</tt>
auf
<a
href="http://www.gm.rt.schule-bw.de">http://www.gm.rt.schule-bw.de</a>
starten.
Dazu geben sie bitte unten das Passwort für den FTP-Server
ein.
Die Spiegelung läuft im Hintergrund.
<form
action="mirror.cgi" method="post">
<p>Passwort:
<input type="password" name="ftp-pw"
size="8">
<input type="submit"
value="Spiegelung starten">
</form>
<p>Zurück
zur <a href="/">Startseite</a>
<hr>
<h1>Logdateien</h1>
<p>Hier
finden sie die Logdateien der Übertragungen. Die Datei
erscheint
in der Liste, sobald die Übertragung
abgeschlossen wurde.
<p>
<ul>
<li><a
href="log-2004.07.15-1.txt">15.07.2004 11.51
Uhr</a></li>
<li><a
href="log-2004.07.15-3.txt">15.07.2004 11.56
Uhr</a></li>
</ul>
</body>
</html>
Dateiname: /usr/local/sbin/mirror-hp.sh.
#!/bin/bash
# erst
verbindungsaufbau erzwingen...
ping -c 1 www.belwue.de >
/dev/null 2>&1
# spiegelung starten
su -c
'/usr/bin/weex Belwue' – homepage
Das ist der (neue) Benutzermanager.
Dateiname: /usr/local/httpd/htdocs/admin/usermanager3.cgi.
#!/usr/bin/perl -wT
# usermanager
#
# Copyright (c) 2001 Thomas Bleher
<ThomasBleher@gmx.de>
# Copyright (c) 2002,2003 Andreas
Dangel <adabolo@adabolo.de>
#
# This program is free
software; you can redistribute it and/or modify
# it under the
terms of the GNU General Public License as published by
# the
Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is
distributed in the hope that it will be useful,
# but WITHOUT
ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should
have received a copy of the GNU General Public License
# along
with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
USA
#
use strict;
use CGI;
use User::pwent;
use
CGI::Carp qw(fatalsToBrowser);
#
=============================================================================
# KONFIGURATION
#
=============================================================================
my
$user_status_script = "sudo
/usr/local/sbin/user-status3";
$ENV{"PATH"} =
"/bin:/usr/bin";
#
=============================================================================
# GLOBALE VARIABLEN
#
=============================================================================
my
$q; # für CGI
my @users; # speichert die
ausgewählten Benutzer (login-names)
my $this_script;
my
$now_time_string = localtime;
my $error = "";
#
=============================================================================
# SUBS
#
=============================================================================
sub
main;
sub print_header;
sub print_seite0;
sub
print_page_end;
sub print_page_data;
sub
get_userlist;
######
main;
exit 0;
######
#
=============================================================================
# MAIN
#
=============================================================================
sub
main {
$q = new CGI;
$this_script = $q->url();
# wurden Daten gesendet?
if ($q->param) {
#&print_header("Parameter vorhanden!");
#print
$q->Dump;
#&print_page_end;
if
(defined($q->param("user"))) {
&print_user_data($q->param("user"));
} elsif
($q->param("seite") == 0) {
&print_page_data;
} elsif ($q->param("seite") == 1) {
if
(defined($q->param("action"))) {
if
($q->param("action") eq "lock") {
&do_lock_users;
} elsif ($q->param("action")
eq "pw") {
&ask_pw_users;
}
elsif ($q->param("action") eq "rights") {
&ask_rights_users;
} elsif
($q->param("action") eq "delete") {
&ask_delete_users;
}
} else {
$error = "Falscher Befehl!";
&print_page_data;
}
} elsif ($q->param("seite") == 2) {
&do_pw_users;
} elsif ($q->param("seite")
== 3) {
&do_rights_users;
} elsif
($q->param("seite") == 4) {
&do_delete_users;
} elsif ($q->param("seite") == 5) {
&do_save_user_data;
}
} else {
&print_seite0;
}
}
#
=============================================================================
# PRINT_HEADER
#
=============================================================================
sub
print_header {
my $title = shift;
print $q->header;
print qq(<html>\n);
print qq(<head>\n);
print
qq( <title>$title</title>\n);
print qq(</head>\n);
print qq(<body>\n);
print qq(<h1>$title</h1>\n);
}
#
=============================================================================
# PRINT_SEITE0
#
=============================================================================
sub
print_seite0 {
&print_header("Benutzermanager");
print qq(<form method="post">\n);
print
qq(<h3>Welche Benutzer sollen angezeigt werden?</h3>\n);
print qq(<input type="radio" name="auswahl"
value="alle" checked>Alle<br>\n);
print
qq(<input type="radio" name="auswahl"
value="passwort">Nur Benutzer, die
als Passwort
"passwort" haben<br>\n);
print qq(<input
type="radio" name="auswahl" value="gesperrt">Nur
gesperrte
Benutzer<br>\n);
print qq(<input
type="radio" name="auswahl" value="aktiv">Nur
aktivierte
Benutzer<br>\n);
print qq(<input
type="radio" name="auswahl" value="jahrgang">Nur
bestimmter
Abi-Jahrgang (nur Schüler):\n);
print qq( <input type="text" name="abijahr" value=""
size="2"
maxlength="2"><br>\n);
print qq(<input type="radio" name="auswahl"
value="gruppen">Nur bestimmte
Gruppen:\n);
print
qq( <input type="checkbox"
name="gruppe_schueler">Schüler\n);
print qq( <input type="checkbox" name="gruppe_lehrer">Lehrer\n);
print qq( <input type="checkbox"
name="gruppe_internet">Internet\n);
print qq( <input type="checkbox"
name="gruppe_admin">Administratoren\n);
print qq( <input type="checkbox"
name="gruppe_homepage">Homepage<br>\n);
print
qq(<input type="radio" name="auswahl"
value="name">Bestimmter
Benutzer:\n);
print qq( <input type="text" name="loginname" value=""
size="15">\n);
print qq(<p>\n);
print
qq(<input type="hidden" name="seite"
value="0">\n);
print qq(<input type="submit"
value="Anfrage starten..."\n);
print qq(</form>\n);
&print_page_end;
}
#
=============================================================================
# PRINT_PAGE_END
#
=============================================================================
sub
print_page_end {
print qq(<hr>\n);
print qq(<a
href="http://server/">zur Startseite</a>\n);
print qq( - <a
href="http://server/admin/">Administration</a>\n);
print qq( - <a href="$this_script">Benutzermanager</a>\n);
print qq( - $now_time_string\n);
#print qq( - <i>©
adabolo.de network solutions</i>\n);
print qq(</body>\n);
print qq(</html>\n);
}
#
=============================================================================
# PRINT_PAGE_DATA
#
=============================================================================
sub
print_page_data {
&print_header("Benutzermanager");
if ($error ne "") {
print qq(<font
color="green">$error</font>\n);
}
my
@userlist = &get_userlist;
my $anzahl = @userlist;
# Benutzerliste sortieren...
my @sorted = sort {
my $c =
$a;
my $d = $b;
# Lehrer:
if ($c =~
m/\A(\w)\.([\w\-]+)\Z/) { $c = "000.$2.$1." };
if
($d =~ m/\A(\w)\.([\w\-]+)\Z/) { $d = "000.$2.$1." };
# Sonstige:
if ($c =~ m/\Abo\.vhs(\d\d)\Z/) { $c =
"EEE.bo.vhs.$1." };
if ($d =~ m/\Abo\.vhs(\d\d)\Z/) { $d = "EEE.bo.vhs.$1." };
if ($c =~
m/\Abl\.vhs(\d+)\Z/) { $c = "FFF.bl.vhs.$1." };
if ($d =~ m/\Abl\.vhs(\d+)\Z/) { $d = "FFF.bl.vhs.$1."
};
if ($c =~ m/\Akghs(\d+)\Z/) { $c = "GGG.kghs.$1."
};
if ($d =~ m/\Akghs(\d+)\Z/) { $d = "GGG.kghs.$1."
};
if ($c =~ m/\Abo\.kgrt(\d+)\Z/) { $c = "HHH.bo.kgrt.$1."
};
if ($d =~ m/\Abo\.kgrt(\d+)\Z/) { $d = "HHH.bo.kgrt.$1."
};
# Schüler
if ($c =~ m/\A(\w)(\w+)(\d\d)\Z/) {
$c = "AAA.$3.$2.$1." };
if ($d =~
m/\A(\w)(\w+)(\d\d)\Z/) { $d = "AAA.$3.$2.$1." };
$c cmp $d;
} @userlist;
# JavaScript Programm:
print qq(\n<script type="text/javascript"
language="javascript">\n);
print qq(function
mark_all() {\n);
print qq( var b =
window.document.forms[0].checker.checked;\n);
print qq( var
count = 0;\n);
print qq( while (count < $anzahl) {\n);
print qq( window.document.forms[0].elements[count++].checked =
b;\n);
print qq( }\n);
print qq(}\n);
print
qq(</script>\n\n);
# Formular starten
print
$q->start_form;
# Tabelle starten
print qq(<table
border="1">\n);
print
qq(<tr><th>Login</th><th>Name</th><th>Gruppen
(Rechte)</th>);
print qq(<th>Quota</th><th>"passwort"
(letzte Änderung)</th><th>Status</th>);
print qq(<th>Auswahl</th></tr>\n);
foreach
(@sorted) {
my $login = $_;
my $name =
&get_fullname($_);
my $gruppen = &get_groups($_);
my $quota = &get_quota($_);
my $passwort =
&get_password($_);
my $status = &get_status($_);
my $color = "#FFFFDD";
if ($passwort =~
m/JA/) {
$color = "#FF0000";
}
if
($status eq "deaktiviert") {
$color = "#EEEEEE";
}
print qq(<tr bgcolor="$color">);
print qq(<td><a
href="$this_script?user=$_">$_</a></td>);
print qq(<td>$name</td>);
print
qq(<td>$gruppen</td>);
print qq(<td>$quota</td>);
print qq(<td>$passwort</td>);
print
qq(<td>$status</td>);
print qq(<td><input
type="checkbox" name="users"
value="$_"></td></tr>\n);
}
print qq(<tr><td align="right" colspan="6">Alle
angezeigten Benutzer
markieren:</td>);
print
qq(<td><input type="checkbox" name="checker"
onclick="mark_all();
></td></tr>\n);
print qq(</table>\n);
print qq(Angezeigte Benutzer:
$anzahl\n);
print qq(<p>\n);
print
qq(<h2>Aktion</h2>\n);
print qq(<input
type="radio" name="action"
value="lock">Benutzer
sperren/freigeben<br>\n);
print qq(<input type="radio" name="action"
value="pw">Passwort ändern<br>\n);
print
qq(<input type="radio" name="action"
value="rights">Rechte
ändern<br>\n);
print qq(<input type="radio" name="action"
value="delete">Benutzer
löschen<br>\n);
print qq(<input type="hidden" name="seite"
value="1">\n);
&print_seite1_values;
print qq(<input type="submit" value="Ausführen">
<input type="reset"
value="Abbrechen">\n);
print qq(</form>\n);
&print_page_end;
}
#
=============================================================================
# GET_USERLIST
#
=============================================================================
sub
get_userlist {
my @users = split / /, (getgrnam('users'))[3];
if ($q->param("auswahl") eq "alle") {
return @users;
} elsif ($q->param("auswahl") eq
"passwort") {
my @userlist = qw();
foreach
(@users) {
# für jeden Benutzer prüfen, ob
"passwort" das Passwort ist...
# das Script gibt
den Benutzernamen zurück, wenn das Passwort
# unsicher
ist. Es gibt "---secure" zurück, wenn das Passwort
# sicher ist.
my $ret = `$user_status_script -passwd
$_`;
if ($ret ne "---secure") {
push(@userlist, $_);
}
}
return @userlist;
} elsif ($q->param("auswahl") eq "gesperrt")
{
my @userlist = qw();
foreach (@users) {
#
für jeden Benutzer prüfen, ob er gesperrt ist...
my $ret = `$user_status_script -locked $_`;
if ($ret ne
"---unlocked") {
push(@userlist, $_);
}
}
return @userlist;
} elsif
($q->param("auswahl") eq "aktiv") {
my
@userlist = qw();
foreach (@users) {
# für jeden
Benutzer prüfen, ob er "unlocked" ist...
my
$ret = `$user_status_script -locked $_`;
if ($ret eq
"---unlocked") {
push(@userlist, $_);
}
}
return @userlist;
} elsif
($q->param("auswahl") eq "jahrgang") {
# erst Abi-Jahrgang herausfinden
my $abi =
$q->param("abijahr");
# keine zwei Ziffern?
if ($abi !~ m/\d\d/) {
# dann alle Benutzer anzeigen...
return @users;
}
# jeden Benutzer durchgehen und
in @userlist speichern
my @userlist = qw();
foreach
(@users) {
if ($_ =~ m/\w+$abi/) {
push(@userlist, $_);
}
}
return @userlist;
} elsif ($q->param("auswahl") eq "gruppen")
{
# wenn gar nichts gewählt...
if
($q->param("gruppe_schueler") ne "on" &&
$q->param("gruppe_lehrer") ne "on" &&
$q->param("gruppe_internet") ne "on"
&&
$q->param("gruppe_admin") ne "on"
&&
$q->param("gruppe_homepage") ne
"on") {
return @users;
}
my
%userlist;
my @group_users;
if
($q->param("gruppe_schueler") eq "on") {
@group_users = split / /, (getgrnam('schueler'))[3];
foreach (@group_users) { $userlist{$_} = 1; }
}
if
($q->param("gruppe_lehrer") eq "on") {
@group_users = split / /, (getgrnam('lehrer'))[3];
foreach
(@group_users) { $userlist{$_} = 1; }
}
if
($q->param("gruppe_internet") eq "on") {
@group_users = split / /, (getgrnam('internet'))[3];
foreach (@group_users) { $userlist{$_} = 1; }
}
if
($q->param("gruppe_admin") eq "on") {
@group_users = split / /, (getgrnam('admin'))[3];
foreach
(@group_users) { $userlist{$_} = 1; }
}
if
($q->param("gruppe_homepage") eq "on") {
@group_users = split / /, (getgrnam('homepage'))[3];
foreach (@group_users) { $userlist{$_} = 1; }
}
return keys(%userlist);
} elsif ($q->param("auswahl")
eq "name") {
my $login = $q->param("loginname");
$login = quotemeta($login);
return grep(/$login/, @users);
} else {
# in sonstigen Fällen, die eigentlich nicht
auftreten sollten:
# Alle Benutzer anzeigen...
return
@users;
}
}
#
=============================================================================
# GET_FULLNAME
#
=============================================================================
sub
get_fullname {
my $login = shift;
my $user =
getpwnam($login);
return $user->gecos;
}
#
=============================================================================
# GET_HOMEDIR
#
=============================================================================
sub
get_homedir {
my $login = shift;
my $user =
getpwnam($login);
return $user->dir;
}
#
=============================================================================
# GET_SHELL
#
=============================================================================
sub
get_shell {
my $login = shift;
my $user =
getpwnam($login);
return $user->shell;
}
#
=============================================================================
# GET_GROUPS
#
=============================================================================
sub
get_groups {
my $login = shift;
# untaint
$login
=~ m/([\w\.\-]+)/;
$login = $1;
my $groups = `id -nG
$login`;
return $groups;
}
#
=============================================================================
# GET_PASSWORD
#
=============================================================================
sub
get_password {
my $login = shift;
my $ret =
`$user_status_script -passwd $login`;
my $answer = "";
if ($ret eq "---secure") {
$answer .= "nein
";
} else {
$answer .= "JA ";
}
$answer .= "(" . `$user_status_script -change $login` .
")";
return $answer;
}
#
=============================================================================
# GET_STATUS
#
=============================================================================
sub
get_status {
my $login = shift;
# untaint
$login
=~ m/([\w\.\-]+)/;
$login = $1;
my $ret =
`$user_status_script -locked $login`;
if ($ret eq "---unlocked")
{
return "aktiviert";
} else {
return
"deaktiviert";
}
}
#
=============================================================================
# GET_QUOTA
#
=============================================================================
sub
get_quota {
my $login = shift;
# untaint
$login =~
m/([\w\.\-]+)/;
$login = $1;
my $ret =
`$user_status_script -quota $login`;
return $ret;
}
#
=============================================================================
# PRINT_USER_DATA
#
=============================================================================
sub
print_user_data {
my $login = shift;
# untaint
$login =~ m/([\w\.\-]+)/;
$login = $1;
&print_header("Benutzermanager - $login");
my
$fullname = &get_fullname($login);
my $homedir =
&get_homedir($login);
my $shell = &get_shell($login);
my $rights = &get_groups($login);
my $quota =
&get_quota($login);
$quota =~ m/(\d+)\/(\d+)/;
my
$quota_used = $1;
my $quota_limit = $2;
my $status =
&get_status($login);
my $change = `$user_status_script
-change $login`;
print $q->start_form;
print
qq(<table border="0">\n);
print
qq(<tr><td><b>Login</b></td><td>$login</td></tr>\n);
print
qq(<tr><td><b>Homeverzeichnis</b></td><td>$homedir</td></tr>\n);
print
qq(<tr><td><b>Shell</b></td><td>$shell</td></tr>\n);
print
qq(<tr><td><b>Name</b></td><td><input
type="text"
name="fullname"
value="$fullname"></td></tr>\n);
print
qq(<tr><td><b>Gruppen</b></td><td>);
print qq(<input type="checkbox" name="rights"
value="schueler");
print qq( checked) if ($rights =~
m/schueler/);
print qq(>Schüler );
print qq(<input
type="checkbox" name="rights" value="lehrer");
print qq( checked) if ($rights =~ m/lehrer/);
print qq(>Lehrer
);
print qq(<input type="checkbox" name="rights"
value="internet");
print qq( checked) if ($rights =~
m/internet/);
print qq(>Internet );
print qq(<input
type="checkbox" name="rights" value="admin");
print qq( checked) if ($rights =~ m/admin/);
print
qq(>Administratoren );
print qq(<input type="checkbox"
name="rights" value="homepage");
print qq(
checked) if ($rights =~ m/homepage/);
print qq(>Homepage );
print qq(</td></tr>\n);
print
qq(<tr><td><b>Quota</b></td><td>);
print qq($quota_used / <input type="text" size="4"
value="$quota_limit"
name="quota"> MB);
print qq(</td></tr>\n);
print
qq(<tr><td><b>Status</b></td><td>);
print qq(<input type="radio" name="lock"
value="gesperrt");
print qq( checked) if ($status eq
"deaktiviert");
print qq(>gesperrt );
print
qq(<input type="radio" name="lock"
value="freigegeben");
print qq( checked) if ($status
eq "aktiviert");
print qq(>freigegeben );
print qq(</td></tr>\n);
print
qq(<tr><td><b>Passwort</b></td><td>);
print qq(<input type="password" name="passwort"
value="">);
print qq( \(Letzte Änderung:
$change\));
print qq(</td></tr>\n);
print
qq(</table>\n);
print qq(<input type="submit"
name="save" value="speichern">\n);
print
qq(<input type="submit" name="abort"
value="abbrechen">\n);
print qq(<input
type="hidden" name="edit_user"
value="$login">\n);
print qq(<input
type="hidden" name="seite" value="5">\n);
#&print_seite1_values;
print qq(<input type="hidden"
name="auswahl" value="name">\n);
print
qq(<input type="hidden" name="loginname"
value="$login">\n);
print qq(</form>\n);
&print_page_end;
}
#
=============================================================================
# DO_LOCK_USERS
#
=============================================================================
sub
do_lock_users {
my @users = qw();
if
(defined($q->param("users"))) {
@users =
$q->param("users");
} else {
$error =
"<strong>Fehler:</strong> Keine Benutzer
ausgewählt!";
return;
}
$error =
"Folgende Benutzer wurden gesperrt bzw.
freigegeben:<br>\n<b>";
foreach (@users) {
my $login = $_;
# untaint
$login =~
m/([\w\.\-]+)/;
$login = $1;
my $status =
&get_status($login);
if ($status eq "aktiviert")
{
# sperre Benutzer $login
`sudo /usr/bin/passwd -l
$login`;
fehler("Benutzer sperren (passwd) [$login]")
if ($? != 0);
`sudo /usr/bin/smbpasswd -d $login`;
fehler("Benutzer sperren (smbpasswd) [$login]") if ($? !=
0);
} else {
# Gebe Benutzer $login frei
`sudo /usr/bin/passwd -u $login`;
fehler("Benutzer
freigeben (passwd) [$login]") if ($? != 0);
`sudo
/usr/bin/smbpasswd -e $login`;
fehler("Benutzer
freigeben (smbpasswd) [$login]") if ($? != 0);
}
$error .= "$_ ";
}
$error .= "</b>";
`sudo /usr/local/sbin/generate_apache_auth`;
&print_page_data;
}
#
=============================================================================
# ASK_PW_USERS
#
=============================================================================
sub
ask_pw_users {
my @users = qw();
if
(defined($q->param("users"))) {
@users =
$q->param("users");
} else {
$error =
"<strong>Fehler:</strong> Keine Benutzer
ausgewählt!";
&print_page_data;
return;
}
&print_header("Benutzermanager - Passwort
ändern");
print qq(Von folgenden Benutzern soll
das Passwort geändert werden: <b>);
print join("
", @users);
print qq(</b>\n<p>\n);
print $q->start_form;
print qq(Bitte geben Sie das neue
Passwort ein:\n);
print qq(<input type="password"
name="password" size="8"
maxlength="8"
value="passwort">\n);
print qq(<input type="hidden" name="seite"
value="2">\n);
foreach (@users) {
print
qq(<input type="hidden" name="users"
value="$_">\n);
}
&print_seite1_values;
print qq(<p>);
print qq(<input type="submit"
name="do_it" value="Passwort ändern">\n);
print qq(<input type="submit" name="abort"
value="Abbrechen">\n);
print qq(</form>\n);
&print_page_end;
}
#
=============================================================================
# PRINT_SEITE1_VALUES
#
=============================================================================
sub
print_seite1_values {
print qq(<input type="hidden"
name="auswahl" value=");
print
$q->param("auswahl");
print qq(">\n);
print qq(<input type="hidden" name="loginname"
value=");
print $q->param("loginname");
print qq(">\n);
print qq(<input type="hidden"
name="abijahr" value=");
print
$q->param("abijahr");
print qq(">\n);
print qq(<input type="hidden" name="gruppe_schueler"
value=");
print $q->param("gruppe_schueler");
print qq(">\n);
print qq(<input type="hidden"
name="gruppe_lehrer" value=");
print
$q->param("gruppe_lehrer");
print qq(">\n);
print qq(<input type="hidden" name="gruppe_internet"
value=");
print $q->param("gruppe_internet");
print qq(">\n);
print qq(<input type="hidden"
name="gruppe_admin" value=");
print
$q->param("gruppe_admin");
print qq(">\n);
print qq(<input type="hidden" name="gruppe_homepage"
value=");
print $q->param("gruppe_homepage");
print qq(">\n);
}
#
=============================================================================
# DO_PW_USERS
#
=============================================================================
sub
do_pw_users {
my @users = $q->param("users");
my $password = $q->param("password");
if
(defined($q->param("abort"))) {
&print_page_data;
return;
}
#untaint
$password =~ m/([-\w#*,;:.+!$%&\/|?{\[()\]}]+)/;
$password =
$1;
my $enc_pw = crypt($password, join("", (".",
"/", 0..9, "a".."z", "A".."Z")
rand
64, rand 64]));
$error = "Von folgenden Benutzern wurde
das Passwort geändert:<br>\n<b>";
foreach (@users) {
my $login = $_;
#untaint
$login =~ m/([\w\.\-]+)/;
$login = $1;
`sudo
/usr/sbin/usermod -p $enc_pw $login`;
fehler("Passwortänderung
(usermod) [$login]") if ($? != 0);
open PIPE, "|
sudo /usr/bin/smbpasswd -s $login > /dev/null"
or
fehler("Passwortänderung (pipe open) [$login]");
print PIPE "$password\n$password\n"
or
fehler("Passwortänderung (pipe write) [$login]");
close PIPE
or fehler("Passwortänderung (pipe
close) [$login]");
$error .= "$login ";
}
$error .= "</b>";
`sudo
/usr/local/sbin/generate_apache_auth`;
&print_page_data;
}
#
=============================================================================
# ASK_RIGHTS_USERS
#
=============================================================================
sub
ask_rights_users {
my @users = qw();
if
(defined($q->param("users"))) {
@users =
$q->param("users");
} else {
$error =
"<strong>Fehler:</strong> Keine Benutzer
ausgewählt!";
&print_page_data;
return;
}
&print_header("Benutzermanager –
Rechteänderung");
print qq(Von folgenden Benutzern
sollen die Rechte geändert werden: <b>);
print join("
", @users);
print qq(</b>\n<p>\n);
print $q->start_form;
print qq(<h2>Rechte</h2>\n);
print qq(<input type="checkbox" name="rights"
value="schueler">Schüler<br>\n);
print
qq(<input type="checkbox" name="rights"
value="lehrer">Lehrer<br>\n);
print qq(<input
type="checkbox"
name="rights"
value="internet">Internet<br>\n);
print qq(<input type="checkbox"
name="rights"
value="admin">Administratoren<br>\n);
print qq(<input type="checkbox"
name="rights"
value="homepage">Homepage<br>\n);
print qq(Quota (0 = unbegrenzt): <input type="text"
name="quota" value="50"
size="4">MB<br>\n);
print qq(<input type="hidden" name="seite"
value="3">\n);
foreach (@users) {
print
qq(<input type="hidden" name="users"
value="$_">\n);
}
&print_seite1_values;
print qq(<p>);
print qq(<input type="submit"
name="do_it" value="Rechte ändern">\n);
print qq(<input type="submit" name="abort"
value="Abbrechen">\n);
print qq(</form>\n);
&print_page_end;
}
#
=============================================================================
# DO_RIGHTS_USERS
#
=============================================================================
sub
do_rights_users {
my @users = $q->param("users");
if (defined($q->param("abort"))) {
$error =
"Abbruch!";
&print_page_data;
return;
}
# Rechte sammeln und überprüfen
my
@new_rights;
push(@new_rights, "users");
my
@rights = $q->param("rights");
foreach (@rights) {
push(@new_rights, "schueler") if ($_ eq "schueler");
push(@new_rights, "lehrer") if ($_ eq "lehrer");
push(@new_rights, "internet") if ($_ eq "internet");
push(@new_rights, "admin") if ($_ eq "admin");
push(@new_rights, "homepage") if ($_ eq "homepage");
}
my $rights_string = join(",", @new_rights);
# Quota
$q->param("quota") =~ m/(\d+)/;
my
$quota = $1 * 1024; # Anzahl der KB-Blöcke
# Shell
my $shell = "/bin/false";
if ($rights_string =~
m/admin/) {
$shell = "/bin/bash";
}
$error = "Von folgenden Benutzern wurden die Rechte auf
<i>$rights_string</i>
geändert:<br>\n<b>";
foreach (@users) {
my $login = $_;
#untaint
$login =~ m/([\w\.\-]+)/;
$login = $1;
`sudo
/usr/sbin/usermod -s $shell -G $rights_string,$login $login`;
fehler("Rechteänderung (usermod) [$login]") if ($? !=
0);
`sudo /usr/sbin/setquota $login $quota $quota 0 0
/dev/md0`;
fehler("Rechteänderung (setquota)
[$login]") if ($? != 0);
$error .= "$login ";
}
$error .= "</b>\n";
`sudo
/usr/local/sbin/generate_apache_auth`;
&print_page_data;
}
#
=============================================================================
# ASK_DELETE_USERS
#
=============================================================================
sub
ask_delete_users {
my @users = qw();
if
(defined($q->param("users"))) {
@users =
$q->param("users");
} else {
$error =
"<strong>Fehler:</strong> Keine Benutzer
ausgewählt!";
&print_page_data;
return;
}
&print_header("Benutzermanager - Benutzer
löschen");
print qq(<font
color="red"><b>ACHTUNG!</b></font>
Folgende Benutzer werden
gelöscht: <b>);
print
join(" ", @users);
print qq(</b>\n<p>\n);
print qq(Auch die Homeverzeichnisse und alle persönlichen Daten
werden
gelöscht );
print qq(und <strong>können
nicht wiederhergestellt werden</strong>. Nur
die );
print qq(<tt>public_html</tt>-Verzeichnisse bleiben
erhalten.<p>\n);
print qq(Wollen Sie wirklick
fortfahren?<p>\n);
print $q->start_form;
print
qq(<input type="hidden" name="seite"
value="4">\n);
foreach (@users) {
print
qq(<input type="hidden" name="users"
value="$_">\n);
}
&print_seite1_values;
print qq(<p>);
print qq(<input type="submit"
name="do_it" value="Benutzer löschen!">\n);
print qq(<input type="submit" name="abort"
value="Abbrechen">\n);
print qq(</form>\n);
&print_page_end;
}
#
=============================================================================
# DO_DELETE_USERS
#
=============================================================================
sub
do_delete_users {
my @users = $q->param("users");
if (defined($q->param("abort"))) {
$error =
"Abbruch!";
&print_page_data;
return;
}
$error = "Folgende Benutzer wurden
gelöscht:<br>\n<b>";
foreach (@users)
{
my $login = $_;
#untaint
$login =~
m/([\w\.\-]+)/;
$login = $1;
# Samba-User löschen
`sudo /usr/bin/smbpasswd -x $login`;
fehler("Benutzer
löschen (smbpasswd) [$login]") if ($? != 0);
#
public_html-Verzeichnis verschieben
`sudo /bin/mv
/home/public_html/$login /usr/local/httpd/htdocs/oldhomes/`;
fehler("Benutzer löschen (move public_html) [$login]")
if ($? != 0);
`sudo /bin/chown -h -f -R root:www-data
/
sr/local/httpd/htdocs/oldhomes/$login`;
fehler("Benutzer
löschen (chown public_html) [$login]") if ($? != 0);
`sudo /bin/chmod -R 755 /usr/local/httpd/htdocs/oldhomes/$login`;
fehler("Benutzer löschen (chmod public_html) [$login]")
if ($? != 0);
# Benutzer und Homeverzeichnis löschen
`sudo /usr/sbin/userdel -r $login`;
fehler("Benutzer
löschen (userdel) [$login]") if ($? != 0);
`sudo
/usr/sbin/groupdel $login`;
fehler("Benutzer löschen
(groupdel) [$login]") if ($? != 0);
$error .= "$login
";
}
$error .= "</b>\n";
`sudo /usr/local/sbin/generate_apache_auth`;
&print_page_data;
}
#
=============================================================================
# FEHLER
#
=============================================================================
sub
fehler {
my $text = shift;
$error .= qq(<p><font
color="red"><big><strong>Schwerwiegender
Fehler:</strong></big>
$text</font>);
`sudo
/usr/local/sbin/generate_apache_auth`;
&print_page_data;
exit 1;
}
#
=============================================================================
# DO_SAVE_USER_DATA
#
=============================================================================
sub
do_save_user_data {
if (defined($q->param("abort")))
{
$error = "Abbruch!";
&print_page_data;
return;
}
my $login = $q->param("edit_user");
# untaint
$login =~ m/([\w\.\-]+)/;
$login = $1;
my $fullname;
my $rights;
my $quota;
my $status;
if (defined($q->param("fullname"))) {
$fullname
= $q->param("fullname");
#untaint
$fullname =~ m/([\w\.\ ,äöüÄÖÜ\-*#']+)/;
$fullname = $1;
`sudo /usr/sbin/usermod -c "$fullname"
$login`;
fehler("Benutzer ändern, Name (usermod)
[$login]") if ($? != 0);
}
if
(defined($q->param("rights"))) {
# Rechte sammeln
und überprüfen
my @new_rights;
push(@new_rights, "users");
my @rights =
$q->param("rights");
foreach (@rights) {
push(@new_rights, "schueler") if ($_ eq "schueler");
push(@new_rights, "lehrer") if ($_ eq "lehrer");
push(@new_rights, "internet") if ($_ eq "internet");
push(@new_rights, "admin") if ($_ eq "admin");
push(@new_rights, "homepage") if ($_ eq "homepage");
}
my $rights_string = join(",",
@new_rights);
my $shell = "/bin/false";
if ($rights_string =~ m/admin/) { $shell = "/bin/bash"; }
`sudo /usr/sbin/usermod -s $shell -G $rights_string,$login
$login`;
fehler("Benutzer ändern, Rechte (usermod)
[$login]") if ($? != 0);
}
if
(defined($q->param("lock"))) {
$status =
$q->param("lock");
if ($status eq "gesperrt")
{
# sperre Benutzer $login
`sudo /usr/bin/passwd -l
$login`;
fehler("Benutzer sperren (passwd) [$login]")
if ($? != 0);
`sudo /usr/bin/smbpasswd -d $login`;
fehler("Benutzer sperren (smbpasswd) [$login]") if ($? !=
0);
} else {
# Gebe Benutzer $login frei
`sudo /usr/bin/passwd -u $login`;
fehler("Benutzer
freigeben (passwd) [$login]") if ($? != 0);
`sudo
/usr/bin/smbpasswd -e $login`;
fehler("Benutzer
freigeben (smbpasswd) [$login]") if ($? != 0);
}
}
if (defined($q->param("quota"))) {
# Quota
$q->param("quota") =~ m/(\d+)/;
my $quota = $1 *
1024; # Anzahl der KB-Blöcke
`sudo
/usr/sbin/setquota $login $quota $quota 0 0 /dev/md0`;
fehler("Benutzer ändern, Quota (setquota) [$login]")
if ($? != 0);
}
if (defined($q->param("passwort"))
&& $q->param("passwort") ne "") {
my $password = $q->param("passwort");
#untaint
$password =~ m/([-\w#*,;:.+!$%&\/|?{\[()\]}]+)/;
$password = $1;
my $enc_pw = crypt($password, join("",
(".", "/", 0..9, "a".."z",
"A".."Z")
rand 64, rand 64]));
`sudo /usr/sbin/usermod -p $enc_pw $login`;
fehler("Benutzer
ändern, Passwort (usermod) [$login]") if ($? != 0);
open PIPE, "| sudo /usr/bin/smbpasswd -s $login >
/dev/null"
or fehler("Benutzer ändern,
Passwort (pipe open) [$login]");
print PIPE
"$password\n$password\n"
or fehler("Benutzer
ändern, Passwort (pipe write) [$login]");
close
PIPE
or fehler("Benutzer ändern, Passwort (pipe
close) [$login]");
}
`sudo
/usr/local/sbin/generate_apache_auth`;
$error = "Benutzer
$login geändert.";
&print_page_data;
}
Dateiname: /usr/local/sbin/user-status3.
#!/usr/bin/perl -wT
use
User::pwent;
# Path setzen, wegen Taint-Mode
$ENV{"PATH"}
= "/bin:/usr/bin";
# Parameter holen...
my
$action = shift;
my $login = shift;
# $login untainten
if
(defined($login)) {
$login =~ m/([\w\.-]+)/;
$login =
$1;
}
if (defined($action) && defined($login))
{
if ($action eq "-passwd") { &print_passwd();
}
elsif ($action eq "-locked") { &print_locked();
}
elsif ($action eq "-groups") { &print_groups();
}
elsif ($action eq "-change") { &print_change();
}
elsif ($action eq "-quota") { &print_quota(); }
}
print "fehlerhafte Argumente...\n";
print
"user-status action login\n";
print "action:
{-passwd|-locked|-groups|-change|-quota}\n";
exit 1;
sub
print_passwd {
my $user = getpwnam($login);
if
(crypt("passwort", $user->passwd) eq $user->passwd)
{
print $login;
} else {
print "---secure";
}
exit 0;
}
sub print_locked {
my $user =
getpwnam($login);
if (substr($user->passwd, 0, 1) eq "!")
{
print $login;
} else {
print "---unlocked";
}
exit 0;
}
sub print_groups {
my $groups = `id
-nG $login`;
print $groups;
exit 0;
}
sub
print_change {
open(SHADOW, "</etc/shadow");
my @data = <SHADOW>;
close(SHADOW);
my @user =
grep(/$login/, @data);
my $line = shift @user;
my $age =
(split(/:/, $line))[2];
$age = $age * 24 * 60 * 60;
my
$day;
my $mon;
my $year;
(undef, undef, undef, $day,
$mon, $year) = localtime($age);
$mon += 1;
$year += 1900;
if ($day < 10) { $day = "0$day"; }
if ($mon <
10) { $mon = "0$mon"; }
print "$day.$mon.$year";
exit 0;
}
sub print_quota {
my $ret = `quota -v
$login`;
$ret =~ tr/ //s;
my @zeilen = split /\n/, $ret;
my @quota = split / /, $zeilen[2];
$quota[2] =~ m/(\d+)/;
my $quota_used = $1;
$quota_used = int($quota_used/1024);
$quota[3] =~ m/(\d+)/;
my $quota_limit = $1;
$quota_limit =
int($quota_limit/1024);
print "$quota_used/$quota_limit
MB";
exit 0;
}
Das Programm dient dazu, die Benutzerverzeichnisse (public-html) anzuzeigen.
Dateiname: /usr/local/httpd/cgi-bin/benutzer.
#!/usr/bin/perl -w
use
CGI;
$html = new CGI;
$dir = "/home/public_html";
print
$html->header, $html->start_html('Öffentliche
Benutzer-Verzeichnisse');
print "Hier findet sich eine Liste
der auf diesem Server abgelegten
HTML-Angebote von Schülern
und Lehrern. Jeder, der ein eigenes
Benutzerkonto im Computerraum
hat, kann ein eigenes HTML-Angebot erstellen und
zwar einfach im
Verzeichnis <tt>public_html</tt> unterhalb des
Home-Verzeichnisses. Alle Dateien in diesem Verzeichnis mit
seinen
Unterverzeichnissen sind
öffentlich.<P>";
setpwent;
while (my
@user = getpwent) {
$userdir ="$dir/$user[0]";
if (-d $userdir) {
opendir DIR, $userdir;
rewinddir
DIR;
@dirlist = readdir DIR;
if (@dirlist > 2) {
$text='';
if (-s "$userdir/index.html")
{
open DATEI, "$userdir/index.html";
$text =
join '',<DATEI>;
close DATEI;
} elsif (-s
"$userdir/index.htm") {
open DATEI,
"$userdir/index.htm";
$text = join
'',<DATEI>;
close DATEI;
}
($titel)
=($text =~ m@<TITLE>(.*?)</TITLE>@is);
$titel =
($titel ? "; <i>Titel: $titel</i>":'');
$username = ($user[6] ? $user[6] : $user[0]);
print
$html->a({href=>"/~$user[0]/"},$username.$titel),$html-
br;
}
closedir
DIR;
}
}
endpwent;
print '<hr><p><a
href="/oldhomes/">Seiten ehemaliger
Schüler</a>';
print
$html->p,$html->a({href=>"/"},'Hier geht\'s
zurück zum Anfang.'),
$html->end_html;
Dateiname: /usr/local/httpd/htdocs/admin/netzstatus.cgi.
#!/usr/bin/perl
print
"Content-type: text/html\n\n";
my $uhrzeit =
localtime();
print <<HTML;
<html>
<head>
<title>Netzstatus</title>
</head>
<body>
<h1>Netzstatus</h1>
<i>$uhrzeit</i><p>
<table
border="1">
<tr><th>Host</th><th>Beschreibung</th><th>Erreichbar?</th></tr>
HTML
my
%hosts;
my %reachable;
$hosts{"192.168.0.1"} =
"server";
$hosts{"192.168.0.136"} = "Access
Point";
$hosts{"192.168.0.137"} = "PrintServer
R23 hpdj930c";
$hosts{"192.168.0.138"} = "Drucker
magicolor 2350 R23";
$hosts{"192.168.0.139"} =
"Drucker OkiPage R23";
$hosts{"192.168.0.254"}
= "Drucker HP LJ5 R104";
foreach (keys(%hosts)) {
my $ip = $_;
system("ping -nc1 $ip > /dev/null 2>&1");
my $ret = $?;
$reachable{$ip} = not $ret;
}
foreach
(keys(%hosts)) {
my $ip = $_;
print
qq(<tr><td>$ip</td><td>$hosts{$ip}</td>);
print qq(<td bgcolor="green">Ja</td>) if
($reachable{$ip});
print qq(<td bgcolor="red">Nein</td>)
if (not $reachable{$ip});
print qq(</tr>);
}
print
<<HTML;
</table>
</body>
</html>
HTML
Dateiname: /usr/local/sbin/ping.pl.
#!/usr/bin/perl
use
Net::Ping;
my $host = shift ||
"127.0.0.1";
chomp($host);
print $host;
my
$p = Net::Ping->new("icmp");
if ($p->ping($host))
{
print "\t1\n";
} else {
print
"\t0\n";
}
$p->close();
Dateiname: /usr/local/httpd/htdocs/admin/smbstatus.cgi.
#!/usr/bin/perl -wT
print
<<EOF;
Content-type: text/html
<html>
<head>
<title>Samba Status</title>
</head>
<body>
<h1>Samba
Status</h1>
<pre>
EOF
$ENV{"PATH"}
= "/usr/bin/";
system("/usr/bin/smbstatus
-b");
print <<EOF;
</pre>
</body>
</html>
EOF
exit
0;
Dateiname: /usr/local/httpd/htdocs/admin/samba-logger.cgi.
#!/usr/bin/perl
#
samba-logger.cgi
# 2002/03/20
# leichte änderung:
2004/07/19 für debian
# Andreas Dangel <a.dangel@gmx.de>
use
CGI;
#########################################################
##################
MAIN PROGRAM
#########################
#########################################################
$q
= new CGI;
print "Content-type: text/html\n\n";
print
"<html>\n";
print "<head>\n";
print
" <title>samba-logger</title>\n";
print
"</head>\n";
print "<body>\n";
print
"<h1>samba-logger</h1>\n";
$url =
$q->url();
print "<p>\n";
print "<a
href=\"$url\">samba-logger.cgi</a>\n";
print
"<p>\n";
if
(defined($q->param('logfile'))) {
$logfile =
$q->param('logfile');
@loglines = &openLogfile($logfile);
&analyze_loglines(\@loglines);
} else {
@SambaLogfiles = &getSambaLogfiles();
print "<form
method=\"post\">\n";
foreach(@SambaLogfiles)
{
print "<input type=\"radio\"
name=\"logfile\" value=\"$_\">$_<br>\n";
}
print "<input type=\"submit\"
name=\"submit\">\n";
print
"</form>\n";
}
print "<p>\n";
print
"<a href=\"$url\">samba-logger.cgi</a>\n";
print
"<p>\n";
print "<hr>\n";
print
"2002/03/20 - Andreas Dangel\n";
print
"</body>\n";
print "</html>";
#print
@SambaLogfiles;
#open(LOGFILE, "zcat $SambaLogfiles[1]
|");
#@lines = <LOGFILE>;
#close(LOGFILE);
#print
@lines;
#########################################################
#########################################################
sub
getSambaLogfiles {
@array = glob("/var/log/samba/log.smb*");
my @array2 = grep(!/smbd/, @array);
return @array2;
}
sub
openLogfile {
$file = shift;
if ( $file =~ s/\.gz// )
{
open(FHANDLE, "zcat $file |");
} else
{
open(FHANDLE, "$file");
}
@lines
= <FHANDLE>;
close(FHANDLE);
return
@lines;
}
sub analyze_loglines {
$samba_lines =
shift;
@input = @$samba_lines;
#print @input;
$zeilen = @input;
@data = ();
%logins = {};
for
($i = 0; $i < $zeilen; $i++) {
$zeile1 = $input[$i];
$i++;
$zeile2 = $input[$i];
if ($zeile1 =~
m/smbd\/service\.c\:make\_connection\(/) {
if ($zeile2 =~
m/connect\ to\ service\ netlogon\ as\ user\ /) {
$zeile1 =~ s/smbd\/service\.c\:make\_connection\(//;
$zeile2 =~ s/connect\ to\ service\ netlogon\ as\ user\ //;
$datum = substr($zeile1, 0, 24);
$datum =
substr($datum, 1, 19);
#chomp($datum = `date -d
\"$datum\" +\%s`);
$adresse =
substr($zeile2, index($zeile2, "("));
$adresse = substr($adresse, 1, index($adresse, ")")-1);
$rechner = substr($zeile2, 2, index($zeile2, "(")-3);
#$adresse .= " ($rechner)";
#$adresse =
substr($zeile2, 2, 23);
#$login = substr($zeile2,
25);
#$login = substr($login, 0, index($login, "("));
$login = substr($zeile2, index($zeile2, ")")+1);
$login = substr($login, 0, index($login, "("));
$logins{$adresse} = ["$adresse ($rechner)",
$datum, $login];
}
}
elsif ($zeile1 =~
m/smbd\/service\.c\:close\_cnum\(/) {
if ($zeile2 =~
m/closed\ connection\ to\ service\ pub/) {
$zeile1 =~
s/smbd\/service\.c\:close\_cnum\(//;
$zeile2 =~
s/closed\ connection\ to\ service\ pub//;
$datum =
substr($zeile1, 0, 24);
$datum = substr($datum, 1,
19);
#chomp($datum = `date -d \"$datum\"
+\%s`);
#$adresse = substr($zeile2, 2, 23);
$adresse = substr($zeile2, index($zeile2, "("));
$adresse = substr($adresse, 1, index($adresse, ")")-1);
if (exists($logins{$adresse})) {
$ref =
$logins{$adresse};
push(@$ref, $datum);
delete($logins{$adresse});
push(@data, $ref);
}
}
} else
{
$i--;
}
}
&sort(\@data);
&output(\@data);
}
sub sort {
$ref = shift;
@data = @$ref;
$lines = @data;
#print STDERR
"$lines\n";
for ($i = 0; $i < $lines - 1; $i++)
{
#printf STDERR "%d of %d (%.1f%%)\r", $i,
$lines-1, 100*$i/($lines-1);
for ($k = 0; $k <
$lines -1; $k++) {
$ref_a = $data[$k];
$ref_b = $data[$k + 1];
$time_a = @$ref_a[1];
#chomp($time_a = `date -d \"$time_a\" +%s`);
$time_b = @$ref_b[1];
#chomp($time_b = `date
-d \"$time_b\" +%s`);
if ($time_a gt
$time_b) {
#print "$time_a $time_b\n";
$data[$k] = $ref_b;
$data[$k + 1] =
$ref_a;
}
}
#exit;
}
}
sub output {
$ref = shift;
@data =
@$ref;
print "<table border=1>\n";
print
"<tr><th>Anmeldung</th><th>Benutzer</th><th>IP-
dresse</th><th>Abmeldung</th></tr>\n";
foreach (@data) {
$ref = $_;
$newline =
"<tr><td>" . @$ref[1] . "</td>";
$newline .= "<td>" . @$ref[2] . "</td>";
$newline .= "<td>" . @$ref[0] . "</td>";
$newline .= "<td>" . @$ref[3] .
"</td></tr>";
print $newline;
}
print "</table>\n";
}
Version 1.2, November 2002
Copyright (C) 2000,2001,2002 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
0. PREAMBLE
The purpose of this License is to make a manual, textbook, or other functional and useful document "free" in the sense of freedom: to assure everyone the effective freedom to copy and redistribute it, with or without modifying it, either commercially or noncommercially. Secondarily, this License preserves for the author and publisher a way to get credit for their work, while not being considered responsible for modifications made by others.
This License is a kind of "copyleft", which means that derivative works of the document must themselves be free in the same sense. It complements the GNU General Public License, which is a copyleft license designed for free software.
We have designed this License in order to use it for manuals for free software, because free software needs free documentation: a free program should come with manuals providing the same freedoms that the software does. But this License is not limited to software manuals; it can be used for any textual work, regardless of subject matter or whether it is published as a printed book. We recommend this License principally for works whose purpose is instruction or reference.
1. APPLICABILITY AND DEFINITIONS
This License applies to any manual or other work, in any medium, that contains a notice placed by the copyright holder saying it can be distributed under the terms of this License. Such a notice grants a world-wide, royalty-free license, unlimited in duration, to use that work under the conditions stated herein. The "Document", below, refers to any such manual or work. Any member of the public is a licensee, and is addressed as "you". You accept the license if you copy, modify or distribute the work in a way requiring permission under copyright law.
A "Modified Version" of the Document means any work containing the Document or a portion of it, either copied verbatim, or with modifications and/or translated into another language.
A "Secondary Section" is a named appendix or a front-matter section of the Document that deals exclusively with the relationship of the publishers or authors of the Document to the Document's overall subject (or to related matters) and contains nothing that could fall directly within that overall subject. (Thus, if the Document is in part a textbook of mathematics, a Secondary Section may not explain any mathematics.) The relationship could be a matter of historical connection with the subject or with related matters, or of legal, commercial, philosophical, ethical or political position regarding them.
The "Invariant Sections" are certain Secondary Sections whose titles are designated, as being those of Invariant Sections, in the notice that says that the Document is released under this License. If a section does not fit the above definition of Secondary then it is not allowed to be designated as Invariant. The Document may contain zero Invariant Sections. If the Document does not identify any Invariant Sections then there are none.
The "Cover Texts" are certain short passages of text that are listed, as Front-Cover Texts or Back-Cover Texts, in the notice that says that the Document is released under this License. A Front-Cover Text may be at most 5 words, and a Back-Cover Text may be at most 25 words.
A "Transparent" copy of the Document means a machine-readable copy, represented in a format whose specification is available to the general public, that is suitable for revising the document straightforwardly with generic text editors or (for images composed of pixels) generic paint programs or (for drawings) some widely available drawing editor, and that is suitable for input to text formatters or for automatic translation to a variety of formats suitable for input to text formatters. A copy made in an otherwise Transparent file format whose markup, or absence of markup, has been arranged to thwart or discourage subsequent modification by readers is not Transparent. An image format is not Transparent if used for any substantial amount of text. A copy that is not "Transparent" is called "Opaque".
Examples of suitable formats for Transparent copies include plain ASCII without markup, Texinfo input format, LaTeX input format, SGML or XML using a publicly available DTD, and standard-conforming simple HTML, PostScript or PDF designed for human modification. Examples of transparent image formats include PNG, XCF and JPG. Opaque formats include proprietary formats that can be read and edited only by proprietary word processors, SGML or XML for which the DTD and/or processing tools are not generally available, and the machine-generated HTML, PostScript or PDF produced by some word processors for output purposes only.
The "Title Page" means, for a printed book, the title page itself, plus such following pages as are needed to hold, legibly, the material this License requires to appear in the title page. For works in formats which do not have any title page as such, "Title Page" means the text near the most prominent appearance of the work's title, preceding the beginning of the body of the text.
A section "Entitled XYZ" means a named subunit of the Document whose title either is precisely XYZ or contains XYZ in parentheses following text that translates XYZ in another language. (Here XYZ stands for a specific section name mentioned below, such as "Acknowledgements", "Dedications", "Endorsements", or "History".) To "Preserve the Title" of such a section when you modify the Document means that it remains a section "Entitled XYZ" according to this definition.
The Document may include Warranty Disclaimers next to the notice which states that this License applies to the Document. These Warranty Disclaimers are considered to be included by reference in this License, but only as regards disclaiming warranties: any other implication that these Warranty Disclaimers may have is void and has no effect on the meaning of this License.
2. VERBATIM COPYING
You may copy and distribute the Document in any medium, either commercially or noncommercially, provided that this License, the copyright notices, and the license notice saying this License applies to the Document are reproduced in all copies, and that you add no other conditions whatsoever to those of this License. You may not use technical measures to obstruct or control the reading or further copying of the copies you make or distribute. However, you may accept compensation in exchange for copies. If you distribute a large enough number of copies you must also follow the conditions in section 3.
You may also lend copies, under the same conditions stated above, and you may publicly display copies.
3. COPYING IN QUANTITY
If you publish printed copies (or copies in media that commonly have printed covers) of the Document, numbering more than 100, and the Document's license notice requires Cover Texts, you must enclose the copies in covers that carry, clearly and legibly, all these Cover Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on the back cover. Both covers must also clearly and legibly identify you as the publisher of these copies. The front cover must present the full title with all words of the title equally prominent and visible. You may add other material on the covers in addition. Copying with changes limited to the covers, as long as they preserve the title of the Document and satisfy these conditions, can be treated as verbatim copying in other respects.
If the required texts for either cover are too voluminous to fit legibly, you should put the first ones listed (as many as fit reasonably) on the actual cover, and continue the rest onto adjacent pages.
If you publish or distribute Opaque copies of the Document numbering more than 100, you must either include a machine-readable Transparent copy along with each Opaque copy, or state in or with each Opaque copy a computer-network location from which the general network-using public has access to download using public-standard network protocols a complete Transparent copy of the Document, free of added material. If you use the latter option, you must take reasonably prudent steps, when you begin distribution of Opaque copies in quantity, to ensure that this Transparent copy will remain thus accessible at the stated location until at least one year after the last time you distribute an Opaque copy (directly or through your agents or retailers) of that edition to the public.
It is requested, but not required, that you contact the authors of the Document well before redistributing any large number of copies, to give them a chance to provide you with an updated version of the Document.
4. MODIFICATIONS
You may copy and distribute a Modified Version of the Document under the conditions of sections 2 and 3 above, provided that you release the Modified Version under precisely this License, with the Modified Version filling the role of the Document, thus licensing distribution and modification of the Modified Version to whoever possesses a copy of it. In addition, you must do these things in the Modified Version:
A. Use in the Title Page (and on the covers, if any) a title distinct from that of the Document, and from those of previous versions (which should, if there were any, be listed in the History section of the Document). You may use the same title as a previous version if the original publisher of that version gives permission.
B. List on the Title Page, as authors, one or more persons or entities responsible for authorship of the modifications in the Modified Version, together with at least five of the principal authors of the Document (all of its principal authors, if it has fewer than five), unless they release you from this requirement.
C. State on the Title page the name of the publisher of the Modified Version, as the publisher.
D. Preserve all the copyright notices of the Document.
E. Add an appropriate copyright notice for your modifications adjacent to the other copyright notices.
F. Include, immediately after the copyright notices, a license notice giving the public permission to use the Modified Version under the terms of this License, in the form shown in the Addendum below.
G. Preserve in that license notice the full lists of Invariant Sections and required Cover Texts given in the Document's license notice.
H. Include an unaltered copy of this License.
I. Preserve the section Entitled "History", Preserve its Title, and add to it an item stating at least the title, year, new authors, and publisher of the Modified Version as given on the Title Page. If there is no section Entitled "History" in the Document, create one stating the title, year, authors, and publisher of the Document as given on its Title Page, then add an item describing the Modified Version as stated in the previous sentence.
J. Preserve the network location, if any, given in the Document for public access to a Transparent copy of the Document, and likewise the network locations given in the Document for previous versions it was based on. These may be placed in the "History" section. You may omit a network location for a work that was published at least four years before the Document itself, or if the original publisher of the version it refers to gives permission.
K. For any section Entitled "Acknowledgements" or "Dedications", Preserve the Title of the section, and preserve in the section all the substance and tone of each of the contributor acknowledgements and/or dedications given therein.
L. Preserve all the Invariant Sections of the Document, unaltered in their text and in their titles. Section numbers or the equivalent are not considered part of the section titles.
M. Delete any section Entitled "Endorsements". Such a section may not be included in the Modified Version.
N. Do not retitle any existing section to be Entitled "Endorsements" or to conflict in title with any Invariant Section.
O. Preserve any Warranty Disclaimers.
If the Modified Version includes new front-matter sections or appendices that qualify as Secondary Sections and contain no material copied from the Document, you may at your option designate some or all of these sections as invariant. To do this, add their titles to the list of Invariant Sections in the Modified Version's license notice. These titles must be distinct from any other section titles.
You may add a section Entitled "Endorsements", provided it contains nothing but endorsements of your Modified Version by various parties--for example, statements of peer review or that the text has been approved by an organization as the authoritative definition of a standard.
You may add a passage of up to five words as a Front-Cover Text, and a passage of up to 25 words as a Back-Cover Text, to the end of the list of Cover Texts in the Modified Version. Only one passage of Front-Cover Text and one of Back-Cover Text may be added by (or through arrangements made by) any one entity. If the Document already includes a cover text for the same cover, previously added by you or by arrangement made by the same entity you are acting on behalf of, you may not add another; but you may replace the old one, on explicit permission from the previous publisher that added the old one.
The author(s) and publisher(s) of the Document do not by this License give permission to use their names for publicity for or to assert or imply endorsement of any Modified Version.
5. COMBINING DOCUMENTS
You may combine the Document with other documents released under this License, under the terms defined in section 4 above for modified versions, provided that you include in the combination all of the Invariant Sections of all of the original documents, unmodified, and list them all as Invariant Sections of your combined work in its license notice, and that you preserve all their Warranty Disclaimers.
The combined work need only contain one copy of this License, and multiple identical Invariant Sections may be replaced with a single copy. If there are multiple Invariant Sections with the same name but different contents, make the title of each such section unique by adding at the end of it, in parentheses, the name of the original author or publisher of that section if known, or else a unique number. Make the same adjustment to the section titles in the list of Invariant Sections in the license notice of the combined work.
In the combination, you must combine any sections Entitled "History" in the various original documents, forming one section Entitled "History"; likewise combine any sections Entitled "Acknowledgements", and any sections Entitled "Dedications". You must delete all sections Entitled "Endorsements."
6. COLLECTIONS OF DOCUMENTS
You may make a collection consisting of the Document and other documents released under this License, and replace the individual copies of this License in the various documents with a single copy that is included in the collection, provided that you follow the rules of this License for verbatim copying of each of the documents in all other respects.
You may extract a single document from such a collection, and distribute it individually under this License, provided you insert a copy of this License into the extracted document, and follow this License in all other respects regarding verbatim copying of that document.
7. AGGREGATION WITH INDEPENDENT WORKS
A compilation of the Document or its derivatives with other separate and independent documents or works, in or on a volume of a storage or distribution medium, is called an "aggregate" if the copyright resulting from the compilation is not used to limit the legal rights of the compilation's users beyond what the individual works permit. When the Document is included in an aggregate, this License does not apply to the other works in the aggregate which are not themselves derivative works of the Document.
If the Cover Text requirement of section 3 is applicable to these copies of the Document, then if the Document is less than one half of the entire aggregate, the Document's Cover Texts may be placed on covers that bracket the Document within the aggregate, or the electronic equivalent of covers if the Document is in electronic form. Otherwise they must appear on printed covers that bracket the whole aggregate.
8. TRANSLATION
Translation is considered a kind of modification, so you may distribute translations of the Document under the terms of section 4. Replacing Invariant Sections with translations requires special permission from their copyright holders, but you may include translations of some or all Invariant Sections in addition to the original versions of these Invariant Sections. You may include a translation of this License, and all the license notices in the Document, and any Warranty Disclaimers, provided that you also include the original English version of this License and the original versions of those notices and disclaimers. In case of a disagreement between the translation and the original version of this License or a notice or disclaimer, the original version will prevail.
If a section in the Document is Entitled "Acknowledgements", "Dedications", or "History", the requirement (section 4) to Preserve its Title (section 1) will typically require changing the actual title.
9. TERMINATION
You may not copy, modify, sublicense, or distribute the Document except as expressly provided for under this License. Any other attempt to copy, modify, sublicense or distribute the Document is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance.
10. FUTURE REVISIONS OF THIS LICENSE
The Free Software Foundation may publish new, revised versions of the GNU Free Documentation License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. See http://www.gnu.org/copyleft/.
Each version of the License is given a distinguishing version number. If the Document specifies that a particular numbered version of this License "or any later version" applies to it, you have the option of following the terms and conditions either of that specified version or of any later version that has been published (not as a draft) by the Free Software Foundation. If the Document does not specify a version number of this License, you may choose any version ever published (not as a draft) by the Free Software Foundation.
How to use this License for your documents
To use this License in a document you have written, include a copy of the License in the document and put the following copyright and license notices just after the title page:
Copyright (c) YEAR YOUR NAME.
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.2
or any later version published by the Free Software Foundation;
with no Invariant Sections, no Front-Cover Texts, and no Back-Cover
Texts. A copy of the license is included in the section entitled "GNU
Free Documentation License".
If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts, replace the "with...Texts." line with this:
with the Invariant Sections being LIST THEIR TITLES, with the
Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST.
If you have Invariant Sections without Cover Texts, or some other combination of the three, merge those two alternatives to suit the situation.
If your document contains nontrivial examples of program code, we recommend releasing these examples in parallel under your choice of free software license, such as the GNU General Public License, to permit their use in free software.
This is an unofficial translation of the GNU Free Documentation License into German. It was not published by the Free Software Foundation, and does not legally state the distribution terms for documentation that uses the GNU FDL--only the original English text of the GNU FDL does that. However, we hope that this translation will help German speakers understand the GNU FDL better.
Dies ist eine inoffzielle deutsche Übersetzung der GNU Free Documentation License. Sie ist nicht von der Free Software Foundation herausgegeben und erläutert nicht die Bedingungen der GNU FDL -- Dies tut nur der original englische Text der GNU FDL. Dennoch hoffen wir, dass diese Übersetzung mit dazu beiträgt deutschsprachigen Personen das Verstehen der GNU FDL zu erleichtern.
Präambel
Der Zweck dieser Lizenz ist es, ein Handbuch,
Textbuch oder ein anderes zweckdienliches und nützliches
Dokument frei, im Sinne von Freiheit, zu machen; jedermann die
Freiheit zu sichern, es zu kopieren und mit oder ohne Änderungen
daran, sowohl kommerziell als auch nicht kommerziell weiter zu
verbreiten.
Weiterhin sichert diese Lizenz einem Autor oder
Verleger die Möglichkeit, Anerkennung für seine Arbeit zu
erhalten ohne für Änderungen durch Andere verantwortlich
gemacht zu werden.
Diese Lizenz ist eine Art des "copyleft",
was bedeutet, daß von diesem Dokument abgeleitete Werke
ihrerseits in derselben Weise frei sein müssen.
Dies
vervollständigt die GNU General Public License, die eine
"copyleft"-Lizenz ist, und für freie Software
entworfen wurde.
Diese Lizenz wurde für Handbücher für
freie Software entworfen, denn frei Software braucht freie
Dokumentation: Ein freies Programm sollte von Handbüchern
begleitet sein, die dieselben Freiheiten bieten, die auch die
Software selbst bietet.
Diese Lizenz ist aber nicht auf
Softwarehandbücher beschränkt; vielmehr kann sie für
jede Art von textuellen Werken verwendet werden, unabhängig
davon, was das Thema ist, oder ob es als gedrucktes Buch
veröffentlicht wurde. Wir empfehlen diese Lizenz prinzipiell für
Werke, die als Anleitungen oder Referenzen dienen sollen.
1. Anwendbarkeit und Definitionen
Diese Lizenz findet Anwendung auf jedes Handbuch
oder andere Werk, unabhängig von dem Medium, auf dem es
erscheint, das einen vom Rechteinhaber eingefügten Hinweis
enthält, der besagt, daß das Werk unter den Bedingungen
dieser Lizenz verbreitet werden darf.
Ein solcher Hinweis gewährt
eine weltweit gültige, tantiemenfreie und zeitlich unbefristete
Lizenz, die es gestattet das Werk, unter den hier festgelegten
Bedingungen, zu nutzen.
Der Begriff Dokument wird im
Folgenden für alle solche Handbücher und Werke
verwendet.
Jede Person kann Lizenznehmer sein und wird im
Folgenden mit Sie angesprochen.
Sie akzeptieren diese
Lizenz, wenn Sie ein Dokument derart kopieren, verändern oder
verteilen, daß Sie gemäß den Gesetzen zum Copyright
die Erlaubnis benötigen.
Eine modifizierte Version des Dokumentes steht für jedes Werk, das das Dokument als Ganzes oder in Teilen enthält, sowohl auf Datenträger kopiert, als auch mit Änderungen und/oder in andere Sprachen übersetzt.
Ein zweitrangiger Abschnitt ist ein
benannter Anhang oder eine Enleitung des Dokumentes, der sich
ausschließlich mit dem Verhältnis des Autors oder
Verlegers des Dokumentes zu dem eigentlichen Thema des Dokumentes
(oder damit zusammenhängender Dinge) beschäftigt, und der
nichts enthält, das direkt zu dem eigentlichen Thema gehört.
(Wenn das Dokument beispielweise ein Buch über Mathematik ist,
dann darf ein zweitrangiger Abschnitt nichts über Mathematik
enthalten).
Dies kann eine historische Beziehung zu dem Thema,
oder damit zusammenhängender Dinge, oder von gesetzlicher,
gesellschaftlicher, philosophischer, ethischer oder politischer Art
sein, die das Thema betreffen.
Die unveränderlichen Abschnitte sind
benannte zweitrangige Abschnitte, deren Titel als unveränderlicher
Abschnitt in dem Lizenhinweis, der das Dokument unter diese Lizenz
stellt, aufgeführt sind.
Wenn ein Abschnitt nicht in die oben
stehende Definition eines zweitrangigen Abschnittes passt, dann ist
es nicht erlaubt diesen Bereich als unveränderlichen Bereich zu
kennzeichnen.
Umschlagtexte sind bestimmte, kurze
Textstücke, die als vorderer Umschlagtext oder als
hinterer Umschlagtext in der Notiz benannt werden, die besagt,
dass das Dokument unter dieser Lizenz freigegeben ist.
Ein
vorderer Umschlagtext kann bis zu 5 Worte enthalten, ein hinterer
Umschlagtext bis zu 25 Worte.
Eine transparente Kopie des Dokumentes
bezeichnet eine maschinenlesbare Kopie, dargestellt in einem Format,
dessen Spezifikationen allgemein verfügbar sind, und das
geeignet ist das Dokument auf einfache Weise mit einem allgemeinen
Texteditor oder (für Bilder, die aus Pixeln bestehen) mit einem
allgemeinen Bildberabeitungsprogramm oder (für Zeichnungen) mit
einem häufig verfügbaren Zeichenprogramm zu überarbeiten,
und das geeignet ist es als Eingabe für Textformatierer zu
verwenden, oder als Eingabe für automatische
Konvertierungsprogramme, die eine Reihe von unterschiedlichen
Formaten erzeugen, die ihrerseits als Eingabe für
Textformatierer verwendet werden können. Eine Kopie in ein
anderes transparentes Dateiformat dessen Auszeichnung oder das fehlen
der Auszeichnungen derart beschaffen sind, nachfolgende
Modifikationen durch die Leser zu verhindern oder zu erschweren ist
nicht transparent
Ein Bildformat ist nicht transparent, wenn es
für eine wesentliche Menge von Text verwendet wird.
Eine
Kopie, die nicht transparent ist, wird als opak bezeichnet.
Beispiele verwendbarer Formate für transparente Kopien schliessen einfachen ASCII-Text ohne Auszeichnungen, TeX-info Eingabe, LaTeX-Eingabeformat, SGML oder XML, sofern die verwendete DTD öffentlich verfügbar ist, sowie standardkonformes, einfaches HTML, Postscript oder PDF, die für Veränderungen durch Menschen entworfen sind, ein.
Beispiele für transparente Bildformate sind
u.a. PNG, XCF und JPG.
Opake Formate sind unter anderen solche
proprietären Formate, die nur von proprietären
Textverarbeitungsprogramm gelesen und bearbeitet werden können,
SGML oder XML deren DTD und/oder Verarbeitungswerkzeuge nicht
allgemein verfügbar sind, und maschinengeneriertes HTML,
PostScript oder PDF, das von manchen Textverarbeitungsprogrammen nur
zu Ausgabezwecken erzeugt wird.
Mit Titelseite wird in einem gedruckten
Buch die eigentliche Titelseite sowie die direkt darauf folgenden
Seiten bezeichnet, die all das in lesbarer Form enthalten, was in
dieser Lizenz gefordert ist, dass es auf der Titelseite erscheinen
muss.
Für Werke, die in Formaten vorliegen, die keine
Titelseiten haben, gilt als Titelseite der Text, der der
auffälligsten Darstellung des Titels des Werkes direkt folgt,
aber noch vor dem Inhalt des Werkes steht.
Ein Abschnitt mit dem Titel xyz bezeichnent einen
benannten Unterbereich des Dokumentes, dessen Titel entweder genau
xyz ist, oder der xyz in Anführungszeichen enthält, der
einem Text folgt, der xyz in eine andere Sprache übersetzt.
(Hier steht xyz für einen speziellen Abschnittsnamen, der im
Folgenden erwähnt wird wie"Danksagung"(Acknowledgements),
"Widmung"(Dedications), "Anmerkung"(Endorsement)
oder "Historie"(History).).
Den Titel erhalten
eines Abschnittes bedeutet, daß beim Modifizieren des
Dokumentes dieser Abschnitt mit dem Titel xyz bleibt, wie es in
dieser Definition festgelegt ist.
Das Dokument kann direkt hinter der Notiz, die besagt, dass das Dokument unter dieser Lizenz freigegeben ist, Garantieausschlüsse enthalten. Diese Garantieausschlüsse werden so behandelt, asl seien sie als Referenzen in diese Lizenz eingeschlossen, allerdings nur um Garantien auszuschliessen: Jede andere Implizierung, die dieser Ausschluss hat ist ungültig und keine Wirkung im Sinne dieser Lizenz.
2. Datenträgerkopien
Sie dürfen das Dokument auf jedem Medium
sowohl kommerziell als auch nicht kommerziell kopieren und
verbreiten, vorausgesetzt, daß diese Lizenz, die
Copyright-Hinweise sowie der Lizenzhinweis, der besagt, daß
diese Lizenz auf das Dokument anzuwenden ist, in allen Kopien
reproduziert wird, und daß keine weiteren Bedingungen jeglicher
Art zu denen dieser Lizenz hinzugefügt werden.
Sie dürfen
in den Kopien, die Sie erstellen oder verbreiten, keinerlei
technische Maßnahmen treffen um das Lesen oder das weitere
Kopieren zu erschweren oder zu kontrollieren. Dennoch dürfen Sie
Gegenleistungen für Kopien akzeptieren. Wenn Sie eine
ausreichend große Menge von Kopien verteilen, müssen Sie
zusätzlich die bestimmungen von Ziffer 3 beachten.
Sie können
ausserdem unter denselben Bedingungen, die oben angeführt sind,
Kopien verleihen und sie können Kopien auch öffentlich
bewerben.
3. Kopien in Stückzahlen
Wenn Sie gedruckte Kopien des Dokumentes (oder
Kopien auf Medien, die üblicherweise gedruckte Umschläge
haben), in einer Stückzahl von mehr als 100 veröffentlichen,
und der Lizenzhinweis des Dokumentes Umschlagtexte verlangt, müssen
die Kopien in Hüllen verpackt sein, die alle diese Umschlagtexte
klar und lesbar enthalten. Die vorderen Umschlagtexte auf dem
vorderen Umschlag, die hinteren Umschlagtexte auf dem hinteren
Umschlag.
Beide Umschläge müssen Sie ausserdem klar und
lesbar als den Herausgeber dieser Kopien benennen.
Der vordere
Umschlag muss den gesamten Titel darstellen, mit allen Worten gleich
auffällig und sichtbar. Sie können weiteres Material den
Umschlägen hinzufügen.
Das Kopieren mit Änderungen,
die auf Umschläge begrenzt sind, können, so lange der Titel
des Dokuments erhalten bleibt, ansonsten als Datenträgerkopien
behandelt werden.
Wenn der vorgeschriebene Text für einen der Umschläge zu umfangreich ist um lesbar zu bleiben, sollten Sie den ersten der aufgelisteten Texte auf den aktuellen Umschlag nehmen (so viel wie vernünftigerweise möglich ist) und den Rest auf direkt angrenzenden Seiten.
Wenn Sie mehr als 100 opake Kopien veröffentlichen oder verbreiten, müssen Sie entweder eine maschinenlesbare, transparente Kopie jeder opaken Kopie beilegen, oder mit bzw. in jeder opaken Kopie eine Computer-Netzwerk Adresse angeben, von wo die allgemeine, netzwerk benutzende Öffentlichkeit, Zugriff zum Download einer kompletten transparenten Kopie über öffentliche Standardnetzwerkprotokolle hat.
Wenn Sie sich für die letztere Möglichkeit entscheiden, müssen Sie mit Beginn der Verbreitung der opaken Kopien in Stückzahlen, zumutbare und vernünftige Schritte unternehmen, um sicher zu stellen, daß die transparenten Kopien mindestens ein Jahr nach der Auslieferung der letzten opaken Kopie (direkt oder über einen Agenten oder Händler) dieser Ausgabe an die Öffentlichkeit, an der genannten Adresse verfügbar bleiben.
Es ist erbeten, aber nicht gefordert, daß Sie ausreichend lange vor der Auslieferung einer grösseren Menge von Kopien, Kontakt mit den Autoren des Dokumentes aufnehmen, um jenen die Möglichkeit zu geben, Ihnen eine aktualisierte Version des Dokumentes zuzuleiten.
4. Modifikationen
Unter den obigen Bedingungen unter Ziffer 2 und 3
können Sie modifizierte Versionen kopieren und verbreiten,
vorausgesetzt, daß Sie die modifizierte Version unter exakt
dieser Lizenz herausgeben, wobei die modifizierte Version die Rolle
des Dokumentes einnimmt, und dadurch die weitere Modifikation und
Verbreitung an jeden Lizensieren, der eine Kopie davon
besitzt.
Zusätzlich müssen Sie die folgenden Dinge in
der modifizierten Version beachten:
Benutzen Sie auf der
Titelseite (und auf Umschlägen, sofern vorhanden) einen Titel, der sich
von dem Titel des Dokumentes und von früheren Versionen unterscheidet.
(Die früheren Versionen sollten, wenn es welche gibt, in dem Abschnitt Historie
aufgelistet werden.)
Sie können denselben Titel wie den einer Vorgängerversion verwenden,
wenn der ursprüngliche Herausgeber damit einverstanden ist.
Geben Sie auf der Titelseite eine oder mehrere Personen oder Einheiten, die als Autoren auftreten können, als für die Modifikationen verantwortliche Autoren der modifizierten Version, zusammen mit mindestens fünf der ursprünglichen Autoren der Ursprungsversion an (alle vorherige Autoren, wenn es weniger als fünf sind), es sei denn diese befreien Sie von dieser Notwendigkeit.
Geben Sie auf der Titelseite den Namen des Herausgebers als Herausgeber an.
Erhalten Sie alle Copyright-Vermerke des Dokumentes.
Setzen Sie einen passenden Copyright-Vermerk für Ihre Modifikationen direkt hinter die anderen Copyright-Vermerke.
Schliessen Sie direkt hinter den Copyright-Vermerken einen Lizenzhinweis ein, der die öffentliche Erlaubnis erteilt, die modifizierte Version unter den Bedingungen dieser Lizenz zu benutzen, wie es im Anhang weiter unten beschrieben ist.
Erhalten Sie im Copyright-Vermerk die komplette Liste der unveränderlichen Abschnitte und obligatorischen Umschlagtexte, die in dem Lizenzvermerk des Dokumentes aufgeführt sind.
Schliessen Sie eine unveränderte Kopie dieser Lizenz mit ein.
Erhalten Sie den Abschnitt "Historie". Erhalten Sie den Titel und fügen Sie einen Punkt hinzu der mindestens den Titel, das Jahr, die neuen Autoren und Herausgeber, wie sie auf der Titelseite aufgeführt sind, enthält. Sollte es keinen Abschnitt Historie geben, dann erstellen Sie einen, der Titel, Jahr, Autor und Herausgeber des Dokumentes, wie auf der Titelseite angegeben, enthält und fügen Sie einen Punkt hinzu, der die modifizierte Version wie oben dargestellt beschreibt.
Erhalten Sie die Netzwerkadresse, die angegeben wurde, um Zugang zu einer transparenten Kopie zu gewähren, sowie entsprechend angegebene Adressen früherer Versionen, auf denen das Dokument aufbaute. Diese Angaben können in den Abschnitt Historie verschoben werden. Sie können die Netzwerkadresse weglassen, wenn sie sich auf ein Werk bezieht, das mindestens 4 Jahre vor dem Dokument selbst veröffentlicht wurde, oder wenn der ursprüngliche Herausgeber der Version, auf die sich die Adresse bezieht, seine Erlaubnis erteilt.
Erhalten Sie für alle Abschnitt, die als Danksagungen(Acknowledgements) oder Widmungen(Dedications) überschrieben sind, den Titel sowie die Substanz und den Ton aller vom Geber gemachten Danksagungen und/oder Widmungen in diesem Abschnitt.
Erhalten Sie alle unveränderlichen Abschnitte unverändert, sowohl im Titel als auch im Text. Abschnittsnummern oder dergleichen gelten hierbei nicht als Teil des Titels.
Löschen Sie alle Abschnitte, die als Anmerkungen(Endorsements) überschrieben sind. Ein solchen Abschnitt sollte nicht in der modifizierten Version enthalten sein.
Benennen Sie keinen Abschnitt in Anmerkungen um, oder in einen Namen, der in Konflikt mit einem unveränderlichen Abschnitt gerät.
Erhalten Sie alle Garantieausschlüsse.
Wenn die modifizierte Version neue Vorspannabschnitte oder Anhänge enthält, die zweitrangige Abschnitte sein können, und die kein vom Dokument kopiertes Material enthalten, können Sie, nach Ihrem Belieben, einige oder alle diese Abschnitte als unveränderliche Abschnitte in die Lizenzanmerkung der modifizierten Version aufnehmen. Diese Titel müssen sich von allen anderen Titeln unterscheiden.
Sie können einen Abschnitt Anmerkungen
anfügen, sofern dieser nichts als Bemerkungen, verschiedener
Stellen, zu der modifizierten Version enthält.
Beispielsweise
Publikumsreaktionen oder eine Mitteilung, daß der Text von
einer Organisation als maßgebliche Definition eines Standards
geprüft wurde.
Sie können einen Teil mit bis zu fünf
Worten als vorderen Umschlagtext und einen mit bis zu 25 Worten als
hinteren Umschlagtext an das Ende der Liste mit den Umschlagtexten
der modifizierten Version hinzufügen.
Nur je ein Teil für
den vorderen Umschlagtext und den hinteren Umschlagtext können
von jeder Einheit hinzugefügt (oder durch entsprechende
Anordnung erstellt) werden.
Wenn das Dokument bereits einen Umschlagtext für denselben Umschlag enthält, das von Ihnen oder der Einheit, in deren Namen Sie tätig sind, bereits früher eingefügt wurde, dürfen Sie keine neue hinzufügen. Sie können aber den alten ersetzen, wenn sie die ausdrückliche Genehmigung des Herausgebers haben, der den früheren Text eingefügt hat.
Der/die Autor(en) und Herausgeber des Dokumentes geben duch diese Lizenz weder implizit noch explizit die Erlaubnis ihren Namen für Werbung in den Anmerkungen der modifizierten Version zu benutzen.
5. Dokumente Kombinieren
Sie können mehrere Dokumente, die unter dieser Lizenz freigegeben sind, unter den Bedingungen unter Ziffer 4 für modifizierte Versionen miteinander kombinieren, vorausgesetzt, daß in der Kombination alle unveränderlichen Abschnitte aller Originaldokumente, enthalten sind, und daß Sie diese alle in der Liste der unveränderlichen Abschnitte der Lizenzanmerkung des kombinierten Dokumentes aufführen, sowie alle Garantieausschlüsse erhalten.
Das kombinierte Werk braucht nur eine Kopie dieser
Lizenz zu enthalten, und mehrere identische unveränderliche
Abschnitte können durch eine einzelne Kopie ersetzt werden.
Wenn
es mehrere unveränderliche Abschnitte mit unterschiedlichem
Inhalt aber gleichem Namen gibt, machen Sie den Namen eindeutig,
indem Sie am Ende des Titels, in Anführungszeichen, den Namen
des original Autors oder Herausgebers, falls bekannt, oder
andernfalls eine eindeutige Nummer anhängen.
Machen Sie
dasselbe mit den Titeln der Abschnitte in der Liste der
unveränderlichen Abschnitte im Lizenzhinweis des kombinierten
Werkes.
In der Kombination müssen Sie alle Abschnitte mit dem Titel Historie in den unterschiedlichen Dokumenten zu einem einzelnen Abschnit Historie zusammenführen; entsprechend verfahren Sie mit den Abschnitten Danksagungen und Widmungen. Sie müssen alle Abschnitte mit dem Titel Anmerkungen löschen.
6. Sammlungen von Dokumenten
Sie können eine Sammlung von Dokumenten erstellen, bestehend aus diesem Dokument und weiteren, unter dieser Lizenz stehenden Dokumenten, wobei Sie die einzelnen Kopien dieser Lizenz in den verschiedenen Dokumenten durch eine einzelne Kopie, die in der Sammlung enthalten ist, ersetzen, vorausgesetzt, Sie befolgen in allen andern Punkten, für jedes der Dokumente, die Regeln für Datenträgerkopien.
Sie können ein einzelnes Dokument aus einer solchen Sammlung herausziehen und einzeln unter dieser Lizenz verbreiten, vorausgesetzt, Sie fügen eine Kopie dieser Lizenz in das extrahierte Dokument ein, und befolgen ansonsten die Bedingungen dieser Lizenz für Datenträgerkopien.
7. Aggregation mit unabhängigen Werken
Eine Zusammenstellung des Werkes, oder von
Ableitungen davon, mit anderen, separaten und unabhängigen
Dokumenten oder Werken, in oder auf demselben Band eines Speicher-
oder Verbreitungsmediums, wird dann eine Aggregation genannt, wenn
die Copyrights der Zusammenstellung nicht dazu verwendet werden die
Rechte der Benutzer, die für die einzelnen Werke gewährt
werden, stärker zu beschränken als dies durch die Lizenzen
der einzelnen Werke geschieht.
Wenn das Werk in einer Aggregation
vorhanden ist, so gilt diese Lizenz nicht für die anderen Werke
dieser Aggregation, die keine Ableitung des Dokumentes sind.
Wenn die Bestimmungen für die Umschlagtexte
aus Ziffer 3 Anwendung finden, und wenn das Dokument weniger als die
Hälfte der gesammten Aggregation ausmacht, dann können die
Umschlagtexte auf Seiten gesetzt werden, die das Dokument innerhalb
der Aggregation umschliessen, oder auf das elektronische Äquivalent
eines Umschlages, wenn das Dokument in elektronischer Form
vorliegt.
Andernfalls müssen sie auf gedruckten Umschlägen
erscheinen, die das gesamte Werk umschliessen.
8. Übersetzung
Übersetzungen werden als eine Art von
Modifikationen betrachtet. Damit können Sie eine Übersetzung
des Dokumentes unter den Bestimmungen von Ziffer 4 verbreiten.
Um
die unveränderlichen Abschnitte durch eine Übersetzung zu
ersetzen, benötigen Sie die spezielle Erlaubnis des
Copyright-Inhabers. Sie können allerdings Übersetzungen von
einigen oder allen unveränderlichen Abschnitten zu den original
Versionen der unveränderlichen Abschnitte hinzufügen.
Sie
können eine Übersetzung dieser Lizenz und allen
Lizenzhinweisen im Dokument sowie allen Garantieausschlüssen
hinzufügen, vorausgesetzt, daß Sie ebenso die originale
englische Version dieser Lizenz und aller Hinweise und Ausschlüsse
beifügen.
Sollten die Übersetzung und die
Originalversion dieser Lizenz oder eines Hinweises oder Ausschlusses
voneinander abweichen, so hat die Originalversion vorrang.
Wenn ein Abschnitt des Dokumentes als Danksagung, Widmungen oder Historie überschrieben ist, so erfordert die Forderung (Ziffer 4) den Titel dieses Abschnittes zuerhalten, die Änderung des aktuellen Titels.
9. Abschlussbestimmungen
Sie dürfen dieses Dokument nicht kopieren,
verändern, unterlizensieren oder verteilen mit der Ausnahme, daß
Sie es ausdrücklich unter dieser Lizenz tun.
Jedweder andere
Versuch zu kopieren, zu modifizieren, unter zu lizensieren oder zu
verbreiten ist unzulässig und führt automatisch zum Entzug
der durch diese Lizenz gewährten Rechte. Dennoch verlieren jene
Parteien, die von ihnen Kopien oder Rechte unter dieser Lizen
erhalten haben, nicht Ihre Rechte, so lange sie sich in völliger
Übereinstimmung mit der Lizenz befinden.
10. Spätere Überarbeitungen dieser Lizenz
Die Free Software Foundation kann von Zeit
zu Zeit neue, überarbeitete Versionen der GNU Free
Dokumentation License veröffentlichen. Diese neuen Versionen
werden im Geiste gleich bleiben, können sich aber in Details
unterscheiden um neuen Problemen oder Besorgnissen gerecht zu
werden.
Siehe: http://www.gnu.org/copyleft/
Jede Version dieser Lizenz erhält eine eigene
Versionsnummer.
Wenn das Dokument bestimmt, daß eine
bestimmt numerierte Version oder jede spätere Version
dafür gilt, haben Sie die Wahl den Bestimmungen dieser speziell
benannten Version zu folgen, oder jeder Version, die später von
der Free Software Foundation, nicht als Entwurf,
veröffentlicht wurde.
Anhang:
Wie Sie diese Lizenz für Ihre
Dokumente verwenden können
Um diese Lizenz in einem Dokument zu verwenden, das sie selbst geschrieben haben, schliessen Sie eine Kopie dieser Lizenz (eine englische Kopie des Originals anm. des Übersetzers) in Ihr Dokument mit ein, und setzen Sie den folgenden Copyright- und Lizenzhinweis gleich hinter die Titelseite:
Copyright (c) YEAR YOUR
NAME
Persmission is granted to copy, distribute and/or modify this
document under the terms of the GNU Free Documentation License,
Version 1.2 or any later version published by the Free Software
Foundation;
with no Invariant Sections, no Front-Cover Texts, and
no Back-Cover Texts.
A copy of the license is included in the
section entitled "GNU Free Documentation License".
Es folgt eine Übersetzung des oben stehenden
Hinweises, der nur zur Klarheit hier angegeben ist ! (anm.: des
Übersetzers)
Copyright Jahr Ihr Name
Kopieren, Verbreiten
und/oder Modifizieren ist unter den Bedingungen der
GNU Free
Documentation License, Version 1.2 oder einer späteren
Version, veröffentlicht von der Free Software Foundation,
erlaubt.
Es gibt keine unveränderlichen Abschnitte,
keinen
vorderen Umschlagtext und keinen hinteren Umschlagtext
Eine Kopie
des Lizenztextes ist unter dem Titel
GNU Free Documentation
License enthalten.
(Ende der Übersetzung des
Lizenzhinweistextes)
Wenn Sie unveränderlichen Abschnitte, vordere
und hintere Umschlagtexte haben, ersetzen Sie die Zeile: "Es
gibt keine...... Umschlagtext" durch die Folgende:
Mit den
unveränderlichen Abschnitten:
Liste dem den Titeln der
unveränderlichen Abschnitte
mit dem vorderen
Umschlagtext:
vorderer Umschlagtext
und dem
hinteren Umschlagtext:
hinterer Umschlagtext
Wenn Sie unveränderliche Abschnitte, aber keine Umschlagtexte oder irgend eine andere Kombination der drei Bereiche haben, mischen Sie die verschiedenen Alternativen, daß sie zu Ihren Anforderungen passen.
Wenn Ihr Dokument nicht-triviale Codebeispiele enthält empfehlen wir diese Beispiele parrallel unter einer freien Softwarelizenz Ihrer Wahl, beispielsweise der GNU General Public License zu lizensieren, um ihren Gebrauch in freier Software zu erlauben.