SSH-Client-Konfiguration unter MacOS

Beim letzten Beitrag zur SSH-Konfiguration unter Cisco IOS und Cisco ASA fiel mir noch ein, dass man über sinnvolle Anpassungen der Client-Konfiguration auch mal schreiben sollte. Zumindest unter MacOS (und mindestens auch unter Debian und älterem Ubuntu Linux) wird standardmäßig nicht immer die optimale Kryptographie verwendet.
Die SSH-Parameter können an zwei Stellen konfiguriert werden:

  • systemweit unter /etc/ssh_config
  • per User unter ~/.ssh/config

In der systemweiten SSH-Config befinden sich z.B. die folgenden drei Zeilen, die weite Teile der verwendeten Kryptographie bestimmen (genauer gesagt zeigen sie die Defaults):

#Ciphers aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc,aes256-cbc,arcfour
#KexAlgorithms ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1
#MACs hmac-md5,hmac-sha1,umac-64@openssh.com,hmac-ripemd160,hmac-sha1-96,hmac-md5-96,hmac-sha2-256,hmac-sha2-256-96,hmac-sha2-512,hmac-sha2-512-96

Was kann/sollte man ändern:

Ciphers

Wer keine legacy Systeme zu pflegen hat, der könnte alle nicht-AES ciphers entfernen. Aber Geräte wie 2950 Switche sind halt auch noch ab und an anzutreffen. Daher muss man in so einem Fall 3des-cbc auch konfiguriert haben. Die Cipher-Zeile könnte dann folgendermaßen aussehen:

Ciphers aes256-ctr,aes128-ctr,aes256-cbc,aes128-cbc,3des-cbc

Laut Manpage (und basierend auf der sowohl unter Mavericks und Yosemite verwendeten OpenSSH-Version 6.2p2) sollten auch die moderneren GCM-Typen unterstützt sein. Wenn die konfiguriert sind, meldet der SSH-Client aber „Bad SSH2 cipher spec“.
Beim Zugriff auf Cisco Router und Switche kommen typischerweise die CBC-Versionen zum Einsatz, da CTR erst ab IOS 15.4 unterstützt ist.

KexAlgorithms
Hier wird der Key-Exchange gesteuert. Meine Konfig-Zeile auf dem Mac ist die folgende:

KexAlgorithms diffie-hellman-group-exchange-sha256,diffie-hellman-group14-sha1,diffie-hellman-group-exchange-sha1,diffie-hellman-group1-sha1

Die ElipticCurve Algorithmen habe ich entfernt, da diese im Verdacht stehen Backdoors zu beinhalten. Die vermutlich vertrauenswürdige curve25519 von D.J. Bernstein ist erst in OpenSSH 6.6p1 enthalten. Diese werde ich bei Verfügbarkeit mit aufnehmen. Als letztes in der Zeile ist weiterhin ein Group1-Exchange (768 Bit), der für Legacy-Geräte benötigt wird.

MACs
Am meisten stört mich, dass eine MD5-Methode die höchste Priorität hat, gefolgt von einer SHA1-Methode. Da sollte die Reihenfolge angepasst werden:

MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512,hmac-sha2-256,hmac-ripemd160,hmac-sha1

Interessant sind die etm-MACs. Dazu ein kleiner Ausflug in Message Authentication Codes. Die Protokolle SSL, IPsec und SSH verwenden standardmäßig verschiedene Methoden um die Daten zu verschlüsseln und die Integrität zu sichern:

  • SSL: mac-then encrypt. Dabei wird erst der MAC gebildet, dann werden Daten und MAC verschlüsselt.
  • IPsec: encrypt-then-mac. Dabei werden die Daten erst verschlüsselt und dann darüber der MAC gebildet.
  • SSH: encyrpt-and-mac. Die Daten werden verschlüsselt, die MAC wird aber über die Klartextdaten gebildet.

Es hat sich herausgestellt, dass von diesen drei Optionen die von IPsec verwendete Methode die sicherste ist. Diese encrypt-then-mac (etm) Verfahren können auch bei SSH verwendet werden.

Update: In RFC 7366 wird eine TLS-Erweiterung definiert, die auch die Verwendung von “encrypt then mac” benutzt.

Was hat sich jetzt beim Zugriff auf ein IOS-Gerät geändert? Ohne diese Anpassungen sieht die SSH-Session so aus (auf einem Cisco 3560 mit IOS 15.0(2)SE5):

c3560#sh ssh
Connection Version Mode Encryption  Hmac	 State	            Username
1          2.0     IN   aes128-cbc  hmac-md5     Session started   ki
1          2.0     OUT  aes128-cbc  hmac-md5     Session started   ki

Es wird aes-128-cbc mit einem MD5-HMAC verwendet. Nach den Änderungen ist die Krypto etwas besser (im Rahmen der Möglichkeiten des IOS):

c3560#sh ssh
Connection Version Mode Encryption  Hmac	 State	           Username
0          2.0     IN   aes256-cbc  hmac-sha1    Session started   ki
0          2.0     OUT  aes256-cbc  hmac-sha1    Session started   ki

Hier noch einmal die resultierende ~/.ssh/config:

Ciphers aes256-ctr,aes128-ctr,aes256-cbc,aes128-cbc,3des-cbc
KexAlgorithms diffie-hellman-group-exchange-sha256,diffie-hellman-group14-sha1,diffie-hellman-group-exchange-sha1,diffie-hellman-group1-sha1
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512,hmac-sha2-256,hmac-ripemd160,hmac-sha1

Update:
Nach einigem Nachdenken kam ich zu dem Ergebnis, dass mir die Aufnahme der Legacy-Verfahren in die Config-Datei irgendwie nicht gefällt. Daher habe ich diese wieder rausgeschmissen und gebe bei der Verbindung zu älteren Geräten die benötigte Crypto direkt an. Hier ein Beispiel für den Zugriff auf einen 2950:

ssh -l ki 10.10.10.200 -o Ciphers="3des-cbc" -o KexAlgorithms="diffie-hellman-group1-sha1"

Und hier die angepasste ~/.ssh/config:

Ciphers aes256-ctr,aes128-ctr,aes256-cbc,aes128-cbc
KexAlgorithms diffie-hellman-group-exchange-sha256,diffie-hellman-group14-sha1,diffie-hellman-group-exchange-sha1
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512,hmac-sha2-256,hmac-ripemd160,hmac-sha1

Weitergehende Verbesserungsvorschläge werden gerne angenommen.

SSH-Client-Konfiguration unter MacOS

Konfiguration von SSH auf Cisco ASA und IOS

Ab und zu erschrecke ich doch was Cisco-Mitarbeiter so verzapfen. Jetzt hat gerade einer in der Cisco Support-Community ein Dokument zur Konfiguration von SSH auf der ASA veröffentlicht. Und da liest man z.B., dass die Keysize von 1024 Bit benutzen werden soll. Und nichts weiter zu heutigen “Best Practices” der SSH-Konfig. Grund genug eine in meinen Augen “anständige” SSH-Konfig für IOS-Geräte und die ASA zu zeigen:

Cisco IOS
Es geht damit los, ein RSA-Keypair zu generieren, das nur für den SSH-Prozess verwendet wird. Dafür wird dem Keypair ein Label mitgegeben:

crypto key generate rsa label SSH-KEY modulus 4096

Etwas Gedanken sollte man sich über die Keylänge machen. Länger bedeutet zum einen sicherer, aber auch langsamer. Allerdings nicht so langsam, dass es nicht benutzbar wäre. Damit ist die Entscheidung recht einfach. Allgemeine Hinweise zu minimalen Keylängen findet man u.a. auf http://www.keylength.com

Das RSA-Keypair wird der SSH-Konfig zugewiesen:

ip ssh rsa keypair-name SSH-KEY

Nur SSHv2 erlauben:

ip ssh version 2

Beim Verbindungsaufbau werden die Session-Keys per Diffie-Hellman erzeugt. Das ist standardmäßig mit der Gruppe 1 (768 Bit) erlaubt, was nicht mehr state-of-the-art ist. Daher wird eine höhere DH-Gruppe konfiguriert. Jetzt ist es aber so, dass die aktuelle Version (0.63) von Putty mit einem 4096 Bit Key-Exchange nicht klar kommt. Sowohl mit SecureCRT, als auch mit dem eingebauten SSH von Mac OS und Linux klappt es aber. Wer per Putty administrieren will, sollte hier also nur 2048 verwenden, was natürlich auch sehr sicher ist.

ip ssh dh min size 4096

Login-Vorgänge sollten protokolliert werden:

ip ssh logging events

Als letztes wird auf der VTY-Line nur SSH erlaubt. Telnet ist damit abgeschaltet.

line vty 0 4
  transport input ssh

Was könnte man sonst noch für SSH konfigurieren: Ab und an kommt der Wunsch auf, für SSH nicht den Port TCP/22 zu verwenden. Das erhöht zwar nicht unbedingt die Sicherheit, sorgt aber dafür, dass die Logs etwas kleiner bleiben wenn SSH vom Internet aus erreichbar ist:

ip ssh port 7890 rotary 1
line vty 0 4
  rotary 1

Wenn der Zugriff über ein Interface erfolgt, auf dem eine eingehende ACL konfiguriert ist, dann muss in dieser die Kommunikation natürlich auch erlaubt werden.

Weitere Schutzmechanismen über die nachgedacht werden können sind Control-Plane-Protection und Management-Plane-Protection wenn out-of-band Management verwendet wird. Wenn der SSH-Zugriff nicht von “any” benötigt wird, dann sollte für die Lines natürlich auch eine Access-Class konfiguriert werden. Aber auch das ist nicht SSH-spezifisch.

Cisco ASA
Für die ASA gilt so ziemlich das oben genannte, nur das die SSH-Konfiguration nicht so umfangreich angepasst werden kann. Weiterhin ist die Syntax teilweise anders:

crypto key generate rsa modulus 4096
ssh version 2
ssh key-exchange group dh-group14-sha1

Die Key-Länge ist hier auch von der Plattform abhängig. Die Legacy-ASAs unterstützen keine Keys mit mehr als 2048 Bit. Auf den aktuellen -X-Geräten kann aber auch 4096 Bit genutzt werden.

Auch muss der SSH-Zugriff auf der ASA explizit für die Management-IPs erlaubt werden:

ssh 10.10.0.0 255.255.0.0 inside
ssh 192.0.2.100 255.255.255.255 outside
Konfiguration von SSH auf Cisco ASA und IOS

Cisco IOS: Interface-ACLs für VPNs

Jeder Router, der mit dem Internet verbunden ist, sollte mit einer eingehenden Access-Liste (ACL) auf dem externen Interface konfiguriert sein, der den Zugriff auf den Router einschränkt. In diesem Beitrag zeige ich, wie so eine ACL aussehen kann.

Anmerkung1: Die gezeigte Konfig gilt nur für IOS-Versionen 12.4+. Bei älteren IOS-Releases ist etwas mehr Konfiguration notwendig.
Anmerkung2: Dies gilt nicht für die ASA da dort so eine ACL nicht benötigt wird. Auf der ASA filtert die Interface-ACL standardmäßig nur den durch die ASA durchgehenden Traffic, aber nicht den Traffic, der zur ASA selbst gesendet wird.

Die folgenden Beispiele basieren auf der folgenden Topologie:
VPN-Interface-ACLs

Voraussetzungen:
Der Router sollte mit einer Stateful-Firewall-Konfig versehen sein, die Antwort-Pakete auf selbst generierten Traffic ohne ACEs erlaubt. Das ist Bestandteil der Baseline-Security und vereinfacht die Konfiguration. In diesen Beispiel wird das ältere CBAC verwendet, da es deutlich einfacher zu verstehen und implementieren ist, als die leistungsfähigere Zone-Based-Firewall:

ip inspect name FW ftp
ip inspect name FW tcp router-traffic
ip inspect name FW udp router-traffic
ip inspect name FW icmp router-traffic
!
interface GigabitEthernet0/0
  ip access-group SITE-A-INTERNET-IN in
  ip inspect FW out
!
ip access-list extended SITE-A-INTERNET-IN
  deny ip any any

Basierend auf dieser Konfiguration wird die ACL mit den benötigten ACEs ergänzt.

Scenario 1: Site-to-Site VPNs mit statischen VPN-Peers
Bei diesem einfachen Beispiel wird angenommen, dass alle Peers eine statische public IP haben, die zwischen den beiden Gateways nicht genatted werden. Der in der ACL benötigte Traffic ist IP-Protocol 50 (ESP) und UDP/500 (ISAKMP). Viele Beispiele im Internet haben auch ACEs für IP/51 (AH), dies wird aber normalerweise nicht für VPNs verwendet.

Als erstes wird eine Object-Group für alle VPN-Peers erstellt (Object-Groups benötigen mindestens IOS 12.4(20)T+):

object-group network IPSEC-PEERS
  host 198.51.100.1
  host 203.0.113.1

Dann wird in der ACL der ESP- und ISAKMP-Traffic von den VPN-Peers zum Router-Interface erlaubt:

ip access-list extended SITE-A-INTERNET-IN
  permit esp  object-group IPSEC-PEERS host 192.0.2.1
  permit udp  object-group IPSEC-PEERS host 192.0.2.1 eq isakmp
  permit icmp object-group IPSEC-PEERS host 192.0.2.1 echo

Die letzte Zeile ist für die VPN-Funktionalität natürlich nicht nötig, erleichtert aber das Troubleshooting.

Scenario 2: VPN-Peers hinter einem NAT-device mit statischen IPs
Wenn ein oder beide IPsec-Peers sich hinter einem NAT-Device befinden, dann verwendet IPsec NAT-Traversal, das auch mit UDP/500 anfängt, aber dann auf UDP/4500 wechselt.

Dafür werden die folgenden Einträge benötigt:

ip access-list extended SITE-A-INTERNET-IN
  permit esp  object-group IPSEC-PEERS host 192.0.2.1
  permit udp  object-group IPSEC-PEERS host 192.0.2.1 eq isakmp non500-isakmp
  permit icmp object-group IPSEC-PEERS host 192.0.2.1 echo

Die Einträge in der Object-Group sind weiterhin die public IPs der Router, nicht die realen IP-Adressen der Router.
Wenn alle Router hinter einem NAT-Device sind, dann wird der ACL-Eintrag für ESP (IP/50) nicht benötigt, da dann der gesamte User-Traffic über UDP/4500 gesendet wird.

Scenario 3: IPsec-Peers mit dynamischer IP-Adresse
Dies ist das typische Remote-Access-Scenario, oder aber auch verwendet, wenn z.B. Branchoffices mit günstigen Kabel- oder DSL-Anschlüssen betrieben werden, für die keine festen IPs verfügbar sind. Daraus resultiert die folgende ACL:

ip access-list extended SITE-A-INTERNET-IN
  permit esp any host 192.0.2.1
  permit udp any host 192.0.2.1 eq isakmp non500-isakmp
  ! generally allow ping from the internet if your security-policy allows that:
  permit icmp any host 192.0.2.1 echo

In diesem Scenario wird die Object-Group mit den IPsec-Peers nicht benötigt, da deren IP im Vorwege sowieso nicht bekannt sind.

Viel Spaß beim Absichern der VPNs!

Cisco IOS: Interface-ACLs für VPNs

Cisco Access-Control-Listen

routerImmer wieder stelle ich fest, dass manche Admins eine der wichtigsten Erweiterungen der Cisco Access-Listen verpasst haben:

Access-Listen lassen sich komfortabel editieren
Seit einiger Zeit (nein, an das genaue Release erinnere ich mich nicht mehr) haben die ACEs (Access-List-Entries) Sequenznummern, die man beim show access-lists sehen kann:

c1841#sh access-lists    
Extended IP access list 100
    10 permit icmp any any (5 matches)
Extended IP access list TEST
    10 permit icmp any any (5 matches)
    20 permit udp any any
    30 permit esp any any

Diese Sequenznummern können verwendet werden, um neue ACEs einzufügen. Dazu muss eine bisher nicht verwendete Nummer genommen werden:

c1841(config)#ip access-list ext TEST
c1841(config-ext-nacl)#15 permit tcp any any 
c1841(config-ext-nacl)#
c1841(config-ext-nacl)#do sh ip access-list TEST
Extended IP access list TEST
    10 permit icmp any any (5 matches)
    15 permit tcp any any
    20 permit udp any any
    30 permit esp any any
c1841(config-ext-nacl)#

ACEs können natürlich auch gelöscht werden:

c1841(config-ext-nacl)#no 10
c1841(config-ext-nacl)#do sh ip access-list TEST
Extended IP access list TEST
    15 permit tcp any any
    20 permit udp any any
    30 permit esp any any
c1841(config-ext-nacl)#

Wenn in einer ACL keine freien Sequenznummern mehr zur Verfügung stehen, können diese neu gebildet werden. Bei einem Reload werden diese mit einem Startwert von 10 und einer Schrittweite von 10 gebildet.

c1841(config)#ip access-list resequence TEST 50 20 
c1841(config)#
c1841(config)#do sh ip access-list TEST           
Extended IP access list TEST
    50 permit tcp any any
    70 permit udp any any
    90 permit esp any any
c1841(config)#

Wer noch an seinen nummerierten ACLs hängt, kann die Editier-Funktionen natürlich auch benutzen. Dafür muss die Nummer einfach wie ein Name in den named ACLs verwendet werden:

c1841(config)#ip access-list extended 100
c1841(config-ext-nacl)#20 deny ip any any log
c1841(config-ext-nacl)#
c1841(config-ext-nacl)#do sh ip access-list 100
Extended IP access list 100
    10 permit icmp any any (5 matches)
    20 deny ip any any log
c1841(config-ext-nacl)#

Weitere Funktionen, die bei den ACLs in der Vergangenheit hinzugekommen sind:

Direktes Anzeigen der ACL zu einem Interface

c1841#sh ip access-list interface loo11
Extended IP access list TEST in
    10 permit icmp any any (5 matches)
c1841#
c1841#sh ip access-list interface loo12
Extended IP access list TEST in
    10 permit icmp any any (10 matches)
c1841#
c1841#sh ip access-list interface loo13
Extended IP access list TEST in
    10 permit icmp any any (15 matches)
Extended IP access list TEST2 out
    10 permit tcp any any

Obwohl dieselbe ACL auf drei verschiedenen Interfaces gebunden wurde, werden getrennte Statistiken geführt.

Mehrere Ports pro ACE

c1841(config)#ip access-list ext IPSEC
c1841(config-ext-nacl)#permit esp any any
c1841(config-ext-nacl)#permit udp any any eq isakmp non500-isakmp 
c1841(config-ext-nacl)#
c1841(config-ext-nacl)#do sh access-list IPSEC
Extended IP access list IPSEC
    10 permit esp any any
    20 permit udp any any eq isakmp non500-isakmp
c1841(config-ext-nacl)#

Natürlich verliert man bei dieser Konfiguration die getrennten Counter für die unterschiedlichen Ports (hier 500 und 4500).

ACLs können auf weitere Felder wie z.B. den TTL-, den DSCP-Wert oder TCP-Flags filtern

c1841(config)#ip access-list extended TEST3
c1841(config-ext-nacl)#permit icmp any any ttl gt 128
c1841(config-ext-nacl)#permit udp any any dscp ef 
c1841(config)#ip access-list extended TEST4
c1841(config-ext-nacl)#permit tcp any any match-all +syn +ack +fin -urg 

Im zweiten Beispiel wird TCP-Traffic erlaubt, der sowohl das SYN, ACK und FIN-Bit trägt, aber nicht das URG-Bit.

Gruppieren von Network- oder Service-Objekten
Wer sich traut, das IOS 12.4(20)T einzusetzen, hat sogar die Möglichkeit, Object-Groups zu verwenden, wie es die PIX bzw. ASA schon lange vorgemacht hat:

c1841(config)#object-group network RFC1918
c1841(config-network-group)#10.0.0.0 0.255.255.255
c1841(config-network-group)#172.16.0.0 0.15.255.255
c1841(config-network-group)#range 192.168.0.0 192.168.255.255
c1841(config-network-group)#exit
c1841(config)#
c1841(config)#ip access-list extended TEST5
c1841(config-ext-nacl)#permit icmp any object-group RFC1918 

Setzen von Cookies für das Logging
Ab 12.4(22)T kann an das Keyword log oder log-input ein “Cookie” angehängt werden, das als Tag zum Syslog-Server mitgesendet wird:

c1841(config)#ip access-list ext TEST6
c1841(config-ext-nacl)#deny icmp host 10.1.1.1 host 10.2.2.2 log BewareOfTheseHosts
c1841(config-ext-nacl)#
c1841(config-ext-nacl)#do sh ip access-lists TEST6
Extended IP access list TEST6
    10 deny icmp host 10.1.1.1 host 10.2.2.2 log (10 matches) (tag = BewareOfTheseHosts)
c1841(config-ext-nacl)#

Auf dem Syslog-Server kommt dieses Tag mit der Log-Meldung an und kann z.B. gefiltert werden:

%SEC-6-IPACCESSLOGDP: list TEST6 denied icmp 10.1.1.1 -> 10.2.2.2 (0/0), 10 packets  [BewareOfTheseHosts]
Cisco Access-Control-Listen

Vergleichen von IOS-Features

In der Vergangenheit war der Feature Navigator das Mittel der Wahl um herauszufinden, ob ein Image ein bestimmtes Feature unterstützt oder nicht. Mit der Umstellung des “Download IOS Software”-Bereichs auf die “Download Area” ist eine neue Möglichkeit hinzu gekommen. Dort kann man sich nicht nur die unterstützten Features eines Images anzeigen lassen, sondern auch die Features zweier Images vergleichen:
downloadarea

Vergleichen von IOS-Features

Welches Cisco IOS sollte man verwenden?

Ok, eigentlich lässt sich diese Frage nicht wirklich allgemein beantworten. Trotzdem wird sie mir häufiger mal gestellt. Ohne auf die nähere Umgebung eines Fragestellers einzugehen, war meine bisherige Antwort meist: “Ein relativ neues und gut gepatchtes MD-Release wie das 12.4.13f. Oder 12.4(15)T7 wenn man die neuesten Funktionen benötigt oder VPNs einsetzt”.

Seit dem 3. Dezember ist aber das IOS 12.4(15)T8 verfügbar. Dieses hat Cisco, obwohl es ein T-Release ist, zum Maintenance Deployment (MD) befördert und verspricht Updates bis Dezember 2010.

Von daher wird sich in Zukunft meine Antwort auf solche Fragen vermutlich auf folgendes reduzieren können: “Das neuste 12.4(15)T-Release.”

Welches Cisco IOS sollte man verwenden?