3.2.4 manuelle SSH-Konfiguration des Servers
Nun sind die Schlüssel verteilt und wir passen die Einstellungen von SSH unseren Bedürfnissen an. Dabei wollen wir die unsichere Passwort-Authentifikation deaktivieren sowie auch gleich ein paar mehr Dinge für die Sicherheit unseres Servers tun.
Entweder wir loggen uns per SSH auf unseren Server ein (ssh username@serverip) oder wir sitzen direkt vor diesem.
Wir nutzen das Terminal und wechseln per cd das Verzeichnis zu /etc
Also: Hier ist die Datei sshd_config abgelegt, welche die Einstellungen für unseren SSH-Dienst enthält.
Um diese zu öffnen nutzen wir am besten pico als Editor. Man kann aber auch Alternativen wie Subethaedit nutzen, was ich immer mache. Man muss aber auf jeden Fall sudo davor setzen, denn man kann nur mit root-Rechten die sshd_config verändern. Die /etc/services muss man zusätzlich ändern, wenn man den SSH-Port verändern will. Dazu muss sowohl die bei /etc/services als auch bei /etc/sshd_config der Eintrag für den SSH-Port geändert werden.
Jedoch gibt es dabei immer ein paar Probleme. Auch ich hab diese. Angeblich soll es ausreichen bei der /etc/services die Zeilen
Code:
ssh 22/udp # SSH Remote Login Protocol
ssh 22/tcp # SSH Remote Login Protocol
zu ändern. Dies erreicht man durch den Befehl:
Code:
sudo pico /etc/services
Danach wird man nach dem Admin-Passwort gefragt. Wenn dies richtig eingegeben wurde, öffnet sich pico; ein Texteditor für die Konsole. Man scrollt dabei runter bis Port 22. Dort ändert man den Port von 22 auf einen anderen Port. Er sollte auf jeden Fall unter 65536 bleiben und nicht den Port eines aktiven Dienstes nutzen oder niedriger als 1024 sein, der dann entweder blockiert oder zu komischen Nebenwirkungen führt. Die Ports unter 1024 gelten als priorisierte Systemports, welche nicht überschrieben werden sollten.
Ich nutze da einen Portscanner, der Stealth FIN und ACK-Scans durchführen kann. Nmap hat dann noch den kleinen Vorteil einen ping-losen Scan durchzuführen, womit die Firewall auch nichts blockt. Als Host geben wir logischerweise unseren Server ein, oder beim Server localhost, bzw. 127.0.0.1.
Beim Scan-Typen Stealth FIN und der Ping-Art no-ping sollten wir auf alle offenen Ports stoßen. Offene Ports heissen immer aktive Service. Ist der Port geschloßen, ist der Dienst inaktiv.
Somit nutzen wir den neuen SSH-Port, der dort nicht in der Liste steht. Aber wie gesagt... bei mir scheitert es aus unerfindlichen Gründen bei der Port-Änderungen.
Wie gesagt muss zusätzlich zur /etc/services die /etc/sshd_config für die Port-Änderungen abgeändert werden.
In der Zeile ändern wir die 22 in unseren neuen Ziel-Port um, den wir auch in /etc/services angegeben haben.
Bei pico speichert man, indem man Ctrl+X drückt. Er fragt, ob die Änderungen übernommen werden sollen. Man tippt yes, bzw. ein y reicht, ein. Wenn wir gefragt werden als was es abgespeichert werden soll, und man übernimmt die Orginal-Datei und überschreibt man somit die Bestehende.
Alternativ kann man die Konfigurationsdatei auch anders bezeichnen und den SSH-Daemon, der auf dem Server läuft, per sshd -f /ort/der/neuen/sshd_config anweisen eine andere sshd_config für grundlegende Einstellungen zu nutzen.
Wenn es jemand hinbekommen haben sollte den SSH-Port manuell umstellen zu können, dann soll er es mir doch bitte verraten.
Da wir auch gerade noch in der /etc/sshd_config sind, ändern wir diese auch gleich noch weiter ab.
Falls die Zeile noch nicht existiert fügen wir die Zeile
Code:
PubKeyAuthentication yes
ein, bzw. ändern von no auf yes, falls es noch nicht geschehen ist. Damit wird die Authentifizierung per Schlüsseldatei erlaubt.
Wenn wir uns für die RSA-Verschlüsselung entschieden haben, setzen wir die Zeile Code:
DSAAuthentication no
ein, bzw. ändern von yes auf no.
Damit wird die Authentifizierung per DSA-Schlüssel verboten. Gleichzeitig erlauben wir aber mit der Zeile
Code:
RSAAuthentication yes
die Authentifizierung per RSA-Schlüssel.
weiter nützliche Zeilen:
Code:
KeyRegenerationInterval 1800
Mit dieser Option weisst man den SSH-Dienst an, alle 1800 Sekunden den Schlüssel zu erneuern. Wenn man anstelle einer beliebigen Zahl 0 schreibt, wird der SSH-Dienst angewiesen den Schlüssel niemals zu aktualisieren. Wenn die Option aktiviert ist, verhindert man, dass Hacker, denen ein Schlüssel bekannt ist, sich die komplette Verbindungszeit miteinhacken können. Sie werden durch die Regeneration des Schlüssels von der Verbindung getrennt und ausgesperrt.
Hiermit wird die Schlüsselgröße festgelegt. Es ist ähnlich wie bei der Erstellung des Schlüssels. Nur, dass hierbei mit der Option KeyRegenerationInterval ein Zusammenspiel stattfindet. Das ist also die Größe des neugenerierten Schlüssels.
Es wird hiermit erreicht, dass der SSH-Dienst nähere sicherheitsrelevante Unterscheidungen durchführt. Dabei achtet er, bei sonst auch als standardmässig aktivierter Form, auf gesetzte Rechte auf Konfigurationsdatein und Ordner. Die Rechte- und Besitzer-Problematik ist dann essentiell wichtig und auch eine häufige Fehlerursache bei einer misslungenden Verbindung. Denn bei falsch gesetzten Rechten der authorized_keys oder des Login-Verzeichnisses verweigert der Dienst die Verbindung.
Code:
UsePrivilegeSeparation yes
Vor etwa 3 Jahren existierte in einer früheren OpenSSH-Version eine Sicherheitslücke, die durch UsePrivelegeSeperation verhindert wurde. Dabei konnte ein Eindringling direkt root-Rechte erlangen. Mit dieser Option kann man jedoch die Rechte-Verteilung vom SSH-Dienst genau aufteilen lassen. Es ist somit eine weitere Sicherheitsoption, die genutzt werden sollte, da sie mit StrictMode Hand in Hand geht
Sollte eigentlich selbst erklärend sein... wenn es auf no steht, wird die Verbindung getrennt, sobald Inaktivität auftritt. Ansonsten wird die Verbindung getrennt, wenn das Terminal beendet oder die getunnelten Verbindungen getrennt wurden.
Code:
RhostsAuthentication no
Diese Option bildet eine andere Authentifizierung. Hierbei wird eine rhost-Datei angelegt und diese mit den Hosts, die sich auf unseren Servern verbunden haben, befühlt wird. Standardmässig ist sie deaktiviert und sollte es auch bleiben.
Es existiert noch die RhostsRSAAuthentification, die zusätzlich zur Rhost- eine Art RSA-Authentifizierung durchführt. Standard ist auch hier no.
Code:
ChallengeResponseAuthentication no
Diese Option würde Verbindungen als normaler User ohne Schlüssel zulassen bzw. beantworten, wenn aktiviert. Dies wäre anzuraten, wenn noch andere User auf den Server sich anmelden müssen. Hierdurch bekommen sie nämlich die Möglichkeit sich mit ihrem Benutzernamen und Passwort zu authentifizieren. Jedoch gab es da meines Wissens auch Probleme mit root-Login. Daher auch gleich noch der Befehl:
Hiermit verhindert man die direkte Anmeldung root-(Super)-User. Standardmässig ist dies auf yes gestellt, und sollte daher auf no gesetzt werden! Der unschlagbare Vorteil ist, dass man erstens Skript-Kiddies umgeht, die normalerweise alle Standard-User (und da ist root 100%ig drunter) durchgehen und Passwörter ausprobieren. Der Login root ist komplett blockiert durch diese Option und sollte auch wahr genommen werden. Der Hacker muss also beim Versuch unseren Server zu hacken den eigentlichen Login heraus bekommen, um dann festzustellen, dass zusätzlich mehr als nur ein Passwort, nämlich noch die Verschlüsselung knacken darf. Hat er dies geschafft, darf er erstmal knobbeln wie das Passwort von root ist, um superuser-Rechte zu erlangen. Die vorgehensweise ist dann bei uns ähnlich. Man logt sich erst als Anwender mit einem Schlüssel an, und arbeitet dann entweder an entscheidenen Stellen per su oder bei kleinen Eingreifen mit sudo, und sonst als einfacher Anwender.
Code:
#PAMAuthentitcationViaKbdInt no
Die genaue Arbeitsweise kann ich leider nicht erklären. Da sind die Quellen leider nicht so informativ... Es findet hier auf jeden Fall eine Interaktion mit der Option ChallengeResponseAuthentification statt. Hierbei wird das Passwort irgendwie per Tastatur-Interaktion aufgenommen und sich damit authentifiziert. Das lässt aber die Schlüssel-Authentifizierung null und nichtig werden. Standardmässig ist es auf no gestellt.
Das sollte grundsätzlich(!) auf Protocol 2 beschränkt bleiben. Es ist jedoch auch auf Protokoll 1 erweiterbar. Die Protokolle sind mit Komma zu trennen.
Bsp.: Protocol 1,2
Code:
PermitEmptyPasswords no
Dies sollte auch grundsätzlich auf no gestellt sein/werden. Leere Passwörter sind das Einfallsloseste und Gefährlichste von allem. Ist diese Option auf no gesetzt, kann man sich nicht mehr einloggen als User, der kein gesetztes Passwort hat. Aber unter Unix-Systemen sollte dies auch auf normalen Wege gar nicht erst möglich sein.
Code:
PasswordAuthentication no
Hiermit deaktivieren wir die Passwort-Authentifizierung explizit. Aber wie schon bei anderen Optionen aufgefallen sein sollte, kann sich dies ins Gehege kommen mit zum Beispiel ChallengeResponseAuthentification. Auf solche Kleinigkeiten sollte man achten bei der Konfiguration, denn man kann ein inkonsistentis System riskieren.
Hierbei wird die Zeit festgelegt in welcher sich der User authentifizieren und einloggen muss. Man sollte aber beachten, dass man die Zeit nicht zu niedrig wählt. Ein paar Datenpakete brauchen ihre Zeit von einem Punkt der Erde zum anderen. Dazu kommt dann die Zeit in der die Schlüssel verglichen werden. Zusätzlich wird auch die Passphrase-Eingabe dazu gezählt. Da sind schnell 30 Sekunden erreicht.
Hiermit legt man die "Tiefe" der mitgeschnittenen Aktivitäten, die in die Logs geschrieben werden, fest.
Es gibt folgende Möglichkeiten dabei: QUIET, FATAL, ERROR, INFO, VERBOSE, DEBUG. INFO ist der Standardwert, und VERBOSE sehr tiefgehend. DEBUG ist so stark mitschneidend, dass sogar private Aktivitäten der einzelnen User mitgeschnitten und protokolliert werden. Dies sollte man daher tunlichst lassen bei einem Firmen-Rechner oder dergleichen...
Code:
AllowUsers username
Hierbei werden die User eingetragen, mit denen man sich einloggen darf per SSH. Es gibt auch den Gegenpart DenyUsers, doch dieser steht hierarchisch unter AllowUsers. Wenn beide Befehle gleichzeitig genutzt werden, blockieren sie sich gegenseitig, und es kommt zu interessanten Nebenerscheinungen.
Das gleiche in grün... man kann hier aber am besten mit der Wildcard arbeiten. Als Wildcard existieren ? und *.
Beispiel: AllowGroups Power?
dies würde alle Mitglieder der Gruppen: PowerTeam, Power, PowerRangers etc. erlauben. Der Gegenpart zu dieser Option ist natürlich DenyGroups.
Sind alle Einstellungen getroffen, testen wir alles mit einem neuen Login per SSH auf unseren Server, nachdem alle Einstellungen übernommen wurden und der SSH-Daemon neugestartet wurde. Dies erreicht man indem man den Dienst bei Sharing de- und gleich darauf wieder -aktiviert.
Möglicher Geschwindigkeitsgewinn:
Wenn unser Test erfolgreich verlaufen ist, lohnt es sich die Einstellungen unseres Clients ebenfalls zu editieren. Dadurch erreicht man einen kleinen Geschwindigkeitsschub da die Einstellungen durch unseren Client schon vorgegeben sind und dieser nicht doch noch andere Möglichkeiten ausprobieren geht. Außerdem ist auch so unser Client während der SSH-Verbindung geschützt.
Es reicht, wenn wir per sudo pico /private/etc/ssh_config DSAAuthentication und PasswordAuthentication auf jeweils no setzen. Hier durch wird unser Dienst so eingeschränkt, dass wir uns nur noch mit RSA-Schlüsseln authentifizieren können. Wer SSH öfter brauch um sich auch auf andere Server mit nur einem Passwort oder DSA anzumelden, sollte seinen Dienst dann natürlich nicht einschränken.
3.3 Per SSH Anwendungen tunneln (Port-Forwarding)
Vielleicht kennt ein jeder das sichere HTTP-Protokoll, welches HTTPS genannt wird. Dies hat die selbe grundlegende Funktionsweise, die wir uns zu eigen machen wollen. Hierbei wird ein Schlüssel zwischen Server und Client ausgetauscht und nur über diesen Schlüssel kommuniziert man untereinander.
Wir haben nun schon die Schlüssel-Authentifizierung aktiviert und nutzen diese auch voll. Wenn wir nun Anwendungen von unserem Server auf unseren Client nutzen wollen, sollten wir auf eine sichere Verbindung achten. Die erreichen wir, indem wir die Übertragung der Daten per SSH tunneln. Tunneln ist hierbei wirklich sehr bildlich gesprochen.
Als kleines Beispiel:
ich nutze MLDonkeyWebmin auf meinem Server. Dieses agiert im Hintergrund und über ein Webinterface eine bequeme Übersicht über Aktivitäten bieten. Mit Webmin kann man kurz gesagt den Server komplett fernwarten. Darunter fällt die User-, Festplatten- und Rechte-Verwaltung, um nur ein paar zu nennen. Es ist mit das mächtigste Tool um sein System auch in kürzester Zeit zu zerschiessen. Man kann das Webinterface einschränken. Entweder kann es nur vom localhost oder vom internen Netzwerk erreicht werden. Ferner kann es sogar für das Internet freigegeben werden, wenn der Router den Ziel-Port weiterleitet.
Das Webinterface von Webmin reagiert auf den Port 10000 standardmässig.
Wenn mein Server nun die IP-Adresse 192.168.1.2 hat, erreiche ist das Webinterface, wenn ich in den Browser: 192.168.1.2:10000 eingebe. Wenn ich es nur auf den localhost beschränke, funktioniert es logischerweise auch über: localhost:10000.
Ich möchte Webmin jetzt nur auf den localhost beschränken, um jegliches Sicherheitsrisiko zu minimieren.
Nun muss ich mir etwas einfallen lassen, wie ich trotzdem von meinem Client, der noch im selben Netzwerk steht und später weit außerhalb, auf meinen Server zugreifen kann, um dann Webmin steuern zu können.
Die Lösung steckt im Tunneln von Ports bzw. Diensten per SSH.
Hierbei verbinden wir uns per SSH von unserem Client auf unseren Server. Wir setzen als zusätzlichen Parameter dabei die Aufforderung, den Ziel-Port 10000 von unserem Server zu unseren Client weiterzuleiten.
Der Parameter würde dabei so aussehen (per RSA-Authentizifierung):
Code:
ssh -l username -L 10000:localhost:50000 192.168.1.2
Mit diesem Befehl im Terminal wird der SSH-Dienst angewiesen sich auf die 192.168.1.2 zu verbinden mit unserem username. Weiter soll der Start-Port 10000 von unserem Server auf den localhost (unseres Client) auf den Ziel-Port 50000 getunnelt werden.
Wenn die Authentifizierung erfolgreich war, öffnen wir bei unseren Client den Browser und tippen localhost:50000 ein. Jetzt öffnet sich das Webinterface von Webmin mit dem Login.
Dies ist nun als sicherer anzusehen als zum Beispiel die Freigabe des Webinterfaces für das ganze Internet, denn nun wird unsere Verbindung mit dem Server über SSH verschlüsselt und geschützt. Durch die RSA-Schlüssel-Authentifizierung ist es auch nicht möglich, dass jemand Drittes unsere Verbindung mitlauscht oder gar mitsteuert.
Diese Methodik kann auf alle Dienste angewendet werden, die die Möglichkeit bieten, Zugriffe per Netzwerk, oder gar vom Internet aus, zu steuern. Hierbei ist ein Webinterface immer am praktischsten, da dieses auch oft sehr sparsam gehalten ist, und somit auch keinen großen Netzwerkverkehr erzeugt.
Es können auch mehrere Ports bei nur einer SSH-Authentifizierung auf dem Server getunnelt werden.
Beispielsweise: Code:
ssh -l username -L 4080:localhost:4080 10000:localhost:10000
Hierbei werden jetzt die Start-Ports 4080 und 10000 unseres Servers auf die Ziel-Ports 4080 und 10000 unseres Clients getunnelt.
Die Allgemeine Vorschrift für den Parameter -L ist:
Code:
ssh username@serverip -L Start-Port:ZielIP:Ziel-Port
Start-Port:Das ist der Port, der von dem aktiven Dienst auf dem Server genutzt wird. Wenn webmin auf dem Server läuft, dann läuft dieses standardmässig auf Port 10000. Wenn man den Port von Webmin auf 100 ändert, dann ist der Start-Port, der bei SSH gesetzt wird, auch 100.
ZielIP:Das ist das Ziel auf welches der Port von unserem Server hingetunnelt werden soll. Logischerweise schreibt man dabei eigentlich fast immer localhost oder 127.0.0.1. Man kann jedoch auch eine andere ZielIP auswählen. Hierbei funktioniert jedoch anscheinend nur das interne Netz außerdem muss natürlich auch eine SSH-Verbindung zu der ZielIP bestehen.
Ziel-Port:Hier setzen wir den Port, auf den wir den getunnelten Dienst nutzen wollen. Man sollte hierbei am besten nicht Port 80 nehmen.... genauso wenig wie Port 8080, welcher oft von Proxys und anderen Internet-Diensten genutzt wird. Außerdem wie bereits oben erwähnt Ports unter 1024 prinzipiell meiden.
Ansonsten gilt auch hier wieder: jeder Port ist frei nutzbar, solange er nicht von einem anderen Dienst belegt wird.
Am besten nimmt man immer den Start-Port vom Server. Dann muss man sich auch keine krummen Zahlen merken.