<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Ssl on zefanjas.de - Open Source &amp; Education</title>
    <link>https://zefanjas.de/tags/ssl/</link>
    <description>Recent content in Ssl on zefanjas.de - Open Source &amp; Education</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>de-DE</language>
    <lastBuildDate>Mon, 01 Jan 2018 04:55:59 +0000</lastBuildDate><atom:link href="https://zefanjas.de/tags/ssl/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>HAProxy, Nginx, LXD und Let’s Encrypt</title>
      <link>https://zefanjas.de/haproxy-nginx-lxd-und-lets-encrypt/</link>
      <pubDate>Mon, 01 Jan 2018 04:55:59 +0000</pubDate>
      
      <guid>https://zefanjas.de/haproxy-nginx-lxd-und-lets-encrypt/</guid>
      <description>&lt;p&gt;In meinem &lt;a href=&#34;https://zefanjas.de/wie-man-mehrere-webseiten-mit-nginx-und-haproxy-mit-lxd-hosten-kann/&#34;&gt;letzten Beitrag habe ich beschrieben&lt;/a&gt;, wie man verschiedene Webserver, die in einem LXD Container laufen, von außen über einen Reverse-Proxy (in unserem Fall HAProxy) erreichbar machen kann. Diese Setup läuft aber nur über HTTP (Port 80) und damit über einen unverschlüsselte Verbindung. Heutzutage ist es unabdingbar, dass man seine Website auch verschlüsselt. Deswegen möchte ich heute das Setup erweitern, sodass die Webserver über eine verschlüsselte Verbindung erreichbar sind. HAProxy wird dabei &lt;a href=&#34;https://en.wikipedia.org/wiki/TLS_termination_proxy&#34;&gt;SSL/TLS Termination Proxy&lt;/a&gt; agieren, d.h. wir müssen nur an einer Stelle alle unsere Zertifikate verwalten und nicht auf jedem einzelnen Webserver selbst. Der Vorteil ist, dass den Webservern Arbeit durch den Proxy abgenommen wird, allerdings muss man wissen, dass die Kommunikation zwischen HAProxy und den Webservern unverschlüsselt erfolgt. Dieses private Netz sollte als sicher angesehen werden. In unserem Fall ist das das Subnet von LXD, in dem sich die Container befinden. Folgende Grafik veranschaulicht den Prozess:&lt;/p&gt;
&lt;img loading=&#34;lazy&#34; decoding=&#34;async&#34; class=&#34;size-full aligncenter&#34; src=&#34;https://upload.wikimedia.org/wikipedia/commons/thumb/3/34/SSL_termination_proxy.svg/640px-SSL_termination_proxy.svg.png&#34; alt=&#34;TLS / SSL Termination&#34; width=&#34;640&#34; height=&#34;185&#34; /&gt; 
&lt;h3 id=&#34;container-überprüfen&#34;&gt;Container überprüfen&lt;/h3&gt;
&lt;p&gt;Zuerst überprüfen wir, ob alle unsere Container laufen und eine IP haben. Das können wir mit dem bekannten &lt;code&gt;lxc list&lt;/code&gt; Befehl machen:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ lxc list
+---------+---------+-----------------------+------+------------+-----------+
|  NAME   |  STATE  |         IPV4          | IPV6 |    TYPE    | SNAPSHOTS |
+---------+---------+-----------------------+------+------------+-----------+
| haproxy | RUNNING | 10.10.10.10 (eth0)    |      | PERSISTENT | 0         |
+---------+---------+-----------------------+------+------------+-----------+
| web1    | RUNNING | 10.10.10.100 (eth0)   |      | PERSISTENT | 0         |
+---------+---------+-----------------------+------+------------+-----------+
| web2    | RUNNING | 10.10.10.200 (eth0)   |      | PERSISTENT | 0         |
+---------+---------+-----------------------+------+------------+-----------+
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Alle unsere Container sind online und haben eine IP-Adresse bekommen. Weiterhin sollten die DNS-Einträge unserer beiden Webserver auf die öffentliche IP des Servers zeigen. Dies können wir z.B. mit dem &lt;code&gt;host&lt;/code&gt;-Befehl überprüfen:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ host web2.example.com
web1.example.com has address 1.2.3.4
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;weiterleitung-für-https-einrichten&#34;&gt;Weiterleitung für HTTPS einrichten&lt;/h3&gt;
&lt;p&gt;Bisher wird nur Traffic, der auf Port 80 auf unserem Server ankommt an den HAProxy Container weitergeleitet. Für HTTPS brauchen wir aber noch eine Weiterleitung für Port 443. Diese können wir mit einer ähnlichen iptables Regel einrichten:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ sudo iptables -t nat -I PREROUTING -i eth0 -p TCP -d server_ip/32 --dport 443 -j DNAT --to-destination haproxy_ip:443
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Diese Regel ist nach einem Neustart wieder weg. Um sie dauerhaft einzurichten, kann man z.B. das Paket &lt;em&gt;iptables-persistent&lt;/em&gt; installieren.&lt;/p&gt;
&lt;h3 id=&#34;haproxy-anpassen&#34;&gt;HAProxy anpassen&lt;/h3&gt;
&lt;p&gt;Als nächsten müssen wir den HAProxy Konfiguration anpassen. Dazu loggen wir uns als &lt;code&gt;root&lt;/code&gt; in dem Container ein:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ lxc exec haproxy bash
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Nun können wir die Konfigurationsdatei (&lt;strong&gt;&lt;em&gt;/etc/haproxy/haproxy.cfg&lt;/em&gt;&lt;/strong&gt;) öffnen (im HAProxy-Container) und anpassen.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ nano /etc/haproxy/haproxy.cfg
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Damit unser SSL Setup möglichst sicher ist, fügen wir folgende Zeilen im &lt;code&gt;global&lt;/code&gt; Abschnitt hinzu. Ich habe Sie mit dem &lt;a href=&#34;https://mozilla.github.io/server-side-tls/ssl-config-generator/&#34;&gt;Mozilla SSL Configuration Generator&lt;/a&gt; erzeugt:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;global
    ...
    # set default parameters to the modern configuration
    ssl-default-bind-ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256
    ssl-default-bind-options no-sslv3 no-tlsv10 no-tlsv11 no-tls-tickets
    ssl-default-server-ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256
    ssl-default-server-options no-sslv3 no-tlsv10 no-tlsv11 no-tls-tickets
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Im &lt;code&gt;defaults&lt;/code&gt; Block fügen wir folgende Zeilen hinzu:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;defaults
     ...
     option forwardfor
     option http-server-close
     ...
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Nun sind einige Anpassungen im &lt;code&gt;frontend www_frontend&lt;/code&gt; Abschnitt notwendig:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;frontend www_frontend
    # Http
    bind *:80
    # Https mit Ordner für Certifikate
    bind *:443 ssl crt /etc/haproxy/certs/
    # allen Traffic nach https weiterleiten
    redirect scheme https if !{ ssl_fc }
    # TLS Termination. HAProxy informiert hier unseren Webserver darüber. 
    reqadd X-Forwarded-Proto:\ https

    # Unterscheide zwischen sicheren und unsicheren Requests (wird in den nächsten zwei Zeilen verwendet).
    acl secure dst_port eq 443
    
    # Markiere alle Cookies als sicher, wenn sie über SSL gesendet werden.
    rsprep ^Set-Cookie:\ (.*) Set-Cookie:\ \1;\ Secure if secure
    # Füge den HSTS-Header mit einem maximalen Alter von 1 Jahr hinzu.
    rspadd Strict-Transport-Security:\ max-age=31536000 if secure
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In in den Backend Abschnitten müssen wir keine Änderungen vornehmen.&lt;/p&gt;
&lt;h3 id=&#34;let8217s-encrypt-zertifikate-einrichten&#34;&gt;Let’s Encrypt Zertifikate einrichten&lt;/h3&gt;
&lt;p&gt;Nun brauchen wir für die verschlüsselte Kommunikation noch ein Zertifikat für unsere Webserver. Let’s Encrypt bietet kostenfreie Zertifikate schon seit einigen Jahren an und ab diesem Jahr sogar Wildcard-Zertifikate.&lt;/p&gt;
&lt;p&gt;Damit wir die Zertifikate einrichten können, brauchen wir den Let’s Encrypt Client, den wir wie folgt installieren (im HAProxy Container):&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ sudo apt install letsencrypt
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Wir generieren ein Zertifikat, welches für alle unsere Domains gültig ist:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ letsencrypt certonly -d example.com -d web2.example.com
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Wenn alles geklappt hat, haben wir nun ein gültiges Zertifikat für unsere beiden Webserver. Jetzt müssen wir nur noch HAProxy die richtigen Zertifikate zur Verfügung stellen. Dazu müssen wir die Certificate Chain und den Private Key zusammenfügen, damit HAProxy etwas damit anfangen kann. Wir legen im ersten Schritt das Zielverzeichnis an und fügen dann die Zertifikate und den Key zusammen:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ mkdir -p /etc/haproxy/certs/
$ DOMAIN=&amp;#39;example.com&amp;#39; sudo -E bash -c &amp;#39;cat /etc/letsencrypt/live/$DOMAIN/fullchain.pem /etc/letsencrypt/live/$DOMAIN/privkey.pem &amp;amp;gt; /etc/haproxy/certs/$DOMAIN.pem&amp;#39;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Zum Schluss starten wir den HAProxy neu:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ systemctl restart haproxy
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;testen&#34;&gt;Testen&lt;/h3&gt;
&lt;p&gt;Wir sind fast am Ziel und möchten unsere Domains noch testen, ob auch alles richtig konfiguriert wurde.  Zuerst rufen wir die Seiten in einem Webbrowser auf. Es sollte neben der Adresse ein grünes Schloss erscheinen (im Firefox). Weiterhin sollten wir noch einen &lt;a href=&#34;https://www.ssllabs.com/ssltest/index.html&#34;&gt;SSL Server Test&lt;/a&gt; durchführen. Das Ergebnis lässt sich sehen:&lt;/p&gt;
&lt;img loading=&#34;lazy&#34; decoding=&#34;async&#34; class=&#34;aligncenter size-full wp-image-2298&#34; src=&#34;https://zefanjas.de/wp-content/uploads/2018/01/Auswahl_149.png&#34; alt=&#34;SSL Test Result&#34; width=&#34;1008&#34; height=&#34;432&#34; srcset=&#34;https://zefanjas.de/wp-content/uploads/2018/01/Auswahl_149.png 1008w, https://zefanjas.de/wp-content/uploads/2018/01/Auswahl_149-300x129.png 300w, https://zefanjas.de/wp-content/uploads/2018/01/Auswahl_149-768x329.png 768w, https://zefanjas.de/wp-content/uploads/2018/01/Auswahl_149-604x259.png 604w&#34; sizes=&#34;(max-width: 1008px) 100vw, 1008px&#34; /&gt; 
&lt;h3 id=&#34;fazit&#34;&gt;Fazit&lt;/h3&gt;
&lt;p&gt;Mit wenigen Schritten haben wir ein Setup geschaffen, in dem wir mehrere Webseiten nach außen hin erreichbar machen können. Das Ganze lässt sich leicht erweitern und skalieren. Besonders angenehm finde ich die Verwaltung der Zertifikate an einer Stelle und nicht auf jedem Webserver einzeln. LXD und Let’s Encrypt, sowie HAProxy sind für mich eine der großen persönlichen Entdeckungen der letzten zwei Jahre.&lt;/p&gt;
&lt;p style=&#34;text-align: center;&#34;&gt;
  &lt;strong&gt;Was sind für dich die größten Herausforderung bei der Bereitstellung von Webservern?&lt;/strong&gt;
&lt;/p&gt;
</description>
    </item>
    
  </channel>
</rss>
