Update: 29.03.2018

Hinweis: Neben den Anleitungen im Rahmen dieser Serie habe ich mittlerweile fertige Shell Scripte erstellt, die quasi voll automatisch die Installation eines Servers für euch übernehmen. Ihr findet das Ganze auf github.de, wobei ihr entweder den ganzen Server per Script aufsetzen und konfigurieren lassen könnt, oder eben jeden einzelnen Schritt, wie  z.B. das Absichern des Servers, oder das Installieren eines LEMP Stacks, mit Hilfe der jeweiligen Scripte erledigen könnt. Die Scripte entsprechen quasi 1:1 zu den Tutorials.

Server absichern

Dies ist quasi das erste Tutorial aus der Reihe: Der perfekte Server. Ich habe längere Zeit überlegt, womit genau ich anfangen soll und mich dann schließlich für dieses Thema entschieden, einfach weil es wohl eines der wichtigsten überhaupt ist. In einem etwas kürzerem Tutorial hatte ich bereits einige Grundlagen dazu erläutert.

Ihr solltet nämlich nie vergessen, dass ihr für euren Server bzw. vServer und den evtl. davon ausgehenden Schaden selbst verantwortlich seid. Darauf weisen die wenigsten Hoster einen natürlich hin, im Ernstfall kann das aber nicht nur ganz schön teuer werden, sondern auch ernste Konsequenzen nach sich ziehen. Von einfachen Spam- und Phishing-Mails, über DDos Attacken bis hin zum Umschlagpunkt für Kinderpornografie, so ein Server lässt sich mit genügend krimineller Energie zu so einigem missbrauchen.

Wem der Arbeitsaufwand hierbei zu hoch ist, aber dennoch anstelle eines einfachen Webhosting Pakets einen eigenen Server betreiben möchte, dem empfehle ich hierbei ein paar Euro mehr in die Hand zu nehmen und sich einen „managed“ Server zu mieten. Netcup bietet solch einen Service z.B. an. Absicherung, Verwaltung und Wartung werden hier in Absprache mit dem Kunden direkt vom Hoster übernommen. Ich denke es ist überflüssig zu erwähnen, dass das Ganze nicht gerade kostengünstig ist.

Meine persönliche Meinung dazu? Das Managen eines Servers ist sicherlich kein Hexenwerk, wer sich hier ein bisschen mit dem Thema vertraut macht und einige Regel befolgt, der kann sich das Geld getrost sparen.

Wenn ihr den Server innerhalb weniger Stunden vollständig einrichtet, könnt ihr die Absicherung auch gerne als letzten Schritt durchführen – erfahrungsgemäß kann ich aber sagen, dass die Meisten sich dann doch ein bisschen mehr Zeit zum Einrichten nehmen. Also worauf warten? Sicher ist sicher. Fangen wir mit dem Absichern an!

SSH Port ändern

Gemessen am Arbeitsaufwand ist die Änderung des Standard SSH Ports wohl am einfachsten und effektivsten. Denn die meisten Angreifer zielen direkt auf den Port 22 ab. Wenn ich z.B. bei Linode einen neuen Server aufsetze dauert es keine 10 Minuten und ich habe die ersten Zugriffsversuche und Bruteforce Attacke aus Ländern wie China, die alle auf diesen Port abzielen. Zugegeben, der IP Pool von Netcup ist nicht so bekannt wie ein bunter Hund, aber warum das Risiko eingehen?

Hierzu ändern wir einfach in der /etc/ssh/sshd_config den Standard Port von 22 auf einen anderen Port unserer Wahl. Achtet aber bei eurer Auswahl darauf, dass ihr nicht gerade einen Port belegt, der anderweitig benötigt wird. Der Standardport für HTTP wäre z.B. Port 80. Das wissen natürlich auch die Browser, weswegen die Kommunikation hier ohne Probleme verläuft. Änderungen würden also dafür führen, dass eure gehosteten Webseiten nicht mehr erreichbar wären.

Zum editieren könnt ihr einen der unzähligen Editoren nutzen, z.B. vim, nano, etc., ganz wie ihr mögt. Die Schreibfaulen könnten das Ganze auch bequem in einem einzigen Befehl verpacken:

sed -i 's/^Port .*/'"Port <neuer SSH Port>/g" /etc/ssh/sshd_config

Hier mal eine kurze Überblick über die Ports:

  1. Ports 0 – 1023: Well known Ports – die meisten bekanntesten Dienste laufen hier
  2. Ports 1024 – 49151: Registered Ports – einige Ports sind für bekannte Dienste reserviert, andere sind unbelegt
  3. Ports 49152 – 65535: Private / Dynamic Ports – können in der Regel ohne Probleme genutzt werden

Im Zweifelsfall, einfach mal den gewünschten Port googlen.

Zu guter Letzt müssen wir den SSH Dienst natürlich neustarten. Danach können wir uns über den neuen Port via SSH einloggen.

service ssh restart

Oder, wenn ihr lieber eins der älteren init.d scripte dafür nutzen wollt:

/etc/init.d/ssh restart

So, das wärs auch schon. Der erste Schritt zum Sicheren Server!

Benachrichtigung bei SSH Login

Darüber lässt sich jetzt sicher diskutieren, ob das Ganze sinnvoll, oder vielleicht nur Spam ist. Fakt ist aber, dass es sicherlich nicht schaden kann, wenn ihr eine kure Nachricht bekommt, sobald sich jemand via SSH auf eurem Server einloggt. Weniger geeignet wäre so eine Benachrichtigung, wenn ihr regelmäßig via SSH auf den Server zugreift, quasi um Daten abzurufen oder Veränderungen vorzunehmen. In meinem Fall logge ich mich aber ,wenn es hoch kommt, zwei Mal die Woche auf dem Server ein und das auch meist nur, um Updates zu installieren.

Option 1: email

Hierfür erstellen wir einfach ein kurzes und simples Shell Skript /opt/shell-login.sh:

#!/bin/bash
 
echo "Login auf $(hostname) am $(date +%d.%m.%Y) um $(date +%H:%M) Uhr"
echo "Benutzer: $USER"
echo

Anschließend vergeben wir die passenden Rechte und sagen dem Server, dass dieses Script beim erfolgreichen Login ausgeführt werden soll.

chmod 755 /opt/shell-login.sh
echo '/opt/shell-login.sh | mailx -s "SSH Login auf <euer Server>" <mail@domain.de>' >> /etc/profile

Jetzt sollte eigentlich sobald sich ein user via SSH auf eurem Server einloggt eine kurze Nachricht an die hinterlegte email geschickt werden. Je nach Server Grundkonfiguration müssen wir hier noch sendmail konfigurieren. Dazu aber an anderer Stelle mehr.

Option 2: Push Notification aufs Smartphone

Das Prinzip ist eigentlich das Gleich, wie bereits oben in Option 1 beschrieben, nur eben mit dem Unterschied, dass ihr statt einer email, eine Push Notification auf euer Smartphone/Tablet, Computer, etc. bekommt.

Ich verwende auf meinem Server hierfür Pushover. Das Preisleistungsverhältnis stimmt, die passenden Apps gibt es sowohl für Android, als auch für iOS und die Registrierung, bzw. Konfiguration ist schnell erledigt. Für die Nutzung mit meinem Smartphone fielen glaube ich einmalig 5€ an Gebühren an und das Volumen des Basis Tarifs sollte wohl für die Meisten ausreichen.

Wir erstellen uns also, wie bereits oben erwähnt, ein Shell Skript /opt/shell-login.sh

#!/bin/bash

# Pushover Config

API_TOKEN="<euer Token>"
USER_KEY="<euer Key>"

TITLE="SSH Login"
MESSAGE="Login auf $(hostname) am $(date +%d.%m.%Y) um $(date +%H:%M) Uhr
Benutzer: $USER"

curl -s \
--form-string "token=$API_TOKEN" \
--form-string "user=$USER_KEY" \
--form-string "title=$ITLE" \
--form-string "message=$MESSAGE" \
https://api.pushover.net/1/messages.json

Anschließend setzten wir die passenden Rechte und sorgen dafür, dass das Script beim Login ausgeführt wird.

chmod 755 /opt/shell-login.sh
echo "/opt/shell-login.sh > /dev/null 2>&1" >> /etc/profile

Praktisch ist auch, dass man den Dienst eben nicht nur zum Absichern seines Servers nutzen kann, sondern auch für viele andere coole Projekte, wie z.B. das Senden von Fotos der Überwachungskamera etc.

Fail2ban

Fail2ban gehört auf jeden Fall zu meinen Favoriten, wenn es um das Absichern von Servern geht. Fail2ban arbeit sowohl simple, als auch effektiv. Es ermittelt mit Hilfe der Daten aus den Logfiles, ob und wie oft sich eine IP Adresse versucht hat einzuloggen. Hierbei ist die Überwachung nicht nur auf den SSH Zugang beschränkt, sondern es lassen sich auch ohne Probleme alle anderen Logins überwachen, z.B. für FTP Accounts, nginx Logins, worpress oder nextcloud Logins, etc..

Ihr könnt mit Hilfe der Config selbst festlegen, welche Logins überwacht werden sollen, bzw. wie bei zweifelhaften Aktionen verfahren werden soll, sprich wie lange eine IP Adresse gebannt werden soll und ab wie vielen missglückten Einloggversuchen.

Installieren können wir fail2ban bequem per apt.

apt-get install fail2ban

Im Ordner /etc/fail2ban/ findet ihr anschließend die Konfigurationsdatei. Wobei es zu empfehlen ist eine Kopie namens jail.local zu erstellen, da die original Datei bei jedem Update überschrieben wird.

cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local

In der jail.local zu können wir nun all unsere Anpassungen vornehmen. Um den Rahmen dieses Tutorials nicht ganz zu sprengen möchte ich das Ganze nur kurz am Beispiel des SSH Logins zeigen:

# "bantime" is the number of seconds that a host is banned.
bantime = 86400

# A host is banned if it has generated "maxretry" during the last "findtime"
# seconds.
findtime = 600
maxretry = 3

#
# Destination email address used solely for the interpolations in
# jail.{conf,local} configuration files.
destemail = <deine@email.de>

#
# Name of the sender for mta actions
sendername = Fail2ban

# Email address of the sender
sender = <fail2ban@domain.de>

...

[ssh]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 4

In meinem Beispiel wird also nach 4 fehlgeschlagenen SSH Logins die IP für 86.400 Sekunden gebannt, das entspricht genau einem Tag. Zusätzlich werde ich per email über den Ban benachrichtigt. Netterweise gibt es noch einige zusätzlich Infos, so dass man gleich sieht, woher der Angriff kommt. Nicht unbedingt nötig – aber in jedem Fall „nice to have“.

Hi,

The IP 58.218.211.198 has just been banned by Fail2Ban after
4 attempts against ssh.


Here is more information about 58.218.211.198:

% [whois.apnic.net]
% Whois data copyright terms    http://www.apnic.net/db/dbcopyright.html

% Information related to '58.208.0.0 - 58.223.255.255'

inetnum:        58.208.0.0 - 58.223.255.255
netname:        CHINANET-JS
descr:          CHINANET jiangsu province network
descr:          China Telecom
descr:          A12,Xin-Jie-Kou-Wai Street
descr:          Beijing 100088
country:        CN
admin-c:        CH93-AP
tech-c:         CJ186-AP
mnt-by:         APNIC-HM
mnt-lower:      MAINT-CHINANET-JS
mnt-routes:     MAINT-CHINANET-JS
remarks:        -+-+-+-+-+-+-+-+-+-+-+-++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
remarks:        To report network abuse, please contact the IRT
remarks:        For troubleshooting, please contact tech-c and admin-c
remarks:        For assistance, please contact the APNIC Helpdesk
remarks:        -+-+-+-+-+-+-+-+-+-+-+-++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
status:         ALLOCATED PORTABLE
source:         APNIC
mnt-irt:        IRT-CHINANET-CN
changed:        hm-changed@apnic.net 20050624

irt:            IRT-CHINANET-CN
address:        No.31 ,jingrong street,beijing
address:        100032
e-mail:         anti-spam@ns.chinanet.cn.net
abuse-mailbox:  anti-spam@ns.chinanet.cn.net
admin-c:        CH93-AP
tech-c:         CH93-AP
auth:           # Filtered
mnt-by:         MAINT-CHINANET
changed:        anti-spam@ns.chinanet.cn.net 20101115
source:         APNIC

role:           CHINANET JIANGSU
address:        260 Zhongyang Road,Nanjing 210037
country:        CN
phone:          +86-25-86588231
phone:          +86-25-86588745
fax-no:         +86-25-86588104
e-mail:         ip@jsinfo.net
remarks:        send anti-spam reports to spam@jsinfo.net
remarks:        send abuse reports to abuse@jsinfo.net
remarks:        times in GMT+8
admin-c:        CH360-AP
tech-c:         CS306-AP
tech-c:         CN142-AP
nic-hdl:        CJ186-AP
remarks:        www.jsinfo.net
notify:         ip@jsinfo.net
mnt-by:         MAINT-CHINANET-JS
changed:        dns@jsinfo.net 20090831
changed:        ip@jsinfo.net 20090831
changed:        hm-changed@apnic.net 20090901
source:         APNIC
changed:        hm-changed@apnic.net 20111114

person:         Chinanet Hostmaster
nic-hdl:        CH93-AP
e-mail:         anti-spam@ns.chinanet.cn.net
address:        No.31 ,jingrong street,beijing
address:        100032
phone:          +86-10-58501724
fax-no:         +86-10-58501724
country:        CN
changed:        dingsy@cndata.com 20070416
changed:        zhengzm@gsta.com 20140227
mnt-by:         MAINT-CHINANET
source:         APNIC

% This query was served by the APNIC Whois Service version 1.69.1-APNICv1r0 (UNDEFINED)


Lines containing IP:58.218.211.198 in /var/log/auth.log

Mar  5 23:53:40 packer-debian-8-amd64 sshd[25109]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=58.218.211.198  user=root
Mar  5 23:53:41 packer-debian-8-amd64 sshd[25109]: Failed password for root from 58.218.211.198 port 19118 ssh2
Mar  5 23:53:45 packer-debian-8-amd64 sshd[25109]: Failed password for root from 58.218.211.198 port 19118 ssh2
Mar  5 23:53:48 packer-debian-8-amd64 sshd[25109]: Failed password for root from 58.218.211.198 port 19118 ssh2
Mar  5 23:53:51 packer-debian-8-amd64 sshd[25109]: Failed password for root from 58.218.211.198 port 19118 ssh2


Regards,

Fail2Ban

Mein potentieller Angreifer stammt also aus China, zumindest wird ein Rechner/Server von dort benutzt. Soll mich aber nicht weiter stören, fail2ban übernimmt den Rest!

Nicht vergessen, wie eigentlich nach jeder Änderung einer Config, den entsprechenden Service neuzustarten.

service fail2ban restart

Port Knocking

Port Knocking ist auf jeden Fall noch eine super Sache, um seinen Server gegen Unbefugte abzusichern. Man kann sich das Ganze in etwa wie ein Klopfzeichen vorstellen. In den guten alten Gangsterfilmen hatten diese meistens ja auch eine Art Klopfzeichen. Zwei Mal kurz, ein Mal lang, erst dann wurde einem die Tür geöffnet. So in etwa funktioniert das beim Port Knocking auch. Der eigentliche SSH Port ist geschlossen, weswegen man ihn auch nicht als Angriffsziel nutzen kann. Erst wenn an eine bestimmte Anzahl anderer Ports in einer bestimmten Reihenfolge angeklopft wird, wird der eigentliche SSH Port geöffnet.

Da ich das Port Knocking aber gerade im Alltag eher unpraktisch finde, möchte ich an dieser Stelle nicht weiter darauf eingehen. Eine Kurze Anleitung hatte ich mal an dieser Stelle geschrieben. Man muss halt immer auch ein wenig zwischen Sicherheit und Komfort abwägen.

Systemupdates checken

Ähnlich wie an eurem heimischen Computer oder Notebook, wird auch die Software auf eurem Server ständig geupdatet. Neben Stabilität geht es dort natürlich auch um Sicherheitsupdates. Automatische Updates können hier aber mitunter heikel sein, da man gerade bei Problemen kaum eine Chance hat nachzuverfolgen, wo der Fehler liegt.

Sich jetzt aber täglich auf dem Sever einloggen, nur um zu gucken, ob es ein neues Update gibt wäre sicherlich ein wenig übertrieben. Aber das ist dank Apticron auch gar nicht nötig. Apticron informiert euch per mail, sobald ein neues Update verfügbar ist. Ihr könnt euch dann bequem per SSH einloggen und euren Server manuell updaten.

apt-get install apticron

Anschließend müssen wir nur noch in der /etc/apticron/apticron.conf unsere Informationen eintragen:

EMAIL="<deine@email.de>"
SYSTEM="<Server Name>"

Die emails die apticron verschickt sehen dann in etwa so aus:

apticron has detected that some packages need upgrading on:

        geekmonkey.de 
        [ 46.101.159.89 10.19.0.7 46.101.159.89 ]

The following packages are currently pending an upgrade:

        git 1:2.1.4-2.1+deb8u2
        git-man 1:2.1.4-2.1+deb8u2

========================================================================

Package Details:

Reading changelogs...
--- Changes for git (git git-man) ---
git (1:2.1.4-2.1+deb8u2) jessie-security; urgency=high

  * Non-maintainer upload by the Security Team.
  * Fix remote code execution via buffer overflows (CVE-2016-2315,
    CVE-2016-2324) (Closes: #818318)

 -- Salvatore Bonaccorso <carnil@debian.org>  Fri, 18 Mar 2016 06:20:38 +0100

========================================================================

You can perform the upgrade by issuing the command:

        apt-get dist-upgrade

as root on geekmonkey.de

--
apticron

Hinweis: Im Rahmen dieser Tutorials werden wir allerdings nicht nur auf vorgefertigte Pakete zurückgreifen, sondern einiges auch selbst compilieren, bzw. sogar vom Updateprozess bewusst ausschließen. Apticron ist also nur als kleine Erinnerungshilfe gedacht, nicht aber als Komplettlösung!

Rootkits aufspüren

Sollte es dennoch, trotz unseren Schutzmaßnahmen mal einem Angreifer gelingen in euer System einzudringen, ist es meist schwer nachzuvollziehen, wo genau der Einbruch stattgefunden hat, bzw. welche Spuren er hinterlassen hat. Das Tool Rootkit Hunter unterstützt uns hierbei und scannt unser System nach bekannten Rootkits, verdächtigen Strings, etc.

apt-get install rkhunter

Anschließend fügen wir noch unsere email in die Konfigurationsdatei /etc/rkhunter.conf ein, so kann rkhunter uns bei Problemen via mail benachrichtigen.

sed -i 's/^#MAIL-ON-WARNING.*/MAIL-ON-WARNING="<deine@mail.de>"/' /etc/rkhunter.conf

Nun indexieren wir erst einmal all unsere Files. Dies sollte eigentlich zu Beginn bei einem frisch aufgesetzten System geschehen. Anschließend updaten wir die Datenbank.

rkhunter --propupd
rkhunter --update

Mit Hilfe eines Cronjobs überprüft rkhunter regelmäßig unser System:

rkhunter -c --cronjob

Wir können uns nun also zurücklehnen und rkhunter behält für uns alles im Auge.

Hinweis: Sollte euer Server trotz all dieser Maßnahmen dennoch einmal von einem Angreifer übernommen werden, so kann ich euch nur empfehlen, das System platt zu machen und ein nicht-kompromittiertes Backup aufzuspielen.

Es gibt sicherlich noch eine Vielzahl von Möglichkeiten euren Server abzusichern. In meinen Augen sind dies hier aber die effektivsten.

6 Kommentare

  1. vielen dank dafür. was ist mit ssh login via schlüsseln? hast du das extra nicht erwähnt oder gehst du davpn aus das dies eh gemacht werden sollte?

    • Auf die Option gehe ich absichtlich nicht ein, da es mir unpraktisch erscheint, wenn man von unterwegs auf seinen Server zugreifen will, beispielsweise vom Smartphone, oder dem Notebook, etc, … Man müsste imme rund überlal die Keyfiles mit sich rum schleppen, .. wenn die mal verloren gehen ist das Geschrei dann groß, denn die wenigsten können wohl einfach nen Keyboard am Server anschließen.

  2. Läuft ganz gut durch deine Auflistung.

    Nur irgendwo musste ja der Wurm drin sein! cronjob will nich…

    Hab alles genau nach deiner Auflistung gemacht (ausser das ich SSH über Keys geregelt hab) und dann meckert cronjob rum
    /usr/bin/rkhunter: 1: eval: Syntax error: end of file unexpected

    Jetzt bin ich verwirrt…

    habs mal versucht zu ergoogeln (muss aber ehrlich zugeben nicht sehr erfolgreich)

    • Hm, rkhunter scheint sich eher zu beschweren, sehe gerade nicht, wo der Zusammenhang zu cronjob ist? Ferndiagnosen sin da ähnlich wie bei Krankheiten nicht wirklich möglich. Aber wo genau taucht der Fehler denn auf? Bzw. funktioniert alles ohne rkhunter?

    • Uff Sorry, da bin ich gerade überfragt – ohne genau zu wissen, was du für nen System hast, was für Pakete installiert sind, bzw was du installierst hast, … ist das per Ferndiagnose nicht einfach.

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein