Articlename: Secure SSH Tutorial Part 4: Security & ssh-agent Keywords: Security, SSH, Tutorial, ssh-agent, agent, iptables Date: 07.06.2007, 01:12 Views: 18181 Categoryname: Security ---------------------------------------- Vorwort ------------------ Im ersten Teil dieser Tutorialserie (http://www.online-tutorials.net/security/secure-ssh-tut orial-part-1-host-key/tutorials-t-69-201.html) ging es um die sichere Verwaltung des Host-Schlüssels, der zweite Teil (http://www.online-tutorials.net/security/secure-ssh-t utorial-part-2-identity-pubkey-authentifizierung/tutorials-t-69-202.html) beschäftigt sich mit Identity/Pubkey Authentifizierung unter SSH. Der dritte Teil (http://www.online-tut orials.net/security/secure-ssh-tutorial-part-3-usage/tutorials-t-69-205.html) hat sich mit dem Ungang mit den SSH-Tools beschäftigt. In diesem Teil werden wir uns mit einigen Sicherheitszusätzen beschäftigen, und den ssh-agent kennen lernen. Tutorials in dieser Artikelserie ------------------ - Tutorial Part 1: Host Key (http://www.online-tutorials.net/security/secure-ssh-tutorial-pa rt-1-host-key/tutorials-t-69-201.html) - Tutorial Part 2: Identity/Pubkey Authentifizierung (http://www.online-tutorials.net/securi ty/secure-ssh-tutorial-part-2-identity-pubkey-authentifizierung/tutorials-t-69-202.html) - Tutorial Part 3: Usage (http://www.online-tutorials.net/security/secure-ssh-tutorial-part- 3-usage/tutorials-t-69-205.html) - Tutorial Part 4: Security & ssh-agent (http://www.online-tutorials.net/security/secure-ssh -tutorial-part-4-security-ssh-agent/tutorials-t-69-206.html) Kapitel 1: Der ssh-agent ------------------ Im zweiten Teil (http://www.online-tutorials.net/security/secure-ssh-tutorial-part-2-identit y-pubkey-authentifizierung/tutorials-t-69-202.html) haben wir die gewöhnliche plaintext-Passwort-Authentifizierung gegen eine Identity/Pubkey Authentifizierung ausgetauscht. Dort habe ich versprochen einen Artikel zu bringen, in dem erklärt wird, wie wir einrichten, dass wir keine passphrase mehr eingeben müssen. Das machen wir jetzt mithilfe von ssh-agent. ssh-agent Enviroment-Variablen setzen ------------------ Als erstes starten wir den ssh-agent ohne Parameter: ------- Code ------- workstation:/home# ssh-agent SSH_AUTH_SOCK=/tmp/ssh-OqdW7921/agent.7921; export SSH_AUTH_SOCK; SSH_AGENT_PID=7922; export SSH_AGENT_PID; echo Agent pid 7922; ------- End-Code ------- Der ssh-agent gibt Informationen aus, die wir nutzen können um die enviroment-variables der shell zu setzen. Sollten Sie in einer anderen shell, z.B. einer C-shell, ala /bin/csh oder /bin/tcsh arbeiten, können diese Variablen anders sein, in diesem Fall sollten Sie die Parameter -c oder -s benutzen, um den C-Shell, bzw. Bourne shell Syntax ausgeben zu lassen. Wir müssen die SSH Enviroment-Variable SSH_AUTH_SOCK setzen, damit ssh weiß, wie mit dem ssh-agent kommunizieren kann, jedesmal wenn der ssh-agent gestartet wird, sollten wir diese Variable setzen. ------- Code ------- #Wir testen ob Variablen gesetzt sind workstation:/home# set | grep SSH_ #Variablen mit eval setzen workstation:/home# eval `ssh-agent` Agent pid 7943 #Jetzt sind wir bereit, nur noch testen: workstation:/home# set | grep SSH_ SSH_AUTH_SOCK=/tmp/ssh-xoGi7942/agent.7942 SSH_AGENT_PID=7943 ------- End-Code ------- Jetzt haben wir die SSH_AGENT_PID Variable gesetzt. Wenn wir den ssh-agent nicht mehr als Daemon laufen lassen wollen können wir ihn mit ssh-agent -k killen. ssh-agent Schlüssel hinzufügen ------------------ Als nächstes müssen wir Schlüssel mit dem Programm ssh-add hinzufügen. Wenn wir ssh-add ohne Parameter starten wird es automatisch die Schlüssel von $HOME/.ssh/identit y, $HOME/.ssh/id_rsa, und $HOME/.ssh/id_dsa zum laufenden ssh-agent hinzufügen. Da unsere Schlüssel immer(!) mit passphrases geschützt sind, wird uns das Programm automatisch nach der passphrase fragen. ------- Code ------- #Wir testen ob der ssh-agent läuft workstation:/home# ps -fp $SSH_AGENT_PID UID PID PPID C STIME TTY TIME CMD lainee 7943 1 0 15:52 ? 00:00:00 ssh-agent #Welche keys sind bereits im ssh-agent -l = list workstation:/home# ssh-add -l The agent has no identities. #Keys importieren workstation:/home# ssh-add Enter passphrase for /home/simon/.ssh/id_rsa: Identity added: /home/simon/.ssh/id_rsa (/home/simon/.ssh/id_rsa) Identity added: /home/simon/.ssh/identity (simon@workstation) #Keys aus einer anderen Datei imporiteren workstation:/home# ssh-add ssh-keys/id* Enter passphrase for id_rsa.simon: Identity added: id_dsa.simon (id_dsa.simon) ------- End-Code ------- Das Beispiel sollte selbst-erklärend sein. ssh-agent Schlüssel löschen ------------------ Wenn wir zu viele Schlüssel im ssh-agent haben, einen Schlüssel nicht länger, oder nur für eine kurze Zeit brauchen, dann wollen wir den Schlüssel aus dem Schlüsselbund entfernen, mit ssh-add -d kann ein Schlüssel von ssh-agent entfernt werden: ------- Code ------- workstation:/home# ssh-add -d ~/.ssh/id_dsa Identity removed: id_dsa (id_dsa.pub) workstation:/home# ssh-add -l The agent has no identities. ------- End-Code ------- ssh-add -D löscht alle Schlüssel. ssh-agent Zu viele Schlüssel ------------------ Der SSH-Server erlaubt uns nur eine bestimmte Anzahl von Versuchen für eine bestimmte Zeit, jeder falsche Login-Versuch zieht uns erlaubte Versuche ab. Wenn wir viele Schlüssel in ssh-agent haben, kickt uns der Server vielleicht bevor wir uns einloggen können. Wenn dieser Fall eintrifft gibt es ein paar Möglichkeiten die wir nutzen können: - Wenn wir einen Schlüssel haben den wir nicht mehr brauchen, z.B. einen alten RSA1 Schlüssel, können wir ihn mit ssh-agent -d Dateiname löschen, siehe letztes Kapitel - Wir könnten auf Passwort-Authentifizierung umsteigen, dazu können wir temporär SSH_AUTH_SOCK abschalten: ------- Code ------- workstation:/home# SSH_AUTH_SOCK='' ssh simon@vsn-server ------- End-Code ------- Oder wir machen es per Konfigurations-Datei, ~/ssh/options für einen bestimmen host: ------- Code ------- workstation:/home# nano ~/.ssh/config Host vsn-server #Authentifizierung abschalten RSAAuthentication no PubkeyAuthentication no ------- End-Code ------- Die dritte Möglichkeit wäre: ------- Code ------- ssh -o 'PubkeyAuthentication=no' -o'RSAAuthentication=no' simon@vsn-server ------- End-Code ------- ssh-agent Unix Domain Socket ------------------ Wenn der ssh-agent gestartet wird, erstellt er einen unix domain socket, der auf Verbindungen von /usr/bin/ssh wartet, er erstellt ein neues Verzeichnis in /tmp/, mit 0700, und einen socket mit 0600, dadurch werden die Schlüssel für die root Benutzer lesbar. Mit ls -la /tmp/ssh-*/* lassen sich die sockets auslesen, und mit SSH_AUTH_SOCK=/tmp/ssh-x && export SSH_AUTH_SOCK setzen. Das Problem lässt sich zwar mit der -c Option beim importieren lösen, danach wird bei der Benutzung eine Bestätigung verlangt, indem ssh-agent das Programm ssh-askpass startet. Dieses Programm läuft aber auf dem X11 server, der wiederum vom root komplett kontrollier werden kann. ssh-agent Lebensdauer der Schlüssel ------------------ Mit ssh-add -t seconds filename, oder ssh-agent -t seconds können wir die Lebensdauer eines bestimmen Schlüssels, oder von allen Schlüsseln im ssh-agent bestimmen. ssh-agent Sperren ------------------ Mit der Option -x kann man den ssh-agent bis zur nächsten Eingabe von ssh-add -x sperren. Wärend dieser Zeit ist ssh-agent unbenutzbar, eine gute Möglichkeit wenn man für eine bestimmte Zeit weg ist. ssh-agent agent forwarding ------------------ Ein weiteres feature ist agent forwarding, dabei "folgt" uns SSH von Rechner zu Rechner, bei jeder weiteren Verbindung erstellt der Server einen ssh-tunnel zurück mit einer Verbindung zum agent. Wichtig dabei ist das ssh-agent natürlich von jedem root auf dem Rechner ausgelesen werden kann, wenn agent forwarding aktiviert ist. Wir benutzen agent forwarding so: ------- Code ------- workstation:/home# ssh -A user@ssh-server ------- Code ------- In der globalen ssh_config Datei, die sich normalerweise in /etc/ oder /etc/ssh/ befindet können wir agent forwarding global ausstellen: ------- Code ------- Host * ForwardAgent no ------- End-Code ------- Wenn wir agent forwarding für einen bestimmten Server einschalten wollen, können wir das mit ForwardAgent yes machen: ------- Code ------- Host ssh-server-ip ForwardAgent yes ------- End-Code ------- Kapitel 2: Sicherheitstipps ------------------ In diesem Kapitel werden noch zusätzlich zu den vorherigen Tutorials Sicherheitstipps besprochen, wobei es sinnlos sein kann, wenn man einige kombiniert, es wird für dasselbe mehrere Möglichkeiten angeboten. Die Möglichkeit mit den begrenzten logins ist mit einem Pubkey oder mit einer Identity übrigens sinnlos. ;) Root login abschalten ------------------ Wenn es zum Konzept passt, kann man in der Datei ssh_config, die sich normalerweise in /etc/ oder /etc/ssh befindet, den login vom Benutzer root abschalten: ------- Code ------- PermitRootLogin no ------- End-Code ------- Falls nötig kann man immer noch mit su oder sudo arbeiten. Nur bestimmte User zulassen ------------------ Mit der Option AllowUser in der Datei ssh_config kann man nur bestimme User einloggen lassen: ------- Code ------- AllowUsers simon blubbfish ------- End-Code ------- Nur ein bestimmtes Land zulassen ------------------ (Das setzt voraus, dass ssh mit "--with-tcp-wrappers" konfiguriert wurde und die entsprechende Bibliothek vorhanden ist.) Wenn man für das einloggen nur ein bestimmtes Land zulassen will, kann man das in der Datei /etc/hosts.allow machen: ------- Code ------- sshd : .at : allow sshd : ALL : deny ------- End-Code ------- Maximale Login Versuche setzen ------------------ Wenn man nur ein paar login Versuche von einem Host zulassen will, kann man das mit MaxAuthTries in sshd_config machen: ------- Code ------- MaxAuthTries 1 ------- End-Code ------- Bruteforce Attacks mit iptables stoppen ------------------ Ich bin http://nodomain.cc/exit.php?url_id=816&entry_id=190]hier auf eine Lösung gestossen SSH mit iptables gegen Bruteforce zu schützen: ------- Code ------- #!/bin/sh IPTABLES="/sbin/iptables" TRUSTED_HOST="192.168.0.2" $IPTABLES -F $IPTABLES -X $IPTABLES -N SSH_WHITELIST $IPTABLES -A SSH_WHITELIST -s $TRUSTED_HOST -m recent --remove --name SSH -j ACCEPT $IPTABLES -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --set --name SSH $IPTABLES -A INPUT -p tcp --dport 22 -m state --state NEW -j SSH_WHITELIST $IPTABLES -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 60 --hitcount 3 --rttl --name SSH -j ULOG --ulog-prefix SSH_brute_force $IPTABLES -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 60 --hitcount 3 --rttl --name SSH -j DROP ------- End-Code ------- Wenn man innerhalb einer Minute mehr als 3 neue eingehende Verbindungen hat, werden die Verbindungen gedroppt. Benötigte Module: ipt_ULOG, ipt_state, ip_conntrack, ipt_REJECT, ipt_LOG, ipt_recent, iptable_filter, ip_tables Schlusswort ------------------ In diesem Tutorial haben wir gelernt SSH sicher zu benutzen und den ssh-agent richtig einzurichten. Dieses Tutorial ist vermutlich der letzte Teil, ausser wenn es noch Feedback wegen einem zusätzlichen Thema gibt ;)