ABSTRACT: die grundlagen fuer die anwendung von SSL (secure socket layer) verschluesselung werden erklaert. AUDIENCE: junior admin SYSTEM: any unix SECTION: basic unix commands AUTHOR: mond COPYRIGHT: GNU Free Documentation Licence http://www.gnu.org/licenses/fdl.txt wie man sichere verbindungen mit ssh oeffnet wissen wir ja schon. neben ssh gibt es aber auch andere protokolle die verschluesselte verbindungen zulassen. am gebraeuchlichsten ist SSL (secure socket layer). SSL arbeitet wie ssh ebenfalls mit "public key encryption". also einer verschluesselung, wo die eine haelfte des schluessels oeffentlich sein kann und der andere teil privat ist, man aber aus dem oeffentlichen schluessel den privaten nicht mehr (d.h nicht mit vertretbarem aufwand) gewinnen kann. SSL kann mit verschiedenen dieser verfahren arbeiten. (z.b. RSA "rivest shamir adleman" oder DH "diffie-hellman") SSL ist auch das protokoll das fuer gesichterte web verbindungen verwendet wird (d.h. auf https:// seiten). leider ist SSL wesentlich komplizierter als ssh. hat aber auch ein breiteres einsatzgebiet. prinzipiell kann man zwischen 2 arten von SSL einsatz unterscheiden: a) SSL wird transparent ueber ein service gelegt. d.h. es wird eine ganz normale verbindung z.b. pop3, http oder telnet verwendet aber das ganze in eine SSL verbindung eingepackt. zur unterscheidung ob man SSL oder das normale service verwenden will muss man bei SSL ein eigenes port verwenden. (z.b. port 443 statt port 80 fuer http) b) die SSL verbindung wird beim verbindungsaufbau als teil des normalen protokolls ausgehandelt. haben sich client und server auf die verwendung von SSL geeinigt so wird der rest der kommunikation ueber SSL abgewickelt. um den folgenden teil besser verstehen zu koennen hier ein kurzer ueberblick ueber die bei SSL verwendete terminologie: SSL speak: ========== * KEY - der private schluessel wird im SSL jargon "key" genannt. * CERT - zertifikat. der oeffentliche schluessel. eventuell kann dieser von verschiedenen authoritaeten unterschrieben sein die die echtheit der angaben bestaetigen. * CA - certification authority. eine institution die zertifikate unterschreibt und damit die identitaet bestaetigt. die zertifkate von einigen solcher organisationen sind in den wichtigsten browsern und mailprogrammen schon eingespeichert. hat man ein solcherart "offiziell" bestaetigtes zeriftikat so akzeptieren browser die verbindung ohne lang nachzufragen. fuer den privaten gebrauch kann man aber seine eigene CA sein. die einfachste variante ist ein "self-signed" zertifkat das seine echtheit selbst "bestaetigt". offizille CAs sind Thawte, VeriSign und andere organistaionen. Zertifikate fuer einen server kosten pro jahr etwa in der groessenordnung von etwa 100 bis 1000 euro. zur feststellung der identiaet muss man meist firmenbuchauszuege oder aehnliches faxen. * CSR "certificate signing request". eine anforderung mit bitte um signierung eines zertifikates. * PEM in welchem format die schluessel gespeichert werden. PEM orientiert sich am "privacy enhanced mail" format. PEM ist das unter unix am gebraeuchlichsten format fuer schluessel und zertifkat. ein cert und ein key in einem .pem file koennten z.b. so aussehen.: -----BEGIN RSA PRIVATE KEY----- M7ai2... ... ......44425jk -----END RSA PRIVATE KEY----- -----BEGIN CERTIFICATE----- SD89435... ... ...L8Zdj.. -----END CERTIFICATE----- da private key und cert jeweils duch andere BEGIN zeilen markiert sind kann im selben .pem file sowohl der key als auch das zugehoerige zertifikat gespeichert sein. * DER alterntaives format wie schluessel und zertifikate gespeichert werden. eher wenig gebraeuchlich. * X.509 ISO/ITU norm die die wesentlichen details der PKI (public key infrastruktur) definiert und die die grundlage fuer viele SSL relevante RFCs (RFC == die im intenet verwendeten normen fuer protokolle, dateiformate, etc.. - siehe http://www.ietf.org/rfc.html ) bildet. * x509v3 erweiterungen von X.509 die es erlauben zertifkate fuer einen bestimmten verwendungszweck zu kennzeichnen. z.b. nur als CA (zum zertifizieren von anderen zertifikaten, oder nur fuer clients oder server, etc..) * TLS steht fuer "transport layer security" und bezeichnet eine weiterentwicklung von SSL version 3.0, die in neueren protokollen zum einsatz kommt. die wichtigsten programme die SSL verschluesselung unterstuetzen: ================================================================= * stunnel ein programm dass es erlaubt beliebige protokolle/programme ohne eingriff mit SSL faehigekeiten auszusatten. stunnel uebernimmt die SSL verschluesselung und verbindet sich selbst dann mit dem unverschluesselten service. * sslwrap wie stunnel, jedoch vorwiegend zur verwendung in inetd gedacht. nachteil bei der verwendung von stunnel und sslwrap ist dass die programme selbst nicht mehr wissen mit wem sie jetzt kommunizieren. d.h. es erscheinen alle verbindungen von localhost. besser ist daher wenn die programme die ssl unterstuetzung eingebaut haben. * openssl das universalwerkzeug fuer den umgang mit SSL schluesseln und zertifikaten. kann diese erstellen, signieren, in verschiedenen formate umwandeln und hat nebenbei noch einen einfachen server und client modus eingebaut mit dem man SSL verbindungen testen kann. * apache es gibt vorallem 2 arten wie man apache mit SSL austatten kann: o apache-ssl: ein apache mit SSL unterstuetzung eingebaut o mod_ssl: ein modul dass bei bedarf SSL unterstuetzung in apache einfuegt. (es gibt auch eine komerzielle version von apache mit ssl unterstuetzung von stronghold diese wird aber seit der verfuegbarkeit obiger freier loesungen kaum noch verwendet) * ssl-telnet ein telnet und ein telnetd die als ersatz fuer den normalen telnet dienen koennen. wenn sowohl client als auch server SSL unterstuetzen wird dies beim telnet verbindungsaufbau ausgehandelt. die verbindung ist ab dann verschluesselt. * ... nungut auf zu einigen praktischen experimenten mit ssl. zuerst verbinden wir uns mit einerm SSL verschluessteln webserver auf das https port. z.b. mithilfe des client modus von openssl: openssl s_client -connect online.bankaustria.com:443 tippen wir dort GET / koennen wir haendisch ueber die verschluesslten verbindung eine website abfragen. (ist wie wenn wir mit https:// im webbrowser zugreifen). der s_client modus zeigt uns zusaetzlich alle parameter der gesicherten verbindung an. alternativ zu openssl c_client koennten wir auch ein ssl-faehigen telnet client verwenden. mit einer option muessen wir dem telnet allerdings mitteilen dass es die ssl verbindung nicht erst aushandeln sondern sofort voraussetzen soll: telnet -z ssl,verbose online.bankaustria.com 443 ( und dann z.b. wieder GET / um eine webseite abzufragen) -z erlaubt die angabe von ssl optionen. "ssl" besagt dass die verbindung mit ssl aufgebaut werden soll. "verbose" besagt dass wir davon auch etwas merken wollen. das ganze geht natuerlich nur mit einer ssl faehigen telnet version. nun wollen wir uns unseren eigenen key basteln damit wir selbst ein service betreiben koennen. wir benutzen openssl: openssl req -new -nodes -newkey rsa:1024 -keyout mykey.pem -out mycsr.pem obige zeile dient dazu einen "zertifizierungsrequest" zu behandel (req) wir wollen einen neuen request anlegen (-new) und im selben schritt auch gleich einen neuen schluessel anlegen (-newkey). den schluessel wollen wir im format RSA mit einer laenge von 1024 bits). die option -nodes besagt dass wir den schluessel nicht noch mit einer DES verschluesselung und einem passwort zusaetzlich schuetzen wollen. (der schluessel waere sonst nur mit dem passwort zusammen gueltig. aber wenn wir das fuer einen server einsetzen wollen ist eventuell niemand um 3 uhr morgens anwesend um nach einem stromausfall das passwort wieder neu einzutippen...) das CN attribut (common name -> siehe auch ldap_basics) sollte bei einem server key gleich dem hostnamen des servers sein. z.b CN=meinserver.irgendwo.at der schluessel findet sich dann in der datei mykey.pem und die zertifizierungsanforderung in der dateil mycsr.pem. es sind ascii im oben beschriebenen PEM format die man z.b. mit less ansehen kann. openssl bietet uns die moeglichkeit die in den datein enthaltenen info genauer zu untersuchen. z.b. mit: openssl rsa -in mykey.pem -text |less openssl req -in mycsr.pem -text |less wir unterschreiben jetzt unsere eigene zertifizierungsanfrage (mycsr.pem) mit unserem schluessel (mykey.pem) und produzieren damit ein x509 zertifikat (mycert.pem): openssl x509 -req -in mycsr.pem -signkey mykey.pem -out mycert.pem -days 365 alternativ koennten wir den CA modus benutzen um uns z.b. zertifikate fuer clients zu signieren. wir generieren uns zuerst wieder ein paar aus schluessel und .csr: openssl req -new -nodes -newkey rsa:1024 -keyout client-key.pem -out client-csr.pem und signieren es dann: openssl x509 -req -in client-csr.pem -out client-cert.pem -CA mycert.pem \ -CAkey mykey.pem -CAcreateserial -days 365 wir koennten jetzt unsere keys testen. z.b versuchen sie mit stunnel zu verwenden. stunnel will alledings key und cert in einem gemeinsamen file. dazu verwenden wir z.b. cat: cat mykey.pem mycert.pem > my.pem jetzt starten wir stunnel. wir koennten z.b. ein locales port 80 forwarden. als root: /usr/sbin/stunnel -f -d 7777 -p my.pem -r 80 (die option -f besagt "foreground" und ist praktisch zum testen) wir koennen jetzt unseren webbrowser auf port 7777 dieses hosts richten und haben dort eine gesicherte webverbindung. sicherheit von SSL verbindungen =============================== neben der (einstweilen noch relativ geringen) gefahr dass jemand im stande ist, die verwendete verschluesselung selbst zu knacken liegen die groessten gefahren eher in der anwendung des SSL protokolls. * wie bei SSH gilt: sind client oder server nicht vertraunswuerdig (d.h. eventuell gehackt) nuetzt das ganze verschluesseln nichts. * verbindet man sich mit einem anonymen (self-signed) server von dem man noch keinen key hat so bietet die SSL verbindung zwar schutz vor passivem abhoeren der verbindung (jemand der z.b. mit tcpdump am netzwerkkabel lauscht sieht den klartext-inhalt der verbindung nicht. ABER: * jemand der auf einem router zwischen client und server root rechte hat oder den netzwerkdatenstrom sonst irgendwie umbiegen kann (mit arp tricks wenn man am selben LAN segment haengt, etc..) kann dem client vorgaukeln dass er der server ist und kann somit die verbindung belauschen oder modifizieren ("man in the middle attack"). d.h. die verbindung ist NICHT besonders sicher. * einwenig schutz davor bietet ein offizielles zertifikat: man weiss zumindest mit wem man spricht. allerdings koennte es sich um ein gestohlenes oder erschwindeltes zertifikat handeln. * gerade bei SSL geschuetzten web seiten werden vermutlich 90% (oder mehr) aller server bei einer warnung dass etwas mit dem zertifikat nicht stimmen koennte ohnehin auf "OK" klicken ohne zu verstehen was vorsich geht.. der schutz ist also nicht wirklich stark. * hat man clients die automatisch connecten und will man vermeiden dass man einer "man-in-the-middle attack" erliegt so sollte man dem client nur erlauben auf bekannte server zu connecten. (SSH z.b. merkt sich nach einer ersten verbindungsaufnahme den schluessel des servers in .ssh/known_hosts). cp mycert.pem /etc/ssl/certs cd /etc/ssl/certs ln -s mycert.pem $(openssl x509 -hash -noout -in mycert.pem ).0 die meisten ssl programme erlauben es einzustellen welche sicherheit man verlangt: 1 ... das peer (peer = verbindungspartner) zertifikate wird ueberprueft falls vorhanden. 2 ... das peer zertifikat muss mit einer signatuer zertzifiziert sein die uns bekannt ist ( z.b. in /etc/ssl/certs ) die meisten programme erlauben es das directory in dem die certs gesucht werden einzustellen. 3 ... das zertifikat muss uns direkt bekannt sein (also nicht blos von einer bekannten cert unterschrieben sein) etwas unpraktisch daran ist dass die meisten implemenentierungen im falle von 3 keine "self-signed" zertifikate akzeptieren (auch wenn wir dazu ein cert haben). man muss also, wenn man einer "man-in-the-middle" attacke vorbeugen will, eine eigene private CA betreiben und sich damit seinen key signieren. echo GET / | stunnel -a /etc/ssl/certs/ -v 3 -c -r localhost:7777 obiger aufruf wuerde eine html site von localhost nur dann laden wenn wir sowohl 2 certs im /etc/ssl/cert haben, wovon die eine den key beschreibt der auf port 7777 hoehrt und die andere den der dessen zertifikat unterschrieben hat. akzeptieren wir alle schluessel sobald sie von einer uns bekannten CA unterschrieben wurden haben wir das problem dass sobald eine maschine kompromitiert wurde auf der ein unterschriebener schluessel liegt dass damit alle anderen rechner gefaehrdet sind. es gibt zwar mechanismen zur "certificate revocation". (CRL) aber trotzdem nicht ideal. * zuletzt soll noch erwaehnt werden: die key ueberpruefung kann auch in richtung client erfolgen. also ein server kann den key eines clients ueberpruefen. die problem dabei sind analog. erlaubt man alle clients die von einer bekannten CA unterschrieben sind? etc.. fazit: SSL verbindungen bieten relativ bequemen schutz vor passiven ^^^^^^ angriffen wie packet sniffern. aber auch wirklich sichere verbindungen sind moeglich, jedoch wesentlich aufwendiger und umstaendlicher zu handhaben als bei SSH. EXERCISES: * verbinde dich mit web-browser, stunnel, telnet (mit ssl), openssl s_client auf ein SSL port deiner wahl (z.b. deine hausbank) * generiere dir mit openssl einen self-signed key zur verwendung als eigene private CA. * generiere dir ein CSR das du mit obiger CA unterschreibst. * statte ein service deiner wahl mit sslwrap oder stunnel mit SSL faehikeiten aus. connecte dich mit einem SSL faehigen programm auf dieses service. experimentiere mit verschiedenen "verify"-level. REFERENCES: man openssl man stunnel man sslwrap man ssl http://www.openssl.org http://www.modssl.org/docs/ http://www.stunnel.org/ http://www.roko.goe.net/~dieter/pages/ssl.html http://www.apache-ssl.org/