[HowTo] Absicherung und Administration eines Linux-Servers (Stand: 29. 11. 2015)

Jimini

PCGH-Community-Veteran(in)
Aloha,

da das Interesse an Servern immer mehr zunimmt, steigt natürlich auch der Anteil derer, die neu in diesem Umfeld sind. Zusammen mit dem Umstand, dass virtuelle Server mittlerweile a) recht potent und b) ziemlich bezahlbar sind, ergibt das natürlich eine steigende Anzahl von Systemen, die an einer fetten Anbindung im Netz hängen, aber ziemlich ungeschützt sind. Das Ergebnis ist quasi der Traum eines Crackers / Spam-Versenders etc.
Da das Absichern eines Linux-Systems zwar komplex, aber keineswegs ein Buch mit sieben Siegeln ist, habe ich hier einen Guide mit den wichtigsten Schritten erstellt. Die meisten dieser Schritte lassen sich natürlich auch auf einen Homeserver übertragen - ein solcher sollte ebenso wie ein "öffentlicher" vServer anständig konfiguriert und abgesichert sein. Als Betriebssystem verwende ich Debian 7.6 (Wheezy), die Schritte lassen sich aber größtenteils auf jede andere gängige Linux-Distribution übertragen.

Dieser Guide setzt grundlegende Linux- und Netzwerk-Kenntnisse voraus - ihr solltet also etwa wissen, wie man eine Shell bedient und wie man eine Konfigurationsdatei editiert.

1 - Konzept und Vorbereitungen
In diesem Teil gehe ich auf die Vorbereitung und die Planung eines entsprechenden Systems ein.

2 - Konfiguration
Der mit Abstand umfangreichste Teil. Hier richten wir alle Dienste so ein, dass sie dauerhaft lauffähig sind.

3 - Routineaufgaben
Mit der Installation und Einrichtung verschiedener Daemons ist es nicht getan - die "echte" Administration geht jetzt erst los.

1 - Konzept und Vorbereitungen

Die für mich fast wichtigsten Utensilien beim Aufsetzen eines Serversystems sind Papier und Stift. In seltenen Fällen läuft alles auf Anhieb und da man ebenso selten alles in einem Rutsch erledigt, sind Notizen verdammt nützlich und sinnvoll.
Ich lege mir für solche Situationen immer eine Liste der zu installierenden Software an, welche ich dann nach und nach abarbeite.

Ich gehe an dieser Stelle davon aus, dass ein entsprechendes System bereits beschafft bzw. zur Verfügung gestellt wurde. Im Falle eines Homeservers ist die Linux-Distribution der Wahl installiert, haben wir einen vServer gemietet, so wurden uns die Zugangsdaten zur Verfügung gestellt und wir können uns als root auf dem System einloggen.

2 - Konfiguration

Wir haben uns also auf dem neuen System eingeloggt und verfügen über alle Rechte, die wir brauchen.

2.1 - Nutzerkonten
Handelt es sich um einen gemieteten Server, ändern wir als allererstes das root-Passwort durch das Ausführen von passwd. Danach legen wir mittels
adduser benutzername einen unprivilegierten Benutzer an. Möchten wir (weiterhin) sudo nutzen, fügen wir den soeben neu angelegten Nutzer mit addgroup benutzername sudo zur Gruppe "sudo" hinzu.

Es folgt ein Test dahingehend, ob sich der neu angelegte Nutzer via SSH auf dem System einloggen und mittels sudo root-Rechte erlangen kann.


2.2 - Netzwerkkonfiguration bearbeiten (gilt nur für Homeserver)
Wenn der Server zuhause steht, ist es sinnvoll, ihm eine feste IP-Adresse zuzuweisen. Je nach verwendeter Linux-Distribution unterscheiden sich die Config-Files sehr stark.

Erstes Beispiel für Debian / Ubuntu: /etc/network/interfaces
Code:
auto lo
iface lo inet loopback

auto eth0
iface eth0 inet static
        address 10.0.0.10
        netmask 255.255.255.0
        gateway 10.0.0.1
Hier wird nur ein Netzwerkinterface (10.0.0.10) genutzt. Dieses stellt über einen Router (10.0.0.1) eine Internetverbindung her.

Zweites Beispiel für Debian / Ubuntu: /etc/network/interfaces
Code:
auto lo
iface lo inet loopback

auto eth0
iface eth0 inet dhcp

auto eth1
iface eth1 inet static
        address 10.0.0.1
        netmask 255.255.255.0
eth0 stellt hierbei die Internetverbindung her (bei einer Kabel-Anbindung geschieht das einfach über DHCP) und eth1 (10.0.0.1) bindet das System an das interne Netzwerk an.

Die Änderungen werden anschließend mit
/etc/init.d/networking restart übernommen und - oh Wunder - auch hier folgt wieder ein Test (beispielsweise durch das Pingen einer Domain).


2.3 - SSHd absichern #1: root-Zugang deaktivieren

Als nächstes konfigurieren wir den SSHd so, dass ein SSH-Login auf root nicht mehr möglich ist. Dazu öffnen wir /etc/ssh/sshd_config und ändern die Zeile PermitRootLogin yes auf PermitRootLogin no. Durch das Neustarten des SSHd (/etc/init.d/ssh restart) werden die Änderungen übernommen.
Auch hier testen wir, ob ein root-Zugang via SSH noch möglich ist und - ganz wichtig - ob der soeben neu angelegte Nutzer nach wie vor auf das System kommt.

2.4 - SSHd absichern #2: Port ändern
Es empfiehlt sich zudem, den SSHd nicht auf dem Standardport 22 laufen zu lassen. Natürlich bringt eine solche Maßnahme keine absolute Sicherheit mit sich - man erspart sich aber Tausende von Logeinträgen durch Bots, welche a) nach Systemen mit offenem Port 22 suchen und b) dort dann versuchen, Zugang zu erlangen. Um den verwendeten Port zu ändern, bearbeiten wir einfach wieder /etc/ssh/sshd_config und wählen einen anderen Port.
Auch hier empfiehlt sich nach einem Neustart des SSHd ein Test.

2.5 - SSHd absichern #3: Public-Key-Auth
Noch sicherer wird es, wenn man sich nicht mehr mit einem Passwort, sondern nur noch mit einem Keyfile einloggen kann. Eigentlich sind es genau genommen zwei Keys - ein privater und ein öffentlicher. Der private Key liegt lokal auf dem Rechner, von dem aus wir uns auf dem Server einloggen wollen. Der öffentliche wurde auf dem Server hinterlegt. Wollen wir nun eine Verbindung herstellen, müssen wir uns mit einem Passwort gegenüber dem private Key authentifizieren. Daraufhin wird der private Key mit der Liste der erlaubten Keys auf dem Server verglichen und eine Verbindung gestattet oder abgelehnt.

Hierzu generieren wir mittels ssh-keygen einen Key. Möchte man kein Passwort eingeben - was nicht empfehlenswert ist - so lässt man dieses leer. Als nächstes muss der Public Key (in der Regel im jeweiligen Homeverzeichnis unter ~/.ssh/id-rsa.pub) auf dem Zielsystem in ~./ssh/authorized_keys des vorhin eingerichteten Benutzers kopiert werden.
Natürlich testen wir hier auch wieder, ob ein Login unter Verwendung des Keys sauber funktioniert.

Danach konfigurieren wir den SSHd so, dass ein Login unter Verwendung eines Passworts nicht mehr möglich ist, sondern nur noch das Pubkey-Verfahren akzeptiert wird. Hierzu muss die Option "PubkeyAuthentication" auf "yes" gesetzt sein sowie "PasswordAuthentication" auf "no".
Auch hier empfehle ich dringend einen Test - am besten einmal als Nutzer, welcher im Besitz des Keys ist und einmal als anderer Nutzer. Dieser sollte dann die Fehlermeldung "Permission denied (publickey)." erhalten, während sich der Nutzer mit dem gültigen Key einloggen kann.

2.6 - Updates installieren
Als nächstes sollte die installierte Software auf den neusten Stand gebracht werden. Bei einem Homeserver sollte diese schon größtenteils aktuell sein, bei vServern hingegen sind die installierten Pakete erschreckend oft (sehr) veraltet. Dies kann man mit apt-get update und anschließendem apt-get dist-upgrade beheben. Sollte dabei der Kernel aktualisiert werden, sollten wir das System sicherheitshalber rebooten.

2.7 - Firewall mit iptables
Meiner Meinung nach sollte jedes Linux-System, welches direkt am Netz hängt und / oder sensible Daten beherbergt, mit iptables abgesichert werden. Die iptables stellen ein Frontend zu den netfilter-Modulen im Linux-Kernel dar. Die im nächsten Schritt zu schreibenden Firewall-Regeln haben das Ziel, nur als erlaubt definierten Traffic durchzulassen. Alles andere wird geblockt / verworfen. Auf den meisten Systemen ist iptables bereits installiert.

Als Grundlage für die Firewall auf einem routenden Homeserver kann folgendes Skript dienen:
Code:
#!/bin/bash

### KERNEL-OPTIONEN

# Antispoofing
echo "1" > /proc/sys/net/ipv4/conf/all/arp_filter
echo "1" > /proc/sys/net/ipv4/conf/all/rp_filter

# martian packets loggen?
echo "0" > /proc/sys/net/ipv4/conf/all/log_martians

# ICMP Redirects verweigern
echo "0" > /proc/sys/net/ipv4/conf/all/accept_redirects
echo "0" > /proc/sys/net/ipv4/conf/all/send_redirects

# Source Routing deaktivieren
echo "0" > /proc/sys/net/ipv4/conf/all/accept_source_route

# ICMP Broadcast Echos ignorieren
echo "1" > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts

# Bogus ICMP-Errors ignorieren
echo "1" > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses 

# Forwarding aktivieren (wird nur benötigt, wenn das System routet)
echo "1" > /proc/sys/net/ipv4/ip_forward

### GENERELLE EINSTELLUNGEN

lan="eth1"
wan="eth0"
intern=10.0.0.0/24

### FILTERREGELN

# Vorhandene Tabellen löschen (die nat-Zeile wird nur benötigt, wenn das System routet)
iptables -F
iptables -t nat -F
iptables -t mangle -F 

# Default-Policy: alles droppen
iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -P FORWARD DROP

# Default-Policy: alles natten, erst beim Filtern verwerfen (wird nur benötigt, wenn das System routet)
iptables -t nat -P PREROUTING ACCEPT
iptables -t nat -P POSTROUTING ACCEPT
iptables -t nat -P OUTPUT ACCEPT

# Akzeptiere Verbindungsaufbauten aus dem LAN  (wird nur benötigt, wenn das System routet)
iptables -A FORWARD -s $intern -i $lan -o $wan -j ACCEPT

# Akzeptiere alle Pakete, die zu einer aufgebauten Verbindung gehören
iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# Akzeptiere lokalen Traffic
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT

# Alle Pakete bei der Weiterleitung nach aussen maskieren (wird nur benötigt, wenn das System routet)
iptables -t nat -A POSTROUTING -o $wan -j MASQUERADE

# DNS (das System darf DNS-Verbindungen zu zwei Systemen aufbauen)
iptables -A OUTPUT -d 1.2.3.4,5.6.7.8 -p tcp --dport 53 -j ACCEPT
iptables -A OUTPUT -d 1.2.3.4,5.6.7.8 -p udp --dport 53 -j ACCEPT

# FTP (das System darf FTP-Verbindungen zu zwei Systemen aufbauen)
iptables -A OUTPUT -p tcp -d 1.2.3.4 --dport 21 -m state --state NEW -j ACCEPT
iptables -A OUTPUT -p tcp -d 5.6.7.8 --dport 21 -m state --state NEW -j ACCEPT

# HTTP
iptables -A INPUT -p tcp --sport 80 -m state --state NEW -j ACCEPT
iptables -A OUTPUT -p tcp --dport 80 -j ACCEPT

# HTTPS
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
iptables -A OUTPUT -p tcp --sport 443 -j ACCEPT

# NTP
iptables -A OUTPUT -p udp -d 1.2.3.4 --dport 123 -j ACCEPT

# SSH (läuft auf 10.0.0.1 auf Port 12345, Anfragen von 1.2.3.4 werden zugelassen und direkt auf den richtigen Port weitergeleitet)
iptables -A INPUT -p tcp -s 1.2.3.4 --dport 22 -j ACCEPT
iptables -t nat -A PREROUTING -s 1.2.3.4 -p tcp --dport 22 -j DNAT --to 10.0.0.1:12345
iptables -A INPUT -p tcp --dport 12345 -m conntrack --ctstate NEW -j ACCEPT

### LOGGING

# alles, was durch die vorherigen Regeln nicht erfasst wurde, wird  abgewiesen (rejected) und geloggt (sehr nützlich für die anfängliche  Fehlersuche)
iptables -A INPUT -j LOG --log-prefix "DROPPED_INPUT: " --log-level=5
iptables -A INPUT -j REJECT
iptables -A OUTPUT -j LOG --log-prefix "DROPPED_OUTPUT: " --log-level=5
iptables -A OUTPUT -j REJECT
iptables -A FORWARD -j LOG --log-prefix "DROPPED_FORWARD: " --log-level=5
iptables -A FORWARD -j REJECT

### Speichern der Regeln
iptables-save > /etc/iptables.conf


Für einen vServer wird das Skript etwas abgeändert:
Code:
#!/bin/bash

### KERNEL-OPTIONEN

# Antispoofing
echo "1" > /proc/sys/net/ipv4/conf/all/arp_filter
echo "1" > /proc/sys/net/ipv4/conf/all/rp_filter

# martian packets loggen?
echo "0" > /proc/sys/net/ipv4/conf/all/log_martians

# ICMP Redirects verweigern
echo "0" > /proc/sys/net/ipv4/conf/all/accept_redirects
echo "0" > /proc/sys/net/ipv4/conf/all/send_redirects

# Source Routing deaktivieren
echo "0" > /proc/sys/net/ipv4/conf/all/accept_source_route

# ICMP Broadcast Echos ignorieren
echo "1" > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts

# Bogus ICMP-Errors ignorieren
echo "1" > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses 

### FILTERREGELN

# Vorhandene Tabellen löschen
iptables -F
iptables -t mangle -F

# Default-Policy: alles droppen
iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -P FORWARD DROP

# Akzeptiere alle Pakete, die zu einer aufgebauten Verbindung gehören
iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# Akzeptiere lokalen Traffic
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT

# DNS (das System darf DNS-Verbindungen zu zwei Systemen aufbauen)
iptables -A OUTPUT -d 1.2.3.4,5.6.7.8 -p tcp --dport 53 -j ACCEPT
iptables -A OUTPUT -d 1.2.3.4,5.6.7.8 -p udp --dport 53 -j ACCEPT

# FTP (das System darf FTP-Verbindungen zu zwei Systemen aufbauen)
iptables -A OUTPUT -p tcp -d 1.2.3.4 --dport 21 -m state --state NEW -j ACCEPT
iptables -A OUTPUT -p tcp -d 5.6.7.8 --dport 21 -m state --state NEW -j ACCEPT

# HTTP
iptables -A INPUT -p tcp --sport 80 -m state --state NEW -j ACCEPT
iptables -A OUTPUT -p tcp --dport 80 -j ACCEPT

# HTTPS
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
iptables -A OUTPUT -p tcp --sport 443 -j ACCEPT

# NTP
iptables -A OUTPUT -p udp -d 1.2.3.4 --dport 123 -j ACCEPT

# SSH (läuft auf 10.0.0.1 auf Port 12345, Anfragen von 1.2.3.4 werden zugelassen und direkt auf den richtigen Port weitergeleitet)
iptables -A INPUT -p tcp -s 1.2.3.4 --dport 22 -j ACCEPT
iptables -t nat -A PREROUTING -s 1.2.3.4 -p tcp --dport 22 -j DNAT --to 10.0.0.1:12345
iptables -A INPUT -p tcp --dport 12345 -m conntrack --ctstate NEW -j ACCEPT 

### LOGGING

# alles, was durch die vorherigen Regeln nicht erfasst wurde, wird abgewiesen (rejected) und geloggt (sehr nützlich für die anfängliche Fehlersuche)
iptables -A INPUT -j LOG --log-prefix "DROPPED_INPUT: " --log-level=5
iptables -A INPUT -j REJECT
iptables -A OUTPUT -j LOG --log-prefix "DROPPED_OUTPUT: " --log-level=5
iptables -A OUTPUT -j REJECT
iptables -A FORWARD -j LOG --log-prefix "DROPPED_FORWARD: " --log-level=5
iptables -A FORWARD -j REJECT

### Speichern der Regeln
iptables-save > /etc/iptables.conf

Egal für welche der beiden Versionen wir uns entscheiden - wir packen sie in eine Datei (beispielsweise /usr/bin/firewall_active) und machen diese mit chmod +x /usr/bin/firewall_active ausführbar. Bitte die Datei an dieser Stelle noch nicht ausführen!

Dazu erstellen wir noch ein Skript, welches die Firewall deaktiviert (konsequenterweise /usr/bin/firewall_inactive):
Code:
#!/bin/bash

# alle vorhandenen Regeln löschen
iptables -F
iptables -t nat -F
iptables -t mangle -F

# Default-Policies wiederherstellen
iptables -P INPUT ACCEPT
iptables -P OUTPUT ACCEPT
iptables -P FORWARD ACCEPT
Auch diese Datei machen wir ausführbar und führen sie testweise aus. Danach fügen wir in /etc/crontab folgenden Eintrag ein:
Code:
15       10       *       *       *       root    /usr/bin/firewall_inactive
"15" und "10" bewirken, dass um 10:15 die Firewall aktiviert wird. Ändert diese Werte so ab, dass das Skript stattdessen in 5 Minuten aufgerufen wird. Solltet ihr euch nämlich durch einen Fehler im Firewallskript aus dem System aussperren, so kommt ihr in 5 Minuten wieder rein.
Danach aktiviert ihr die Firewall und schaut, ob ihr nach wie vor auf das System zugreifen könnt.

Es ist natürlich sinnvoll, die Firewall direkt beim Systemstart zu aktivieren. Es gibt zwei Möglichkeiten:
1) das Aufrufen des Firewallskripts nach dem Bootvorgang durch einen entsprechenden Eintrag in /etc/rc.local
2) das Koppeln des Starts des Netztwerks mit der Aktivierung der Firewall (Anleitungen für Debian / Ubuntu / Gentoo)

Wenn ihr sichergehen wollt, dass das alles funktioniert, könnt ihr die Kiste an dieser Stelle rebooten.

2.8 - Logging
Das Logging wird gerne unterschätzt, ist aber ein sehr wichtiger Aspekt bei der Administration eines Serversystems. Für gewöhnlich ist schon ein Loggingdienst installiert, welcher seinen Ouput unter /var/log speichert. Wenn ihr das Syslog (meistens liegt das in /var/log/syslog oder /var/log/messages) während eurer Arbeit am System beobachtet, lassen sich frühzeitig Probleme erkennen. Ideal ist es, dazu eine weitere Shell zu öffnen und das Log mittels tail -f /var/log/syslog kontinuierlich im Blick zu haben.
Das Firewallskript weist iptables an, nicht erfasste Pakete nicht still und leise zu verwerfen, sondern dies zusätzlich im Log zu vermerken. Dies ist beispielsweise dann extrem nützlich, wenn ein frisch installierter Dienst nicht erreichbar ist oder sonstige Verbindungsversuche - etwa beim Download von Updates - fehlschlagen.

Insbesondere in den ersten "Lebenstagen" des Systems ist eine regelmäßige Analyse der Logs also nicht nur hilfreich, sondern dringend anzuraten.

2.9 - restliche Software
Nachdem ihr für ein sauberes und sicheres Grundsystem gesorgt habt, könnt ihr auch daran machen, weitere benötigte Software zu installieren und zu konfigurieren.

Quellen und weitere Infos:
- Ubuntu: Benutzer und Gruppen
- Debian-Benutzerverwaltung
- Nutzer hinzufügen unter Gentoo
- SSH-Public-Key-Authentifizierung
- Wikipedia-Artikel zur Public-Key-Authentifizierung
- Konfiguration des Netzwerks unter Debian / Ubuntu / Gentoo
- iptables-Artikel im Ubuntu-Wiki
- Logging-Artikel im Ubuntu-Wiki


3 - Routineaufgaben

Nachdem euer Server eingerichtet ist und zuverlässig seinen Dienst verrichtet, könnt ihr euch nun zurücklehnen - die Arbeit ist erledigt und ihr müsst euch von nun an um nichts mehr kümmern. Richtig? Falsch! :)
Die Administration eines Servers ist ein kontinuierlicher Prozess. Selbst wenn es keine Probleme gibt, müsst ihr damit rechnen, euch regelmäßig dem System widmen zu müssen, denn es gilt, immer wieder Routinearbeiten durchzuführen.

3.1 - Software aktuell halten
Die Sicherheit eures Systems steht und fällt mit der eingesetzten Software. Dies gilt inbesondere für Sicherheitslücken, welche immer wieder entdeckt werden und eine schnelle Reaktion des Admins erfordern. Gewöhnt euch daher an, regelmäßig zumindest die Sicherheitsupdates zu installieren.

3.2 - Backups
Sei es ein Festplattenausfall, ein Anwenderfehler oder gar ein erfolgreicher Angriff auf euer System - ein möglichst aktuelles Backup kann extrem viel Stress und Arbeit ersparen. Dies gilt nicht nur für einen Homeserver; Hoster bieten in der Regel Slots für Image-Backups an, dennoch ist es sinnvoll, sich unabhängig davon selbst um die Backups zu kümmern.
Legt daher nicht nur vor Arbeiten an wichtigen Konfigurationsdateien eine Sicherung selbiger an, sondern sichert die wichtigsten Daten regelmäßig auf ein zusätzliches System.

3.3 - Monitoring
Darüber hinaus ist es sehr empfehlenswert, regelmäßig den Zustand des Systems zu checken. Ist genügend Speicherplatz verfügbar (df -h)? Ist genügend freier Arbeitsspeicher vorhanden (free)? Läuft vielleicht ein Prozess Amok und lastet das System aus (top)? Ist die Temperatur der Festplatten in Ordnung (hddtemp)? Zudem sollte ein Blick in die Logs zur Gewohnheit werden.

3.4 - Informationen beschaffen
News zu Sicherheitslücken und andere wichtige Informationen erscheinen in der Regel sehr zeitnah. Schaut daher regelmäßig auf entsprechende News-Seiten oder abonniert die entsprechenden Mailinglisten eurer Distribution, um auf dem Laufenden zu bleiben.

Fazit

In dieser Anleitung habe ich dargestellt, welche grundsätzlichen Schritte empfehlenswert zur Einrichtung und Absicherung eines Linux-Serversystems sind. Ich habe mich hierbei auf Debian bezogen, das Konzept ist aber auf jedes Linux-System übertragbar. Ich werde diesen Thread dazu nutzen, in Kürze weitere Anleitungen zu posten - etwa zu empfehlenswerter Software, der Implementierung einer sinnvollen Backup-Strategie oder zur Möglichkeiten der Log-Analyse.

Auch wenn ich den Guide an einem frischen System auf seine Tauglichkeit hin überprüft habe, kann ich natürlich nicht ausschließen, dass mir ein Fehler unterlaufen ist. Tippt daher die hier vorgestellten Befehle und Skripts nicht blind ab, sondern denkt mit :)

Bei Fragen und Antworten stehe ich selbstverständlich gerne hier im Thread zur Verfügung.

MfG Jimini
 
Zuletzt bearbeitet:
AW: [HowTo] Absicherung eines Linux-Servers


Die Logs und die Auslastung eines Systems zu überwachen, indem man direkt auf dem System nachschaut, ist natürlich eine naheliegende Möglichkeit. Allerdings bringt dieses Vorgehen Nachteile mit sich: es ist zeitaufwändig, man verpasst wahrscheinlich die "interessanten" Ereignisse und man sieht dafür zu viele uninteressante Informationen. Für mich ist es ziemlich irrelevant, dass ClamAV seine Signaturen aktualisiert hat oder mein Smartphone sich mit dem WLAN verbunden hat. Dafür möchte ich natürlich Fehlermeldungen sehen. Oder um es in Facilities auszudrücken: Info- und Notice-Meldungen sind für mich vergleichsweise uninteressant, Error-, Alert- oder Emergency-Einträge hingegen möchte ich mitunter sofort mitbekommen.
Es zeigt sich somit, dass eine gewisse Automatisierung vonnöten ist, um ein System möglichst umfassend überwachen zu können. Ich werde daher im Folgenden einige Konzepte und Programme vorstellen, mit denen sich ein Linux-Server sehr gut im Auge behalten lässt, ohne dass der eigene egelmäßige Aufwand zu groß wird.

Kern des Setups bildet der Logging-Daemon, ich verwende hier eigentlich schon immer den syslog-ng. Dieser schreibt die Logs nicht nur nach /var/log, sondern packt die interessanten Facilities zusätzlich in eine MySQL-Datenbank. Deren Inhalte werden mit Hilfe von LogZilla über den Webserver bereitgestellt, so dass ich die Logs bequem im Browser aufrufen und filtern kann.
Dies gestaltet die Log-Analyse etwas komfortabler, erfordert aber nach wie vor etwas Aufwand - ideal wäre doch beispielsweise, wenn der Admin nicht auf gut Glück nachsehen muss, sondern der Server ihm die arbeit abnimmt und ihn gegebenenfalls informiert, oder? Genau das macht tenshi. tenshi beobachtet kontinuierlich die Logs des Systems und kann auf bestimmte Ereignisse mit bestimmten Aktionen reagieren. So bekomme ich sofort eine Mail zugeschickt, wenn jemand ein falsches root-Passwort eingibt oder die USV anspringt. Zusätzlich liefert mir tenshi einmal täglich eine Zusammenfassung der Logeinträge der letzten 24 Stunden. Über eine (riesige) Config-Datei habe ich dabei all jene Meldungen definiert, welche für mich nicht von Interesse sind - so bekomme ich einmal täglich wirklich nur die Meldungen, welche ich wirklich haben möchte und / oder welche ich noch nicht definiert habe.

Einen Schritt weiter gehen große Monitoringsysteme wie Zabbix, Nagios oder Icinga. Hiermit können so gut wie alle Parameter eines Systems überwacht werden - sei es die Festplattentemperatur, verfügbare Updates, die Anzahl der TCP-Verbindungen auf einem bestimmten Port, SMART-Parameter oder der Tintenstand des angeschlossenen Druckers. Auch hier kann selbstverständlich auf ein bestimmtes Ereignis mit einer bestimmten Aktion reagiert werden. Simplere Lösungen wie etwa linux-dash oder phpsysinfo kommen mit einem schmaleren Funktionsumfang daher, sind dafür aber auch innerhalb weniger Minuten eingerichtet und nutzbar.

Ich logge mich mittlerweile nur noch auf meinen Servern ein, wenn es ein Problem gibt oder Updates installiert werden wollen - Log-Analyse und Monitoring arbeiten von alleine und informieren mich selbstständig, wenn es was zu tun gibt.

Hinweis: um uns während der Installation das ständige Bearbeiten des iptables-Skripts zu ersparen, können wir für die Dauer der Einrichtung die Output-Default-Policy auf "ACCEPT" setzen.


Logging mit syslog-ng

Eine grundlegende Voraussetzung für brauchbare Logs ist, dass die Systemzeit korrekt ist. Hierzu kann man auf NTP zurückgreifen, was unter Debian und verwandten Systemen mittels apt-get install ntp in wenigen Augenblicken installiert und einsatzbereit ist. Danach wird der Logging-Daemon installiert. Natürlich kann jeder beliebige Logging-Daemon verwendet werden, da ich aber schon immer auf den syslog-ng setze, werde ich die Konfiguration an seinem Beispiel darstellen.
Code:
@version: 3.3
@include "scl.conf"
@include "`scl-root`/system/tty10.conf"

options {
        chain_hostnames(no);
        check_hostname(no);
        keep_hostname(yes);
        stats_freq(0);
        mark_freq(0);
        use_fqdn(yes);
};

source src_local        { unix-stream("/dev/log" max-connections(256)); internal(); file("/proc/kmsg"); tcp(); udp(); };
source src_remote       { udp ( ip(10.0.0.1) port(514) ); };
source kernsrc          { file("/proc/kmsg"); };

destination authlog     { file("/var/log/auth.log" owner("root") perm(0644) ); };
destination debug       { file("/var/log/debug.log" owner("root") perm(0644) );  };
destination mysql       { sql(type(mysql) host("localhost")  username("db_user") password("db_passwort") database("syslog")  table("logs") columns("host", "facility", "priority", "level", "tag",  "program", "msg", "fo", "lo") values("$HOST", "$FACILITY", "$PRIORITY",  "$LEVEL", "$TAG", "$PROGRAM", "$MSG",  "$YEAR-$MONTH-$DAY\t$HOUR:$MIN:$SEC",  "$YEAR-$MONTH-$DAY\t$HOUR:$MIN:$SEC") indexes("host", "facility",  "priority", "program", "fo", "lo")); };
destination mail        { file("/var/log/mail.log" owner("root") perm(0644)); };
destination messages    { file("/var/log/messages" owner("root") perm(0644)); };

filter f_auth           { facility(auth, authpriv); };
filter f_auth_mail_msg  { facility(auth, authpriv, mail) and level(warn...emerg); };
filter f_mail           { facility(mail); };
filter f_messages       { level(info..emerg) and not facility(auth, authpriv, mail); };

log { source(src_local); filter(f_auth); destination(authlog); };
log { source(src_local); filter(f_mail); destination(mail); };
log { source(src_local); filter(f_messages); destination(mysql); destination(messages); };
log { source(src_local); filter(f_auth_mail_msg); destination(mysql); destination(messages); };
log { source(src_remote); destination(mysql); destination(messages); };
Da die Config auf den ersten Blick etwas kompliziert aussieht, will ich sie kurz erklären:
- Zuerst werden grundlegende Optionen festgelegt. Diese (und andere) sind hier erklärt.
- Danach werden die Quellen für Log-Einträge angegeben. Ich habe neben dem Socket /dev/log und dem Log-Output des Kernel /proc/kmsg noch den Ausgang eines SSH-Tunnels definiert.
- Der nächste Block teilt syslog-ng mit, wohin geloggt werden soll. Ich logge in verschiedene Dateien und in eine MySQL-Datenbank.
- Die Filter legen fest, was überhaupt geloggt werden soll.
- Schließlich werden für verschiedene Quellen verschiedene Ziele festgelegt - man sieht hier beispielsweise, dass ich nicht alles in die Datenbank logge.
Wichtig: die "remote"-Zeilen werden nur benötigt, wenn wir die Logs von verschiedenen Systemen auf diesem Server sammeln. Ist das nicht der Fall, löschen wir die beiden Zeilen. Gleiches gilt für die "mysql"-Zeilen - diese brauchen wir nur, wenn wir in die Logs in eine Datenbank schreiben lassen wollen.

Log-Analyse mit LogZilla
Der nächste Schritt zu bequemeren Log-Analyse ist das Verfügbarmachen über den Webserver - ich verwende Apache. Dieser sollte daher natürlich nicht nur installiert sein (apt-get install apache2), sondern auch Zugriffe ermöglichen (ggf. iptables-Regeln anpassen!). Wenn unser System also über einen Browser erreichbar ist, geht's weiter.

Zunächst fügen wir folgende Zeile in /etc/apt/sources.list ein:
Code:
deb http://ftp.uk.debian.org/debian/ wheezy contrib non-free
Danach führen wir folgende apt-get update und apt-get install php5 php5-gd php5-mysql aus.
Den Parameter "max_execution_time" in /etc/php5/apache2/php.ini max_execution_times setzen wir von 30 auf 60 hoch. Anschließend geht es mit folgenden Befehlen weiter:
Code:
# apt-get install ttf-mscorefonts-installer
# wget [url=https://lamp-ng.googlecode.com/files/logzilla_v2.9.9o.tgz]Error 404 (Not Found)!!1[/url]
# tar xzvf logzilla_v2.9.9o.tgz 
# mv php-syslog-ng logzilla
# mv logzilla /var/www/
# cpan Text::LevenshteinXS
Danach legen wir /etc/apache2/sites-available/logzilla mit folgendem Inhalt an:
Code:
# LogZilla
   Alias /logs "/var/www/logzilla/html/"
   <Directory "/var/www/logzilla/html/">
       Options Indexes MultiViews FollowSymLinks
       AllowOverride All
   Order allow,deny
   Allow from all
   </Directory>
Mit a2ensite logzilla und /etc/init.d/apache2 restart übernehmen wir die Änderungen.

Bevor es nun an die eigentliche Logzilla-Installation geht, ändern wir in /var/www/logzilla/html/install/sql/dbsetup.sql jedes Vorkommen von "TYPE" in "ENGINE" ab, da es sonst Fehlermeldungen beim Erstellen der Datenbank gibt. Danach rufen wir im Browser das Logzilla-Verzeichnis (http://adresse.des.servers/logs) auf. Die Installation ist relativ selbsterklärend. Es gilt nur zu beachten, dass bei den MySQL-Zugangsdaten einmal der MySQL-root-Zugang (für das Anlegen der Datenbank) und zweimal die von syslog-ng benutzten Zugangsdaten (db_user / db_passwort) angegeben werden müssen, damit selbiger auch die Berechtigung hat, in die Datenbank zu schreiben.
Im letzten Schritt der Installation muss darauf geachtet werden, dass die Site-URL korrekt angegeben wird - in diesem Fall ist es /logs/.

Am Schluss starten wir mit /etc/init.d/syslog-ng restart den Logging-Daemon neu.

Wenn wir nun ein logger test123 ausführen, sollte dies zum einen im Logfile (in diesem Fall /var/log/messages) als auch in der Datenbank landen. Die Datenbank können wir wie folgt überprüfen:
Code:
# mysql -udb_user -pdb_passwort syslog
mysql> select * from logs where msg='test123';
Und natürlich sollte auch Logzilla diesen Eintrag anzeigen.

Von nun an lassen sich die Logs deutlich bequemer filtern und betrachten :)
Man muss sich somit nicht mehr auf dem System einloggen und die Logs von Hand durchsuchen, sondern schaut einfach, ob Logzilla Einträge listet, welche nicht grün markiert sind. Besonders praktisch ist das natürlich dann, wenn man auf diese Weise die Logs mehrerer Systeme auf einen Blick kontrollieren kann.

Mailversand mit Postfix
Wie ich eingangs schrieb, ist es aber natürlich am bequemsten, wenn man die interessantesten Log-Meldungen per Mail geschickt bekommt. Um den Mailversand aber überhaupt zu ermöglichen, müssen wir erstmal Postfix installieren (apt-get install postfix). Dessen Konfiguration unterscheidet sich je nachdem, ob wir einen Server mit einer festen IP-Adresse unter einer eigenen Domain betreiben oder ob der Server zuhause steht. Ich werde mich erstmal nur einem Homeserver widmen, kann aber gerne die Postfix-Einrichtung auf einem öffentlich zugänglichen en Server beschreiben, wenn Bedarf besteht.

Postfix auf einem Homeserver (d.h. ohne öffentliche Domain):
- im Setup "Internet mit Smarthost" auswählen und als SMTP-Relay-Server den SMTP-Server eures Mailanbieters auswählen (Liste)
- die Postfix-Konfiguration in /etc/postfix/main.cf um folgende Zeilen erweitern:
Code:
smtp_sasl_auth_enable = yes
smtp_sasl_security_options = noplaintext noanonymous
smtp_sasl_password_maps = hash:/etc/postfix/sasl_password
sender_canonical_maps = hash:/etc/postfix/sender_canonical
Als nächstes hinterlegen wir unsere Zugangsdaten zum Mailserver in der Form "smtp.server.des.mailanbieters nutzername:passwort" in /etc/postfix/sasl_password. Diese Datei schützen wir zudem mit chmod 600 /etc/postfix/sasl_password vor unberechtigten Zugriffen. Anschließend erzeugen wir daraus mit postmap /etc/postfix/sasl_password eine für Postfix lesbare Datenbank.

Da aus gutem Grund in den meisten Fällen Mails von Absendern wie fritz@home.dyndns.org oder root@localhost von den Mailservern abgelehnt werden erstellen wir die Datei /etc/postfix/sender_canonical - hier hinterlegen wir Zuordnungen von lokalen Nutzerkonten und ihren E-Mail-Adressen nach folgendem Schema:
Code:
root fritz@gmx.de
www-data bert@aol.com
Auch hiervon erzeugen wir mit postmap /etc/postfix/sender_canonical eine Datenbankdatei.
Anschließend starten wir Postfix neu (/etc/init.d/postfix restart) und schicken uns mittels echo "Das ist eine Testmail | mail -s "Testmail" deine_mail_adresse eine E-Mail (sollte mail nicht verfügbar sein, einfach die mailutils nachinstallieren). Sollte dies wider Erwarten nicht funktionieren, hilft ein Blick ins Mail-Log, welches in der Regel unter /var/log/mail oder /var/log/mail.log zu finden ist.

Automatisierte Log-Analyse mit tenshi


Nachdem das System zuverlässig loggt und auch der Mailverstand funktioniert, widmen wir uns tenshi. Nach der Installation (apt-get install tenshi) rufen wir die Config auf, welche in /etc/tenshi/tenshi.conf liegt. Die wichtigsten Bestandteile dieser Datei will ich im Folgenden kurz erläutern
Code:
set uid tenshi
set gid tenshi

set pidfile /var/run/tenshi/tenshi.pid

# Hier müssen wir natürlich Logfiles auswählen, welche 1) tatsächlich  existieren und 2) überwacht werden sollen. Ich habe bei mir  beispielsweise noch das Mail-Log eingetragen.
set logfile /var/log/auth.log
set logfile /var/log/messages

# Wie viel Zeit soll zwischen dem Versenden von Mails mindestens vergehen? Muss bei unter 60 Sekunden liegen
set sleep 5
# Wie viele Einträge soll eine Mail maximal beinhalten?
set limit 800
set pager_limit 2
set mask ___
set mailserver localhost
# Betreffzeile der von tenshi versendten Mails, falls es bei den folgenden Queues nicht festgelegt wurde
set subject tenshi report
set hidepid on

# syntax: set queue <queue_name> <mail_from> [pager:]<mail_to> <cron_spec> [<subject>]
# die folgenden Zeile bewirkt, dass mit "misc" markierte Meldungen zwischen 9 und 17 Uhr alle 2 Stunden verschickt werden
set queue misc     fritz@mail.de fritz@mail.de [0 9-17/2 * * *]
# gemäß der nächsten Zeile werden mit "critical" geflaggte Meldungen  sofort verschickt, der Betreff wird auf "tenshi CRITICAL report" gesetzt
set queue critical fritz@mail.de fritz@mail.de [now] tenshi CRITICAL report

# wenn eine Zeile mehrfach auftaucht, wird sie nicht mehrfach in die  Mail gepackt, sondern es wird vermerkt, wie oft sie ins Log geschrieben  wurde
repeat ^(?:last message repeated|above message repeats) (\\d+) times?

# Zeilen, welche mit "trash ^" beginnen, werden verworfen
trash ^hub.c
trash ^usb.c
trash ^uhci.c
trash ^sda
trash ^Initializing USB
trash ^scsi0 : SCSI emulation
trash ^Vendor:
trash ^Type:
trash ^Attached scsi removable
trash ^SCSI device sda
trash ^sda: Write
trash ^/dev/scsi
trash ^WARNING: USB
trash ^USB Mass Storage
trash ^/dev
trash ^ISO
trash ^floppy0
trash ^end_request
trash ^Directory
trash ^I/O error: dev 08:(.+), sector

critical ^Oops
critical ^Linux
critical ^init

#Wenn man will, kann man die Definitionen auf verschiedene Dateien  aufteilen, welche man dann hier einbindet. Ich persönlich habe lieber  alles in einer großen Datei
includedir /etc/tenshi/includes-active

#Mit der folgenden Zeile bewirkt man, dass alles, was nicht definiert wurde, im misc-Report landet.
misc .*
Eine ordentliche tenshi-Config zusammenzustellen, kann Tage oder sogar Wochen dauern. Ich empfehle, anfangs erstmal nichts zu verwerfen, sondern sich während der Einrichtung mittels /etc/init.d/tenshi reload ständig Reports schicken zu lassen. Die dort aufgeführten Meldungen kann man dann in der tenshi-Config definieren. Ähnliche Meldungen lassen sich dabei in Gruppen zusammenfassen:
Code:
group ^sshd
        critical,misc ^sshd: pam_unix\(sshd_auth\): authentication failure; .+
        critical,misc ^sshd: Failed (none|password) for .+
        critical,misc ^sshd: Illegal user
        critical,misc ^sshd: Invalid user .+
        trash ^sshd: Accepted publickey for root from 192.168.0.(1|2|3|4|10|11|13|14|15) port .+ ssh2
        trash ^sshd(\[.*\])?: Connection closed by 192.168.0.\.* \[preauth\]
        trash ^sshd: pam_unix\(sshd:session\): session (closed|opened) for user (fritz|root)( by \(uid=0\))?
        trash ^sshd: Received disconnect from .+: .+: disconnected by user
        trash ^sshd: Received signal 15; terminating.
        trash ^sshd: Server listening on (\:\:|0.0.0.0) port (22|12345).
group_end
Wie man sieht, lassen sich hier durch die Verwendung von Regulären Ausdrücken sehr fein granulierte Filterregeln erstellen. Meine Config ist nach rund 3 Jahren knapp 600 Zeilen dick und wächst auch jetzt noch ab und an um einige Einträge. Ganz so fett wie die Config des Gentoo-Entwicklers Wolfram Schlich ist sie aber noch nicht ;)

Hinweis: bei mir wollte tenshi anfangs partout nicht laufen. Dies lag an falsch gesetzten Zugriffsrechten auf dem Ordner, in welchem das PID-File landet. Beheben kann man dies mit chown tenshi:tenshi -R /var/run/tenshi

Auch wenn die Einrichtung einiges an Arbeit bedeutet: auf lange Sicht spart eine effiziente Logging-Lösung Zeit und Nerven. LogZilla hilft, die Logs des System bequem im Blick behalten und schnell analysieren zu können, während tenshi die Informationsflut gehörig eindämmen kann.
Nun fehlt noch eine Möglichkeit, Eckdaten des Systems bequem über den Browser abrufen zu können. Ich werde daher im nächsten Schritt auf die Installation der beiden Monitoring-Lösungen phpsysinfo und linux-dash eingehen.
Eine mächtigere, aber auch wesentlich komplexere Rundum-Monitoring-Lösung wie Zabbix werde ich zu einem späteren Zeitpunkt vorstellen.

MfG Jimini
 
Zuletzt bearbeitet:
AW: [HowTo] Absicherung eines Linux-Servers


Während die Analyse der Logs des Systems dazu dient, Meldungen der laufenden Daemons zu analysieren, bietet das Monitoring einen Einblick in den "Ist-Zustand" eures Systems. Die CPU-Last oder die Belegung des Speicherplatzes sind typische Größen, welche sich hierüber schnell abfragen lassen, ohne sich erst einloggen zu müssen. Simplere Softwarepakete wie phpsysinfo und linux-dash sind schnell installiert, intuitiv bedienbar und können die wichtigsten Eckdaten abbilden.
Möchte man hingegen Benachrichtigungsfunktionen, die Überwachung mehrerer Systeme und eine flexibel und individuell erweiterbare Monitoringlösung, stoßen die eben genannten Optionen schnell an ihre Grenzen. Große Projekte wie Icinga, Nagios und Zabbix erfüllen auch anspruchsvollere Wünsche, sind allerdings auch wesentlich komplexer, was Einrichtung und Bedienung anbelangt. Ich habe vor ein paar Jahren angefangen, mit Zabbix zu arbeiten, welches schließlich diverse Server eines Uni-Rechenzentrums sowie die Beamer und Drucker überwachte. So ließen sich dann die Zustände der Beamerlampen, der Papier- und Tintenfüllstand der Drucker sowie deren Auslastung und natürlich alle möglichen Eckdaten unserer (Windows- und Linux-)Server bequem über den Browser abfragen. Hinzu kam eine History, so dass ich am Ende des Monats automatisch einen Report der gedruckten Seiten o.ä. per Mail geschickt bekam.
Privat setze ich Zabbix vor allem ein, um den SMART-Status meiner Festplatten und den Zustand meiner RAIDs im Auge zu behalten. Fällt etwa eine Festplatte aus, erhalte ich innerhalb von Sekunden eine E-Mail und weiß Bescheid. Da Zabbix aber wesentlich mehr Aufwand erfordert, gehe ich zunächst nur auf die Einrichtung und Benutzung von phpsysinfo und linux-dash ein.

1) Monitoring mit linux-dash

Das sehr kleine Paket lässt sich schnell von linux-dash : Server Monitoring Web Dashboard herunterladen. Nach dem Entpacken muss es nur noch dorthin verschoben werden, wo der Webserver seine Daten hält - fertig. Unter linux-dash : Server Monitoring Web Dashboard kann man sich das Tool so ansehen, wie es im alltäglichen Einsatz aussieht.

2) Monitoring mit phpsysinfo

Genauso schnell geht die Installation von phpsysinfo vonstatten. Nach der Installation verschiebt man das Verzeichnis gegebenenfalls noch an den korrekten Ort und kann sofort über den Browser die Daten seines Systems einsehen. So sieht es dann fertig aus: phpSysInfo 3.1.17

Hinweis: die Daten, welche sich hier auf so einfache Weise abrufen lassen, können potentiellen Angreifern nützliche Informationen liefern. Es kann daher ratsam sein, die Seiten mit htaccess oder ähnlichen Werkzeugen vor dem Zugriff Unbefugter zu schützen.

3) Monitoring mit Zabbix

linux-dash und phpsysinfo decken die grundlegenden Funktionen eines Monitoringsystems ab - der größte Vorteil ist, dass diese Lösungen schnell einsatzbereit sind. Der Nachteil ist, dass hier natürlich kaum ein flexibles Überwachen des eigenen Systems oder gar das Einbinden weiterer Systeme möglich ist. Hier muss man dann auf komplexere Lösungen wie beispielsweise Icinga, Nagios oder eben Zabbix zurückgreifen. Ich werde mich auf die Vorstellung von Zabbix beschränken, da ich hiermit seit über 5 Jahren arbeite. Neben meinen eigenen Servern überwache ich damit zwei Server auf der Arbeit, ferner habe ich Zabbix vor Jahren als zentrale Monitöringlösung in einem Uni-Rechenzentrum aufgesetzt, womit nicht nur Server, sondern auch Drucker überwacht wurden.

3.1 - Installation von Zabbix

Ich verwende Zabbix im Zusammenspiel mit Apache und MySQL. PHP wird vorausgesetzt. Zabbix ist in Debian in drei grundlegende Komponenten unterteilt: den Server, den Client und das Webinterface. Wir fügen zunächst einmal die Quellen hinzu, damit wir Zabbix bequem über das Paketmanagement installieren können:
Code:
root@debian:~# wget http://repo.zabbix.com/zabbix/2.4/debian/pool/main/z/zabbix-release/zabbix-release_2.4-1+jessie_all.deb
root@debian:~# dpkg -i zabbix-release_2.4-1+jessie_all.deb

Nach einem apt-get update können wir dann zabbix-agent, zabbix-frontend-php und zabbix-server-mysql installieren. Die Installation dauert ein paar Augenblicke, da eine Handvoll Pakete installiert werden muss.
Danach ist Zabbix unter http://adresse.des.servers/zabbix erreichbar und kann eingerichtet werden.

Standardmäßig müssen noch ein paar PHP-Optionen angepasst werden, hier öffnet ihr /etc/php5/apache2/php.ini und setzt zunächst "date.timezone auf" "Europe/Berlin", danach entfernt ihr bei dieser Option sowie bei "always_populate_raw_post_data" das Semikolon am Zeilenanfang. Nach einem Neustart von Apache könnt ihr im Zabbix-Installationsassistenten "Retry" anklicken - jetzt sollten alle Optionen stimmen.
Im Anschluss legt ihr die Datenbank an, nach fertiggestellter Installation könnt ihr euch mit dem Benutzer "admin" und dem Passwort "zabbix" in Zabbix einloggen. :)

3.2 - Einrichten von Zabbix
Die detaillierte Einrichtung von Zabbix würde den Rahmen dieses Threads sprengen - je nach "Überwachungsbedarf" kann es Monate dauern, bis Zabbix fertig eingerichtet ist. Ich beschränke mich daher auf die grobe Erklärung der Funktionsweise und werde ein paar Möglichkeiten von Zabbix beleuchten.
Für jedes zu überwachende System - das können neben PCs auch Drucker oder generell SNMP-fähige Geräte sein - wird ein Host angelegt.
Jeder Host enthält dann verschiedene Items. Ein Item ein zu überwachender Aspekt - beispielsweise die Speicherplatzbelegung einer Partition, die Erreichbarkeit eines Netzwerkdienstes oder ein bestimmter SMART-Wert. Items werden in Applications zusammengefasst. Eine Application ist somit eine Itemgruppe, etwa "Filesystem", "RAID" oder "Security".
Einem Item lässt sich dann ein Trigger zuordnen. Dieser Auslöser springt an, wenn ein bestimmter Zustand erreicht wird, wie eine Temperatur oder ein defektes RAID. Natürlich kann man für einen Trigger dann auch eine Action definieren, so dass man beispielsweise eine E-Mail erhält, wenn ein Trigger ausgelöst wurde.
Eine ganze Sammlung von Applications, Items und Triggern kann in einem Template zusammengefasst werden.

3.3 - Hinzufügen zusätzlicher Hosts
Zabbix kann seine Vorteile insbesondere dann ausspielen, wenn mehrere Systeme überwacht werden sollen. Auf zusätzlichen Hosts wird daher der zabbix-agent installiert, welcher dann nach der lokalen Einrichtung im Client und nach dem Anlegen auf dem Zabbix-Server eine Verbindung zu selbigem herstellt und seine Werte übermitteln kann.

3.4 - Nutzen von Zabbix in Skripten
Zabbix liefert schon viele Items von Haus aus mit, ferner werden viele Templates zur Verfügung gestellt. Diese können aber natürlich nicht alle Wünsche abdecken.
Es gibt daher zwei wesentliche Möglichkeiten, Zabbix mit Werten zu füttern: zabbix-agent (diese Werte holt sich der Server ab) und zabbix_sender (diese Werte werden vom Client an den Server übermittelt).

Erstere können über bestimmte UserParameter erstellt werden, welche man einfach in /etc/zabbix/zabbix_agentd.conf hinzufügt. Im Folgenden finden sich die UserParameter eines Fileservers von mir - wie man sieht, bin ich im Umgang mit sed, cut, awk und Konsorten noch nicht ganz sicher ;)
Code:
### AIDE
UserParameter=aide.check, sudo /usr/bin/zabbix_aide

### FILESYSTEM                                                                                                                                                                                                                                 
UserParameter=custom.vfs.dev.read.ops
[*],cat /proc/diskstats | grep $1 | head -1 | awk '{print $$4}'                                                                                                                                           
UserParameter=custom.vfs.dev.read.ms
[*],cat /proc/diskstats | grep $1 | head -1 | awk '{print $$7}'                                                                                                                                            
UserParameter=custom.vfs.dev.write.ops
[*],cat /proc/diskstats | grep $1 | head -1 | awk '{print $$8}'
UserParameter=custom.vfs.dev.write.ms
[*],cat /proc/diskstats | grep $1 | head -1 | awk '{print $$11}'
UserParameter=custom.vfs.dev.io.active
[*],cat /proc/diskstats | grep $1 | head -1 | awk '{print $$12}'
UserParameter=custom.vfs.dev.io.ms
[*],cat /proc/diskstats | grep $1 | head -1 | awk '{print $$13}'
UserParameter=custom.vfs.dev.read.sectors
[*],cat /proc/diskstats | grep $1 | head -1 | awk '{print $$6}'
UserParameter=custom.vfs.dev.write.sectors
[*],cat /proc/diskstats | grep $1 | head -1 | awk '{print $$10}'

### GENERAL
UserParameter=Temp_cpu,sensors | grep "Physical" | cut -c 18-19

### MEMORY
UserParameter=mem_used,free | grep Mem | cut -d ' ' -f 12- | sed 's/ //' | cut -f1 -d ' '

### MPD
UserParameter=mpd.status,if [ "$( mpc -h 10.0.0.2 | grep "playing" )" ]; then echo "0"; else echo "1"; fi

### MYSQL
UserParameter=mysql.threads,mysqladmin -uzabbix -p'Z4bb!xPwt3x14r6!' status | cut -f3 -d":"|cut -f1 -d"Q" | sed 's/\ //g'
UserParameter=mysql.questions,mysqladmin -uzabbix -p'Z4bb!xPwt3x14r6!' status | cut -f4 -d":"|cut -f1 -d"S" | sed 's/\ //g'
UserParameter=mysql.slowqueries,mysqladmin -uzabbix -p'Z4bb!xPwt3x14r6!' status | cut -f5 -d":"|cut -f1 -d"O" | sed 's/\ //g'
UserParameter=mysql.qps,mysqladmin -uzabbix -p'Z4bb!xPwt3x14r6!' status|cut -f9 -d":" | sed 's/\ //g'

### NETWORK
UserParameter=ExternalIP,echo "`ip addr show br0 | grep 'inet ' | cut -d t -f2 | cut -d / -f1 | cut -b 2- | cut -d ' ' -f 1`"
UserParameter=iptstate.tcp,sudo /usr/sbin/iptstate -1 | grep tcp | wc -l
UserParameter=iptstate.tcp.syn,sudo /usr/sbin/iptstate -1 | grep SYN | wc -l
UserParameter=iptstate.tcp.timewait,sudo /usr/sbin/iptstate -1 | grep TIME_WAIT | wc -l
UserParameter=iptstate.tcp.established,sudo /usr/sbin/iptstate -1 | grep ESTABLISHED | wc -l
UserParameter=iptstate.tcp.close,sudo /usr/sbin/iptstate -1 | grep CLOSE | wc -l
UserParameter=iptstate.udp,sudo /usr/sbin/iptstate -1 | grep udp | wc -l
UserParameter=iptstate.icmp,sudo /usr/sbin/iptstate -1 | grep icmp | wc -l
UserParameter=iptstate.other,sudo /usr/sbin/iptstate -1 -t | head -2 | tail -1 | sed 's/^.*Other: //' | cut -d' ' -f1

### OS
UserParameter=gentoo.config,find /etc/ -name '._cfg*' 2>/dev/null | wc -l
UserParameter=gentoo.installed_packages, find /var/db/pkg/*/* -type d | wc -l

### PRINTER
UserParameter=ink.black,sudo /usr/bin/inkstatus | grep -A3 -E '(Black|Photo)' | tail -n1
UserParameter=ink.color,sudo /usr/bin/inkstatus | grep -A3 Tri-color | tail -n1

### RAID
UserParameter=check_
[*],if [ "$( cat /proc/mdstat | grep -A1 $1 | grep "_" )" ]; then echo "0"; else echo "1"; fi
UserParameter=resync_
[*],if [ "$( sudo mdadm --detail /dev/$1 | grep "resyncing" )" ]; then echo "0"; else echo "1"; fi

### SMART
UserParameter=temp_
[*],sudo smartctl -A /dev/$1 | grep Temperature | grep 194 | cut -c 88-89
UserParameter=rrer_
[*],sudo smartctl -A /dev/$1 | grep Raw_Read_Error_Rate | cut -c 38-40
UserParameter=rsc_
[*],sudo smartctl -A /dev/$1 | grep Reallocated_Sector_Ct | cut -c 38-40
UserParameter=ser_
[*],sudo smartctl -A /dev/$1 | grep Seek_Error_Rate | cut -c 38-40
UserParameter=src_
[*],sudo smartctl -A /dev/$1 | grep Spin_Retry_Count | cut -c 38-40
UserParameter=stp_
[*],sudo smartctl -A /dev/$1 | grep Seek_Time_Performance | cut -c 38-40
UserParameter=sut_
[*],sudo smartctl -A /dev/$1 | grep Spin_Up_Time | cut -c 38-40
UserParameter=tp_
[*],sudo smartctl -A /dev/$1 | grep Throughput_Performance | cut -c 38-40
UserParameter=pars_
[*],sudo smartctl -A /dev/$1 | grep Perc_Avail_Resrvd_Space | cut -c 38-40

### USV
UserParameter=battv,apcaccess | grep "BATTV    :" | cut -c 11-16 | sed 's/ //'
UserParameter=bcharge,apcaccess | grep "BCHARGE" | cut -c 11-17 | sed 's/ //'
UserParameter=cumonbatt,apcaccess | grep "CUMONBATT" | cut -c 11-30 | sed 's/seconds//' | sed 's/ //'
UserParameter=loadpct,apcaccess | grep "LOADPCT" | cut -c 11-17 | sed 's/ //' | sed 's/ //'
UserParameter=loadwatts,echo 540\*`apcaccess | grep "LOADPCT" | cut -c 11-17 | sed 's/ //' | sed 's/ //'`/100 | bc
UserParameter=timeleft,apcaccess | grep "TIMELEFT" | cut -c 11-17 | sed 's/ //' | sed 's/ //'
UserParameter=ups.status,apcaccess | grep "STATUS" | cut -d ':' -f2 | cut -d ' ' -f2

Manchmal möchte man aber beispielsweise im Anschluss an ein Skript einen Wert übermitteln. So lasse ich Zabbix überwachen, ob meine Backups tagesaktuell sind:
Code:
#!/bin/bash
day=`date +"%m-%d"`
backupdate_apollon=`if [ "$(ls /home/share/backup/Apollon/*tar | tail -2 | cut -c12- | grep $day )" ]; then echo "0"; else echo "1"; fi`
zabbix_sender -z 10.0.0.2 -s Apollon -k backupdate.apollon -o $backupdate_apollon
backupdate_apollon_db_anope=`if [ "$(ls /home/share/backup/Apollon/DB/*anope | tail -1 | cut -c6- | grep $day )" ]; then echo "0"; else echo "1"; fi`
zabbix_sender -z 10.0.0.2 -s Apollon -k backupdate.apollon_db -o $backupdate_apollon_db_anope
backupdate_apollon_db_information_schema=`if [ "$(ls /home/share/backup/Apollon/DB/*information_schema | tail -6 | cut -c6- | grep $day )" ]; then echo "0"; else echo "1"; fi`
zabbix_sender -z 10.0.0.2 -s Apollon -k backupdate.apollon_db -o $backupdate_apollon_db_information_schema
backupdate_apollon_db_kodi_music=`if [ "$(ls /home/share/backup/Apollon/DB/*kodi_music | tail -1 | cut -c6- | grep $day )" ]; then echo "0"; else echo "1"; fi`
zabbix_sender -z 10.0.0.2 -s Apollon -k backupdate.apollon_db -o $backupdate_apollon_db_kodi_music
backupdate_apollon_db_kodi_videos=`if [ "$(ls /home/share/backup/Apollon/DB/*kodi_videos | tail -1 | cut -c6- | grep $day )" ]; then echo "0"; else echo "1"; fi`
zabbix_sender -z 10.0.0.2 -s Apollon -k backupdate.apollon_db -o $backupdate_apollon_db_kodi_videos
backupdate_apollon_db_mysql=`if [ "$(ls /home/share/backup/Apollon/DB/*mysql | tail -1 | cut -c6- | grep $day )" ]; then echo "0"; else echo "1"; fi`
zabbix_sender -z 10.0.0.2 -s Apollon -k backupdate.apollon_db -o $backupdate_apollon_db_mysql
backupdate_apollon_db_syslog=`if [ "$(ls /home/share/backup/Apollon/DB/*syslog | tail -1 | cut -c6- | grep $day )" ]; then echo "0"; else echo "1"; fi`
zabbix_sender -z 10.0.0.2 -s Apollon -k backupdate.apollon_db -o $backupdate_apollon_db_syslog
backupdate_apollon_db_zabbix=`if [ "$(ls /home/share/backup/Apollon/DB/*zabbix | tail -1 | cut -c6- | grep $day )" ]; then echo "0"; else echo "1"; fi`
zabbix_sender -z 10.0.0.2 -s Apollon -k backupdate.apollon_db -o $backupdate_apollon_db_zabbix
backupdate_jimini=`if [ "$(ls /home/share/backup/Profile/jimini/*tar | tail -1 | cut -c6- | grep $day )" ]; then echo "0"; else echo "1"; fi`
zabbix_sender -z 10.0.0.2 -s Apollon -k backupdate.profjimini -o $backupdate_jimini

Und so sieht das Ding dann nach einiger Zeit aus:
zabbix.png

Zabbix lässt sich mit allem möglichen füttern. In einem Rechenzentrum habe ich beispielsweise den Toner- und Papierstand sowie die Auslastung der Drucker überwacht. Der Fantasie sind eigentlich kaum Grenzen gesetzt :)
Auch wenn die Einrichtung viel Zeit in Anspruch nimmt - eine einmal aufgesetzte Zabbix-Installation kann über Jahre hinweg viel Arbeit ersparen: ich logge mich nur noch auf meinen Servern ein, wenn Zabbix verfügbare Updates meldet oder ich irgendwas machen muss. Für das reine "im Auge behalten" reicht mir ein kurzer Blick in Zabbix und die Logs via phpsyslogng oder LogZilla.

Die hier vorgestellten Lösungen erleichtern die tägliche Arbeit mit einem Linux-Server ungemein. Zum einen führen sie viele routinemäßige Arbeitsschritte automatisch aus und ersparen somit das Eintippen vieler Befehle. Zudem bereiten sie den Output oftmals grafisch auf, so dass etwa Ressourcenengpässe sofort deutlich werden. Hinzu kommt, dass größere und flexiblere Lösungen dazu beitragen, den Administrator jederzeit auf dem neusten Stand zu halten, ohne dass dieser sich mehrfach pro Tag selbst einen Eindruck verschaffen muss. Im Zusammenspiel mit tenshi entgeht dem Admin kaum etwas - gleichzeitig werden uninteressante Informationen gefiltert.

MfG Jimini
 
Zuletzt bearbeitet:
AW: [HowTo] Absicherung eines Linux-Servers


Die Bedeutung von Backups wird gerne unterschätzt. Viele User vergessen, dass es sehr viele Möglichkeiten gibt, den gespeicherten Daten auf einem Computersystem Schaden zuzufügen. Ebenso sind viele der Meinung, dass ihre Daten ohnehin nicht so wichtig wären, als dass sie regelmäßig gesichert werden müssten - "dann installiere ich halt neu" liest man leider gar nicht mal so selten. Was man aber gerne vergisst: eine Installation kostet Zeit. Das Betriebssystem mag schnell installiert sein, aber der wirkliche Zeitaufwand kommt danach: zusätzliche Software muss installiert und eingerichtet werden, es kann Tage dauern, bis das System halbwegs so arbeitet wie vor dem Crash.
Das Zurückspielen eines Images kostet IMMER weniger Zeit als die manuelle Neueinrichtung und -anpassung eines Systems - mal ganz abgesehen davon, dass sich nicht alle Daten durch den User rekonstruieren lassen. Da das Anlegen eines Images allerdings in der Regel (zu den Ausnahmen komme ich gleich) nicht im laufenden Betrieb anlegen lassen und zudem kaum automatisiert werden können, eignen sie sich nicht für regelmäßige / tägliche Sicherungsvorgänge. Es braucht also einen zusätzlichen Schritt, um Backups möglichst aktuell zu halten.

Ich sichere den Dateibestand meines Homeservers und meines Mailservers wie folgt:
- Images werden in unregelmäßigen Abständen angelegt (zuhause nutze ich Clonezilla, den Mailserver sichere ich über eine Image-Option beim Hoster).
- Jede Nacht wird der komplette Datenbestand auf Dateiebene gesichert. Mein Homeserver lädt dabei die Backups des Mailservers automatisch herunter. Ein zweites System bei mir zuhause, welches fast baugleich mit meinem Homeserver ist, wird nur für Sicherungsvorgänge an Strom und Netzwerk angeschlossen. Dieses System enthält alle Daten des ersten Homeservers. Meine Daten werden somit auf mindestens zwei Systemen gesichert.
- Die wichtigsten Daten des Mailservers sind natürlich die Mails. Diese sichere ich stündlich.
- Die Daten werden für 2 Wochen vorgehalten und dann automatisch gelöscht.

Backupstrategie - die Details

Würde ich die zu sichernden Daten plump an einen anderen Ort kopieren (lassen), so hätte ich nach einer Woche rund 500 GB an Backups. Da zudem die Backups vom Mailserver heruntergeladen werden müssen, habe ich mindestens zwei Gründe, die Backups möglichst schlank zu halten. Hierzu empfiehlt sich die Verwendung von rsync. Dieses Programm kopiert - je nach Parametern - nur die Daten, welche sich seit dem letzten Kopiervorgang geändert haben. Es ist hierdurch als möglich, den Sicherungsvorgang eines Systems mit mehreren Terabyte an Daten auf wenige Minuten zu verkürzen.


Einmal pro Woche wird auf meinem Homeserver folgendes Skript aufgerufen:
Code:
#!/bin/bash

DATUM=`date +%Y-%m-%d`

# Löschen der Backups, die älter als 13 Tage sind
for i in `find /backup/homeserver/ -maxdepth 1 -mtime +13 -print`; do rm -rf $i; done
for i in `find /backup/mailserver/ -maxdepth 1 -mtime +13 -print`; do rm -rf $i; done

# Backup des Homeservers
rsync -a --delete --ignore-errors --exclude=/dev/* --exclude=/proc/* --exclude=/sys/* --exclude=/var/run/* --exclude=/var/cache/squid/* --exclude=/tmp/* --exclude=/usr/portage/distfiles/* --exclude=/var/lib/mysql/* / /backup/tmp/homeserver/
rm /backup/checksums_homeserver.log
tar -cpf /backup/homeserver/homeserver-$DATUM-full.tar -g /backup/checksums_homeserver.log /backup/tmp/homeserver/

Was macht das Skript nun?
1. Löschen der Sicherungen, welche älter als 13 Tage sind
2. Sichern der Daten des Homeservers. /dev/*, /sys/* und ein paar andere Verzeichnisse werden ausgelassen. Die Daten werden nach /backup/tmp/homeserver/ kopiert. Auf dieses Verzeichnis könnte ich zwar verzichten, aber so habe ich immer ein aktuelles Backup zur Hand, ohne dass ich erst ein großes Archiv entpacken muss.
3. Die soeben kopierten Daten werden gepackt, und zwar inkrementell. Das bedeutet, dass auch hier nur die Daten verarbeitet werden, welche sich seit dem letzten Sicherungsvorgang geändert haben. Hierzu nutzt tar Checksummen, welche in einem Checksummen-Log festgehalten werden. Dieses Log lösche ich wöchentlich, damit ich einmal pro Woche ein neues, "frisches" Backup erhalte.

An den restlichen sechs Tagen der Woche wird ein ähnliches Skript ausgeführt - nur dass hier eben nicht das Checksummenlog vorher gelöscht wird.

Das Ergebnis ist folgendes:
Code:
24G     homeserver-2015-02-22-full.tar
3,3G    homeserver-2015-02-23-incremental.tar
666M    homeserver-2015-02-24-incremental.tar
128M    homeserver-2015-02-25-incremental.tar
1,1G    homeserver-2015-02-26-incremental.tar
796M    homeserver-2015-02-27-incremental.tar
772M    homeserver-2015-02-28-incremental.tar
=> Statt rund 170 GB belegen die Backups einer Woche nur etwa 30 GB Speicherplatz.


zeitliche Planung: der Cronjob

Der Eintrag in /etc/crontab sieht wie folgt aus:
Code:
0       2       *       *       0       root    /usr/bin/backup_full > /dev/null 2>&1
0       2       *       *       1-6     root    /usr/bin/backup_incremental > /dev/null 2>&1
Jeden Sonntag wird demzufolge um 2:00 das Vollbackup ausgeführt, an den restlichen sechs Tagen der Woche das inkrementelle.


Kommen Dateisysteme wie btrfs oder ZFS zum Einsatz, kann man im laufenden Betrieb Snapshots anlegen und sich das Hantieren mit Archiven und Checksummen sparen. Allerdings setze ich bislang ext4 ein und bin somit auf die nicht ganz so elegante Methode, Daten zu sichern angewiesen.



Das Mischen verschiedener Backupmethoden macht es möglich, sehr aktuelle Backups anzulegen und die Wiederherstellung (mit Hilfe der Images) gleichzeitig sehr einfach und schnell zu gestalten. Selbstverständlich können die Parameter nach Belieben verändert werden - so könnte man bestimmte Sicherungen auch über Monate oder Jahre vorhalten.

MfG Jimini
 
Zuletzt bearbeitet:
AW: [HowTo] Absicherung und Administration eines Linux-Servers

Sieht bisher nicht schlecht aus!

Eine Bitte habe ich aber, nachdem ich den Text nur schnell überflogen habe: Netzwerkinterface nur dann ändern wenn man einen Heimserver hat. Wenn die Kiste gemietet ist, besser nicht am interface spielen. ;)
 
AW: [HowTo] Absicherung und Administration eines Linux-Servers

Mal ne blöde Frage zur Netzwerkkonfiguration. Bei mir ist in interfaces auch noch ein automatisches ipv6 interface eingetragen, kann ich das auf auto stehen lassen oder auskommentieren und dann ist es aus?
 
AW: [HowTo] Absicherung und Administration eines Linux-Servers

Mal ne blöde Frage zur Netzwerkkonfiguration. Bei mir ist in interfaces auch noch ein automatisches ipv6 interface eingetragen, kann ich das auf auto stehen lassen oder auskommentieren und dann ist es aus?
Ich muss gestehen, dass ich mich seit Jahren um die Thematik "IPv6" drücke. In https://superuser.com/questions/692952/disable-ipv6-on-interface-in-debian-wheezy ist beschrieben, wie unter Debian und entsprechenden Derivaten IPv6 für bestimmte oder alle Interface deaktiviert werden kann.

MfG Jimini
 
AW: [HowTo] Absicherung und Administration eines Linux-Servers

Warum IPv6 deaktivieren? *kopfschüttel* :hail: IPv6
Mein vServer hat mehr IP-Adressen als dein Adressraum... :D
Aber ein sehr schickes Howto, vielen Dank! Erinnert mich daran, mich noch mal mehr mit iptables zu beschäftigen. Persönlich praktisch finde ich noch fail2ban für diverse Dienste, lässt sich aber schlecht pauschal konfigurieren.

Bei Interesse noch mein IPv6 Block aus /etc/network/interfaces:
Code:
iface eth0 inet6 static
      address 2xxx:xxxx:xxxx:xxxx::x:1 #provider legt in der Regel die ersten 64 von 128bit fest, manche mehr
      netmask 64
      gateway fe80::1 #je nach Provider, teils auch automatisch via NDP/RA
      #zusätzliche Adressen: (bei /64-Block 2^64 mögliche):
      post-up ip addr add 2xxx:xxxx:xxxx:xxxx::x:2/64 dev eth0
      post-up ip addr add 2xxx:xxxx:xxxx:xxxx::x:3/64 dev eth0
      post-up ip addr add 2xxx:xxxx:xxxx:xxxx::x:4/64 dev eth0
Natürlich müssen noch firewall-Regeln angepasst werden, die Dienste auf den richtigen Devices lauschen, etc. Aber es lohnt sich, sich damit "frühzeitig" auseinanderzusetzen (eher überfällig als früh, aber das liegt an den ISPs).
 
AW: [HowTo] Absicherung und Administration eines Linux-Servers

Warum IPv6 deaktivieren? *kopfschüttel* :hail: IPv6
Mein vServer hat mehr IP-Adressen als dein Adressraum... :D
Ich habe auf meinem Homeserver IPv6 aktuell deaktiviert, da ich mich bislang noch nicht mit ip6tables bzw. nftables auseinandergesetzt habe.
Aber ein sehr schickes Howto, vielen Dank!
Gern geschehen :D
Erinnert mich daran, mich noch mal mehr mit iptables zu beschäftigen.
Wenn du noch nicht viel mit iptables gearbeitet hast, ist es vielleicht sinnvoll, direkt in die nftables einzusteigen, die meines Wissens iptables auf lange Sicht ersetzen sollen.
Persönlich praktisch finde ich noch fail2ban für diverse Dienste, lässt sich aber schlecht pauschal konfigurieren.
Stimmt, fail2ban nutze ich ebenfalls. Allerdings sollten für den Anfang Maßnahmen wie "Dienste wie SSH nicht auf Standardports laufen lassen" ausreichen - meine Server leiten SSH-Anfragen von einigen wenigen Adressen automatisch auf den richtigen Port um, so dass ich nicht immer den Port angeben muss. Alle anderen Anfragen laufen ins Leere.

MfG Jimini
 
AW: [HowTo] Absicherung und Administration eines Linux-Servers (Stand: 2. 3. 2015)

So, heute ist dann auch endlich das Tutorial zu Zabbix hinzugekommen :)

MfG Jimini
 
Villeicht sollte man noch anhängen, dass man einen sicheren Zugang nützen sollte um auf den Server zuzugreifen.
Denn wer ein System hat, dass mit einem Trojaner befallen ist so nützt auch das beste Password oder ein Public Key Auth nichts!
Am besten wäre es natürlich mittels VMWare oder Dualboot über ein Linux Betriebssystem auf dem Linux Server zu arbeiten, da eigentlich jeder der Viren verbreitet es auf Windows user absieht da dort viele unaufmerksame oder gar dumme Leute arbeiten! (Soll nicht heißen das jeder dumm ist der Windows verwenden ich tue es auch!) Aber da die gewünschte Zielgruppe so eines angriffs halt größtenteils auf Windows arbeitet werden diese Würmer, Viren oder Trojaner... für Windows Systeme geschrieben.
 
Villeicht sollte man noch anhängen, dass man einen sicheren Zugang nützen sollte um auf den Server zuzugreifen.
Denn wer ein System hat, dass mit einem Trojaner befallen ist so nützt auch das beste Password oder ein Public Key Auth etwas!
Am besten wäre es natürlich mittels VMWare oder Dualboot über ein Linux Betriebssystem auf den Linux Server zu arbeiten, da eigentlich jeder der Viren verbreitet es auf Windows user absieht da dort meist die "dümmeren" Leute arbeiten! (Soll nicht heißen das jeder dumm ist der Windows verwenden ich tue es auch!) Aber das die gewünschte Zielgruppe so eines angriffs halt größtenteils auf Windows arbeitet!
Eine VM ist zwar sicherer als eine native Installation, aber nicht sicher - es gibt mittlerweile genug Schadsoftware, die von einer VM auf den Host überspringen kann und umgekehrt.

Hier gilt aber, was woanders auch gilt: wenn man auf einem kompromittierten System arbeitet, sind passwortgeschützte Zugänge ebenfalls als kompromittiert zu betrachten. Das gilt für E-Mail-Accounts, Onlineshops, Onlinebanking und natürlich auch für (passwortgeschützte) SSH-Zugänge.
PubKey erhöht die Sicherheit zumindest ein bisschen. Es empfiehlt sich zudem, die von mir vorgeschlagenen Maßnahmen zur Absicherung durchzuführen. Wenn dann der SSHd noch auf einem anderen Port läuft und Verbindungen nur mittels PubKey von bestimmten IP-Adressen zulässt, dann ist das Kontrukt schon ziemlich sicher.
Ferner kann man natürlich Tenshi so konfigurieren, dass es eine E-Mail rausschickt, sobald sich ein User via SSH einloggt.

MfG Jimini
 
Sehr sehr coole HowTo, vielen Dank dafür. Brauche es zwar nicht, aber manchmal ganz brauchbar einfach mal was nachzuschlagen.:daumen:
 
AW: [HowTo] Absicherung und Administration eines Linux-Servers

Kleine Frage: Wieso verwendest du manchmal --sport statt --dport?
 
Habe mich länger nicht mit der Absicherung meines "Servers" beschäftigt, deswegen nochmal ne blöde Frage.

Ich habe hier einen kleinen Fileserver auf dem ein paar Samba-Freigaben, Plex und Seafile laufen. Zusätzlich habe ich noch ein Raspberry PI auf dem ein OpenVPN-Server läuft.
Per ipv4 bin ich dank DS-Lite :nene: sowieso nicht erreichbar, im Router wird nur der ipv6 OpenVPN-Port auf dem PI weitergeleitet. Sprich mein Heimnetz ist theoretisch nur über den VPN erreichbar. Würde es in diesem Fall überhaupt Sinn machen eine firewall zu verwenden?
 
Guter Guide! Ich habe dazu noch eine Erweiterung:

Ich würde ebenfalls dringend empfehlen noch Fail2Ban zu installieren: apt-get install fail2ban

das conf file liegt dann hier: /etc/fail2ban/jail.conf

Das log das fail2ban generiert hier: /var/log/fail2ban.log

IP´s die geblockt wurden hier: /etc/fail2ban/ip.blacklist


Filter kann man sich recht leicht selber anlegen in : /etc/fail2ban/filter.d/ -> diese Filter müssen dann natürlich hier referenziert werden: /etc/fail2ban/filter.d/

fail2ban bringt schon viele Filter mit, wenn ihr noch andere braucht findet ihr diese mit google oder mit etwas Ahnung schreibt ihr euch selber einen Filter:

failregex = warning: (.*)\[<HOST>\]: SASL LOGIN authentication failed: authentication failure
reject: RCPT from (.*)\[<HOST>\]: 554 5.1.1
reject: RCPT from (.*)\[<HOST>\]: 450 4.7.1
reject: RCPT from (.*)\[<HOST>\]: 554 5.7.1



Wenn ihr anderen leuten helfen wollt nutzt ihr noch das automatische übersenden der geblockten IP´s an: badips.com | an IP based abuse tracker

Ihr könnt euch hier ein Tool laden womit ihr eine grafische Auswertung eurer Blocks auf badips.com | an IP based abuse tracker bekommt. Dazu nach der Installation einfach das absetzen: wget -q -O - http://www.badips.com/get/key

und dann den Key der ausgegeben wurde auf der Website eintragen.

Eine recht gute Anleitung zur Anbindung an badip findet man hier: https://www.netmess.org/examine-your-attackers/

Ich bin sehr restrektiv, ich lasse nur einen Fehlversuch zu und banne die IP für immer:

ignoreip = 127.0.0.1/8 172.16.0.1/16
bantime = -1
maxretry = 1

Zusätzlich habe ich auf der Büchse noch nen OpenVPN Server installiert und dessen Netz exkludiert, sollte ich mich also mal aussperren, komme ich noch immer per OpenVPN dran.

EDIT: Wenn ihr das erste mal mit Fail2Ban eure Erfahrungen macht, solltet ihr nicht mit einer negativen Bantime arbeiten sondern mit einem sehr geringen Wert wie 1, solltet ihr euch so mal aus dem eigenen System aussperren, so kommt ihr nach einer Minute wieder auf das System. Tastet euch hier erst einmal ran und macht euch mit dem System vertraut! Werft auch hin und wieder mal einen Blick in das Logfile um zu sehen was da eigtl. passiert. Solltet ihr euch dennoch mal aussperren: entweder den DSL Anschluß resetten und ne neue IP bekommen oder das Handy mit Mobilen Daten und SSH Client nutzen.

So sieht ein fail2ban.log (/var/log/fail2ban.log) nach ner Weile aus:

2016-01-24 23:46:14,098 fail2ban.actions: WARNING [postfix_sasl] Ban 112.90.XXX.XXX
2016-01-31 13:38:38,072 fail2ban.actions: WARNING [postfix_unknow] Ban 61.219.XXX.XXX
2016-01-31 15:30:19,418 fail2ban.actions: WARNING [ssh] Ban 61.244.XXX.XXX



----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Ich hatte mich bei deinem Guide etwas gewundert warum du empfohlen hast den Postfix als MTA zu nutzen, daß macht ja keinen Sinn wenn der User keinen Mailserver betreibt und sich dafür nen TB bzw. Evolution installiert.

Ansonsten für die, die nen Postfix betreiben empfehle ich noch ein Hardening in /etc/postfix/main.cf:

smtpd_tls_exclude_ciphers = aNULL, eNULL, EXPORT, DES, RC4, MD5, PSK, aECDH, EDH-DSS-DES-CBC3-SHA, EDH-RSA-DES-CDB3-SHA, KRB5-DES, CBC3-SHA
smtpd_tls_mandatory_protocols = !SSLv2,!SSLv3
smtpd_tls_protocols = !SSLv2,!SSLv3
smtp_tls_protocols = !SSLv2,!SSLv3
smtpd_tls_mandatory_ciphers = high
smtpd_tls_ciphers = high

smtpd_tls_dh1024_param_file = /etc/ssl/private/dhparams.pem -> dazu noch nen dhparams erstellen -> openssl dhparam -out /etc/ssl/private/dhparams.pem 2048

dazu noch ein paar restrictions:

smtpd_helo_required = yes
smtpd_helo_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_non_fqdn_helo_hostname, reject_invalid_helo_hostname
smtpd_data_restrictions = reject_unauth_pipelining
smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination, reject_unknown_recipient_domain, reject_invalid_hostname, reject_rbl_client sbl.spamhaus.org, reject_non_fqdn_hostname, reject_invalid_hostname, reject_non_fqdn_sender, reject_non_fqdn_recipient
smtpd_client_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unknown_client_hostname,
strict_rfc821_envelopes = yes
smtpd_sasl_security_options = noanonymous
 
Zuletzt bearbeitet:
Zurück