(Info) Kleine Letsencrypt + nginx Anleitung

Begonnen von Wernieman, 25 Januar 2019, 12:06:33

Vorheriges Thema - Nächstes Thema

Wernieman

Kleine Letsencrypt + nginx Anleitung

Mal eine Kurzfassung zum meinem gestrigen Vortag zu letsenrypt auf dem Leipziger FHEM-Stammtisch

Es wurde behandelt: letsencrypt (certpot) über einen laufenden nginx-Server (http Authentifizierung)

Voraussetzungen: nginx, letsenrypt und Maschine ist extern über Port 80 erreichbar
Voraussetzungen: Automatisierung: da ein Zertifikat nur 3 Monate Haltbarkeit hat, sollte (und muß) man den Erhalt automatisieren, also Port 80 NICHT dicht machen!
Voraussetzungen: Domainname muß auf IP zeigen (hier www.test.de, bitte anpassen!)

Vorbereiten nginx:
server {
    listen      80 default_server;
    listen      [::]:80 default_server;
    server_name default_server;

    root /usr/share/nginx/html;
    index index.html index.htm;

    access_log  /var/log/nginx/default.access.log;
    error_log   /var/log/nginx/default.error.log;

    # Sicherheit
    server_tokens off;
    add_header Strict-Transport-Security 'max-age=31536000; includeSubDomains' always;

    # Für LetsEncrypt
    location ~ /\.well-known {
        root /usr/share/nginx/html;
    }

    # Alles andere auf https://
    location / {
        try_files $uri $uri/ =404;
        return 301 https://$host$request_uri;
    }


Damit leitet nginx die Authentifizierung letsencrypt auf /usr/share/nginx/html, alles andere per redirect auf https (Auch wenn es noch nicht funktioniert). Nach einem reboot kann (und sollte) man testen, ein externer Aufruf auf port 80 muß zu einer Umleitung auf https und damit ein "nicht erreichbar" führen

Aufruf letsencrypt (als root):

letsencrypt certonly --webroot -w /usr/share/nginx/html -d www.test.de


Hinweis: Man kann auch mehrere "-d Domainname" angeben. Das Zertifikat erhält den ersten Domainnamen, aber alle sind im zetifikat enthalten

Jetzt sollte man ein ".. Gratulation .." bekommen, sonst Fehlermeldung lesen!

Das Zertifikat liegt unter /etc/letsencrypt/live/www.test.de

nginx einrichten:
server {
    listen      443 ssl default_server;
    listen [::]:443 ssl default_server;
    server_name default_server;

    ssl_certificate_key /etc/letsencrypt/live/www.test.de/privkey.pem;
    ssl_certificate     /etc/letsencrypt/live/www.test.de/fullchain.pem;

    root        /usr/share/nginx/html;
    index       index.html index.htm;

    access_log  /var/log/nginx/default.access.log;
    error_log   /var/log/nginx/default.error.log;

    # Hier Security-Regel einfügen
    #include /etc/nginx/template/security;

    # Normalerweise alles nur nach Login
    location / {
        auth_basic              "Restricted Content";
        auth_basic_user_file    /etc/nginx/.htpasswd;
    }
}


So ... nun haben wir ein Zertifikat, einen laufenden nginx und können uns freuen .. bis in 3 Monaten ... es fehlt also die Automatisierung.
letsencrypt renew
Dieses guckt, ob ein Zertifikat y30 Tage gültig und erneuert es ggf., sofern obiger Webserver noch läuft. leider ... müsste nach einem Zertifikatserneuerung der nginx neu gestartet werden, sonst kriegt er davon nichts mit. Besser ... es gleich als cron-atumatisieren:
in /etc/cron.weekly/letsencrypt (ausführbar!)
#!/bin/sh

DIR="/etc/letsencrypt/live"
LOG="/var/log/letsencrypt/weekly.letsencrypt.log"

/usr/bin/letsencrypt renew >${LOG}.tmp 2>&1

result=$(find ${DIR}/ -type l -mtime -1 )
if [ -n "$result" ]; then
  echo "$(date "+%Y-%m-%d/%H:%M:%S") Neues Zertifikat" >>$LOG

  # Hier kann man mit dem zertifikat noch andere Dinge erledigen, z.B. es auf andere Geräte verteilen

  echo "$(date "+%Y-%m-%d/%H:%M:%S") Notwendige Dienste rebooten" >>$LOG
  /usr/sbin/service nginx restart
else
  echo "$(date "+%Y-%m-%d/%H:%M:%S") Keine neuen Dateien" >>${LOG}.no
fi


So ... dad war es nun, noch Fragen?

-----

Ausblick:
beim Treffn habe ich über Authentifizierung über http gesprochen. Mittlerweile gibt es auch eine über DNS. Dort braucht man aber eine API-fähigen DNS-Provider ....
- Bitte um Input für Output
- When there is a Shell, there is a Way
- Wann war Dein letztes Backup?

Wie man Fragen stellt: https://tty1.net/smart-questions_de.html

det.

Hallo Wernieman,
Vielen Dank für den Vortrag und die Anleitung. Da kommt gleich die erste Noob Frage: ich habe eine feste ip auf meinem VDSL, kein dynDNS. Die mag Let's Encrypt nicht:"The Let's Encrypt certificate authority will not issue certificates for a bare IP address."
Was mache ich da?
LG
det.

Wernieman

Du brauchst eine Domain, keine IP.

Ei n Zertifikat wird z.B. für www.test.de oder auch broetchen.metwurst.de ausgestellt, aber NICHT für eine IP.
- Bitte um Input für Output
- When there is a Shell, there is a Way
- Wann war Dein letztes Backup?

Wie man Fragen stellt: https://tty1.net/smart-questions_de.html

DS_Starter

Hi Wernieman,

danke für deine Infos !

Grüße
Heiko
ESXi@NUC+Debian+MariaDB, PV: SMA, Victron MPII+Pylontech+CerboGX
Maintainer: SSCam, SSChatBot, SSCal, SSFile, DbLog/DbRep, Log2Syslog, SolarForecast,Watches, Dashboard, PylonLowVoltage
Kaffeekasse: https://www.paypal.me/HMaaz
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/DS_Starter

Wernieman

Edit:
Hatte oben ausversehen die Zeile "include ...." vergessen auszukommentieren. Was ih damit erreichen will, kommt später (nächste Woche?)
- Bitte um Input für Output
- When there is a Shell, there is a Way
- Wann war Dein letztes Backup?

Wie man Fragen stellt: https://tty1.net/smart-questions_de.html

beddo

Hallo Wernieman,

Ich wäre übrigens sehr daran interessiert dies über Docker abzubilden.
Also im Optimalfall Reverse Proxy, Letsencrypt und fail2ban als Docker Container mit einem Configfile zur Steuerung der Ports welche an welchem Container ankommen sollen.
Idee ist den internen Zugriff auf fhem und nodered über freigegebene Ports im Docker auf den Standardports zuzulassen.
Für den externen Zugriff dann per Dyndns (example.duckdns.org), Fritzbox Weiterleitung an 443 über den Reverse Proxy und der verteilt an fhem bzw. nodered mit fhem.example.duckdns.org oder nodered.example.duckdns.org.
Ich habe versucht mein Fhem im Dockercontainer über solch eine Konstellation per https erreichbar zu machen. Bin aber kläglich gescheitert, da ich mich im Proxyumfeld nicht auskenne.

Wernieman

fail2ban mußt DU auf dem Hostsystem laufen lassen, da die Berechtigung für Netzwerkzugriffe über Docker .... nicht nett sind.

Auch würde ich Dir (persönlich) empfehlen, den Proxy auf dem Host. Wenn Du mehrere Netwerke im Docker definiert (ideal), hat nur der Host auf alle Zugriff. Es gibt docker-Container mit Proxylösungen (z.B. j.wilder), aber dann müssen alle Contaiiner in einem Netz sein.

Ich habe mich entschlossen, hier keinen Vortrag über Proxy zu halten. Der Sicherheitsaspekt ist doch sehr hoch. Wer nicht weiß, was er tut (gilt bei VPN genau so), sollte lieber "die Finger von lassen". Zu schnell holt man sich "den Fein" ins Haus!
- Bitte um Input für Output
- When there is a Shell, there is a Way
- Wann war Dein letztes Backup?

Wie man Fragen stellt: https://tty1.net/smart-questions_de.html

HoTi

Hallo Wernieman,
ich versuche gerade deine Anleitung zu folgen komme da aber nicht weiter.
Deine Voraussetzungen erfülle ich:
Zitat von: Wernieman am 25 Januar 2019, 12:06:33
Voraussetzungen: nginx, letsenrypt und Maschine ist extern über Port 80 erreichbar
Voraussetzungen: Automatisierung: da ein Zertifikat nur 3 Monate Haltbarkeit hat, sollte (und muß) man den Erhalt automatisieren, also Port 80 NICHT dicht machen!
Voraussetzungen: Domainname muß auf IP zeigen (hier www.test.de, bitte anpassen!)

1.   Ja ist es
2.   Ja bleibt es
3.   Domainname habe ich und lautet etwa so ,,ort.nachname.net"
Die FritzBox aktualisiert auch immer und alle anderen Server sind auch zu erreichen (andrer Port)

Dann habe ich die Datei ,,/etc/nginx/sites-available/reverse-proxy" angepasst mit deinem Code.
Reboot wurde ausgeführt.

Das Ergebnis von:
letsencrypt certonly --webroot -w /usr/share/nginx/html -d ort.nachname.net
lautet dann:
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator webroot, Installer None
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for ort.nachname.net
Using the webroot path /usr/share/nginx/html for all unmatched domains.
Waiting for verification...
Cleaning up challenges
Failed authorization procedure. ort.nachname.net (http-01): urn:ietf:params:acme:error:connection :: The server could not connect to the client to verify the domain :: Fetching http://ort.nachname.net/.well-known/acme-challenge/xxxxx: Connection refused

IMPORTANT NOTES:
- The following errors were reported by the server:

   Domain: ort.nachname.net
   Type:   connection
   Detail: Fetching
   http://ort.nachname.net/.well-known/acme-challenge/xxxxx:
   Connection refused

   To fix these errors, please make sure that your domain name was
   entered correctly and the DNS A/AAAA record(s) for that domain
   contain(s) the right IP address. Additionally, please check that
   your computer has a publicly routable IP address and that no
   firewalls are preventing the server from communicating with the
   client. If you're using the webroot plugin, you should also verify
   that you are serving files from the webroot path you provided.


Was mache ich da jetzt falsch?
Viele Grüße aus  Oberbayern
Tim (RettungsTim)

Wernieman

Fetching http://ort.nachname.net/.well-known/acme-challenge/xxxxx: Connection refused

Zum Testen
Lege mal einen Ordner an:
mkdir /usr/share/nginx/html/.well-known

Und jetzt
date >/usr/share/nginx/html/.well-known/test.txt

Beides sollte für jeden Lesbar sein. Und jetzt im Browser (von Extern!):
Zitathttp:/www.test.de/.well-known/test.txt

Natürlich, wie immer, www.test.de anpassen.

Es sollte im Browser das Datum / die Uhrzeit des date Aufrufs erscheinen. Wenn ja .. haben wir ein problem. Wenn Nein (bei Dir am wahrscheinlichsten), solltest Du im nfginx / beim router gucken, warum NICHT
- Bitte um Input für Output
- When there is a Shell, there is a Way
- Wann war Dein letztes Backup?

Wie man Fragen stellt: https://tty1.net/smart-questions_de.html

HoTi

Natürlich nein!

Router ist der Port offen! Definitiv. Dann weiß ich aber schon nimmer weiter.

Ich habe mich beim einrichten an diese Anleitung gehalten:
https://wiki.fhem.de/wiki/HTTPS-Absicherung_%26_Authentifizierung_via_nginx_Webserver

Wird da etwas gemacht was hier nicht passt?
Viele Grüße aus  Oberbayern
Tim (RettungsTim)

Wernieman

Vergiss erst mal FHEM und nimm erstmal einfach "nur" meinen zitierten Code in nginx (Mach von Deiner Config eine Sicherung!)

Bist Du Dir Sicher, das die Portweiterleitung auf den richtigen Rechner zeigt?
- Bitte um Input für Output
- When there is a Shell, there is a Way
- Wann war Dein letztes Backup?

Wie man Fragen stellt: https://tty1.net/smart-questions_de.html

HoTi

#11
das Praktische an Proxmox ist man baut sich schnell eine neue VM.

also wieder alles installiert und frei gegeben:

*bevor die Frage kommt: Ja die Datei mit dem Datum ist da!*

jetzt hat sich die Fehlermeldung verändert:

Failed authorization procedure. xxx.xxxx.net (http-01): urn:ietf:params:acme:error:unauthorized :: The client lacks sufficient authorization :: Invalid response from http://xxx.xxx.net/.well-known/acme-challenge/xxxxx: "<html>\r\n<head><title>404 Not Found</title></head>\r\n<body bgcolor=\"white\">\r\n<center><h1>404 Not Found</h1></center>\r\n<hr><center>"

IMPORTANT NOTES:
- The following errors were reported by the server:

   Domain: xxx.xxx.net
   Type:   unauthorized
   Detail: Invalid response from
Viele Grüße aus  Oberbayern
Tim (RettungsTim)

Wernieman

#12
Wie rufst Du letsencrypt auf?

Was er eindeutig sagt:
Zitathttp://xxx.xxx.net/.well-known/acme-challenge/xxxxx: ".... 404 Not Found

Er findet das "Geheimnis" nicht. Du bist Dir sicher, das der oben genannte Zugriff von außen (Wichtig: außen!) auch wirklich funktioniert?

p.s.:
Wie häufig ändert sich Deine IP-Adresse? Wie aktuell ist dann Dein DNS-Record?

Letsencrypt fragt mit mehreren Rechnern ab und da die in der Welt verteilt sind, kann es bei zu schnellen Änderungen dazu führen, das es eben nicht aktuell ist.
- Bitte um Input für Output
- When there is a Shell, there is a Way
- Wann war Dein letztes Backup?

Wie man Fragen stellt: https://tty1.net/smart-questions_de.html

HoTi

#13
Jeden Tag wird getrennt. Das kann ich aber ändern, ich meine das das die Telekom nicht mehr verlangt.

ich bin bei der Arbeit somit das das hier von außen! und gestern Abend habe ich es mit dem Handy getestet (wlan off)

ich habe Zugriff von Außen. Es ist ja auch eine 404 Seite von nginx "404 Not Found nginx/1.10.3"


Ich habe es noch nicht ganz verstanden. Das Verzeichnis /acme-challenge/ existiert nicht. Wie und wann wird das angelegt?
Viele Grüße aus  Oberbayern
Tim (RettungsTim)

Wernieman

1. Wo siehst Du in Deiner Antwort das: "nginx/1.10.3"??
2. Das acme-challenge wird von letsencrypt angelegt und anschließend auch wieder aufgeräumt.
3. Geb uns bi8tt mal Deinen "letsencrypt-Aufruf" ...

Und .. auf welchem Betriebsystem mit welcher letsencrypt-Version?
- Bitte um Input für Output
- When there is a Shell, there is a Way
- Wann war Dein letztes Backup?

Wie man Fragen stellt: https://tty1.net/smart-questions_de.html