Securing openSSH (ssh-audit)

Dank einem Kollegen habe ich das nette Python Script „ssh-audit“ zum Auditing des SSH Daemons auf GitHub gefunden. Das Tool prüft Host Keys und Ciphers einer SSH Instanz und gibt direkt sinnvolle Empfehlungen zur Absicherung aus.

Die Absicherung von openSSH ist tatsächlich etwas, mit dem man sich im Normalfall recht wenig beschäftigt. Dennoch macht es massiv Sinn die paar Minuten Zeit zu investieren.

Ich hatte bereits einige Ciphers in meiner SSH Config hinterlegt, dennoch war etwas Raum für Verbesserung. Mit meiner ursprünglichen Konfiguration hatte ich in Sachen versuchter SSH Angriffsversuche bereits merklich Besserung gegenüber der CentOS Default Konfiguration gespürt (in Verbindung mit fail2ban). Statt fast 1000 Angriffen und Blocks pro Tag hatte ich mit meiner Cipher Konfiguration nur noch rund 100 Einträge im fail2ban Log. Mit der neuen Konfiguration (und dem deaktivieren von DSA und ECDSA) konnte ich die Anzahl nochmal auf ca. 10 pro Tag minimieren.

Das liegt insbesondere daran, das meist ältere (nicht mit Sicherheitsupdates versorgte) Systeme gehackt und für derartige SSH Scans und Angriffe verwendet werden. Die dort installierten SSH Clients unterstützen jedoch in der Regel nicht die aktuellsten SSH Sicherheitsstandards und kommen somit gar nicht zum Verbindungsaufbau.

Eine mögliche Konfiguration für ein CentOS 7 System sieht folgendermaßen aus.

# disable DSA and ECDSA host keys
#HostKey /etc/ssh/ssh_host_dsa_key
#HostKey /etc/ssh/ssh_host_ecdsa_key
HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_ed25519_key

# force strong ciphers
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr
KexAlgorithms curve25519-sha256@libssh.org
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,umac-128-etm@openssh.com

Das ganze setzt einen aktuellen SSH Client voraus. Ältere Putty Installationen müssen u.U. geupdated werden.

Prepare Windows (WinRM) for Ansible

Bekanntlich lassen sich mit Ansible auch Windows Maschinen via WinRM managen.

Bei einer Standardinstallation von Windows ist WinRM deaktiviert. Das ganze lässt sich zwar relativ einfach via „winrm quickconfig“ aktivieren, jedoch wird mit diesem Kommando lediglich der Plaintext Port geöffnet. Dies ist gerade für Produktionsumgebungen nicht empfehlenswert.

Als mögliche Alternative können die benötigen Zertifikate entweder via Windows CA enrolled werden (sofern vorhanden), oder man nutzt einfach diesen nützlichen PowerShell Oneliner, der WinRM automatisch mit Self Signed Zertifikaten konfiguriert.

Invoke-Expression ((New-Object System.Net.Webclient).DownloadString('https://raw.githubusercontent.com/ansible/ansible/devel/examples/scripts/ConfigureRemotingForAnsible.ps1'))

Das Script öffnet auch direkt den nötigen SSL Listener Port in der Windows Firewall, der bei der Verwendung von SSL manuell freigeschaltet werden muss.

Gefunden in der Doku von pywinrm.

NetScaler Gateway sends wrong Host-Header to StoreFront

In gewissen Konstellationen kommt es bei NetScaler Gateway Deployments trotz korrekter Konfiguration dazu das Requests an Storefront mit dem externen DNS-Namen des NetScaler Gateways an Storefront weitergeleitet werden.

Dabei scheint es sich um einen Bug im Build 11.1-51.21 zu handeln. Der Bug kommt jedoch nur dann zum Vorschein wenn im UserAgent „CitrixReceiver“ vorkommt. Dabei ist es irrelevant wie die Session Policies konfiguriert sind, daher vermute ich eine defekte Clienterkennung innerhalb des NetScalers.

Das ganze lässt sich nachvollziehen indem man z.B. mein NetScaler Nagios Plugin um einen UserAgent erweitert. Wie genau dieser lautet ist egal, solange irgendwo im String „CitrixReceiver“ vorkommt.

$lwp->agent("CitrixReceiver/MyTestClient");

Das Resultat in einem Test Setup mit einer Sophos UTM als Loadbalancing sieht folgendermaßen aus.

root@web01:/opt/check_netscaler_gateway 
-bash# ./check_netscaler_gateway.pl -H gateway.linux-dev.ext -u username -p password -v
** POST https://gateway.linux-dev.ext/cgi/login ==> 302 Object Moved
** POST https://gateway.linux-dev.ext/cgi/setclient?wica ==> 200 OK
** POST https://gateway.linux-dev.ext/Citrix/StoreWeb/Home/Configuration ==> 403 Forbidden
NetScaler Gateway CRITICAL - request to https://gateway.linux-dev.extCitrix/StoreWeb/Home/Configuration failed with HTTP 403

Der „fehlerhafte“ Request wird von der Sophos UTM als möglicher Angriffsversuch erkannt und geblockt. Das ganze könnte jedoch auch bei anderen Loadbalancern oder einem Setup mit aktiviertem SNI auftreten.

Als Workaround kann eine Rewrite Policy genutzt werden, die den Host-Header mit dem internen DNS-Namen ersetzt (z.B. storefront.linux-dev.local).

add rewrite action act_rewrite_hostname replace HTTP.REQ.HOSTNAME "storefront.linux-dev.local"
add rewrite policy pol_rewrite_hostname true act_rewrite_hostname
bind vpn vserver vs_vpn_citrix -policy pol_rewrite_hostname -priority 100 -gotoPriorityExpression END -type REQUEST

Diese Policy ersetzt den Header bei jedem HTTP-Request in das Backend mit dem korrekten Namen. Diese Policy funktioniert so nur in „ICA Only“ Deployments. Für Setups mit Smartaccess (Clientless VPN) sind weitere Anpassungen notwendig.

SMS Passcode: Login mit sAMAccountName unterbinden

SMS Passcode ist eine Software für die 2-Faktor-Authentifizierung. Sie generiert OTPs die dem User auf verschiedenen Wegen zugestellt werden können, z.B. via Software Token App auf dem Handy, E-Mail, Telefonanruf, API, oder eben SMS. SMS Passcode setzt dabei auf den Network Policy Server (den RADIUS Dienst von Microsoft) auf. SMS Passcode lässt sich durch die RADIUS Architektur sehr einfach an jeden RADIUS kompatiblen Dienst anbinden, u.a. an den Citrix NetScaler.

SMS Passcode kann Passwörter bzw. User Accounts mit „Windows NT“ über das Active Directory (via Computer Account in der Domäne) oder LDAP (via LDAP Bind) auflösen. Auch im LDAP Mode ist aber trotz richtiger Konfiguration auch immer der Login via sAMAccountName möglich, selbst wenn der sAMAccountName explizit nicht als Benutzername angegeben oder importiert wird.

Problematisch ist dies in Multi-Domain-Setups, in denen ausschließlich mit einem Login mit dem userPrincipalName gerechnet wird, etwa wenn Citrix StoreFront ohne Default Domains betrieben wird. Hier funktioniert nur der Login mit dem Domänenprefix (DOMAIN\username) bzw. dem userPrincipalName (user@domain.local).

Falls User aus der Gewohnheit heraus den Login mittels sAMAccountName versuchen klappt dieser zwar, das NetScaler Gateway kennt jedoch die für das SSO nötige Domain des Users nicht. Die Folge ist eine „Permission Denied“ Fehlermeldung von Storefront nach erfolgreicher Authentifizierung.

Es gibt jedoch eine einfache Möglichkeit Loginversuche via SAM auf der Windows NPS Ebene zu unterbinden, um Benutzer nicht in dieses Problem laufen zu lassen.

SMS Passcode - NPS Policy

In der Connection Request Policy im NPS kann eine Condition für den Usernamen konfiguriert werden. Hier sind auch Regular Expressions supported.

# Regular Expression für den userPrincipalName
^.*\@.*$

Mit dieser Condition wird geprüft ob der Username mindestens ein @-Zeichen enthält. Falls nicht, greift die Policy nicht. Gibt es keine andere machende Policy, schlägt der Login komplett fehl.

NetScaler Gateway Nagios Plugin

Ich habe gestern einen sehr interessanten Beitrag zum Thema Storefront und cURL gefunden (Login to Storefront with cURL). In diesem Blog ist beschrieben wie man mittels PowerShell den Login auf einem NetScaler Gateway durchführen kann um sich ein funktionierendes ICA File herunterladen zu können.

Auf dieser Basis habe ich mich mal an die Arbeit gemacht und das ganze in Perl und LWP übersetzt. Entstanden ist ein weiteres, kleines Nagios Plugin zur Überwachung eines Citrix NetScaler Gateway Deployments in Verbindung mit

-bash# ./check_netscaler_gateway.pl -H citrix.example.com -u monitoring -p password -S Lab -v
** POST https://citrix.example.com/cgi/login ==> 302 Object Moved
** POST https://citrix.example.com/cgi/setclient?wica ==> 200 OK
** POST https://citrix.example.com/Citrix/LabWeb/Home/Configuration ==> 200 OK
** POST https://citrix.example.com/Citrix/LabWeb/Authentication/GetAuthMethods ==> 200 OK
** POST https://citrix.example.com/Citrix/LabWeb/GatewayAuth/Login ==> 200 OK
** POST https://citrix.example.com/Citrix/LabWeb/Resources/List ==> 200 OK
** GET https://citrix.example.com/cgi/logout ==> 200 OK
NetScaler Gateway OK - Admin Desktop; CAD Desktop; Calculator; HDX Desktop; HDX TS Desktop; Server 2016 Desktop; Windows 8 Desktop; XA 2012 Desktop;

Das Plugin emuliert den kompletten Login Prozess eines Users von NetScaler Gateway über SSO zum Storefront bis hin zum Auflisten der Applikationen. Der Code steht auf GitHub bereit.

Im Fehlerfall lässt sich mittels –verbose Parameter direkt feststellen an welcher Stelle es Probleme gibt.