< Startseite >

OpenVPN - mit sicheren Kommunikationswegen einen sicheren Zugang ins heimische Netzwerk herstellen

Datenschutz zum ersten (gegen Ausspähen), Schutz der eigenen Daten zum zweiten (gegen Manipulation), sichere Kommunikationswege zum dritten (gegen Abhören)... das ist hier in diesem Artikel mein Thema.

Inhaltsübersicht über die Kapitel dieses Artikels:

>  Was ist OpenVPN?

>  Wann kann ich es nutzen?

>  Was kann es für mich tun?

>  Überblick - Was ist alles zur Einrichtung von OpenVPN notwendig ?

>  Setup DSL-Router

>  Deb-Package für OpenVPN erstellen und installieren

>  Ein paar Basics zu Protokollen, Verschlüsselung und Perfect Forward Secrecy

>  Erstellen der Konfigurationsdateien, Keyfiles, Zertifikate und Service-Units

     >   Konfigurations-Dateien

     >   Zertifikate und Key-Files

     >   Certificate Revocation List  (CRL)

     >   HMAC-Firewall

     >   Service-Units

>  Setup Server

>  Setup Clients

>  Setup Android-Clients

>  Änderungsprotokoll

 

Kontinuierlich dem schon in meinen anderen Artikeln vorhandenen Security-Leitfaden folgend, befasst sich auch dieser Artikel wieder mit dem Thema Sicherheit, hier mit den beiden Aspekten Datenschutz und Schutz meiner Daten. Das sind tatsächlich zwei unterschiedliche Aspekte, der Datenschutz richtet sich gegen den unbemerkten, heimlichen und missbräuchlichen Zugriff durch Fremde, der Schutz meiner Daten richtet sich gegen unerlaubte Manipulation, Verlust oder Zerstörung. In diesem Artikel geht es um sichere Kommunikationswege. Im weiteren Sinne ist damit also ein Schutz gegen Zugriff auf meine Daten durch Fremde von außerhalb gemeint. Das betrifft sowohl meine Daten im heimischen LAN als auch die Daten meiner mobilen Aktivitäten, wenn ich auf Reisen Account- oder Zugangsdaten auf einer Web-Site eingeben soll/muss/will, um zum Beispiel unterwegs mal schnell einen Blick in mein Online-Postfach zu werfen. Speziell beim Letzteren geht es darum, das mögliche Belauschen der Verbindung und der Datenübertragungen durch Fremde vollständig zu unterbinden, wenn ich mich mit meinem Laptop an offenen WLAN-AccessPoints verbunden habe. Wir haben es hier also mit zwei unterschiedlichen Aspekten zu tun, die allerdings beide mit dem gleichen Werkzeug verfolgt und gelöst werden.... und zwar mit OpenVPN. In diesem Artikel befasse ich mich also mit OpenVPN und versuche Antworten auf die folgenden Fragen zu finden. Was ist OpenVPN? Was kann es für mich tun? Wann kann ich es nutzen? Wie richte ich es ein? Fangen wir mit der ersten Frage an.

Was ist OpenVPN?

Den Wortanteil "Open" im Namen des Paketes muss man wohl nicht erläutern... es ist halt ein Programm aus einer Open-Source-Community. Der Wort-Anteil "VPN" steht für "Virtual Private Network". OpenVPN ist also eine Netzwerk-Software, die zwischen zwei weit entfernt voneinander betriebenen Endgeräten (Computern) über das Internet eine Netzwerkverbindung als in sich geschlossene private End-to-End-Verbindung herstellen kann. Es handelt sich hierbei jedoch nicht um ein neues physikalisches Netzwerk, basierend auf Hardware und Kabeln, sondern um ein logisches, rein virtuelles Netzwerk. Allerdings bildet die vorhandene physische Infrastruktur wie z.B. PCs mit Netzwerk-Interface, Patchkabel und DSL-Router oder Mobilgeräte mit WLAN-Karten und natürlich auch das Internet die physische Grundlage, in der das virtuelle VPN eingebettet ist.

"In sich geschlossen" bedeutet, dass diese Datenverbindung aufgrund der in der Verbindung angewendeten Verschlüsselung von allem anderen im Internet vorhandenen Traffic unlesbar isoliert oder gekapselt ist. Umgangssprachlich wird hierbei von den Insidern oft von einem Tunnel gesprochen, mit dem i.ü.S. ein blickdichter Tunnel gemeint ist, der von dem einem Endgerät durchs gesamte weltweite Internet bis zum anderen Endgerät reicht. Blickdicht (ein vergleichender Begriff von mir) bedeutet, das alle Datenpakete, die durch diesen Tunnel transportiert werden, von niemand anderen abhörbar oder lesbar sind. Nach meiner Kenntnis sind entsprechend dem heutigen technischen Stand solcherart durch ein VPN geleitete Datenpakete nicht hackbar, die Verschlüsselung solcher auf dem Transportweg befindlicher Daten-Pakete ist auf absehbare Zeit nicht zu knacken. Das mag dann auch wohl der Grund dafür gewesen sein, dass Apple vom chinesischen Regime im Zeitraum Juli-August 2017 gezwungen wurde, weit über 600 VPN-Apps aus dem App-Store zu entfernen... ein tatsächlicher Sachverhalt, den man mit den entsprechenden Stichworten einfach im Web selber recherchieren und nachlesen kann. Dabei ist OpenVPN gar nichts subversives, es ist nichts aufrührerisches, nichts gefährliches.... es verhindert lediglich, dass meine Daten-Privatsphäre von mir fremden Menschen verletzt wird... es schützt meine digitale Privatsphäre, es schützt mein Recht auf die vollständige Verfügungshoheit meiner persönlichen Daten beim Transport durch das Internet.

Wann kann ich es nutzen?

Diese und die nächste Frage sind etwas komplizierter zu beantworten. Um die Sinnhaftigkeit und sogar Notwendigkeit von VPN-Software zu verstehen, muss man sich zuerst der real vorhandenen Gefahren bewusst sein, denen unsere privaten Daten permanent ausgesetzt sind. Und erst daraus resultiert die Erkenntnis, wie wertvoll OpenVPN für uns sein kann und bei welchen Gegebenheiten wir es verwenden sollten.

Um die Situation insgesamt etwas besser einschätzen zu können und um unsere Ausgangslage und die Rahmenbedingungen auch wirklich zu verstehen, schauen wir uns kurz das nebenstehende Bild an...

...und wir erkennen darin eine eigentlich völlig normale Situation... wir sitzen irgendwo auf der Welt in einem Café, in einer Strandbar, in einer Pension oder einem Hotel, oder sind irgendwo in einer City, oder in einem Park und freuen uns über das offene kostenlose WLAN.

Unser Laptop ist also gerade mit irgendeinem 'freundlichen' AccessPoint via WLAN verbunden und wir können komfortabel unser Mailpostfach öffnen und auf neue Emails prüfen, oder unser Facebook-Konto auf neue Nachrichten prüfen, oder einfach nur frei Surfen im Web und vielleicht auch Postings in unseren abonnierten Online-Foren beantworten.

 
 

Nun überlegen wir kurz, was uns zu solchen Situationen einfällt bzw. was wir dazu wissen ... und anschließend natürlich auch, was wir nicht wissen. Das, was wir wissen, ist einfach. Mir fallen dazu -wenn ich an mich und meinen Laptop denke- wirklich nur zwei Punkte ein:

Ich weiß, dass

1. mein Laptop 'sauber' ist und das ich keine bösen Absichten in diesem Gastnetz habe. Ich möchte das Gäste-WLAN einfach nur kurz für meine persönlichen Belange ins Internet nutzen.

2. mein Laptop nach der Anmeldung in ein fremdes Netzwerk integriert ist, was aus technischer Sicht faktisch gleich einzuschätzen ist, als wenn ich zuhause im LAN angeschlossen bin. Das ist insofern erwähnenswert, weil das Betriebssystem selber der Bewertung, ob das fremde Netzwerk ein freundliches Netz ist oder nicht, eher keine Bedeutung beimisst. Rein technisch betrachtet verbindet es sich mit einem "feindlich" gesinnten Netzwerk genauso schnell, wie zuhause im heimischen Netzwerk und es behandelt andere Clients in beiden Netzen gleich. Wenn mein Laptop zuhause einen SSH-Zugang oder einen Samba-Share anbietet, woher soll er wissen, dass er das in diesem fremden Netz nicht soll oder darf? Tja, er weiß es nicht.

Dem entgegen ist die Liste dessen, was ich nicht weiß, was aber trotzdem für mich von Bedeutung ist, etwas länger. Und wer jetzt denkt "was ich nicht weiß, macht mich nicht heiß" ... tja, der braucht hier auch nicht mehr weiterlesen.

Ich weiß nicht,

1. ob der Betreiber des Lokals (oder was auch immer diese Örtlichkeit darstellt) tatsächlich auch der Betreiber des WLAN-Access-Point ist

2. wer die Verantwortung für die Wartung und Pflege der WLAN- bzw. Netzwerk-Infrastruktur innehat

3. wer neben dem Betreiber außerdem auch (kontrolliert oder offen und unkontrolliert) Zugang zu dieser exponierten IT-Hardware hat

4. ob dieser AP von einem sachkundigen Administrator eingerichtet wurde oder ob der Koch nur einfach WLAN an seinem Router freigegeben hat

5. ob dieser AP resp. dessen Hardware durch fahrlässigen früheren Umgang nicht vielleicht schon kompromittiert ist

6. ob dieser AP über eine Firewall verfügt oder eingerichtet hat, die gegen das Internet wirkt

7. welche Absichten der Betreiber dieses AP überhaupt verfolgt, ob er integer sind oder eher als dubios einzuschätzen ist. Vielleicht geht's ihm ja auch nur darum, bei dem vielleicht hohen Durchsatz an Reisenden und Tourismus-Gästen gewisse Account-Daten abzugreifen um damit nebenher Geld zu verdienen

8. welchen lokalen staatlichen Bestimmungen ein WLAN-Betreiber vielleicht zwangsweise folgen muss, z.B. durch Anti-Terror-Gesetze, Gesetze zur Telekommunikationsüberwachung, etc.

9. welchen "Charakter" der AP überhaupt hat und ob er wirklich der ist, der er zu sein vorgibt (Stichwort Evil Twin)... ein Umstand, der für uns überhaupt nicht zu erkennen ist. Wenn ein Strandcafé beispielsweise das WLAN mit der SSID beach_cafe_mary anbietet, so ist es für uns unmöglich zu erkennen, dass die SSID beach_cafe_mary2 mit vielleicht besserer Leistung gar nicht zu diesem Café gehört, sondern ein Evil Twin ist. Dem Chef des Cafés wird das gar nicht auffallen, weil der bei der Bewirtung seiner Gäste wichtigeres zu tun hat, als ständig sein WLAN zu beobachten. Mit der SSID beach_cafe_mary2 melden wir uns aber in ein Netzwerk an, was uns gegenüber unzweifelhaft feindselig eingestellt ist ... eben weil es nicht von diesem Café betrieben wird und weil es keine andere Rechtfertigung dafür gibt, sich als jemand anderes auszugeben. Vielleicht hat das keine Konsequenzen für uns, aber dann nur deshalb nicht, weil wir als unbescholtene Urlauber einfach zu unwichtig sind. Aber vielleicht hat sich auch jetzt jemand Zugang zu unserem Laptop verschafft oder einfach nur unsere Anmeldedaten abgehört.

Es gibt also wirklich gute Gründe, sich vor der Anmeldung an fremden WLAN-Access-Points ein paar Gedanken über die Sicherheit seines Laptops zu machen. An dieser Stelle verweise ich deshalb natürlich auch noch mal auf meinen Artikel zu Sicherheit durch Firewall, in dem ich einen Paketfilter für solche Situationen beschrieben habe ... nun ja, das nur mal am Rande, denn hier soll es ja primär um OpenVPN gehen.

Die oben beschriebene Situation mit der WLAN-Verbindung an einem offenen/freien AccessPoint ist also offensichtlich etwas ganz normales, was völlig alltägliches ... nur leider eben durchaus auch mit ein paar Risiken behaftet. Das ganze erhält aber noch eine zusätzliche Dimension an Risiken, wenn ein Anwender darüber hinausgehend auch noch vorhat, sich von unterwegs mit seinem heimischen Netzwerk zu verbinden, um damit von jedem Ort auf der Welt einen Zugriff auf die Daten seines Servers zuhause zu bekommen. Das ist beispielsweise eine immer häufiger auftretende Frage in "meinen" Onlineforen, wenn Linux-Beginner nach Möglichkeiten fragen, um von außerhalb einen Zugriff auf die Hausautomatisierung zu bekommen, auf Überwachungskameras, auf die vom Server vorgehaltenen Daten.

Technisch ist das wirklich kein großes Problem. Das ist alles ganz fix gemacht. Wir öffnen einfach die benötigten Türen in der Firewall unseres DSL-Routers und schon steht uns von überall auf der Welt das ganze private Netzwerk zur Verfügung.

 

Ein SSH-Zugang mit leicht zu merkendem Password, ein Web-Server, der sich sofort mit "Hallo, hereinspaziert" meldet, ein lokaler Mailserver, mit dem man sich auf Reisen problemlos mit Thunderbird oder einem Smartphone-Client verbinden kann, die Home-Automatisierung, bei der man sich mit "1234" als Password authentifiziert ... alles kein Problem.... das geht alles ganz fix einzurichten. Man installiert die entsprechenden Dienste auf dem Server, passt die Einstellungen an, öffnet zudem die Ports im DSL-Router mit passender Weiterleitung und schon läuft alles wunderbar.

 

Wäre das nicht schön, wenn's dabei bleiben würde? Aber leider befindet sich genau hier das Problem... denn es bleibt nämlich nicht allein dabei. Die Wirklichkeit sieht leider ein wenig anders aus.

 

Was kann es für mich tun?

Sobald wir einzelne Türen in unser Netzwerk herein öffnen, besteht ab diesem Moment ununterbrochen die äußerst signifikante Gefahr, dass sich durch diese Tür auch Fremde einschleichen wollen, und das heimlich einbrechend, unberechtigt, mit unbekannten Absichten. Und genau darin besteht meine größte Herausforderung: wie schaffe ich es, dass die von mir geöffneten Türen nicht unberechtigt auch von Fremden durchschritten werden? Wie verhinderte ich effektiv, dass Fremde sich illegalen Zugriff auf mein Heimnetzwerk verschaffen und mich belauschen, oder meine Daten stehlen, oder schlimmstenfalls sogar alle meine Daten zerstören? Tja... ich habe für unser Netzwerk meine Antwort auf diese Frage gefunden... die auch relativ einfach ist, aber auch radikal und endgültig. Ich vermeide heute einfach konsequent Türen zu öffnen, deren Sicherheit ich nicht selber absolut unzweifelhaft in der Hand habe. Und ich vermeide verschiedene Türen (also mehr als nur eine) für verschiedene Dienste öffnen zu müssen.

Genau für diese Zielsetzung eines wirklich kontrollierten Zugangs in mein Heimnetzwerk ist OpenVPN ein perfekte Lösung, weil ich für OpenVPN erfreulicherweise nur eine einzige Tür öffnen muss, die mir aber trotzdem den vollständigen Zugang auf alle Ressourcen ermöglicht und deren Passage nur mit Vorlage "meines Personalausweises" erlaubt ist ... man verzeihe mir den Vergleich mit dem Personalausweis, aber das ist eben für uns Laien die beste sinngemäße Übertragung für das Zertifikat zur Authentifizierung und dem Keyfile für die Ver-/Entschlüsselung ... mir fiel wirklich nichts besseres ein. Unbestritten ist, ohne diesen "Ausweis" (das Zertifikat) wird der Zugang ins Netzwerk verwehrt. Das bedeutet allerdings auch, dieses Zertifikat und das Keyfile sind als zwei äußerst sensible Dateien zu behandeln, die man wirklich zuverlässig geschützt vor unberechtigtem Zugriff aufbewahren muss. Die notwendige sichere Aufbewahrung habe ich auf meinen Laptop durch einem grundsätzlich unzugänglichen LUKS-Container realisiert, in dem die beiden Files gespeichert sind. Der Container wird on-the-fly erst dann geöffnet, wenn ich einen bestimmten USB-Stick ins Gerät einstecke. Sobald ich den Stick wieder abziehe, ist der Container wieder gesichert und kann nicht mehr eingesehen werden.

Die Vorgehensweise bis zur sicheren Verbindung ist also eigentlich ganz einfach:

1. Ein restriktiver Paketfilter ist aktiv

2. Netzwerk-Verbindung zum AccessPoint wird hergestellt

3. Bevor eine Anwendung gestartet wird, die das Netzwerk nutzt, wird der OpenVPN-Client gestartet

4. Nach erfolgreicher VPN-Verbindung starte ich auf dem Laptop die jetzt von mir gewünschten Programme oder Dienste

Mit OpenVPN habe ich also eine Möglichkeit gefunden, trotz aller vorhandenen Gefahren auf absolut sichere Weise sämtliche in meinem heimischen LAN verfügbaren Ressourcen auch von außerhalb erreichen und nutzen zu können, wie den Samba-Server, oder den Mailserver. Ich kann meine auf dem Server gespeicherten Kontakte mit dem Smartphone synchronisieren, meine Web-Cams öffnen und Haus und Hof kontrollieren, oder einfach auf abhörsichere Art und Weise über meinen Router zuhause im Internet surfen.... und das alles ganz (un)bequem auf dem oben gezeichneten Stuhl im Café sitzend, mit meinem Laptop auf dem Tisch, verbunden mit einem potentiell unsicheren fremden und unbekannten Netzwerk. OpenVPN kann damit vielleicht sogar die Installation eines eigenen Web-Servers und installierter Cloud-Software unnötig machen ... eine Idee, auf die man möglicherweise kommt, weil man drüber gelesen hat und weil man glaubt, nur damit können die Kontakte und Termine vom Handy mit dem Server synchronisiert werden. Dabei geht das auch wirklich prima ohne solch schweren Geschütze, deren Sicherheit ich aufgrund der wirklich hohen technischen Anforderungen als Laie vielleicht kaum gewährleisten kann. Dieses Problem löst radicale perfekt, welches genau für den Zweck der Synchronisation mehrerer Smartphones mit mehreren Adressbüchern und Kalendern ein tolles Werkzeug ist.

Der wirklich augenfällige Vorteil von OpenVPN ist, ich muss gar nicht eine für jeden Service meines LAN-Servers passende Tür öffnen, um über das Internet Zugang zu diesen Service zu bekommen, ich integriere mich mit OpenVPN einfach in das heimische Netzwerk und kann dann alle Dienste so nutzen, so als wäre ich mit meinem Laptop zuhause im Netz angemeldet.

Schauen wir auf das nebenstehende Bild, um noch besser die Funktionsweise von OpenVPN zu verstehen. Ich melde meinen Laptop zunächst mal ganz normal bei diesem AccessPoint über einen Netzwerkmanager an. Bis zu diesem Moment sind noch keinerlei private Daten geflossen... es wird nur rein technisch eine Funkverbindung zwischen zwei Geräten hergestellt und ein Netzwerk etabliert.

Das bedeutet, der Laptop bekommt eine IP-Adresse vom Router des APs aus dessen Netz zugewiesen. Ab diesem Moment ist mein Laptop aber auch in diesem Netzwerk resp. für den Admin dieses Netzes sichtbar, genau so wie ich meinen Laptop oder die anderen Geräte zuhause im Netz sehe, wenn ich das mit meinem PC kontrolliere oder überwache. Ich wiederhole das noch mal kurz... an diesem Punkt ist eine restriktiver Paketfilter eine wichtige Empfehlung.

 

 

Und nun starte ich auf dem Laptop den VPN-Client, der dann automatisch eine Verbindung zu meinem VPN-Server zuhause aufbaut und damit den schon erwähnten sicheren Tunnel zwischen diesen beiden Geräten etabliert. Nach erfolgreicher Verbindung bin ich ab jetzt nicht nur ein Mitglied meines Netzwerkes zuhause und alle dessen Ressourcen stehen mir zur Verfügung, es ist auch noch der direkte Zugang vom Laptop über den AccessPoint zum normalen Internet blockiert. Das bedeutet, wenn ich jetzt mit dem Browser im Internet surfe, geht der vollständige Traffic nicht mehr über den AccessPoint ins Internet, sondern erst durch den Tunnel in mein Netzwerk zuhause und dann über den heimischen Router wieder ins Internet. Keine einzige mit meinem Browser geöffnete Web-Seite ist vom AccessPoint sichtbar, es können keine Daten (Anmeldename, PWD) abgegriffen werden, die ich auf irgendeiner Web-Seite eingebe, der gesamte Datenverkehr findet hochsicher verschlüsselt durch den Tunnel über meinen Router zuhause statt. Ich kontrolliere das immer zuerst, in dem ich mir kurz auf einer Online-Website meine jetzt aktuellen öffentlichen IP-Adressen anzeigen lasse.... und mit erfolgreich gestarteten OpenVPN ist das nie die temporäre Adresse des AccessPoints, sondern immer die IP meines Routers zuhause oder eine IPv6-Adresse gebildet aus meinem heimischen ISP-Prefix.

Ist das VPN meiner FRITZ!Box nicht das gleiche, wie OpenVPN? Im DSL-Router ist VPN ja schon als Grundfunktion vorhanden und man kann es ohne viel Arbeitsaufwand nutzen. Ja, stimmt, vermutlich ist VPN über die Fritzbox um einiges leichter in Betrieb zu nehmen. Aber leider gibt es auch einige gravierende sicherheitsrelevante Unterschiede im Vergleich zu OpenVPN, wegen derer ich schließlich zu dem Fazit gekommen bin, das AVM-VPN nicht zu verwenden.

Ein OpenVPN-Tunnel ist immer eine end2end-Verbindung zwischen zwei vertrauenswürdigen Geräten, die von mir selber eindeutig als vertrauenswürdiger Erster und Letzter Punkt auf dieser Kommunikationsstrecke identifiziert sind. Alles was zwischen diesen beiden Endpunkten liegt, also auf dem ganzen Weg des Tunnels, kann man eigentlich durchweg als potentiell unsicher einstufen. Das betrifft natürlich zuallererst den offenen Start-AccessPoint mit dem wir verbunden sind, dann den Transport durchs Internet und letztlich auch die Fritzbox als End-AccessPoint. Der Vorteil des OpenVPN-Tunnels ist, dass die übertragenen Daten-Pakete diese "drei unvermeidbaren Teilnehmer" nicht entschlüsselbar und somit völlig unlesbar passieren, einschließlich der vielleicht auch übertragenen Passworte oder Zugangsdaten zu Geräten der Home-Automation.

Und warum ist das Fritzbox-eigene VPN als unsicher einzustufen? Zum einen, weil die Paketverschlüsselung an einem Punkt aufhört, der auf proprietärer Software basiert und zum anderen wegen der Tatsache, dass die Fritzbox bekanntermaßen eine Backdoor implementiert hat. Also braucht man eine Antwort auf die Frage, ob man einer fremden Hardware mit quasi unkontrollierbarer Software als Endpunkt einer Verschlüsselung wirklich vertrauliche Daten anvertrauen will? Wenn es dabei auch noch um Home-Automation und Zugangsdaten dazu geht, halte ich das für einigermaßen fahrlässig.

Was bedeutet Backdoor...?... das klingt ja irgendwie beunruhigend. Viele moderne DSL-Router -wie eben auch die FRITZ!Box von AVM- haben die TR-069-Schnittstelle implementiert. Über diese Schnittstelle werden primär Updates installiert, oder neue Programme, aber auch Sicherheitspatches. Und bei manchmal auftretenden heimischen Problemen, mit denen unkundige normale Home-User oft überfordert sind, können Support-Mitarbeiter des DSL-Anbieters über diese Schnittstelle auch Wartungsarbeiten am Router durchführen, bis hin sogar zu veränderten Einstellungen. Aber genau deswegen ist es funktional wie ein SSH-Zugang für Fremde in unser Netzwerk zu sehen, ohne faktisch selber ein SSH-Server zu sein. Also ist das alles nur scheinbar vorteilhaft für uns, es wird uns nämlich gar nicht offen mitgeteilt, welche Nachteile das zeitgleich für uns beinhaltet und wir werden nicht gefragt, ob wir dem überhaupt zustimmen. Denn wer diese Schnittstelle bedienen darf, kann alles installieren und im Router alles veranlassen. Ein Wikipedia-Artikel beschreibt die TR-069-Schnittstelle deshalb auch als Beschneidung der Privatsphäre und des Datenschutzes für den Endanwender. Dem DSL-Anbieter wird damit ermöglicht, Änderungen am DSL-Router durchzuführen, die der Benutzer weder kennt noch erlaubt hat. Über diese Schnittstelle sind sogar nicht nur Änderungen im Roll-Out-Mode für alle im Land betriebenen DSL-Router möglich, sondern auch explizit für einen einzeln Router, was insbesondere für uns eine große Bedeutung bei Online-Durchsuchungen, digitaler Schleierfahndung oder Abhörbefugnissen haben kann. TR-069 sieht sogar die Möglichkeit vor, Geräte hinter der Router-Firewall, also unsere Geräte im Netz zu sehen und ggf. dort Daten zu verändern. Damit stellt TR-069 durch sein Funktionsprinzip ohne jeden Zweifel eine Backdoor da. Einige DSL-Anbieter erlauben es, diese Schnittstelle im Router zu deaktivieren, einige DSL-Anbieter räumen einem dieses Recht nicht ein. In einem solchen Fall würde ich diese Fritzbox nicht verwenden bzw. eine eigene Router-Firewall zwischen DSL-Router und lokales Netzwerk positionieren.

Der Zusammenhang zum VPN ist also ganz einfach. TR-069 ist eine Schnittstelle, mit der natürlich folgerichtig auch direkt und unautorisiert auf die im DSL-Router hinterlegten Zertifikate und Kryptografie-Schlüssel zugegriffen werden könnte. Und wenn man die hat, braucht man die Schnittstelle gar nicht mehr, um Zugang zu Deinem Netzwerk zu bekommen, damit ist man einfach auf geraden Weg direkt drin. Wegen der Schnittstelle TR-069 hast Du tatsächlich also keine Kontrolle mehr darüber, wer vielleicht auf diese Daten zugreift und wie er das verwendet. Wie willst Du außerdem gewährleisten oder verhindern, dass bei einer Fritzbox nicht sogar beabsichtigt ist, die Keys auszulesen und anders als Du erlaubst zu verwenden? Wie willst Du gewährleisten, dass eine Behörde nicht so was wie einen 'Generalschlüssel' für diese Keyfiles hat oder von AVM oder dem DSL-Anbieter die Herausgabe als Polizeimaßnahme erzwingen kann?

Und genau hier besteht der wirklich beunruhigende Unterschied zu OpenVPN, denn wer Zertifikat und Kryptografie-Schlüssel aus der Fritzbox 'entwendet' hat, hat ungehinderten Zugang zu Deinem Netzwerk. Dabei ist es völlig egal, ob die Keys legal ausgelesen wurden, oder illegal, oder gehackt, oder über eine Sicherheitslücke. Deshalb machst Du die Sicherheit Deines privaten Netzwerkes auch von dem Zufall abhängig, wie "sorgfältig" und "gewissenhaft verschwiegen" irgendein beliebiger Support-Mitarbeiter Deines DSL-Anbieters mit den Zugangsdaten zu Deinem Router umgeht, ohne das Du selber den geringsten Einfluss darauf hast. Genauso wenig hast Du Einfluss darauf, wer beim DSL-Anbieter überhaupt wie autorisiert und wie kontrolliert und von welchen Compliance-Regeln geleitet Zugang zu deren Systemen hat, um darüber vielleicht die Zugangsdaten für Deinen Router auszulesen. Und vergiss nicht, dass im First-Level-Support manchmal auch nur 400€-Teilzeit-Kräfte für eine Erst-Hilfe sitzen, oder es handelt sich gar nur um ein mit dem Auftrag "Kunden-Erst-Kontakt" beauftragtes Call-Center.

Bei meiner FRITZ!Box konnte ich den Port jedenfalls nachweislich (mithilfe eines Port-Scanners) schließen. Wenn sich diese Situation jemals ändern sollte, schalte ich sofort eine eigene Router-Firewall zwischen LAN und DSL-Router. Und selbst wenn mein DSL-Router LAN-Intern unerlaubt lauschen und Passwörter (o.ä.) mitschreiben würde, so hat er dennoch keine Möglichkeit, auf Zertifikat und Keyfile lesend zuzugreifen und diese anders als von mir erlaubt zu verwenden. Insofern ist natürlich wegen fehlender Keyfiles auch kein unerlaubter Zugriff von außen möglich. Du solltest also akzeptieren, dass Du mit der Verwendung des AVM-VPNs die Kontrolle über Deine Hardware und Deines Netzwerkes zu einem beträchtlichen Teil aus der Hand gibst und somit möglicherweise in eine Situationen kommst, in der Du nicht mehr allein Entscheidungen für Deine Hardware triffst.

Meine Fritzbox hat definitiv keinen Zugang zu den Dateien, die die Kryptografie und ausschließlich den erlaubten Zugang in mein Netz sicherstellen. Insofern kann sie auch nichts übernehmen und ggf. unautorisiert weitergeben. Alles zusammengenommen sind das für mich wirklich gute Gründe, OpenVPN als Alternative zu verwenden.... auch wenn es -wie wir noch sehen werden- einigermaßen kompliziert einzurichten ist.

Bevor es nun endlich mit der Installation unseres VPN-Netzwerks losgeht, solltest Du Dir aber jetzt noch einmal bewusst machen, um was es hier überhaupt geht:

Du öffnest ein Portal in Dein privates Heim-Netzwerk!

Das bedeutet, wenn Du im Anschluss daran nicht zweifelsfrei eine auf Wissen beruhende Kontrolle über Deine Hardware hast, entscheidest Du auch nicht darüber, wer diese Hardware mit welchen Absichten verwendet. Punkt! Wie Deine Hardware verwendet wird, entscheiden dann vielleicht irgendwelche Dir völlig unbekannte Menschen. Akzeptiere das einfach. Allein zu denken und darauf zu vertrauen, Du hättest die Kontrolle und es passiert schon nix ... vergiss es! So funktioniert das nicht! Gerade bei den allzu oft vorgefundenen und fast normalen privaten Rahmenbedingungen ist das in Wirklichkeit nur ein Trugschluss. Auf einem potentiell unsicheren Betriebssystem kannst Du keine ausschließliche Kontrolle und somit keine vollständige Sicherheit erwarten, infolgedessen gibt es auch keine Garantie dafür, dass nur Du alleine Entscheidungen für Dein System triffst.

 

Ein potentiell unsicheres Betriebssystem ist es, wenn Du z.B. den Nutzungsbedingungen proprietärer Software ungelesen (oder unverstanden) zugestimmt hast, oder wenn Du Software aus dubiosen Fremd-Quellen (anonyme ppa's oder Quellen im Internet) verwendest, oder wenn Du in der Admin-Group eingetragen bist und als Du selber Programme starten kannst, die dann mit privilegierten Rechten ausgeführt werden. Unter solchen Bedingungen ist der Gedanke ganz allein die exklusive Kontrolle zu haben eine Illusion, ein reines Glücksspiel.

Sei Dir deshalb immer zu jeder Zeit bewusst, dass Du im Fall der Fälle niemals nur Dir allein schadest, der Schaden trifft immer uns alle. Mach Dir bewusst, was es bedeutet, wenn Deine Hardware als Mitglied einer Bot-Net-Attacke z.B. einen Energieversorger angreift oder ein Krankenhaus oder eine Bank oder eine Versicherung. So etwas betrifft immer uns alle. Die Kontrolle darüber, wer Deine Hardware verwendet, kannst Du nur dadurch erhalten, wenn Du alles mit Sachverstand und der zweifelsfreien Feststellung "ich verstehe, was ich hier mache" tust. Und nicht vergessen, "Glauben" hat wirklich absolut gar nichts mit "Wissen" zu tun.

Überblick - Was ist alles zur Einrichtung von OpenVPN notwendig ?

Die folgenden Liste verschafft uns einen kurzen Überblick über das, was uns ab jetzt erwartet.... mit folgender Zielsetzung:

- Ich möchte einen VPN-Zugang einrichten, um auf sichere Art und Weise von außerhalb über das Internet auf die Ressourcen meines Heimnetzwerks zugreifen zu können.

- Für ein Fallback-Szenario wird zusätzlich ein zweites VPN-Netz via TCP auf Port 443 vorgesehen.

- IPv6 soll via NAT geroutet werden. (Kann bei reinen IPv4-Netzen ignoriert werden!)

Dazu wird mit OpenVPN ein End-to-End-Tunnel über den Routing-Mode mit tun-Devices etabliert (alternativ: tap-Devices + Bridging). Als regelmäßig verwendetes Protokoll ist UDP vogesehen. Das Fallback-VPN ist in den Fällen eine mögliche Alternative, wenn ein Gastgeber-WLAN den Datenverkehr auf HTTP(S) beschränkt und sämtliche UDP-Ports über einen Paketfilter gesperrt hat. Bitte unbedingt dabei beachten, dass der Port 443 nicht durch einen anderen Service belegt sein darf, wie zum Beispiel durch einen Web-Server wie Apache oder Nginx. Wird der Port 443 bereits verwendet, steht diese Möglichkeit eines Fallback-VPNs nicht zur Verfügung. Es gibt zwar die Möglichkeit des Port-Sharings, OpenVPN unterstützt das, aber das kann nicht Thema dieses Artikels sein.

Die To-do-Liste:

Was?

Wo?

  1. 1. 

Benötigte Ports öffnen und deren Weiterleitung einrichten

DSL-Router

  1. 2. 

Statische Routen für die VPN-Netze zum VPN-Gateway einrichten

DSL-Router

  1. 3. 

OpenVPN aus dem Source-Paket kompilieren und ein Deb-Package erstellen

Arbeitsplatz-PC

  1. 4. 

Keyfiles und Zertifikate für Server und alle betroffenen Clients-Geräte erstellen

Arbeitsplatz-PC

  1. 5. 

Config-Files für den Server erstellen

Arbeitsplatz-PC

  1. 6. 

Config-Files für Clients erstellen

Arbeitsplatz-PC

  1. 7. 

Systemd-Service-Units zum Starten der VPN-Daemons und nftables-Regeln erstellen

Arbeitsplatz-PC

  1. 8. 

Deb-Package für OpenVPN installieren

OpenVPN-Server

  1. 9. 

Kernelparameter für Forwarding setzen

OpenVPN-Server

  1. 10. 

Service-Units übertragen und aktivieren

OpenVPN-Server

  1. 11. 

Deb-Package für OpenVPN auf den Laptops installieren

mobile OpenVPN-Clients

  1. 12. 

Keyfiles und Zertifkate auf die betroffenen Laptops übertragen

mobile OpenVPN-Clients

  1. 13. 

On-The-Fly-Starter auf den betroffenen Laptops einrichten, um es nur bei Bedarf zu starten

mobile OpenVPN-Clients

  1. 14. 

OpenVPN-Client auf den betroffenen Smartphones installieren

Smartphone

  1. 15. 

Keyfiles und Zertifkate auf die Smartphones übertragen

Smartphone

  1. 16. 

OpenVPN-Client auf den Smartphones einrichten

Smartphone

 

Mit einem Blick auf das nebenstehende Bild versuchen wir uns auch noch einmal kurz zu verinnerlichen, wohin die Reise überhaupt gehen soll, was unser Ziel ist, welche Komponenten wir mir welcher IP in Erinnerung behalten müssen ... und was ganz am Ende, wenn wir fertig sind, hinten rauskommen soll.

 

Wenn alles korrekt eingerichtet ist, haben wir 3 Netzwerke, 2 Gateways und 3 DHCP-Server in Betrieb genommen. Wir haben Clients, die sich mit allen 3 Netzen verbinden können, zuhause ins heimische LAN und unterwegs in eins der beiden VPN-Netze. Und sie erhalten je nach Netzwerk eine zum Netzwerk passende IP-Adresse für IPv4 und ggf. auch für IPv6.

Wir haben dann

 

>   das alte Heim-Netzwerk, IP-Range 10.0.1.0/24

und

>   ein neues VPN-Netzwerk (UDP), IP-Range 10.0.8.0/24

>   ein neues VPN-Netzwerk (TCP), IP-Range 10.0.9.0/24

>   das alte Gateway und DHCP-Server, IP 10.0.1.1

und

>   ein neues Gateway, IP 10.0.1.2

sowie

>   einen neuen VPN-DHCP-Server (UDP), IP 10.0.8.1

>   einen neuen VPN-DHCP-Server (TCP), IP 10.0.9.1

 

Für die Vorbereitung der Installation auf Server und Clients verwende ich 2 Systeme, einmal meinen persönlichen PC, der hierfür als Entwickler-PC und als Key-Signing-Machine genutzt wird. Und einen RasPi zum Erstellen des OpenVPN-Binaries für die Arm-Architektur.

Weil mein als Server arbeitender Pi keine Entwicklungstools beinhaltet und ich diese dazu notwendigen Pakete nicht nur für diesen einen Ausnahmefall installieren will, erstelle ich das Paket auf einem Zweit-Pi mit einem eigenem Raspian-Lite. Falls kein zweiter PI zur Verfügung steht, empfehle ich im vorhandenen PI kurzerhand vorübergehend die Karte auszutauschen. Dazu einen shutdown durchführen, eben schnell eine Zweit-Karte mit einem abgespeckten Raspian-Lite rein, das Paket wie beschrieben erstellen, Karte raus, erste Karte wieder rein und den Pi für den Normalbetrieb durchstarten. Von der Zweitkarte übertrage ich dann das Paket zur Sicherung via Card-Reader und SSH auf meinen PC und führe später von dort die OpenVPN-Installation auf dem Server durch.

Für den späteren ersten Funktionstest einer Verbindung von außen über das Internet zum OpenVPN-Server verwende ich meinen Laptop und mein Galaxy-S8. Mit dem S8 kann ich über die Verwendung der Funktion "Mobile Daten" die aktive UMTS-Verbindung via Tethering "weitergeben". Der Laptop meldet sich dazu einfach am WLAN-Accesspoint des Handys an und hat damit über das Handy-Netz eine Internet-Verbindung.

 

Setup DSL-Router

Beginnen wir mir den notwendigen Einstellungen in unserem DSL-Router. Wie oben schon in den Bildern sichtbar und erklärt, ist es notwendig, eine spezielle Tür für die OpenVPN-Datenpakete ausdrücklich zu öffnen. Einige weitergehende und durchaus wichtige und mit diesem Artikel unbedingt im Zusammenhang stehenden Informationen zur rudimentären Firewall-Funktion des DSL-Routers habe ich in meinem Firewall -Artikel beschrieben, deswegen begnüge ich mich hier mit einem Verweis und spare mir damit lange Wiederholungen.

Ich empfehle als erstes den Dialog-Modus des Web-Inferfaces unseres DSL-Routers auf "erweitert" oder "Expert" einzustellen. Nur mit dieser Einstellung werden uns auch alle wichtigen Parameter angezeigt bzw. sind änderbar. Ich verwende hier Beispiele für die Fritzbox 7490, die aber im Großen und Ganzen auch passend für die FB 7270 sind. Für alle anderen Router muss man sich die äquivalenten Einstellungen im Menüsystem suchen.

Über den Menüpunkt Freigaben werden die zu öffnenden Ports eingerichtet, über die später ein Zugang aus dem Internet heraus in unser lokales Netzwerk ermöglicht wird. Bitte die Schaltfläche Gerät für Freigaben hinzufügen auswählen.

Der erste Schritt ist es, den Zielhost für die von außen kommenden Datenpakete zu bestimmen. Erster Empfänger aller Pakete von außen ist immer unser DSL-Router, weil der als einziger eine Internet-taugliche IPv4 innehat. Die IPV4-Adressen aller anderen Clients sind nur lokal gültige Adressen, die nicht internettauglich sind. Auf diesem Bildschirm teilen wir dem DSL-Router mit, welcher PC im LAN als OpenVPN-Ziel-Host diese Pakete erhalten soll.

Damit es hier zu keinen Missverständnissen führt, wähle ich immer den Zielhost ausdrücklich über seine in meinem Netz statische IP-Adresse aus. Das ist ein sehr wichtiger Umstand: Wir müssen sicherstellen, dass kein anderer PC diese IP-Adresse zugeteilt bekommt, diese IPv4 muss für den OpenVPN-Server reserviert bleiben.

Bitte nach Eingabe des Zielhosts die Schaltfäche Neue Freigabe auswählen.

Mit diesen 2 Dialogen können für den zuvor festgelegten Ziel-Host die zu öffnenden Ports vorgegeben werden. Die Bezeichnung OpenVPN_UDP4 und OpenVPN_TCP4 sind von mir willkürlich festgelegt worden, ebenso ist die Wahl der Ports 443 und 55553 willkürlich. Den Port 443 habe ich als Fallback-Port freigegeben, der nur in Ausnahmesituationen verwendet wird, wenn durch den Admin eines für Gäste offenen AccessPoints das primär von mir genutzte UDP-Protokoll gesperrt ist – wovon möglicherweise unprivilegierte Ports oberhalb 1024 betroffen sein können. Der Port 55553 ersetzt den für OpenVPN regulär verwendeten Port 1194.

Die Variante mit Port 443 ist eine besondere Spielerei, die bei einer Erst-Einrichtung eigentlich nicht zwingend notwendig ist. Für den Anfang reicht es aus, sich erst mal nur auf den UDP-Port zu konzentrieren und erst später, wenn das läuft, vielleicht über einen alternativen TCP-Port nachzudenken. Und es besteht hierbei noch eine wichtige Besonderheit, die uns durchaus bewusst sein muss. Eigentlich ist der Port 443 ja der für HTTPS-Traffic verwendete Port. Üblicherweise lauscht also ein Web-Server auf Verbindungsversuche, die von außerhalb über DSL-Router über diesen Port "reinkommen".

Auf meinem OpenVPN-Server lauscht aber kein Web-Server auf Port 443, ich habe diesen Port im DSL-Router quasi zweckentfremdet. Bei mir lauscht auf dem Ziel-Host nur ein OpenVPN-Server auf den Ports 55553 (UDP) und 55554 (TCP). Man muss sich die Wege eines Daten-Paketes also wie folgt vorstellen:

Internet-Anfrage:    Annahme durch DSL-Router:       Weitergeleitet an OpenVPN-Server:

von Port 55553       auf Port 55553                  auf Port 55553

von Port 443         auf Port 443                    auf Port 55554

Wenn allerdings jetzt sofort beide Freigaben eingerichtet werden, empfehle ich, beide Freigaben einzeln einzurichten. Das heißt, nicht beide gleichzeitig, sondern die zweite erst dann, wenn die erste auf der Einstiegsseite als Aktiv markiert ist.

Siehe ergänzend zu den Port-Nummern auch: < Firewall >

Die Übersichtsseite zeigt, dass die neuen Freigaben fehlerfrei eingerichtet sind.

Als nächstes sind im DSL-Router noch statische Routen zu setzen. Wir haben es ja hier faktisch mit 3 Netzen zu tun.

Home-Network:             10.0.1.0/24      Gateway:  DSL-Router     =  10.0.1.1

OpenVPN-Netz via UPD:     10.0.8.0/24      Gateway:  OpenVPN-Server =  10.0.1.2

OpenVPN-Netz via TCP:     10.0.9.0/24      Gateway:  OpenVPN-Server =  10.0.1.2

Allein die Weiterleitung vom DSL-Router zum VPN-Server reicht nicht aus. Diese statischen Routen sorgen dafür, dass zwischen den 2 VPN-Netzwerken und dem Home-Netzwerk auch eine normale Kommunikation zwischen VPN-Clients und Home-Netzwerk-Clients möglich ist. Ohne Routen wären im Heimnetz die VPN-Clients unbekannte Ziele... das bedeutet, Pakete mit dem Ziel eines VPN-Clients (also unbekannt) würden die Standard-Route (DSK-Router) ins Internet nehmen und dort irgendwann verworfen werden, weil sie auch dort unbekannt sind. Durch diese neuen Routen wird definiert, dass für Pakete mit dem Ziel 10.0.8/24 und 10.0.9/24 unser OpenVPN-Server das Standard-Gateway ist und nicht der DSL-Router.... also kommen sie auch am Empfänger an.

Abschließend werfen wir noch einen Blick auf die Netzwerk-Einstellungen des DSL-Routers. Wir sehen hier die Adressen, die selbstverständlich die gleichen sind, die später bei den Konfigurationsdateien verwendet werden.

Das ist sowieso einer der wichtigsten Grundsätze: Wenn wir solche Arbeiten tun oder vorhaben, also z.B. wie hier mehrere miteinander kommunizierende Netzwerke einrichten, so müssen wir uns zu jeder Zeit aller Faktoren bewusst sein. Dabei ist es auf jeden Fall hilfreich, wenn man zuvor ein Papier-Planungs-Netzwerk entwirft, auf dem alle Komponenten schon ihre zukünftigen Parameter erhalten und von dem man beim individuellen Einrichten die betroffenen Werte abliest oder einfach nur, um die eingerichteten Parameter am Ende noch mal mit der Planung zu vergleichen. Ein kleiner Fehler, und schon funktioniert's am Ende nicht... und dann beginnt das frustrierende Drama der Fehlersuche, weil man zunächst mal gar keine Ahnung hat, wo man überhaupt zu suchen anfangen soll. Also ganz wichtig, besser vorher genau planen und beim Einrichten immer äußerst konzentriert und gewissenhaft arbeiten.

 

Gerade im Hinblick auf die angemahnte Sorgfalt und Gewissenhaftigkeit und für das bessere Verständnis von Zusammenhängen (und ggf. auch meiner eigenen Rahmenbedingungen) möchte ich an dieser Stelle noch einen wirklich wichtigen Hinweis platzieren: Alle hier in diesem Beispiel verwendeten Adressen wurden willkürlich von mir festgelegt. Ich hatte hierbei wirklich nur ein einziges Interesse, und zwar einen von Anfang bis Ende nachvollziehbaren durchgängigen roten Faden zu haben. Und darüber hinaus muss dieser Artikel technisch passend und vollständig kompatibel zu meinen Artikel Sicherheit durch Firewall sein - denn das eine ohne das andere ist nur eine halbe Lösung.

Die hier verwendeten IP-Adressen sind also keine Empfehlung, sie genau so zu übernehmen. Idealerweise baut man das oder die neue(n) VPN-Netz(e) in das bestehende Heim-Netzwerk ein, was zugegeben alles manchmal sehr kompliziert und umfangreich anmutet. Die stabilste Basis für einen erfolgreichen Abschluss eines solchen Projektes ist deswegen völlig unbestritten immer der Faktor "Verstehen". Ich zeige hier deshalb alles vollständig, damit man bei einer späteren Fehlersuche überhaupt eine Vorstellung über die Zusammenhänge hat, wo man überall nachsehen muss, oder ein grobe Richtung erkennt, in der man sich bei der Fehlersuche "bewegen" kann.

 

Und was mir als Hinweis noch wichtiger ist, das ist mein folgender Rat an alle jene, die glauben, man könne sich ohne Verständnis der Zusammenhänge von Netzwerk, VPN, Protokollen und Paketfilter alles Quick&Dirty auf die Rechner kopieren und einfach starten: Bitte lass es! Du schadest Dir viel mehr, als Du glaubst.... und der Nutzen ist im Vergleich zum Schaden viel geringer, als Du Dir vorstellen kannst. Fahrlässigkeit und Leichtsinnigkeit sind die schlechtesten Voraussetzungen für solcherart exponierten Netzwerks-Zugänge.

 

 

Deb-Package für OpenVPN erstellen und installieren

An diesem Punkt verlasse ich jetzt eingetretene Wege und beschreite einen eigenen Weg. Der übliche Weg zur Installation eines OpenVPN-Server/-Client ist meiner Meinung nach, OpenVPN aus dem Distributions-Repository mit apt install zu installieren. Das übliche Ergebnis dabei ist, dass auch eine Script-Umgebung installiert wird, die sich u.a. mit dem Starten und Schließen des Services befasst. Bedauerlicherweise ist das bis zu diesem Zeitpunkt, an dem ich meinen Artikel schreibe, immer noch sysvinit-basierend. Und zum zweiten ist mir die im Repository vorhandene Version zumeist schlichtweg nicht aktuell genug. Außerdem habe ich sowieso einen etwas höheren Anspruch an Flexibilität und Variabilität. Wegen all dieser Gründe verwende ich nicht die Repo-Version, sondern das aktuelle OpenVPN direkt von der Project-Web-Seite.

Der erste Schritt ist, die zum Erstellen notwendige Programme zu prüfen und ggf. zu installieren. Soll das Paket in der normalen Laufzeit-Umgebung des PCs erstellt werden, empfehle ich, das System vorher auf einen aktuellen Stand zu bringen. Wenn das System aktuell ist und nichts aktualisiert wird, kann der Reboot übersprungen werden.

$ su -

# apt update

# apt full-upgrade

# dpkg -l wget

  dpkg-query: Kein Paket gefunden, das auf wget passt

# apt install wget

# systemctl reboot

Wir laden nun das aktuelle OpenVPN-Paket herunter. Der Suchbegriff "openvpn.net download" im Browser und auf der Suchmaschine meiner Wahl bringt mir (in den meisten Fällen) gleich im ersten Ergebnis die Download-Seite des Projektes, auf der ich einen Hinweis auf die (am heutigen Tag) aktuelle Version und etwas weiter unten das Source-Code-Paket als Tar-File zum Downloaden finde. Bitte unbedingt darauf achten, den Download des Tar-Files nur von der Projekt-Seite und nicht von irgendeiner Dritt-Seite durchzuführen.

Source Tarball (gzip)                        openvpn-2.5.7.tar.gz        

Das Tar-File lade ich mir einmalig runter und es wird mit dem Browser nach /tmp gespeichert, um es dann später (auf geeigneten Systemen (passende CPU-Architektur)) zu entpacken und dort zu kompilieren.

Das derzeit aktuelle und hier verwendete Paket kann auch direkt heruntergeladen werden. Aber bitte vorher auf der Web-Site überprüfen, ob es wirklich immer noch das aktuelle ist, wenn ja:

# cd /tmp

# wget -c https://swupdate.openvpn.org/community/releases/openvpn-2.5.7.tar.gz

Eine durch das ältere Buster-Release seinerzeit notwendig gewordene Änderung betrifft das Paket "checkinstall", welches vermutlich aufgrund von Fehlern zeitweise nur über die Backports installiert werden konnte. Checkinstall hatte ich bis dahin zum Bauen des Pakets verwendet. Die aktuellen Probleme des Programms, wegen derer es wahrscheinlich noch nicht im regulären Repo verfügbar ist, werden wahrscheinlich im Lauf der Zeit alle korrigiert, aber wenn es eine wirklich einfache Alternative für das gleiche Ergebnis mit sowieso im Betriebssystem vorhandenen Bordmitteln gibt, warum sollte ich da überhaupt ein weiteres Paket installieren? Wie wir sehen werden, ist das auch gar nicht notwendig. Aber speziell zu diesem Punkt möchte ich noch einen wichtigen Hinweis geben, der für beide Methoden gilt:

Das hier von uns selbst erzeugt Deb-Package ist nach seiner Fertigstellung ein statisches Paket, man könnte fast sagen "quick&dirty" erstellt, ohne Prüfsummen, es wird nicht automatisch upgedatet, erhält keine Security-Patches und erfüllt auch nicht die Dokumentationsanforderungen für Debian. Deshalb sind diese Pakete von "geringerer" Qualität als die durch einen Maintainer regulär erstellten Pakete. Das alles ist jedoch nichts wirklich Schlimmes, im Gegenteil, das erzeugte Paket ist technisch astrein und top-aktuell... aber wir sollten/dürfen es nicht verbreiten oder verteilen. Denn das wäre einfach nur unfair gegenüber dem anderen Nutzer, der mit Sicherheit bestimmte Erwartungen an seine Debian-Installation hat, Erwartungen die unser Deb-Package jedenfalls nicht erfüllen kann - selbst wenn es fehlerfrei funktioniert. Rein technisch betrachtet ist das Paket tatsächlich tadellos, aber das ist eben nicht alles, was man dabei berücksichtigen sollte.

Fangen wir an, die Erstellung unseres neuen Deb-Packages vorzubereiten. Weil für die Installation und Inbetriebnahme weitere Werkzeuge notwendig sind, tue ich hier alles von vornherein als "root". Man kann das auch alles umständlich mit sudo-Statements erledigen, aber da ich "sudo" sowieso für völlig überflüssig und geradezu als gefährliches Sicherheitsleck erachte, verschwende ich hier ganz bestimmt keinen Gedanken daran. Ich empfehle aber, meiner Vorgehensweise in \tmp unverändert zu folgen, weil das keine Nachteile beinhaltet und im Ablauf getestet ist.

Weitere und noch zusätzlich notwendige Pakete werden zuerst überprüft. Überprüfen bedeutet nachzusehen, ob die entsprechenden Pakete nicht schon auf dem Rechner installiert sind, um dann nur die noch fehlenden zu installieren. Bitte also nicht einfach blind die Befehlszeilen kopieren und übernehmen und ausführen... es ist jedes mal sicherzustellen, dass nur die jetzt noch fehlenden Pakete installiert werden.... alles andere lassen wir unberührt!

# dpkg -l build-essential autoconf automake autotools-dev intltool

dpkg-query: Kein Paket gefunden, das auf build-essential passt

dpkg-query: Kein Paket gefunden, das auf autoconf passt

dpkg-query: Kein Paket gefunden, das auf automake passt

dpkg-query: Kein Paket gefunden, das auf autotools-dev passt

dpkg-query: Kein Paket gefunden, das auf intltool passt

# apt install build-essential autoconf automake autotools-dev intltool

# dpkg -l liblzo2-2 libssl-dev liblzo2-dev liblz4-dev libpam0g-dev net-tools iproute2 openssl

dpkg-query: Kein Paket gefunden, das auf openssl passt

dpkg-query: Kein Paket gefunden, das auf liblzo2-2 passt

dpkg-query: Kein Paket gefunden, das auf libssl-dev passt

usw... NUR fehlende Pakete installieren!

# apt install liblzo2-2 libssl-dev liblzo2-dev liblz4-dev libpam0g-dev net-tools openssl iproute2

# mkdir -p /tmp/openvpn/root/opt/openvpn/plugins

# mkdir -p /tmp/openvpn/root/DEBIAN

# mkdir -p /tmp/openvpn/root/usr/local/share/man/man8

# mkdir -p /tmp/openvpn/root/usr/sbin

Ich verwende als Zielverzeichnis zum Entpacken und für die Erstellung des Pakets auf allen Systemen einfach /tmp, denn, wenn alles fertig ist, brauch ich den ganzen Kram nicht mehr und lass es mit dem Runterfahren meines Rechner einfach verschwinden. Selbst wenn ich es erneut brauchen würde, habe ich es in wenigen Sekunden neu erstellt, warum soll ich mich also dafür mit Aufwand zum Aufbewahren belasten? Also, weg mit dem unnötigen Kram am Ende.

# ne /tmp/openvpn/root/DEBIAN/control

Package: openvpn

Version: 100.2.5.7

Section: misc

Priority: extra

Architecture: amd64

Depends: liblzo2-2, libpam0g

Installed-Size: 8

Maintainer: toml <toml@thlu.de>

Homepage: www.thlu.de

Description: Openvpn-2.5.7

                            

Die 100 als Prefix zur Version des Pakets stellt sicher, dass OpenVPN nicht im Zuge der regulären System-Upgrades verändert wird. Die Version 100 ist eine deutlich höhere Version, als es die derzeit aktuelle 2 ist.

 

Die markierten Werte sind auf eigene Parameter anzupassen

 

Achtung: Unterhalb des Feldes „Description“ muss als letzte Zeile eine Leerzeile angefügt werden.

# cd /tmp/openvpn

# tar -xf /tmp/openvpn-2.5.7.tar.gz

Das OpenVPN-Tar-Archiv wird in den neu erstellten Zielordner entpackt.

# cd /tmp/openvpn/openvpn-2.5.7

# ./configure

# make

Kompilieren der Sourcen. Bitte jeweils auf Fehlermeldungen achten. Wenn Fehler berichtet werden, dann nicht weitermachen, die Fehler müssen zuerst behoben werden. "Warnings" können allerdings zunächst ignoriert werden.

...und kopieren der benötigten Dateien in unser temporäres build-deb-Verzeichnis:

# cp /tmp/openvpn/openvpn-2.5.7/src/openvpn/openvpn /tmp/openvpn/root/opt/openvpn

# cp /tmp/openvpn/openvpn-2.5.7/src/plugins/down-root/.libs/openvpn-plugin-down-root.so /tmp/openvpn/root/opt/openvpn/plugins

# cp /tmp/openvpn/openvpn-2.5.7/src/plugins/auth-pam/.libs/openvpn-plugin-auth-pam.so /tmp/openvpn/root/opt/openvpn/plugins

# cp /tmp/openvpn/openvpn-2.5.7/src/plugins/down-root/openvpn-plugin-down-root.la /tmp/openvpn/root/opt/openvpn

# cp /tmp/openvpn/openvpn-2.5.7/src/plugins/auth-pam/openvpn-plugin-auth-pam.la /tmp/openvpn/root/opt/openvpn

# cp /tmp/openvpn/openvpn-2.5.7/doc/openvpn.8 /tmp/openvpn/root/usr/local/share/man/man8

# cd /tmp/openvpn/root/opt/openvpn/plugins

# ln -s ../openvpn-plugin-down-root.la openvpn-plugin-down-root.la

# ln -s ../openvpn-plugin-auth-pam.la  openvpn-plugin-auth-pam.la

# cd /tmp/openvpn/root/usr/sbin

# ln -s ../../opt/openvpn/openvpn openvpn

Drei Symlinks zur Vervollständigung erstellen

# cd /tmp/openvpn

# dpkg -b /tmp/openvpn/root openvpn-2.5.7_bullseye_amd64.deb

Nun wird das deb-Package erzeugt

# cp /tmp/openvpn/openvpn-2.5.7_bullseye_amd64.deb /home

Das neue Deb-Package wird zur späteren Verwendung aus dem /tmp-Dir auf einen nichtflüchtigen Speicher gesichert.

Achtung: Bitte auf keinen Fall vergessen, dass jedes erstellte Deb-Package ausdrücklich für eine bestimmte Prozessor-Architektur erstellt wurde. Ein amd64.deb ist nicht auf einer 32-Bit-Architektur und auch nicht auf einem Raspberry Pi installierbar. Haben wir noch einen 32-Bit-Rechner, so muss für diese Maschine ein passendes 32-Bit-Deb erstellt werden, was man problemlos mit exakt gleichen Schritten entweder auf der 32-Bit-Maschine oder in einer 32Bit-VM unseres Entwickler-PCs erledigen kann. Und wiederum mit exakt den gleichen Schritten muss das Paket auch auf einem Raspberry Pi für armhf erzeugt werden. Für alle Systeme gilt gleichermaßen, wenn das Deb-Package im Verzeichnis /tmp erzeugt wurde, muss das erstellte Paket sofort gesichert werden, damit es nicht nach einem Shutdown verloren ist. Entweder durch direktes kopieren oder bei einer bestehenden Netzverbindung auch einfach via SSH auf ein nichtflüchtiges Verzeichnis eines anderen Rechners im LAN kopieren.

.../openvpn-2.5.7_bullseye_amd64.deb

.../openvpn-2.5.7_bullseye_armhf.deb

.../openvpn-2.5.7_bullseye_x86.deb

Sofern OpenVPN auf unterschiedlichen Architekturen installiert werden soll, sollten wir am Ende unserer Arbeit für jede Rechner-Architektur ein eigenes deb-Package vorliegen haben, was jeweils auf einem zum Zielsystem passenden System erstellt wurde.

Auf unserem "Entwickler-PC" müssen wir OpenVPN nun installieren, auch wenn wir es später auf dieser Maschine nicht nutzen. Aber es wird im Laufe der weiteren Arbeiten zum Generieren der notwendigen Keyfiles benötigt.  

# dpkg -i /tmp/openvpn/openvpn-2.5.7_bullseye_amd64.deb

Vormals nicht ausgewähltes Paket openvpn wird gewählt.

(Lese Datenbank ... 24744 Dateien und Verzeichnisse sind derzeit installiert.)

Vorbereitung zum Entpacken von .../deb/openvpn_...

Entpacken von openvpn ...

# dpkg -l openvpn

||/ Name           Version      Architektur  Beschreibung

+++-==============-============-============-=========================

ii  openvpn        100.2.5.7    amd64        Openvpn-2.5.7

Wir können es später, wenn alle Arbeiten erledigt sind, natürlich auch wieder löschen. Aber genauso gut kann man's auch einfach bestehen lassen. Im Unterschied zu der aus dem Repository installierten Version wird hier nicht der Start des VPN-Daemons beim Systemstart durchgeführt. Weil wir das Paket auf dem Entwickler-PC vermutlich sowieso nicht nutzen, sind es also einfach nur ein paar Dateien in einer Menge von vielleicht 100.000 oder 200.000 weiteren Dateien - mit anderen Worten, nichts worüber man großartig nachdenken muss. Aber wer will, kann es später mit apt purge openvpn auch wieder entfernen.

 

Einige der hier in dieser Beschreibung angelegten bzw. anzulegenden Dateien können mit dem dieser Beschreibung entsprechenden Inhalt unter der folgenden Adresse runter geladen werden.

 http://www.thlu.de/Public/openvpn.tar

Wenn die im Tar-File enthaltenen Dateien in die späteren Original-Verzeichnisse kopiert werden, um sie dort manuell anzupassen, müssen unbedingt die Rechte-Einstellungen gemäß dieser Anleitung nachbearbeitet werden! Im Übrigen ist es möglich, dass die Beispiele hier in der Anleitung weniger aktuell sind, als die im Tar-File enthaltenen Dateien. Deswegen empfehle ich unbedingt, nur die Beispieldateien aus dem Tar-File zu verwenden und nach /tmp zu entpacken. Bei mir ist das dann der Ordner /tmp/OpenVPN, auf den ich im weiteren Verlauf des Artikels mehrfach Bezug nehme.

 

 

Ein paar Basics zu Protokollen, Verschlüsselung und Perfect Forward Secrecy

Trotz ziemlich mühsamen und tagelangen Recherchen im WWW zur Beantwortung der Frage, wie viele Bits braucht's denn nun für eine sichere Verschlüsselung, musste ich irgendwann zweifelsfrei feststellen, dass es ab einem gewissen Level wirklich schwierig wird, verständliche und belastbare Antworten allein durch Suchen zu finden. Aber letztlich muss auch bei solchen Schwierigkeiten trotzdem immer das bereits in der Kapitelüberschrift erwähnte "Perfect Forward Secrecy" (PFS) das angestrebte Ziel sein. Die Probleme dabei sind sehr anspruchsvoll, die im Web gefundenen Lösungen bleiben hinsichtlich der Erklärungen meistens ein wenig vage, bis hin zu völlig fehlenden Erklärungen. Und manchmal erkennt man, dass eine Lösung auch nur woanders abgeschrieben wurde... bis hin zum auch gefundenen und geradezu fatalistischen Fazit, dass es vermutlich wirklich keine ultimative Sicherheit für lange Zeiträume geben wird. PFS beinhaltet jedenfalls nach derzeitigem Wissensstand die maximale Sicherheit dafür, dass heutige OpenVPN-Verbindungen (Mehrzahl!), die jetzt durch irgendeine Instanz unerlaubt mitgeschnitten und gespeichert wurden, auch in der Zukunft nicht rückwirkend mal eben auf die Schnelle entschlüsselt werden können. Es bedeutet, dass, wenn im schlimmsten Fall eine einzelne Sitzung erfolgreich gehackt wurde, dennoch alle anderen früheren und künftigen Sitzungen nicht gleichzeitig ebenfalls gehackt worden sind oder gehackt werden können.

 
TLS 1.3 ist die Implementierung des derzeitig höchsten Sicherheitsstandards, ein Standard, der uns Anwendern überhaupt Perfect Forward Secrecy ermöglicht. Und genau diesem Aspekt, also TLS 1.3, sollten wir durchaus immer Aufmerksamkeit widmen. Denn gerade aller staatlichen Überwachung beim Angriff auf demokratische Grundrechte durch digitale Entmündigung der Bürger ist an TLS 1.3 überhaupt nicht gelegen. Mit dem Versuch der europäischen Standardisierungsorganisation (ETSI) das sichere TLS durch ein unsicheres Enterprise-TLS zu ersetzen, wird nämlich die mögliche Sicherheit schlichtweg wieder untergraben, indem erstens Kryptografie-Schlüssel mit einer Kurzzeitlebensdauer wirksam verhindert werden, wodurch zweitens wiederum PFS verhindert wird. Wenn also ETLS auf dem Karton drauf steht, ist definitiv kein TLS drin... darauf sollten wir achten. Also zugegeben, dieses kleine jetzt folgende Kapitel ist schon sehr tief in die harte Technik eintauchend, und das braucht wirklich nicht jeder. Aber es ist trotzdem nicht unwichtig, so kann es einem selber mit besserem Verständnis über die Zusammenhänge dabei helfen, bessere und belastbarere eigene Entscheidungen treffen zu können.
 

Vor einer technisch gut begründeten Entscheidung über die Art und Weise der Verschlüsselung für den Schutz privater Daten vor unerlaubtem Ausspähen fehlt zunächst eine Antwort auf die wichtigste Frage: Bis wie weit in die Zukunft sollen die von mir verschlüsselten Daten überhaupt sicher sein?

Im Regelfall sollte man dabei an die langfristige Speicherung von Dateien auf einem Speichermedium denken, wenn man für den Lagerort des Mediums nicht garantieren kann, dass sich keine unberechtigten Personen Einsicht oder Zugriff verschaffen können. Deshalb sollen die Dateien ja schließlich verschlüsselt werden. Weil man allerdings davon ausgehen kann, das RSA-2048 in naher Zukunft gebrochen wird oder werden kann, ist das für langfristig zu speichernde Daten vermutlich keine gute Wahl. Allerdings sollte man an diesem Punkt auch mal kurz darüber nachdenken, wer solchen Schutz überhaupt brechen kann, welche Hardware er dazu benötigt und ob das wirklich sogar on-the-fly auch mit unseren Low-Level-Consumer-Geräten möglich ist. Bei diesem Aspekt vermute ich, dass es da schon größeres und deutlich leistungsfähigeres Werkzeug bedarf. Und außerdem korreliert der Aufwand zum Entschlüsseln unserer privaten Daten auch immer mit der Bedeutsamkeit dieser Daten... der Aufwand muss sich schlichtweg lohnen, für belanglosen Kram ist das einfach zu teuer und zu aufwendig. Aber unberücksichtigt davon, besser wäre es dafür auf jeden Fall bereits heute schon RSA-3072 oder sogar RSA-4096 zu verwenden. Vielleicht darf es sogar noch ein bisschen mehr sein... so nach dem Motto "viel hilft viel", vielleicht 8192 oder sogar 16384 Bit? Denn wer kann schon heute beantworten, wie lange solcherart Verschlüsselung überhaupt noch sicher ist. Allerdings löst das sofort auch weitere Fragen aus, z.B. ob die Ver- und Entschlüsselung in sehr hoher Qualität und mit einer echten Langzeit-Perspektive im eigenen täglichen Gebrauch überhaupt praktikabel ist, oder ob das Arbeiten dann möglicherweise unzumutbar länger dauert? Ist das noch erträglich oder sitzt man ständig wartend vor dem Bildschirm? Was ist überhaupt ein gesundes Verhältnis von Performance und Sicherheit und eigenen Anforderungen/Bedürfnissen?

Und als nächstes muss die ebenso wichtige Frage beantwortet werden, mit der uns eine Unterscheidung abverlangt wird: Will ich selber tatsächlich langfristig schutzwürdige Daten verschlüsselt speichern oder erzeuge ich mit OpenVPN-Verbindungen nur dialogartige Kommunikationsdaten mit einer für mich nur kurzlebigen Bedeutung, wobei ich aber verhindern will, dass jemand diese verschlüsselte Kommunikation unerlaubt speichert und sie möglicherweise irgendwann in der Zukunft unautorisiert entschlüsselt?

Bei dieser zweiten Frage geht es um typische kurzlebige Ad-Hoc-Datenverbindungen, die man zwischen zwei vertrauenswürdigen (aber an entfernt voneinander liegenden Standorten befindlichen) Geräten über eine nicht-vertrauenswürdige Datenleitung (das Internet) hergestellt hat. Dabei greift man zum Beispiel von unterwegs mithilfe eines OpenVPN-Tunnels auf sein NAS im heimischen Netzwerk zu, oder auf den Kalender-/Kontakte-Sync des Homeservers, oder auf den heimischen Mailserver oder die Cloud, oder man will einfach nur über seinen eigenen DSL-Router einen sicheren Zugang ins Internet herstellen... was auch immer... also eben genau das, worum es hier in dieser Setup-Dokumentation geht. Hierbei werden nicht explizit Dateien verschlüsselt, sondern lediglich kurzzeitig auftretende Kommunikationsdaten.... und selbst wenn dabei tatsächlich Dateien übertragen werden, auf dem Transportweg sind das letztlich dennoch nur Dialog- oder Kommunikationsdaten, weil sie rechts und links außerhalb des Tunnels wieder ganz normale unverschlüsselte Dateien sind. Der charakteristische Unterschied ist, bei der ersten Frage geht es um den Zugriffsschutz bei der Langzeit-Speicherung von Dateien, bei der zweiten Frage geht es um die Abhörsicherheit eines kurzzeitigen 'Gesprächs' zwischen zwei vertrauenswürdigen Computern über die unsichere Wegstrecke 'Internet'.

Weil die Langzeitspeicherung von Dateien jedoch nicht das Thema dieses Artikels ist, gehe ich auch nur in aller Kürze darauf ein. Aber es ist wichtig, das nicht vollkommen außer acht zu lassen, weil es dabei hilft, die unterschiedlichen (!) Auswirkungen zu verstehen und was es für unsere heutigen OpenVPN-Verbindungen bedeutet, wenn gesagt wird, RSA2048 ist langfristig unsicher. Ganz allgemein wird heute aber auch festgestellt, dass die Verschlüsselung mit RSA-2048 derzeit im Jahr 2019 eben noch nicht gebrochen werden kann. Es wird jedoch empfohlen, schon heute für Langzeitarchive eine über das Jahr 2030 hinausreichende Verschlüsselung z.B. mit RSA-3072 oder RSA-4096 zu wählen. Solange es nicht auf einmal zu einem massiven Forschungs-Durchbruch in mathematischen Erkenntnissen oder zu enormer Leistungsfähigkeit von neuen Computern kommt, ist eine solche Verschlüsselung sicher. Allerdings kann man sich auch die Frage stellen, wenn es irgendwann in der Zukunft Risiken gibt, warum sollte ich dann heute überhaupt noch RSA für diesen Zweck nehmen? Warum sollte ich mir über all das Gedanken machen, wenn ich ein Longterm-Storage doch gleich mit AES256 ohne diese Risiken des möglichen Brechens schützen kann? Genau aus diesem Grund speichere ich solche Daten-Archive bereits heute mit GPG und AES256 verschlüsselt. Dabei unterliegt es dann kompromisslos meiner Verantwortung dafür zu sorgen, dass der Kryptografie-Schlüssel konsequent vor Fremdzugriff geschützt ist. Gelingt das, sind die Daten sicher ... verschlampe ich allerdings die sichere Aufbewahrung des Schlüssels, sind die Dateien möglicherweise auch nicht mehr sicher. Aber hier gilt ergänzend, der verschlampte Schlüssel bedarf mindestens einer Person, die diesem Schlüssel unberechtigt verwendet.

Völlig anders sieht es aber m.M.n. bei Ad-Hoc-Verbindungen mit OpenVPN aus, weil bei dieser temporären Datenverbindung kein gewollter Longterm-Storage beabsichtigt ist, das sind immer alles sehr kurzlebige Daten aus einer Quasi-Dialog-Kommunikation zwischen zwei Geräten. Hier kann es schlimmstenfalls passieren, dass irgendeine fremde Instanz diesen verschlüsselten Datenverkehr unerlaubt mitschneidet und auf einen Zeitpunkt in der Zukunft wartet, um diesen (für mich dann belanglosen) Traffic aus einem weit zurückliegendem Jahr rückwirkend entschlüsseln zu können. Wie zuvor ist also auch für solcherart verschlüsselter Kommunikation selbstverständlich ein Kryptografie-Schlüssel notwendig, hierbei zum fast zeitgleichen verschlüsseln und unmittelbarem entschlüsseln auf der anderen Seite. Und weil es sich hier um zwei im Dialog mit einander 'sprechende' Geräte handelt, muss natürlich beiden Geräten jetzt und in diesem Moment der gleiche Schlüssel bekannt sein, denn wenn beide nicht das 'gleiche' sprechen, gibt's auch keine Kommunikation. Das tatsächlich größte Problem bei solchen Moment-Verbindungen ist also, beide Geräten direkt am Anfang auf den gleichen Schlüssel einzustellen. Keinesfalls kann z.B. der Server bestimmen "das Password lautet heute novembergeheimsache" und überträgt dieses Password dann einfach über das Internet zum anderen Peer, z.B. via Email, oder Whatsapp, oder eine Cloud-Platform von Google oder Microsoft oder ähnlich. Als Ergebnis einer solchen Aktion kann man dann feststellen, dass die Verschlüsselung für diese Sitzung damit gerade eben aufgehoben wurde. Und natürlich kann man einen solchen Schlüssel auch nicht per Briefpost versenden oder persönlich übergeben, weil dann dieser Schlüssel einerseits zu einem statischen Kryptografie-Schlüssel werden würde, der immer wieder erneut benutzt werden würde, und andererseits weil man diese Schlüsselvereinbarung auf ggf. große Entfernung ja schließlich jetzt sofort benötigt. Der statische Schlüssel hätte zudem mit PFS natürlich überhaupt nichts mehr zu tun... wurde eine Sitzung geknackt, sind alle anderen Sitzungen auch geknackt. Das tatsächlich zu lösende Problem bei Beginn einer VPN-Sitzung ist also der geheime Schlüsselaustausch, der unbedingt jedes Mal erneut geschehen muss, bei jedem Mal mit einem neuen Schlüssel als Ergebnis, wodurch schließlich zweifelsfrei verhindert wird, dass ein bereits verwendeter Kryptografie-Schlüssel ein zweites Mal verwendet wird.

Weil man zur Lösung des Problems beim Schlüsselaustausch also keinen symmetrischen Schlüssel verwenden kann (also auf beiden Seiten des Tunnels zeitgleich und sofort verwendbar den gleichen Schlüssel), eben weil dieser nicht sicher transportiert werden kann, besteht die Lösung schon seit langer Zeit darin, zunächst einen asymmetrische Schlüssel verwendenden Algorithmus zu nutzen, wie eben RSA. An diesem Punkt angekommen ist es jetzt notwendig, zunächst einmal sowohl Bedeutung und Unterschied von asymmetrischer und symmetrischer Verschlüsselung zu verstehen. Ein Hauptunterschied von asymmetrischer (RSA/ECC) und symmetrischer Verschlüsselung (AES) besteht darin, dass es beim asymmetrischen Verfahren immer zwei Schlüssel gibt, einen öffentlichen und einen geheimen. Mit dem öffentlichen Schlüssel kann verschlüsselt werden, nur mit dem geheimen kann entschlüsselt werden. Das bedeutet, beide Peers müssen bei Beginn der Sitzung zunächst mal ihren öffentlichen Schlüssel dem Partner senden, was beim öffentlichen Schlüssel durchaus auch über einen unsicheren Weg geschehen kann, denn verschlüsselte Daten können damit eben nicht entschlüsselt werden. Zur Entschlüsselung der empfangenen Daten, die vom Partner mit dem eigenen (zuvor übertragenen) öffentlichen Schlüssel verschlüsselt wurden, verwendet der Empfänger dann seinen geheimen Schlüssel, wodurch sich der Kreis wieder schließt. Ein symmetrischer Schlüssel wird hingegen für beide Schritte verwendet, sowohl zur Verschlüsselung als auch zur Entschlüsselung... was wiederum die Konsequenz beinhaltet, dass man einen symmetrischen Schlüssel keinesfalls über einen unsicheren Weg versenden oder abgeben darf. Denn jeder, der über diesen Schlüssel verfügt, kann unsere Daten damit unerlaubt sowohl entschlüsseln als auch wieder verschlüsseln.

Und trotz der Feststellung, dass RSA-1024 und kleiner anscheinend gebrochen ist und RSA-2048 voraussichtlich in den nächsten Jahren gebrochen werden kann, ist hier und jetzt aber dennoch festzustellen, der Teil der OpenVPN-Kommunikation, der heute mit RSA2048 verschlüsselt wird, kann jetzt im Jahr 2019 noch nicht gebrochen werden. Und die Formulierung „Teil der Kommunikation“ führt uns zu der Folge-Frage „Gibt es noch einen anderen Teil?“. Ja, den gibt es, und das ist der wirklich spannende Unterschied zum o.g. Longterm-Storage. Bei OpenVPN sind die eigentlich wichtigen privaten Daten bereits heute schon nicht mehr mit RSA, sondern mit AES verschlüsselt ... und damit sind sie jetzt schon genau so sicher, wie beim oben erwähnten Procedere mit GNUPG plus AES256. Also gibt es bei OpenVPN zwei Verschlüsselungen, gleichzeitig RSA und AES, gleichzeitig asymmetrisch und symmetrisch ausgehandelt? Ja, genau so ist es. Das bedeutet, es finden tatsächlich zwei voneinander getrennte Verschlüsselungen statt.

Um das zu verstehen, muss man sich kurz mit der Funktionsweise des OpenVPN-Protokolls auseinandersetzen. Üblicherweise verwendet OpenVPN aus Performance-Gründen nicht TCP/IP, sondern UDP/IP. Beide Protokolle arbeiten jedoch auf der gleichen Ebene der Netzwerkschichten. Der Unterschied zwischen beiden ist, dass UPD keine Zuverlässigkeit beinhaltet, keine Fehlerprüfung, keine Bestätigung über Reihenfolge, Empfang oder Fehler oder Neuanforderung eines Datenpaketes... UDP ist schlichtweg stateless. UDP-Pakete werden zwar auf gleicher Ebene wie TCP-Pakete übertragen, aber eben ohne Kontroll-Mechanismen. Das macht es schneller, aber dafür mit geringerer Fehlertoleranz.

 
 
 
 

Die eigentlichen OpenVPN-Datenpakete werden wiederum mit einer eigenen Header-Struktur in den UDP-Paketen gekapselt. Um die hierbei bestehenden Mängel (durch die fehlenden Kontroll-Funktionen sowie des bei UDP ebenfalls fehlenden Security-Layers TLS) in einem bidirektionalen Dialog mit dem Anspruch auf Zuverlässigkeit zu beheben, verwendet OpenVPN eine Technik analog DTLS. Bei OpenVPN ist diese Technik allerdings um einige Jahre älter, sie basiert auf dem Multiplexing zweier Kanäle auf einem Port (z.B. 1194). Der Control-Channel emuliert dabei das, wofür TLS bei TCP/IP zuständig ist, also Authentifizierung der Peers, Verschlüsselung, Paket-Integrität, Fehlerbehandlung, auf dem weiterhin z.B. Server-Options 'gepusht' werden können und worüber Peer-Infos ausgetauscht werden. Der Daten-Channel transportiert letztlich separat verschlüsselt unsere schützenswerte persönliche Daten-Nutzlast. Die beiden folgenden Grafiken versuchen das zu veranschaulichen:

 
 

Die wichtigen Aufgaben des Control-Channels sind also, Authentifizierung der Peers, Zuverlässigkeit und Sicherheit der Kommunikation zu gewährleisten, sowie die Integrität der durchs Internet übertragenen Pakete sicherzustellen, also bis hin zur Überwachung darauf, dass die ankommenden Pakete auf dem Transportweg nicht manipuliert oder verändert wurden. Der Control-Channel wird zum Schutz der Kommunikation mit einem asymmetrischen Schlüssel verschlüsselt. Die tatsächlich schützenswerten persönlichen Daten werden auf einem eigenen Kanal transportiert, und zwar dem Daten-Channel, wo sie mit AES und einem symmetrischen Schlüssel verschlüsselt werden.

Wie in der folgenden Grafik ersichtlich ist, existiert neben RSA alternativ auch noch ECC, was für Elliptic Curve Cryptography steht. Beiden ist gemein, dass sie eine Grundlage der asymmetrischen Verschlüsselung sind. Beide Algorithmen dienen als Basis für das Diffie-Hellman Protokoll, über das schließlich der eigentliche einmalig geltende symmetrische Sitzungsschlüssel verhandelt wird. Ich habe mich in meinem Setup anstatt für RSA für die Verwendung von ECC entschieden.

 
 

Das gibt uns also jetzt einen deutlichen Hinweis darauf, wie man die Sinnhaftigkeit der Überlegung zum angeblich besseren Schutz unserer privaten Daten durch einen Wechsel von RSA-2048 auf hohe RSA-8192 auf dem Control-Channel einschätzen kann. Beides kann jetzt nämlich nicht gebrochen werden, und selbst wenn RSA-2048 im Jahr 2030 gebrochen sein sollte, ist das dennoch irrelevant, weil der Sitzungsschlüssel auf dem Daten-Chanel nicht rückwirkend rekonstruiert werden kann. Mit anderen Worten: eine solch enorme Steigerung bringt im Moment gar nichts, kostet aber, wodurch die Nachteile überwiegen. Das bedeutet aber nicht, dass man die Frage jetzt gedankenlos nach hinten schieben kann, nein, wir müssen uns trotzdem unbedingt auch Gedanken über eine sichere Verschlüsselung des Control-Channels machen, aber doch ein wenig losgelöst von den Lebenszeit-Garantien eines asymmetrischen Schlüssels. Wir brauchen mit Blick auf die Zukunft natürlich auch für den Control-Channel eine starke Verschlüsselung, einfach deshalb, damit uns die Zukunft nicht unbemerkt überholt. Dazu ein kleiner Vergleich, wie asymmetrische Verschlüsselung derzeit im Verhältnis zur symmetrischen Verschlüsselung einzuschätzen ist:

RSA

<=

AES

=>

ECC

 

 1024 Bit

 2048 Bit

 3072 Bit

15360 Bit

 

 80 Bit

112 Bit

128 Bit

256 Bit

 

160-223 Bits

224-255 Bits

256-383 Bits

512+ Bits

= Unsicher

= Voraussichtlich sicher bis ~ 2030  (Prognose basierend auf heutigem Wissensstand!)

= Sicher über 2030 hinaus (dto.)

= dto.

 

 

Die Steigerung von 2048 auf 3072 Bit ist bei RSA jedoch keine einfache Steigerung um 50% der Sicherheit, auf 4096 ist auch keine Steigerung um 100%, die Steigerung ist immer exponentiell. Die Steigerung von 112 auf 128 Bit und dann auf 256 Bit verändert die tatsächliche Tiefe auf AES bezogen wie folgt:

2^112 =

~5,19229685853483 x 1033

echo "2^112" | bc =                                             5192296858534827628530496329220096

2^128 =

~3,40282366920938 x 1038

echo "2^128" | bc =                                        340282366920938463463374607431768211456

2^256 =

~1,15792089237316 x 1077

echo "2^256" | bc = 115792089237316195423570985008687907853269984665640564039457584007913129639936

Anmerkung: Es geht hier nicht um mathematische Korrektheit bis auf die letzte Stelle. Für einen rein optischen Eindruck, um welche Größen es hierbei überhaupt geht, ist das aber völlig ausreichend. Es soll lediglich deutlich werden, dass mit einer einfachen Verdopplung tatsächlich eine exponentielle Steigerung verbunden ist.

 

Obwohl wir nun wissen, dass es nicht die Aufgabe der Verschlüsselung auf dem Control-Channel ist, unsere persönlichen Daten vor unberechtigtem Zugriff zu schützen, so ist es dennoch wichtig, sich auch mit dem Schutz eben dieses Control-Channels zu befassen.

Daraus resultieren jetzt einige Probleme und die entsprechenden Fragen:

1. Wie transportiere ich einen symmetrischen Schlüssel sicher von meinem Gerät durch das unsichere Internet zum anderen Gerät?

2. Wie verhindere ich, dass (sogar) rückwirkend alle meine Daten gehackt werden können, wenn jemand diesen Schlüssel abgreift/ermittelt/hackt/etc.?

Zu 1 kann man sagen: sicher? ist nicht möglich!.... und zu 2 kann man feststellen: verhindern? ist auch nicht möglich! Die Lösung für dieses Problem muss also anders aussehen. Zu 1 lautet sie: Wir übertragen niemals einen symmetrischen Schlüssel über unsichere Wege. Zu 2 lautet sie: Wir verwenden jeden Schlüssel nur ein einziges mal, so das ein bestimmter Schlüssel nur für eine einzige Verbindung gilt.

 

Wenn also ein symmetrischer Schlüssel zur Verschlüsselung unserer privaten VPN-Verbindung vor Beginn einer Sitzung nicht auf unsicheren Wegen übertragen werden darf und weil deshalb die beiden Peers bei Beginn der Verbindung noch gar keine Kenntnis über einen gemeinsam und temporär verwendbaren Sitzungsschlüssel haben können, müssen sie sich irgendwie ad hoc auf einen solchen Schlüssel einigen. Dieses Problem wird auf dem Control-Channel unter dem Schutz der asymmetrischen Verschlüsselung gelöst. Auf diesem Kanal können sich die beiden Peers über den Algorithmus des Diffie-Hellman-Protokolls in einer Schlüsselverhandlung auf einen neuen geheimen symmetrischen Einmal-Schlüssel einigen. Die Besonderheit dieses DH-Protokolls ist, dass der gefundene neue symmetrische Schlüssel selbst niemals übertragen wird, sondern das ihn beide Parteien jeder für sich selber errechnen. Dazu wird wie zuvor wieder von beiden Seiten jeweils ein öffentlicher Schlüssel-Anteil ausgetauscht und beide Peers errechnen in Kombination mit dem jeweils eigenen geheimen Teil einen beiden Seiten bekannten symmetrischen Schlüssel.

Hierbei ist lediglich vorher die Entscheidung zu treffen, welcher Algorithmus bei der Schlüsselverhandlung durch DH verwendet werden soll, also entweder RSA oder ECC. Die Wahl der entsprechenden Cipher-Suite erfolgt dann beim Erzeugen der Zertifikate. Bei beiden ist es aber klar, dass das als Publickey/Privatekey-Kombination nicht vollständig geheim ist, sondern das das i.ü.S. nur große Primzahlen sind, wo der Publickey als öffentlicher Schlüssel auch im unsicheren Internet übertragen werden kann. Das ist auch erst mal unkritisch, denn diese Schlüsselverhandlung für den Daten-Channel findet ja auf dem bereits verschlüsselten Control-Channel statt, und der jeweils geheime Schlüsselanteil verbleibt sowieso lokal auf dem Gerät. Die Sicherheit basiert hierbei auf der Überlegung, dass der öffentlich übertragene Schlüssel ohne weitere Bestandteile zu kennen nicht mehr zurück in seine ursprünglichen Bestandteile zerlegt werden kann.

Ein weitaus wichtigerer Aspekt bei der Schlüsselverhandlung ist jedoch der Anspruch, unbedingt eine ephemeral Cipher-Suite zu verwenden, die zweifelsfrei einen kurzlebigen Kryptografie-Schlüssel für eine einmalige Verwendung verhandelt, was derzeit durch das aktuelle TLS 1.3 sichergestellt ist. Ob jetzt als verwendeter Algorithmus nun RSA oder ECC besser ist oder schlechter ...?... die Frage muss sich jeder selber im Internet beantworten.

Die Funktionsweise des DH-Algorithmus vereinfacht dargestellt:

 
 

Für uns ist hierbei nur die Erkenntnis wichtig, ein so verhandelter Schlüssel hat wirklich nur für die aktuelle VPN-Sitzung Gültigkeit und kann selbst bei Vorliegen allen vergangenen Datenmaterials vermutlich nicht rekonstruiert werden... ganz egal und völlig unberücksichtigt davon, ob zuvor RSA-2048 oder RSA-8192 oder ECC den Control-Channel verschlüsselt hat. Und wenn man aus dem vielleicht vorliegenden Datenmaterial eines Mitschnitts ephemere Schlüssel nicht rekonstruieren kann, können auch die damit und mit AES256 verschlüsselten privaten Daten auf dem Daten-Channel nicht rückwirkend entschlüsselt werden.

Diese Schlüsselverhandlung bei Beginn einer OpenVPN-Verbindung zum Schutz des Daten-Channels findet also auf dem bereits verschlüsselten Control-Channel statt, wobei das Diffie-Hellman-Proktoll selber zur Schlüsselverhandlung nicht extra verschlüsselt ist. Und genau damit haben wir jetzt noch einmal deutlich die Bedeutung der asymmetrischen Verschlüsselung auf dem Control-Channel festgestellt... und zwar die Kommunikation an sich zu schützen, damit am Ende die vom Control-Channel unabhängige AES-Verschlüsselung auf dem Daten-Channel auf zweifelsfrei sichere Weise erfolgen kann. RSA/ECC schützt die Kommunikation auf dem Control-Channel und dort insbesondere auch die Schlüsselverhandlung zur Findung des symmetrischen Schlüssels, AES schützt dann mit diesem Schlüssel unsere auf dem Daten-Channel übertragenen Daten.

Vor dem Hintergrund der Prognose einer anscheinend begrenzten 'Haltbarkeit' einer RSA-2048-Verschlüsselung befassen wir uns nun kurz mit den vorhandenen Risiken. Fakt ist, eine schwache RSA-Verschlüsselung macht die Kommunikation auf dem Control-Channel angreifbar, wenn auch nicht heute direkt, sondern eher in der Zukunft rückwirkend. Theoretisch ist es also denkbar, wenn die Verschlüsselung erst einmal gebrochen ist, dass eine aufgezeichnete komplette Kommunikation auf dem Control-Channel rückwirkend lesbar ist. Das beinhaltet dann ggf. den Umstand, dass auch die in der Schlüsselverhandlung ausgetauschten öffentlichen Parameter möglicherweise unautorisierten Personen bekannt sind. Allerdings kann damit immer noch nicht sofort auch der Daten-Kanal entschlüsselt werden, es fehlt ja noch von beiden Seiten der geheime Teil aus der Schlüsselverhandlung, der nicht übertragen wurde. Möglicherweise ist es irgendwann in der Zukunft sogar möglich, aus einer mitgeschnittenen OpenVPN-Sitzung nicht nur den Control-Channel zu hacken, sondern auch den geheimen Schlüssel des Daten-Channels zu rekonstruieren. Das könnte möglicherweise dadurch begünstigt sein, wenn die beiden Peers in der Schlüsselverhandlung quasi wiederholt den gleichen Key quasi als Static-Session-Key verwenden würden. Aus mehreren mitgeschnittenen Sitzungen im Rahmen einer quasi fortlaufenden Überwachung wären dann wegen des größeren Daten-Material-Umfangs evtl. bessere Möglichkeiten für mathematische Rückschlüsse gegeben. Aber das führt uns dann zwangsläufig zu der Erkenntnis, dass man Wiederholungen des zuletzt verwendeten symmetrischen Schlüssels auf dem Daten-Channel besser kategorisch ausschließt, was durch TLS 1.3 sichergestellt sein sollte.

Also, nicht die sinnlos übertriebene Steigerung der RSA-Tiefe auf dem Control-Channel ist die Lösung, denn da ist der Wechsel von 'Schlecht' auf 'Optimal' auf 'Überoptimal und wieder Schlecht' schnell geschehen. Die optimale Lösung liegt bei der Wahl der richtigen Cipher-Suite, die dafür sorgt, dass ein einmalig generierter symmetrischer Schlüssel keinesfalls wiederholt wird oder wiederholbar ist und auch nicht aus dem vorliegenden Datenmaterial rekonstruiert werden kann. Wenn also tatsächlich die Verschlüsselung des Control-Channels irgendwann gebrochen wäre, bedeutet das jedenfalls noch lange nicht, dass auch wirklich unsere Daten auf dem Daten-Channel gehackt worden sind. Und wenn wir für diesen Kanal einen ephemeren Schlüssel verwenden, bedeutet das auf jeden Fall, dass mit einem einzelnen gehackten symmetrischen Schlüssel keinesfalls frühere Sitzungen entschlüsselt werden können. Es reicht also überhaupt nicht aus, nur die Verschlüsselung des Control-Channels zu brechen, um sofort Zugang zu unseren vertraulichen Verbindungsdaten zu haben. Wer also wirklich besorgt ist, sollte sich zwischen ECC und RSA-4096 entscheiden... beides ist nach heutigem technischen Wissen noch lange sicher.

Außerdem vertrete ich an der Stelle unverändert den Standpunkt, das ist doch alles vor dem Hintergrund der eher geringen Bedeutung meiner privaten Daten sowieso viel zu aufwendig. Darüber hinaus ist doch auch viel einfacher an relevante Daten heranzukommen, wenn es gelingt die Daten-Quelle selber zu kompromittieren... z.B. durch Trojaner resp. den Staatstrojaner direkt auf der Festplatte des PCs, über vielleicht subversive Software aus fremden Quellen (ppa's), durch proprietäre unkontrollierbare Software, durch subversive AddOns, Plugins, Apps, durch Ausnutzung bzw. Missbrauch von administrativen Rechten (sudo) leichtsinniger oder fahrlässiger User. Dabei findet das Ausspähen der Daten direkt an der Quelle statt, bevor überhaupt eine Verschlüsselung Schutz bieten kann. Allein auf OpenVPN zu vertrauen und gleichzeitig die Integrität des eigenen Netzwerks durch leichtsinnig installierte Fremd-Software fahrlässig zu behandeln ist sicher keine gute Lösung.

Als weiteres wirklich relevantes Problem erachte ich zudem die Frage, was sich bei allen Betrachtungen auch klar herausgestellt hat, wie kann ich sicherstellen, dass der Host auf der anderen Seite wirklich der ist, der er zu sein vorgibt? Ich muss mir für den Erfolg all meiner Schutzmaßnahmen sicher sein, dass bei der Schlüsselverhandlung auf dem Control-Channel auch wirklich meine zwei vertrauenswürdigen Geräte sicher verschlüsselt verbunden sind. Kommuniziere ich nämlich unbemerkt mit einem MITM oder einer Middlebox, ist es faktisch völlig egal, ob ich mit dem oder dem Mann im Mond über RSA-1024 oder RSA-15360 kommuniziere.... dann verhandele ich nämlich mit einem unautorisierten Dritten über den symmetrischen Schlüssel und nicht mit dem gewollten Partner. Dann spielt es keine Rolle, mit welcher Logik oder Schlüsseltiefe verschlüsselt wird, die 'Leitung' ist gehackt. Andersrum ist es heute noch ebenfalls egal, wenn die Integrität beider Peers und der Verbindung unzweifelhaft ist, ob ich RSA2048 oder größer verwende... in dem Fall ist RSA2048 heute genauso sicher, wie ein höherer Wert, weil darüber auf zweifelsfrei sichere Weise ein nur einmalig gültiger symmetrischer Schlüssel für den Daten-Channel verhandelt wurde.

Das primäre Ziel muss deswegen immer sein sicherzustellen, dass der andere Peer auch wirklich der ist, der er vorgibt zu sein... und deshalb muss ich meine Zertifikate durchaus vor unberechtigtem Zugriff geschützt sicher aufbewahren, eben damit nicht jemand Fremdes mit der Verwendung eines gestohlenen Zertifikats vorgeben kann, jemand zu sein, der er gar nicht ist.

Ums nun zum Ende zu bringen ... bei all den vielen vorhandenen Faktoren, die man beachten muss und die es einem selber wirklich sehr schwer machen, für die Lösung der eigenen Ansprüche überhaupt einen Überblick zu behalten und belastbare Entscheidungen treffen zu können, lautet mein Fazit für dauerhaft sichere OpenVPN-Verbindungen:

1. Zertifikate vor Fremdzugriff gesichert aufbewahren, um die Zweifelsfreiheit bei der Identifizierung/ Authentifizierung der Peers zu gewährleisten

2. Key-Files für die Verschlüsselung vor Fremdzugriff gesichert aufbewahren

3. Sofern die eigene Hardware/Software das unterstützt, nur TLS 1.3 zulassen, was definitiv die stärkste Sicherheit darstellt.

4. Im Conf-File des Servers keine Cipher-Suites für TLS vorgegeben, denn das verbessert nicht die Sicherheit, sondern schwächt sie auf der Zeitschiene. Ein üblicher Umstand für solche Fehlentscheidungen kann z.B. der Einsatz von ggf. ältere Hardware sein, die vielleicht nur TLS 1.2 unterstützt. Wenn also ältere Hardware den aktuellen TLS-Standard nicht unterstützt und damit die Einstellung --tls-version-min 1.2 zwingend erfordert und gleichzeitig eine für das alte Gerät passende Cipher-Suite vorgegeben würde, bedeutet das, dass diese schwächere Cipher auch für Geräte verwendet wird, die eine höhere Version verwenden könnten. So würde bei modernen Client-Systemen wie z.B. Debian bullseye ohne vorgegebene Cipher-Suites ganz unabhängig davon dennoch TLS 1.3 angewendet werden.

 

Die explizite Angabe einer Cipher-Suite mit --tls-cipher hingegen würde genau das verhindern und stattdessen auf die vorgegebene schwächere Sicherheit wechseln. Ein weiterer negativer Effekt besteht, wenn in einem modernen System ein Cipher-Upgrade auf eine höhere Version durchgeführt wurde, würde für das moderne Gerät auch diese bessere Version unterdrückt werden. Es ist deshalb grundsätzlich keine gute Idee, die Sicherheit durch Angabe einer speziellen Cipher-Suite generell zu schwächen, weil möglicherweise ein altes Gerät nur den älteren TLS-Standard unterstützt. Im Grunde genommen gibt es wenig gute Begründungen für die Verwendung von --tls-cipher, außer das man die Sicherheit bewusst und vorsätzlich beschränken will. OpenVPN verhandelt von sich aus zwischen den beiden verbundenen Geräten immer die best-mögliche Sicherheit ... man muss das nur zulassen. Wenn aus der automatischen Wahl einer Cipher-Suite durch OpenVPN eine unzureichende Sicherheit resultiert, liegt es nicht an mangelhaften Einstellungen, sondern an den fehlenden Möglichkeiten eines unsicheren Gerätes.

Wenn man sich allerdings sicher ist, dass alle Geräte TLS 1.3 beherrschen, bietet die Einstellung --tls-version-min 1.3 (ohne --tls-cipher-Parameter) derzeit zweifelsfrei die best-mögliche Sicherheit, die auch 'Perfect Forward Secrecy' beinhaltet. In TLS 1.3 wurden alle statischen Cipher-Suites entfernt (siehe RFC8446). Bei meinen Tests mit Android-Geräten hatten die Clients ab Android 6 keinerlei Probleme mit der Vorgabe TLS 1.3.

5. Eine auf den Moment bezogen angemessene Verschlüsselung auf dem Control-Channel verwenden, derzeit also ECC oder RSA (3072 oder 4096 Bit). Der Verschlüsselungsalgorithmus wird im Zertifikat festgelegt, siehe weiter unten easy-rsa->vars.

6. Statt --tls-auth den Parameter --tls-crypt verwenden, wodurch der zunächst mit einer asymmetrischen Verschlüsselung geschützte Control-Channel zusätzlich mit einem eigenen symmetrischen Schlüssel gleichermaßen wie der Daten-Channel verschlüsselt wird. Mehr Sicherheit geht fast nicht.

7. Die Message-Authentifizierung mit --auth SHA256 herstellen. Es gilt hierbei die gleiche Regel, wie oben schon mal erwähnt: ohne Message-Authentifizierung ist schlecht, SHA256 ist optimal, SHA512 ist überoptimal und somit wieder schlecht. SHA512 verbessert nicht die Sicherheit, sondern verschlechtert nur die Performance. Die Message-Authenfizierung ist keine Verschlüsselung, sondern sie signiert lediglich die verschlüsselten Pakete, damit der Empfänger feststellen kann, dass ein Paket auf dem Transport durchs Internet nicht 'blind' verändert wurde. Es ist nämlich durchaus vorstellbar, nach der 'blinden' Manipulation eines verschlüsselten Paketes über die Fehlerreaktion des empfangenden Programms Rückschlüsse auf das Programm ziehen. Wenn einmal das Programm erkannt ist, lassen sich dann wieder Rückschlüsse auf die Form/Struktur der Inhalte ableiten. Je mehr Vergleichsdaten danach vorliegen, umso besser sind dann weitere mögliche Rückschlüsse, wodurch letztlich die Sicherheit definitiv geschwächt wird. Wenn man sicher ist, eine sicher verschlüsselte Verbindung hergestellt zu haben, ist SHA256 zur Prüfung der Paketintegrität absolut ausreichend. SHA512 'kostet' annähernd den 4-fachen Overhead im Datenpaket und beeinträchtigt somit völlig unnötig negativ die Performance, ohne das mit diesem höheren Aufwand ein Gewinn verbunden wäre.

8. Wenn eine Verbindung laut OpenVPN-Logs diesen Status innehat, wurde meines Erachtens nach heutigem Stand seitens OpenVPN die best-mögliche Sicherheit hergestellt, für die es in diesem Augenblick keinen weiteren Handlungsbedarf gibt oder das irgendwelche Verbesserungen möglich sind:

Tue Nov 19 15:54:06 2019 Control Channel: TLSv1.3, cipher TLSv1.3 TLS_AES_256_GCM_SHA384, 384 bit EC, curve: secp384r1

Tue Nov 19 15:54:07 2019 Outgoing Data Channel: Cipher 'AES-256-GCM' initialized with 256 bit key

Tue Nov 19 15:54:07 2019 Incoming Data Channel: Cipher 'AES-256-GCM' initialized with 256 bit key

Und ja, man kann durchaus trotzdem noch eigene Änderungen vorsehen, wie z.B. RSA anstatt ECC, oder nur eine andere Kurve anstatt secp384r1, eine andere Cipher anstatt AES-256-GCM auf dem Daten-Channel. Hier andere Parameter zu verwenden erhöht ganz bestimmt die Variabilität im allgemeinen Netz mit Blick auf alle OpenVPN-Anwender, was auch wiederum die Angreifbarkeit erschwert. Man sollte aber dabei immer die Konsequenzen seiner Änderungen auch wirklich verstehen.


 

Erstellen der Konfigurationsdateien, Keyfiles, Zertifikate und Service-Units

Weil auch dieses Thema wieder eine kleine Herausforderung darstellt, erfolgt als erstes ein Überblick darüber, was alles notwendig ist und was dafür zu tun ist. Es sind die Konfigurationsdateien für Server und Client-Systeme notwendig, sowie Service-Units, die den OpenVPN-Server in den Systemstart einreihen. Jeder Aufbau einer VPN-Verbindung fängt mit einer Authentifizierung an. Beide Teilnehmer müssen sich unzweifelhaft zu erkennen geben und müssen nachweisen, dass sie auch wirklich der sind, der sie zu sein vorgeben. Diese eindeutige Authentifizierung findet über ein für das Client-Gerät "personifiziertes" Zertifikat und Keyfile statt.

Um die folgenden Dateien müssen wir uns nun kümmern bzw. diese erstellen:

Datei

Benötigt durch

Zweck:

Geheimhaltung:

server_udp.conf

server

OpenVPN-Konfiguration

nein

server_tcp.conf

server

dto.     (von Port 443)

nein

 

 

 

 

client_udp.conf

alle clients

dto.

nein

client_tcp.conf

alle clients

dto.     (für Port 443)

nein

 

 

 

 

Datei

Benötigt durch

Zweck:

Geheimhaltung:

ca.key

key signing machine

Root CA Key

(wird zur Erstellung aller Client-Certs benötigt, unbedingt unzugänglich aufbewahren)

JA!

ca.crt

server + alle clients

Root CA Certificate

nein

ta.key

"

Encrypt + HMAC

ja

server.crt + server.key

server

Zertifikat  + Key für

Authentifizierung und Encrypt

Cert=nein, Key=ja

dh4096.pem

server

Diffie Hellman Parameters

nein

client1.crt + client1.key

client1

Zertifikate + Keys für

Peer-Authentifizierung und Encrypt

Cert=nein, Key=ja

client2.crt + client2.key

client2

client3.crt + client3.key

client3

 

 

 

 

Datei

Benötigt durch

Zweck:

Geheimhaltung:

openvpn.service

server

Service-Unit für Systemstart

nein

openvpn@.service

server

dto.

nein

set-nftables-vpn.service

server

dto.

nein

Geheimhaltung ist hier immer aus der Perspektive der CA-Signing-Machine (hier ist das mein Entwicklungsrechner) zu sehen. Von diesem Rechner werden an den Server und den Client-Systemen sowohl ein Zertifikat als auch ein Keyfile herausgegeben, denn beides wird bei der späteren Verbindungsaufnahme benötigt. Ab dem Moment der Herausgabe sind diese Dateien aber nicht mehr wirklich geheim, sie sind ja herausgegeben und ab jetzt hat nicht mehr die Key-Signing-Machine die absolute Kontrolle darüber, was mit diesen Dateien passiert. Es liegt jetzt in der Sorgfalt und der Hand dessen, der das jeweilige Client-Gerät bedient. Und auf dem Server liegt es in der Hand des Admins, der den Server wirksam gegen Zugriff von außen geschützt hat. Die auf den Client-Systemen vorhandenen Certs und Keys sind aber immer noch und ohne jeden Zweifel als äußerst "brisant" einzuschätzen, und natürlich müssen wir diese Dateien vor unberechtigtem Zugriff und vor der Öffentlichkeit als Top Secret schützen. Jeder Angreifer, der sich dieser Dateien bemächtigt, könnte sich damit als jemand ausgeben, der er gar nicht ist und sich dadurch einen vollständigen Zugriff auf unser Netzwerk verschaffen.... und wir würden das vielleicht noch nicht mal bemerken. Auf einem unbeaufsichtigten Laptop oder auf einem leicht zugänglichen Smartphone ohne Einschalt- oder Aktivierungsschutz würde ich diese Dateien jedenfalls nicht unverschlüsselt aufbewahren.

Konfigurations-Dateien

Als nächstes sind jetzt 4 Konfigurations-Files zu erstellen oder - was der bessere Weg ist - wir verwenden die Dateien aus dem zum Artikel gehörenden Tar-Archiv. Zwei sind für den Server vorgesehen, die anderen 2 werden auf allen infrage kommenden Client-Systemen installiert. Wir werden zwar alle Dateien verwenden bzw. installieren, beginnen aber bei der Inbetriebnahme zunächst nur mit der UDP-Konfiguration - so ist das auch weiter unten in der systemd-Service-Unit vorgesehen. Die TCP-Variante via Port 443 ist für mich nur eine Fallback-Installation. Im Regelfall funktioniert das UDP-Protokoll bestens.... zumal es auch den Vorteil hat, dass es performanter ist. Aber ich zeige dennoch beide Fälle, einfach auch aus dem Grund, damit die Geringfügigkeit der Anpassungen erkennbar sind. Wenn das UPD-basierte Protokoll läuft, ist es tatsächlich ein einfaches, zu einem späteren Zeitpunkt auf gleichem Weg wie zuvor auch den Daemon für das TCP-Protokoll in Betrieb zu nehmen und die Freigaben im Router einzurichten. Und wer sowieso nur vorhat, sich überwiegend hier innerhalb DE von unterwegs via UMTS mit seinem Heim-Netzwerk zu verbinden, wird die TCP-Variante eigentlich gar nicht verwenden, denn UDP läuft hierbei wirklich bestens.

TCP ist immer nur dann eine Fallback-Alternative, wenn ein übereifriger Admin sein öffentlich zur Verfügung gestelltes WLAN absichtlich oder dilettantisch kastriert hat. Das ist mir zwar nur selten passiert, aber ab und zu ist es so. Und in solchen Fällen ist es praktisch, eine Alternative zu haben... eben als Fallback via TCP Port 443.

Wenn das Tar-Archiv openvpn.tar nach /tmp entpackt ist, finden wir die folgenden neuen Verzeichnisse vor, in denen die benötigten Dateien teilweise schon enthalten sind. Im weiteren Ablauf werden wir noch Keyfiles und Zertifikate dort hineinkopieren und ganz am Ende daraus ein Setup-Paket erstellen, welches uns dann bei den einzelnen Installationen auf Server- und Client-PCs unterstützen soll.

# cd /tmp

# wget -c http://www.thlu.de/Public/openvpn.tar

# tar -xf /tmp/openvpn.tar

# ls /tmp/OpenVPN

drwxr-x--- 2 thomas thomas  60 2018-10-14 15:53 ca_client

drwxr-x--- 2 thomas thomas  60 2018-10-14 15:53 ca_server

drwxr-x--- 2 thomas thomas 120 2018-09-11 21:11 easy-rsa

drwxr-x--- 3 thomas thomas 140 2019-08-20 15:59 /etc/openvpn

drwxr-x--- 2 thomas thomas 100 2019-08-20 15:45 /etc/systemd/systemd

drwxr-x--- 2 thomas thomas  80 2018-10-14 11:51 /usr/local/bin

 

Die OpenVPN-Konfigurations-Dateien:

jetzt hier in /tmp/OpenVPN/root/etc/openvpn, später auf den Systemen installiert in /etc/openvpn

Client-Konfiguration für Transport-Protokoll UDP

 

client_udp.conf

Client-Konfiguration für Transport-Protokoll TCP

 

client_tcp.conf

tls-client

remote myprivateddnslink.net

 

proto udp

dev tun0

port 55553

 

remote-cert-tls server

pull

ping 60

 

cipher AES-256-GCM

auth SHA256

auth-nocache

 

ca        /etc/openvpn/keys/ca.crt

cert      /etc/openvpn/keys/client.crt

key       /etc/openvpn/keys/client.key

tls-crypt /etc/openvpn/keys/ta.key

 

mute 10

verb 3

explicit-exit-notify

log-append /var/run/openvpn/client.log

tls-client

remote myprivateddnslink.net

 

proto tcp-client

dev tun0

port 443

 

remote-cert-tls server

pull

ping 60

 

cipher AES-256-GCM

auth SHA256

auth-nocache

 

ca        /etc/openvpn/keys/ca.crt

cert      /etc/openvpn/keys/client.crt

key       /etc/openvpn/keys/client.key

tls-crypt /etc/openvpn/keys/ta.key

 

mute 10

verb 3

 

log-append /var/run/openvpn/client.log

 
 

Client verbindet sich als Roadwarrior mit dem

OpenVPN-Daemon des Servers

via UDP auf Port 55553

 
 

Client verbindet sich als Roadwarrior mit dem

OpenVPN-Daemon des Servers

via TCP über Extern-Port 443 auf Port 55554

Server-Konfiguration für Transport-Protokoll UDP

 

server_udp.conf

Server-Konfiguration für Transport-Protokoll TCP

 

server_tcp.conf

server 10.0.8.0 255.255.255.0

server-ipv6 fd00:10:0:8::/64

 

proto udp

dev tun0

port 55553

topology "subnet"

 

push "topology subnet"

push "redirect-gateway def1 bypass-dhcp"

push "dhcp-option DNS 10.0.1.1"

push "dhcp-option DNS fd00:10:0:1:228d:ff77:fe11:2892"

push "route 10.0.1.0 255.255.255.0"

push "route-ipv6 fd00:10:0:1::/64"

 

ca   /etc/openvpn/keys/ca.crt

cert /etc/openvpn/keys/server.crt

key  /etc/openvpn/keys/server.key

 

cipher AES-256-GCM

auth SHA256

auth-nocache

 

dh /etc/openvpn/keys/dh4096.pem

ecdh-curve secp384r1

tls-version-min 1.3

tls-crypt /etc/openvpn/keys/ta.key

 

ping-timer-rem

keepalive 10 60

persist-key

persist-tun

group vpnuser

user vpnuser

 

verb 3

mute 10

log-append /var/log/openvpn/openvpn_udp.log

server 10.0.9.0 255.255.255.0

server-ipv6 fd00:10:0:9::/64

 

proto tcp-server

dev tun1

port 55554

topology "subnet"

 

push "topology subnet"

push "redirect-gateway def1 bypass-dhcp"

push "dhcp-option DNS 10.0.1.1"

push "dhcp-option DNS fd00:10:0:1:228d:ff77:fe11:2892"

push "route 10.0.1.0 255.255.255.0"

push "route-ipv6 fd00:10:0:1::/64"

 

ca   /etc/openvpn/keys/ca.crt

cert /etc/openvpn/keys/server.crt

key  /etc/openvpn/keys/server.key

 

cipher AES-256-GCM

auth SHA256

auth-nocache

 

dh /etc/openvpn/keys/dh4096.pem

ecdh-curve secp384r1

tls-version-min 1.3

tls-crypt /etc/openvpn/keys/ta.key

 

ping-timer-rem

keepalive 10 60

persist-key

persist-tun

group vpnuser

user vpnuser

 

verb 3

mute 10

log-append /var/log/openvpn/openvpn_tcp.log

 

Schauen wir uns noch kurz ein paar der wichtigen Parameter und deren Bedeutung an:

remote myprivateddnslink.net

my private ddns link.net ist ein immer gleichbleibende symbolischer Name für die öffentliche IP-Adresse unseres DSL-Routers, mit dem wir über das Internet unser Netzwerk zuhause erreichen können. Üblicherweise richtet man sich dafür einen dyndns-Account bei einem entsprechenden Dienstleister ein, um dann bei Verwendung dieses Namens an die Internet-taugliche WAN-IP-Adresse seines heimischen DSL-Routers weitergeleitet zu werden. Wer über eine Fritzbox verfügt hat es einfach, MyFritz bietet einen solchen Dienst kostenlos an.

Warum das notwendig ist, ist einfach zu verstehen, wenn man sich das einmal so vorstellt, als hätte man kein feste heimische Telefonnummer, sondern eine täglich wechselnde, veranlasst durch den Telefon-Anbieter. Dann versuch mal zuhause anzurufen, wenn Du unterwegs bist und Dir die neue Nr. unbekannt ist. Dieses Problem löst der symbolischer Name, beim Netzwerk ist es der DynDNS-Account. Es gibt zwar Tricks und Mittel und Wege, z.B., wenn man einen eigenen Web-Space hat... aber das ist Aufwand und erfordert hohe Sachkenntnis.

remote-cert-tls server

Es ist völlig normal, mehr als 1 Client-CA herauszugeben, deshalb, weil man auch mehrere verschiedene Mobil-Geräte verwendet. Aber es wird eigentlich nie mehr als eine einzige Server-CA installiert. Und weil es sich bei den VPN-Clients meist um mobile Geräte handelt, die oft an unsicheren Standorten betrieben werden und die z.T. auch unsichere Software verwenden, werden natürlich zwangsläufig auch mehr Clients gehackt, als fest-installierte Server, die sich zudem auch noch hinter dem eigenen meist sicheren DSL-Router befinden. Mit diesem Parameter wird versucht zu verhindern, dass ein sich unrechtmäßig angeeignetes Client-Zertifikat von einem Angreifer dazu genutzt wird, sich einem anderen Client gegenüber als Server auszugeben. Ein richtiges Server-Zertifikat enthält ein Flag, welches es als Server-Cert identifiziert, was mit dieser Anweisung vom Client überprüft werden kann. Es handelt sich somit um eine zusätzliche Sicherheitsprüfung.

Eine umgekehrte Prüfung, das also der Server prüft, ob es ein echtes Client-Zertifikat ist, kann man machen, hat aber rein logisch betrachtet wenig Sinn, weil ein Server-Cert nicht so einfach entwendet werden kann. Und wenn das wirklich passiert wäre, dann hat man ein echtes und größeres Problem, weil dann nämlich der Server als solcher kompromittiert ist.

port 55553

port 55554

Muss natürlich angepasst werden, wenn eigene Ports vorgesehen sind. Für UDP ist Port 1194 der Default-Port, den man auch problemlos verwenden kann. Vielleicht ist hier der Hinweis interessant, dass auf dem UDP-Port überhaupt keine Verbindungs-Fehlversuche durch Fremde im Protokoll nachgewiesen oder festgestellt sind. Fehlversuche auf dem Fallback-Port 443 gibts allerdings täglich.

tls-crypt /etc/openvpn/keys/ta.key

Im Vergleich zu tls-auth leistet tls-crypt grundsätzlich das gleiche, verschlüsselt aber zusätzlich noch den gesamten Traffic auf dem Control-Chanel mit einem symmetrischen Schlüssel. Die Richtungsangabe ist hierbei nicht mehr notwendig.

dh /etc/openvpn/keys/dh4096.pem

ecdh-curve secp384r1

 

 

Die Wahl, ob für die asymmetrische Verschlüsselung RSA oder ECC zugrunde gelegt wird, erfolgt beim Erstellen der Zertifikate, siehe vars weiter unterhalb.

 

Das Aushandeln eines symmetrischen Schlüssels erfolgte mithilfe des Diffie-Hellman-Algorithmus. --dh ist ein Parameter auf der Server-Seite zur Verwendung beim  RSA-Algorithmus. Dieses Tutorial verwendet jedoch ECC. Aber unberücksichtigt davon, ob zuvor ECC oder RSA gewählt wird, sollte auf jeden Fall trotzdem ein dh4096.pem-File generiert und in die Conf eingetragen werden. Der Hintergrund ist, dass ansonsten bei fehlendem Pem-File die im Programm vorhandenen 'hard-coded parameter' verwendet werden, wodurch die Sicherheit wieder herabgesetzt wird und was möglicherweise eine 'Logjam Attack' begünstigt.

 

Kontroll-Befehle im Terminal, um zu prüfen für welchen Algorithmus die Zertifikate erstellt wurden:

 

openssl ec -noout -text -in /etc/openvpn/keys/server.key

openssl rsa -noout -text -in /etc/openvpn/keys/server.key

tls-version-min 1.3

Die für die Sicherheit wichtigste Einstellung. Damit wird beschränkt, wie weit die Sicherheit reduziert werden darf oder soll, damit sich ggf. auch ältere Geräte verbinden können. TLS 1.3 bietet derzeit die best-mögliche Sicherheit. Mit meiner Hardware gab es bei dieser Einstellung keine Probleme, alle Systeme unterstützten das. Falls auch Geräte verwendetet werden sollen, die nur den älteren Standard verwenden können, musst hier auf 1.2 oder ggf. noch weiter zurück geändert werden.

 

An dieser Stelle noch mal der Hinweis auf den Parameter --tls-cipher. Das ist ein Ergänzungsparameter, der die Sicherheit nicht verbessert, sondern immer nur einschränkt. Die konstante Vorgabe einer Cipher hat den Nachteil, dass sie auch dann beibehalten wird, wenn ein System eigentlich eine Cipher-Suite mit höherer Security verwenden würde und könnte. Siehe dazu die 'preferred list', in der immer die höchstwertige geeignete Cipher verwendet wird. Geeignet bedeutet, dass beide Peers die gewählte Cipher-Suite unterstützen. Wenn ein einzelnes Gerät eine hohe Sicherheit nicht unterstützt, ist es eine wirklich schlechte Entscheidung, deshalb mit ---tls-cipher die Gesamtsicherheit für alle Geräte zu reduzieren.

 

Kontroll-Befehle im Terminal:

openvpn --show-tls

openvpn --show-ciphers | less

openvpn --show-curves | less

auth SHA256

auth-nocache

Mit SHA256 erfolgt die Authentifizierung der Paketintegrität (HMAC) auf der Protokoll-Ebene.

'No Cache' verhindert, dass zur Authentifizierung eingegebene Passwörter im Speicher verbleiben und somit u.U. ausgelesen werden könnten.

server-ipv6 fd00:10:0:8::/64

push "dhcp-option DNS fd00:10:0:1:228d:ff77:fe11:2892"

push "route fd00:10:0:1::/64"

Diese Einträge sorgen dafür, dass bei meinem Dual-Stack-Account der IPv6-Stack komplett durch den VPN-Tunnel geroutet wird. Das bedeutet, sogar wenn ich mit meinem S8 via UMTS (= IPv4-Netz) Tethering erlaube, so hat mein Laptop als WLAN-Client des S8 trotzdem einen vollständigen IPv6-Stack verfügbar, mit der IPv6 (GUA) des OpenVPN-Servers als Gateway.

 

Beinhaltet der heimische DSL-Account ein reines IPv4-Netz, so müssen diese Zeilen mit dem Comment-Tag '#' deaktiviert werden.

push "dhcp-option DNS 10.0.1.1"

push "route 10.0.1.0 255.255.255.0"

Hier ist natürlich die IP-Adresse des heimischen DSL-Routers und das von ihm repräsentierte Netzwerk einzutragen, siehe:

Netzwerkeinstellungen Router

group vpnuser

user vpnuser

Die Festlegung, unter welcher UID und GID die VPN-Prozesse im System laufen. Muss man nicht, kann man aber machen und verbessert die Sicherheit, weil der User vpnuser keine privilegierten Rechte im System besitzt.

log-append /var/run/openvpn/client.log

Auf dem Client besteht immer nur eine einzige aktive Verbindung zu einer Zeit. Also kann auch immer gleichbleibend dasselbe Log verwendet werden. Ich speichere es unter tmpfs, weil ich es nur zum reinschauen brauche, wenn es Probleme gibt. War eine Verbindung erfolgreich, ist es Datenmüll, der beim nächsten Poweroff des Rechners vergessen wird.

log-append /var/log/openvpn/openvpn_udp.log

log-append /var/log/openvpn/openvpn_tcp.log

Auf dem Server sind die Grundlagen anders, weil wegen 2 möglicher Protokolltypen auch 2 Daemons gleichzeitig laufen, die jeder für sich eigene Log-Daten erzeugen.

Darüber hinaus werte ich nachträglich über Port 443 kommende Verbindungen aus und übertrage wiederholt vorkommende Hacking-IPs in meine Paketfilter-IP-Blacklist. Mir ist aufgefallen, dass es eine nur Handvoll gleicher IPs sind, die ununterbrochen eine Kontaktaufnahme versuchen. Alle anderen täglich ankommenden Einzel-Versuche sind möglicherweise nur Irrläufer, die ich ignoriere.

Alle weiteren Parameter können einfach auf der Projektseite von OpenVPN nachgesehen werden, oder noch einfacher via

# man openvpn | less

auf einem System, auf dem OpenVPN installiert ist. Sucht man einen bestimmten Parameter, wie z.B. persist-key, tippt man shift-7 (das Zeichen /) auf der Tastatur und gibt unten auf der Eingabe-Zeile den Suchbegriff --persist-key (mit führenden --) ein. Nach Drücken der Entertaste springt less zum ersten Vorkommen, mit Taste "n" springt es zum nächsten. Taste "q" beendet less.

Zertifikate und Key-Files

Wie wir in der Tabelle der "benötigten Dateien" oberhalb schon gesehen haben, müssen sowohl für den Server als auch für jeden Client unterschiedliche und jeweils individuelle Keyfiles und Zertifikate erstellt werden. Alle benötigten Files werden im Zusammenwirken mit dem neu installierten OpenVPN, OpenSSL und der Script-Sammlung aus dem Paket Easy-RSA erstellt. Und selbstverständlich werden im Anschluss die Keyfiles so gehandhabt, dass keines der Systeme die Keyfiles eines anderen System sehen oder lesen oder verwenden kann. Das bedeutet, wir kopieren auf jeden Rechner nur genau die für diesen Rechner bestimmten Dateien.

Damit uns das aber hinterher in der Handhabung während der Installation nicht unnötig schwer gemacht wird, packen wir einfach für alle Systeme die benötigten Dateien in ein Archiv, aus dem wir dann nach Bedarf für jedes System genau die Dateien herauskopieren, die dort explizit benötigt werden.

Eine Besonderheit ist das zweite Archiv, welches die PKI-Struktur enthält.

 

Jeder, der über diese Verzeichnisstruktur verfügt, kann damit neue Schlüssel erzeugen und diese für einen Zugang in unser Netzwerk verwenden, auch außerhalb unserer Kenntnisnahme. Deswegen muss dieses PKI-Archiv absolut sicher und vor Zugriff geschützt aufbewahrt werden, also idealerweise nicht auf dem PC, an dem man selber oder andere Personen täglich arbeiten. Das Setup-Paket für die Clients darf natürlich ebenfalls auch nicht einfach so an die Anwender der Clients verteilt werden, weil eben im Paket Keyfiles für verschiedene Systeme enthalten sind.

 

Dieses Paket so zu verwenden ist nur dann ein gangbarer Weg, wenn ausschließlich eine einzelne Person (der Admin) dieses Paket zur Installation auf allen Geräten verwendet, z.B. von einem USB-Stick. Muss das Paket auf ein Gerät kopiert werden, so muss es nach Ende der Arbeiten natürlich auch wieder gelöscht werden… und folgerichtig natürlich auch aus dem Papierkorb, um jeglichen Missbrauch zu verhindern.

Wie zuvor bei OpenVPN beschreite ich auch für die Erstellung der Zertifikate und Keyfiles einen eigenen Weg. Üblicherweise werden diese Dateien mit dem Paket easy-rsa erstellt, was mir aber -wie schon bei OpenVPN- im Debian-Repository nicht aktuell genug ist. Aus diesem Grund lade ich die aktuelle Version direkt von der Projektseite herunter. Der Suchbegriff "download easy-rsa" in der Suchmaschine meines Browsers führt mich sofort im ersten Ergebnis auf die passende Seite "Releases" bei GitHub, wo ich problemlos das jetzt aktuelle Release EasyRSA-*.tgz finde. Das ist die Version, welche ich auch hier in diesem Artikel verwende. Auch diesen Download muss man nicht aufbewahren, man kann ihn jederzeit aktuell neu laden, ich speichere die Datei also einfach über den Browser ebenfalls in /tmp. Alternativ kann die Datei auch direkt im Zielverzeichnis heruntergeladen werden. Das Paket easy-rsa ist selber eigentlich kein Programm im üblichen Sinne, sondern eher eine Sammlung von Script-Befehlen.

# cd /tmp

# wget -c https://github.com/OpenVPN/easy-rsa/releases/download/v3.1.0/EasyRSA-3.1.0.tgz

# tar -xf /tmp/EasyRSA-3.1.0.tgz

Da es sich hier um die Herstellung einer Certificate Authority handelt, die auf einer vertrauenswürdigen Key-Signing-Machine eingerichtet bzw. vorbereitet wird, halte ich es für angemessen, wenn diese Aktivitäten außerhalb dessen stattfindet, worauf anschließend mit normalen User-Berechtigungen zugegriffen werden kann. Die Einrichtung in tmpfs-->/tmp sorgt dafür, dass nach dem Ausschalten des Rechners nichts mehr davon vorhanden ist.

Nun sind noch einige kleinere Vorbereitungen zum Erstellen unserer eigenen Certificate Authority vornzunehmen:

# cd /tmp/EasyRSA-3.1.0

# mv /tmp/OpenVPN/easy-rsa/create-ca3 create-ca3

# mv /tmp/OpenVPN/easy-rsa/vars vars

# mv vars.example vars.example.sik

# chown -R root:root /tmp/EasyRSA-3.1.0

# chmod 755 /tmp/EasyRSA-3.1.0/create-ca3

Wenn alles richtig gemacht wurde, enthält das Verzeichnis nun u.a. die folgenden Dateien und 1 Verzeichnis:

# ls -lah /tmp/EasyRSA-3.1.0

drwxrwxr-x  2 root root  140 2018-01-21 16:37 x509-types

-rwxr-xr-x  1 root root 6,4K 2018-09-11 19:26 create-ca3

-rwxrwxr-x  1 root root  36K 2018-01-21 16:37 easyrsa

-rw-rw-r--  1 root root 4,5K 2018-01-21 16:37 openssl-easyrsa.cnf

-rw-rw-r--  1 root root  789 2018-09-11 17:32 vars.example.sik

-rw-rw-r--  1 root root  727 2022-08-25 15:32 vars

Der vermutlich übliche Weg mit EasyRSA zur Erstellung von Keys und Certs ist es, zuerst ein paar Befehle einzeln zu starten und dabei jedes mal die im Dialog gestellten Fragen zu beantworten. Ein paar dieser Befehle dienen der einmaligen grundsätzlichen Vorbereitung, andere Befehle müssen danach dann wiederholt für jedes VPN-System erneut aufgerufen werden. Ich beschreibe das hier nur in aller Kürze, weil mir das eigentlich zu kompliziert ist und weil ich das beim jährlichen Wechsel meiner CA-Files immer nur 'mit wieder erneuten Einlesen in meine How-To-Dokumentation' hinkriegen würde. Mein Script erspart mir diese Arbeit. Das hier wären die notwendigen Befehle, wenn man es Schritt für Schritt durchführt:

./easyrsa init-pki

Sollte durchgeführt werden, wenn ein komplett neuer Satz von Certs und Keys erzeugt werden soll. Der Befehl erzeugt eine neue und leere pki-Verzeichnisstruktur. Bei Wiederaufnahme eines bestehenden Verzeichnisses (z.B. Ergänzungen) muss der Punkt mit Skip übersprungen werden.

./easyrsa build-ca nopass

Key-Signing-Zertifikat und -Key ... die Grundlage aller Client-Zertifikate und Keys. Mit anderen Worten, ca.key ist die wichtigste Datei überhaupt, die unbedingt geheim zu halten ist und am besten separat aufbewahrt wird.

./easyrsa gen-req $host nopass

./easyrsa sign-req server $host

Erstellt Zertifikat und Keyfile für den Server, hier natürlich ohne Password. Mit Password wäre einigermaßen ungeschickt,weil dann in der Bootphase ein Password abgefragt wird... nur leider sieht man die Abfrage nicht, weil Systemd alle Ausgaben "einsammelt".

./easyrsa gen-req $host

./easyrsa gen-req $host [nopass]

./easyrsa sign-req client $host

Wird für jeden Client separat durchgeführt und erstellt individuelle CA-Files, meine Androids mit Password, die Debian-Clients ohne.

./easyrsa gen-crl

Eine am Anfang leere Revoke-Liste, um herausgegebene Client-Keys nachträglich zu sperren, z.B. bei Diebstahl eines Gerätes.

openssl dhparam -out dh4096.pem 4096

Diffie-Hellman-Parameters. Die Datei dient dazu, einen kryptografischen Schlüssel über potentiell unsichere Kanäle auszuhandeln. DH ist im Betrieb sicher langsamer als RSA2048, aber eben auch deutlich performanter beim Aushandeln periodischer Schlüssel. Und letztlich dient es hier nur dazu, eine sichere Authentifizierung zu gewährleisten und nicht dazu, den Normalbetrieb zu verschlüsseln.

Das Pem-File sollte unbedingt erstellt werden, weil ansonsten die im Programm vorhandenen 'hard-coded parameter' verwendet werden, was möglicherweise eine 'Logjam Attack' begünstigt.

openvpn --genkey --secret ta.key

Die HMAC-Firewall, weitere Erläuterungen siehe weiter unterhalb.

Man kann das also durchaus auch auf diesem manuellen Step-by-Step-Weg machen, nur ist mir das echt zu kompliziert und einfach zu aufwendig. Ich verwende dafür ein Helper-Script und vordefinierte Parameter, die statt der Defaults exportiert werden. Somit kann ich mich mit der Enter-Taste einfach geradlinig durch die Erstellung durchbewegen, was mich dann im Nebeneffekt auch noch erfolgreich vor Tippfehlern und meinen Leichtsinns- oder Unaufmerksamkeitsfehlern bewahrt.

Das Paket EasyRSA enthält seit jeher eine interessante Besonderheit, und zwar können wir individuellen Einfluss auf die neue Certificate Authority durch von uns vordefinierte Parameter nehmen. In gewisser Weise könnte man das auch mit einer Programm-Conf mit fest eingestellten Werten vergleichen - die Vorgehensweise ist zwar etwas anders, aber der Effekt ist für uns der gleiche. Wenn man nicht nur ein einziges mal eine CA erzeugt, sondern vielleicht regelmäßig (ich tu's jährlich), bekommt man damit bei den Wiederholungen die Garantie, dass gewisse Grundparameter immer gleich bleiben. Diese Möglichkeit ist mit der im easy-rsa-tgz-Archiv vorhandenen Datei 'vars.example' für uns als Beispiel abgebildet. Mit einer eigenen Datei 'vars' können wir nun eigene Vorgabewerte setzen. Das Script und meine geänderte vars sind selbstverständlich im Tarfile-Archiv enthalten.

Ich unterscheide in meiner vars zwei Sektionen. Der obere Teil enthält Parameter für die Kryptografie und die Gültigkeitsdauer meiner Zertifikate. Im Original ist die Gültigkeit mit 3650 Tagen auf 10 Jahre festgelegt, ich stelle es bei mir auf 365 Tage = 1 Jahr ein. Die hier vorgegebene Key-Size 4096 bietet derzeit eine hohe Sicherheit, aber man kann das natürlich ändern. Und wenn jemand denkt, SHA256 ist nicht ausreichend, kann er das auch ändern, wobei ich jedoch von einer Änderung abrate ... siehe Hinweise. Das alles muss aber jeder für sich selber entscheiden. Für meine Anforderungen sind die unten eingesetzten Parameter passend.

In der zweiten Sektion können dem Zertifikat Herausgeber-Informationen mitgegeben werden. In der früheren easy-rsa-Version hatte ich das immer noch gemacht, jetzt in der aktuellen nicht mehr. Der Aufwand beim Erstellen ist im Vergleich zu ohne um einiges höher, weil diese Parameter jedes mal einzeln bestätigt werden müssen. Es handelt sich aber doch nur um allein von uns selbst verwendete Zertifikate, da sind keine fremden Anwender, die das auch nutzen können sollen. Welchen Mehrwert hat es also, wenn Name, EMail, Wohnort, usw. im Zertifikat stehen, wenn das sowieso niemand liest. Ich habe mich deshalb für den einfachen Weg entschieden und mit der Einstellung set_var EASYRSA_DN "cn_only" nur den Common-Name zu verwenden, der einmalig abgefragt wird. Dafür wird im Dialog bei der entsprechenden Frage einmalig der Herausgeber eingetragen und fertig ist's damit:

Common Name (eg: your user, host, or server name) [Easy-RSA CA]: TomL

Meine "vars" nutzt also nur einen Teil der folgenden für mich/uns möglichen individualisierten Parameter, die während der Erstellung der Files exportiert werden, um damit die Defaults zu ersetzen. Als erstes wird bestimmt, dass auf dem Control-Channel Elliptic Curve Cryptography als Algorithmus für den asymmetrischen Schlüssel verwendet werden soll, worüber dann eine entsprechende best-möglich geeignete Cipher-Suite maschinell ausgewählt wird. Soll das Zertifikat über die notwendigen Paramenter auch die umfassenderen Herausgeber-Infos enthalten, muss EASYRSA_DN "org" gesetzt sein. Weiterhin müssen die rot markierten Werte entsprechend den eigenen Gegebenheiten angepasst werden. Und schließlich sind natürlich bei den betroffenen Zeilen auch noch die Comment-Tags '#' zu entfernen. damit diese Zeilen überhaupt beachtet werden.

/tmp/EasyRSA-3.1.0/vars

# Algorithmus?  "ec" or "rsa"  

set_var EASYRSA_ALGO            ec  

 

set_var EASYRSA_KEY_SIZE        4096

set_var EASYRSA_CRL_DAYS        365

set_var EASYRSA_CA_EXPIRE       365

set_var EASYRSA_CERT_EXPIRE     365

set_var EASYRSA_DIGEST          sha256

 

# Certificate-Properties:

# Use a Common-Name-Value requested in dialog?                           "cn_only"

# Use the "traditional" Country/Province/City/Org/OU/email/CN format?    "org"

set_var EASYRSA_DN              "cn_only"

 

set_var EASYRSA_REQ_CN          ""

set_var EASYRSA_REQ_COUNTRY     ""

set_var EASYRSA_REQ_PROVINCE    ""

set_var EASYRSA_REQ_CITY        ""

set_var EASYRSA_REQ_ORG         ""

set_var EASYRSA_REQ_OU          ""

set_var EASYRSA_REQ_EMAIL       ""

Mit der Vorgabe "org" könnten die Werte wie folgt gesetzt werden, um traditionelle Parameter-Werte einzufügen:

set_var EASYRSA_DN             "org"

set_var EASYRSA_REQ_CN         "toml.de"

set_var EASYRSA_REQ_COUNTRY    "DE"

set_var EASYRSA_REQ_PROVINCE   "NRW"

set_var EASYRSA_REQ_CITY       "Zuhause"

set_var EASYRSA_REQ_ORG        "toml"

set_var EASYRSA_REQ_EMAIL      "thomas@toml.de"

set_var EASYRSA_REQ_OU         "private"

Und auch im Script sind einige Parameter unbedingt an die eigenen Gegebenheiten anzupassen. Wegen des Zugangs zu unserer Card/Cal-Dav-Synchronisation mit den Android-Geräten und auch zum Mailserver erzeuge ich immer für mehrere VPN-Clients Zertifikate. Die Bezeichnungen dieser Clients habe ich hier willkürlich vorgenommen. Wichtig ist für mich nur, dass die tatsächlichen Namen beim jährlichen Wechsel von Cert + Key unverändert bleiben, weil eben genau darauf durch die Conf-Files Bezug genommen wird. Auf unseren Debian-Systemen sind die jeweiligen namentlich benannten Files schließlich via SymLink mit der OpenVPN.conf 'verbunden'. Das macht den Austausch dann ganz einfach.... alte Cert+Key mit neuen überschreiben und fertig. Für die Androids ist das irrelevant, da sie dort sowieso einzeln importiert werden müssen.

Eine weitere Besonderheit sind die drei Ergänzungen: {srv}, {pwd} und {p12}. In der Liste der verwendeten Hosts muss natürlich der Server von den Clients unterschieden werden, dazu dient der Eintrag {srv}. Weil ich insbesondere Android-Geräte beim Zugang ins Internet grundsätzlich für 'exponiert' erachte und deren Sicherheit systemimmanent als kritisch einzuschätzen ist, verlange ich für diese Geräte vor der Verbindung nach Hause ein Password für das Zertifikat. Wer das Password nicht kennt, kann sich nicht verbinden. Bei den Linux-Clients verzichte ich darauf, weil Debian eben nicht Android ist. Ums kurz zu sagen, die beiden Einschübe {srv} und {pwd} steuern die Erstellung der Zertfikate oder nehmen Einfluss darauf. Mit dem Eintrag {p12} wird ein Paket-Archiv mit Cert, Key und root-Cert erzeugt, welches alternativ zum einzelnen Import der Dateien als Paket in die Keychain eines Android-Smartphones übernommen werden kann.

Zur Erinnerung: alle notwendigen Dateien können mit diesem Archiv herunter geladen werden (was ich anstatt der Verwendung der Texte von der Web-Seite auch unbedingt empfehle):     http://www.thlu.de/Public/openvpn.tar

/tmp/EasyRSA-3.1.0/create-ca3

#! /bin/bash

#===================================================================================================

# Description : Create Certificate Authority ((CA) Certs & Keyfiles) for OpenVPN)

#

# Script-Name : create-ca3

# Date        : 24.08.2022

# Version     : 4.3

# Licence     : GNU General Public License 3

#

# create-ca is written and tested for Debian (... and with easy-rsa)

#===================================================================================================

 

PATH=/sbin:/usr/sbin:/bin:/usr/bin:$PATH

 

# VPN-Hosts:

fname[ 0]="{srv} server“

fname[ 1]="{pwd} S5"

fname[ 2]="{pwd} S8"

fname[ 3]="{pwd}{p12} Tab"

fname[ 4]="D630"

 

BOLD="\033[1m"

RED="\033[31m"

GREEN="\033[32m"

YELLOW="\033[33m"

LIGHTBLUE="\033[36m"

COLRES="\033[0m"

INVERSE="\033[7m"

 

jobs=()

keysize=2048

 

#---------------------------------------------------------------------------------------------------

 

DoPrepareJobs()

{

    clear

    for i in "${jobs[@]}"; do

        echo -e "\n${GREEN}${BOLD}Want to start $i?${COLRES}\n"

        read -p "Continue? Yes,Skip,Quit?   (y/s/q): " CONFIRM

 

        case $CONFIRM in

            q)

                echo "Stopped!"

                exit 1

                ;;

            s)

                echo $i "skipped!"

                ;;

            *)

                $i

                echo -e "\n $i ${GREEN}done!${COLRES}\n\n"

                ;;

        esac

    done

 

    return

}

#===================================================================================================

 

BuildFilesPerHost()

{

    Hint 3

 

    KeyCN_bak=$KEY_CN

    clear

 

    for host in "${fname[@]}"; do

        withpwd=false

        server=false

        p12=false

 

        if [[ "$host" =~ "{pwd}" ]]; then

            host="${host//'{pwd}'/''}"

            withpwd=true

        fi

        if [[ "$host" =~ "{srv}" ]]; then

            host="${host//'{srv}'/''}"

            server=true

        fi

        if [[ "$host" =~ "{p12}" ]]; then

            host="${host//'{p12}'/''}"

            p12=true

        fi

 

        host="${host#"${host%%[![:space:]]*}"}"

        host="${host%"${host##*[![:space:]]}"}"

        export KEY_CN="${KeyCN_bak}_${host}"

 

        clear

        echo -e "\n\n${GREEN}${BOLD}Want to start build-key for Host '$host' (pwd=$withpwd) (pkcs12=$p12)?\n${COLRES}\n"

        read -p "Continue?   Yes,Skip,Quit? (y/s/q):  " CONFIRM

 

        case $CONFIRM in

            q)

                echo "Stopped!"

                exit 1

                ;;

            s)

                echo "Skipped!"

                ;;

            *)

                if [ $server == true ]; then

                    ./easyrsa gen-req $host nopass

                    ./easyrsa sign-req server $host

                else

                    if [ $withpwd == true ]; then

                        Hint 2

                        clear

                        ./easyrsa gen-req $host

                    else

                        ./easyrsa gen-req $host nopass

                    fi

                    ./easyrsa sign-req client $host

                    if [ $p12 == true ]; then

                        Hint 4

                        openssl pkcs12 -export -in ./pki/issued/$host.crt -inkey ./pki/private/$host.key -certfile ./pki/ca.crt -name $host -out ./pki/private/$host.p12

                    fi

                fi

 

                if [ -s "./pki/private/$host.key" ] && [ -s "./pki/issued/$host.crt" ]; then

                    echo -e "\n\nbuild key for Host $host ${GREEN}done!${COLRES}\n"

                else

                    echo -e "\n\nbuild key for Host $host ${RED}failed!${COLRES}\n"

                fi

 

                read -p "Press Enter to Continue: " CONFIRM

                [ "$CONFIRM" = "q" ] && exit 1

                ;;

        esac

    done

}

#===================================================================================================

 

Hint()

{

    local ahelp=()

 

    clear

    if [ $1 -eq 1 ]; then

        ahelp=(

                "${INVERSE} Hinweis! ${COLRES}"

                " "

                "Die folgende sich mehrfach wiederholende Abrage mit der Eingabeaufforderung:"

                "       ${LIGHTBLUE}Continue? Yes,Skip,Quit?   (y/s/q):${COLRES}"

                "kann jeweils einfach mit der Enter-Taste zur Fortführung beantwortet werden."

                " "

                "Taste 'q' und Enter beendet das Programm"

                "Taste 's' und Enter überspringt den betreffenden Programmpunkt!"

                " "

                "Die meisten weiteren Abfragen können ebenfalls jeweils mit der Enter-Taste"

                "bestätigt werden. Sofern eine Eingabe ausdrücklich notwendig ist, erfolgt"

                "vorher ein Hinweis."

                )

 

    elif [ $1 -eq 2 ]; then

        ahelp=(

                "${INVERSE} Hinweis! ${COLRES}"

                " "

                "Die Angabe {pwd} im Client-Array  verlangt später beim"

                "Herstellen einer Verbindung durch diesen Client ein Password"

                "zur Authorisierung der Verwendung des Zertifikats. Bitte jetzt"

                "bei der Eingabeaufforderung auf dem nächsten Bildschirm:"

                " "

                "       ${LIGHTBLUE}Enter PEM pass phrase:${COLRES}"

                " "

                "das gewünschte Password eingeben! Achtung: Es müssen mindestens"

                "4 Zeichen eingegeben werden!"

                )

 

    elif [ $1 -eq 3 ]; then

        ahelp=(

                "${INVERSE} Hinweis! ${COLRES}"

                " "

                "Die folgende Abfrage für 'Sign' und 'Commit' als Abschlussfrage bei der"

                "Erstellung der Zertifikate muss bei jedem einzelnen Host explizit mit ${GREEN}${BOLD}'yes'${COLRES} "

                "als Eingabe beantwortet werden, da sonst kein Zertifikat erstellt wird:"

                "${LIGHTBLUE}Type the word 'yes' to continue, or any other input to abort.${COLRES}"

                "${LIGHTBLUE}Confirm request details:"${COLRES}

                )

 

    elif [ $1 -eq 4 ]; then

        ahelp=(

                "${INVERSE} Hinweis! ${COLRES}"

                " "

                "Für die Zertifikat-Erstellung  wurde der Parameter ${GREEN}${BOLD}{p12}${COLRES} eingetragen, deshalb wird für eine "

                "Verwendung mit besserer Sicherheit (z.B. auf Android-Geräten) eine zusätzliche pkcs12-Datei als"

                "Paket-Archiv erzeugt, die anstelle von clt.key, clt.crt und ca.crt in die Benutzer-Zertifikat-DB"

                "des Android-Geräts übernommen werden kann."

                " "

                "Bitte auf die beiden unterhalb folgenden Abfragen zuerst das vergebene Zertifikat-Password"

                "eingeben, wodurch die Verwendung des Zertifikats für den nächsten Schritt erlaubt wird. Und"

                "bei der nächsten Abfrage bitte ein weiteres neues Password eigeben, mit dem das Zertifikat"

                "später aus der  pkcs12-Datei in die Keychain des Android-Gerätes exportiert werden darf, um"

                "sie dann von dort in das OpenVPN-Profil zu importieren."

                "Wenn man das unbedingt möchte, kann man das gleiche Password sowohl für das Zertfikat als"

                "auch für den Export in die Keychain verwenden."

                " "

                )

    fi

 

    echo -e "\n"

    for i in "${ahelp[@]}"; do  echo -e "$i"; done

    echo -e "\n"

 

    [ $1 -eq 4 ] && return

    read -p "Press Enter to Continue!  " CONFIRM

    echo -e "\n\n"

 

   [ "$CONFIRM" = "q" ] && exit 1

 

    return

}

#===================================================================================================

# Main

 

[ -z "$(which openssl)" ] && echo "Fehler: Kein openssl gefunden!" && exit 1

[ -z "$(which openvpn)" ] && echo "Fehler: Kein openvpn gefunden!" && exit 1

[ -f "vars.example" ] && mv vars.example vars.example.sik

 

while read line; do

    [ -n "$line" ] && line=${line%#*}

    if [ -n "$line" ];then

        name=$(awk -F ' ' '{ print $2 }' <<< $line)

        parm=$(awk -F ' ' '{ print $3 }' <<< $line)

 

        case $name in

            EASYRSA_KEY_SIZE) [ -n "$parm" ] && keysize=$parm;;

        esac

    fi

done < <(cat "$(dirname $0)/vars"; echo "")

 

Hint 1

 

# Pre-Jobs

jobs=()

jobs[0]="./easyrsa init-pki"

jobs[1]="./easyrsa build-ca nopass"

DoPrepareJobs

 

BuildFilesPerHost

 

# Post-Jobs

jobs=()

jobs[0]="./easyrsa gen-crl"

jobs[1]="openssl dhparam -out dh$keysize.pem $keysize"

jobs[2]="openvpn --genkey secret ta.key"

DoPrepareJobs

 

[ -s ./pki/ca.crt ]     && mv ./pki/ca.crt      ./pki/issued

[ -s ta.key ]           && mv ta.key            ./pki/private

[ -s dh${keysize}.pem ] && mv dh${keysize}.pem  ./pki/private

 

#===================================================================================================

#EOF

Nachdem nun alle benötigten Dateien kopiert sind, wird das Script gestartet:

# cd /tmp/EasyRSA-3.1.0

# ./create-ca3

Die erste Abfrage ist ziemlich wichtig. Die Antwort entscheidet nämlich darüber, ob eine neue pki-Verzeichnisstruktur erstellt oder eine bestehende genutzt wird. Wenn die Antwort mit Enter als "Yes" gegeben wird, wird bei einer Erstinstallation eine neue pki-Struktur angelegt, eine bestehende Struktur würde aber gelöscht werden und mit der neuen leeren überschrieben. Damit können dann für die alte CA keine neuen Clients mehr angelegt werden und auch keine Sperrung für aktive Clients eingerichtet werden. An dieser Stelle muss man also aufpassen. Wenn es sich um eine Erst-Einrichtung handelt, gibt es das pki-Verzeichnis noch nicht, also kann man auch nichts versehentlich falsch machen.

Want to start ./easyrsa init-pki?

Continue? Yes,No,Skip?   (y/n/s):

Hier ist es noch interessant zu wissen, dass easy-rsa eigentlich auf jedem PC-System und auf jedem Betriebssystem funktioniert, egal ob das nun Debian (oder eines der Derivate) ist, oder Raspian, oder Windows. Auf Windows-PCs funktioniert natürlich nicht mein Bash-Script, dafür hatte ich früher und vor etlichen Jahren ein ähnliches Batch-File für den gleichen Zweck, aber Windows interessiert mich heute nicht mehr.

Sofern man sich nach dem Start einmal im Script "verhampelt" hat oder ein Fehler ist bei einem bestimmten Client durch Unachtsamkeit passiert ... kein Problem.... einfach ignorieren und weitermachen, als wäre nichts passiert. Es ist kein Problem, das Script ein zweites Mal zu starten und fehlerhafte Clients erneut zu generieren. Das Script wird dazu einfach noch mal gestartet und alle Abfragen, die sich nicht auf den neuen Client beziehen, werden mit Taste "s" (für skip) und Enter übersprungen. Auf gleiche Weise werden auch neue Clients hinzugefügt. Einfach an das Array anhängen und das Script starten, dann durchskippen bis zum neuen Client und fertig, die neu hinzugekommenen Files sind generiert.

Certificate Revocation List  (CRL)

Eine Zertifikatsperrliste ist eine Liste, mit der die Ungültigkeit von Zertifikaten festgelegt werden kann, oder anderes ausgedrückt, mit der die Gültigkeit eines Zertifikats widerrufen werden kann. Es ist durchaus möglich, dass wir zu einem späteren Zeitpunkt für ein bestimmtes Client-Gerät den VPN-Zugang sperren möchte (zum Beispiel weil das Gerät gestohlen wurde). Das erfolgt über einen Widerruf der Certificate Authority mithilfe der Revoke-Liste. Das betroffene Client-Gerät, hier im Beispiel mein "GalaxyS3", wird dazu in die Revoke-Liste eingetragen. Danach muss die geänderte Liste auf den OpenVPN-Server übertragen und aktiviert werden. Die folgenden Befehle sind dazu auf der Key-Signing-Machine (mein "Entwickler-PC") mit Verwendung der o.g. PKI-Struktur durchführen.

Vor der Änderung:

# cd /tmp/EasyRSA-3.1.0

# openssl crl -inform PEM -text -in pki/crl.pem

Certificate Revocation List (CRL):

        Version 2 (0x1)

    Signature Algorithm: sha512WithRSAEncryption

        Issuer: /CN=Easy-RSA CA

        Last Update: Sep 17 13:05:33 2018 GMT

        Next Update: Dec 16 13:05:33 2018 GMT

        CRL extensions:

            X509v3 Authority Key Identifier:

                keyid:0B:GG:6C:77:34:66:KK::NN:6C:34:43:12:21:89:98:76:67:B5:AB

                DirName:/CN=Easy-RSA CA

                serial:23:GG:PP:ZZ:32:VV:45:54

No Revoked Certificates.

Zertifikat widerrufen und CRL neu generieren:

# ./easyrsa revoke S3

# ./easyrsa gen-crl

Nach der Änderung:

# openssl crl -inform PEM -text -in pki/crl.pem

Certificate Revocation List (CRL):

        Version 2 (0x1)

    Signature Algorithm: sha512WithRSAEncryption

        Issuer: /CN=Easy-RSA CA

        Last Update: Sep 17 13:11:42 2018 GMT

        Next Update: Dec 16 13:11:42 2018 GMT

        CRL extensions:

            X509v3 Authority Key Identifier:

                keyid:0B:GG:6C:77:34:66:KK::NN:6C:34:43:12:21:89:98:76:67:B5:AB

                DirName:/CN=Easy-RSA CA

                serial:23:GG:PP:ZZ:32:VV:45:54

Revoked Certificates:

    Serial Number: DA694678569SDGFHDKGHKGHKK523D8FE

        Revocation Date: Sep 17 13:10:49 2018 GMT

Die Befehle:

openssl crl -inform PEM -text -in pki/crl.pem

Zeigt den aktuellen Inhalt der CRL

./easyrsa revoke S3

übernimmt das S3 in die Zertifikat-Speerliste

./easyrsa gen-crl

generiert eine aktulle Sperrliste mit dem Gültigkeitszeitraum in EASYRSA_CRL_DAYS

Anschließend ist die neue Datei crl.pem natürlich auf den OpenVPN-Server zu transportieren und dort zu aktivieren.

# cp $(speicherort)/crl.pem /etc/openvpn/ssl/

In der server_udp.conf ist die folgende neue Zeile einzutragen, um den OpenVPN-Server darüber zu informieren, dass es eine Revoke-Liste gibt und das er die beachten soll. Wird auch der TCP-Daemon genutzt, muss die gleiche Änderung natürlich auch in dessen TCP-Conf durchgeführt werden. Danach muss der OpenVPN-Daemon neu gestartet werden.

crl-verify /etc/openvpn/ssl/crl.pem

Im oberhalb stehenden Listing habe ich zusätzlich die beiden Datumsfelder markiert, aus denen der Gültigkeitszeitraum dieser CRL abgelesen werden kann. Diese recht kurze 3-monatige Laufzeit ist entstanden, weil ich zuvor in der vars (s.o.) den Ablaufzeitraum der CRL mit EASYRSA_CRL_DAYS 90 auf eben nur diese 90 Tage gesetzt habe. Dabei muss man nun daran denken, dass nach Ablauf der 90 Tage Verbindungsversuche möglicherweise mit dem Fehler "VERIFY ERROR, CRL has expired" abgewiesen werden, selbst wenn der Client ein im Moment noch gültiges Zertifikat verwendet. Denn es könnte ja sein, dass in einer aktuellen CRL genau dieser Client jetzt gesperrt ist. In dem Fall muss die CRL also mit aktueller Gültigkeit neu generiert werden. 'Best Practice' ist es meiner Meinung nach, die CRL solange nicht in der aktuellen Laufzeit-Version zu verwenden, wie man keine Zertifikate widerrufen muss. Und wenn ich einen komplett neuen Satz von Certs und Keys erzeuge, was bei mir einmal jährlich passiert, würde ich den vielleicht vorhandenen älteren Eintrag zunächst auch wieder deaktivieren.

HMAC-Firewall

Nachdem nun das Ziel Certificate Authority über die von uns erstellten Zertifikate und Key-Files erreicht ist, fehlt uns an dieser Stelle nur noch ein etwas besseres Verständnis für die HMAC-Firewall. Was ist das denn schon wieder? Ums vorweg zu nehmen, das ist was ziemlich wichtiges. HMAC steht für "Hash Message Authentication Code" und findet bei der Verschlüsselung und Authentifizierung über den TLS-Control-Chanel einer Verbindung seine Anwendung. Die HMAC-Firewall verschlüsselt und signiert die auf dem TLS-Control-Chanel übertragenen Pakete, alle Pakete mit fehlender oder falscher Signatur werden verworfen. Der Hintergrund für die Wichtigkeit dieser Firewall ist einfach erklärt:

Eine Verschlüsselung (also das was OpenVPN tut) bedeutet, die Daten beim Transport vor Ausspähen zu schützen. Das beinhaltet aber nicht, dass damit eine gezielte Manipulation dieser Daten ausgeschlossen ist, also das jemand die Daten auf der Transportstrecke verändert. Mit einer Traffic-Analyse und bei Beachtung von Größe und Timing von Daten-Paketen bestehen für einen Angreifer durchaus gute Chancen, bestimmte Pakete gezielt zu manipulieren, um darüber eine über diesen Link laufende korruptionsgefährdete Anwendung gezielt zu attackieren. Vielleicht weiß der Angreifer nicht einmal, was er verändert hat, aber wir können es jedenfalls nicht feststellten, denn Kryptografie beinhaltet für uns keine Möglichkeit zu erkennen, dass unsere verschlüsselte Daten unerlaubt verändert wurden. Und genau das verhindert die HMAC-Firewall. Sie erlaubt es OpenVPN zu erkennen, dass ein Paket manipuliert wurde, um es dann verwerfen zu können... was ein erneutes Senden des fallengelassenen Paketes nach sich zieht - in der Hoffnung, dass es nun ein intaktes Paket ist. Die HMAC-Firewall ist nach meinem Verständnis eine zusätzliche Schicht über dem bekannten TLS (Transport Layer Security) und garantiert, dass man auf der anderen Seite der Leitung auch wirklich mit dem spricht, von dem man glaubt, dass er das ist. Ums kurz und mal ganz lapidar auszudrücken: Das Teil ist wichtig! :-)

Ich gehe jetzt davon aus, dass auf dem System, auf dem wir bis jetzt alle Vorarbeiten erledigt haben und gerade die Zertifikate mit easy-rsa erzeugt haben, natürlich auch OpenVPN installiert ist und das das folgende Keyfile ta.key bereits erfolgreich erzeugt wurde. Wenn das nicht der Fall ist, weil OpenVPN fehlte, so kann die Datei auch nachträglich manuell erzeugt werden. Dazu müssen aber jetzt OpenVPN und die liblzo2-2 installiert sein. Der folgende Befehl erstellt dann manuell durchgeführt das Keyfile für die HMAC-FW. Aber wie gesagt, wenn das Script fehlerfrei durchgelaufen ist, sollte das Key-File bereits erstellt sein.

# cd /tmp/EasyRSA-3.1.0/pki/ssl

# ls -lah                                          # Achtung: Erstellen abbrechen, wenn die Datei schon enthalten ist

# openvpn --genkey --secret ta.key

Der Hintergrund, warum ich alle Arbeiten in /tmp erledige ist relativ einfach erklärt... ich verlasse mich darauf, dass alle in /tmp vorhandenen Dateien nach dem Ausschalten meines PCs auch wieder unwiederbringlich beseitigt sind. /tmp ist bei mir kein Festplattenspeicher, sondern durch tmpfs quasi als RAM-Disk zu sehen. Das bedeutet, ich muss vor dem Ausschalten des Rechners nur daran denken, nachdem alle Zertifikate und Keys erzeugt sind, unbedingt das Verzeichnis /tmp/easy-rsa/pki zu sichern. Das erledige ich mit der Übernahme der Dateien in ein eigenes Tar-Archiv:

# cd /tmp/EasyRSA-3.1.0

# tar -cvf openvpn-ca-pki.tar pki/

# mv openvpn-ca-pki.tar /home

Das neu erzeugte Tar-Archiv enthält nun alle erstellten Schlüssel für Server und Clients, aber mit der ca.key auch die grundsätzliche Autorisierung, neue Schlüssel für vielleicht neu hinzugekommene Clients zu generieren. Darüber hinaus ist die leere Revoke-Datei enthalten und die dafür notwendige Grundlage, um bei Bedarf zu sperrende Clients in eine neue Revoke-Liste zu übernehmen. Dieses Tar-Archiv sollte keinesfalls auf die Rechner verteilt werden, sondern wirklich sicher vor missbräuchlichem Zugriff aufbewahrt werden. Man kann sie einfach auf eine SD-Card speichern und wegschließen oder mit einem Kryptografie-Tool verschlüsselt auf einem Rechner speichern. Für die zweite Variante muss man natürlich gewährleisten, dass man sich auch noch nach 1 Jahr an das Password erinnert. Man kann sie aber auch einfach sofort unwiederbringlich löschen. Wichtig ist nur eines, Missbrauch zu verhindern. Wenn sie gelöscht ist, ist das im Fall der Fälle auch kein wirkliches Drama, dann muss man eben einmal für alle Systeme neue Keyfiles generieren und die neuen gegen die alten austauschen. Damit sind die alten wertlos und können nicht mehr verwendet werden.

Service-Units

Zwei für den Systemstart des OpenVPN-Servers notwendige Dateien. Die Service-Units sorgen im späteren Normalbetrieb des Servers dafür, dass der oder die OpenVPN-Daemons direkt beim Systemstart auch gestartet werden. Die drei hier verwendeten Service-Units sind bereits im Ordner

# ls /tmp/OpenVPN/etc/systemd/system

insgesamt 12K

-rw-r--r-- 1 thomas thomas 391 2018-10-14 11:20 openvpn.service

-rw-r--r-- 1 thomas thomas 535 2019-08-05 12:11 openvpn@.service

-rw-r--r-- 1 thomas thomas 496 2019-08-20 15:45 set-nftables-vpn.service

enthalten. Bitte beachten, dass der TCP-Daemon zunächst mit einem Comment-Tag # deaktiviert ist. Es ist besser, sich erst mal nur mit dem UDP-Protokoll zu befassen und erst dann, wenn es fehlerfrei läuft, nimmt man auf gleiche Art und Weise wie zuvor den TCP-Daemon in Betrieb. Mit großer Wahrscheinlichkeit reicht es dann aus, einfach die Comment-Tags zu entfernen, die Service-Unit 'openvpn.service' einmal zu stoppen und erneut zu starten. In den Log-Files kann dann nachgesehen werden, ob der Start ohne Fehler durchgelaufen ist.

openvpn.service

[Unit]

Description=thlu:openvpn.service   Start OpenVPN-Daemons for TCP and UDP

 

[Service]

Type=oneshot

RemainAfterExit=yes

ExecStart=/bin/systemctl start openvpn@server_udp.service

#ExecStart=/bin/systemctl start openvpn@server_tcp.service

ExecStop=/bin/systemctl stop openvpn@server_udp.service

#ExecStop=/bin/systemctl stop openvpn@server_tcp.service

 

[Install]

WantedBy=basic.target

openvpn@.service

[Unit]

Description=thlu:openvpn@%I.service   Start OpenVPN-Daemon

 

[Service]

Type=forking

PIDFile=/var/run/openvpn/%I.pid

ExecStartPre=/bin/mkdir -p /var/run/openvpn

ExecStartPre=/bin/mkdir -p /var/log/openvpn

ExecStartPre=/bin/chmod 770 /var/log/openvpn

ExecStartPre=/bin/chown root:vpnuser /var/log/openvpn

ExecStartPre=/bin/sleep 2

ExecStart=/usr/sbin/openvpn --daemon --writepid /var/run/openvpn/%I.pid --status /var/run/openvpn/%I.status 60 --config /etc/openvpn/%I.conf

KillMode=process

 

[Install]

WantedBy=multi-user.target

Eine Service-Unit mit Paketfilter-Regeln. Ohne diese Regeln könnte zwar ein Tunnel zwischen Client und Server erfolgreich aufgebaut werden, aber das war's dann auch schon. Sicheres Surfen im Internet über den heimischen Router sowie der Zugriff auf Ressourcen des Heimnetzwerks wäre allein mit dem Tunnel nicht möglich. Dafür werden zusätzlich diese Regeln benötigt.

Hinweise:

1. Wenn das Interface gemäß der mit systemd eingeführten 'Predictable Network Interface Names' einen anderen Namen hat, muss eth0 natürlich durch den richtigen Interface-Namen ersetzt werden.

2. In einem reinen IPv4-Netzwerk müssen die 3 IPv6-Einträge in der folgenden Service-Unit mit # einkommentiert werden.

3. Bei einer bereits installierten Desktop-Firewall darf diese Unit zur Vermeidung von Konflikten nicht gestartet werden. Der richtige Weg ist dann, die notwendigen Regeln in der Firewall zu setzen und auf die Unit zu verzichten. Mit den folgenden 3 Befehlen kann kontrolliert werden, ob eine vorhandene Firewall schon Paketfilter-Regeln gesetzt hat:

4. Achtung: Die unterhalb in der Service-Unit stehenden Regeln ermöglichen auf dem Server ausschließlich den Paket-Transport aus dem VPN-Netz in das LAN bzw. zum Standard-Gateway und haben keinerlei schützende oder überwachende Funktionen.... ergänzende Informationen für notwendige Sicherheitseinstellungen von Client und Server mithilfe des Paketfilters siehe Artikel security und Kapitel Netfilter OpenVPN/Mobil-Geräte

# nft list ruleset

 

# iptables -L -nv

Chain INPUT (policy ACCEPT 0 packets, 0 bytes)

pkts bytes target     prot opt in     out     source     destination        

 

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)

pkts bytes target     prot opt in     out     source     destination        

 

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)

pkts bytes target     prot opt in     out     source     destination        

 

# ip6tables -L -nv

Chain INPUT (policy ACCEPT 0 packets, 0 bytes)

pkts bytes target     prot opt in     out     source     destination        

 

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)

pkts bytes target     prot opt in     out     source     destination        

 

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)

pkts bytes target     prot opt in     out     source     destination    

Hier in diesem Beispiel oberhalb ist keine Desktop-Firewall installiert, also kann die folgende Unit auch problemlos -ohne Konflikte auslösen zu können- verwendet werden. Die inet-family zur vereinfachten Dual-Stack-Administration für  IPv4/IPv6 wird für stateful NAT erst ab Kernel 5.2 unterstützt.

set-nftables-vpn.service

[Unit]

Description=thlu:set-nftables-vpn.service:  Setting some netfilter-rules for openvpn-server

 

[Service]

Type=oneshot

RemainAfterExit=no

 

ExecStart=/usr/sbin/nft flush ruleset

ExecStart=/usr/sbin/nft add table ip  filter

ExecStart=/usr/sbin/nft add chain ip  filter postrouting "{ type nat hook postrouting  priority 100; policy accept; counter;}"

ExecStart=/usr/sbin/nft add rule  ip  filter postrouting oifname eth0 ip saddr 10.0.8.0/23 masquerade

 

ExecStart=/usr/sbin/nft add table ip6 filter

ExecStart=/usr/sbin/nft add chain ip6 filter postrouting "{ type nat hook postrouting  priority 100; policy accept; counter;}"

ExecStart=/usr/sbin/nft add rule  ip6 filter postrouting oifname eth0 ip6 saddr fd00:10:0:8::/63 masquerade

 

[Install]

WantedBy=multi-user.target

 

ipv4_vpn="10.0.8.0/23"

ipv6_vpn="fd00:10:0:8::/63"

Deklaration der durch OpenVPN verwendeten Subnetze

 

10.0.1.0/24

10.      0.       1.       0.

00001010 00000000 00000001 00000000

Lokales Netzwerk

10.0.8.0/24

10.0.9.0/24

00001010 00000000 00001000 00000000

00001010 00000000 00001001 00000000

VPN UDP

VPN TCP

10.0.8.0/23

^^^^^^^^ ^^^^^^^^ ^^^^^^^           

Deckt beide VPN-Netze ab.

Nachdem nun alle Zertifikate und Key-Files sowie die zusätzlich benötigten Daten erfolgreich erzeugt wurden, müsse nur noch die Dateien aus den Easy-RSA-Verzeichnissen in die schon bestehende Verzeichnis-Struktur nach /tmp/OpenVPN kopiert werden, um daraus dann unser "Transport- und Setup-Archiv" zu erstellen. Dazu verwende ich natürlich wieder den auch in den anderen Artikeln schon erwähnten Midnight-Commander. Mit dem Midnight Commander wird in der einen Hälfte das Verzeichnis /tmp/EasyRSA-3.1.0/pki geöffnet und in der Hälfte gegenüber das Verzeichnis /tmp/OpenVPN. Dann werden alle Dateien passend zur folgenden Tabelle kopiert.

Nicht vergessen: Die beiden Verzeichnisse (also weder /tmp*/pki noch /tmp/OpenVPN) mit den darin enthaltenen CA-Dateien für Server und mehrere Clients sind überhaupt nicht geeignet, um sie an andere Personen weiterzugeben, damit die selber Ihren Client-PC einrichten. Ich gehe davon aus, dass der CA-Ersteller (hier bin ich das) diese Dateien niemals komplett aus der Hand gibt, sondern selber die heimischen Clients einrichtet und hinterher alle Spuren beseitigt.

Verzeichnis:

bereits enthaltene / zu kopierende Dateien:

/tmp/OpenVPN/etc/openvpn

client_tcp.conf

client_udp.conf

server_tcp.conf

server_udp.conf

 

Server-Setup:

/tmp/OpenVPN/etc/systemd/systemd

openvpn.service

openvpn@.service

set-nftables-vpn.service

Client-Setup:

/tmp/OpenVPN/usr/local/bin

vpn.1

vpn.2

/tmp/OpenVPN/ca_server

server.crt

crl.pem

dh4096.pem

ca.crt

ta.key

server.key

-

/tmp/OpenVPN/ca_client

S5.crt

S8.crt

Tab.crt

d630.crt

ca.crt

ta.key

S5.key

S8.key

Tab.key

d630.key

 

 

Tab.p12

 

Alle anderen in der pki-Struktur verbliebenen Dateien, wie *.pem, *.csr, index* und serial* sind für den Betrieb des OpenVPN-Netzwerks nicht notwendig. Man kann sie aufbewahren oder auch einfach löschen... die Entscheidung muss man für sich selber treffen. Es gibt wirklich nur einen einzigen Grund, warum man später noch einmal darauf zugreifen können wollte. Und zwar braucht man das, wenn man einen neuen VPN-Client dem VPN-Netz zufügen will, also wenn nachträglich noch mal ein individuelles neues Zertifikat und ein Schlüssel erzeugt werden sollen. Dann muss aus dem Archiv die alte pki-Struktur zurückkopiert werden. Man trägt den neuen Client ins Script ein, skip't sich durch und verwendet anschließend Cert und Key wie gehabt. Na ja... ich habe das noch nie gebraucht, ich lösche eigentlich immer alles sofort, was nicht direkt verwendet ober benötigt wird. Und ganz nebenbei bemerkt schätze ich es auch als Sicherheits-Feature ein, wenn die Gültigkeit solcher Dateien sowieso nicht diese 10 Jahre besteht, wie aktuell in der vars eingetragen ist. Meine Dateien haben immer nur 1 Jahr Gültigkeit, danach wird sowieso alles neu erstellt.

Abschließend packen wir alle im nun vorsortierten Sammel-Verzeichnis vorhandenen Dateien in ein Tar-File, welches wir dann später irgendwo an vor Fremdzugriff sicherer Stelle aufbewahren sollten. Aber zunächst mal brauchen wir das natürlich noch bei der Installation auf unseren Geräten.

# cd /tmp

# tar -cvf openvpn-setup.tar OpenVPN/

# mv openvpn-setup.tar /home

# ls /home

insgesamt 132K

-rw-r--r--  1 root   root   80K 2019-09-04 16:06 openvpn-ca-pki.tar

-rw-r--r--  1 root   root   50K 2019-09-04 16:31 openvpn-setup.tar

-rw-r--r--  1 root   root  1,3M 2019-09-04 16:34 openvpn-2.5.7_bullseye_amd64.deb

Wenn alles richtig gemacht wurde, finden wir jetzt im Verzeichnis /home diese Einträge:

openvpn-ca-pki.tar

Das Tar-Archiv der originalen Certificate Authority. Dieses Archiv sollte unzugänglich und vor unberechtigtem Zugriff gesichert aufbewahrt werden.

openvpn-setup.tar

Das Tar-Archiv .... enthält für alle Systeme immer alles, was notwendig ist... wir können beim Setup der einzelnen Systeme nichts vergessen.

openvpn-2.5.7_bullseye_amd64.deb

Das in Debian installierbare OpenVPN-Deb-Package für 64-Bit-Systeme (... oder auch mehrere, wenn weitere Packages für andere Rechnerarchitekturen erstellt wurden).

 

Nach der erfolgreichen Erstellung von allen benötigten Zertifikaten, Schlüsseln und Zertifikatsunterzeichnungsanforderungen müssen wir unbedingt verstehen, dass nur .key-Dateien als wirklich vertrauenswürdig behandelt werden können. Die noch zusätzlich im Verzeichnis bestehenden .csr-Dateien könnten auch über potentiell unsichere Kommunikationswege gesendet werden, wie z.B. Klartext-Emails. Aber das ist nicht unser Problem, wir brauchen das nicht, wir müssen überhaupt keine Dateien versenden, wir installieren einfach die CA-Files direkt auf unsere VPN-Systeme. Deshalb können wir auch diese .csr-Files ignorieren.

Wir dürfen nur eines NIEMALS tun, und zwar .key-Dateien über potentiell unsichere Wege zu transportieren, wie z.B. via EMails oder per Whatsapp oder als Facebook-Message, oder über eine Cloud (Google/Microsoft/etc.) oder ganz allgemein durchs Internet. Das ist ein absolutes NoGo!

 

 

 

Setup OpenVPN-Server

Jetzt, wo alles wirklich gut vorbereitet ist, ist die abschließende Inbetriebnahme auf den Zielgeräten eine einfache Angelegenheit. Wir kopieren dazu von unserem Entwickler-PC das neu erstellte Tar-Archiv, welches alle notwendigen Dateien enthält, auf unserem künftig als OpenVPN-Server arbeitenden LAN-Server und kopieren aus dem Archiv die relevanten Dateien komfortabel mit dem Midnight Commander und in wenigen Schritten an ihren jeweiligen Zielort. Weil mein Server gleichzeitig auch noch NAS ist, ist das natürlich ganz einfach: Ich kopiere die Files von meinem Debian-PC rauf auf die NAS-Platte und dann von dort dann via SSH-Zugriff lokal auf dem Server angemeldet in dessen Zielverzeichnisse.

Aber falls es keine gemeinsamen Laufwerke gibt, kann man sowohl das Deb-Package als auch das Tar-Archiv mit allen enthaltenen Dateien ganz elegant via SSH kopieren. Bitte beachten, dass ich das hier als user toml tue und nicht als root. Auf meinem Server ist der Login via SSH direkt als root nicht erlaubt. "toml" ist hier der SSH-Anmeldename, der als User sowohl auf meinem PC als auch auf dem Pi (dem Server) existiert.

$ scp "/home/openvpn-setup.tar" "toml@10.0.1.2:/tmp"

$ scp "/home/openvpn-2.5.7_bullseye_amd64.deb" "toml@10.0.1.2:/tmp"

 

Bevor es nun an die Einrichtung geht, möchte ich noch einen wirklich wichtigen Hinweis geben: Bitte achte IMMER auf Fehlermeldungen, und zwar ausnahmslos bei jedem Befehl, den du an der Tastatur abschickst. Wenn eine Fehlermeldung kommt, bedeutet das nicht, dass Du diesen Schritt erst mal auf Eis legst und mit dem nächsten fortfährst. Das ist FALSCH! Bei einer Fehlermeldung gibt es nur eine einzige Entscheidung ... und die lautet Abbrechen. Der Fehler muss zuerst beseitigt werden. Und erst danach geht es weiter im Programm. Bitte achte unbedingt darauf, das so einzuhalten.

 

Der nächste Schritt ist jetzt natürlich der Wechsel zum Server, um dort zuerst die Installation des Programms OpenVPN und danach dann die Inbetriebnahme durchzuführen. Die folgenden Arbeiten werden alle als root durchgeführt. Als erstes wird ein virtueller (völlig unberechtigter) User ohne Password (verhindert eine Anmeldung dieses Users) angelegt, unter dessen UID später die beiden VPN-Daemons laufen, danach wird OpenVPN installiert. Als letztes wird noch geprüft, ob die für OpenVPN notwendigen Abhängigkeiten erfüllt sind…. fehlende Pakete sind zu installieren.

$ ssh 10.0.1.2

$ su -

# adduser vpnuser --no-create-home --gecos "" --disabled-password

# dpkg -l libc6 liblz4-1 liblzo2-2 libpam0g libssl1.1 libsystemd0 iproute2 lsb-base openssl

# apt install $(fehlende)

# cd /tmp

# dpkg -i openvpn-2.5.7_bullseye_amd64.deb

# tar -xf openvpn-setup.tar

In der Datei /etc/sysctl.d/sysctl.conf, mit der Kernel-Parameter gesetzt oder verändert werden können, sind die beiden folgenden Einträge vorzunehmen. Bei einem Dual-Stack-Account beide Einträge, bei einem IPV4-DSL-Vertrag nur der IPv4-Parameter. Das Forwarding zu aktivieren ist notwendig, weil sonst aus dem VPN-Netz kommende Datenpakete u.U. nicht an das Default-Gateway unseres DSL-Routers weitergeleitet werden, womit dann für die Clients die Verbindung ins Internet scheitern würde.

net.ipv4.ip_forward=1

net.ipv6.conf.all.forwarding=1

net.ipv6.conf.all.accept_ra = 2

Die Änderung der Kernel-Parameter muss aktiviert werden, damit die neuen Einstellungen wirksam sind. Das ist über einen Reboot möglich oder auch mit dem Kernel-Werkzeug sysctl. Der anschließende Befehl zeigt, ob die neuen Werte übernommen wurden. Falls die Schnittstelle nicht eth0 heisst, muss der zweite Befehl natürlich angepasst werden.

# sysctl --system

# sysctl -a | grep "forwarding =\|accept_ra =" | grep eth0 | grep -v mc

Weiter gehts mit den Konfigurationsdateien, Zertifikaten und Key-Files, die in das jeweilige Verzeichnis zu kopieren sind. Bevor wir die jeweils benötigten neuen Dateien erstellen oder kopieren, richten wir natürlich zuerst die notwendigen Verzeichnisse auf dem jeweiligen Zielhost ein:

# mkdir -p /etc/openvpn/keys

Nun werden die aus dem zuvor nach /tmp übertragenen und dort entpackten Tar-Archiv alle Dateien einzeln an ihren jeweiligen Bestimmungsort kopiert. Und bitte nach dem Kopieren immer gewissenhaft die gesetzten Rechte kontrollieren und sie ggf. auch zu korrigieren. Auch dabei unterstützt uns der Midnight Commander, in dem man nach dem Markieren betroffener Dateien (oder Verzeichnisse) mit der Taste F9 im Menü "Datei" je nach Bedarf den Menüpunkt "chmod" oder "chown" auswählt.

Verzeichnis

Rechte

Datei

Rechte

etc/systemd/system

root:root 755

openvpn.service

openvpn@.service

set-nftables-vpn.service

root:root 644

/etc/openvpn

root:root 700

server_udp.conf

server_tcp.conf

root:root 600

/etc/openvpn/keys

root:root 700

ca.crt

ta.key

dh4096.pem

server.crt

server.key

root:root 600

 

# cd /etc/openvpn/keys

# chown -R root:root /etc/openvpn

# chmod -R 600 /etc/openvpn

# chmod 700 /etc/openvpn

# chmod 700 /etc/openvpn/keys

Löschen der jetzt nicht mehr benötigten Dateien:

# cd /tmp

# rm openvpn-setup.tar

# rm -r OpenVPN

Und ja, ich bin rigoros der Meinung, auch wenn man glaubt, es müsse so sein, dass sich der normale Anwender mal eben eine OpenVPN-Verbindung herstellen darf, das der reguläre Anwender in seiner Login-Session keine Zugriffs-Rechte auf diese Dateien haben sollte. Hat er keine Rechte darauf, können die auch nicht von Angreifern missbräuchlich verwendet werden, um sich Zugang zu diesen wichtigen Dateien zu verschaffen. Die Dateien gehört root, werden von root verwendet und niemand anderes hat darin was zu lesen oder sie gar noch herauszukopieren. Ein Lesezugriff für andere ist für den Betrieb des VPNs nicht notwendig. Bei Bedarf starte ich in einer root-Login-Session auf meinem Laptop das VPN, arbeite mit der Verbindung als normaler User und am Ende schließe ich das VPN wieder in der root-Login-Session. Und garantiert würde ich so etwas nie mit diesem überflüssigen und wirklich gravierenden Sicherheitsrisiko "sudo" tun. .. deswegen beachte ich das auch hier nicht.

Nun wird ein manueller Start vorbereitet, um zu bestätigen, dass der Start des Programms selber keine Fehlermeldungen erzeugt. Dazu benötigen wir 3 gleichzeitig geöffnete Terminalfenster zum Pi, in denen wir uns jeweils via SSH auf dem PI anmelden und dann zu root wechseln. Die Fenster sollte man am besten so anordnen, dass immer alle 3 gleichzeitig zu sehen sind, was ja auf einem normalen PC-Monitor nicht schwer sein sollte. Im ersten lassen wir uns das OpenVPN-upd-log anzeigen:

# mkdir -p /var/log/openvpn

# touch /var/log/openvpn/openvpn_udp.log

# tail -f /var/log/openvpn/openvpn_udp.log

Im zweiten Fenster erfolgt gleich der manuelle Start von OpenVPN als im Vordergrund laufendes Programm. Nur leider, jetzt ganz kurz vor der ersten Inbetriebnahme, habe ich das Problem, dass ich mich nicht mehr erinnern kann, ob das Programm beim Start selber generisch die zwei benötigten Tun-Devices erzeugt oder ob das vom Admin einmalig manuell vorbereitet werden muss. Man kann es einfach mal ohne die zwei folgenden Statements versuchen, und wenn es zu Fehlern führt, werden eben einmalig die beiden Devices eingerichtet. Der dritte Befehl listet zur Kontrolle alle Netzwerk-Devices auf und zeigt deren Status an. Wenn beabsichtigt ist, nur das UDP-Protokoll zu nutzen, ist auch nur tun0 einzurichten. Mit TCP braucht es natürlich beide.

# openvpn --mktun --dev tun0

# openvpn --mktun --dev tun1

# ip a

 

# openvpn --config /etc/openvpn/server_udp.conf

Im Log-Fenster sollte dann als Reaktion auf den Programmstart die folgende (oder eine sehr ähnliche) Ausgabe angezeigt werden - hier bei mir ohne Fehlermeldungen:

Fri Sep 7 11:21:43 2018 OpenVPN -2.5.7 armv6l-unknown-linux-gnueabihf [SSL (OpenSSL)] .... build Aug 12 2018

Fri Sep 7 11:21:43 2018 library versions: OpenSSL 1.1.0f  25 May 2017, LZO 2.08

Fri Sep 7 11:21:43 2018 Diffie-Hellman initialized with 2048 bit key

Fri Sep 7 11:21:43 2018 Outgoing Control Channel Authentication: Using 256 bit message hash 'SHA256' for HMAC authentication

Fri Sep 7 11:21:43 2018 Incoming Control Channel Authentication: Using 256 bit message hash 'SHA256' for HMAC authentication

Fri Sep 7 11:21:43 2018 ROUTE_GATEWAY 10.0.1.1/255.255.255.0 IFACE=eth0 HWADDR=k7:ff:gg:za:31:3p

Fri Sep 7 11:21:43 2018 TUN/TAP device tun1 opened

Fri Sep 7 11:21:43 2018 TUN/TAP TX queue length set to 100

Fri Sep 7 11:21:43 2018 do_ifconfig, tt->did_ifconfig_ipv6_setup=1

Fri Sep 7 11:21:43 2018 /sbin/ifconfig tun1 10.0.8.1 pointopoint 10.0.8.2 mtu 1500

Fri Sep 7 11:21:43 2018 /sbin/ifconfig tun1 add fd00:10:0:8::1/64

Fri Sep 7 11:21:43 2018 /sbin/route add -net 10.0.8.0 netmask 255.255.255.0 gw 10.0.8.2

Fri Sep 7 11:21:43 2018 Could not determine IPv4/IPv6 protocol. Using AF_INET

Fri Sep 7 11:21:43 2018 Socket Buffers: R=[163840->163840] S=[163840->163840]

Fri Sep 7 11:21:43 2018 UDPv4 link local (bound): [AF_INET][undef]:55553

Fri Sep 7 11:21:43 2018 UDPv4 link remote: [AF_UNSPEC]

Fri Sep 7 11:21:43 2018 GID set to vpnuser

Fri Sep 7 11:21:43 2018 UID set to vpnuser

Fri Sep 7 11:21:43 2018 MULTI: multi_init called, r=256 v=256

Fri Sep 7 11:21:43 2018 IFCONFIG POOL IPv6: (IPv4) size=62, size_ipv6=65536, netbits=64, base_ipv6=fd00:10:0:8::1000

Fri Sep 7 11:21:43 2018 IFCONFIG POOL: base=10.0.8.4 size=62, ipv6=1

Fri Sep 7 11:21:43 2018 Initialization Sequence Completed

Im dritten Fenster kontrollieren wir, auf welchen Ports durch OpenVPN gelauscht wird. Achtung: Bei mir sind es schon beide Ports, weil ich hier einfach auf mein laufendes Setup zurückgegriffen habe. Es ist aber richtig, wenn bei der Test-Inbetriebnahme jetzt nur UPD angezeigt wird.

# ss -tulpen | grep openvpn

Netid  State      Recv-Q Send-Q   Local Address:Port  Peer Address:Port

udp    UNCONN     0      0        *:55553             *:*               users:(("openvpn"))

tcp    LISTEN     0      1        *:55554             *:*               users:(("openvpn"))

Viel mehr Möglichkeiten haben wir jetzt hier erst mal nicht. Wenn die Terminal-Ausgaben mit denen hier im Artikel übereinstimmen, also keine Fehler angezeigt werden, haben wir bis hierhin alles richtig gemacht. Wir klicken uns nun zurück in das Fenster, in dem wir das Programm im Vordergrund gestartet haben und beenden es mit der Tastenkombination Strg-c. In der Log-Ausgabe-Terminal sehen wir zeitgleich die Reaktion

SIGINT[hard,] received, process exiting

wonach es sicher ist, dass OpenVPN beendet wurde. Danach führen wir den nächsten Test durch und starten OpenVPN über die Service-Unit als regulären Daemon.

# systemctl daemon-reload

# systemctl start set-nftables-vpn.service

# systemctl start openvpn.service

Und auch hier sehen wir sofort wieder die Reaktion in der Log-Ausgabe. Nun schauen wir uns nur noch den Status der Dienste an. Und wenn auch diese Ausgabe übereinstimmt und keine Fehler berichtet, dann hat die Service-Unit "openvpn" die beiden Daemons für die Protokolle TCP und UDP über die jeweils eigene Service-Unit gestartet. Also können wir OpenVPN nun auch für den Systemstart aktivieren:

# systemctl status openvp*.service set-nftables-vpn.service

openvpn@server_udp.service - thlu:openvpn@server_udp.service   Starts a OpenVPN-Daemon

   Loaded: loaded (/etc/systemd/system/openvpn@.service; disabled; vendor preset: enabled)

   Active: active (running) since Sun 2018-09-09 16:11:06 UTC; 2min 35s ago

  Process: 1024 ExecStart=/usr/sbin/openvpn --daemon --writepid /var/run/openvpn/server_udp.pid  :::::::>> server_udp.conf

  Process: 1021 ExecStartPre=/bin/chown root:vpnuser /var/log/openvpn (code=exited, status=0/SUCCESS)

  Process: 1017 ExecStartPre=/bin/chmod 770 /var/log/openvpn (code=exited, status=0/SUCCESS)

  Process: 1013 ExecStartPre=/bin/mkdir -p /var/log/openvpn (code=exited, status=0/SUCCESS)

  Process: 1010 ExecStartPre=/bin/mkdir -p /var/run/openvpn (code=exited, status=0/SUCCESS)

  Main PID:1025 (openvpn)

   CGroup: /system.slice/system-openvpn.slice/openvpn@server_udp.service

           └─1025 /usr/sbin/openvpn --daemon --writepid /var/run/openvpn/server_udp.pid - :::::::>> server_udp.conf

Sep 09 16:11:05 raspi5 systemd[1]: Starting thlu:openvpn@server_udp.service   Starts a OpenVPN-Daemon...

Sep 09 16:11:06 raspi5 systemd[1]: openvpn@server_udp.service: PID file /var/run/openvpn/server_udp.pid not readable (yet?) after start: No such file or directory

Sep 09 16:11:06 raspi5 systemd[1]: Started thlu:openvpn@server_udp.service   Starts a OpenVPN-Daemon.

openvpn@server_tcp.service - thlu:openvpn@server_tcp.service   Starts a OpenVPN-Daemon

   Loaded: loaded (/etc/systemd/system/openvpn@.service; disabled; vendor preset: enabled)

   Active: active (running) since Sun 2018-09-09 16:11:07 UTC; 2min 34s ago

  Process: 1049 ExecStart=/usr/sbin/openvpn --daemon --writepid /var/run/openvpn/server_tcp.pid  :::::::>> server_udp.conf

  Process: 1046 ExecStartPre=/bin/chown root:vpnuser /var/log/openvpn (code=exited, status=0/SUCCESS)

  Process: 1043 ExecStartPre=/bin/chmod 770 /var/log/openvpn (code=exited, status=0/SUCCESS)

  Process: 1040 ExecStartPre=/bin/mkdir -p /var/log/openvpn (code=exited, status=0/SUCCESS)

  Process: 1033 ExecStartPre=/bin/mkdir -p /var/run/openvpn (code=exited, status=0/SUCCESS)

  Main PID:1050 (openvpn)

   CGroup: /system.slice/system-openvpn.slice/openvpn@server_tcp.service

           └─1050 /usr/sbin/openvpn --daemon --writepid /var/run/openvpn/server_tcp.pid   :::::::>> server_tcp.conf

Sep 09 16:11:06 raspi5 systemd[1]: Starting thlu:openvpn@server_tcp.service   Starts a OpenVPN-Daemon...

Sep 09 16:11:07 raspi5 systemd[1]: openvpn@server_tcp.service: PID file /var/run/openvpn/server_tcp.pid not readable (yet?) after start: No such file or directory

Sep 09 16:11:07 raspi5 systemd[1]: Started thlu:openvpn@server_tcp.service   Starts a OpenVPN-Daemon.

openvpn.service - thlu:openvpn.service   Starts OpenVPN-Daemon for TCP and UDP

   Loaded: loaded (/etc/systemd/system/openvpn.service; disabled; vendor preset: enabled)

   Active: active (exited) since Sun 2018-09-09 16:11:07 UTC; 2min 34s ago

  Process: 1028 ExecStart=/bin/systemctl start openvpn@server_tcp.service (code=exited, status=0/SUCCESS)

  Process: 1009 ExecStart=/bin/systemctl start openvpn@server_udp.service (code=exited, status=0/SUCCESS)

  Main PID:1028 (code=exited, status=0/SUCCESS)

Sep 09 16:11:05 raspi5 systemd[1]: Starting thlu:openvpn.service   Starts OpenVPN-Daemon for TCP and UDP...

Sep 09 16:11:07 raspi5 systemd[1]: Started thlu:openvpn.service   Starts OpenVPN-Daemon for TCP and UDP.

set-nftables-vpn.service - thlu:set-nftables-vpn .service:   Setting some netfilter-rules for openvpn-server

   Loaded: loaded (/etc/systemd/system/set-nftables-vpn.service; disabled; vendor preset: enabled)

   Active: active (exited)  since Sun 2018-09-09 16:11:07 UTC; 2min 34s ago

   Main PID: 154 (code=exited, status=0/SUCCESS)

   CGroup: /system.slice/set-nftables-vpn .service

Die Services in den Systemstart einplanen:

# systemctl enable openvpn.service

# systemctl enable set-nftables-vpn.service

Sofern das Verzeichnis /tmp nicht auf tmpfs (also eine RAM-Disk) basiert, löschen wir abschließend noch unser Installations-Tar-Archiv. Wenn /tmp jedoch eine RAM-Disk ist, passiert das Löschen automatisch beim nächsten Shutdown. Aber es schadet auf gar keinen Fall, es jetzt bewusst zu löschen, denn wir brauchen es ja hier nicht mehr... und so können wir es auch nicht vergessen, falls der RPi durchläuft.

# rm /tmp/openvpn-setup.tar

Das war's, mehr ist nicht zu tun. Wir lassen das geöffnete Log-Terminal-Fenster einfach mal laufen und richten nun ein Client-System ein. Optimal ist es, wenn uns dafür ein Smartphone und ein Laptop zur Verfügung steht. Ich verwende jetzt hier als Smartphone mein Galaxy S8, sowie den Laptop mit dem Hostnamen D620 und baue damit diesen nächsten Test auf.

 

Setup OpenVPN-Client

Dieser Punkt einer ersten Test-Inbetriebnahme ist eigentlich der interessanteste überhaupt. Hier zeigt sich, ob wir bei diesen vielen Einzelschritten auch wirklich sorgfältig gearbeitet haben.

Hier erweist sich jetzt, ob

> die Router-Konfiguration und

> die Server-OpenVPN-Konfiguration und

> Server-Zertifikate und Keyfiles und

> die Server-systemd-Komponenten und

> Server-Kernel-Parameter und

> die Client-OpenVPN-Konfiguration und

> die Client-Zertifikate und Keyfiles

am Ende auch wirklich erfolgreich zusammenwirken.

 

Das sind ziemlich viele Faktoren, die ziemlich viel Raum für Fehler enthalten. Und wenn dann wirklich was falsch ist, ist die Fehlersuche immer absolut mühsam. Der beste Weg ist also der, von Beginn an sehr sorgfältig zu arbeiten, sich selber immer wieder zu kontrollieren und jeden Schritt ein zweites Mal zu prüfen.

Einige der nun folgenden Arbeiten sind exakt die gleichen, wie zuvor schon beim Server: Zunächst kopieren wir wieder von unserem Entwickler-Rechner das Tar-Archiv zur Installation auf den Laptop. Ich habe jetzt hier willkürlich die IP-Adresse 95 eingetragen, aber welche wirklich die richtige des Laptops ist, muss natürlich zuvor am Laptop oder am DSL-Router nachgesehen werden. Ich kommentiere jetzt aber nicht noch einmal erneut die Befehle, wenn es wirklich die gleichen sind wie zuvor, sondern liste sie einfach nur gruppiert auf:

$ scp "/home/openvpn-setup.tar" "toml@10.0.1.95:/tmp"

$ scp "/home/openvpn-2.5.7_amd64.deb" "toml@10.0.1.95:/tmp"

 

$ ssh 10.0.1.95

$ su -

# dpkg -l libc6 liblz4-1 liblzo2-2 libpam0g libssl1.1 libsystemd0 iproute2 lsb-base

# apt install $(fehlende)

# cd /tmp

# dpkg -i openvpn-2.5.7_bullseye_amd64.deb

# tar -xf openvpn-setup.tar

Auch hier kann der virtuelle VPN-User angelegt werden, wenn der VPN-Prozess mit eingeschränkten Rechten laufen soll. Achtung: In der aktuellen Client-Conf sind die beiden relevanten Parameter (siehe Server-Conf) derzeit nicht eingetragen.

# adduser vpnuser --no-create-home --gecos "" --disabled-password

Weiter geht's mit dem Kopiervorgang der Konfigurationsdateien aus dem Tar-Archiv, sowie Zertifikat und Key-File, die wie gehabt in die jeweiligen Verzeichnisse zu kopieren sind. Dazu entweder die Zielverzeichnisse wie hier folgend manuell anlegen oder in 2 Schritten mit dem Midnight Commander. Und auch hier bitte hinterher wieder gewissenhaft die gesetzten Rechte kontrollieren und ggf. korrigierien:

# mkdir -p /etc/openvpn/keys

 

Verzeichnis

Rechte

Datei

Rechte

/etc/openvpn

root:root 700

client_udp.conf

client_tcp.conf

root:root 600

/etc/openvpn/keys

root:root 700

ca.crt

ta.key

D620.crt

D620.key

root:root 600

/etc/systemd/system

 

openvpn@.service

root:root 644

/usr/local/bin

 

vpn

root:root 755

Hier besteht das gleiche Problem wie beim Server, deshalb der Symlink, der den Eintrag in den Client-Conf's passend auf die tatsächlichen Files verlinkt, um das Problem des Namenskonflikts zu beheben:

# cd /etc/openvpn/keys

# ln -s D620.key client.key

# ln -s D620.crt client.crt

# ls -lah

# chown -R root:root /etc/openvpn

# chmod -R 600 /etc/openvpn

# chmod 700 /etc/openvpn

# chmod 700 /etc/openvpn/keys

Löschen der jetzt nicht mehr benötigten Dateien:

# cd /tmp

# rm openvpn.tar

# rm -r OpenVPN

Sofern wir die letzten Schritte auf unserem Laptop auch via SSH durchgeführt haben, müssen wir uns nun dort abmelden. Der jetzt folgende Test erfordert, dass wir uns tatsächlich auf dem Laptop selber anmelden und den finalen Test an seiner Tastatur und Bildschirm durchführen. Der Hintergrund ist einfach, wir müssen jetzt als erstes die bestehende Verbindung unseres Laptops ins lokale WLAN trennen - und mit getrennter WLAN-Verbindung ist natürlich auch der SSH-Zugang getrennt.

Access-Point via Tethering:

 
Für den jetzt von uns beabsichtigten Test, ob unser OpenVPN auch wirklich unter realen Bedingungen funktioniert, ist die wichtigste Voraussetzung, dass der Laptop über eine vom heimischen Netzwerk unabhängige Internetverbindung verfügt. Genau dazu benötigen wir das Smartphone. Und auch im Smartphone ist dazu die WLAN-Verbindung vom heimischen Netzwerk zu trennen und stattdessen eine Verbindung ins Internet via UMTS (mobile Daten) zu aktivieren. Als nächstes wird Tethering aktiviert. Ich war da sehr erfindungsreich und hab dem S8 einfach die SSID "toms_s8" vergeben, aber dafür habe ich ein gutes WLAN-Password.gewählt. Nun wird der Laptop mit dem WLAN des Smartphones verbunden. Und wenn wir alles richtig gemacht haben, zeigt uns eine Browser-Abfrage "was ist meine ip?" nicht mehr die öffentliche IP unseres Heim-Netzwerkes, sondern die des Handy-Netzwerks.
 

Und wie zuvor wird nun auch hier zuerst ein manueller Start vorbereitet, um sicher zu bestätigen, dass der Start des Programms selber keine Fehlermeldungen erzeugt. Dazu benötigen wir 2 gleichzeitig geöffnete Terminalfenster, in denen wir uns beide Male als root anmelden. Die Fenster werden wieder so angeordnet, dass beide gleichzeitig zu sehen sind. Im ersten lassen wir uns das upd-log anzeigen.

# mkdir -p /var/run/openvpn

# touch /var/run/openvpn/client.log

# tail -f /var/run/openvpn/client.log

Im zweiten Terminal-Fenster erfolgt der manuelle Start von OpenVPN als im Vordergrund laufendes Programm, was dann im Log-Fenster zu folgender Ausgabe führen sollte, hier bei mir wieder ohne Fehlermeldungen:

# openvpn --mktun --dev tun0

# /usr/sbin/openvpn --config /etc/openvpn/client_udp.conf

 

Eigentlich hatte ich erwartet, dass die Terminal-Ausgabe jetzt dem folgenden Listing entspricht... das hats aber nicht.... im Gegenteil... gar nix ging... nicht mal eine brauchbare Fehlermeldung.

Das hat mir dann eine volle Stunde echt unnötiger Arbeit beschert, weil ich wirklich Schritt für Schritt und ziemlich ermüdend jeden einzelnen Eintrag in allen betroffenen Dateien und Verzeichnissen kontrollieren musste. Und natürlich habe ich 2 Flüchtigkeitsfehler gefunden.

Die Server-Conf enthielt die beiden folgenden Einträge... original hier aus dem Artikel:

push "dhcp-option DNS 10.0.1.1"

push "dhcp-option DNS fd00:10:0:1:228d:ff77:fe11:2892"

 
 

Der Fehler ist offensichtlich, denn selbstverständlich müssen auch beim Testen dieser Doku in meinem Netzwerk die IPs meines Routers eingesetzt werden. Mit Phantasie-IPs kann das natürlich nicht funktionieren. Und außerdem enthielt im DSL-Router der Eintrag für die statische Route vom VPN-Netz noch einen Dreher, statt 10.0.8.0 war 10.8.0.0 eingetragen.

Also... was sagt uns das? Alle ... und ja, wirklich alle ... verwendeten IP-Adressen stehen auf die eine oder andere Art in Beziehung zueinander. Wenn an irgendeiner Stelle eine bestimmte Verbindung aufgerissen ist, weil eine fehlerhafte IP nicht zum Gesamten passt... tja... dann fällt möglicherweise alles durch diesen Riss und verschwindet im Nirgendwo.... mit dem Endergebnis, dass es nicht funktioniert. Zwei Dinge sind also für den Erfolg maßgebend:

Sorgfalt (beim Arbeiten) und Wissen (um der Zusammenhänge)

Reaktion bzw. Ausgabe im Log-Fenster, nachdem die Fehler behoben waren:

Tue Sep 11 18:38:10 2018 OpenVPN-2.5.7 x86_64-pc-linux-gnu [SSL (OpenSSL)] [LZO] [LZ4] [EPOLL] [MH/PKTINFO] [AEAD] built on Aug  2 2018

Tue Sep 11 18:38:10 2018 library versions: OpenSSL 1.1.0f  25 May 2017, LZO 2.08

Tue Sep 11 18:38:10 2018 Outgoing Control Channel Authentication: Using 256 bit message hash 'SHA256' for HMAC authentication

Tue Sep 11 18:38:10 2018 Incoming Control Channel Authentication: Using 256 bit message hash 'SHA256' for HMAC authentication

Tue Sep 11 18:38:11 2018 TCP/UDP: Preserving recently used remote address: [AF_INET]555.444.333.666:55553

Tue Sep 11 18:38:11 2018 Socket Buffers: R=[212992->212992] S=[212992->212992]

Tue Sep 11 18:38:11 2018 UDP link local (bound): [AF_INET][undef]:55553

Tue Sep 11 18:38:11 2018 UDP link remote: [AF_INET]555.444.333.666:55553

Tue Sep 11 18:38:11 2018 TLS: Initial packet from [AF_INET]555.444.333.666:55553, sid=b8c0dc84 1f9212fb

Tue Sep 11 18:38:11 2018 VERIFY OK: depth=1, CN=Easy-RSA CA

Tue Sep 11 18:38:11 2018 VERIFY KU OK

Tue Sep 11 18:38:11 2018 Validating certificate extended key usage

Tue Sep 11 18:38:11 2018 ++ Certificate has EKU (str) TLS Web Server Authentication, expects TLS Web Server Authentication

Tue Sep 11 18:38:11 2018 VERIFY EKU OK

Tue Sep 11 18:38:11 2018 VERIFY OK: depth=0, CN=server

Tue Sep 11 18:38:11 2018 Control Channel: TLSv1.2, cipher TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384, 2048 bit RSA

Tue Sep 11 18:38:11 2018 [server] Peer Connection Initiated with [AF_INET]555.444.333.666:55553

Tue Sep 11 18:38:12 2018 SENT CONTROL [server]: 'PUSH_REQUEST' (status=1)

Tue Sep 11 18:38:13 2018 PUSH: Received control message: 'PUSH_REPLY,redirect-gateway def1 bypass-dhcp,redirect-gateway ipv6 bypass-dhcp

Tue Sep 11 18:38:13 2018 OPTIONS IMPORT: timers and/or timeouts modified

Tue Sep 11 18:38:13 2018 OPTIONS IMPORT: --ifconfig/up options modified

Tue Sep 11 18:38:13 2018 OPTIONS IMPORT: route options modified

Tue Sep 11 18:38:13 2018 OPTIONS IMPORT: --ip-win32 and/or --dhcp-option options modified

Tue Sep 11 18:38:13 2018 OPTIONS IMPORT: peer-id set

Tue Sep 11 18:38:13 2018 OPTIONS IMPORT: adjusting link_mtu to 1625

Tue Sep 11 18:38:13 2018 OPTIONS IMPORT: data channel crypto options modified

Tue Sep 11 18:38:13 2018 Data Channel: using negotiated cipher 'AES-256-GCM'

Tue Sep 11 18:38:13 2018 Outgoing Data Channel: Cipher 'AES-256-GCM' initialized with 256 bit key

Tue Sep 11 18:38:13 2018 Incoming Data Channel: Cipher 'AES-256-GCM' initialized with 256 bit key

Tue Sep 11 18:38:13 2018 ROUTE_GATEWAY 192.168.43.1/255.255.255.0 IFACE=wlp2s0 HWADDR=zz:gg:88:77:66:55

Tue Sep 11 18:38:13 2018 GDG6: remote_host_ipv6=n/a

Tue Sep 11 18:38:13 2018 ROUTE6: default_gateway=UNDEF

Tue Sep 11 18:38:13 2018 TUN/TAP device tun0 opened

Tue Sep 11 18:38:13 2018 TUN/TAP TX queue length set to 100

Tue Sep 11 18:38:13 2018 do_ifconfig, tt->did_ifconfig_ipv6_setup=1

Tue Sep 11 18:38:13 2018 /sbin/ifconfig tun0 10.0.8.6 pointopoint 10.0.8.5 mtu 1500

Tue Sep 11 18:38:13 2018 /sbin/ifconfig tun0 add fd00:10:0:8::1000/64

Tue Sep 11 18:38:13 2018 /sbin/route add -net 555.444.333.666 netmask 255.255.255.255 gw 192.168.43.1

Tue Sep 11 18:38:13 2018 /sbin/route add -net 0.0.0.0 netmask 128.0.0.0 gw 10.0.8.5

Tue Sep 11 18:38:13 2018 /sbin/route add -net 128.0.0.0 netmask 128.0.0.0 gw 10.0.8.5

Tue Sep 11 18:38:13 2018 /sbin/route add -net 10.0.1.0 netmask 255.255.255.0 gw 10.0.8.5

Tue Sep 11 18:38:13 2018 /sbin/route add -net 10.0.8.1 netmask 255.255.255.255 gw 10.0.8.5

Tue Sep 11 18:38:13 2018 add_route_ipv6(fd00:10:0:1::/64 -> fd00:10:0:8::1 metric -1) dev tun0

Tue Sep 11 18:38:13 2018 /sbin/route -A inet6 add fd00:10:0:1::/64 dev tun0

Tue Sep 11 18:38:13 2018 add_route_ipv6(::/3 -> fd00:10:0:8::1 metric -1) dev tun0

Tue Sep 11 18:38:13 2018 /sbin/route -A inet6 add ::/3 dev tun0

Tue Sep 11 18:38:13 2018 add_route_ipv6(2000::/4 -> fd00:10:0:8::1 metric -1) dev tun0

Tue Sep 11 18:38:13 2018 /sbin/route -A inet6 add 2000::/4 dev tun0

Tue Sep 11 18:38:13 2018 add_route_ipv6(3000::/4 -> fd00:10:0:8::1 metric -1) dev tun0

Tue Sep 11 18:38:13 2018 /sbin/route -A inet6 add 3000::/4 dev tun0

Tue Sep 11 18:38:13 2018 add_route_ipv6(fc00::/7 -> fd00:10:0:8::1 metric -1) dev tun0

Tue Sep 11 18:38:13 2018 /sbin/route -A inet6 add fc00::/7 dev tun0

Tue Sep 11 18:38:13 2018 Initialization Sequence Completed

Fehlermeldungen = keine, die beiden folgenden Meldung sind aber noch interessant:

Peer Connection Initiated with [AF_INET]555.444.333.666:55553       Verbindung zum Server ist hergestellt

Initialization Sequence Completed                                   Authentifizierung mit Keyfile und Zertifikat war erfolgreich

Wenn diese Meldungen kommen und es sind keine Fehler unterlaufen, sollte der Tunnel mit daran anschließender Funktionalität erfolgreich etabliert sein. Wenn wir nun wieder im Browser nachschauen und erneut unsere aktuelle IP abfragen, so sollten wir nicht mehr die öffentliche IP des Handy-UMTS-Netzwerks sehen, sondern die öffentlichen IPs unseres heimischen Netzwerkes. Das wars... Projekt geglückt.... es funktioniert... Ziel erreicht.

Die OpenVPN-Verbindung auf meinem Laptop ist nicht etwas, was ich ständig benötige. Ich nutze meinen Laptop ja ganz selbstverständlich auch zu Hause und da brauch ich kein VPN. Also starte ich das VPN auf Reisen auf dem Laptop immer nur manuell bei Bedarf. Entweder über meinen eigenen kleinen Netzwerkmanager selnic, der mich bei der Verbindung mit häufig wechselnden WLAN-Access-Points optimal unterstützt. Oder in Einzelfällen auch über ein kleines Script, was im Terminal gestartet wird. Nur mit dem Aufruf vpn startet es den UDP-Client, mit einem beliebigen Parameter wird TCP gestartet. Ich habe jetzt hier mehrere einfache Alternativen beschrieben, die allesamt OpenVPN starten.

Vier einfache Alternativen, um das VPN auf einem Laptop nur bei Bedarf manuell zu starten:

1. Ein direkter manueller Start im Terminal. Der OpenVPN-Prozess läuft dabei im Vordergrund und kann mit der Tastenkombination strg-c unterbrochen/beendet werden. Wenn das die bevorzugte Methode ist, sollte das log-append-Statement in der betroffenen Client.conf mit # einkommentiert werden... aber auch nur bei dieser Alternative. Die Einkommentierung führt dann dazu, das alle Ausgaben des Programms nach dem Start unmittelbar im Terminal-Fenster angezeigt werden. Diesen Aufruf favorisiere ich z.B. bei der Fehlersuche... aber er funktioniert natürlich auch im täglichen Arbeitsablauf.

# /usr/sbin/openvpn --config /etc/openvpn/client_udp.conf

2. Führt im Grunde genommen den gleichen manuellen Start im Vordergrund durch, wie unter Pkt. 1. Der wichtige Unterschied ist, dass zusätzlich ein zweites Fenster zur laufenden Anzeige der Log-Einträge geöffnet wird, um jederzeit den aktuellen Status der VPN-Sitzung zu sehen. Das VPN-Sitzung wird wie zuvor mit strg-c unterbrochen/beendet.

# /usr/local/bin/vpn

 

#!/bin/bash

# Script-Name   : vpn        

# Date          : 15.01.2017

# Version       : 1.0

# Usage         : vpn {x}

 

if [[ $EUID -ne 0 ]]; then

   echo -e "\nThis script must be run as root" 1>&2

   exit 1

fi

 

mkdir -p /var/run/openvpn

TerminalApp=$(which xterm)

[ -f /var/run/openvpn/client.log ] || touch /var/run/openvpn/client.log

[ -n "$TerminalApp" ] && $TerminalApp -geometry 120x20+1+1 -e "/usr/bin/tail /var/run/openvpn/client.log -n 100 --sleep-interval=2 -f --pid=$$" &

 

if [ -z "$1" ]; then

   confnme="/etc/openvpn/client_udp.conf"

else

   confnme="/etc/openvpn/client_tcp.conf"

fi

 

echo -e "\r\nstrg-c beendet die OpenVPN-Sitzung\r\n"

 

[ -f $confnme ] && openvpn --config "$confnme" || echo "$confnme nicht gefunden!"

3. Ein direkter manueller Start im Terminal über systemd. Dazu muss natürlich die Service-Unit (s.o.) in das Verzeichnis /etc/systemd/system/openvpn@.service kopiert werden. Der OpenVPN-Prozess läuft als Daemon im Hintergrund. Eine begleitende fortlaufende Log-Ausgabe findet hierbei nicht statt. Diese Start-Methode über systemd verwendet auch mein Script "selnic". Das aktive Fenster könnte nach dem Start sogar geschlossen werden. In dem Fall wird für das Stop-Statement bei Bedarf einfach ein neues Terminal-Fenster geöffnet.

# systemctl start openvpn@client_udp.service

# tail -n 20 /var/run/openvpn/client.log

# systemctl stop openvpn@client_udp.service

4. Der Start des OpenVPN-Tunnels erfolgt über ein Script durch systemd, der OpenVPN-Prozess läuft hier wie unter Pkt.3 ebenfalls als Daemon und somit im Hintergrund. Der wichtige Unterschied zu Pkt. 3 ist, dass hier wieder zusätzlich ein zweites Fenster zur laufenden Anzeige der Log-Einträge über tail geöffnet wird, um jederzeit den aktuellen Status der VPN-Sitzung zu sehen. Das Script wartet auf Tastendruck (Enter) und beendet dann den laufenden OpenVPN-Prozess. Das ist meine favorisierte Startmethode.

# /usr/local/bin/vpn

 

#!/bin/bash

# Script-Name   : vpn        

# Date          : 15.01.2017

# Version       : 1.0

# Usage         : vpn {x}

 

if [[ $EUID -ne 0 ]]; then

   echo -e "\nThis script must be run as root" 1>&2

   exit 1

fi

 

mkdir -p /var/run/openvpn

TerminalApp=$(which xterm)

[ -f /var/run/openvpn/client.log ] || touch /var/run/openvpn/client.log

[ -n "$TerminalApp" ] && $TerminalApp -geometry 120x20+1+1 -e "/usr/bin/tail /var/run/openvpn/client.log -n 100 --sleep-interval=2 -f --pid=$$" &

 

if [ -z "$1" ]; then

   confnme="client_udp"

else

   confnme="client_tcp"

fi

 

if [ ! -f /etc/openvpn/$confnme.conf ]; then

   echo "/etc/openvpn/$confnme.conf nicht gefunden!"

   exit 1

fi

 

systemctl start openvpn@$confnme.service

read -p "Enter-Taste beendet die laufende OpenVPN-Sitzung"

systemctl stop openvpn@$confnme.service

 

exit 0

 

 

An der Stelle bleibt nur noch übrig, einen abschließenden wirklich wichtigen Hinweis zu geben. Öffentliche Access-Points für eine WLAN-Verbindung mit dem eigenen Laptop ohne eine Firewall zu nutzen, erachte ich in jeder Hinsicht als grob fahrlässig. Ich hatte das deshalb hier im Artikel mit dem Stichwort 'Paketfilter' schon mehrfach erwähnt, allerdings ohne jeweils näher darauf einzugehen. In diesem Artikel geht es ja um OpenVPN und nicht um eine Firewall. Das Thema Firewall ist aber mindestens genau so umfangreich, mindestens genau so anspruchsvoll und für den Schutz der eigenen digitalen Privatsphäre nicht weniger wichtig.

Deswegen habe ich das in einem eigenen Artikel umfassend beschrieben, der sich nur mit dem Thema Firewall befasst

 

 

 

Setup Android-Clients

Für die Installation eines VPN-Clients auf unseren Android-Geräten verwende ich seit vielen Jahren "OpenVPN für Android" von Arne Schwabe, dem Autor des Programms. Gefühlsmäßig möchte ich fast sagen, es müssten bestimmt mittlerweile an die 8 Jahre sein, in denen ich diese App nutze. Heute und auf die lange Zeit zurückblickend hat mich die wirklich großartige Umsetzung und die Stabilität dieser App ohne jeden Zweifel davon überzeugt, dieses Programm mit wirklich gutem Gewissen empfehlen zu können. Hier an der Stelle also auch mein Dank an Arne Schwabe für diese großartige Arbeit.

Ebenso wie für die anderen VPN-Client-Geräte wurde auch für mein Smartphone (Galaxy S8) zuvor auf meinem PC mit Easy-RSA (siehe oben) u. a. diese 4 Files (Zertifikate und Keys) erzeugt: S8.crt, S8.key, ca.crt und ta.key. Der schwierigste Teil in der Installation ist es nun, diese 4 notwendigen Dateien abhörsicher aufs das Handy zu übertragen. Auf gar keinen Fall sollte man sich diese 4 Files via Whatsapp, Telegram, EMail oder auf sonstige Weise irgendwie ungeschützt über das öffentliche Netzwerk an das Smartphone zusenden. Denn darüber muss sich ein jeder im Klaren sein, wer diese 4 Files besitzt und die öffentliche IP oder den DDNS-Namen unseres heimischen Netzwerks kennt, hat vollständigen Zugang in unser privates Netzwerk. Zum Kopieren von Dateien zwischen Smartphone und dem Samba-Server in meinem Netzwerk verwende ich auf den Android-Geräten den Total-Commander und das dazugehörige LAN-Plugin. Auf dem Smartphone wird zuerst eine lokale WLAN-Verbindung hergestellt, dann starte ich den TC und öffne mit dem LAN-Plugin den entsprechenden Samba-Share auf meinem Server und kopiere von dort die Dateien in einen temporären Ordner aufs Smartphone, um sie dann von da in das VPN-Profil zu importieren (siehe Screenshots 4 und 8). Der Total-Commander auf den Androids ist für mich schlichtweg unverzichtbar, ebenso wie der Midnight-Commander auf den Debian-PCs - einfacher und noch schneller geht's wirklich kaum noch, Dateien von hier nach dort zu kopieren oder zu verschieben. Nach dem Import werden die 4 Files umgehend wieder gelöscht!

Zwei ergänzende Hinweise: Wenn zuvor erfolgreich eine Client-Verbindung vom Laptop hergestellt werden konnte, wird die Verbindung vom Smartphone ebenfalls sofort funktionieren. Das bedeutet aber auch, solange ich nicht eine erfolgreiche Verbindung mit dem Laptop herstellen konnte, würde ich mich mit dem Smartphone gar erst nicht befassen. Fakt ist, die Fehlersuche gestaltet sich auf meinem Debian-Laptop gravierend einfacher, als das auf dem Smartphone möglich ist. Zuerst muss es grundsätzlich funktionieren... damit meine ich die Komponenten DDNS-Account, Port-Öffnung, Weiterleitung und Routen im DSL-Router, Authentifizierung am VPN-Server, Paketfilter-Regeln. Klappt das alles mit dem Laptop, klappt es auch sofort mit den Android-Geräten. Hat man allerdings nur das Smartphone zur Verfügung... tja... dann muss man halt probieren und schauen, wie man evtl. auftretenden Fehlern und Problemen auf die Schliche kommt.

Und zweitens erachte ich den wirklich geringen Unterschied zwischen UDP- und TCP-Profil auf dem Android-Gerät für erwähnenswert. Wenn ich mit dem neuen UDP-Profil eine erfolgreiche Verbindung zum Server herstellen konnte, kopiere ich das UDP-Profil einfach mit dem App-GUI, vergebe ihm einen neuen Namen und muss dann nur noch im kopierten Profil die beiden Einträge für Protokoll und Port (siehe Screenshot 5) ändern. Sofern auch auf dem Server der OpenVPN-Daemon für TCP läuft und man hat sich keine Tipp-Fehler eingebaut, klappt auch diese Verbindung eigentlich sofort.

Neues Profil hinzu-

fügen

Eingerichtete Profile

Globale Einstellungen

OpenVPN

Einstellungen für

Profil UDP

 
 

 

Der Profilname ist frei wählbar. Ich empfehle einen "sprechenden" Namen, mit dem sofort der Zweck des Profils erkennbar ist.

Bei mir gibt es nur 1 VPN-Server und nur diese 2 Profile, also kann ich auch einfachste und natürlich selbsterklärende Namen verwenden.

Unveränderte Default-Einstellungen.

Die zuvor auf meinem PC erstellten und aufs Smartphone kopierten Cert- und Keyfiles werden in das VPN-Profil importiert.

 

Die Eingabe der Cert-Passphrase ist hier optional. Es ist aber schwierig, das generell zu empfehlen oder abzulehnen. Wurden die Certs ohne PWD erzeugt, wird auch keines abgefragt. Siehe Script!

Als alternative Möglichkeit zur Übernahme der einzelnen Dateien in Bild 4 kann auch das zusätzlich erzeugte Zertifikat-Paket (pkcs12) in den Benutzer-Zertifikat-Speicher des Smartphones importiert werden. Damit wird auf jeden Fall die Zugriffssicherheit verbessert.

Der DDNS-Name meines Netzwerks (DSL-Routers), der zu verwendende Port sowie die Festlegung des Protokolls (entweder UDP oder TCP).

 

Port und Protokoll sind die einzigen Unterschiede zum TCP-Profil.

1

2

3

4

5

6

 

 

 

 

 

 

 

Einstellungen für

Profil UDP

 
 

 

 

 

 

Der Server teilt den Client-PCs alle wichtigen Parameter bzw. Informationen mit.  

 

Einstellungen des lokalen Netzwerkes werden ignoriert.

Legt fest, dass kein Datenverkehr am VPN vorbei in das lokale Netz des Gastgeber-Access-Points erfolgt.

HMAC-Firewall durch den Import des Keyfiles aktivieren.

 

Verschlüsselungs-parameter setzen.

 

Achtung: Parameter müssen mit denen in der server.conf übereinstimmen!

Keine Authentifizierungs-Informationen im Speicher belassen.

 

Siehe auch Bild 10b,

wenn 9 keine Option für --auth enthält.

Keine Apps zulassen, die am VPN vorbei ins Internet operieren dürfen.

Protokoll einer erfolgreich hergestellten Verbindung.

7

8

9

10

11

12

 

 

 

 

Speziell auf die Frage nach 'Best Practice', ob man besser Cert & Key als Files in die App importiert oder ob man besser die Android Keychain verwendet, habe ich leider keine Antwort. Auf der GitHub-Web-Site der OpenVPN-App findet man einen Link zu einer ics-openvpn-FAQ, die unter der Absatz-Überschrift 'Security considerations' sinngemäß erklärt, dass auf die einmal in das VPN-Profil importierten Dateien kein Zugriff durch andere Apps besteht ... zumindest solange das Smartphone nicht gerootet ist. Das werte ich für meinen Anspruch als eine ausreichend gute Erklärung für den Schutz gegen Fremdzugriff anderer Apps auf die Einstellungen.

Da es auf der anderen Seite auf meinem Smartphone keine weitere Berechtigungsabfrage beim Import aus der Keychain in das OpenVPN-Profil gab, vermute ich, dass auch andere Apps die Daten importieren könnten... was ich aber mangels Hintergrundkenntnissen zu Android nicht abschließend weiß. Ich würde vermutlich dann die Keychain wählen, wenn ich Verlust oder Diebstahl des Handys in den Vordergrund stellen würde. Weil ich diese Befürchtung aber nicht hege, vertraue ich auf die fehlenden Lese-Berechtigungen durch andere Apps auf meine VPN-Profile.

Schließlich ausschlaggebend für meine Entscheidung war auch der Umstand, dass das als File importierte Zertifikat die bei der Erstellung eingerichtete Password-Abfrage beibehalten hat. Das aus der Keychain importierte Zertifikat hat dieses Password hingegen nicht mehr verlangt.

 

 

 

Nachwort:

Immer wieder aufs Neue bin ich über den Umfang eines Artikels erschrocken, wenn er denn irgendwann mal fertig ist. Und immer wieder aufs Neue frage ich mich dann, wie kann man eigentlich die Anforderung "mit Sachverstand und verantwortungsbewusst" für ein solches Projekt erfüllen, wenn man nicht wirklich alle Fakten und Rahmenbedingungen verstanden hat und sich nicht deren Bedeutung und mögliche Auswirkungen auch wirklich bewusst gemacht hat. Ein generisch erzeugtes Netzwerk mit Zugriff über das Internet auf sensible persönliche private Daten oder sogar der Home-Automatisierung ist doch nicht etwas, was man mal eben zwischendurch mit einem 75-Zeilen-HowTo per Copy/Paste auf seinen Rechner bringt und dann denkt "das war ja easy".

Was liegt denn da für eine Erwartungshaltung zu Grunde? Da stimmt doch irgendwas nicht. Mir kommt es manchmal so vor, als hätte ein Fahranfänger vor seinem allerersten (!) Einstieg in ein modernes Auto die Erwartungshaltung, es wäre völlig ausreichend, mal eben schnell das kurze Quick-Start-Guide der Bedienungsanleitung dieses Autos zu lesen, um dann im Anschluss von Flensburg nach München fahren zu können. Tja... was soll ich sagen ...?... bin sprachlos ... deshalb ist mein Artikel genau so lang, wie ich glaube, dass er es sein muss, ums auch wirklich zu kapieren.... alle anderen begleitet mein Wunsch, sie mögen heil in München ankommen - selbst wenn sie es dem Zufall überlassen.

 

 

 

Änderungsprotokoll

 

 

Datum

Änderungen

01.10.2018

Redaktionelle Korrekturen

 

server.conf alt:

comp-lzo                  (wird ab OpenVPN 2.5 nicht mehr unterstützt)

server.conf neu:

compress lzo

Achtung:

Die Kompression enthält unter bestimmten Umständen ein Sicherheitsrisiko, bei dem es dann ratsam ist, die Kompression zu deaktivieren:

  •   Der Angreifer befindet sich im selben Netzwerk 

  •   Es wird eine HTTP-Verbindung verwendet 

  •   Es wird eine Website besucht, die vom Angreifer kontrolliert wird 

  •   Es wird ein für VORACLE anfälliger Browser verwendet 

  •   OpenVPN wird mit aktivierter Kompression verwendet 

 

adduser-Statement hinzugefügt, um den unberechtigten virtuellen User  'vpnuser' ohne Password anzulegen.

10.10.2018

Authentifizierung und Verschlüsselung auf dem TLS-Kontrollkanal  umgestellt

server.conf alt:          (signiert alle Pakete mit einer HMAC-Signatur)

tls-auth /etc/openvpn/keys/ta.key 0

server.conf neu:          (verschlüsselt zusätzlich alle Pakete  (Schlüsselrichtung ist hier unnötig))

tls-crypt /etc/openvpn/keys/ta.key

 

Android-Clients: Bild 8.b an tls-crypt angepasst

 

Diffie-Hellman-Schlüsselaustausch von statischem Keyfile auf Elliptic Curves  umgestellt

server.conf alt:

dh /etc/openvpn/keys/dh.pem

server.conf neu:

ecdh-curve secp384r1

dh none

Ohne Angabe tls-cipher wird die Verwendung der 'höchstwertigen' Cipher präferiert, siehe Log-Eintrag nach einer hergestellten Verbindung:

2018-10-01 18:15:42 Control Channel: TLSv1.2, cipher TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384, 2048 bit RSA

10.10.2018

Verbindungen "schlechter" als Version 1.2 werden abgewiesen:

tls-version-min 1.2

05.08.2019

- Überprüfung und Anpassung des Setups auf Debian Buster

- Das Paket 'checkinstall' zur Erzeugung des deb-Packages für OpenVPN durch die Build-Deb-Package-Funktion des Programms dpkg ersetzt

- Installationspfad mit der Begründung „eigenes Deb-Package“ nach /opt/openvpn verlegt

- symlink für Openvpn-Binary in /usr/sbin erzeugt

22.08.2019

Harmonisierung der in den Beispielen verwendeten IP-Adressen in den Artikeln security, openvpn, cameventctl  zur Verbesserung der Zusammenhang-Darstellung.

06.09.2019

Redaktionell mit dem Ziel "geradliniger" überarbeitet

15.11.2019

OpenVPN-2.4.8

 

Kapitel "Perfect Forward Secrecy" eingefügt...  gehe zu.

 

auth SHA512 auf auth SHA256 geändert... siehe Hinweise.

 

Sicherheit durch Wechsel von tls-version-min 1.2 auf tls-version-min 1.3 verbessert... siehe Hinweise.

 

dh none beim Wechsel auf ECC war eine Fehlentscheidung, siehe Änderungen 10.10.2018

dh.pem-File mit 4096 Bit erzeugt...  siehe Hinweise unterhalb server.conf.

 

compress lzo entfernt, da es die Sicherheit wegen charakteristischer Merkmale bei der Komprimierung schwächt

 

iptables-Regeln durch nftables ersetzt

 

create-ca3 erzeugt bei Angabe {p12} im Script (siehe Array Hosts) zusätzlich ein pkcs12-File (Archiv-Format) für den Import von Zertifikat und Key in die Keychain eines Android-Geräts

 

Einige 'Unstimmigkeiten' redaktionell korrigiert

15.12.2019

explicit-exit-notify in Client-UDP-Conf eingefügt

15.04.2020

Erläuterungen zu remote-cert-tls server eingefügt

26.12.2021

OpenVPN-2.5.5

Migration der Installation nach Debian 11 (Bullseye)

 

Fehlermeldung „checking for lz4.h... no usable LZ4 library or header not found“ bei ./configure behoben: Paket liblz4-dev hinzugefügt.

 

Update auf EasyRSA 3.08

 

In beiden Server-Conf-Files das Statement push "redirect-gateway ipv6 bypass-dhcp" entfernt. Damit Fehlermeldung durch Kollision mit push "redirect-gateway def1 bypass-dhcp" beseitigt.

26.08.2022

Update:

von Easy-RSA 3.0.8 auf 3.1.0

von OpenVPN 2.5.5 auf 2.5.7

 

create-ca3: Auf Grund geänderter Openssl-Parameter neu entstandene Warnungen korrigiert. Vorherige Syntax ist jetzt deprecated markiert.

 

 

< Startseite >