Umożliwia szyfrowanie za pomocą odwrotnego proxy nginx

45

Wprowadzenie

Mam serwer deweloperów (obecnie działający pod kontrolą Ubuntu 14.04 LTS), z którego korzystam już od jakiegoś czasu do hostowania różnych narzędzi programistycznych na różnych portach. Ponieważ porty mogą być trudne do zapamiętania, postanowiłem używać portu 80 dla wszystkich moich usług i przekierowywać porty wewnętrznie, na podstawie nazwy hosta.

Zamiast pisać domain.com:5432, mogę po prostu uzyskać do niego dostęp przez sub.domain.com

Na przykład aplikacja X, która używa portu 7547 i działa na sub.domain.com, ma następującą konfigurację nginx:

upstream sub {
    server 127.0.0.1:7547;
}

server {
    listen 80;
    server_name sub.domain.com www.sub.domain.com;
    access_log /var/log/nginx/sub.log combined;
    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_pass http://127.0.0.1:7547;
            proxy_set_header Authorization "";
    }
}

Pytanie

Biorąc pod uwagę obecną strukturę konfiguracji, którą wybrałem, czy można korzystać z letsencrypt i uruchamiać różne usługi pod https?

0x450
źródło
3
Napisałem post na blogu na ten temat: tom.busby.ninja/letsecnrypt-nginx-reverse-proxy-no-downtime
Tom Busby

Odpowiedzi:

81

Tak, możesz mieć żądania proxy nginx do serwerów HTTP, a następnie samodzielnie odpowiadać na klientów przez HTTPS. Robiąc to, będziesz chciał mieć pewność, że połączenie proxy nginx <-> jest mało prawdopodobne, aby ktoś cię obwąchał. Bezpieczne podejścia mogą obejmować:

  • proxy do tego samego hosta (tak jak Ty)
  • proxy do innych hostów za twoją zaporą ogniową

Proxy do innego hosta w publicznym Internecie raczej nie będzie wystarczająco bezpieczne.

Oto instrukcje dotyczące uzyskiwania certyfikatu Let's Encrypt przy użyciu tego samego serwera WWW, którego używasz jako serwera proxy.

Żądanie początkowego certyfikatu od Let's Encrypt

Zmodyfikuj serverklauzulę, aby umożliwić obsługę podkatalogu .well-knownz katalogu lokalnego, np .:

server {
    listen 80;
    server_name sub.domain.com www.sub.domain.com;
    […]
    location /.well-known {
            alias /var/www/sub.domain.com/.well-known;
    }

    location / {
        # proxy commands go here
        […]
    }
}

http://sub.domain.com/.well-known to tam serwery Let's Encrypt będą szukać odpowiedzi na wyzwania, które stwarza.

Następnie możesz użyć klienta certbot, aby zażądać certyfikatu od Let's Encrypt przy użyciu wtyczki webroot (jako root):

certbot certonly --webroot -w /var/www/sub.domain.com/ -d sub.domain.com -d www.sub.domain.com

Twój klucz, certyfikat i łańcuch certyfikatów zostaną teraz zainstalowane w /etc/letsencrypt/live/sub.domain.com/

Konfigurowanie nginx do używania twojego certyfikatu

Najpierw utwórz nową klauzulę serwera:

server {
    listen 443 ssl;

    # if you wish, you can use the below line for listen instead
    # which enables HTTP/2
    # requires nginx version >= 1.9.5
    # listen 443 ssl http2;

    server_name sub.domain.com www.sub.domain.com;

    ssl_certificate /etc/letsencrypt/live/sub.domain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/sub.domain.com/privkey.pem;

    # Turn on OCSP stapling as recommended at 
    # https://community.letsencrypt.org/t/integration-guide/13123 
    # requires nginx version >= 1.3.7
    ssl_stapling on;
    ssl_stapling_verify on;

    # Uncomment this line only after testing in browsers,
    # as it commits you to continuing to serve your site over HTTPS
    # in future
    # add_header Strict-Transport-Security "max-age=31536000";

    access_log /var/log/nginx/sub.log combined;

    # maintain the .well-known directory alias for renewals
    location /.well-known {
        alias /var/www/sub.domain.com/.well-known;
    }

    location / {
        # proxy commands go here as in your port 80 configuration
        […]
    }
}

Przeładuj nginx:

service nginx reload

Sprawdź, czy HTTPS działa teraz, odwiedzając https://sub.domain.comiw https://www.sub.domain.comswojej przeglądarce (i innych przeglądarkach, które chcesz wesprzeć) i sprawdzając, czy nie zgłaszają błędów certyfikatów.

Zalecane: przejrzyj także raymii.org: Silne zabezpieczenia SSL na nginx i przetestuj swoją konfigurację w SSL Labs .

(Zalecane) Przekieruj żądania HTTP do HTTPS

Gdy potwierdzisz, że Twoja witryna działa z https://wersją adresu URL, zamiast umożliwić niektórym użytkownikom wyświetlanie niezabezpieczonych treści, ponieważ do nich podeszli http://sub.domain.com, przekieruj ich do wersji HTTPS witryny.

Zamień całą serverklauzulę portu 80 na :

server {
    listen 80;
    server_name sub.domain.com www.sub.domain.com;
    rewrite     ^   https://$host$request_uri? permanent;
}

Powinieneś teraz również odkomentować ten wiersz w konfiguracji portu 443, aby przeglądarki pamiętały nawet o nie wypróbowaniu wersji HTTP strony:

add_header Strict-Transport-Security "max-age=31536000";

Automatycznie odnów swój certyfikat

Możesz użyć tego polecenia (jako root), aby odnowić wszystkie certyfikaty znane dla certbota i ponownie załadować nginx przy użyciu nowego certyfikatu (który będzie miał tę samą ścieżkę, co istniejący certyfikat):

certbot renew --renew-hook "service nginx reload"

certbot podejmie próbę odnowienia certyfikatów, które mają więcej niż 60 dni, więc bezpieczne (i zalecane!) jest uruchamianie tego polecenia bardzo regularnie i automatycznie, jeśli to w ogóle możliwe. Na przykład możesz wprowadzić następujące polecenie /etc/crontab:

# at 4:47am/pm, renew all Let's Encrypt certificates over 60 days old
47 4,16   * * *   root   certbot renew --quiet --renew-hook "service nginx reload"

Możesz przetestować odnowienia w trybie „na sucho”, który skontaktuje się z serwerami pomostowymi Let's Encrypt, aby wykonać prawdziwy test kontaktu z Twoją domeną, ale nie zapisze wynikowych certyfikatów:

certbot --dry-run renew

Lub możesz wymusić wcześniejsze odnowienie za pomocą:

certbot renew --force-renew --renew-hook "service nginx reload"

Uwaga: możesz uruchamiać na sucho tyle razy, ile chcesz, ale prawdziwe odnowienia podlegają ograniczeniom prędkości Let's Encrypt .

zakłopotanie
źródło
Twoje rozwiązanie wydaje mi się nie działać. Mam w zasadzie tę samą konfigurację. Działa dla goopen.tk, ale nie www.goopen.tk
Alko
3
@ Alko, instrukcje odpowiedzi są poprawne i obejmują ten problem. Korzystając z certbotdowolnego innego narzędzia, nie można zapomnieć o określeniu domeny do działania zarówno w formacie www, jak i innym niż www.
Paulo Coghi
Poniżej location /.well-knownmusisz opuścić .well-knownścieżkę. Użyj alias /var/www/sub.domain.com, niealias /var/www/sub.domain.com/.well-known
gldraphael
1
Czy ktoś może mi wyjaśnić, dlaczego chcesz użyć „przepisać ^ https: // $ host $ request_uri? Permanent;” tutaj zamiast „return 301 https: // $ server_name $ request_uri;”
ZaxLofful,
Odkryłem, że potrzebowałem cytatów na ścieżce w miejscu. location '/.well-known' {. Nie jestem pewien, czy jest to wersja, czy tylko moja konfiguracja, ale na wypadek, gdyby ktoś utknął.
Frank V
2

Tak, możesz użyć nginxjako punktu końcowego https i współpracować z backendami za pośrednictwem http. Na przykład moja konfiguracja:

server {
        server_name host;
        listen 443 ssl;
...
 location /svn/ {
            auth_ldap off;

            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_pass http://localhost:1080/svn/;
            proxy_redirect http://localhost:1080/ https://host/;
        }
...
}

Ale jak wiem, z szyfrowaniem musimy wskazać wszystkie subdomeny, gdy otrzymasz certyfikat, a jeśli to jest problem, wybierz adres URL https://host/servicezamiasthttps://service.host

Fghj
źródło