LPI 202 Vorbereitung
Topic 207: Domain Name Server
207.1 Basic DNS server configuration
Einführung
A) Geschichtliches
Datei hosts.txt: https://internetdagarna.se/arkiv/2000/internationella-aktorer/ICANN-and-se.pdf
Generell - Geschichte des Internets: http://www.michaelkaul.de/Geschichte/zakon/zakon.html
Es gibt verschiedene Möglichkeiten der Namensauflösung:
Datei hosts.txt (heute: /etc/hosts, Hyperlink: siehe oben)
Yellow Pages (aus Lizenzgründen umbenannt in Network Information System)
Domain Name System
B) Wichtige Kennzeichen von DNS
Dezentral, um dem Datenaufkommen Herr zu werden (13 Root-Server)
Hierarische Struktur
Authoritative Root Server
TIPP: Domänen-Suche am besten bei den jeweiligen gemeinnützigen Organisationen oder mit whois duchführen:
C) Begriffe
Weltweit einheuitlicher Namensraum, Weltwurzel = ein Punkt
Domäne = Teil des Namensraums
Zone = Verwaltungseinheit einer Domäne
Cache-only Nameserver einrichten
ZIEL: Häufige DNS-Anfragen zwischenspeichern, Performancegewinn
Die Installation ist schnell erledigt:
$ apt-get install bind9 dnsutils
Eine Änderung der Konfiguration ist in diesem Szenario nur erforderlich, wenn keine transparenten Downloads von Zoneninformationen möglich sind. Dann müssen ‚forwarders‘ Verwendung finden:
$ grep -A3 forwarders /etc/bind/named.conf.options
// nameservers, you probably want to use them as forwarders.
// Uncomment the following block, and insert the addresses replacing
// the all-0's placeholder.
forwarders {
194.25.2.129; 8.8.8.8;
};
$
In unserem Netzwerk haben wir allerdings keinen Handlungsbedarf und belassen die Datei, wie sie ist.
DNS-Client Konfigurieren
Auf dem Nameserver selbst, wird in aller Regel der hier laufende Bind9-Daemon als zu befragender DNS-Server angegeben:
$ cat /etc/resolv.conf
nameserver 127.0.0.1
Soll ein Windowssystem als DNS-Client herangezogen werden, ist der Weg dieser:
$ ncpa.cpl $ ... Eigenschaften ... Karte DNS ...
Starten und Testen
$ systemctl start bind9
$ systemctl status bind9
* bind9.service - BIND Domain Name Server
Loaded: loaded (/lib/systemd/system/bind9.service; enabled; vendor preset: enabled)
Drop-In: /run/systemd/generator/bind9.service.d
`50-insserv.conf-$named.conf
Active: active (running) since Mi 2016-10-26 11:50:00 CEST; 1s ago
Docs: man:named(8)
Main PID: 19894 (named)
Tasks: 4
Memory: 11.4M
CPU: 26ms
CGroup: /system.slice/bind9.service
`19894 /usr/sbin/named -f -u bind
Okt 26 11:50:00 dns1 named[19894]: command channel listening on 127.0.0.1#953
Okt 26 11:50:00 dns1 named[19894]: configuring command channel from '/etc/bind/rndc.key'
Okt 26 11:50:00 dns1 named[19894]: command channel listening on ::1#953
Okt 26 11:50:00 dns1 named[19894]: managed-keys-zone: loaded serial 0
Okt 26 11:50:00 dns1 named[19894]: zone 0.in-addr.arpa/IN: loaded serial 1
Okt 26 11:50:00 dns1 named[19894]: zone 127.in-addr.arpa/IN: loaded serial 1
Okt 26 11:50:00 dns1 named[19894]: zone 255.in-addr.arpa/IN: loaded serial 1
Okt 26 11:50:00 dns1 named[19894]: zone localhost/IN: loaded serial 2
Okt 26 11:50:00 dns1 named[19894]: all zones loaded
Okt 26 11:50:00 dns1 named[19894]: running
$
$ host linux.at
linux.at has address 143.130.20.3
linux.at mail is handled by 10 mx1.luga.at.
$
$
$ nslookup linux.com
Server: 127.0.0.1
Address: 127.0.0.1#53
Non-authoritative answer:
Name: linux.com
Address: 151.101.129.5
Name: linux.com
Address: 151.101.193.5
Name: linux.com
Address: 151.101.65.5
Name: linux.com
Address: 151.101.1.5
$
Der DNS-Cache
Wer sehen möchte, dass schon erfolgte Namensauflösungen nun aus dem Cache heraus beantwortet werden können, führe am besten mehrmals hintereinander
$ dig metager.de | grep "Query time"
aus. Die zweite Auflösung ist viel schneller als die erste abgelaufen, sie wurde soeben aus dem Cache beantwortet.
Nach dem Anlernen des Caches z.B. mit dig metager.de
, kann man ihn leicht in die Datei /var/cache/bind/named_dump.db exportieren:
$ rndc dumpdb
Im Experiment:
$ rndc dumpdb
$
$ ls -ltrc /var/cache/bind/
insgesamt 16
-rw-r--r-- 1 bind bind 821 Okt 26 11:50 managed-keys.bind
-rw-r--r-- 1 bind bind 6160 Okt 26 12:02 named_dump.db
$
$ less /var/cache/bind/named_dump.db
$
$
$ cp /var/cache/bind/named_dump.db /root/
$
$ systemctl stop bind9
$
$ less /var/cache/bind/named_dump.db
$
$
$ systemctl start bind9
$
$ grep erfurt /var/cache/bind/named_dump.db
erfurt.de. 35 \-DS ;-$NXRRSET
$
$ systemctl stop bind9
$
$ rm /var/cache/bind/named_dump.db
$
$ systemctl start bind9
$
$ grep erfurt /var/cache/bind/named_dump.db
grep: /var/cache/bind/named_dump.db: Datei oder Verzeichnis nicht gefunden
$
$
$ dig erfurt.de | tail -5
;; Query time: 148 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Wed Oct 26 12:06:55 CEST 2016
;; MSG SIZE rcvd: 265
$
$ dig erfurt.de | tail -5
;; Query time: 0 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Wed Oct 26 12:07:00 CEST 2016
;; MSG SIZE rcvd: 265
$
$ grep erfurt /var/cache/bind/named_dump.db
grep: /var/cache/bind/named_dump.db: Datei oder Verzeichnis nicht gefunden
$
$ rndc dumpdb
$
$ grep erfurt /var/cache/bind/named_dump.db
erfurt.de. 23 \-DS ;-$NXRRSET
$
207.2 Create and maintain DNS zones
Eine eigene Domäne
DEFINITION: Eine Domäne ist ein Teil des DNS-Namensraumes, der weltweit einheitlich ist. Verwaltet wird sie in einem Zonenfile. Unter Debian wird z.B. die Datei /etc/bind/db.local verwendet, um eine eigene Zone für localhost bereitzustellen.
Voraussetzungen
Der Name der Domäne entsteht über die Einträge in der /etc/hosts:
127.0.1.1 dns1.dom1.test dns1
Da wir selber einen bind9-Server auf der Maschine haben, muss die DNS-Clientseite idealerweise auch davon erfahren:
$ vi /etc/resolv.conf
search dom1.test
Man kann auch alles in der /etc/network/interfaces konfigurieren, wenn das Paket resolvconf installiert ist:
auto eth0
iface eth0 inet static
address 10.20.30.4
netmask 255.255.255.0
gateway 10.20.30.1
dns-nameservers 127.0.0.1
dns-search dom1.test
Da der Bind9-Daemon schon läuft, muss auch schon die eigene, lokale Zone benutzbar sein:
Mit dig A localhost | grep -v '^\;' | grep -v '^\.'
schauen wir uns die Vorwärtsauflösung an:
localhost. 604800 IN A 127.0.0.1
localhost. 604800 IN NS localhost.
localhost. 604800 IN AAAA ::1
Mit dig -x 127.0.0.1 | grep -v '^\;' | grep -v '^\.'
danach die Rückwärtsauflösung:
1.0.0.127.in-addr.arpa. 604800 IN PTR localhost.
127.in-addr.arpa. 604800 IN NS localhost.
localhost. 604800 IN A 127.0.0.1
localhost. 604800 IN AAAA ::1
Das ist bereits am Start aufgrund der vorhandenen Zonendateien db.local und db.127, die für unsere eigen Zone Ausgangspunkt sein werden.
Zonenfiles bereitstellen
$ cd /etc/bind
$ cp db.local db.dom1.test
$ cp db.127 db.10.20.30
Die Inhalte sind nun nach den jeweiligen Bedürfnissen anzupassen.
Die wichtigste Datei ist die für die Vorwärtsauflösung. Sie heißt ‚db.dom1.test‘ und beinhaltet im Endeffekt folgendes:
$TTL 604800
@ IN SOA dns1.dom1.test. root.dns1.dom1.test. (
2 ; Serial
604800 ; Refresh
86400 ; Retry
2419200 ; Expire
604800 ) ; Negative Cache TTL
;
@ IN NS dns1.dom1.test.
dns1 IN A 10.20.30.3
; Weitere Einträge (ähnlich der /etc/hosts, allerdings ZUERST die Hostnamen, DANN die IPs!)
dns2 IN A 10.20.30.4
xphost IN A 10.20.30.126
Die Datei für die Rückwärtsauflösung heißt ‚db.10.20.30‘, sie beinhaltet im Endeffekt folgendes:
$TTL 604800
@ IN SOA dns1.dom1.test. root.dns1.dom1.test. (
1 ; Serial
604800 ; Refresh
86400 ; Retry
2419200 ; Expire
604800 ) ; Negative Cache TTL
;
@ IN NS dns1.dom1.test.
3 IN PTR dns1.dom1.test.
; Weitere...
4 IN PTR dns2.dom1.test.
126 IN PTR xphost.dom1.test.
Einbinden der Zonendateien:
So ähnlich wie bei den beiden Zonendateien db.local und db.127 müssen wir nun unsere Zonenfiles einbinden:
$ vi named.conf.local
Die beiden wichtigen Abschnitte sehen schließlich so aus:
zone "dom1.test" {
type master;
file "/etc/bind/db.dom1.test";
};
zone "30.20.10.in-addr.arpa" {
type master;
file "/etc/bind/db.10.20.30";
};
Danach:
$ tail -f /var/log/syslog # in zweitem Fenster
$ systemctl restart bind9
Testings
Mit Hilfe des Kommandos ‚host‘:
$ host `hostname -f`
dns1.dom1.test has address 10.20.30.3
dns1.dom1.test has IPv6 address ::1
$ host -t ptr 10.20.30.3
3.30.20.10.in-addr.arpa domain name pointer dns1.dom1.test.
$
Anschauliche Ausgabe bei MX-Einträgen bei Verwendung von ‚host‘:
$ host -t mx web.de
web.de mail is handled by 100 mx-ha03.web.de.
web.de mail is handled by 100 mx-ha02.web.de.
$
$
$ host -t ns web.de
web.de name server ns-webde.ui-dns.de.
web.de name server ns-webde.ui-dns.biz.
web.de name server ns-webde.ui-dns.org.
web.de name server ns-webde.ui-dns.com.
$
Mit Hilfe des Kommandos ‚dig‘:
$ dig dns1 | grep -v '\;' | grep -v ^$
. 10800 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2016102700 1800 900 604800 86400
$
$ dig -x 10.20.30.3 | grep -v '\;' | grep -v ^$
3.30.20.10.in-addr.arpa. 604800 IN PTR dns1.dom1.test.
30.20.10.in-addr.arpa. 604800 IN NS dns1.dom1.test.
dns1.dom1.test. 604800 IN A 10.20.30.3
dns1.dom1.test. 604800 IN AAAA ::1
$
Slave-Nameserver
Bereitstellen eines zweites Servers
ZIEL: Einen zweiten Nameserver als Slave für Replikation vorbereiten.
Am einfachsten ist es, wir klonen uns DNS1 (Debian-System namens ‚dns1.dom1.test‘) via VirtualBox zu DNS2…
EINGELOGGT AUF DNS2 (dns2.dom1.test):
Umbenennen, anpassen der IP-Adresse auf 10.20.30.4
$ grep dns2 /etc/hostname
dns2
$
$ grep dns2 /etc/hosts
127.0.1.1 dns2.dom1.test dns2
$
$
$ grep 4 /etc/network/interfaces
address 10.20.30.4
$
$ systemctl restart networking
$
$ /etc/init.d/hostname.sh
$
$ hostname --fqdn
dns1.dom1.test
$
$ hostname dns2
$
$ hostname --fqdn
dns2.dom1.test
$
$
$ hostname -d
dom1.test
$
$ dnsdomainname :
dom1.test
Anpassen der Zonen-Definition für Slave-Rolle:
$ vi /etc/bind/named.conf.local
BITTE AUF FOLGENDE WERTE ÄNDERN:
Ändern von master auf slave, Ergebnis:
type slave;
Einfügen dieser Zeile:
masters { 10.20.30.3; };
Insgesamt sieht das Gnaze dann so aus:
zone "dom1.test" {
type slave;
masters { 10.20.30.3; };
file "/etc/bind/db.dom1.test";
};
zone "30.20.10.in-addr.arpa" {
type slave;
masters { 10.20.30.3; };
file "/etc/bind/db.10.20.30";
};
Zum Weiterforschen siehe http://www.microhowto.info/howto/configure_bind_as_a_slave_dns_server.html
Replikation einrichten
Beide VMs sind mit Debian 8 ausgestattet und haben folgende Eigenschaften:
Master-Server
Hostname: dns1.dom1.test
IP-Adresse: 10.20.30.3
Slave-Server:
Hostname: dns2.dom1.test
IP-Adresse: 10.20.30.4
Konfiguration des Masters
Hier ist besonders die Zeile notify yes;
von Belang. Wir haben sie
hinzugefügt, um den Slave bei Erhöhung der serial-Nummer informieren
zu können, dass er sich die Daten replizieren muss:
$ vi /etc/bind/named.conf.local
Der Inhalt sollte danach folgendermaßen aussehen:
zone "dom1.test" {
type master;
notify yes;
file "/etc/bind/db.dom1.test";
};
zone "30.20.10.in-addr.arpa" {
type master;
notify yes;
file "/etc/bind/db.10.20.30";
};
AUFGABE: Bitte die Sicherheit mit allow-transfer verbesseren!
Im entsprechenden Zonenfile ist es wichtig, den zweiten Nameserver, der als Slave fungieren soll, auch als solchen mit aufzunehmen. Das wird mit der folgenden, hinzuzufügenden Zeile realisiert:
@ IN NS dns2.dom1.test.
Vergisst man dies, kann sich zwar der Slave die Daten bei
einem systemctl restart bind9
selber ziehen, wird aber nicht vom
Master mittels seiner notify-Nachrichten über Änderugen informiert!
$ vi /etc/bind/db.dom1.test
Der Inhalt sollte danach folgendermaßen aussehen:
$TTL 604800
@ IN SOA dns1.dom1.test. root.dns1.dom1.test. (
90 ; Serial
604800 ; Refresh
86400 ; Retry
2419200 ; Expire
604800 ) ; Negative Cache TTL
;
; Dies ist der eigene, lokale Master-Nameserver:
@ IN NS dns1.dom1.test.
; HINZUGEFÜGT: Dies ist der andere, entfernte Slave-Nameserver:
@ IN NS dns2.dom1.test.
dns1 IN A 10.20.30.3
; Weitere Einträge (ähnlich der /etc/hosts, allerdings ZUERST die Hostnamen, DANN die IPs!)
dns2 IN A 10.20.30.4
xphost IN A 10.20.30.126
xphost2 IN A 10.20.30.127
AUFGABE: Bitte auch die reversen Zonenfiles anpassen!
Konfiguration des Slaves
Hier ist zuerst einmal wichtig, anzugeben, wer der Master ist, von dem dann die Daten kopiert werden sollen. Das legen wir mit der Anweisung masters { 10.20.30.3; }; fest:
$ cat /etc/bind/named.conf.local
Der Inhalt sollte dann so aussehen:
zone "dom1.test" {
type slave;
masters { 10.20.30.3; };
file "/etc/bind/db.dom1.test";
};
zone "30.20.10.in-addr.arpa" {
type slave;
masters { 10.20.30.3; };
file "/etc/bind/db.10.20.30";
};
Dann brauchen wir auch wieder das Zonenfile. Anders als beim Master, wo wir den Slave mittels NS-Record eintragen mussten, sind für die Replikation keine besonderen Einstellungen erforderlich:
$ cat /etc/bind/db.dom1.test
$TTL 604800
@ IN SOA dns2.dom1.test. root.dns2.dom1.test. (
2 ; Serial
604800 ; Refresh
86400 ; Retry
2419200 ; Expire
604800 ) ; Negative Cache TTL
;
@ IN NS dns2.dom1.test.
dns2 IN A 10.20.30.4
; Weitere Einträge sind hier auf dem Slave nicht erforderlich,
; da er sich die Datensätze repliziert.
Testings
Auf beiden Maschinen:
tail -f /var/log/syslog
Auf dem Master - Datensatz hinzufügen - Seriennummer erhöhen - Config neu laden:
rndc reload
Sicherheit
(Lediglich auf dem Master durchzuführen)
Um nur dem Slave-Server mit der Adresse 10.20.30.4 Zonentransfers zu erlauben (AXFR = Asynchronous Full Transfer Zone oder Asynchronous Xfer Full Range), verwenden wir allow-transfer:
zone "dom1.test" {
type master;
notify yes;
allow-transfer { 10.20.30.4; };
file "/etc/bind/db.dom1.test";
};
zone "30.20.10.in-addr.arpa" {
type master;
notify yes;
file "/etc/bind/db.10.20.30";
};
Weiterhin kann man das ganz normale Abfragen der Datenbank (nslookup) reglementieren, in der Zonendefinition können wir dazu diese Zeile einfügen:
allow-query { 127.0.0.1; 10.20.30.0/24; };
Damit haben wir unsere beiden DNS-Server mit einfachen Mitteln schon mal etwas sicherer gemacht.
207.3 Securing a DNS server
Einführung
Zu möglichen Angriffen siehe http://www.tecchannel.de/a/dns-attacken-typen-und-sicherheitsvorkehrungen,2064862
Relevante Schutzziele:
Integrität
Verfügbarkeit
Authentizität
Siehe dazu
Gegenmaßnahmen:
Härten des Servers (Grsecurity-Patch, Minimal-Systeme wie Alpine Linux)
Kryptografisches Beweisen der Authentizität des Servers
Chroot-Jail einrichten (https://wiki.ubuntuusers.de/Archiv/DNS-Server_Bind/Erweiterte_Konfiguration/)
Zur Kryptographie:
http://www.trojaner-und-sicherheit.de/security/verschluesselung.htm
http://www.golem.de/news/imho-dnssec-ist-gescheitert-1506-114940.html
ACHTUNG: MD5 hat mit Kollisionsproblemen zu kämpfen
https://www.schneier.com/blog/archives/2008/05/random_number_b.html
Master/Slave via TSIG absichern
Allgemein zum Thema Verschlüsselung: http://www.trojaner-und-sicherheit.de/security/verschluesselung.htm
Zur Arbeitsweise von TSIG: https://de.wikipedia.org/wiki/TSIG
Praktische Einrichtung: http://www.cyberciti.biz/faq/unix-linux-bind-named-configuring-tsig/
A) Auf dem Master
$ cd /etc/bind
$
$ dnssec-keygen -a HMAC-MD5 -b 512 -n HOST rndc-key
Krndc-key.+157+04038
$
$ ls -ltrc | tail -5
-rw-r--r-- 1 root bind 494 Nov 1 09:23 named.conf.local
-rw-r--r-- 1 root bind 545 Nov 1 09:35 named.conf
-rw-r----- 1 root bind 77 Nov 1 09:39 rndc.key
-rw------- 1 root bind 229 Nov 1 16:24 Krndc-key.+157+04038.private
-rw------- 1 root bind 117 Nov 1 16:24 Krndc-key.+157+04038.key
Wir sehen uns nun die Datei an, in der unser Pre-Shared-Key steht und erzeugen daraus die Schlüsseldatei:
$ cat Krndc-key.+157+04038.private
Private-key-format: v1.3
Algorithm: 157 (HMAC_MD5)
Key: 8kvk9rllTIsb/WlBYvLQdSsXKoMJ8uCUYYLIAy0DMoOmNdZiAgdK+yloqCDZnDya1CIrYAbsVV8mi1/nI3v0CQ==
Bits: AAA=
Created: 20161101152458
Publish: 20161101152458
Activate: 20161101152458
$
In der neu anzulegenden Datei namens ‚tsig.key‘ müssen wir als nächstes einige Eintragungen vornehmen:
Den eben mittels ‚cat‘ ausgegebenen Key bei „secret“ hinterlegen
Die IP-Adresse des Slave-Servers angeben
# Dateiinhalt von '/etc/bind/tsig.key'
#
key "TRANSFER" {
algorithm hmac-md5;
secret "8kvk9rllTIsb/WlBYvLQdSsXKoMJ8uCUYYLIAy0DMoOmNdZiAgdK+yloqCDZnDya1CIrYAbsVV8mi1/nI3v0CQ==";
};
# Slave server IP # 1
server 10.20.30.4 {
keys {
TRANSFER;
};
};
################################
# If you have 3rd slave server with IP 64.1.2.3
#server 64.1.2.3 {
# keys {
# TRANSFER;
# };
#};
################################
Weitere Schritte sind das Einbinden der Schlüsseldatei sowie die Anpassung der Dateirechte:
$ echo 'include "/etc/bind/tsig.key";' >> named.conf
$
$ tail -4 named.conf
include "/etc/bind/named.conf.options";
include "/etc/bind/named.conf.local";
include "/etc/bind/named.conf.default-zones";
include "/etc/bind/tsig.key";
$
$ chmod 640 tsig.key
Nun legen wir fest, wer die Datensätze replizieren darf:
$ vi /etc/bind/named.conf.local
Dazu fügen wir die jeweilige Zonendefinition folgendes ein:
allow-transfer { key TRANSFER; };
Jetzt können wir den Daemon schon mal neu starten:
$ systemctl restart bind9
Und kopieren schließlich nur noch den Schlüssel für die spätere Übertragung an einen passenden Ort:
$ cp /etc/bind/tsig.key /home/tux
$ chmod 700 /home/tux/
$ chown tux: /home/tux/tsig.key
B) Auf dem Slave
Wir müssen uns nun die Schlüsseldatei hierher auf den Slave-Server kopieren und wieder die Rechte anpassen:
$ scp tux@10.20.30.3:tsig.key /etc/bind
$ chmod 640 /etc/bind/tsig.key
$ chown root:bind /etc/bind/tsig.key
Die nächsten Schritte sind das Einbinden und Anpassen der Datei ‚/etc/bind/tsig.key‘ in ähnlicher Weise wie auf dem Master-Server, nur dass jetzt anstelle der IP-Adresse des Slaves die des Masters eingetragen werden muss:
$ echo 'include "/etc/bind/tsig.key";' >> named.conf
$ vi /etc/bind/tsig.key
Mit grep -v ^# /etc/bind/tsig.key
kontrollieren wir abschließend die Einstellungen:
key "TRANSFER" {
algorithm hmac-md5;
secret "8kvk9rllTIsb/WlBYvLQdSsXKoMJ8uCUYYLIAy0DMoOmNdZiAgdK+yloqCDZnDya1CIrYAbsVV8mi1/nI3v0CQ==";
};
server 10.20.30.3 {
keys {
TRANSFER;
};
};
Die Datei ‚/etc/bind/named.conf.local‘ muss hier nicht um die Direktive allow-transfer { key TRANSFER; };
in der Zonendefinition erweitert werden.
Es fehlt schließlich nur noch ein Neustart des Daemons:
$ systemctl restart bind9
Have a‘ lot of fun…
Kennenlernen von DNSSEC
ZIEL: Asymmetrische Verschlüsselung für die Authentizitätsprüfung kennenlernen und verstehen (Bei eventuellen praktischen Versuchen am besten vorher VM-Snapshot anlegen!)
Erste Schritte mit DNSSEC
Zu den Grundlagen siehe:
Mehr Entropie für lange Schlüssel
QUELLE https://www.digitalocean.com/community/tutorials/how-to-setup-additional-entropy-for-cloud-servers
Damit das Erzeugen der Schlüsseln nachher schneller geht, installieren wir zuerst haveged und überprüfen, ob der Daemon läuft:
$ pgrep -a have
516 /usr/sbin/haveged --Foreground --verbose=1 -w 1024
$
Gut verfahren lässt sich nach dem Tutorial von https://www.digitalocean.com/community/tutorials/how-to-setup-dnssec-on-an-authoritative-bind-dns-server–2
ACHTUNG: Die Direktive dnssec-validation auto; bitte in der Datei named.conf.options auskommentieren, sie ist schon per Default gesetzt. Ansonsten kann sie einfach wie im Folgenden gezeigt, mit sed nachträglich entfernt werden.
Hinzufügen müssen wir in diese Datei dann folgendes:
dnssec-enable yes;
dnssec-validation yes;
dnssec-lookaside auto;
Das folgende Hilfsskript macht uns nachher das Ergänzen unseres Zonefiles um die Schlüssel einfacher:
$ cat /home/tux/include-key.sh
Und das ist der Inhalt:
for key in `ls Kdom1.test*.key`
do
echo "\$INCLUDE $key">> db.dom1.test
done
Nun geht es mit der Schlüsselerzeugung des Zone Signing Keys (ZSK) los:
$ dnssec-keygen -a NSEC3RSASHA1 -b 2048 -n ZONE dom1.test
Generating key pair.......................................................+++ ......................+++
Kdom1.test.+007+50675
$
$ ls -ltrc
insgesamt 60
-rw-r--r-- 1 root root 375 Nov 1 17:04 db.10.20.30
-rw-r--r-- 1 root root 53 Nov 3 08:00 bind9-default.md5sum
-rw-r--r-- 1 bind bind 540 Nov 3 11:14 db.dom1.test
-rw------- 1 root root 1779 Nov 3 11:36 Kdom1.test.+007+50675.private
-rw-r--r-- 1 root root 602 Nov 3 11:36 Kdom1.test.+007+50675.key
Danach wird ein Key Signing Key (KSK) erzeugt:
$ dnssec-keygen -f KSK -a NSEC3RSASHA1 -b 4096 -n ZONE dom1.test
Generating key pair................................++ ...........................................++
Kdom1.test.+007+23568
$
$ ls -ltrc
insgesamt 68
-rw-r--r-- 1 root root 375 Nov 1 17:04 db.10.20.30
-rw-r--r-- 1 root root 53 Nov 3 08:00 bind9-default.md5sum
-rw-r--r-- 1 bind bind 540 Nov 3 11:14 db.dom1.test
-rw------- 1 root root 1779 Nov 3 11:36 Kdom1.test.+007+50675.private
-rw-r--r-- 1 root root 602 Nov 3 11:36 Kdom1.test.+007+50675.key
-rw------- 1 root root 3319 Nov 3 11:38 Kdom1.test.+007+23568.private
-rw-r--r-- 1 root root 947 Nov 3 11:38 Kdom1.test.+007+23568.key
$
Die 4 neuen Schlüsselpaare (ZSK und KSK) werden nun weiterverwendet. Mit Hilfe des o.g. Skriptes werden die öffentlichen Schlüssel, die den DNSKEY-Record des Zonenfiles enthalten, hinzugefügt.
$ bash /home/tux/include-key.script
$
$ tail -5 db.dom1.test
xp2 A 10.20.30.127
xphost A 10.20.30.126
testhost A 10.20.30.128
$INCLUDE Kdom1.test.+007+23568.key
$INCLUDE Kdom1.test.+007+50675.key
$
Als letztes wird die Zone signiert, wobei der Salt-Anteil durch Zufallszahlen ersetzt wird:
$ dnssec-signzone -A -3 $(head -c 1000 /dev/random | sha1sum | cut -b 1-16) -N INCREMENT -o dom1.test -t db.dom1.test
Verifying the zone using the following algorithms: NSEC3RSASHA1.
Zone fully signed:
Algorithm: NSEC3RSASHA1: KSKs: 1 active, 0 stand-by, 0 revoked
ZSKs: 1 active, 0 stand-by, 0 revoked
db.dom1.test.signed
Signatures generated: 20
Signatures retained: 0
Signatures dropped: 0
Signatures successfully verified: 0
Signatures unsuccessfully verified: 0
Signing time in seconds: 0.029
Signatures per second: 689.441
Runtime in seconds: 0.051
$
Zur Kontrolle der Ergebnisse sei dem geneigten Leser schließlich dieser Output mitgegeben:
$ ls -ltrc | tail -5
-rw------- 1 root root 3319 Nov 3 11:38 Kdom1.test.+007+23568.private
-rw-r--r-- 1 root root 947 Nov 3 11:38 Kdom1.test.+007+23568.key
-rw-r--r-- 1 bind bind 610 Nov 3 11:40 db.dom1.test
-rw-r--r-- 1 root root 163 Nov 3 11:42 dsset-dom1.test.
-rw-r--r-- 1 root root 13313 Nov 3 11:42 db.dom1.test.signed
$
$ ls -l
insgesamt 88
-rw-r--r-- 1 root root 53 Nov 3 08:00 bind9-default.md5sum
-rw-r--r-- 1 root root 375 Nov 1 17:04 db.10.20.30
-rw-r--r-- 1 bind bind 610 Nov 3 11:40 db.dom1.test
-rw-r--r-- 1 root root 13313 Nov 3 11:42 db.dom1.test.signed
-rw-r--r-- 1 root root 163 Nov 3 11:42 dsset-dom1.test.
-rw-r--r-- 1 root root 947 Nov 3 11:38 Kdom1.test.+007+23568.key
-rw------- 1 root root 3319 Nov 3 11:38 Kdom1.test.+007+23568.private
-rw-r--r-- 1 root root 602 Nov 3 11:36 Kdom1.test.+007+50675.key
-rw------- 1 root root 1779 Nov 3 11:36 Kdom1.test.+007+50675.private
$
$ less Kdom1.test.+007+23568.key
$
$ less Kdom1.test.+007+23568.private
$
$ cat Kdom1.test.+007+50675.key
; This is a zone-signing key, keyid 50675, for dom1.test.
; Created: 20161103103631 (Thu Nov 3 11:36:31 2016)
; Publish: 20161103103631 (Thu Nov 3 11:36:31 2016)
; Activate: 20161103103631 (Thu Nov 3 11:36:31 2016)
dom1.test. IN DNSKEY 256 3 7 AwEAAcGkG9CjVlJKlJb8nv0lRyCn3x5Akt2SPoJaiAHjTjlEfpqHd1ra 6Etxkk5+bWn0xuIXNPsfyYX4ZibpIrffCo/xzuwseQhNjr2vNlSxxdRK zSPFZ4kmf9C3Er77/JF9OLe6roag3E2B4PRmr9O0xy4JO9ea4tXm4NWh VDJWy+6c2Ht70lyiaI1Cf+EYZfmBlH5i3lw8BbeKJs3FM2PzxImVO2kr 6o+IN2ets8pZUyAS4if3JrZhLDMbF0K7jxJXaTcnUnUVmf2T8oawpr89 xxZ8DWzb8rJCeS0pbl6WSbn347YTJO4wDTmGUoDGW2EGVryWe54SFTV4 U6miOwulkvk=
$
$ head Kdom1.test.+007+50675.private
Private-key-format: v1.3
Algorithm: 7 (NSEC3RSASHA1)
Modulus: waQb0KNWUkqUlvye/SVHIKffHkCS3ZI+glqIAeNOOUR+mod3WtroS3GSTn5tafTG4hc0+x/JhfhmJukit98Kj/HO7Cx5CE2Ova82VLHF1ErNI8VniSZ/0LcSvvv8kX04t7quhqDcTYHg9Gav07THLgk715ri1ebg1aFUMlbL7pzYe3vSXKJojUJ/4Rhl+YGUfmLeXDwFt4omzcUzY/PEiZU7aSvqj4g3Z62zyllTIBLiJ/cmtmEsMxsXQruPEldpNydSdRWZ/ZPyhrCmvz3HFnwNbNvyskJ5LSluXpZJuffjthMk7jANOYZSgMZbYQZWvJZ7nhIVNXhTqaI7C6WS+Q==
PublicExponent: AQAB
PrivateExponent: wKUzxu25A0WPbmcFBXQAv0xDfSVg9253IdhPVxF80RyDl9kNtSXz1Jq4o77Du5X6BxRvcSa+prnpZuypzaPoLiyzX+MexlPinnOh6cCyv/FrBRtvVdMndc2sqLSpIVUjCCaBWw7OHY4I7xz57/T586LcFjPRWFzJcb9+tFYFrOxCr6zryRiBt0x3wovEPfM0paCfMpjlAG0WFd2vlU24sOn68/CsWMeXtTy6lMbg8DFC5peVABVYsAFG9RWs+FwZKZNMOSIFIiF1e07ICMT4EbaoRrJKMb9VcbScWbb753tjYZ0J4+W3yYo+/51x2uyGYCt+7jkHwr+3/wTOwVTIwQ==
Prime1: 3veH134Fo/VKXs0k/PRfNKKMjYFppGcFEXlahh4zr0YueyjFcLN0a2SBKprFiAOykHu3iZ41dRJg72BzXmkCJyZwJol6yF0QoPR3asGVmzLxY7qpfD3Z/q/6Ypd73PVPZpZbu/cN42HPcTkQm4demAjuYIMd/41kG8n9bnY8LzM=
Prime2: 3lRV3+UxHHuEmmQpKMcZgZ9RndysuElZlbn8NtdR1pJ74BxLdh22AGsgiZ6kGs3nH4KOaOwHbrxcdfJgrsDK+w3W79BIt5o0cnCY1iBox9mO1S3qRtHZl8KQDQpvdsNPbV4IyENGfdazhFPZPPV95nssGT7LKfb0Qy/BJAIEZSM=
Exponent1: YSbiHddfhc1/lkc08rNYOIsLSy00Ztosryx9cSr/wkOGRUvCnBTViWXFklbV8yoJSENf+ariCBz199fC7UQ8F+r7uw70XRGQCVH8JpwrH/DWlWnkJ6qbrgnnw8XVxrVs33pshj5j4svfo6oFvn8BjKV3mL4I+C0XjbQ5pUQHfVk=
Exponent2: usGm/RMeBOnwwmv+cwWD9HFq8qsq3wamXPJE3aBTW2Xi7qd17/sXJhTW2SNMgEOTsNFPZO1XdPp+xIjcFA9Ysji24u1YF/pNsg/JIp1Ixw+GPqZ6FBE0sZk6vemVJfL8JkeGIwr4DL6sPyzb36vrnQ68RVyM9mw+VK2plOCo5nc=
Coefficient: zPeQaoYzo7TuLDCXpgadzc7+uir1FAOMwqTIhQW8wdNuMAsquh2KgkkakHalv0h3vfO9hyKWfUKTHQK7eFmjIb/gSo1ZHD0vxI1pAfzvWwoKZXfVtQ5A6ixhPPMhTSte3BaJpt0POY7Rq1VHdHpyY7wN5dxGj/8t3PWZCCHYSlU=
$
Bind-Version unterdrücken
In der Standardeinstellung verrät nämlich der Daemon die ganze Karte:
$ dig @localhost version.bind txt chaos
; <<>> DiG 9.10.3-P4-Ubuntu <<>> @localhost version.bind txt chaos
; (2 servers found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 56569
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 1
;; WARNING: recursion requested but not available
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;version.bind. CH TXT
;; ANSWER SECTION:
version.bind. 0 CH TXT "9.10.3-P4-Ubuntu"
;; AUTHORITY SECTION:
version.bind. 0 CH NS version.bind.
;; Query time: 0 msec
;; SERVER: ::1#53(::1)
;; WHEN: Thu Nov 03 11:21:59 CET 2016
;; MSG SIZE rcvd: 84
$
$ vi /etc/bind/named.conf.options
Wir fügen hier eine Zeile ein:
version "Not supported";
Nun verrät unser Server nicht mehr seine Version:
$ dig @localhost version.bind txt chaos
; <<>> DiG 9.10.3-P4-Ubuntu <<>> @localhost version.bind txt chaos
; (2 servers found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 36261
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 1
;; WARNING: recursion requested but not available
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;version.bind. CH TXT
;; ANSWER SECTION:
version.bind. 0 CH TXT "Not supported"
;; AUTHORITY SECTION:
version.bind. 0 CH NS version.bind.
;; Query time: 0 msec
;; SERVER: ::1#53(::1)
;; WHEN: Thu Nov 03 13:51:39 CET 2016
;; MSG SIZE rcvd: 81
$
Siehe auch https://raymii.org/s/tutorials/Get_DNS_server_version_and_hide_it_in_BIND.html
Andere DNS-Server
Chroot für bind9
(Ein missglückter Versuch)
Siehe:
https://tech.rana.at/2015/09/25/bind9-im-chroot-unter-debian-8-jessie-und-systemd/
https://www.kiokoman.eu.org/index.php/per-non-dimenticare/11-ubuntu-16-04-lts-chroot-bind9
https://www.thefanclub.co.za/how-to/how-secure-ubuntu-1604-lts-server-part-1-basics
$ ps auxZ | grep -v uncon
LABEL USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
/usr/sbin/named (enforce) bind 2352 0.0 3.9 208892 19804 ? Ssl 09:26 0:00 /usr/sbin/named -f -u bind
$
$
$ vi mychroot-setup.sh
$
$ cat mychroot-setup.sh
mkdir -p /var/bind9/chroot/{etc,dev,var/cache/bind,var/run/named}
mknod /var/bind9/chroot/dev/null c 1 3
mknod /var/bind9/chroot/dev/random c 1 8
chmod 660 /var/bind9/chroot/dev/{null,random}
$
$ bash mychroot-setup.sh
$
$ ls -lR /var/bind9/
/var/bind9/:
insgesamt 4
drwxr-xr-x 5 root root 4096 Nov 4 09:31 chroot
/var/bind9/chroot:
insgesamt 12
drwxr-xr-x 2 root root 4096 Nov 4 09:31 dev
drwxr-xr-x 2 root root 4096 Nov 4 09:31 etc
drwxr-xr-x 4 root root 4096 Nov 4 09:31 var
/var/bind9/chroot/dev:
insgesamt 0
crw-rw---- 1 root root 1, 3 Nov 4 09:31 null
crw-rw---- 1 root root 1, 8 Nov 4 09:31 random
/var/bind9/chroot/etc:
insgesamt 0
/var/bind9/chroot/var:
insgesamt 8
drwxr-xr-x 3 root root 4096 Nov 4 09:31 cache
drwxr-xr-x 3 root root 4096 Nov 4 09:31 run
/var/bind9/chroot/var/cache:
insgesamt 4
drwxr-xr-x 2 root root 4096 Nov 4 09:31 bind
/var/bind9/chroot/var/cache/bind:
insgesamt 0
/var/bind9/chroot/var/run:
insgesamt 4
drwxr-xr-x 2 root root 4096 Nov 4 09:31 named
/var/bind9/chroot/var/run/named:
insgesamt 0
$
$ systemctl stop bind9
$
$ systemctl stop isc-dhcp-server.service
$
$ mv /etc/bind /var/bind9/chroot/etc/
$
$ ln -s /var/bind9/chroot/etc/bind/ /etc/bind
$
$ ls -l /etc/bind
bind/ bindresvport.blacklist
$ ls -l /etc/bind/named.conf*
-rw-r--r-- 1 root bind 575 Nov 1 16:32 /etc/bind/named.conf
-rw-r--r-- 1 root bind 490 Sep 26 21:57 /etc/bind/named.conf.default-zones
-rw-r--r-- 1 root bind 530 Nov 1 17:24 /etc/bind/named.conf.local
-rw-r--r-- 1 root bind 165 Sep 26 21:57 /etc/bind/named.conf.local~
-rw-r--r-- 1 root bind 918 Nov 3 13:51 /etc/bind/named.conf.options
$
$
$ cp /etc/localtime /var/bind9/chroot/etc/
$
$ chown bind:bind /var/bind9/chroot/etc/bind/rndc.key
$ chmod 775 /var/bind9/chroot/var/{cache/bind,run/named}
$ chgrp bind /var/bind9/chroot/var/{cache/bind,run/named}
$
$
$
Startkonfiguration anpassen:
$ vi /etc/init.d/bind9
$
$
$
$ echo "\$AddUnixListenSocket /var/bind9/chroot/dev/log" > /etc/rsyslog.d/
20-ufw.conf 50-default.conf
$ echo "\$AddUnixListenSocket /var/bind9/chroot/dev/log" > /etc/rsyslog.d/bind-chroot.onf
$
$ cat /etc/rsyslog.d/bind-chroot.conf
$AddUnixListenSocket /var/bind9/chroot/dev/log
$
Ermitteln, welches die Unit-Datei ist:
$ systemctl status bind9.service | grep loaded
Nach dem bearbeiten:
$ cat /lib/systemd/system/bind9.service
[Unit]
Description=BIND Domain Name Server
Documentation=man:named(8)
After=network.target
[Service]
#ExecStart=/usr/sbin/named -f -u bind
ExecStart=/usr/sbin/named -f -u bind -t /var/bind9/chroot
ExecReload=/usr/sbin/rndc reload
ExecStop=/usr/sbin/rndc stop
[Install]
WantedBy=multi-user.target
$
$ systemctl restart bind9
Warning: bind9.service changed on disk. Run 'systemctl daemon-reload' to reload units.
$ systemctl daemon-reload
$
$ systemctl restart bind9
$
Leider sind im Syslog viele Fehler zu finden, die einen Start des bind-Daemons verhindern. Offenbar liegt es an fehlenden Libraries in der chroot-Umgebung.
DNS blocking
Siehe dazu:
https://de.wikipedia.org/wiki/DNS-based_Blackhole_List $ ‚blackhole { …; };‘
http://www.deer-run.com/~hal/sysadmin/dns-advert.html (dummy-Zonen)
http://serverfault.com/questions/618106/set-up-bind9-as-dns-firewall
http://blogs.cisco.com/security/using-dns-rpz-to-block-malicious-dns-requests
http://www.linux-magazine.com/Issues/2014/161/Security-Lessons-DNS-Security
Topic 208: Web Services
208.1 Implementing a web server
Ein LAMP-System aufsetzen
Die Bestandteile:
Linux (Ubuntu Server)
Apache (Version 2)
MySQL als Datenbank
PHP oder Perl als serversetige Skriptsprache
Installation unter Debian / Ubuntu
Bei der Installation muss ein Passwort für die MySQL-Datenbank gesetzt werden!:
$ apt-get install apache2 mysql-server php php-mysql libapache2-mod-php
Normalerweise wird der Webserver auch gleich gestartet, Port 80 wird geöffnet:
$ telnet localhost 80
Trying ::1...
Connected to localhost.
Escape character is '^]'.
HEAD / HTTP/1.1
HTTP/1.1 400 Bad Request
Date: Mon, 07 Nov 2016 10:05:13 GMT
Server: Apache/2.4.18 (Ubuntu)
Connection: close
Content-Type: text/html; charset=iso-8859-1
Connection closed by foreign host.
$
Eine PHP-Testseite im Verzeichnis /var/www/html (= DocumentRoot) erzeugen:
$ cat > phpinfo.php <<EOF
<?php
phpinfo();
?>
> EOF
$
$ cat phpinfo.php
<?php
phpinfo();
?>
$
$ pgrep -a sql
4914 /usr/sbin/mysqld
$
Dann in einem Webbrowser diese Seite aufrufen:
http://IP-des-Apache/phpinfo.php
HINWEIS: Falls über einen Router (Tiny Core Linux) hinweg auf den Web-Server zugefiffen werden soll, ist die folgende Zeile erforderlich (vom Windows-Host aus durch diesen Router hindurch, Port-Forwarding):
$ iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j DNAT --to-destination 10.20.30.3
Testszenario: Wordpress installieren
ZIEL: Erfahrungen sammeln….
$ https://wordpress.org/latest.tar.gz
$ tar -xf latest.tar.gz
$
$ mv wordpress/ wp
$
$ grep www-data /etc/passwd /etc/group
/etc/passwd:www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
/etc/group:www-data:x:33:
$
$ chown -R www-data: wp
Nun müssen wir lediglich eine Datenbank anlegen, das geht ganz einfach mit:
$ mysqladmin -u root -p create wordpress
(MySQL-root-Passwort eingeben!)
Nun geht es im Web-UI mit der Installation weiter:
$ firefox http://localhost/wp
Auszufüllen sind nur wenige Felder, vor allem den Datenbank-Benutzername root und das dazugehörige Passwort toor:
a) Hier sollten die Zugangsdaten zu deiner Datenbank eingetragen werden. Im Zweifel frage bitte deinen Webhoster.
b) Datenbank Name - Der Name der Datenbank, die du für WordPress benutzen möchtest. (wordpress)
c) Benutzername - Dein Datenbank-Benutzername. (root)
d) Passwort - Dein Datenbank-Passwort. (toor)
e) Datenbank-Host - Sollte localhost nicht funktionieren, erfrage bitte den korrekten Wert bei deinem Web-Hoster. (localhost)
f) Tabellen-Präfix - Falls du mehrere WordPress-Installationen innerhalb einer Datenbank aufbauen möchtest, ändere diesen
In Sachen Troubleshooting kann man sich z.B. einfach in die Datenbank einloggen:
$ mysql -p -u root
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 7
Server version: 5.7.16-0ubuntu0.16.04.1 (Ubuntu)
Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> ^DBye
$
Sicherheit verbessern:
$ grep -r axel
$
$ grep -r toor
wp/wp-config.php:define('DB_PASSWORD', 'toor');
$
$
$ ls -l wp/wp-config.php
-rw-rw-rw- 1 www-data www-data 3125 Nov 7 11:46 wp/wp-config.php
$
$
$ chmod 440 wp/wp-config.php
Webserver Apache
Grundlegende Konfiguration
Wir begeben uns dazu ins „ServerRoot“-Verzeichnis (cd /etc/apache2
),
um dort nach grundlegend wichtigen Direktiven zu suchen, wie z.B.:
ServerRoot
DocumentRoot
DirectoryIndex
Options
VirtualHost
$ cd /etc/apache2
$
$ grep --color -r ServerRoot
apache2.conf:# ServerRoot: The top of the directory tree under which the server's
apache2.conf:#ServerRoot "/etc/apache2"
$
$
$
$ grep --color -r DocumentRoot
sites-available/000-default.conf: DocumentRoot /var/www/html
sites-available/default-ssl.conf: DocumentRoot /var/www/html
$
$
$ grep --color -r DirectoryIndex
mods-available/dir.conf: DirectoryIndex index.html index.cgi index.pl index.php index.xhtml index.htm
$
$
$ grep --color -r Virtual
conf-available/localized-error-pages.conf:# even on a per-VirtualHost basis. If you include the Alias in the global server
conf-available/other-vhosts-access-log.conf:# Define an access log for VirtualHosts that don't define their own logfile
ports.conf:# have to change the VirtualHost statement in
apache2.conf:# If you do not specify an ErrorLog directive within a <VirtualHost>
apache2.conf:# logged here. If you *do* define an error logfile for a <VirtualHost>
sites-available/000-default.conf:<VirtualHost *:80>
sites-available/000-default.conf:</VirtualHost>
sites-available/default-ssl.conf: <VirtualHost _default_:443>
sites-available/default-ssl.conf: </VirtualHost>
$
$
$
$ ls -l sites-enabled/
insgesamt 0
lrwxrwxrwx 1 root root 35 Nov 7 11:02 000-default.conf -> ../sites-available/000-default.conf
$
Directory Listing
Für den folgenden Test benennen wir die Standardseite index.html in start.html um. Nach der clientseitigen Aktualisierung (im Webbrowser) ist dann zu beobachten, dass sich der Server öffnet und alle seine weiteren Dateien und Verzeichnisse auflistet:
$ mv /var/www/html/index.html /var/www/html/start.html
ZIEL: Das Directory-Listing abschalten (Direktive: Options Indexes)
Am praktischsten verfährt man dabei so, dass die verantwortliche Datei über ihren Symlink aufgerufen wird (via Verzeichnis sites-enabled):
$ vi /etc/apache2/sites-enabled/000-default.conf
Diesen Abschnitt unterhalb von DocumentRoot /var/www/html einfügen:
<Directory /var/www/html/>
Options none
AllowOverride None
Require all granted
</Directory>
Danach die Konfiguration mit apachectl graceful
neu einlesen (=
reload).
Siehe auch https://wiki.apache.org/httpd/DirectoryListings
Apache historisch: httpd.conf
Siehe https://www.pantz.org/software/apache/apache13config.html
Zugriffsschutz einrichten
Grundlegend gibt es zwei Möglichkeiten:
Mittels separater .htaccess-Datei in DocumentRoot („Directory-level configuration“)
Mittels einer Directory-Anweisung (z.B. in Konfigdatei eines Vhosts)
Für beides benötigen wir die Direktive AllowOverride AuthConfig und Kommando htpasswd.
Siehe auch https://httpd.apache.org/docs/2.4/de/mod/core.html#allowoverride
Zur Methode A) via .htaccess
$ vi /etc/apache/sites-enabled/000-default.conf
### Hinzugefügter Abschnitt, um die Server-Defaults zu überschreiben
<Directory /var/www/html/>
Options none
AllowOverride AuthConfig
Require all granted
</Directory>
$ apachectl graceful
$ mkdir /var/www/html/privat
$ vi /var/www/html/privat/.htaccess
## Dateiname: .htaccess
## Diese versteckte Datei schützt ein privates Verzeichnis mit Benutzername/Passwort-Paar
##
## VORAUSSETZUNG: Apache muss mit Einstellung 'AllowOverride AuthConfig' des virtuellen
## Hosts neu gestartet werden!
## Zu finden ist sie innerhalb der Directory-Direktive des "DocumentRoot"-Vereichnispfades.
##
## Die Passwortdatei wird erstmalig zusammen mit dem ersten Benutzer kreiert:
##
## htpasswd -c /etc/apache2/passwords/access-passwd susi
##
## Später MUSS der Schalter '-c' beim Anlegen neuer Benutzer sowie beim Ändern eines
## Passworts WEGGELASSEN werden.
## Ansonsten wird die Datei ohne Rückfrage überschrieben!!
AuthName "Adminbereich"
AuthType Basic
## Passwortdatei muss mit absolutem Pfad angegeben werden:
AuthUserFile /etc/apache2/passwords/access-passwd
<Limit GET POST PUT>
## Alternativ kann ein bestimmter Benutzer abverlangt werden:
#require user tux max lisa
require valid-user
</Limit>
ACHTUNG: Wird die Datei nicht richtig benannt oder weggschoben, dann ist damit auch der der Schutz weg!
Überzeugen wir uns:
$ mv /var/www/html/privat/.htaccess /var/www/html/privat/.htacces
... F5 im Webbrower drücken: Alles offen!
Zur Methode B) via <VIRTUAL-HOST>.conf
Siehe dazu den Abschnitt Privates Verzeichnis für Firma 2, was im Dokument über Apaches virtuelle Hosts beschrieben wird.
Virtuelle Hosts für Apache2
Siehe dazu das Dokument Apache - virtuelle Hosts
208.2 Apache configuration for HTTPS
Grundlagen
Im OSI-Modell ist TLS-Protokoll zwischen den Schichten 5 bis 6 angesiedelt.
http://resources.infosecinstitute.com/ssl-dot-net-volume-1-hypothesis/
https://luxsci.com/blog/ssl-versus-tls-whats-the-difference.html
http://www.golem.de/news/imho-dnssec-ist-gescheitert-1506-114940.html
Zur Sicherheit des hierarchischen und pyramidenförmigen Aufbaus (Protokoll: X.509):
https://www.kuketz-blog.de/nsa-abhoersichere-ssl-verschluesselung-fuer-apache-und-nginx/
Unterschieben von CA-Zertifikaten, zentrale SSL-Gateways http://www.secupedia.info/wiki/SSL
Die TLS/SSL Technik ist an sich als »sicher« einzustufen, falls Client- wie auch serverseitig starke Cipher-Suiten eingesetzt werden.
Kostenlose Zertifikate gibt es, aber
Sie sind nicht immer in den Clients integriert (Zertifikatsspeicher!)
Abhängig von mehr oder weniger vertrauenswürdigen Zwischenzertifizierungsstellen (auch bei Lets Encrypt) https://jankarres.de/2015/12/lets-encrypt-kostenloses-ssltls-zertifikat-erstellen/
Siehe http://sslwebhosting.de/checkliste-wann-ist-das-ssl-zertifikat-notwendig/
Es muss ein Zugriffsschutz für das Gerät eingerichtet werden, da ein gestohlenes selbstsignierters Zertifikate natürlich auch immer wieder zum Signieren oder Verschlüsseln anderer Verbindungen eingesetzt werden kann!
Einrichtung der Verschlüsselung
Ein selbstsignierters Zertifikat ist schnell erzeugt. Nach dem Aktivieren des Moduls mittels a2enmod ssl
und dem Neustart von Apache kann das Zertifikat mit nur einer Zeile und der Fingerabdruck zur späteren Verifizierung mit einer weiteren erstellt werden:
$ cd /etc/ssl/
$ openssl req -new -outform PEM -out certs/testing.pem -newkey rsa:2048 -nodes \
-keyout private/testing.key -keyform PEM -days 3650 -x509
$ openssl x509 -fingerprint -noout -in testing.pem
Hier speziell ein Auszug der Schritte für Debian 8 (Jessie) mit Apache 2.4.10:
$ cd /etc/ssl/
$
$ ls -l
insgesamt 36
drwxr-xr-x 2 root root 20480 Nov 7 11:03 certs
-rw-r--r-- 1 root root 10835 Mai 2 2016 openssl.cnf
drwx--x--- 2 root ssl-cert 4096 Nov 7 11:03 private
$
$ openssl req -new -outform PEM -out certs/myweb.pem -newkey rsa:2048 -nodes -keyout private/myweb.key -keyform PEM -days 3650 -x509
Generating a 2048 bit RSA private key
..............................................................+++
...............+++
writing new private key to 'private/myweb.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:DE
State or Province Name (full name) [Some-State]:Sachsen
Locality Name (eg, city) []:Dresden
Organization Name (eg, company) [Internet Widgits Pty Ltd]:ComCave
Organizational Unit Name (eg, section) []:Technik
Common Name (e.g. server FQDN or YOUR name) []:www.dom1.test
Email Address []:axel@pemmann.de
$
$
$ head -4 private/myweb.key certs/myweb.pem
=$ private/myweb.key <==
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCqn7/oIYfy/XTB
czdfL437TSoKHoSI84dHslvoAdFQBCr+aernXxaywvErtOeLbDYihW8vXShtHH05
dwBOnVQqGB0TKOeYyI1hSnmZfU8GHGAMEkdrD8P98mV53o9I3IFWjyLpL1xCNQRc
=$ certs/myweb.pem <==
-----BEGIN CERTIFICATE-----
MIID7zCCAtegAwIBAgIJALrpEOAkl9tGMA0GCSqGSIb3DQEBCwUAMIGNMQswCQYD
VQQGEwJERTEQMA4GA1UECAwHU2FjaHNlbjEQMA4GA1UEBwwHRHJlc2RlbjEQMA4G
A1UECgwHQ29tQ2F2ZTEQMA4GA1UECwwHVGVjaG5pazEWMBQGA1UEAwwNd3d3LmRv
$
Danach die Apache-Konfig-Datei in Sachen Zertifikatsdatei und -schlüssel anpassen:
SSLEngine on
SSLCertificateFile /etc/ssl/certs/myweb.pem
SSLCertificateKeyFile /etc/ssl/private/myweb.key
LPI-RELEVANT: Ein auskommentierter Parameter ist u.a. SSLVerifyClient require
. Damit kann eine clientseitige Authentifzierung mit Zertifikat erzwungen werden. Dies entspricht in etwa einem Anmeldevorgang mit einem Benutzername/Passwort-Paar. Siehe dazu http://www.phpgangsta.de/client-zertifikate-als-sicherer-login-ersatz
Insgesamt sieht die Datei dann so aus:
$ grep -v \# sites-enabled/default-ssl.conf | grep -v '^$'
<IfModule mod_ssl.c>
<VirtualHost _default_:443>
ServerAdmin webmaster@localhost
DocumentRoot /var/www/html
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
SSLEngine on
SSLCertificateFile /etc/ssl/certs/myweb.pem
SSLCertificateKeyFile /etc/ssl/private/myweb.key
<FilesMatch "\.(cgi|shtml|phtml|php)$">
SSLOptions +StdEnvVars
</FilesMatch>
<Directory /usr/lib/cgi-bin>
SSLOptions +StdEnvVars
</Directory>
</VirtualHost>
</IfModule>
$
Nun müssen noch diese Konfigurationsdatei sowie das SSL-Modul aktiviert werden:
$ a2ensite default-ssl.conf
$ a2enmode ssl
$ apache2ctl restart
Mit apachectl -M | grep -i ssl
kann überprüft werden, ob das Modul aktiviert wurde.
Kommandozeilenbasierten Verbindungsaufbau durchführen
$ openssl s_client -tls1_2 -connect 10.20.30.3:443
Die Ausgabe sieht dann so aus:
CONNECTED(00000003)
depth=0 C = DE, ST = Sachsen, L = Dresden, O = ComCave, OU = Technik, CN = www.dom1.test, emailAddress = axel@pemmann.de
verify error:num=18:self signed certificate
verify return:1
depth=0 C = DE, ST = Sachsen, L = Dresden, O = ComCave, OU = Technik, CN = www.dom1.test, emailAddress = axel@pemmann.de
verify return:1
---
Certificate chain
0 s:/C=DE/ST=Sachsen/L=Dresden/O=ComCave/OU=Technik/CN=www.dom1.test/emailAddress=axel@pemmann.de
i:/C=DE/ST=Sachsen/L=Dresden/O=ComCave/OU=Technik/CN=www.dom1.test/emailAddress=axel@pemmann.de
---
Server certificate
-----BEGIN CERTIFICATE-----
MIID7zCCAtegAwIBAgIJALrpEOAkl9tGMA0GCSqGSIb3DQEBCwUAMIGNMQswCQYD
VQQGEwJERTEQMA4GA1UECAwHU2FjaHNlbjEQMA4GA1UEBwwHRHJlc2RlbjEQMA4G
A1UECgwHQ29tQ2F2ZTEQMA4GA1UECwwHVGVjaG5pazEWMBQGA1UEAwwNd3d3LmRv
... usw. ...
Start Time: 1478693723
Timeout : 7200 (sec)
Verify return code: 18 (self signed certificate)
^C
208.3 Implementing a proxy server
ZIEL: Ein sehr sicheren, cachenden HTTP-Proxy (Stellvertreter-Dienst nicht nur für HTTP) installieren und konfigurieren:
$ apt-get install squid3
Paketlisten werden gelesen... Fertig
Abhängigkeitsbaum wird aufgebaut.
Statusinformationen werden eingelesen.... Fertig
Die folgenden zusätzlichen Pakete werden installiert:
libecap2 libltdl7 libnetfilter-conntrack3 squid-langpack squid3-common
Vorgeschlagene Pakete:
squidclient squid-cgi squid-purge resolvconf smbclient ufw winbindd
Die folgenden NEUEN Pakete werden installiert:
libecap2 libltdl7 libnetfilter-conntrack3 squid-langpack squid3 squid3-common
0 aktualisiert, 6 neu installiert, 0 zu entfernen und 20 nicht aktualisiert.
Es müssen 2.575 kB an Archiven heruntergeladen werden.
Nach dieser Operation werden 9.115 kB Plattenplatz zusätzlich benutzt.
Möchten Sie fortfahren? [J/n]
Konfiguration des Servers
ACHTUNG: Es ist das ganze Handbuch enthalten, deshalb erst einmal nur die aktiven Zeilen ausgeben:
$ grep -Ev '^\s*#|^$' /etc/squid3/squid.conf
acl SSL_ports port 443
acl CONNECT method CONNECT
http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports
http_access allow localhost manager
http_access deny manager
http_access allow localhost
http_access deny all
http_port 3128
coredump_dir /var/spool/squid3
refresh_pattern ^ftp: 1440 20% 10080
refresh_pattern ^gopher: 1440 0% 1440
refresh_pattern -i (/cgi-bin/|\?) 0 0% 0
refresh_pattern . 0 20% 4320
$
Wichtige Grundeinstellungen:
http_port 3128
cache_dir ufs /var/spool/squid3 100 16 256
cache_mem 256 MB
Der Proxy-Server arbeitet bei Debian per Default nur als lokal verwendbarer Server, deshalb müssen wir sogleich die Konfigurationsdatei ändern:
$ vi /etc/squid3/squid.conf
Wir suchen nach INSERT und schreiben unsere Regeln VOR die deny-Zeile (Hier herrscht batch-Betrieb!):
#
# INSERT YOUR OWN RULE(S) HERE TO ALLOW ACCESS FROM YOUR CLIENTS
#
# Example rule allowing access from your local networks.
# Adapt localnet in the ACL section to list your (internal) IP networks
# from where browsing should be allowed
#http_access allow localnet
http_access allow localhost
# And finally deny all other access to this proxy
http_access deny all
Wir schreiben oberhalb der Regel ‚http_access deny all‘ die zwei folgenden Zeilen hinein:
acl myDMZ src 10.20.30.0/24
http_access allow myDMZ
Oder aber einfach die fertigen Regeln mit localnet suchen und aktivieren:
$ grep -v '\#' /etc/squid3/squid.conf | grep -v '^$'
acl SSL_ports port 443
acl CONNECT method CONNECT
http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports
http_access allow localhost manager
http_access deny manager
http_access allow localnet
http_access allow localhost
http_access deny all
http_port 3128
coredump_dir /var/spool/squid3
refresh_pattern ^ftp: 1440 20% 10080
refresh_pattern ^gopher: 1440 0% 1440
refresh_pattern -i (/cgi-bin/|\?) 0 0% 0
refresh_pattern . 0 20% 4320
$
$ systemctl restart squid3.service
$ pgrep -a squid
4664 /usr/sbin/squid3 -YC -f /etc/squid3/squid.conf
4666 (squid-1) -YC -f /etc/squid3/squid.conf
$
$ tail -f /var/log/squid3/access.log
Konfiguration des Clients
Am besten zuerst einmal für Testzwecke die Variable ‚http_proxy‘ setzen:
$ export http_proxy="http://10.20.30.5:3128"
$ wget blindekuh.de
Port-Forwarding mit iptables
Falls der Proxy-Server hinter einem Router steht, lässt sich auf folgende Weise eine Portweiterleitung einrichten. Die dritte Zeile ist dabei die eigentliche für den Proxy-Serverzugriff erforderliche (Socket: 10.20.30.5:3128):
$ iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j DNAT --to-destination 10.20.30.3
$ iptables -t nat -A PREROUTING -i eth0 -p udp --dport 53 -j DNAT --to-destination 10.20.30.3
$ iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 3128 -j DNAT --to-destination 10.20.30.5
Weitere Server-Einstellungen
Filter mit urlpath_regex
https://wiki.gentoo.org/wiki/Security_Handbook/Firewalls
Dort nach files.acl suchen:
Definition der ACL:
acl archives urlpath_regex "/etc/squid3/files.acl"
Dann weiter unten VOR der allow- und deny-Regel:
http_access deny archives
Insgesamt sieht das so aus:
acl archives urlpath_regex "/etc/squid3/files.acl"
http_access deny archives
http_access allow localnet
http_access allow localhost
# And finally deny all other access to this proxy
http_access deny all
AUFGABE: die Datei /etc/squid3/files.acl erstellen und testen:
\.[Zz][Ii][pP]$
\.[Vv][Ii][Vv].*
\.[Ee][Xx][Ee]$
\.[Mm][Pp]3$
\.[Rr][Aa][Rr]$
\.[Aa][Cc][Ee]$
\.[Aa][Ss][Ff]$
\.[Aa][Vv][Ii]$
\.[Mm][Oo][Vv]$
\.[Mm][Pp][Gg]$
\.[Mm][Pp][Ee][Gg]$
\.[Aa][Uu]$
\.[Rr][Aa]$
\.[Aa][Rr][Jj]$
\.[Tt][Aa][Rr]$
\.[Gg][Zz]$
\.[Zz]$
$ systemctl reload squid3
ACLs logisch verknüpfen
Es lassen sich problemlos logisch ODER- sowie UND-Verknüpfungen realisieren.
Im folgenden Beispiel werden zuerst einmal Datenpakete, die aus den beiden Netzwerken ‚10.20.30.0/24‘ sowie ‚10.22.15.0/24‘ herrühren (‚src‘), in einer ACL namens ‚myDMZ‘ mittels logischem ODER verknüpft und später entsprechend verarbeitet.
Danach wird in der ACL ‚surfZeit‘ eine Zeitspanne festgelegt.
Und schließlich geben wir mittels der ‚http_access‘-Direktive Zugriff auf den Cache des Proxies, wobei eine UND-Verknüpfung von ‚myDMZ‘ und ‚surfZeit‘ zur Anwendung kommt:
acl myDMZ src 10.20.30.0/24
acl myDMZ src 10.22.15.0/24
acl surfZeit time 12:00-13:00
http_access allow myDMZ surfZeit
Siehe dazu auch http://www.selflinux.org/selflinux/html/squid05.html
Mitsamt unserer obigen ACL namens ‚archives‘ und der Voreinstellungen gestaltet sich das Regelwerk unterhalb von ‚INSERT‘ dann so:
http_access allow localhost
acl archives urlpath_regex "/etc/squid3/files.acl"
acl myDMZ src 10.20.30.0/24
acl myDMZ src 10.22.15.0/24
acl surfzeit time 12:00-13:00
http_access deny archives
http_access allow myDMZ surfzeit
# And finally deny all other access to this proxy
http_access deny all
Benutzer-Authentifzierung
(Kurznotizen vom März 2013, Debian stable)
ÜBERBLICK (im oberen Bereich der Konfigdatei einzufügen):
Regeln mit
auth_param
definierenInsbesondere muss ein ‚realm‘ festgelegt werden, Standard ist: „Squid proxy-caching web server“
Für einen Benutzer muss dann in Zusammenhang mit diesem ‚realm‘ ein Passwort-Dateieintrag erzeugt werden (md5sum aus einem Skript aufgerufen $ digest_passwd.sh)
Abschließend VOR dem Erlauben der „lokales Netz“-Regel ist die Authentifizieren abzuverlangen:
acl vertrautenutzer proxy_auth REQUIRED
http_acces allow vertrautenutzer
Inhalt der Datei ‚/etc/squid3/squid.conf‘:
auth_param digest program /usr/lib/squid3/digest_pw_auth -c /etc/squid3/digestpw
auth_param digest children 5
auth_param digest realm Squid proxy-caching web server
auth_param digest nonce_garbage_interval 5 minutes
auth_param digest nonce_max_duration 30 minutes
auth_param digest nonce_max_count 50
acl manager proto cache_object
acl localhost src 127.0.0.1/32 ::1
acl to_localhost dst 127.0.0.0/8 0.0.0.0/32 ::1
acl SSL_ports port 443
acl Safe_ports port 80 # http
acl Safe_ports port 21 # ftp
acl Safe_ports port 443 # https
acl Safe_ports port 70 # gopher
acl Safe_ports port 210 # wais
acl Safe_ports port 1025-65535 # unregistered ports
acl Safe_ports port 280 # http-mgmt
acl Safe_ports port 488 # gss-http
acl Safe_ports port 591 # filemaker
acl Safe_ports port 777 # multiling http
acl CONNECT method CONNECT
http_access allow manager localhost
http_access deny manager
http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports
acl trusted_users proxy_auth REQUIRED
http_access allow trusted_users
acl local_net src 10.2.3.0/24 # RFC1918 possible internal network
http_access allow local_net
acl INSIDE_IP dst 10.2.3.0/24
always_direct allow INSIDE_IP
never_direct allow all
http_access allow localhost
http_access deny all
http_port 3128 intercept
cache_peer 10.2.3.1 parent 3128 0 proxy-only
hierarchy_stoplist cgi-bin ?
coredump_dir /var/spool/squid3
refresh_pattern ^ftp: 1440 20% 10080
refresh_pattern ^gopher: 1440 0% 1440
refresh_pattern -i (/cgi-bin/|\?) 0 0% 0
refresh_pattern . 0 20% 4320
Inhalt der Datei ‚/etc/squid3/digestpw‘:
otto:Squid proxy-caching web server:89221b025babc71df635bca946ce0e21
Relevanter Anteil aus der ‚squid.conf‘:
# Wichtiger Hinweis
# http://www.squid-cache.org/Doc/config/auth_param/
# WARNING: authentication can't be used in a transparently intercepting
# proxy as the client then thinks it is talking to an origin server and
# not the proxy. This is a limitation of bending the TCP/IP protocol to
# transparently intercepting port 80, not a limitation in Squid.
# Ports flagged 'transparent', 'intercept', or 'tproxy' have
# authentication disabled.
### Wichtige Voreinstellungen
auth_param digest program /usr/lib/squid3/digest_pw_auth -c /etc/squid3/digestpw
auth_param digest children 5
auth_param digest realm Squid proxy-caching web server
auth_param digest nonce_garbage_interval 5 minutes
auth_param digest nonce_max_duration 30 minutes
auth_param digest nonce_max_count 50
### Eine dazu passende ACL (oberhalb der LAN-Zugriffs-Regel zu plazieren)
acl trusted_users proxy_auth REQUIRED
http_access allow trusted_users
Inhalt der Datei ‚digest_passwd.sh‘:
#!/bin/sh
#
# http://fsk141.com/tutorial-squid-proxy-with-digest-authentication
#
#
# AUFRUF: digest_passwd.sh name password 'Squid proxy-caching web server' > /etc/squid/digest_passwd
user=$1
pass=$2
realm=$3
if [ -z "$1" -o -z "$2" -o -z "$3" ] ; then
echo "Usage: $0 user password 'realm'";
exit 1
fi
ha1=$(echo -n "$user:$realm:$pass"|md5sum |cut -f1 -d' ')
echo "$user:$realm:$ha1"
Benachbarten Proxy-Cache anzapfen
Wichtige Anweisungen:
cache_peer 10.2.3.1 parent 3128 0 proxy-only
Zur Optimierung im Falle älterer Proxy-Versionen:
acl INSIDE_IP dst 10.2.3.0/24
always_direct allow INSIDE_IP
never_direct allow all
208.4 Implementing Nginx as a web server and a reverse proxy
Nginx als reverser Proxy
Siehe dazu:
http://www.pcwelt.de/ratgeber/Nginx___So_klappt_der_unsinkbare_Webserver-Linux-Server-8005285.html
https://www.google.de/search?q=filetype%3Apdf+%22proxy_pass%22+lpi+202&btnG=Suche
http://gratisexam.com/lpi/117-202/LPI.Pass4sure.117-202.v2015-03-28.by.Isaac.294q.pdf
Apache am Port 8000 betreiben
$ vi /etc/apache2/ports.conf
$
$ vi /etc/apache2/sites-enabled/000-default.conf
$
$ grep 8000 /etc/apache2/ports.conf /etc/apache2/sites-enabled/000-default.conf
/etc/apache2/ports.conf:Listen 8000
/etc/apache2/sites-enabled/000-default.conf:<VirtualHost *:8000>
$
$ apache2ctl restart
$
$ lsof -i -Pn | grep 8000
apache2 1342 root 8u IPv6 37268 0t0 TCP *:8000 (LISTEN)
apache2 4526 www-data 8u IPv6 37268 0t0 TCP *:8000 (LISTEN)
apache2 4527 www-data 8u IPv6 37268 0t0 TCP *:8000 (LISTEN)
apache2 4528 www-data 8u IPv6 37268 0t0 TCP *:8000 (LISTEN)
apache2 4529 www-data 8u IPv6 37268 0t0 TCP *:8000 (LISTEN)
apache2 4530 www-data 8u IPv6 37268 0t0 TCP *:8000 (LISTEN)
apache2 4531 www-data 8u IPv6 37268 0t0 TCP *:8000 (LISTEN)
apache2 4532 www-data 8u IPv6 37268 0t0 TCP *:8000 (LISTEN)
apache2 4533 www-data 8u IPv6 37268 0t0 TCP *:8000 (LISTEN)
apache2 4534 www-data 8u IPv6 37268 0t0 TCP *:8000 (LISTEN)
apache2 4535 www-data 8u IPv6 37268 0t0 TCP *:8000 (LISTEN)
apache2 4536 www-data 8u IPv6 37268 0t0 TCP *:8000 (LISTEN)
apache2 4537 www-data 8u IPv6 37268 0t0 TCP *:8000 (LISTEN)
$
Nginx installieren und einrichten
$ apt-get install nginx
Zu allererst wollen wir eine vom Apache altbekannte Einstellung, das Directory
Listing (Options Indexes
) jetzt auch mit diesem Webserver realisieren. Siehe dazu auch http://nginx.org/en/docs/http/ngx_http_autoindex_module.html
Wir bearbeiten deshalb die Hauptkonfigurationsdatei namens ‚/etc/nginx/sites-enabled/default‘. Innerhalb der
default-Direktive server { ... }
kann man auf einfache Weise eine Freigabe z.B. für einen Ordner namens ‚doc‘ hinzufügen.
Dazu benötigen wir den Parameter autoindex on;
:
location /doc {
autoindex on;
}
Die Datei sieht dann insgesamt so aus (cat /etc/nginx/sites-enabled/default | grep -v \# | grep -v ^$
):
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/html;
index index.html index.htm index.nginx-debian.html;
server_name _;
location / {
try_files $uri $uri/ =404;
}
location /doc {
autoindex on;
}
}
Natürlich müssen wir die Änderungen wieder einlesen:
$ systemctl restart nginx
Erweiterung um reverse Proxy-Funktion
Mit Hilfe von proxy_pass
lassen wir jetzt unseren neuen Webserver als vorgeschalteten Server für den Apachen arbeiten.
Die erforderliche Konfiguration in der ‚/etc/nginx/sites-enabled/default‘ sieht im Endeffekt so aus:
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/html;
index index.html index.htm index.nginx-debian.html;
server_name _;
location / {
# Zeile hinzugefügt:
proxy_pass http://127.0.0.1:8000;
# Zeile auskommentiert:
#try_files $uri $uri/ =404;
}
# Abschnitt hinzugefügt:
location /doc {
autoindex on;
}
}
Im Zusammenhang mit der reversen Arbeitsweise gibt es neben proxy_pass
noch zwei weitere LPI-relevante Direktiven:
proxy_set_header
- Imlocation
-Abschnitt: um auch dynamische Inhalte weiterzuleitenfastcgi_pass
- In einem separatenlocation
-Abschnitt: um Requests von FastCGI-Anwendungen behandeln zu können (PHP)
Siehe dazu:
https://www.nginx.com/resources/wiki/start/topics/examples/likeapache/
https://www.dinotools.de/2012/01/21/nginx-mit-php-per-fastcgi/
HINWEIS: Um Nginx als eigenständigen Webserver mitzuteilen, dass die index.html per Default aus einem Unterverzeichnis von
root
zu laden ist (um z.B. ein kleines CMS wie https://getnikola.com/ auszuprobieren), ist so etwas erforderlich wie hier:
location / {
if ($uri = '/'){
rewrite ^/(.*)$ https://pemmann.de/cms/ permanent;
}
}
Siehe dazu https://stackoverflow.com/questions/17738088/rewrite-root-address-to-a-subdirectory-in-nginx
AUFGABE: Apache soll jetzt nur noch an 127.0.0.1 lauschen
Die momentane Situation sieht nämlich so aus und birgt Sicherheitsrisiken:
$ grep 8000 /etc/apache2/ports.conf /etc/apache2/sites-enabled/000-default.conf
/etc/apache2/ports.conf:Listen 8000
/etc/apache2/sites-enabled/000-default.conf:<VirtualHost *:8000>
$
LÖSUNG / Vertiefung apache/bind
AUFGABE: Bitte die Datei /etc/apache2/ports.conf anpassen auf folgende Einstellung:
Listen 127.0.0.1:8000
Grund: Angreifer könnten sonst im Zusammenhang mit nginx als reversen Proxyserver auf den privaten, von Apache freigegebenen Ordner via
http://10.20.30.3:8000/privat
zugreifen, wobei dann KEINE Passwortabfrage erfolgt!
Zu bind9: Zur Frage, ob überhaupt forwarders bei Bind9 erforderlich und nützlich sind, siehe http://peter-kline.com/?p=64
Topic 209: File Sharing
209.1 SAMBA Server Configuration
Samba - ein Ersatz für Windows Server; wichtige Eckpunkte:
Version 3 wird nicht mehr offiziell supportet! ⇒ umsteigen auf Version 4 (gilt nicht für LTS-Distributionen wie auch CentOS 7)
Der Samba 3-Quellcode wird in samba4 weitergeplegt und fürs File- und Printer-Sharing benutzt
Samba3-Daemons: smbd, nmbd, winbindd
Samba4-Daemon (LDAP- und DNS-Ersatz, Kerberos-Dienst): samba
$ whatis smbd
smbd (8) - server to provide SMB/CIFS services to clients
$
$ whatis winbindd
winbindd (8) - Name Service Switch daemon for resolving names from NT servers
$
$ whatis samba
samba (8) - Server to provide AD and SMB/CIFS services to clients
samba (7) - A Windows AD and SMB/CIFS fileserver for UNIX
$ whatis samba-tool
samba-tool (8) - Main Samba administration tool.
$
$
$
$ whatis nmbd
nmbd (8) - NetBIOS name server to provide NetBIOS over IP naming services to clients
$
Installation und Konfiguration für einfaches File-Sharing
Wir beginnen einfach mal…
$ apt-get install samba smbclient
...
$ cd /etc/samba
$ cp smb.conf smb.conf.orig
$
$ less smb.conf
Aufbau der smb.conf:
Wie Windows-init-Dateien
Vordefinirter Abschnitt 1: [global]
- Arbeitsgruppen- oder Domänenname festlegen:
workgroup = dom1
(Im Zusammenhang mit domain logons = Yes ist das dann der NetBIOS-Domaine) Sicherheitsstufe:
security = User
(ist ehemals Default, heute: „server role = …“)Gast-Account aktivieren:
map to guest = Bad User
Vordefinirter Abschnitt 2 (optional): [homes] - gibt alle Unix-Heimatverzeichnisse frei
Vordefinirter Abschnitt 3 (optional): [printers] - gibt alle eingerichteten Drucker frei
Eine einfache /etc/samba/smb.conf
kann so aussehen:
[global]
map to guest = bad user
[free4all]
path = /srv/samba/pub
public = yes
writable = yes
Wir testen nun ausgiebig (Voreinstellungen mit -v
):
# testparm
Load smb config files from /etc/samba/smb.conf
Processing section "[free4all]"
Loaded services file OK.
Server role: ROLE_STANDALONE
Press enter to see a dump of your service definitions
# Global parameters
[global]
map to guest = Bad User
idmap config * : backend = tdb
[free4all]
path = /srv/samba/pub
read only = No
guest ok = Yes
#
#
# testparm -v | grep guest
Load smb config files from /etc/samba/smb.conf
Processing section "[free4all]"
Loaded services file OK.
Server role: ROLE_STANDALONE
Press enter to see a dump of your service definitions
map to guest = Bad User
guest account = nobody
usershare allow guests = No
guest only = No
guest ok = No
guest ok = Yes
#
# testparm -v | grep workgroup
Load smb config files from /etc/samba/smb.conf
Processing section "[free4all]"
Loaded services file OK.
Server role: ROLE_STANDALONE
Press enter to see a dump of your service definitions
workgroup = WORKGROUP
#
# testparm -v | grep security
Load smb config files from /etc/samba/smb.conf
Processing section "[free4all]"
Loaded services file OK.
Server role: ROLE_STANDALONE
Press enter to see a dump of your service definitions
security = AUTO
#
Wir erzeugen jetzt das Freigabeverzeichnis und starten den Server neu:
# mkdir -m 1777 -p /srv/samba/pub/write
#
#
# ls -lRa /srv/samba/pub/
/srv/samba/pub/:
insgesamt 12
drwxr-xr-x 3 root root 4096 Nov 17 11:31 .
drwxr-xr-x 3 root root 4096 Nov 17 11:31 ..
drwxrwxrwt 2 root root 4096 Nov 17 11:31 write
/srv/samba/pub/write:
insgesamt 8
drwxrwxrwt 2 root root 4096 Nov 17 11:31 .
drwxr-xr-x 3 root root 4096 Nov 17 11:31 ..
#
# systemctl restart smbd
#
# systemctl restart nmbd
Testings
Browseliste beziehen (Welche Shares gibt es?)
# smbclient -NL localhost
Domain=[WORKGROUP] OS=[Windows 6.1] Server=[Samba 4.2.10-Debian]
Sharename Type Comment
--------- ---- -------
free4all Disk
IPC$ IPC IPC Service (Samba 4.2.10-Debian)
Domain=[WORKGROUP] OS=[Windows 6.1] Server=[Samba 4.2.10-Debian]
Server Comment
--------- -------
D8SQUID Samba 4.2.10-Debian
Workgroup Master
--------- -------
WORKGROUP
#
Zugriff aufs Share als Gast (anonymous):
# smbclient -U% //localhost/free4all
Domain=[WORKGROUP] OS=[Windows 6.1] Server=[Samba 4.2.10-Debian]
smb: \>
smb: \> mkdir ABC
NT_STATUS_ACCESS_DENIED making remote directory \ABC
smb: \>
smb: \> dir
. D 0 Thu Nov 17 11:31:03 2016
.. D 0 Thu Nov 17 11:31:03 2016
write D 0 Thu Nov 17 11:31:03 2016
8516872 blocks of size 1024. 7201860 blocks available
smb: \> cd write\
smb: \write\>
smb: \write\> mkdir ABC
smb: \write\>
smb: \write\>
Authentifzierter Zugriff von Linux- und Windows-Clients aus
Hierbei wurde der Gast-Account deaktiviert (mit Semikolon):
# vi smb.conf
#
# cat smb.conf
[global]
;map to guest = bad user
[free4all]
path = /srv/samba/pub
public = yes
writable = yes
#
# systemctl restart smbd
#
#
# testparm -v | grep guest
Load smb config files from /etc/samba/smb.conf
Processing section "[free4all]"
Loaded services file OK.
Server role: ROLE_STANDALONE
Press enter to see a dump of your service definitions
map to guest = Never
guest account = nobody
usershare allow guests = No
guest only = No
guest ok = No
guest ok = Yes
#
# smbclient -U% //localhost/free4all
Domain=[WORKGROUP] OS=[Windows 6.1] Server=[Samba 4.2.10-Debian]
smb: \> quit
#
Jetzt unter Windows mit winuser zugreifen:
# useradd -d /nodir -s /bin/false winuser
#
# smbpasswd -a winuser
New SMB password:
Retype new SMB password:
Added user winuser.
#
#
# smbclient -Uwinuser //localhost/free4all
Enter winuser's password:
session setup failed: NT_STATUS_LOGON_FAILURE
#
# smbclient -Uwinuser //localhost/free4all
Enter winuser's password:
Domain=[WORKGROUP] OS=[Windows 6.1] Server=[Samba 4.2.10-Debian]
smb: \>
smb: \> ls
. D 0 Thu Nov 17 11:31:03 2016
.. D 0 Thu Nov 17 11:31:03 2016
write D 0 Thu Nov 17 11:49:40 2016
8516872 blocks of size 1024. 7201852 blocks available
smb: \> mkdir VonWinuser
NT_STATUS_ACCESS_DENIED making remote directory \VonWinuser
smb: \>
smb: \> cd write\
smb: \write\>
smb: \write\> mkdir VonWinuser
smb: \write\>
smb: \write\> by
by: command not found
smb: \write\>
smb: \write\> quit
#
# ls -l /srv/samba/pub/write/
insgesamt 12
drwxr-xr-x 2 nobody nogroup 4096 Nov 17 11:41 ABC
drwxr-xr-x 2 nobody nogroup 4096 Nov 17 11:49 New folder
drwxr-xr-x 2 winuser winuser 4096 Nov 17 12:00 VonWinuser
#
#
# ls -l /srv/samba/pub/write/
insgesamt 16
drwxr-xr-x 2 nobody nogroup 4096 Nov 17 11:41 ABC
drwxr-xr-x 2 nobody nogroup 4096 Nov 17 11:49 New folder
drwxr-xr-x 2 winuser winuser 4096 Nov 17 12:01 New folder (2)
drwxr-xr-x 2 winuser winuser 4096 Nov 17 12:00 VonWinuser
#
Die Lage der trivialen Datenbank des SAM-Managers (backend: tdbsam) ist hier zu sehen:
# ls -l /var/lib/samba/private/
insgesamt 840
-rw------- 1 root root 696 Nov 17 09:33 netlogon_creds_cli.tdb
-rw------- 1 root root 421888 Nov 17 11:58 passdb.tdb
-rw------- 1 root root 430080 Nov 17 09:30 secrets.tdb
drwxr-xr-x 3 root root 4096 Nov 17 09:33 smbd.tmp
#
#
# testparm -v | grep backend
Load smb config files from /etc/samba/smb.conf
Processing section "[free4all]"
Loaded services file OK.
Server role: ROLE_STANDALONE
Press enter to see a dump of your service definitions
config backend = file
passdb backend = tdbsam
idmap backend = tdb
share backend = classic
idmap config * : backend = tdb
#
#
Anders als Windows schert sich Linux NICHT um den deaktivierten Gastzugang:
# smbclient -U% //localhost/free4all
Domain=[WORKGROUP] OS=[Windows 6.1] Server=[Samba 4.2.10-Debian]
smb: \>
smb: \>
Linktipp: Methoden der Namensauslösung - http://www.elektronik-kompendium.de/sites/net/0901081.htm
WINS - Namensauflösung für NetBIOS-Namen
Samba soll selber als WINS-Server auftreten: wins support = yes
$ man smb.conf
wins support (G)
This boolean controls if the nmbd(8) process in Samba will act as a WINS server. You
should not set this to yes unless you have a multi-subnetted network and you wish a
particular nmbd to be your WINS server. Note that you should NEVER set this to yes on
more than one machine in your network.
Default: wins support = no
Dagegen tritt Samba als WINS-Client mit dieser Direktive auf: wins server = myNeighborWinServer
ACHTUNG: Die beiden Schalter schließen sich gegenseitig aus!
Grundeinstellungen im globalen Abschnitt
Sicherheitslevel
Im globalen Abschnitt der smb.conf findet sich security = ...
, was verschiedene Werte kennt.
Hintergrund ist die historische Entwicklung, die gemeinsam mit IBM begann: der alte LAN-Manager beherrschte nur die Sicherheit auf Share-Ebene, d.h. ein grundsätzliches sich am Server Anmelden-Müssen gab es nicht (aus einem LPI-Braindump: „Using for a simple Print Server“). Die entsprechende Einstellung lautet:
security = share
Heutzutage sollte sich aber ein „User“ zuerst am Server anmelden, danach bekommt er erst die Shares zu sehen. Der User-Level ist Voreinstellung bei Samba v3. Dieser Modus wir auch benötigt, wenn unser Samba-Server selber als
PDC auftreten möchte (domain logons = yes
). Die entsprechende Einstellung lautet:
security = user
Weitere Modi sind wichtig, wenn Samba als Mitgliedsserver in einer Windows-Domänen arbeiten soll, hierbei übernimmt ein alter Windows NT DC die Authentifizierung:
security = domain
Ab Windows 2000 Server gibt es ein zentrales LDAP-Verzeichnis, daher auch ein anderes Level, mit dem Samba als Mitgliedsserver in einem ADS auftreten kann:
security = ads
Falls security = AUTO
auftaucht, liegt Samba in Version 4 vor, wo es jetzt anstelle dessen eigentlich server role = ...
gibt:
[root@debi:~]# testparm -vs 2>/dev/null | grep "server role"
server role = auto
[root@debi:~]#
[root@debi:~]# testparm -vs 2>/dev/null | grep "security"
security = AUTO
[root@debi:~]# # >> Alles "auto", dh. es findet eine automatische Erkennung statt.
Siehe dazu:
Passwort-Backends
Weil wir zweigleisig fahren müssen (Unix: PosixAccount + Windows: SambaSamAccount) muss je nach Sicherheitslevel bzw. Serverrolle ein anderes Backend verwendet werden:
root@debi:~# testparm -vs 2>/dev/null | grep backend
config backend = file
idmap backend = tdb
passdb backend = tdbsam
share backend = classic
idmap config * : backend = tdb
root@debi:~#
Das tdbsam-Backend ist schon länger Standard, das Kürzel steht für „Trivial DataBase of the Security Account Manager“. Diese triviale Datenbank kann schon länger Windows recht gut nachahmen, beinhaltet aber keinen zentralen Verzeichnisdienst. Nachdem wir unserem bereits vorhandenen Unix-Nutzer „tux“ mittels pdbedit -a tux
einen Samba-Account beigeordent haben, können wir uns nun seine Eigenschaften ansehen:
root@debi:~# pdbedit -L -u tux -v
Unix username: tux
NT username:
Account Flags: [U ]
User SID: S-1-5-21-2079638846-3257800411-525591495-1000
Primary Group SID: S-1-5-21-2079638846-3257800411-525591495-513
Full Name: Mr. tux
Home Directory: \\debi\tux
HomeDir Drive:
Logon Script:
Profile Path: \\debi\tux\profile
Domain: DEBI
Account desc:
Workstations:
Munged dial:
Logon time: 0
Logoff time: Mi, 06 Feb 2036 16:06:39 CET
Kickoff time: Mi, 06 Feb 2036 16:06:39 CET
Password last set: Mo, 07 Jun 2021 10:27:40 CEST
Password can change: Mo, 07 Jun 2021 10:27:40 CEST
Password must change: never
Last bad password : 0
Bad password count : 0
Logon hours : FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
Weitere Backends sind:
Flache Textdateien (veraltet!):
passdb backend = smbpasswd
(ähnlich der /etc/passwd)LDAP-Datenbank basierte Authentifizierung:
passdb backend = ldapsam
(Nutzung eines zentralen Verzeichnisdienstes)
Siehe dazu:
Samba 4 in der Rolle eines alten PDC
Neu ist hier, dass wir einen zusätzlichen Parameter brauchen: server role = classic primary domain controller
$ vi /etc/samba/smb.conf
[global]
;map to guest = bad user
workgroup = DOM1
server role = classic primary domain controller
; Einstellungen fürs Browsing
domain master = yes
local master = yes
preferred master = yes
os level = 255
; Übermittlung an Clients, welcher UNC-Pfad verwedet werden soll
;logon path = \\%L\profiles\%U
; AUFGABE: Bitte dies für verschiedene Windows-Architekturen robuster machen!
logon path = \\%L\profiles\%U\%a
[profiles]
comment = Profile Share
path = /srv/samba/profiles
writable = yes
profile acls = yes
[free4all]
path = /srv/samba/pub
public = yes
writable = yes
$ mkdir -m 707 /srv/samba/profiles
$ testparm -v
Maschinenaccount anlegen
$ groupadd machines
$
$ useradd -d /nodir -s /bin/false -g machines IE8WIN7$
$
$ smbpasswd -a -m IE8WIN7
Added user IE8WIN7$.
$
$ pdbedit -L
winuser:1001:
IE8WIN7$:1002:
$
Oder ausführliche Ausgabe aller Objekte: pdbedit -L -v
Root zur Samba-Passwortdatenbank temporär hinzufügen (für Domänenbeitritt con Clients)_
$ smbpasswd -a root
New SMB password:
Retype new SMB password:
Added user root.
$
AUFGAE: Wie heißt die Direktive, mit der ein Samba-Username-Mapping (root = Administrator) eingerichtet werden kann? ANTWORT: ‚username map‘, im Beispiel:
username map = /etc/samba/smbusers
Domänenbeitritt von Windows 7
Via Windows und dem einfachen NetBIOS-Namen dom1….
Troubleshooting
http://www.oreilly.com/openbook/samba/book/ch09_01.html
$ killall smbd
$
$ pgrep -a mbd
1472 /usr/sbin/nmbd -D
$
$ smbd -F -S -i -d 5
INFO: Current debug levels:
all: 5
tdb: 5
printdrivers: 5
...
In der Logausgabe lesen wir, dass das Maschine-Konto noch fehlt (= samba user), wir legen es deshalb an:
$ pgrep -a mbd
1472 /usr/sbin/nmbd -D
$
$
$ useradd -d /nodir -s /bin/false -g machines WIN-2CA02O8XNNS$
$
$
$ smbpasswd -am WIN-2CA02O8XNNS
Added user WIN-2CA02O8XNNS$.
$
$ pdbedit -L
winuser:1001:
root:0:root
IE8WIN7$:1002:
WIN-2CA02O8XNNS$:1003:
$
Ein erfolreicher Mitschnitt der Domänenaufnahme sieht danach so aus:
$ smbd -F -S -i -d 3
Maximum core file size limits now 16777216(soft) -1(hard)
smbd version 4.2.10-Debian started.
Copyright Andrew Tridgell and the Samba Team 1992-2014
uid=0 gid=0 euid=0 egid=0
lp_load_ex: refreshing parameters
Initialising global parameters
Processing section "[global]"
Registered MSG_REQ_POOL_USAGE
Registered MSG_REQ_DMALLOC_MARK and LOG_CHANGED
lp_load_ex: refreshing parameters
Initialising global parameters
Processing section "[global]"
Processing section "[profiles]"
Processing section "[free4all]"
adding IPC service
added interface eth0 ip=10.20.30.5 bcast=10.20.30.255 netmask=255.255.255.0
loaded services
pdb_create_builtin_alias: Could not get a gid out of winbind
WARNING: Failed to create BUILTIN\Administrators group! Can Winbind allocate gids?
pdb_create_builtin_alias: Could not get a gid out of winbind
WARNING: Failed to create BUILTIN\Users group! Can Winbind allocate gids?
waiting for connections
Unable to connect to CUPS server localhost:631 - Ungültiger Dateideskriptor
failed to retrieve printer list: NT_STATUS_UNSUCCESSFUL
Could not find child 1760 -- ignoring
Allowed connection from 10.20.30.98 (10.20.30.98)
GENSEC backend 'gssapi_spnego' registered
GENSEC backend 'gssapi_krb5' registered
GENSEC backend 'gssapi_krb5_sasl' registered
GENSEC backend 'spnego' registered
GENSEC backend 'schannel' registered
GENSEC backend 'naclrpc_as_system' registered
GENSEC backend 'sasl-EXTERNAL' registered
GENSEC backend 'ntlmssp' registered
GENSEC backend 'ntlmssp_resume_ccache' registered
GENSEC backend 'http_basic' registered
GENSEC backend 'http_ntlm' registered
GENSEC backend 'krb5' registered
GENSEC backend 'fake_gssapi_krb5' registered
Got NTLMSSP neg_flags=0xe2088297
Got user=[root] domain=[dom1] workstation=[WIN-2CA02O8XNNS] len1=24 len2=218
lp_load_ex: refreshing parameters
Initialising global parameters
Processing section "[global]"
Processing section "[profiles]"
Processing section "[free4all]"
adding IPC service
check_ntlm_password: Checking password for unmapped user [dom1]\[root]@[WIN-2CA02O8XNNS] with the new password interface
check_ntlm_password: mapped user is: [dom1]\[root]@[WIN-2CA02O8XNNS]
Forcing Primary Group to 'Domain Users' for root
check_ntlm_password: sam authentication for user [root] succeeded
check_ntlm_password: authentication for user [root] -> [root] -> [root] succeeded
NTLMSSP Sign/Seal - Initialising with flags:
Got NTLMSSP neg_flags=0xe2088215
NTLMSSP Sign/Seal - Initialising with flags:
Got NTLMSSP neg_flags=0xe2088215
pdb_create_builtin_alias: Could not get a gid out of winbind
WARNING: Failed to create BUILTIN\Administrators group! Can Winbind allocate gids?
pdb_create_builtin_alias: Could not get a gid out of winbind
WARNING: Failed to create BUILTIN\Users group! Can Winbind allocate gids?
Allowed connection from 10.20.30.98 (10.20.30.98)
Got NTLMSSP neg_flags=0xe20882b7
Got user=[Administrator] domain=[WIN-2CA02O8XNNS] workstation=[WIN-2CA02O8XNNS] len1=24 len2=218
lp_load_ex: refreshing parameters
Initialising global parameters
Processing section "[global]"
Processing section "[profiles]"
Processing section "[free4all]"
adding IPC service
check_ntlm_password: Checking password for unmapped user [WIN-2CA02O8XNNS]\[Administrator]@[WIN-2CA02O8XNNS] with the new password interface
check_ntlm_password: mapped user is: [DOM1]\[Administrator]@[WIN-2CA02O8XNNS]
check_sam_security: Couldn’t find user 'Administrator' in passdb.
check_winbind_security: Not using winbind, requested domain [DOM1] was for this SAM.
check_ntlm_password: Authentication for user [Administrator] -> [Administrator] FAILED with error NT_STATUS_NO_SUCH_USER
_netr_ServerAuthenticate3: no challenge sent to client WIN-2CA02O8XNNS
Got NTLMSSP neg_flags=0xe20882b7
Got user=[Administrator] domain=[WIN-2CA02O8XNNS] workstation=[WIN-2CA02O8XNNS] len1=24 len2=218
lp_load_ex: refreshing parameters
Initialising global parameters
Processing section "[global]"
Processing section "[profiles]"
Processing section "[free4all]"
adding IPC service
check_ntlm_password: Checking password for unmapped user [WIN-2CA02O8XNNS]\[Administrator]@[WIN-2CA02O8XNNS] with the new password interface
check_ntlm_password: mapped user is: [DOM1]\[Administrator]@[WIN-2CA02O8XNNS]
check_sam_security: Couldn’t find user 'Administrator' in passdb.
check_winbind_security: Not using winbind, requested domain [DOM1] was for this SAM.
check_ntlm_password: Authentication for user [Administrator] -> [Administrator] FAILED with error NT_STATUS_NO_SUCH_USER
Forcing Primary Group to 'Domain Users' for WIN-2CA02O8XNNS$
Forcing Primary Group to 'Domain Users' for WIN-2CA02O8XNNS$
Beendet
$
Tests von Windows aus
WIN + R: \\d8squid.dom1.test\profiles
$ Ordner anlegen
$ systemctl restart smbd
$
$
$ pgrep -a mbd
1472 /usr/sbin/nmbd -D
1814 /usr/sbin/smbd -D
1816 /usr/sbin/smbd -D
$
$ smbpasswd tux
New SMB password:
Retype new SMB password:
Failed to find entry for user tux.
$
$
$ pdbedit -L
winuser:1001:
root:0:root
IE8WIN7$:1002:
WIN-2CA02O8XNNS$:1003:
$
$ smbpasswd -a tux
New SMB password:
Retype new SMB password:
Added user tux.
$ ls -l /srv/samba/profiles/
insgesamt 4
drwxr-xr-x 2 tux tux 4096 Nov 18 11:35 Neuer Ordner
$
Einen gleichnamigen Benutzer tux mit selben Passwort wie unter Linux anlegen….
Abmelden als Adminsitrator, anmelden als tux….
Kontrolle unter Linux
$ ### Nach dem Domänenlogin von tux:
$
$ ls -la /srv/samba/profiles/
insgesamt 20
drwx---rwx 4 root root 4096 Nov 18 11:42 .
drwxr-xr-x 4 root root 4096 Nov 18 08:39 ..
drwxr-xr-x 2 tux tux 4096 Nov 18 11:35 Neuer Ordner
drwxrwx--x+ 3 tux tux 4096 Nov 18 11:42 tux
$
$ ls -la /srv/samba/profiles/tux/
insgesamt 20
drwxrwx--x+ 3 tux tux 4096 Nov 18 11:42 .
drwx---rwx 4 root root 4096 Nov 18 11:42 ..
drwxrwx--x+ 2 tux tux 4096 Nov 18 11:42 Vista.V2
$
$ ls -la /srv/samba/profiles/tux/Vista.V2/
insgesamt 16
drwxrwx--x+ 2 tux tux 4096 Nov 18 11:42 .
drwxrwx--x+ 3 tux tux 4096 Nov 18 11:42 ..
$
$
$ ls -la /srv/samba/profiles/tux/Vista.V2/
insgesamt 16
drwxrwx--x+ 2 tux tux 4096 Nov 18 11:42 .
drwxrwx--x+ 3 tux tux 4096 Nov 18 11:42 ..
$
$ ls -F /srv/samba/profiles/tux/Vista.V2/
$ ls -F /srv/samba/profiles/tux/Vista.V2/
AppData/ Desktop/ Downloads/ Links/ NTUSER.DAT* Pictures/ Searches/
Contacts/ Documents/ Favorites/ Music/ ntuser.ini* Saved Games/ Videos/
$
$ grep --color '%a' /etc/samba/smb.conf
logon path = \\%L\profiles\%U\%a
$
$
$ cat /etc/samba/smb.conf
[global]
;map to guest = bad user
workgroup = dom1
server role = classic primary domain controller
; Ich bin PDC:
domain logons = yes
; Einstellungen fürs Browsing
domain master = yes
local master = yes
preferred master = yes
os level = 255
; Übermittlung an Clients, welcher UNC-Pfad verwendet werden soll
logon path = \\%L\profiles\%U\%a
load printers = No
[profiles]
comment = Profile Share
path = /srv/samba/profiles
writable = yes
profile acls = yes
[free4all]
path = /srv/samba/pub
public = yes
writable = yes
Vertiefung PDC
Problembehebung DDNS für Windows-Clients
$ vi /etc/dhcp/dhcpd.conf
#server-identifier d8master;
server-name d8master;
$ systemctl restart isc-dhcp-server.service
Die manuelle Namensauslösung den Windows-2008R2-Clients entfernen:
$ rndc freeze
$
$ vi /var/lib/bind/db.dom1.test
$
$ rndc reload
server reload successful
$
$ rndc thaw
Die aktuelle smb.conf:
[global]
;map to guest = bad user
workgroup = dom1.test
server role = classic primary domain controller
security = User
; Ich bin PDC:
domain logons = yes
; Einstellungen fürs Browsing
domain master = yes
local master = yes
preferred master = yes
os level = 255
; Übermittlung an Clients, welcher UNC-Pfad verwendet werden soll
logon path = \\%L\profiles\%U\%a
load printers = No
[profiles]
comment = Profile Share
path = /srv/samba/profiles
writable = yes
profile acls = yes
[free4all]
path = /srv/samba/pub
public = yes
writable = yes
Neustarten…
$ systemctl restart smbd
$
$
$ systemctl restart nmbd
$
$
$ ps axf | egrep "samba|smbd|nmbd|winbindd"
1341 pts/0 S+ 0:00 \_ grep -E samba|smbd|nmbd|winbindd
1328 ? Ss 0:00 /usr/sbin/smbd -D
1330 ? S 0:00 \_ /usr/sbin/smbd -D
$
Troubleshooting:
$ nmblookup __samba__
10.20.30.5 __samba__
$
Root-Passwort ändern, nicht mehr vorhandene Maschinenaccounts löschen:
$ pdbedit -L
winuser:1001:
root:0:root
tux:1000:tux
IE8WIN7$:1002:
WIN-2CA02O8XNNS$:1003:
$
$
$ smbpasswd root
New SMB password:
Retype new SMB password:
Mismatch - password unchanged.
Unable to get new password.
$
$ smbpasswd root
New SMB password:
Retype new SMB password:
$
$ ls -ltrc /var/lib/samba/private/
insgesamt 844
drwxr-xr-x 3 root root 4096 Nov 17 09:33 smbd.tmp
-rw------- 1 root root 696 Nov 18 08:13 netlogon_creds_cli.tdb
-rw------- 1 root root 430080 Nov 18 12:52 secrets.tdb
-rw------- 1 root root 696 Nov 21 09:41 schannel_store.tdb
-rw------- 1 root root 421888 Nov 21 11:02 passdb.tdb
$
$ testparm -v | grep backend
Load smb config files from /etc/samba/smb.conf
Processing section "[profiles]"
Processing section "[free4all]"
Loaded services file OK.
Server role: ROLE_DOMAIN_PDC
Press enter to see a dump of your service definitions
config backend = file
passdb backend = tdbsam
idmap backend = tdb
share backend = classic
idmap config * : backend = tdb
$
$
$
$ pdbedit -x IE8WIN7$
$
$ pdbedit -L
winuser:1001:
root:0:root
tux:1000:tux
WIN-2CA02O8XNNS$:1003:
$
$ pdbedit -x WIN-2CA02O8XNNS$
$
Automatisierung des Anlegens von Maschinenaccounts:
$ cat /etc/samba/smb.conf
[global]
;map to guest = bad user
workgroup = dom1.test
server role = classic primary domain controller
security = User
; Ich bin PDC:
domain logons = yes
; Einstellungen fürs Browsing
domain master = yes
local master = yes
preferred master = yes
os level = 255
; Übermittlung an Clients, welcher UNC-Pfad verwendet werden soll
logon path = \\%L\profiles\%U\%a
load printers = No
add user script = /usr/sbin/useradd -m '%u'
delete user script = /usr/sbin/userdel -r '%u'
add group script = /usr/sbin/groupadd '%g'
delete group script = /usr/sbin/groupdel '%g'
add user to group script = /usr/sbin/usermod -G '%g' '%u'
add machine script = /usr/sbin/useradd -s /bin/false -d /dev/null '%u'
[profiles]
comment = Profile Share
path = /srv/samba/profiles
writable = yes
profile acls = yes
[free4all]
path = /srv/samba/pub
public = yes
writable = yes
$ systemctl restart smbd
Nun nehmen wir die Windows 2008 - Maschine erfolgreich in die Domäne auf, indem wir lediglich auf dieser Windows-Maschine den Domänenbeitritt wie üblich durchführen. Zur Kontrolle und zur Erinnerung:
$ pdbedit -L
winuser:1001:
root:0:root
tux:1000:tux
W2K8-CL$:1004:W2K8-CL$
$
$
$ ### Wir ersparen uns mit 'add machine script = /usr/sbin/useradd ...' folgende
$ # Zeile:
$
$ # useradd -d /nodir -s /bin/false -g machines WIN-2CA02O8XNNS$
Zum Testen, ob auch Nutzer mittels add user script via Windows angelegt werden können, müssen wir uns mit dem Samba-root-Account an der Domäne anmelden…
Samba-Tools
$ apt-get install smbclient cifs-utils
Der Zugriff auf FTP-Art mittels smbclient:
$ smbclient -NL d8squid
Anonymous login successful
Domain=[DOM1.SITE] OS=[Windows 6.1] Server=[Samba 4.2.10-Debian]
Sharename Type Comment
--------- ---- -------
profiles Disk Profile Share
free4all Disk
IPC$ IPC IPC Service (Samba 4.2.10-Debian)
Anonymous login successful
Domain=[DOM1.SITE] OS=[Windows 6.1] Server=[Samba 4.2.10-Debian]
Server Comment
--------- -------
D8SQUID Samba 4.2.10-Debian
Workgroup Master
--------- -------
DOM1.SITE D8SQUID
WORKGROUP JESSIE
$
$ smbclient \\\\d8squid\\free4all -U%
Domain=[DOM1.SITE] OS=[Windows 6.1] Server=[Samba 4.2.10-Debian]
smb: \> dir
. D 0 Thu Nov 17 11:31:03 2016
.. D 0 Fri Nov 18 08:39:17 2016
write D 0 Thu Nov 17 12:01:01 2016
8516872 blocks of size 1024. 7199432 blocks available
smb: \> quit
$
Transparenter Zugriff via smbfs (veraltet) oder besser cifs (TCP/IP only = NBT):
$ mount -t cifs -o guest \\\\d8squid\\free4all /mnt
mount error(13): Permission denied
Refer to the mount.cifs(8) manual page (e.g. man mount.cifs)
$
Dies gelingt nicht, weil sich Common Internet File System (cifs) anders als smbclient an die Regeln hält und
map to guest = never
respektiert.
Nach dem Setzen von map to guest = bad user gelingt es dann auch anonym.
Oder wir authentifizieren uns richtig beim Mounten:
$ mount -t cifs -o username=tux,password=t //d8squid/profiles /mnt
$
$ ls -l /mnt/
insgesamt 0
drwxrwx--x+ 3 1005 1005 0 Nov 21 11:33 otto
drwxrwx--x+ 3 root root 0 Nov 21 11:24 root
drwxrwx--x+ 3 tux tux 0 Nov 18 11:42 tux
$ mkdir /mnt/tux/Verzeichnis
mkdir: das Verzeichnis „/mnt/tux/Verzeichnis“ kann nicht angelegt werden: Keine Berechtigung
$
ACHTUNG: Die Übergabe von Benutzername und Passwort auf der Kommandozeile ist NICHT empfehlenswert, vor allem, wenn man das in die Datei /etc/fstab aufnehmen will!
Bitte nur so:
$ vi /etc/fstab
//d8squid/profiles /home/tux/smb noauto,user,credentials=/etc/samba/useraccounts 0 0
Dann brauchen wir die Datei:
$ vi /etc/samba/useraccounts
username = tux
password = sup3r-GeHe1m...
$ chmod 600 /etc/samba/useraccounts
Mapping Windows usernames to Linux usernames
ZIEL: Windows-Nutzer können mit dem Namen Administrator arbeiten, es wird aber dann auf root gemappt:
Die [global]-Direktive lautet: username map = </pfad/zur/datei>
Die Datei ist dann so aufgebaut:
root = administrator admin
Samba tools and utilities
# whatis smbstatus
smbstatus (1) - report on current Samba connections
net-Tools
Vergleich mit Windows
ACHTUNG: Diese Werkzeuge sind nicht 100% kompatibel zu Windows!
Unter Windows ein Netzlaufwerk bereitstellen:
net use P: \\d8squid\free4all /user:tux /persistent:yes
c:\> REM Die Serverseite:
C:\> net use
Neue Verbindungen werden gespeichert.
Es sind keine Einträge in der Liste.
C:\> REM Die Serverseite:
C:\>net share
Name Ressource Beschreibung
------------------------------------------------------------
C$ C:\ Standardfreigabe
IPC$ Remote-IPC
ADMIN$ C:\windows Remoteverwaltung
Pointofix C:\Users\apemmann\Documents\Pointofix
Der Befehl wurde erfolgreich ausgeführt.
C:\>
Siehe auch html/samba-pdc.html
Unter Linux
Benutzer anlegen:
$ net user add "winuser-01" "winpw"
Enter root’s password:
Added user 'winuser-01'.
$
$
$ ### Damit ist beides passiert: Es wurde ein Unix- sowie Samba-User angelegt.
$
$ tail -1 /etc/passwd
winuser-01:x:1007:1007::/home/winuser-01:/bin/sh
$
$ pdbedit -L | tail -1
winuser-01:1007:
$
Weitere Experimente:
$ net status sessions
PID Username Group Machine
------------------------------------------------------------------
2669 tux tux 10.20.30.3 (ipv4:10.20.30.3:60923)
$
$ net status shares
Service pid machine Connected at
------------------------------------------------------
profiles 2669 10.20.30.3 Mon Nov 21 16:38:06 2016
IPC$ 2669 10.20.30.3 Mon Nov 21 16:38:06 2016
$
$ net lookup d8master
10.20.30.3
$
$ net lookup d8squid
127.0.1.1
$
Speziell zu Fragen der Berechtigung:
$ net rpc rights list
Enter root’s password:
Could not connect to server 127.0.0.1
The username or password was not correct.
Connection failed: NT_STATUS_LOGON_FAILURE
$
$ net rpc rights list
Enter root’s password:
SeMachineAccountPrivilege Add machines to domain
SeTakeOwnershipPrivilege Take ownership of files or other objects
SeBackupPrivilege Back up files and directories
SeRestorePrivilege Restore files and directories
SeRemoteShutdownPrivilege Force shutdown from a remote system
SePrintOperatorPrivilege Manage printers
SeAddUsersPrivilege Add users and groups to the domain
SeDiskOperatorPrivilege Manage disk shares
SeSecurityPrivilege System security
$
$ net rpc rights list "dom1.test\winuser-01"
Enter root’s password:
$
$ net rpc rights grant "dom1.test\winuser-01" SeDiskOperatorPrivilege
Enter root’s password:
Successfully granted rights.
$
$
$ net rpc rights list "dom1.test\winuser-01"
Enter root’s password:
SeDiskOperatorPrivilege
$
$ net rpc rights grant "dom1.test\winuser-01" SeTakeOwnershipPrivilege
Enter root’s password:
Successfully granted rights.
$
$ net rpc rights list
Enter root’s password:
$ net rpc rights list "dom1.test\winuser-01"
Enter root’s password:
SeTakeOwnershipPrivilege
SeDiskOperatorPrivilege
$
Weitere Links insbesondere zum Kommando *net rpc rights …*:
https://www.samba.org/samba/docs/man/Samba-HOWTO-Collection/NetCommand.html
https://www.samba.org/samba/docs/man/Samba-HOWTO-Collection/rights.html
https://www.windowspro.de/tipp/windows-remote-von-linux-aus-verwalten
http://david.herminghaus.de/de/anleitung/samba-und-ad-domaene-einrichten
Ausblick: Samba4 kann selber als DC agieren:
Exkurs: Kleine Firma mit Standalone Samba-Server
Ziel: Implementieren einer beispielhaften ‚smb.conf‘, die eine kleine Firma ohne Domänenkontroller abbildet.
Im Detail: Eine kleine Firma möchte drei Freigaben mit abgestufter Sicherheit nutzen:
Austausch: Für Jedermann schreibfähig
Dokumente: Nur für authentifizierte Benutzer bei Verwendung einer Schreibliste (otto, kaspar)
Verwaltung: Nur für die vertrauenswürdigen Benutzer der Verwaltung otto und kaspar)
Dabei sollen möglichst robuste Einstellungen für den Zugriff auf das Dateisystem getroffen werden.
Erstellung der Konfigurationsdatei
Die Hauptkonfigurationsdatei für Samba ist neu anzulegen, deshalb die alte erst einmal sichern:
mv /etc/samba/smb.conf /etc/samba/smb.conf.old
Danach einfach eine neue Datei erzeugen:
vi /etc/samba/smb.conf
Vorbereitungen
Benutzer u. Gruppe anlegen:
useradd -m -s /bin/bash otto
useradd -m -s /bin/bash hans
useradd -m -s /bin/bash kaspar
smbpasswd -a otto
smbpasswd -a hans
smbpasswd -a kaspar
groupadd verwaltung
Benutzer zur Gruppe ‚verwaltung‘ zuordnen:
usermod -g verwaltung otto
usermod -g verwaltung hans
usermod -aG verwaltung kaspar
Dateirechte anpassen:
mkdir -p -m 777/srv/samba/free
mkdir -m 775 /srv/samba/doc
mkdir -m 770 /srv/samba/verwaltung
chgrp verwaltung /srv/samba/doc /srv/samba/verwaltung
Einfügen des neuen Inhaltes
Nun werden die folgenden Zeilen eingefügt:
[global]
workgroup = firma1
security = user
map to guest = bad user
[Austausch]
path = /srv/samba/free
guest ok = yes
read only = no
create mask = 666
directory mask = 777
; Alternativ zu den beiden mask-Zeilen:
;force user = nobody
[Dokumente]
path = /srv/samba/doc
read only = yes
write list = otto,kaspar
create mask = 775
directory mask = 775
force group = verwaltung
[Verwaltung]
path = /srv/samba/verwaltung
read only = no
create mask = 770
valid users = otto,kaspar
force group = verwaltung
Das Dokument bitte speichern und den Editor beenden.
Neustarten des Daemons und Testings
Nun muss die Konfiguration neu eingelesen werden, dann kann es ans Testen gehen.
/etc/init.d/samba restart
SMB-Clients:
Linux-Kommandozeile: smbclient,
mount -t cifs //host/Austausch /mnt -o guest
(Voraussetzung: Installiertes Paket „cifs-utils“)Linux-GUI: nautilus, konqueror
Windows-Workstation
209.2 NFS Server Configuration
Ziel: Dateitransfer mit dem Network File System (NFS) durchführen, Bereitstellung eines Netzwerkdateisystemes, das Unix-Clients bequem mounten können.
(Freie Windows-Clients sind rar, eine Möglichkeit ist unter http://nekodrive.software.informer.com/ zu finden.)
Ein paar wichtige Eckpunkte:
NFS stammt von der 1982 gegründeten Firma SUN Microsystems, 1984 gelang ihr mit diesem Protokoll der Durchbruch in der Unix-Welt
Es wird als verteiltes Dateisystem bezeichnet; wenn ein beteiligter Server wegbricht, können allerdings automatische Failover-Aktionen nicht wie bei Ceph oder DFS stattfinden
Client/Server-Anwendung: der Server exportiert einen Teil seines Dateisystemes, der Client importiert es durch einen klassischen Mountvorgang
Transparente Arbeitsweise: auf die entfernte Ressource wird über einen lokalen Ordner zugegriffen (–> systemweit einheitlicher Namensraum)
Bis Version 3 benutzt NFS das verbindungslose UDP, die aktuelle Version 4 verwendet TCP und behebt damit kleinere Probleme, ist aber dadurch nicht mehr ganz so schnell
Bis Version 3 authentifizieren sich Benutzer via User-ID-Mapping, ab Version 4 ist außerdem Authentifizierung mittels Kerberos möglich
NFS benötigt Remote Procedure Calls (RPC), die sich auf OSI-Schicht 5 um das Zuordnen von lokalen und entfernten UDP/TCP-Ports kümmern und ein initiales Filehandle einrichten
RPC wird bis NFSv3 mit dem Dienst ‚portmap‘ realisiert (UDP/2049), ab NFSv4 über ‚rpcbind‘ (TCP/2049)
Die NFSv3-Daemons rpc.mountd, rpc.lockd und rpc.statd werden von NFSv4 nicht mehr verwendet (feste Integration im Kernel), dafür aber gibt es jetzt ein Listening am TCP-Port 2049
Rollen:
Server = der Exporteur (Datei: ‚/etc/exports‘, Tool:
exportfs
)Client = der Importeur (Kommando
mount -t nfs Server:Pfad Mountpunkt
)
Installation unter Debian
Die Installation ist schnell durchgeführt. Falls nicht schon vorhanden, wird der zugrundeliegende Portmapper (Paket ‚rpcbind‘) automatisch mit installiert, ebenso wie der NFS-Client (Paket ‚nfs-common‘):
apt-get install nfs-kernel-server
Der NFS-Daemon startet sich aber nicht automatisch, wie sonst unter Debian üblich, es sei denn, es existiert bereits in der Konfigurationsdatei eine gültige Freigabe.
Als weitere Voraussetzung muss der Kernel NFS unterstützen; das Dateisystem wird dann in der Datei /proc/filesystems
mit aufgelistet. Bei selbst kompilierten Kerneln fehlt diese Option oft!
NFSv3-kompatible Freigaben
Die Konfigurationsdatei bearbeitet man mit
vi /etc/exports
Für NFSv3 reicht im einfachsten Fall nur eine Zeile, die das Verzeichnis ‚/srv/pub‘ für alle Rechner ‚*‘ schreibfähig (rw) freigibt, wobei Änderungen sofort auf die Festplatte geschrieben werden (sync), außerdem sollen Dateirechte nicht rekursiv geprüft werden (no_subtree_check), was sich nur bei reinen Heimatverzeichnissen lohnt:
/srv/pub *(rw,sync,no_subtree_check)
Nach dem Anlegen des Verzeichnisses mit
mkdir -m 777 /srv/pub
muss der NFS-Dienst gestartet werden:
/etc/init.d/nfs-kernel-server start
Eine Freigabe mit NFSv3 clientseitig einbinden
Ob der Server erreichbar ist und was er exportiert, kann auf dem Client via Netzwerk mittels
showmount -e server
überprüft werden. Das Mounten in den normalerweise leeren Ordner ‚/mnt‘ gelingt dann mit
mount -o vers=3 server:/srv/pub /mnt
Für NFSv3 ist hierbei die Option ‚vers=3‘ ausschlaggebend, was bedeutet, dass als Transportprotokoll das schnellere UDP verwendet wird.
Zum automatischen Mounten beim Bootvorgang editieren wir die Datei ‚/etc/fstab‘:
vi /etc/fstab
Als Mountpunkt legt man z.B. vorher einen Ordner ‚/media/pub‘ an und schreibt:
server:/srv/pub /media/pub nfs soft,bg 0 0
Die Option ‚soft‘ verhindert ein Hängenbleiben des Clients beim Bootvorgang, falls der Server nicht erreichbar ist; mit ‚bg‘ versucht er es im Hintergrund weiter. Nach dem Abspeichern der Änderungen kann ein Reboot mittels
mount -a
simuliert werden.
Freigaben mit NFSv4
Grundsätzlich kann die bisherige Konfiguration mit der einen Zeile in der ‚/etc/exports‘ beibehalten werden. Ein moderner NFS-Client benutzt dann automatisch NFSv4, wenn er beim Mounten die Versions-Option ‚vers=3‘ weglässt. Damit kann man allerdings nicht alle Features des neuen Protokolls ausnutzen, wie z.B. das automatische Einhängen aller Freigaben unter einem bestimmten NFS-Wurzelverzeichnis.
Die Konfigurationsdatei ist zuerst einmal wieder die alte:
vi /etc/exports
Idealerweise deklariert man für NFSv4 zuerst in einer extra Zeile einen Ordner als NFS-Wurzelpunkt; das wichtigste Kennzeichen ist ‚fsid=0‘. Die zweite Zeile definiert dann die eigentliche Freigabe, auf die der Client später in relativer Schreibweise beim Mounten zugreift (im Beispiel einfach nur mit ‚pub‘, ohne führenden Slash):
/srv/nfs4 *(rw,sync,fsid=0,crossmnt,no_subtree_check)
/srv/nfs4/pub *(rw,sync,no_subtree_check)
Nach dem Anlegen des Verzeichnisses mit
mkdir -p -m 777 /srv/nfs4/pub
muss der NFS-Dienst neu gestartet werden:
/etc/init.d/nfs-kernel-server restart
Eine Freigabe mit NFSv4 clientseitig einbinden
Ob der Server erreichbar ist und was er exportiert, kann auf dem Client wiederum mittels
showmount -e server
überprüft werden. Das Mounten in den Ordner ‚/mnt‘ gelingt dann in kürzerer Schreibweise mit
mount server:pub /mnt
Für NFSv4 ist hierbei zu beachten, dass lediglich der betreffende Freigabeordner als RELATIVER PFAD (hier: ‚pub‘) zur NFS-Wurzel (hier: ‚/srv/nfs4‘) direkt nach dem Doppelpunkt angegeben wird!
Zum automatischen Mounten beim Bootvorgang editieren wir wieder die Datei ‚fstab‘:
vi /etc/fstab
Als Mountpunkt verwenden wir nach einem ‚umount /media/pub‘ wieder den selben Ordner, die betreffende Zeile sieht jetzt so aus:
server:pub /media/pub nfs4 soft,bg 0 0
Nach dem Abspeichern der Änderungen kann ein Reboot mittels
mount -a
simuliert werden.
Benutzung mit dem Backend ‚exportfs‘
Das Verzeichnis soll lesend und schreiben freigegeben werden:
$ exportfs -o rw *:/tmp
$ ps aux | grep -E 'nfsd|mountd'
root 3969 0.0 0.6 12748 2136 pts/1 S+ 20:21 0:00 grep -E nfsd|mountd
$
$ rpc.nfsd
$ rpc.mountd
$
$ ps aux | grep -E 'nfsd|mountd'
root 3973 0.0 0.0 0 0 ? S< 20:21 0:00 [nfsd4]
root 3974 0.0 0.0 0 0 ? S< 20:21 0:00 [nfsd4_callbacks]
root 3978 0.0 0.0 0 0 ? S 20:21 0:00 [nfsd]
root 3979 0.0 0.0 0 0 ? S 20:21 0:00 [nfsd]
root 3980 0.0 0.0 0 0 ? S 20:21 0:00 [nfsd]
root 3981 0.0 0.0 0 0 ? S 20:21 0:00 [nfsd]
root 3982 0.0 0.0 0 0 ? S 20:21 0:00 [nfsd]
root 3983 0.0 0.0 0 0 ? S 20:21 0:00 [nfsd]
root 3984 0.0 0.0 0 0 ? S 20:21 0:00 [nfsd]
root 3985 0.0 0.0 0 0 ? S 20:21 0:00 [nfsd]
root 3987 0.0 1.5 40956 5416 ? Ss 20:21 0:00 rpc.mountd
root 3989 0.0 0.6 12748 2132 pts/1 S+ 20:21 0:00 grep -E nfsd|mountd
$
$ rpcinfo -p | grep 2049
100003 2 tcp 2049 nfs
100003 3 tcp 2049 nfs
100003 4 tcp 2049 nfs
100227 2 tcp 2049
100227 3 tcp 2049
100003 2 udp 2049 nfs
100003 3 udp 2049 nfs
100003 4 udp 2049 nfs
100227 2 udp 2049
100227 3 udp 2049
$
$ showmount -e localhost
Export list for localhost:
/tmp *
Will man alle Exporte mit einem Mal entfernen, schreibt man einfach:
$ exportfs -ua
Clientseitge Einbindung
Mit der Option ‚vers=3‘ nutzen wir explizit die zwar alte, aber dank UDP schnellere Version 3:
$ showmount -e d8squid
Export list for d8squid:
/tmp *
$
$ mount -o vers=3 d8squid:/tmp /tmp/mnt/
$
$ echo 123 > /tmp/mnt/datei-von-root
$
$ su - tux
$ echo 123 > /tmp/mnt/datei-von-tux
ACHTUNG: Der Benutzer root wird immer auf nobody gequetscht (Default Option: root_squash):
$ ls -ltrc /tmp/ | tail -5
insgesamt 2
-rw-r--r-- 1 nobody nogroup 4 Nov 21 20:27 datei-von-root
-rw-r--r-- 1 tux tux 4 Nov 21 20:28 datei-von-tux
$
Fehlersuche
Fehler können sich natürlich an vielen Stellen ergeben, z.B. durch nicht vorhandene Verzeichnisse oder nicht laufende bzw. nicht neu gestartete Daemons. Zu Diagnosezwecken kommt neben dem bereits bekannten Kommando ‚showmount‘ das speziell für RPC geeignete Kommando ‚rpcinfo‘ in Frage:
rpcinfp -p client
rpcinfp -p server
Damit lässt sich kontrollieren, ob die Remote Procedure Calls auf dem Client (ca. 8 Prozesse sichtbar, vor allem ‚portmapper‘) sowie auf dem Server (ca. 30 Prozesse, neben ‚portmapper‘ auch ‚nfs‘ und ‚mountd‘) zur Verfügung stehen.
Probleme treten oft durch Firewalls auf, insbesondere mit NFSv3.
Dank der NFS-Wurzel-Option ‚fsid=0‘ wird das zu importierende Dateisystem nicht als lokales Blockgerät mit Major- und Minor-Nummer bzw. UUID betrachtet, sondern einfach mit der Dateisystem-ID 0 ausgestattet. Dadurch werden nervende „stale NFS mounts“ vermieden, deren Ursache in nicht mehr erreichbaren NFS-Servern liegen.
Topic 210: Network Client Management
210.1 DHCP configuration
DHCP-Server einrichten
Nach der Installation mittels apt-get install isc-dhcp-server
legt man am besten gleich erst einmal das Listening-Interface fest:
$ vi /etc/default/isc-dhcp-server
Wir müssen hier die Schnittstelle angeben, an welcher der Daemon lauschen soll, z.B.:
INTERFACES="eth1"
Dann ist die Hauptkonfigurationsdatei dran. Nach dem Aktivieren und Anpassen des Abschnitts, der mit „very basic subnet declaration“ überschrieben ist, sieht die Datei ‚dhcpd.conf‘ folgendermaßen aus:
$ grep -v '^#' /etc/dhcp/dhcpd.conf
Der Inhalt nach der Bearbeitung:
option domain-name "dom1.test";
option domain-name-servers 10.20.30.3, 10.20.30.4;
default-lease-time 600;
max-lease-time 7200;
ddns-update-style none;
subnet 10.20.30.0 netmask 255.255.255.0 {
range 10.20.30.50 10.20.30.100;
option routers 10.20.30.3;
}
Weitere Möglichkeiten für Bereichsoptionen sind in diesem Codebeispiel zu sehen:
# A slightly different configuration for an internal subnet.
subnet 10.5.5.0 netmask 255.255.255.224 {
range 10.5.5.26 10.5.5.30;
option domain-name-servers ns1.internal.example.org;
option domain-name "internal.example.org";
option routers 10.5.5.1;
option broadcast-address 10.5.5.31;
default-lease-time 600;
max-lease-time 7200;
}
Ein beliebtes LPI-Thema ist in diesem Zusammenhang das Zuweisen fester IP-Adressen anhand der Client-MAC-Adresse:
host mycentos6 { hardware ethernet 08:00:07:26:c0:a5;
fixed-address 10.20.30.88;
}
Danach bitte nicht vergessen, die Konfiguration neu einzulesen:
$ systemctl restart isc-dhcp-server
Zum Testen ist Live-Monitoring unerlässlich, z.B. mit tail -f /var/log/syslog
.
210.2 PAM authentication
Das System der Pluggable Authentication Modules wurde ursprünglich von Sun entwickelt, um auf neue Authentifizierungsmöglichkeiten wie SmartCards flexibler reagieren zu können.
PAM ist nicht zwingend erforderlich, so kommen Tiny-Core und Alpine Linux erst einmal ohne daher: sie verwenden die klassischen C-Bibliotheksroutinen getpwuid, getpwnam und getpwent und parsen die Datei /etc/passwd. Man kann es nachinstallieren, wobei dann nur spezielle, vorkompilierte Module zur Verfügung stehen.
Neben der Flexibilität gibt es einen weiteren Vorteil, der mit PAM als Abstraktionsschicht zwischen User und Anwendung zu tun hat: Programmierer und Distributionsdesigner müssen sich nicht mit den Details der klassischen Shadow-Suite-Authentifizierung herumplagen, sie brauchen ihre Anwendungen nur gegen die gewünschten PAM-Libs auszurichten.
Die Architektur geht gut aus der um eigene Kommentare ergänzten Grafik von medium.com hervor:
Das PAM-System ist nicht zwingend erforderlich, so kommen Tiny-Core und Alpine Linux erst einmal ohne daher. Man kann es nachinstallieren, wobei dann nur wenige spezielle, vorkompilierte Module zur Verfügung stehen.
Die PAM-Libraries liegen normalerweise unter /lib/security/
, bei Debian 8 und höher allerdings etwas tiefer
unter ‚/lib/x86_64-linux-gnu/security/‘.
Die Konfigurationsdateien liegen normalerweise im Verzeichnis /etc/pam.d
, als alternative Verzeichnisse kommen je nach Distribution aber auch /usr/lib/pam.d
sowie /usr/etc/pam.d
in Frage. Falls davon keines existiert, wird die Datei /etc/pam.conf
abgearbeitet. In man pam
lesen wir dazu:
This dynamic configuration is set by the contents of the single Linux-PAM configuration file /etc/pam.conf. Alternatively, the configuration can be set by individual configuration files located in the /etc/pam.d/ directory. The presence of this directory will cause Linux-PAM to ignore /etc/pam.conf.
Die Datei /etc/pam.conf
liegt im menschlesbaren Tabellenformat vor, hier ein Beispiel für den Service „sshd“ (Quelle: Linux from Scratch):
# Service Type Control Module-path Module-arguments
sshd auth requisite pam_securetty.so
sshd auth required pam_unix.so
sshd account required pam_unix.so
sshd session required pam_unix.so
sshd password required pam_unix.so shadow md5
Beim „Service“ handelt es sich um die Applikation, die reglementiert werden soll, hier den SSH-Daemon. „Type“ und „Control“ besprechen wir im Folgenden.
Modul-Typen und -steuerung
Der Modultyp (type) gibt die Art der Nutzung des Modules an, was in Verwaltungsgruppen organisiert ist: ob man es dafür einsetzen möchte, den Loginprozess zu überwachen oder aber den Prozess beim Ändern von Passwörtern zu gestalten.
Nehmen wir z.B. das wichtigste Modul pam_unix.so her; es kann verschiedenen Zwecken dienen: dem Prüfen der account-Gültigkeit, der authentication selbst, der Verwaltung der session und schließlich dem password-Ändern.
Wir unterscheiden also diese 4 Modultypen:
account - Zugriffsberechtigung prüfen (z.B. anhand der Tageszeit und der Anzahl eingeloggter Benutzer)
auth - Zugriff gewähren (stellt u.a. Loginprompt zur Verfügung)
session - Sitzungsverwaltung (z.B. Logging: bei Debian: /var/log/auth.log, Verzeichnisse mounten)
password - Kennwortänderung („is required for updating the authentication token associated with the user“)
Die Modulsteuerung (control) gibt das Verhalten der PAM-API an, falls das Modul seine Authentifizierungsaufgabe nicht erfolgreich ausführen kann.
Bei dieser Fehlersteuerung unterscheiden wir (von restriktiv zu optional):
requisite - Der erste aufgetretene Fehler führt zum sofortigen Abbruch der Stapelverarbeitung.
Beispiel Debian:
auth requisite pam_deny.so
required - Fehler werden registriert, zum Abbruch kommt es erst nach dem Durchlaufen anderer Module selben Services und Typs.
Beispiel Alpine:
account required pam_unix.so
sufficient - Bei Erfolg wird die Stapelverarbeitung sofort beendet, bei Misserfolg geht die Verarbeitung weiter.
Beispiel Debian für service ‚su‘:
auth sufficient pam_wheel.so trust
optional - Erfolg oder Misserfolg spielen nur eine Rolle, wenn es sich um das einzige Modul im Stapel handelt.
Beispiel Debian für service ‚su‘:
session optional pam_mail.so nopen
Dies sollte nur einen kleinen Überblick bieten, für die LPI-Lernziele studieren Sie bitte die englische Originalformulierung in man pam.conf
. Der erweiterte, komplexe Modus mit eckigen Klammern ist für LPI nicht relevant.
Experimente mit PAM
ACHTUNG: Änderungen sind sofort wirksam, auch root kann sich u.U. nicht mehr einloggen! Daher folgendes beachten:
Backup von /etc/pam.d/ anfertigen
root-Login auf einer zweiten Konsole offen halten
Danach benennen wir unter Debian 12 mittels
mv /etc/pam.d /etc/pam.d_orig
mv /usr/lib/pam.d /usr/lib/pam.d_orig
die beiden pam-Directories um, damit nun die Datei /etc/pam.conf
abgearbeitet wird, in der wir alles zentral konfigurieren können.
Und dies sind die Zeilen, die wir für eine minimale pam.conf brauchen (sie beinhaltet bei Debian lediglich ein paar auskommentierte Infos):
other account requisite pam_unix.so
other auth requisite pam_unix.so
other session requisite pam_unix.so
#other password requisite pam_unix.so minlen=1 shadow
Die vierte Zeile bleibt bei den ersten Login-Versuchen noch auskommentiert. Bitte testen, ob ein User sein Passwort ändern kann. Es dürfte nicht funktionieren (siehe dabei Debians /var/log/auth.log
!). Dann diese Zeile einkommentieren, worauf Passwortänderungen wieder möglich sind.
Mit dieser minimalen Datei können wir nun weitere Experimente anstellen. Am Schluss aber bitte nicht vergessen, mittels mv /etc/pam.d_orig /etc/pam.d
sowie mv /usr/lib/pam.d_orig /usr/lib/pam.d
den Ausgangszustand wiederherzustellen.
Passwortstärke mit PAM verbessern
Ziel ist die Installation eines proaktiven Passwortcheckers.
Mittels apt-get install libpam-pwquality
werden unter Debian 12 die Pakete libcrack2
und cracklib-runtime
mit installiert, die ein einfaches Wörterbuch sowie die dazugehörigen Tools beinhalten.
Damit wurde auch schon das neue Modul in die PAM-Konfiguration eingebunden:
[root@d12:~]# grep qual /etc/pam.d/*
/etc/pam.d/common-password:password requisite pam_pwquality.so retry=3
[root@d12:~]#
Und schon gehts an die Benutzung. Zuerst einmal prüfen wir gewisse Zeichenketten, ob sie als Passwort taugen würden:
[root@d12:~]# cracklib-check
123, qwer
123, qwer: OK
P@ssw0rd
P@ssw0rd: OK
^C
[root@d12:~]# # >>> beide Passwörter werden akzeptiert!!!
Nun wollen wir diese beiden Zeichenketten blockieren, die zu editierende Wörterbuchdatei cracklib-small
stammt aus dem Paket cracklib-runtime
:
[root@d12:~]# cat >> /usr/share/dict/cracklib-small <<EOF
> 123, qwer
> P@ssw0rd
> EOF
[root@d12:~]#
[root@d12:~]# update-cracklib
skipping line: 1
446108 446107
[root@d12:~]#
[root@d12:~]# cracklib-check
123, qwer
123, qwer: Es basiert auf einem Wörterbucheintrag
^C
[root@d12:~]# # >>> Prima Sache, dies wird nun nicht mehr akzeptiert.
PAM für faillock konfigurieren
Nach https://www.server-world.info/en/note?os=Debian_12&p=pam&f=2
Es sollen Login-Fehler bei gleichzeitiger Sperrung des Accounts aufgezeichnet werden (Distribution: Debian 12). Dazu sind drei Konfigurationsdateien anzupassen.
Wir editieren die erste Datei mittels vi +17 /etc/pam.d/common-auth
und fügen drei Zeilen hinzu (wir stehen dabei schon auf Zeile 17, was die erste aktivierte Zeile ist; siehe dazu die mit „AXPE“ beginnenden Kommentare):
#
# /etc/pam.d/common-auth - authentication settings common to all services
#
# This file is included from other service-specific PAM config files,
# and should contain a list of the authentication modules that define
# the central authentication scheme for use on the system
# (e.g., /etc/shadow, LDAP, Kerberos, etc.). The default is to use the
# traditional Unix authentication mechanisms.
#
# As of pam 1.0.1-6, this file is managed by pam-auth-update by default.
# To take advantage of this, it is recommended that you configure any
# local modules either before or after the default block, and use
# pam-auth-update to manage selection of other modules. See
# pam-auth-update(8) for details.
# AXPE: eine Zeile oberhalb der ersten aktiven Zeile einfügen:
auth required pam_faillock.so preauth
# AXPE: dies ist die ursprünglich erste aktive Zeile mit dazugehörigem Kommentar:
# here are the per-package modules (the "Primary" block)
auth [success=1 default=ignore] pam_unix.so nullok
# AXPE: und nun diese zwei neue Zeilen unterhalb der ursprünglich ersten aktiven Zeile einfügen:
auth [default=die] pam_faillock.so authfail
auth sufficient pam_faillock.so authsucc
# here's the fallback if no module succeeds
auth requisite pam_deny.so
# prime the stack with a positive return value if there isn't one already;
# this avoids us returning an error just because nothing sets a success code
# since the modules above will each just jump around
auth required pam_permit.so
# and here are more per-package modules (the "Additional" block)
# end of pam-auth-update config
Die zweite Datei bearbeiten wir mittels vi +17 /etc/pam.d/common-account
, wie landen wieder auf Zeile 17; es ist hier aber nur eine Zeile hinzuzufügen und zwar als erste aktive Zeile vor allen anderen (sie ist wieder mit „AXPE“ kommentiert):
#
# /etc/pam.d/common-account - authorization settings common to all services
#
# This file is included from other service-specific PAM config files,
# and should contain a list of the authorization modules that define
# the central access policy for use on the system. The default is to
# only deny service to users whose accounts are expired in /etc/shadow.
#
# As of pam 1.0.1-6, this file is managed by pam-auth-update by default.
# To take advantage of this, it is recommended that you configure any
# local modules either before or after the default block, and use
# pam-auth-update to manage selection of other modules. See
# pam-auth-update(8) for details.
#
# AXPE: diese Zeile einfach als erste ganz obenan einfügen:
account required pam_faillock.so
# AXPE: Das ist ursprünglich Zeile 17:
# here are the per-package modules (the "Primary" block)
account [success=1 new_authtok_reqd=done default=ignore] pam_unix.so
# here's the fallback if no module succeeds
account requisite pam_deny.so
# prime the stack with a positive return value if there isn't one already;
# this avoids us returning an error just because nothing sets a success code
# since the modules above will each just jump around
account required pam_permit.so
# and here are more per-package modules (the "Additional" block)
# end of pam-auth-update config
Als dritte Datei bearbeiten wir noch die /etc/security/faillock.conf
und passen drei Einstellungen an:
silent
– keine Infos über Fehlversuche ausgebendeny = 1
– nur zwei Fehlversuche erlaubtunlock_time = 0
– zeitgesteuertes Freischalten ist deaktiviert
Jetzt können wir den Login via lokaler Anmeldung oder ssh gründlich austesten, dabei ist es ratsam, einen Blick auf
das Syslog zu werfen, z.B.: journalctl -f
Gesprerrte Accounts sehen wir dann mittels faillock
:
[root@d12:~]# faillock
root:
When Type Source Valid
tux:
When Type Source Valid
2024-06-26 12:12:33 RHOST 192.168.2.104 V
[root@d12:~]#
Wieder freischalten können wir einen gesperrten Account mit der Option --reset
:
[root@d12:~]# faillock --user tux --reset
[root@d12:~]#
[root@d12:~]# faillock
root:
When Type Source Valid
tux:
When Type Source Valid
[root@d12:~]#
[root@d12:~]#
ZUSAMMENFASSUNG pam_faillock:
kein zusätzliches Software-Paket erforderlich
es müssen 3 Configs angepasst werden
Siehe dazu diese Ausschnitte:
[root@d12:~]# alias gg
alias gg='grep -Ev '\''\s*#|^$'\'''
[root@d12:~]#
[root@d12:~]# gg /etc/pam.d/common-auth
auth required pam_faillock.so preauth # <<< Oben drüber gesetzt
auth [success=1 default=ignore] pam_unix.so nullok # Originalzeile
auth [default=die] pam_faillock.so authfail # <<< unten drunter gesetzt
auth sufficient pam_faillock.so authsucc # <<< unten drunter gesetzt
auth requisite pam_deny.so
auth required pam_permit.so
[root@d12:~]#
[root@d12:~]# gg /etc/pam.d/common-account
account required pam_faillock.so # <<< Oben drüber gesetzt
account [success=1 new_authtok_reqd=done default=ignore] pam_unix.so # Originalzeile
account requisite pam_deny.so
account required pam_permit.so
[root@d12:~]#
[root@d12:~]# gg /etc/security/faillock.conf
silent
deny = 2
unlock_time = 0
[root@d12:~]#
Tests durchführen, Kommandos
faillock
undfaillock --user tux --reset
PAM-Konfiguration bei bei Suse 11.0 - ohne Passwort einloggen
(Dies funktioniert im wesentlichen auch bei aktuellen SuSE-Releases)
Es reicht leider nicht mehr aus, die Dateien /etc/passwd und /etc/shadow zu bearbeiten (jeweils die zweite Spalte leeren), zusätzlich muss die PAM-Konfiguration (Pluggable Authentication Modules) angepasst werden:
RUN_AS_ROOT:~# pam-config -a --nullok
Siehe auch: http://vavai.net/tag/opensuse-kiwi-remastering-livecd/
Hinweise, Hyperlinks
Allgemein
http://www.linuxjournal.com/magazine/pammdashsecuring-linux-boxes-everywhere (Figure 1: PAM modules)
Die logische Reihenfolge der Control Flags von restrikt zu offenherzig lautet: requisite → required → sufficient → optional
Beispiele
Weiteres
https://www.tu-chemnitz.de/urz/archiv/kursunterlagen/pamkonf.html
https://docs.oracle.com/cd/E26502_01/html/E29015/pam-32.html
http://www.qucosa.de/fileadmin/data/qucosa/documents/4072/config.html
https://chemnitzer.linux-tage.de/2008/vortraege/shortpaper/bramer.pdf
https://wiki.ubuntuusers.de/Authentifizierung_mit_USB-Stick/?action=backlinks
210.3 LDAP client usage
LDAP unter Linux
Siehe dazu:
Die Zielstellung ist etwas anders als z.B. bei Artikeldatenbanken, die Häufigkeit der Schreibzyklen sind bei LDAP nicht entscheidend, hier geht es mehr um Eigenschaften, die die Realität besonders auch im Zusammenhang mit Workflows abbilden können.
Das zugrundeliegende Protokoll ist X.500, es wird allerdings nur in einer verkürzten Form angewendet.
Hauptgedanke ist, dass weltweit Namesräume für Objekte geschaffen werden (siehe IANA.org).
Grobaufteilung:
Container-Objekte (Dateisystem: Verzeichnisse)
Blatt-Objekte (Dateisystem: Dateien)
Einrichtung unter Debian 8
Auf Maschine: smb1.dom1.test
Wir installieren die Client-Werkzeuge und den Server mit apt-get install ldap-utils slapd
Erster Test: Was läuft?
$ slapd -V
@(#) $OpenLDAP: slapd (Jan 16 2016 23:00:08) $
root@chimera:/tmp/buildd/openldap-2.4.40+dfsg/debian/build/servers/slapd
ACHTUNG: Hier wird die Konfiguration in der Datenbank selber gespeichert! (Option -F):
Das bedeutet, es liegt die neue Online-Konfiguration vor.
$ ps aux | grep slapd
openldap 2697 0.0 1.7 1221240 5084 ? Ssl 05:17 0:00 /usr/sbin/slapd -h ldap:/// ldapi:/// -g openldap -u openldap -F /etc/ldap/slapd.d
root 2757 0.0 0.7 12748 2100 pts/0 S+ 05:24 0:00 grep slapd
$
Ein erster Fehler beim clientseitigen Abfragen der Datenbank:
$ ldapsearch -x
# extended LDIF
#
# LDAPv3
# base <> (default) with scope subtree
# filter: (objectclass=*)
# requesting: ALL
#
# search result
search: 2
result: 32 No such object
# numResponses: 1
$ echo $?
32
$
$ ldapsearch -x '*'
# extended LDIF
#
# LDAPv3
# base <> (default) with scope subtree
# filter: (objectclass=*)
# requesting: *
#
# search result
search: 2
result: 32 No such object
# numResponses: 1
$
Die Ursache liegt im Fehlen der BASE-Angabe in der clientseitigen Konfigurationsdatei:
$ grep -v ^# /etc/ldap/ldap.conf
TLS_CACERT /etc/ssl/certs/ca-certificates.crt
$
Ein erfolgreicher, anonymer Zugriff mitsamt DC-Angaben (Domain Component):
$ ldapsearch -x -b dc=dom1,dc=site
# extended LDIF
#
# LDAPv3
# base <dc=dom1,dc=site> with scope subtree
# filter: (objectclass=*)
# requesting: ALL
#
# dom1.test
dn: dc=dom1,dc=site
objectClass: top
objectClass: dcObject
objectClass: organization
o: dom1.test
dc: dom1
# admin, dom1.test
dn: cn=admin,dc=dom1,dc=site
objectClass: simpleSecurityObject
objectClass: organizationalRole
cn: admin
description: LDAP administrator
# search result
search: 2
result: 0 Success
# numResponses: 3
# numEntries: 2
$
Eine authentifizierte Abfrage:
$ ldapsearch -x -b dc=dom1,dc=site -W -D cn=admin,dc=dom1,dc=site
Enter LDAP Password:
# extended LDIF
#
# LDAPv3
# base <dc=dom1,dc=site> with scope subtree
# filter: (objectclass=*)
# requesting: ALL
#
# dom1.test
dn: dc=dom1,dc=site
objectClass: top
objectClass: dcObject
objectClass: organization
o: dom1.test
dc: dom1
# admin, dom1.test
dn: cn=admin,dc=dom1,dc=site
objectClass: simpleSecurityObject
objectClass: organizationalRole
cn: admin
description: LDAP administrator
userPassword:: e1NTSEF9aFRFYURITHhtZVhMNUJiU3JBbVdWQ3IrU0RFUE85SHM=
# search result
search: 2
result: 0 Success
# numResponses: 3
# numEntries: 2
$
Dazu drei Aufgaben:
Datei /etc/ldap/ldap.conf bearbeiten, anpassen von
BASE dc=example,dc=com
Backup der Datenbank anlegen
mkdir ldap.bk ; cp -a /var/lib/ldap/ ldap.bk/
Asisstenten starten:
dpkg-reconfigure slapd
ACHTUNG das geht nur 1 mal, das Verzeichnis kann aber einfach verschoben werden.
mv /var/backups/unknown-2.4.40+dfsg-1+deb8u2.ldapdb /root
210.4 Configuring an OpenLDAP server
Nutzer via LDIF-Dateien hinzufügen
Zuerst einmal: Habe ich überhaupt die passenden Schemadateien für die gewünschten Objekteigenschaften bereits eingebunden?
$ grep organizationalUnit /etc/ldap/schema/*.schema
/etc/ldap/schema/core.schema:attributetype ( 2.5.4.11 NAME ( 'ou' 'organizationalUnitName' )
/etc/ldap/schema/core.schema:objectclass ( 2.5.6.5 NAME 'organizationalUnit'
/etc/ldap/schema/cosine.schema: organizationName $ organizationalUnitName $ host )
/etc/ldap/schema/cosine.schema: organizationName $ organizationalUnitName $
/etc/ldap/schema/cosine.schema: localityName $ organizationName $ organizationalUnitName )
/etc/ldap/schema/cosine.schema: SUP ( organization $ organizationalUnit ) STRUCTURAL
/etc/ldap/schema/openldap.schema: SUP organizationalUnit
$
$
$ grep posixAccount /etc/ldap/schema/*.schema
/etc/ldap/schema/nis.schema:objectclass ( 1.3.6.1.1.1.2.0 NAME 'posixAccount'
$
Das Hinzufügen des Benutzers „Hugo Schulz“ gelingt problemlos:
$ cat hugo.ldif
dn: cn=Hugo Schulz,dc=dom1,dc=site
objectclass: person
cn: Hugo Schulz
sn: Schulz
$
$ file hugo.ldif
hugo.ldif: ASCII text
$
$ ldapadd -x -w admin -D cn=admin,dc=dom1,dc=site -f hugo.ldif
adding new entry "cn=Hugo Schulz,dc=dom1,dc=site"
$ echo $?
0
$
$ ldapsearch -x
# extended LDIF
#
# LDAPv3
# base <dc=dom1,dc=site> (default) with scope subtree
# filter: (objectclass=*)
# requesting: ALL
#
# dom1.test
dn: dc=dom1,dc=site
objectClass: top
objectClass: dcObject
objectClass: organization
o: dom1.test
dc: dom1
# admin, dom1.test
dn: cn=admin,dc=dom1,dc=site
objectClass: simpleSecurityObject
objectClass: organizationalRole
cn: admin
description: LDAP administrator
# Hugo Schulz, dom1.test
dn: cn=Hugo Schulz,dc=dom1,dc=site
objectClass: person
cn: Hugo Schulz
sn:: U2NodWx6IA==
# search result
search: 2
result: 0 Success
# numResponses: 4
# numEntries: 3
$
Eine initiale Struktur für Samba und Thunderbird
Das folgende Beispiel legt die Grundlagen für Strukturen, wie sie für eine Samba PDC Domäne sowie eine Kontaktdatenbank für Thunderbird (Mail-Client) erforderlich sind.
Die initiale Struktur fügen wir mit Hilfe der Datei init.ldif in die Datenbank ein, ihr Inhalt lautet folgendermaßen:
# Falls kein Debian bzw. 'dpkg-reconfigure slapd' Verwendung findet, muss zuerste eine
# grundlegende Struktur gegründet und der Admin angelegt werden (die beiden folg. Blöcke):
#dn: dc=dom1,dc=site
#objectClass: top
#objectClass: dcObject
#objectClass: organization
#o: dom1.test
#dc: dom1
#dn: cn=admin,dc=dom1,dc=site
#objectClass: simpleSecurityObject
#objectClass: organizationalRole
#cn: admin
#description: LDAP administrator
#userPassword: secret
# Für den Samba DC
dn: ou=users,dc=dom1,dc=site
objectClass: organizationalUnit
ou: users
dn: ou=groups,dc=dom1,dc=site
objectClass: organizationalUnit
ou: groups
dn: ou=idmap,dc=dom1,dc=site
objectClass: organizationalUnit
ou: idmap
dn: ou=computers,dc=dom1,dc=site
objectClass: organizationalUnit
ou: computers
# Für Thunderbirds Kontaktdatenbank
dn: ou=contacts,dc=dom1,dc=site
objectClass: organizationalUnit
ou: contacts
Das Kommando dazu lautet ähnlich wie oben:
$ ldapadd -x -w admin -D cn=admin,dc=dom1,dc=site -f init.ldif
Zum Einbinden von Thunderbird (Addressbuch mittels „ou=contacts“) siehe unter:
Vertiefung LDAP
Hinzufügen des Benutzers ‚fritz‘, der als echter Linux-User netzwerkweit einsetzbar ist.
Dateiinhalt von fritz-posixAccount.ldif:
dn: cn=fritz,dc=dom1,dc=site
objectclass: person
objectclass: posixAccount
cn: fritz
sn: Schulz
uid: fritz
uidNumber: 2000
gidNumber: 100
homeDirectory: /home/fritz
loginShell: /bin/bash
gecos: Fritz Schulz
Danach wollen wir uns den ‚fritz‘ anzeigen lassen:
ldapsearch -x -b dc=dom1,dc=site cn=fritz
# extended LDIF
#
# LDAPv3
# base <dc=dom1,dc=site> with scope subtree
# filter: cn=fritz
# requesting: ALL
#
# fritz, dom1.test
dn: cn=fritz,dc=dom1,dc=site
objectClass: person
objectClass: posixAccount
cn: fritz
sn: Schulz
uid: fritz
uidNumber: 2000
gidNumber: 100
homeDirectory: /home/fritz
loginShell: /bin/bash
gecos: Fritz Schulz
# search result
search: 2
result: 0 Success
# numResponses: 2
# numEntries: 1
Nutzer modifizieren
Mittels löschen und neu anlegen
Komplett entfernen: lda:pdelete -x -w admin -D cn=admin,dc=dom1,dc=site cn=fritz,dc=dom1,dc=site
Ldif-Datei ändern: vi fritz-posixAccount.ldif
(ändern z.B. von „uidNumber“)
$ ldapadd -x -w admin -D cn=admin,dc=dom1,dc=site -f fritz-posixAccount.ldif
adding new entry "cn=fritz,dc=dom1,dc=site"
$
$ ldapsearch -x -b dc=dom1,dc=site uid=3000
# extended LDIF
#
# LDAPv3
# base <dc=dom1,dc=site> with scope subtree
# filter: uid=3000
# requesting: ALL
#
# search result
search: 2
result: 0 Success
# numResponses: 1
$ ldapsearch -x -b dc=dom1,dc=site uidNumber=3000
# extended LDIF
#
# LDAPv3
# base <dc=dom1,dc=site> with scope subtree
# filter: uidNumber=3000
# requesting: ALL
#
# fritz, dom1.test
dn: cn=fritz,dc=dom1,dc=site
objectClass: person
objectClass: posixAccount
cn: fritz
sn: Schulz
uid: fritz
uidNumber: 3000
gidNumber: 100
homeDirectory: /home/fritz
loginShell: /bin/bash
gecos: Fritz Schulz
# search result
search: 2
result: 0 Success
# numResponses: 2
# numEntries: 1
$
Eleganteres Modifizieren mit ldapmodify
Die entscheidende Angabe ist hier changetype, sie gibt an, ob nur modifiziert oder sogar gelöscht werden soll, außerdem muss mit replace angegeben werden, welcher Wert zu ändern ist:
$ cat fritz-uid-modify-posixAccount.ldif
dn: cn=fritz,dc=dom1,dc=site
changetype: modify
replace: uidNumber
uidNumber: 3500
$
$ ldapmodify -x -w admin -D cn=admin,dc=dom1,dc=site -f fritz-uid-modify-posixAccount.ldif
modifying entry "cn=fritz,dc=dom1,dc=site"
$
$ ldapsearch -LLL -x -b dc=dom1,dc=site uidNumber=3000
$
$ ldapsearch -LLL -x -b dc=dom1,dc=site uidNumber=3500
dn: cn=fritz,dc=dom1,dc=site
objectClass: person
objectClass: posixAccount
cn: fritz
sn: Schulz
uid: fritz
gidNumber: 100
homeDirectory: /home/fritz
loginShell: /bin/bash
gecos: Fritz Schulz
uidNumber: 3500
Will man dem Nutzer ein Passwort setzen, benötigen wir ldappasswd:
$ ldappasswd -x -D cn=admin,dc=dom1,dc=site -w admin cn=fritz,dc=dom1,dc=site -s halloWelt
$
$ ldapsearch -LLL -x -b dc=dom1,dc=site uidNumber=3500 -D cn=admin,dc=dom1,dc=site -w admin
dn: cn=fritz,dc=dom1,dc=site
objectClass: person
objectClass: posixAccount
cn: fritz
sn: Schulz
uid: fritz
gidNumber: 100
homeDirectory: /home/fritz
loginShell: /bin/bash
gecos: Fritz Schulz
uidNumber: 3500
userPassword:: e1NTSEF9a1BiMFNEcXBMT2duZ0luMUNuZFZKT3ZLcE1pSjB1M2g=
Was weiterhin erforderlich sein wird, ist die Objektklasse shadowAccount, um Linux-Logins komplett zu machen:
Sicherheit mit SASL mittel einfach einzurichtenten GnuTLS dank easy-rsa:
Konvertierung vom Old Style Config File zur Online-Konfiguration:
Konvertierung in umgekehrte Richtung zur old style Config File Konfiguration:
Online-Konfiguration komplett ausgeben:
ldapsearch -Y EXTERNAL -H ldapi:/// -b "cn=config" | less
Speziell, um nur „RootDN“ zu finden:
$ ldapsearch -Y EXTERNAL -H ldapi:/// -b "cn=config" | grep --color -A3 RootDN SASL/EXTERNAL authentication started
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
SASL SSF: 0
olcAttributeTypes: ( OLcfgDbAt:0.8 NAME 'olcRootDN' EQUALITY distinguishedName
Match SYNTAX OMsDN SINGLE-VALUE )
olcAttributeTypes: ( OLcfgGlAt:51 NAME 'olcRootDSE' EQUALITY caseIgnoreMatch S
YNTAX OMsDirectoryString )
--
cRequires $ olcRestrict $ olcRootDN $ olcRootPW $ olcSchemaDN $ olcSecurity $
olcSizeLimit $ olcSyncUseSubentry $ olcSyncrepl $ olcTimeLimit $ olcUpdateDN
$ olcUpdateRef $ olcMirrorMode $ olcMonitoring $ olcExtraAttrs ) )
olcObjectClasses: ( OLcfgGlOc:5 NAME 'olcOverlayConfig' DESC 'OpenLDAP Overlay
--
olcRootDN: cn=admin,cn=config
# {1}mdb, config
dn: olcDatabase={1}mdb,cn=config
--
olcRootDN: cn=admin,dc=dom1,dc=site
olcRootPW: {SSHA}UM4SLSJpzRHAuzfOEvxSOjn7iMSe8GRb
olcDbCheckpoint: 512 30
olcDbIndex: objectClass eq
$
Fortgeschrittenes Filtern mit ldapsearch
Zuerst legen wir weitere Nutzer an, die auch für spätere Linux-Authentifizierung genutzt werden können:
$ vi fritz1.ldif
$
$ cat fritz1.ldif
dn: uid=fritz,dc=dom1,dc=test
objectClass: top
objectClass: person
objectClass: posixAccount
objectClass: shadowAccount
objectClass: inetOrgPerson
uid: fritz
uidNumber: 10000
gidNumber: 100
cn: fritz
sn: Meier
loginShell: /bin/bash
homeDirectory: /home/fritz
mail: fritz@dom1.test
$
$
$ ldapadd -xWD cn=admin,dc=dom1,dc=test -f fritz1.ldif
Enter LDAP Password:
adding new entry "uid=fritz,dc=dom1,dc=test"
$
$ ldapsearch -xLLL uid=fr*
dn: uid=fritz,dc=dom1,dc=test
objectClass: top
objectClass: person
objectClass: posixAccount
objectClass: shadowAccount
objectClass: inetOrgPerson
uid: fritz
uidNumber: 10000
gidNumber: 100
cn: fritz
sn: Meier
loginShell: /bin/bash
homeDirectory: /home/fritz
mail: fritz@dom1.test
$
$ sed 's/fritz/friedrich/;s/10000/10001/' fritz1.ldif > friedrich1.ldif
$
$ cat friedrich1.ldif
dn: uid=friedrich,dc=dom1,dc=test
objectClass: top
objectClass: person
objectClass: posixAccount
objectClass: shadowAccount
objectClass: inetOrgPerson
uid: friedrich
uidNumber: 10001
gidNumber: 100
cn: friedrich
sn: Meier
loginShell: /bin/bash
homeDirectory: /home/friedrich
mail: friedrich@dom1.test
$
$
$ ldapadd -xWD cn=admin,dc=dom1,dc=test -f friedrich1.ldif
Enter LDAP Password:
adding new entry "uid=friedrich,dc=dom1,dc=test"
$
$ ldapsearch -xLLL uid=fri*
dn: uid=fritz,dc=dom1,dc=test
objectClass: top
objectClass: person
objectClass: posixAccount
objectClass: shadowAccount
objectClass: inetOrgPerson
uid: fritz
uidNumber: 10000
gidNumber: 100
cn: fritz
sn: Meier
loginShell: /bin/bash
homeDirectory: /home/fritz
mail: fritz@dom1.test
dn: uid=friedrich,dc=dom1,dc=test
objectClass: top
objectClass: person
objectClass: posixAccount
objectClass: shadowAccount
objectClass: inetOrgPerson
uid: friedrich
uidNumber: 10001
gidNumber: 100
cn: friedrich
sn: Meier
loginShell: /bin/bash
homeDirectory: /home/friedrich
mail: friedrich@dom1.test
$
Dann vergeben wir ihnen Passwörter:
$ ldappasswd -xWD cn=admin,dc=dom1,dc=test uid=fritz,dc=dom1,dc=test -s fritS001
Enter LDAP Password:
$
$ ldappasswd -xWD cn=admin,dc=dom1,dc=test uid=friedrich,dc=dom1,dc=test -s friedS001
Enter LDAP Password:
$
$ ldapsearch -xLLL uid=frit*
dn: uid=fritz,dc=dom1,dc=test
objectClass: top
objectClass: person
objectClass: posixAccount
objectClass: shadowAccount
objectClass: inetOrgPerson
uid: fritz
uidNumber: 10000
gidNumber: 100
cn: fritz
sn: Meier
loginShell: /bin/bash
homeDirectory: /home/fritz
mail: fritz@dom1.test
$ ldapsearch -xLLL uid=frit* -WD cn=admin,dc=dom1,dc=test
Enter LDAP Password:
dn: uid=fritz,dc=dom1,dc=test
objectClass: top
objectClass: person
objectClass: posixAccount
objectClass: shadowAccount
objectClass: inetOrgPerson
uid: fritz
uidNumber: 10000
gidNumber: 100
cn: fritz
sn: Meier
loginShell: /bin/bash
homeDirectory: /home/fritz
mail: fritz@dom1.test
userPassword:: e1NTSEF9bThBYWFKeENnM2d2QXB5YkxIcndtYTB5VXdicFMrZFY=
$
Und jetzt kommt das Filtern mit logisch UND bzw. ODER.
Logisch ODER:
$ ldapsearch -xLLL '(|(uid=fritz)(cn=ad*))'
dn: cn=admin,dc=dom1,dc=test
objectClass: simpleSecurityObject
objectClass: organizationalRole
cn: admin
description: LDAP administrator
dn: uid=fritz,dc=dom1,dc=test
objectClass: top
objectClass: person
objectClass: posixAccount
objectClass: shadowAccount
objectClass: inetOrgPerson
uid: fritz
uidNumber: 10000
gidNumber: 100
cn: fritz
sn: Meier
loginShell: /bin/bash
homeDirectory: /home/fritz
mail: fritz@dom1.test
$
Logisch UND:
$ ldapsearch -xLLL '(&(uid=fri*)(uidNumber=10001))'
dn: uid=friedrich,dc=dom1,dc=test
objectClass: top
objectClass: person
objectClass: posixAccount
objectClass: shadowAccount
objectClass: inetOrgPerson
uid: friedrich
uidNumber: 10001
gidNumber: 100
cn: friedrich
sn: Meier
loginShell: /bin/bash
homeDirectory: /home/friedrich
mail: friedrich@dom1.test
$
Logisch UND, wobei aber der 2. Term negiert werden soll:
$ ldapsearch -xLLL '(&(uid=fri*)(!(uidNumber=10001)))'
dn: uid=fritz,dc=dom1,dc=test
objectClass: top
objectClass: person
objectClass: posixAccount
objectClass: shadowAccount
objectClass: inetOrgPerson
uid: fritz
uidNumber: 10000
gidNumber: 100
cn: fritz
sn: Meier
loginShell: /bin/bash
homeDirectory: /home/fritz
mail: fritz@dom1.test
$
Siehe dazu auch https://www.tecchannel.de/a/ldap-abfragen-erstellen,464680,2
Von Online Configuration zu Konfigurationsdateien
ZIEL: Konvertierung/Downgrade von OLC zu Files
$ systemctl stop slapd
$
$ mv /etc/ldap/slapd.d /root
$ cp /usr/share/slapd/slapd.conf /etc/ldap/
$ sed -i "s/@BACKEND@/hdb/" /etc/ldap/slapd.conf
$ sed -i "s/@SUFFIX@/dc=dom1,dc=site/" /etc/ldap/slapd.conf
$ sed -i "s/# rootdn/rootdn/" /etc/ldap/slapd.conf
$ slappasswd
New password:
Re-enter new password:
{SSHA}YuHMAaXTvmqNZSyzSXgqN5PQ96btrgjI
$
$ vi /etc/ldap/slapd.conf
$
Hinzuzufügen war die zweite Zeile, wie hier zu sehen:
$ grep -B1 rootpw /etc/ldap/slapd.conf
rootdn "cn=admin,dc=dom1,dc=site"
rootpw "{SSHA}YuHMAaXTvmqNZSyzSXgqN5PQ96btrgjI"
$
$ sed -i "s/@ADMIN@/cn=admin,dc=dom1,dc=site/" /etc/ldap/slapd.conf
$
$ ls -l /var/lib/ldap/
insgesamt 144
-rw------- 1 openldap openldap 143360 Nov 19 11:19 data.mdb
-rw------- 1 openldap openldap 8192 Nov 19 13:07 lock.mdb
$
$ mv -v /var/lib/ldap/* /root
„/var/lib/ldap/data.mdb“ -> „/root/data.mdb“
„/var/lib/ldap/data.mdb“ wurde entfernt
„/var/lib/ldap/lock.mdb“ -> „/root/lock.mdb“
„/var/lib/ldap/lock.mdb“ wurde entfernt
$
$ systemctl start slapd
Job for slapd.service failed. See 'systemctl status slapd.service' and 'journalctl -xn' for details.
$
Der Start schlägt fehl, sind die Startparameter in Ordnung?
Zu Erinnerung:
$ pgrep -a slap
3073 /usr/sbin/slapd -h ldap:/// ldapi:/// -g openldap -u openldap -F /etc/ldap/slapd.d
Die Konfigdatei sieht insgesamt so aus:
$ grep -v ^# /etc/ldap/slapd.conf | grep -v ^$
include /etc/ldap/schema/core.schema
include /etc/ldap/schema/cosine.schema
include /etc/ldap/schema/nis.schema
include /etc/ldap/schema/inetorgperson.schema
pidfile /var/run/slapd/slapd.pid
argsfile /var/run/slapd/slapd.args
loglevel none
modulepath /usr/lib/ldap
moduleload back_hdb
sizelimit 500
tool-threads 1
backend hdb
database hdb
suffix "dc=dom1,dc=site"
rootdn directive for specifying a superuser on the database. This is needed
rootdn "cn=admin,dc=dom1,dc=site"
rootpw "{SSHA}YuHMAaXTvmqNZSyzSXgqN5PQ96btrgjI"
directory "/var/lib/ldap"
dbconfig set_cachesize 0 2097152 0
dbconfig set_lk_max_objects 1500
dbconfig set_lk_max_locks 1500
dbconfig set_lk_max_lockers 1500
index objectClass eq
lastmod on
checkpoint 512 30
access to attrs=userPassword,shadowLastChange
by dn="cn=admin,dc=dom1,dc=site" write
by anonymous auth
by self write
by * none
access to dn.base="" by * read
access to *
by dn="cn=admin,dc=dom1,dc=site" write
by * read
$
Ein Startversuch mit
/usr/sbin/slapd -4 -d 15 -h ldap://127.0.0.1:9009/ -g openldap -u openldap -f /etc/ldap/slapd.conf
schlägt aber leider auch fehl.
Aufgabe: Hier bitte weiterstudieren: https://wiki.debian.org/LDAP/OpenLDAPSetup#Access_control
FEHLER GEFUNDEN
Der entscheidende Hinweis kam durch den Start mit dem Debug-Wert von 64 zustande (configuration processing), siehe zum Debugging: http://www.openldap.org/doc/admin24/runningslapd.html
Das obige sed -i "s/# rootdn/rootdn/" /etc/ldap/slapd.conf
hatte etwas zuviel einkommentiert!
Nach dem Auskommentieren von „rootdn directive for specifying a superuser on the database. This is needed“ funktioniert es jetzt ohne Fehlermeldungen.
Mit folgender Zeile läuft der slpad erst einmal an:
/usr/sbin/slapd -g openldap -u openldap -f /etc/ldap/slapd.conf -d 64
Viel Erfolg und Spaß weiterhin…
Übungsumgebung
Für die nächsten Themen benötigen wir eine etwas komplexere Übungsumgebung. Siehe dazu http://pemmann.de/cc/Doc/Testumgebung/Misc/dmz.png
Topic 211: E-Mail Services
211.1 Using e-mail servers
ROLLE: Mail Transfer Agent (MTA)
Typische Daemons:
sendmail
qmail
postfix
exim
Port-Nummern für E-Mail (https://de.wikipedia.org/wiki/STARTTLS):
SMTP auf Port 25 bzw. 587 und SMTPS auf Port 465
IMAP auf Port 143 und IMAPS auf Port 993
POP3 auf Port 110 und POP3S auf Port 995
Zu exim
https://gambaru.de/blog/2012/03/21/nur-versenden-mailserver-mit-debian-und-exim/
Welchen Port er öffnen soll, wird dem Daemin über die Datei /etc/default/exim4 mitgegeben. Ansonsten ist Port 25 voreingestellt:
$ ps aux | grep exim
Debian-+ 1035 0.0 0.4 53248 3272 ? Ss Nov23 0:00 /usr/sbin/exim4 -bd -q30m
Am besten wir vergleichen die Konfiguration vor der Umstellung auf „Internet Server“ und danach:
$ mkdir /root/exim4.configs_orig
$
$ cp /etc/default/exim4 /root/exim4.configs_orig/etc__default__exim4
$
$ cp -a /etc/exim4/ /root/etc__exim4
$
$ dpkg-reconfigure exim4-config
Wir wählen im Assistenten:
„Internet Server“
deb8.dom1.test
127.0.0.1 ; ::1 ; 10.20.30.5
deb8.dom1.test
Alle weiteren Voreinstellungen übernehmen…
Danach sieht das Ganze so aus:
$ service exim4 restart
$ lsof -i TCP -Pn | grep 25
named 613 bind 23u IPv4 12588 0t0 TCP 127.0.0.1:953 (LISTEN)
named 613 bind 24u IPv6 12589 0t0 TCP [::1]:953 (LISTEN)
sshd 615 root 3u IPv4 12576 0t0 TCP *:22 (LISTEN)
sshd 615 root 4u IPv6 12585 0t0 TCP *:22 (LISTEN)
exim4 2270 root 4u IPv4 15370 0t0 TCP 127.0.0.1:25 (LISTEN)
exim4 2270 root 5u IPv6 15371 0t0 TCP [::1]:25 (LISTEN)
$
$
$ ps xu | grep exim
root 2270 0.0 0.7 53244 2172 ? Ss 09:48 0:00 /usr/sbin/exim4 -bd -q30m
root 2274 0.0 0.7 12748 2176 pts/0 S+ 09:48 0:00 grep exim
$
In der Startkonfiguration hat sich nichts geändert:
$ ls -l /etc/default/exim4
-rw-r--r-- 1 root root 1018 Nov 14 18:34 /etc/default/exim4
$
$ lsof -i TCP -Pn | grep exim
exim4 2270 root 4u IPv4 15370 0t0 TCP 127.0.0.1:25 (LISTEN)
exim4 2270 root 5u IPv6 15371 0t0 TCP [::1]:25 (LISTEN)
$
Aber hier werden wir fündig:
$ grep -v ^# /etc/exim4/update-exim4.conf.conf
dc_eximconfig_configtype='internet'
dc_other_hostnames='deb8.dom1.test'
dc_local_interfaces='127.0.0.1 ; ::1 ; 10.20.30.5'
dc_readhost=''
dc_relay_domains=''
dc_minimaldns='false'
dc_relay_nets=''
dc_smarthost=''
CFILEMODE='644'
dc_use_split_config='false'
dc_hide_mailname=''
dc_mailname_in_oh='true'
dc_localdelivery='mail_spool'
$
$
$ grep -r 'dc_eximconfig_configtype' /root/etc__exim4/ /root/etc__exim4/update-exim4.conf.conf:dc_eximconfig_configtype='local'
Migration von exim4 zu sendmail
Autor: https://de.wikipedia.org/wiki/Alan_Cox
Problem: Exim ist nicht gar zu sehr kompatibel zu sendmail!
Deshalb wollen wir Sendmail installieren:
$ apt-get install sendmail-bin
Dabei wird Exim entfernt und sendmail gestartet (was leider nicht ohne Warnungen verlief):
$ lsof -i TCP -Pn | grep 25
named 613 bind 23u IPv4 12588 0t0 TCP 127.0.0.1:953 (LISTEN)
named 613 bind 24u IPv6 12589 0t0 TCP [::1]:953 (LISTEN)
sshd 615 root 3u IPv4 12576 0t0 TCP *:22 (LISTEN)
sshd 615 root 4u IPv6 12585 0t0 TCP *:22 (LISTEN)
sendmail- 4689 root 3u IPv4 19208 0t0 TCP 127.0.0.1:25 (LISTEN)
$
Erste Tests:
$ mailq
MSP Queue status...
/var/spool/mqueue-client is empty
Total requests: 0
MTA Queue status...
/var/spool/mqueue is empty
Total requests: 0
$
$
$ ls -l /var/spool/mail/
insgesamt 4
-rw-rw---- 1 tux mail 517 Nov 29 11:03 tux
$
$
$
$ echo 123 | mail -s "testmail 2" tux
$
$ ls -l /var/spool/mail/
insgesamt 4
-rw-rw---- 1 tux mail 517 Nov 29 11:03 tux
$
$
$
$
$ mailq
MSP Queue status...
/var/spool/mqueue-client is empty
Total requests: 0
MTA Queue status...
/var/spool/mqueue (1 request)
-----Q-ID----- --Size-- -----Q-Time----- ------------Sender/Recipient-----------
uATAEes6004750 4 Tue Nov 29 11:14 <tux@d8slave.dom1.test>
(Operating system error)
<tux@d8slave.dom1.test>
Total requests: 1
$
ACHTUNG: Nicht einmal die lokale Mailkommunikation funktioniert!
Evl. könnte es an diesem Mischmasch liegen:
$ cat /etc/mailname
deb8.dom1.test
$
$ hostname -f > /etc/mailname
$
$ cat /etc/mailname
d8slave.dom1.test
$
SMTP - Returncodes: http://www.elektronik-kompendium.de/sites/net/0903081.htm
Sendmail ist in Debian 8 nicht mehr besonders gut integriert, das Paket ‚sendmail‘ lässt sich überhaupt nicht installieren, ein Stück weit kommen wir aber damit:
$ dpkg-reconfigure sendmail-bin
Could not open /etc/mail/databases(Datei oder Verzeichnis nicht gefunden), creating it.
$
Die nächsten Schritte zur Erforschung der Konfiguration:
http://64-bit.de/dokumentationen/netzwerk/f/002/DE-Mailserver-HOWTO-3.html
Hauptfile: sendmail.cf
Makro-Konfig-file: /etc/mail/sendmail.mc (Kommentar: „dnl“)
Frontend-file: /etc/mail/sendmail.conf
$ ls -l /etc/mail insgesamt 336 -rw------- 1 root root 4261 Nov 29 11:23 access -rw-r----- 1 smmta smmsp 12288 Nov 29 11:23 access.db -rw-r--r-- 1 root root 281 Jun 30 20:08 address.resolve lrwxrwxrwx 1 root smmsp 10 Nov 29 11:11 aliases -> ../aliases -rw-r----- 1 smmta smmsp 12288 Nov 29 11:23 aliases.db -rw-r--r-- 1 root root 3219 Nov 29 11:23 databases -rw-r--r-- 1 root root 5657 Jul 4 00:32 helpfile -rw-r--r-- 1 root smmsp 28 Nov 29 11:11 local-host-names drwxr-sr-x 2 smmta smmsp 4096 Nov 29 11:11 m4 -rwxr-xr-- 1 root smmsp 9995 Nov 29 11:23 Makefile drwxr-xr-x 2 root root 4096 Nov 29 11:11 peers drwxr-xr-x 2 root smmsp 4096 Jun 30 20:08 sasl -rw-r--r-- 1 root smmsp 64522 Nov 29 11:23 sendmail.cf -rw-r--r-- 1 root smmsp 269 Nov 29 11:23 sendmail.cf.errors -rw-r--r-- 1 root root 64518 Nov 29 11:23 sendmail.cf.old -rw-r--r-- 1 root root 12236 Nov 29 11:23 sendmail.conf -rw-r--r-- 1 root smmsp 4221 Nov 29 11:23 sendmail.mc -rw-r--r-- 1 root root 149 Jun 30 20:08 service.switch -rw-r--r-- 1 root root 180 Jun 30 20:08 service.switch-nodns drwxr-sr-x 2 smmta smmsp 4096 Nov 29 11:11 smrsh -rw-r--r-- 1 root smmsp 44055 Nov 29 11:23 submit.cf -rw-r--r-- 1 root root 44051 Nov 29 11:23 submit.cf.old -rw-r--r-- 1 root smmsp 2381 Nov 29 11:23 submit.mc drwxr-xr-x 2 smmta smmsp 4096 Nov 29 11:11 tls -rw-r--r-- 1 root smmsp 0 Nov 29 11:11 trusted-users $ $ whatis m4 m4 (1) - macro processor $ $ grep -i smarthost /etc/mail/sendmail.cf #O FallbackSmartHost=fall.back.host.net R$* < @ [ $+ ] : > $* $#esmtp $@ [$2] $: $1 < @ [$2] > $3 no smarthost: send R$* < @ [ $+ ] : $- : $*> $* $#$3 $@ $4 $: $1 < @ [$2] > $5 smarthost with mailer R$* < @ [ $+ ] : $+ > $* $#esmtp $@ $3 $: $1 < @ [$2] > $4 smarthost without mailer # pass names that still have a host to a smarthost (if defined) R$* < @ $* > $* $: $>MailerToTriple < $S > $1 < @ $2 > $3 glue on smarthost name $
Das erzeugt nun die eigentliche Konfigdatei:
$ cp /etc/mail/sendmail.mc .
$
$ vi sendmail.mc
$
$ m4 sendmail.mc > sendmail.cf
Weiter Konfigadteien:
Siehe https://www.freebsd.org/doc/de_DE.ISO8859-1/books/handbook/sendmail.html
Die Datei ‚/etc/mail/local-host-names‘ ist das Pendant zu Postfix’s Direktive ‚mydestination‘, damit wird festgelegt, für welche Domänen der Server E-Mails annehmen soll:
# local-host-names - include all aliases for your machine here.
# Example from http://www.faqs.org/docs/securing/chap22sec180.html
openna.com
deep.openna.com
www.openna.com
win.openna.com
mail.openna.com
Unter Debian:
$ cat /etc/mail/local-host-names
localhost
d8slave.dom1.test
$
$ ### Warteschlange ausgehender Mails:
$
$ # mailq = sendmail -bq
$
$ ls -l /var/spool/mqueue
insgesamt 16
-rw-r----- 1 smmta smmsp 4 Nov 29 11:14 dfuATAEes6004750
-rw-r----- 1 root smmsp 4 Nov 29 11:24 dfuATAOW2H005638
-rw-r----- 1 root smmsp 859 Nov 29 11:43 qfuATAEes6004750
-rw-r----- 1 root smmsp 859 Nov 29 11:43 qfuATAOW2H005638
$
$
$
$
$ ### Pfad für ausgelieferte Mails (in house, MDA):
$
$ ls -l /var/spool/mail
lrwxrwxrwx 1 root root 7 Nov 14 18:25 /var/spool/mail -> ../mail
$
$ ls -lL /var/spool/mail
insgesamt 4
-rw-rw---- 1 tux mail 517 Nov 29 11:03 tux
$
Migration zu Postfix
$ apt-get install postfix
Paketlisten werden gelesen... Fertig
Abhängigkeitsbaum wird aufgebaut.
Statusinformationen werden eingelesen.... Fertig
Die folgenden Pakete wurden automatisch installiert und werden nicht mehr benötigt:
libecap2 libnetfilter-conntrack3 squid-langpack squid3-common
Verwenden Sie »apt-get autoremove«, um sie zu entfernen.
Die folgenden zusätzlichen Pakete werden installiert:
ssl-cert
Vorgeschlagene Pakete:
postfix-mysql postfix-pgsql postfix-ldap postfix-pcre sasl2-bin dovecot-common postfix-cdb
ufw postfix-doc openssl-blacklist
Die folgenden Pakete werden ENTFERNT:
sendmail-bin
Die folgenden NEUEN Pakete werden installiert:
postfix ssl-cert
0 aktualisiert, 2 neu installiert, 1 zu entfernen und 5 nicht aktualisiert.
Es müssen 1.392 kB an Archiven heruntergeladen werden.
Nach dieser Operation werden 2.021 kB Plattenplatz zusätzlich benutzt.
Möchten Sie fortfahren? [J/n]
Der Assistent kommt wieder zum Vorschein, wir wählen:
„Internet Site“
„d8slave.dom1.test“
Die beiden wichtigsten Dateien sind:
/etc/postfix/master.cf (ist wie eine klassische inetd-Konfiguration aufgebaut)
/etc/postfix/main.cf (die am meisten benötigte Datei)
Ein einfaches Szanrio, was ohne DNS auskommt (/etc/hosts pflegen!):
disable_dns_lookups = yes
mydestination = d8slave.dom1.test, localhost.dom1.test, , localhost
mynetworks = 10.20.30.0/24 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
inet_interfaces = all
Wir ändern ganz praktisch die Datei ‚main.cf‘, hinzuzufügen ist ‚dom1.test‘ beim ersten Eintrag, beim zweiten dann ‚10.20.30.0/24‘:
mydestination = dom1.test, d8slave.dom1.test, localhost.dom1.test, , localhost
mynetworks = 10.20.30.0/24 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
Außerdem wichtig fürs Port-Listening (ist bei Debian per Default so eingestellt):
inet_interfaces = all
Die Syntax der eigenen Einstellungen prüfen:
$ postconf -n
alias_database = hash:/etc/aliases
alias_maps = hash:/etc/aliases
append_dot_mydomain = no
biff = no
config_directory = /etc/postfix
inet_interfaces = all
mailbox_command = procmail -a "$EXTENSION"
mailbox_size_limit = 0
mydestination = dom1.test, d8slave.dom1.test, localhost.dom1.test, , localhost
myhostname = d8slave.dom1.test
mynetworks = 10.20.30.0/24 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
myorigin = /etc/mailname
readme_directory = no
recipient_delimiter = +
relayhost =
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
smtpd_banner = $myhostname ESMTP $mail_name (Debian/GNU)
smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated defer_unauth_destination
smtpd_tls_cert_file = /etc/ssl/certs/ssl-cert-snakeoil.pem
smtpd_tls_key_file = /etc/ssl/private/ssl-cert-snakeoil.key
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
smtpd_use_tls = yes
$
$ lsof -i TCP -Pn | grep 25
named 613 bind 23u IPv4 12588 0t0 TCP 127.0.0.1:953 (LISTEN)
named 613 bind 24u IPv6 12589 0t0 TCP [::1]:953 (LISTEN)
sshd 615 root 3u IPv4 12576 0t0 TCP *:22 (LISTEN)
sshd 615 root 4u IPv6 12585 0t0 TCP *:22 (LISTEN)
sendmail- 5621 root 3u IPv4 20881 0t0 TCP 127.0.0.1:25 (LISTEN)
$
$ killall sendmail-bin
sendmail-bin: Kein Prozess gefunden
$
$ pkill -9 sendmail
$ lsof -i TCP -Pn | grep 25
named 613 bind 23u IPv4 12588 0t0 TCP 127.0.0.1:953 (LISTEN)
named 613 bind 24u IPv6 12589 0t0 TCP [::1]:953 (LISTEN)
sshd 615 root 3u IPv4 12576 0t0 TCP *:22 (LISTEN)
sshd 615 root 4u IPv6 12585 0t0 TCP *:22 (LISTEN)
$
$
$ systemctl restart postfix
$
$ postfix status
postfix/postfix-script: the Postfix mail system is running: PID: 8386
$
$
$ echo 123 | mail -s "testmail 4" tux
$
$ mailq
Mail queue is empty
$
$ tail -5 /var/spool/mail/tux
Date: Tue, 29 Nov 2016 13:07:40 +0100 (CET)
From: root@d8slave.dom1.test (root)
123
$
Die nächsten Schritte für eine SMTP-Direktkommunikation
Mail-Daemons für SMTP mit zwei postfix-Installationen auf verschiedenen Rechnern
Server 1: dom1.test
Server 2: dom2.test
Bind9: Eine weiter Zone für dom2.test hinzufügen
MX-Records für beide MTAs anlegen
Szenario mit zwei MTAs
MTA 2 - d8mx2.dom2.test
Auf dem zweiten MTA (Debian 8, geklont aus d8slave, bind9 deinstalliert):
Die Datei ‚/etc/postfix/main.cf‘ wurde bereits für ‚dom2.test‘ angepasst:
$ grep -v ^# /etc/postfix/main.cf | grep -v ^$ | grep --color dom[1,2].test
myhostname = d8mx2.dom2.test
mydestination = dom2.test, d8mx2.dom2.test, localhost.dom2.test, , localhost
$
Insgesamt sieht die ‚main.cf‘ dann so aus:
smtpd_banner = $myhostname ESMTP $mail_name (Debian/GNU)
biff = no
append_dot_mydomain = no
readme_directory = no
smtpd_tls_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
smtpd_tls_key_file=/etc/ssl/private/ssl-cert-snakeoil.key
smtpd_use_tls=yes
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated defer_unauth_destination
myhostname = d8mx2.dom2.test
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
myorigin = /etc/mailname
mydestination = dom2.test, d8mx2.dom2.test, localhost.dom2.test, , localhost
relayhost =
mynetworks = 10.20.30.0/24 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
mailbox_command = procmail -a "$EXTENSION"
mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = all
DNS-Server um zone dom2.test erweitern
Wir editieren die Datei für die Zonendefinitionen: vi /etc/bind/named.conf.local
zone "dom2.test" {
type master;
notify yes;
allow-transfer { key TRANSFER; localhost; };
allow-update { key "rndc-key"; };
file "/var/lib/bind/db.dom2.test";
};
$ vi /etc/bind/named.conf.local
$
$ cd /var/lib/bind/
root@d8master:/var/lib/bind#
root@d8master:/var/lib/bind# rndc freeze
root@d8master:/var/lib/bind#
root@d8master:/var/lib/bind# cp db.dom1.test db.dom2.test
root@d8master:/var/lib/bind#
root@d8master:/var/lib/bind# vi db.dom2.test
:1,$s/dom1/dom2/g
:1,$s/d8master/d8mx2/g
Hinzufügen der RRs für den MTA in Domäne 2
dom2.test. MX 10 d8mx2.dom2.test.
d8mx2 A 10.20.30.6
Nach dem Abspeichern kontrollieren wir kurz:
root@d8master:/var/lib/bind# grep dom2 db.dom2.test
dom2.test IN SOA d8mx2.dom2.test. root.d8mx2.dom2.test. (
NS d8slave.dom2.test.
NS d8mx2.dom2.test.
dom2.test. MX 10 d8mx2.dom2.test.
$ORIGIN dom2.test.
root@d8master:/var/lib/bind#
root@d8master:/var/lib/bind#
root@d8master:/var/lib/bind# grep 10.20.30.6 db.dom2.test
d8mx2 A 10.20.30.6
root@d8master:/var/lib/bind#
Hinzufügen des RRs für den MTA in Domäne 1
vi db.dom1.test
dom1.test. MX 10 d8master.dom1.test.
Testings auf d8mx2
Nach dem Neustart von bind9 beginnen wir auf ‚d8mx2‘:
$ cat /etc/resolv.conf
# Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8)
# DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN
nameserver 10.20.30.3
nameserver 10.20.30.4
search dom2.test
$
$ host -t mx dom2.test
dom2.test mail is handled by 10 d8mx2.dom2.test.
$
$ host -t mx dom1.test
dom1.test mail is handled by 10 d8master.dom1.test.
$
tail -f /var/log/mail.log
Eine erste Mail wird mit dem Fehler „…….“ blockiert… (Todo!)
$ echo OK?? | mail -s test1 tux@dom1.test
$
$ echo OK?? | mail -s selftest tux@dom2.test
$
$ telnet d8mx2.dom2.test. 25
Trying 10.20.30.6...
Connected to d8mx2.dom2.test.
Escape character is '^]'.
220 d8mx2.dom2.test ESMTP Postfix (Debian/GNU)
helo
501 Syntax: HELO hostname
mail from: billy@gates.ms
250 2.1.0 Ok
rcpt to: tux@dom1.test
250 2.1.5 Ok
500 5.5.2 Error: bad syntax
data
354 End data with <CR><LF>.<CR><LF>
Hallo,
Frühstück endlich....!
.
250 2.0.0 Ok: queued as 3FC15623
quit
221 2.0.0 Bye
Connection closed by foreign host.
$
Troubleshooting
https://www.cyberciti.biz/tips/howto-linux-unix-check-dns-file-errors.html
Wo steckt der hier der Fehler?
$ cat /var/lib/bind/db.dom1.test
$ORIGIN .
$TTL 604800 ; 1 week
dom1.test IN SOA d8master.dom1.test. root.d8master.dom1.test. (
73 ; serial
604800 ; refresh (1 week)
86400 ; retry (1 day)
2419200 ; expire (4 weeks)
604800 ; minimum (1 week)
)
NS d8slave.dom1.test.
NS d8master.dom1.test.
dom1.test. MX 10 d8master.dom1.test.
d8master A 10.20.30.3
d8slave A 10.20.30.4
d8squid A 10.20.30.5
$
$ named-checkzone dom1.test /var/lib/bind/db.dom1.test
/var/lib/bind/db.dom1.test:14: ignoring out-of-zone data (d8master)
/var/lib/bind/db.dom1.test:15: ignoring out-of-zone data (d8slave)
/var/lib/bind/db.dom1.test:16: ignoring out-of-zone data (d8squid)
zone dom1.test/IN: NS 'd8slave.dom1.test' has no address records (A or AAAA)
zone dom1.test/IN: NS 'd8master.dom1.test' has no address records (A or AAAA)
zone dom1.test/IN: not loaded due to errors.
$
Es liegt an dem einzelnen Punkt bei $ORIGIN .
, was durch die Koppelung von DHCP -> DNS (DDNS) automatisch zustande kam.
Es muss allerdings $ORIGIN dom1.test.
lauten. Alternativ kann der Eintrag auch ganz weggelassen werden.
211.2 Managing Local E-Mail Delivery
Ziel ist, Mails mit Hilfe von Sieve und Procmail ausfiltern zu können. Siehe dazu die Dokumentation E-Mails ausfiltern.
211.3 Managing Remote E-Mail Delivery
Ziel ist, verschiedene Mail Acccess Agents für POP3 und IMAP in unser Mailsystem einzubinden. Siehe dazu die Dokumentation Mailserver mit Postfix und Dovocot.
Topic 212: System Security
212.1 Configuring a router
Hardening
Empfehlenswert ist VOR dem ersten Ans-Netz-nehmen folgendes:
Updates von einem lokalen Mirror einspielen (ähnlich wie unter http://www.informationsarchiv.net/topics/65052/ beschrieben)
Nur die Anwendungen und Dienste installieren, die man benötigt
IDS-Systeme installieren (tripwire, aide, fail2ban, artillery, logwatch, snort)
Siehe dazu auch
https://www.debian.org/doc/manuals/securing-debian-howto/ch-automatic-harden.de.html
http://arstechnica.com/gadgets/2016/01/numbers-dont-lie-its-time-to-build-your-own-router/
https://opensource.com/life/16/6/why-i-built-my-own-linux-router
https://www.olimex.com/Products/OLinuXino/open-source-hardware
Hinweise zum Härten:
Kein Journaling-Dateisystem verwenden
Deinstallieren von Software (z.B.
apt-get remove rpcbind cups
)
Danach sieht es nun so aus:
root@deb8:~# lsof -i | grep LISTEN
sshd 527 root 3u IPv4 21545 0t0 TCP *:ssh (LISTEN)
sshd 527 root 4u IPv6 21547 0t0 TCP *:ssh (LISTEN)
exim4 794 Debian-exim 4u IPv4 12569 0t0 TCP localhost:smtp (LISTEN)
exim4 794 Debian-exim 5u IPv6 12570 0t0 TCP localhost:smtp (LISTEN)
root@deb8:~#
root@deb8:~#
Firewalls unter Linux
Definition: Schutzeinrichtung gegen unerwünschte Datenpakete, die den Rechner selbst bzw. angeschlossene Netzwerke betreffen können.
Firewall-Architekturen
Siehe http://www.netzmafia.de/skripten/sicherheit/sicher4.html
Architektur mit Dualhomed-Host (ein Router als Firewall)
Architektur mit überwachtem Host (ein Router sowie ein Proxy-Server)
Architektur mit überwachtem Teilnetz (DMZ)
Firewall-Technologien
Siehe dazu http://docplayer.org/16366167-Einfuehrung-in-die-firewall-technologie.html
Paketfilter
Circuit Level Gateway
Application Level Gateway (Eine einfache From: transparenter Proxy mit iptables und squid)
Paketfilter-Technologie
Im einfachsten Falle gibt es kein dynamisches Reagieren auf Ereignisse, wie es auch erst später mit Stateful Packet Inspection (SPI) möglich geworden ist (Die Firma Checkpoint ist wohl noch Patentinhaber).
Gundsätzlich ist es immer eine gute Idee, zuerst einmal die Möglichkeiten des Kernels, was ‚/proc/sys/net/‘ betrifft, auszureizen, siehe http://www.thegeekstuff.com/2010/07/how-to-disable-ping-replies-in-linux/
Mit folgender Zeile werden eingehende ICMP-Pakete verworfen:
$ echo "1" > /proc/sys/net/ipv4/icmp_echo_ignore_all
Dieses lässt sich auch mit später auch mit ‚iptables‘ machen…
Zum den intern verwendeten Tabellen und darin befindlichen Ketten siehe http://www.pro-linux.de/artikel/2/761/2,grunds%C3%A4tzliche-funktionsweise.html
Eine grundlegend restriktive Arbeitsweise aktivieren:
$ iptables -P INPUT DROP
$ iptables -P FORWARD DROP
$ iptables -P OUTPUT DROP
Die lokale Kommunikation komplett erlauben:
$ iptables -A INPUT -i lo -j ACCEPT
$ iptables -A OUTPUT -o lo -j ACCEPT
Eingehend ssh zulassen:
$ iptables -A INPUT -i eth0 -p tcp --dport 22 -j ACCEPT
$ iptables -A OUTPUT -o eth0 -p tcp --sport 22 -j ACCEPT
Etwas sicherer wird es, wenn wir den Portbereich für die Antwortpakete ebenfalls vorgeben (‘–sport 1024:65553‘ == ‚–sport 1024:‘):
$ iptables -A INPUT -i eth0 -p tcp --dport 22 --sport 1024: -j ACCEPT
$ iptables -A OUTPUT -o eth0 -p tcp --sport 22 --dport 1024: -j ACCEPT
Zum Speichern der aktuellen Regeln wird ‚iptables-save‘ verwendet, zur späteren wiedereinlesen ‚iptables-restore‘:
root@deb8:~# iptables-save
# Generated by iptables-save v1.4.21 on Tue Dec 6 11:56:41 2016
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT DROP [0:0]
-A INPUT -i lo -j ACCEPT
-A INPUT -i eth0 -p tcp -m tcp --dport 22 -j ACCEPT
-A OUTPUT -o lo -j ACCEPT
-A OUTPUT -o eth0 -p tcp -m tcp --sport 22 -j ACCEPT
COMMIT
# Completed on Tue Dec 6 11:56:41 2016
root@deb8:~#
AUFGABE: Eingehend ping erlauben, aber nur für die Nachrichten-Typen 1 und 8!
LÖSUNG:
$ iptables -A INPUT -i eth0 -p icmp --icmp-type 0 -j ACCEPT
$ iptables -A OUTPUT -o eth0 -p icmp --icmp-type 8 -j ACCEPT
Siehe auch:
Isoliertes Teilnetz nach dem Vorbild einer DMZ
Siehe dazu die Netzwerktopolgie unter http://pemmann.de/cc/Doc/dmz.png sowie die beiden folgenden iptables-Skripte:
Ausblick ip6fables / nftables
IPtabels für IPv6
Ausblick auf das neue Linux-Firewallbackend ‚ntfables‘
Softwarelösungen, die als „Reation System“ iptables-Regeln erzeuegn:
fail2ban, siehe http://spurtikus.de/computer/secserver.html
artillery, siehe https://n0where.net/artillery-project/
212.2 Securing FTP servers
Experimente mit chroot
ZIEL: Einrichtung eines Change-Root Jails
Eine chroot-Jail per Hand aufzusetzen, ist heutzutage nicht mehr ganz so einfach, weil die Daemons selbst schon ein eigenes mitbringen und ein Linken gegen externe Binaries nicht mehr erwünscht ist. Daher scheitern die folgenden Experimente auch, zeigen aber das grundsätzliche Verfahren sehr gut auf:
Die Lösung der Aufgabenstellung (aus Braindump):
$ cp /lib/x86_64-linux-gnu/{libwrap.so.0,libpam.so.0,libcap.so.2,libnsl.so.1,libaudit.so.1,libattr.so.1} /home/sam/jail/lib/x86_64-linux-gnu/
$ mkdir /home/sam/jail/usr/lib/
$ cp /usr/lib/x86_64-linux-gnu/{libssl.so.1.0.0,libcrypto.so.1.0.0} /home/sam/jail/usr/lib/
Ohne Konfigurationsdatei gelingt das Starten des Daemons nicht: „500 OOPS: vsftpd: not configured for standalone, must be started from inetd“:
$ mkdir /home/sam/jail/etc
$ cat > /home/sam/jail/etc/vsftpd.conf <<EOF
# http://www.sigerr.org/linux/setup-vsftpd-custom-multiple-directories-users-accounts-ubuntu-step-by-step/
listen=YES
anonymous_enable=NO
local_enable=YES
write_enable=YES
local_umask=022
nopriv_user=vsftpd
virtual_use_local_privs=YES
guest_enable=YES
user_sub_token=$USER
local_root=/var/www/$USER
chroot_local_user=YES
hide_ids=YES
guest_username=vsftpd
EOF
$ /usr/sbin/chroot /home/sam/jail /usr/sbin/vsftpd
^C
$
Was zu zeigen war: Der FTP Daemon läuft…
Er ist zwar noch nicht benutzbar („cannot locate user specified in ‚guest_username‘:vsftpd“ bei einem ‚ftp localhost‘), ist aber als Daemon in der chroot-Umgebung aktiv und hat dort seine Konfigurationsdatei selbständig gefunden.
Ausflug in die verkehrte Welt:
$ mv /home/sam/jail/lib/x86_64-linux-gnu/libc.so.6 /tmp
$
$ /usr/sbin/chroot /home/sam/jail /usr/sbin/vsftpd
/usr/sbin/vsftpd: error while loading shared libraries: libc.so.6: cannot open shared object file: No such file or directory
$
$ ln -s /lib/x86_64-linux-gnu/libc.so.6 /home/sam/jail/lib/x86_64-linux-gnu/libc.so.6
$
$ /usr/sbin/chroot /home/sam/jail /usr/sbin/vsftpd
/usr/sbin/vsftpd: error while loading shared libraries: libc.so.6: cannot open shared object file: Error 40
$
Wiederherstellen des korrekten Zustands:
$ rm /home/sam/jail/lib/x86_64-linux-gnu/libc.so.6
$ cp /lib/x86_64-linux-gnu/libc.so.6 /home/sam/jail/lib/x86_64-linux-gnu/
$
$ /usr/sbin/chroot /home/sam/jail /usr/sbin/vsftpd
^C
$
Alles klar…?
Einrichten von chroot mit vsftpd
ZIEL: Praktisches Zurverfügungstellen eines FTP-Servers mit chroot-Verzeichnis
=> AUF DEM SERVER ‚dns2‘ (in DMZ)
$ vi /etc/vsftpd.conf
AKTIVIEREN VON:
write_enable=YE
chroot_local_user=YES
Im Endeffekt sieht die Konfiguration folgendermaßen aus (grep -v ^# /etc/vsftpd.conf
):
listen=NO
listen_ipv6=YES
anonymous_enable=NO
local_enable=YES
write_enable=YE
dirmessage_enable=YES
use_localtime=YES
xferlog_enable=YES
connect_from_port_20=YES
chroot_local_user=YES
secure_chroot_dir=/var/run/vsftpd/empty
pam_service_name=vsftpd
rsa_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
rsa_private_key_file=/etc/ssl/private/ssl-cert-snakeoil.key
ssl_enable=NO
Nach einem Einlesen der geänderten Konfiguration mit systemctl restart vsftpd
testen wir gleich mit dem lokalen Host als Client:
root@dns2:~# ftp localhost
Connected to localhost.
220 (vsFTPd 3.0.2)
Name (localhost:tux): tux
331 Please specify the password.
Password:
500 OOPS: vsftpd: refusing to run with writable root inside chroot()
Login failed.
ftp>
Wo liegt das PROBLEM? Es handelt sich wohl tatsächlich eher um ein Feature als um einen Bug. Grund ist, dass das Wurzelverzeichnis ‚/home/tux‘ jetzt kein Schreibrecht mehr haben darf! Wir beheben es auf folgende Weise:
$ chmod -w /home/tux
$ mkdir /home/tux/Writing
$ chown tux: /home/tux/Writing
Nun können auf dem Server leider nur noch unter ‚~/Writing‘ Daten schreibend abgelegt werden:
root@dns2:~# ftp localhost
Connected to localhost.
220 (vsFTPd 3.0.2)
Name (localhost:tux): tux
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp>
ftp> cd Writing
250 Directory successfully changed.
ftp>
ftp> mkdir ABC
257 "/Writing/ABC" created
ftp>
ftp> ls
200 EPRT command successful. Consider using EPSV.
150 Here comes the directory listing.
drwx------ 2 1000 1000 4096 Mar 17 13:12 ABC
226 Directory send OK.
ftp>
ftp> by
221 Goodbye.
root@dns2:~#
Es gibt für dieses Problem Patches, durch die eine Einstellung allow_writeable_chroot=YES
möglich wird, was wohl aber nicht alle Distributionen aus Sicherheitsgründen für gut heißen.
Pure-FTPD
Diese eben geschilderten Probleme vom vsftp-Daemon sind natürlich kein Zustand, wenn es sich um die Heimatverzeichisse von realen Benutzern handelt. Dann empfiehlt es sich, einen Blick auf den pure-ftpd zu werfen:
212.3 Secure shell (SSH)
ZIEL: ssh gegen Brute-Force Angriffe einsetzen und härten
SSH-Tunnel für HTTP
ZIEL: Sambas swat-Konfigurationswerkzeug über einen sicheren SSH-Tunnel absichern
Auf dem ‚zielserver‘ läuft Samba 3.0 mit aktiviertem Swat-Frontend:
Als normaler Benutzer von der Workstation aus einen sicheren Tunnel aufbauen:
$ ssh -L 9901:localhost:901 zielserver
Im Web-Browser von der Workstation aus die verschlüsselte Verbindung zum swat-Frontend herstellen:
Prinzipiell lässt sich auf diese Art lässt sich jede HTTP-Kommunikation absichern, so könnte man z.B. aus dem Verzeichnis ~/public_html
heraus mit
$ python -m SimpleHTTPServer
einen Webserver starten, der am Port 8000 lauscht. Der Clientzugriff kann dann via Tunnel geschehen:
$ ssh -L 8888:localhost:8000 zielserver
$ wget http://localhost:8888/my-important-file.txt
Reverse SSH-Tunnel
Diese Art von Tunnel benötigt man, wenn andersherum als üblich der Server zum Client eine Verbindung z.B. für die Fernadministration aufbauen möchte. Dafür benötigt man die ssh-Option: ‚-R‘.
Weiterführende Dokumente:
ssh-Hostschlüssel
Fingerabdruck von Host-Keys ausgeben
$ ssh-keygen -l -f /etc/ssh/ssh_host_rsa_key.pub
2048 30:1b:5b:5a:9e:99:a7:5c:8a:9f:6b:41:e9:7e:d3:9c ssh_host_rsa_key.pub (RSA)
Neue Schlüsselpaare erzeugen, hier nur für RSA:
$ cd /etc/ssh
$ cp ssh_host_rsa_key* /root
$
$ ssh-keygen -t rsa -b 4096 -N "" -f ssh_host_rsa_key.pub
Generating public/private rsa key pair.
ssh_host_rsa_key.pub already exists.
Overwrite (y/n)? y
Your identification has been saved in ssh_host_rsa_key.pub.
Your public key has been saved in ssh_host_rsa_key.pub.pub.
The key fingerprint is:
41:a6:be:ea:f0:0b:aa:17:b3:7b:4e:ae:25:4e:84:6b root@d8master
The key's randomart image is:
+---[RSA 4096]----+
| o |
| + |
| . . |
| . . . |
|. . . S |
| oo . |
|.E=+o . |
|.+oO.. |
|+.+*B. |
+-----------------+
$
$ systemctl restart ssh
$
$ ssh-keygen -l -f ssh_host_rsa_key.pub
4096 41:a6:be:ea:f0:0b:aa:17:b3:7b:4e:ae:25:4e:84:6b ssh_host_rsa_key.pub.pub (RSA)
Clientseitig eine bestimmte Verschlüsselung anfordern
Soll z.B. nicht ECDSA sondern RSA verwendet werden, schreibt man:
$ ssh -o HostKeyAlgorithms=ssh-rsa-cert-v01@openssh.com,ssh-dss-cert-v01@openssh.com,ssh-rsa-cert-v00@openssh.com,ssh-dss-cert-v00@openssh.com,ssh-rsa,ssh-dss tux@localhost
Bei neueren ssh-Implementationen lässt sich dies kürzer mit -o HostKeyAlgorithms=ssh-rsa
erreichen.
Serverseitig nur bestimmte Schlüssel anbieten
Dazu müssen wir nur diejenigen auskommentieren, nicht mehr an Clients ausgeliefert werden sollen: vi /etc/ssh/sshd_config
# What ports, IPs and protocols we listen for
Port 22
# Use these options to restrict which interfaces/protocols sshd will bind to
#ListenAddress ::
#ListenAddress 0.0.0.0
Protocol 2
# HostKeys for protocol version 2
HostKey /etc/ssh/ssh_host_rsa_key
##HostKey /etc/ssh/ssh_host_dsa_key
##HostKey /etc/ssh/ssh_host_ecdsa_key
##HostKey /etc/ssh/ssh_host_ed25519_key
Nun müssen wir noch einmal die Konfiguration neu einlesen:
$ systemctl restart sshd
212.4 Security tasks
fail2ban - ein Intrusion Prevention System (IPS)
ZIEL: Einbruchsversuche anhand von Logeinträgen erkennen und abwehren
Literatur:
https://www.thomas-krenn.com/de/wiki/SSH_Login_unter_Debian_mit_fail2ban_absichern
https://decatec.de/home-server/owncloud-mit-fail2ban-absichern/
Die Installation erfolgt zuerst auf der inneren Firewall:
$ apt-get install fail2ban
$ cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
Die Konfigurationsdatei ist dann die Datei ‚/etc/fail2ban/jail.local‘.
Inbetriebnahme mit Voreinstellungen
root@d8fw2:/etc/fail2ban# grep 'enabled' /etc/fail2ban/jail.local | grep true
# enabled = true
enabled = true
root@d8fw2:/etc/fail2ban#
root@d8fw2:/etc/fail2ban# pgrep -a fail
1259 /usr/bin/python /usr/bin/fail2ban-server -b -s /var/run/fail2ban/fail2ban.sock -p /var/run/fail2ban/fail2ban.pid
root@d8fw2:/etc/fail2ban#
root@d8fw2:/etc/fail2ban#
root@d8fw2:/etc/fail2ban# systemctl restart fail2ban
root@d8fw2:/etc/fail2ban#
root@d8fw2:/etc/fail2ban# ls -l /var/log/fail2ban.log
-rw-r----- 1 root adm 1743 Dez 12 10:58 /var/log/fail2ban.log
root@d8fw2:/etc/fail2ban#
root@d8fw2:/etc/fail2ban# tail -f /var/log/fail2ban.log
2016-12-12 10:58:41,558 fail2ban.server [1259]: INFO Exiting Fail2ban
2016-12-12 10:58:42,009 fail2ban.server [1373]: INFO Changed logging target to /var/log/fail2ban.log for Fail2ban v0.8.13
2016-12-12 10:58:42,010 fail2ban.jail [1373]: INFO Creating new jail 'ssh'
2016-12-12 10:58:42,023 fail2ban.jail [1373]: INFO Jail 'ssh' uses pyinotify
2016-12-12 10:58:42,035 fail2ban.jail [1373]: INFO Initiated 'pyinotify' backend
2016-12-12 10:58:42,036 fail2ban.filter [1373]: INFO Added logfile = /var/log/auth.log
2016-12-12 10:58:42,037 fail2ban.filter [1373]: INFO Set maxRetry = 6
2016-12-12 10:58:42,038 fail2ban.filter [1373]: INFO Set findtime = 600
2016-12-12 10:58:42,038 fail2ban.actions[1373]: INFO Set banTime = 600
2016-12-12 10:58:42,062 fail2ban.jail [1373]: INFO Jail 'ssh' started
--->> Zwischenzeitlich versuchen sich Personen von den Maschinen
10.1.1.2 sowie 10.20.30.5 mit falschem Benutzername/Passwort einzuloggen <<---
2016-12-12 11:01:52,351 fail2ban.actions[1373]: WARNING [ssh] Ban 10.1.1.2
2016-12-12 11:04:59,651 fail2ban.actions[1373]: WARNING [ssh] Ban 10.20.30.5
Zusätzlich zu den eigenen Firewallregeln schreibt ‚fail2ban‘ die beiden letzteren Zeilen:
root@d8fw2:/etc/fail2ban# iptables -vnL
Chain INPUT (policy DROP 2 packets, 484 bytes)
pkts bytes target prot opt in out source destination
253 25016 fail2ban-ssh tcp -- * * 0.0.0.0/0 0.0.0.0/0 multiport dports 22
0 0 ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0
1934 1243K ACCEPT all -- eth0 * 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
32 5258 ACCEPT all -- eth1 * 0.0.0.0/0 0.0.0.0/0
2 120 ACCEPT tcp -- eth0 * 0.0.0.0/0 0.0.0.0/0 tcp dpt:22
24 5808 LOG all -- * * 0.0.0.0/0 0.0.0.0/0 limit: avg 5/min burst 7 LOG flags 0 level 6 prefix "iptables: "
Chain FORWARD (policy ACCEPT 1 packets, 76 bytes)
pkts bytes target prot opt in out source destination
5077 506K ACCEPT all -- eth1 * 0.0.0.0/0 0.0.0.0/0
Chain OUTPUT (policy DROP 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 ACCEPT all -- * lo 0.0.0.0/0 0.0.0.0/0
1337 241K ACCEPT all -- * eth0 0.0.0.0/0 0.0.0.0/0 state NEW,RELATED,ESTABLISHED
63 7650 ACCEPT all -- * eth1 0.0.0.0/0 0.0.0.0/0
0 0 LOG all -- * * 0.0.0.0/0 0.0.0.0/0 LOG flags 0 level 4 prefix "iptables-out: "
Chain fail2ban-ssh (1 references)
pkts bytes target prot opt in out source destination
0 0 REJECT all -- * * 10.20.30.5 0.0.0.0/0 reject-with icmp-port-unreachable
24 1992 REJECT all -- * * 10.1.1.2 0.0.0.0/0 reject-with icmp-port-unreachable
229 23024 RETURN all -- * * 0.0.0.0/0 0.0.0.0/0
root@d8fw2:/etc/fail2ban#
root@d8fw2:/etc/fail2ban# fail2ban-client -v status ssh
INFO Using socket file /var/run/fail2ban/fail2ban.sock
Status for the jail: ssh
|- filter
| |- File list: /var/log/auth.log
| |- Currently failed: 1
| `- Total failed: 12
`- action
|- Currently banned: 0
| `- IP list:
`- Total banned: 1
root@d8fw2:/etc/fail2ban# fail2ban-client -v status ssh
INFO Using socket file /var/run/fail2ban/fail2ban.sock
Status for the jail: ssh
|- filter
| |- File list: /var/log/auth.log
| |- Currently failed: 0
| `- Total failed: 13
`- action
|- Currently banned: 1
| `- IP list: 10.20.30.5
`- Total banned: 2
root@d8fw2:/etc/fail2ban#
Manuelles Aufheben der Verbannung:
root@d8fw2:/etc/fail2ban# fail2ban-client set ssh unbanip 10.20.30.5
10.20.30.5
root@d8fw2:/etc/fail2ban#
root@d8fw2:/etc/fail2ban#
root@d8fw2:/etc/fail2ban#
root@d8fw2:/etc/fail2ban# fail2ban-client -v status ssh
INFO Using socket file /var/run/fail2ban/fail2ban.sock
Status for the jail: ssh
|- filter
| |- File list: /var/log/auth.log
| |- Currently failed: 0
| `- Total failed: 13
`- action
|- Currently banned: 0
| `- IP list:
`- Total banned: 2
root@d8fw2:/etc/fail2ban#
Weiterführende Links:
212.5 OpenVPN
Siehe dazu unter das Dokument VPN mit SSL: OpenVPN.