Let's Encrypt und nginx Reverse Proxy

Begonnen von larimow, 14 August 2018, 01:21:28

Vorheriges Thema - Nächstes Thema

larimow

Moin in die Runde,

gleich vorweg, ich weiß, dass dieses Thema bereits ausgiebig besprochen wurde, nach stundenlangem herumprobieren, Tutorials durchforsten und Haare raufen sehe ich trotzdem keinen anderen Ausweg, als hier zu fragen.

Zum Problem:
Ich betreibe FHEM auf einem Raspi, habe einen Apache Webserver eingerichtet, mit ddclient eine Weiterleitung eingerichtet und über Let's Encrypt ein Zertifikat erhalten.
Für die Einrichtung des Fernzugriffs habe ich mich größtenteils an dieses Tutorial gehalten, mit dem oben genannten Unterschied, dass DynDNS vom ddclient ausgeht (dieses Tutorial habe ich genutzt) und nicht von der Fritzbox.

So weit, so gut. Leider passiert nicht das, was ich möchte. Ich habe in der Fritzbox eine Portweiterleitung auf 8083 eingerichtet. Gebe ich http://url:port/fhem ein, lande ich ungesichert auf der FHEM Oberfläche (nach der Passwortabfrage). verwende ich https://url:port/fhem lande ich nirgendwo.
Nutze ich einfach nur https://url, lande ich irgendwie auf dem apache webserver und könnte mir meine CUL files herunterladen, zumindest aber gesichert durch das Let's Encrypt Zertifikat.
Als Portfreigaben habe ich nur einen Port, der auf 8083 weiterleitet.

Ich sehe im Moment den Wald vor lauter Bäumen nicht mehr. Irgendwo ist in meinem System der Wurm drin. Der Fehler liegt vermutlich irgendwo in der fehlerhaften Weiterleitung auf dem Apache aber mein Wissen reicht nicht aus, um das zu präzisieren.

Jede Hilfe ist willkommen, weitere Informationen liefere ich gerne auf Anfrage nach.

Gute Nacht
Sebastian

micky0867

Zitat von: larimow am 14 August 2018, 01:21:28
... mit ddclient eine Weiterleitung eingerichtet ...
Das ist keine Weiterleitung, sondern der DDNS-Name zeigt auf die externe IP deiner Fritzbox.

Zitat von: larimow am 14 August 2018, 01:21:28
...Ich habe in der Fritzbox eine Portweiterleitung auf 8083 eingerichtet. ...
Falsch! Die Weiterleitung in der Fritze muss von Port 443 auf Port 443 gehen!
Der ReverseProxy-Teil deines Apache macht dann die "Weiterleitung" von 443 auf 8083 für die Location /fhem:
   
<Location /fhem>
        ProxyPass http://localhost:8083/fhem
        ProxyPassReverse http://localhost:8083/fhem
    </Location>


Zitat von: larimow am 14 August 2018, 01:21:28
...zumindest aber gesichert durch das Let's Encrypt Zertifikat. ...
Das Zertifikat sichert gar nichts.
Es ermöglicht nur (und zwar für jeden Client) eine verschlüsselte Verbindung ohne Fehlermeldungen deines Browsers.

Du solltest dich noch mehr mit der Materie befassen, bevor du deine FHEM-Installation ungeschützt dem Internet aussetzt.


Der beste Schutz ist eine VPN-Verbindung über deine Fritzbox. Das ist einfacher und effektiver.

Micky

larimow

Moin Micky,

danke schon mla für die Antwort.

Ich habe mich teilweise etwas falsch ausgedrückt. Mir ist bewusst, dass ich durch das Zertfikat nicht auf magische Art und Weise eine weitere Sicherheitsstufe ins System bringe. Alles steht und fällt mit einem sicheren Passwort. Mir ist auch klar, dass VPN sicherer wäre, ich würde jedoch gerne weiterhin apps wie andFHEM vom Handy aus nutzen und bin daher den Weg über DynDNS gegangen.

Die Weiterleitung habe ich nun auf 443 geändert, leider jedoch bisher ohne Erfolg. "The requested URL /fhem was not found on this server" ist das einzige, was ich zurück bekomme. Ich werde mich wohl erstmal wieder tiefer mit den Grundlagen beschäftigen müssen. Als ich das System zum ersten mal aufgesetzt hatte, habe ich einen nginx-Server als Reverse-Proxy genutzt. Das ging ohne Probleme. Da ich das System mal grundlegend neu aufsetzen musste, wollte ich dieses mal Apache nutzen. Leidermit dem beschriebenen Erfolg.

MfG Sebastian

Wernieman

Brauchst Du denn den apache? Wenn Du die Websidefunktionalität ala apache brauchst, nimm den. Wenn nicht, nimm einen NINX.

Habe privat intern einen apache. Der Zugriff von extern geht aber über einen (passwortgeschützten) nginx. als Proxy ist nginx viel einfacher als apache.
- 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

larimow

An sich brauche ich den nicht. Habe gerade mal das Thema geändert, da ich jetzt den Weg über nginx suche. Habe mich erstmal an Tutorial gehalten.

Unterschied und damit wieder Stein des Anstoßes: ich habe die Cert-Files und den Key schon dank(?) Let's Encrypt.

SSLCertificateFile /etc/letsencrypt/live/'url'/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/'url'/privkey.pem

Nun sind diese Dateien mal wieder nicht im richtigen Format, entsprechend habe ich nach einer Konvertierung gesucht. Recherche hat das hier ergeben.

Ich habe über
openssl x509 -outform der -in /etc/letsencrypt/live/'url'/fullchain.pem -out url.crt
meine crt erzeugt und privkey.pem einfach über nano als *.key abgespeichert. 

Kurzzusammenfassung, es funktioniert nicht. systemd spuckt

Aug 14 14:27:09 fhem_pi systemd[1]: Failed to start A high performance web server and a r
Aug 14 14:27:09 fhem_pi systemd[1]: nginx.service: Unit entered failed state.
Aug 14 14:27:09 fhem_pi systemd[1]: nginx.service: Failed with result 'exit-code'.

aus, gem. Recherche heißt das, Fehler mit dem Zertifikat. Was habe ich dieses mal falsch gemacht?

Mit jedem weiteren Problem wächst zwar mein Hintergrundwissen, leider nur nicht schnell genug, um der Probleme Herr zu werden.

Ich könnte natürlich auch einfach aus self-signed Zertifikate umsteigen aber jetzt wo ich das Let's Encrypt Zertifikat schon habe wäre das auch dumm.

Danke weiterhin für die Hilfe.


kadettilac89

Zitat von: larimow am 14 August 2018, 14:36:58
SSLCertificateFile /etc/letsencrypt/live/'url'/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/'url'/privkey.pem

Kann es sein, dass die Parameter anders heißen? Oder war das ein Fehler beim Kopieren hier in den Post?

Das hier funktioniert bei mir problemlos. Kann mich nicht erinnern, dass ich vom Standard abweichen (irgendwie konvertieren) musste. Erneuerung läuft automatisch.


    ssl_certificate /etc/letsencrypt/live/<url>/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/<url>/privkey.pem;


Im Wiki ist eine Anleitung, weiß nicht wie aktuell, aber sicher als roter Faden geeignet

... edit: ach ja, poste ggf. mal deine ganze reversproxy config von nginx wenn der Tip von mir nichts bringt.

Wernieman

Du brauchst die Files von letsencrypt NICHT zu konvertieren!
- 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

larimow

#7
Moin nochmal,

ich habe es jetzt mit den originalen *.pem-Dateien versucht. Einmal mit der fullchain.pem und einmal mit cert.pem (beides Ausgaben von lets encrypt).
Selbes Ergebnis, also nginx startet nicht. Im folgenden könnt ihr meinen Code sehen, bis auf den cert-Pfad identisch mit dem Tutorial.


server {
    listen 80;
    return 301 https://$host$request_uri;
}

server {

    listen 443;
    server_name fhempi;

    # check user agent
    if ($http_user_agent ~* '(iPhone|iPod|Opera Mini|Android.*Mobile|NetFront|PSP|BlackBerry|Windows$
    set $ua_type "@mobile";
    }

    ssl_certificate           /etc/nginx/cert.pem;
    ssl_certificate_key       /etc/nginx/privkey.pem;

    ssl on;

# check user agent
    if ($http_user_agent ~* '(iPhone|iPod|Opera Mini|Android.*Mobile|NetFront|PSP|BlackBerry|Windows$
    set $ua_type "@mobile";
    }

    ssl_certificate           /etc/nginx/cert.pem;
    ssl_certificate_key       /etc/nginx/privkey.pem;

    ssl on;
    ssl_session_cache  builtin:1000  shared:SSL:10m;
    ssl_protocols  TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;
    ssl_prefer_server_ciphers on;

    access_log            /var/log/nginx/jenkins.access.log;

    location / {

      proxy_set_header        Host $host;
ssl_protocols  TLSv1 TLSv1.1 TLSv1.2;
   
ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;
    ssl_prefer_server_ciphers on;

    access_log            /var/log/nginx/jenkins.access.log;

    location / {

      proxy_set_header        Host $host;
      proxy_set_header        X-Real-IP $remote_addr;
      proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header        X-Forwarded-Proto $scheme;
      proxy_http_version      1.1;

      # Gehe zu FHEMWEB wenn kein mobiler Browser
      if ($ua_type != "@mobile"){
          proxy_pass          http://localhost:8083;
      }

      # Gehe zu FHEMWEB smallscreen wenn mobiler Browser

      proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header        X-Forwarded-Proto $scheme;
      proxy_http_version      1.1;

      # Gehe zu FHEMWEB wenn kein mobiler Browser
      if ($ua_type != "@mobile"){
          proxy_pass          http://localhost:8083;
      }
      # Gehe zu FHEMWEB smallscreen wenn mobiler Browser
      if ($ua_type = "@mobile"){
          proxy_pass          http://localhost:8084;
      }
      proxy_read_timeout  90;


      auth_basic "Restricted Content";
      auth_basic_user_file /etc/nginx/.htpasswd;

      # proxy_redirect      http://localhost:8083 https://localhost;

   }
  }


kadettilac89

Zitat von: larimow am 14 August 2018, 23:36:01
Im folgenden könnt ihr meinen Code sehen, bis auf den cert-Pfad identisch mit dem Tutorial.


server {
    listen 80;
    return 301 https://$host$request_uri;
}

server {

    listen 443;
    server_name fhempi;

    ssl_certificate           /etc/nginx/cert.pem;
    ssl_certificate_key       /etc/nginx/privkey.pem;

    ssl on;

# check user agent
    if ($http_user_agent ~* '(iPhone|iPod|Opera Mini|Android.*Mobile|NetFront|PSP|BlackBerry|Windows$
    set $ua_type "@mobile";
    }

    ssl_certificate           /etc/nginx/cert.pem;
    ssl_certificate_key       /etc/nginx/privkey.pem;

    ssl on;
    ssl_session_cache  builtin:1000  shared:SSL:10m;
    ssl_protocols  TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;
    ssl_prefer_server_ciphers on;

    access_log            /var/log/nginx/jenkins.access.log;

    location / {

      proxy_set_header        Host $host;
ssl_protocols  TLSv1 TLSv1.1 TLSv1.2;
   
ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;
    ssl_prefer_server_ciphers on;

    access_log            /var/log/nginx/jenkins.access.log;

    location / {

      proxy_set_header        Host $host;
      proxy_set_header        X-Real-IP $remote_addr;
      proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header        X-Forwarded-Proto $scheme;
      proxy_http_version      1.1;

      # Gehe zu FHEMWEB wenn kein mobiler Browser
      if ($ua_type != "@mobile"){
          proxy_pass          http://localhost:8083;
      }

      # Gehe zu FHEMWEB smallscreen wenn mobiler Browser

      proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header        X-Forwarded-Proto $scheme;
      proxy_http_version      1.1;

      # Gehe zu FHEMWEB wenn kein mobiler Browser
      if ($ua_type != "@mobile"){
          proxy_pass          http://localhost:8083;
      }
      # Gehe zu FHEMWEB smallscreen wenn mobiler Browser
      if ($ua_type = "@mobile"){
          proxy_pass          http://localhost:8084;
      }
      proxy_read_timeout  90;


      auth_basic "Restricted Content";
      auth_basic_user_file /etc/nginx/.htpasswd;

      # proxy_redirect      http://localhost:8083 https://localhost;

   }
  }



Du sagst der Code wäre identisch ... ist er nicht. Kopiere mal den Code unverändert und teste nochmal ... Dann sollte ngnix zumindest starten. Dateien sind die, die ich schon genannt hab.

Beispiel: Das "if" hat keine öffnende Klammer aber eine schließende - "{" fehlt.

# check user agent
    if ($http_user_agent ~* '(iPhone|iPod|Opera Mini|Android.*Mobile|NetFront|PSP|BlackBerry|Windows$
    set $ua_type "@mobile";
    }


Dein Ngnix gibt nicht mehr Fehler als die 3 Zeilen aus? Auch nichts in /var/log/nginx im error.log?

Wernieman

1. Lass die Certs im Letsencryptverzeichnis!
2.         ssl    on;
        ssl_certificate         /etc/letsencrypt/live/<DOMAIN>/fullchain.pem;
        ssl_certificate_key     /etc/letsencrypt/live/<DOMAIN>/privkey.pem;

- 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

larimow

Moin und danke für die Hilfe schon mal.
Ich habe das Skript nochmal neu kopiert, die Zertifikate sind noch an ihrem Fleck.

Das hier spuckt mir das Logfile aus:
2018/08/14 14:05:55 [emerg] 6449#6449: PEM_read_bio_X509_AUX("/etc/nginx/<url>.crt") failed (SSL: error:0906D06C:PEM routines:PEM_read_bio:no start line:Expecting: TRUSTED CERTIFICATE)



kadettilac89

Der Fehler sagt dass im  Zertifikat/etc/nginx/.crt die Zeile mit dem hash fehlt. Prüfe nochmal ob du die Datein so eingetragen hast wie wernieman  und ich schrieb. Wenn das passt schau ob die Dateien wirklich so vorhanden sind.

Sind das die Dateien in denen du reinkopiert hast? Wenn ja lege sie komplett neu an. Ich meine certbot renew -force ausführen

Mach auch mal ein

nginx -t

Prüft ob die nginx config Datei passt.

larimow

Es war tatsächlich ein Fehler in der Zertifikatsdatei. Ein Pfad war falsch gesetzt. Den Fehler habe ich gefunden und behoben.

Gem. nginx -t ist jetzt alles in Ordnung, die Zertifikate sind auch noch aktuell:

pi@fhem_pi:~ $ sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful


pi@fhem_pi:~ $ sudo certbot renew
Saving debug log to /var/log/letsencrypt/letsencrypt.log

-------------------------------------------------------------------------------
Processing /etc/letsencrypt/renewal/<url>.com.conf
-------------------------------------------------------------------------------
Attempting to parse the version 0.26.1 renewal configuration file found at /etc/letsencrypt/renewal/<url>.com.conf with version 0.10.2 of Certbot. This might not work.
Cert not yet due for renewal

The following certs are not due for renewal yet:
  /etc/letsencrypt/live/<url>/fullchain.pem (skipped)
No renewals were attempted.


Nun scheitert es am port binding. Ich werde gleich selbst noch recherchieren, wollte das hier nur schon mal als Statusmeldung abgeben.

nginx.service - A high performance web server and a reverse proxy server
   Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset:
enabled)
   Active: failed (Result: exit-code) since Wed 2018-08-15 21:37:37 CEST;
10min ago
     Docs: man:nginx(8)
  Process: 18907 ExecStart=/usr/sbin/nginx -g daemon on; master_process on;
(code=exited, status=1/FAILURE)
  Process: 18904 ExecStartPre=/usr/sbin/nginx -t -q -g daemon on;
master_process on; (code=exited, status=0/SUCCESS)
Main PID: 5991 (code=exited, status=0/SUCCESS)

Aug 15 21:37:36 fhem_pi nginx[18907]: nginx: [emerg] bind() to [::]:80 failed (98: Address already in use)
Aug 15 21:37:36 fhem_pi nginx[18907]: nginx: [emerg] bind() to 0.0.0.0:443 failed (98: Address already in use)
Aug 15 21:37:36 fhem_pi nginx[18907]: nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
Aug 15 21:37:36 fhem_pi nginx[18907]: nginx: [emerg] bind() to 0.0.0.0:443 failed (98: Address already in use)
Aug 15 21:37:37 fhem_pi nginx[18907]: nginx: [emerg] still could not bind()
Aug 15 21:37:37 fhem_pi systemd[1]: nginx.service: Control process exited, code=exited status=1
Aug 15 21:37:37 fhem_pi systemd[1]: Failed to start A high performance web server and a reverse proxy server.
Aug 15 21:37:37 fhem_pi systemd[1]: nginx.service: Unit entered failed state.
Aug 15 21:37:37 fhem_pi systemd[1]: nginx.service: Failed with result 'exit-code'.


Irgendwie nehme ich auch wirklich alles mit, was man so falsch machen kann...

Wernieman

Aug 15 21:37:36 fhem_pi nginx[18907]: nginx: [emerg] bind() to [::]:80 failed (98: Address already in use)
Aug 15 21:37:36 fhem_pi nginx[18907]: nginx: [emerg] bind() to 0.0.0.0:443 failed (98: Address already in use)
Aug 15 21:37:36 fhem_pi nginx[18907]: nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
Aug 15 21:37:36 fhem_pi nginx[18907]: nginx: [emerg] bind() to 0.0.0.0:443 failed (98: Address already in use)


Guck dock einfach mal nach, was auf dem Port schon läuft. als root:
netstat -lntp | grep -e 80 -e 443
- 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

kadettilac89

du hast zu Beginn Apache und Letencrypt verbunden. Mit hoher Wahrscheinlichkeit möchte Letsencryt die Apache Config nutzen und Certs requesten.

1) hast du Apache noch laufen?
2) hast du Nginx gestoppt zum Renewal? Wenn nicht blockt Nginx die Ports

Wenn dein Nginx setup funktioniert ... erst dann ... deinstallierst du letsencrypt und nutzt ein HowTo das Letsencrypt mit Nginx nutzt. Alternativ kannst Letsencrypt als Standalone aufsetzen, jedoch musst du dann jedesmal Nginx stoppen ...

Zitat von: larimow am 15 August 2018, 22:09:29
Irgendwie nehme ich auch wirklich alles mit, was man so falsch machen kann...
Weil du unterschiedliche Anleitungen nutzt, und zu viele Schritte auf einmal. Ich hätte erstmal nur Reverse Proxy konfiguriert. Wenn das läuft Letsencrypt. ... Schritt für Schritt. Aktuell sammelst du Fehler an unterschiedlichster Stelle auf.