nginx jako zwrotny serwer proxy z nadrzędnym protokołem SSL

19

Buduję serwer proxy dla wewnętrznego interfejsu API, aby umożliwić klientom łączenie się bez konieczności instalowania certyfikatów z podpisem własnym.

Klienci (zbudowani, będący własnością i używani tylko wewnętrznie) będą łączyć się za pośrednictwem protokołu SSL z pudełkiem nginx, gdzie używam XSendfile do sprawdzania poświadczeń na poziomie aplikacji (aplikacja railsowa ). Jeśli poświadczenia są prawidłowe, połączenie jest przekazywane z powrotem do nginx, gdzie używa proxy_pass do wysłania połączenia do serwera nadrzędnego.

Teraz działa to świetnie w przypadku standardowych połączeń HTTP, ale próbuję wymyślić, jak dodać nasze certyfikaty do miksu.

To pytanie jest prawie identyczne z tym , ale zawiera niezręczne wymagania dotyczące certyfikatów.

Czy jest to w ogóle możliwe w przypadku Nginx? Czy jest lepsze rozwiązanie?

Rozliczę również http od klienta -> nginx i samopodpisany certyfikat od nginx do API.

simonmaddox
źródło

Odpowiedzi:

19

Dla każdego, kto natknie się na to pytanie i chce używać nginx, możesz ustawić to jak każdy zwykły serwer proxy, a aby zaakceptować samopodpisany certyfikat z zaplecza, musisz dostarczyć wyeksportowany certyfikat pem (i być może klucz) i ustawić weryfikację ssl poza. Na przykład:

...

server {
    listen       10.1.2.3:80;
    server_name  10.1.2.3 myproxy.mycompany.com;

    location / {
         proxy_pass                    https://backend.server.ip/;
         proxy_ssl_trusted_certificate /etc/nginx/sslcerts/backend.server.pem;
         proxy_ssl_verify              off;

         ... other proxy settings
    }

Jeśli Twój bezpieczny back-end używa SNI do identyfikacji nazwy serwera z obsługą wielu hostów na parę adresów IP / portów, może być również konieczne uwzględnienie proxy_ssl_server_name on;w konfiguracji. Działa to na Nginx 1.7.0 i nowszych.

shonky użytkownik Linux
źródło
1
proxy_ssl_server_name on;było wszystkim, czego potrzebowałem, aby działało to, gdy pośredniczę w ruchu do hosta w Google App Engine za pomocą wbudowanego zarządzanego przez Google protokołu SSL! (To nie jest samopodpisany certyfikat ani nic, więc potrzebował tylko jednej linii). Dzięki za świetną radę.
XP84
Otrzymuję komunikat „brak” certyfikatu ssl dla dyrektywy „Listen ... ssl”, jeśli nie używam certyfikatu ssl. Czy możliwe jest proxy proxy bez podawania certyfikatu wstępnego?
Damien
Komentarz jest wyłączony z tematu, ponieważ dotyczy proxy pośredniczącego w http łączeniu się z upstream https. Jeśli chcesz proxy https, prawdopodobnie lepiej jest to rozwiązać jako osobne pytanie. Szybka i krótka odpowiedź brzmi: żaden Nginx nie może „nasłuchiwać” portu https bez certyfikatu i klucza prywatnego.
shonky Linux użytkownik
5

Myślę, że prawdopodobnie chcesz czegoś takiego (oczywiście uproszczonego w tym przykładzie):

worker_processes  1;
events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;
    keepalive_timeout  65;

    upstream backend {
        server mybackendserver:443;
    }

    server {
        server_name localhost;
        listen 443 ssl;
        ssl_certificate /etc/nginx/server.crt;
        ssl_certificate_key /etc/nginx/server.key;
        ssl_verify_client off;
        location / {
            proxy_pass  https://backend;
            proxy_set_header Host $http_host;
            proxy_set_header X_FORWARDED_PROTO https;
        }
    }
}

Jedyną rzeczą, którą możesz zmienić, byłoby wyraźne określenie „hosta” - jeśli na przykład nazwa hosta proxy nie była taka sama, jak nazwa hosta używana na serwerze proxy nginx.

Dżem
źródło
Z mojego zrozumienia, parametry ssl_certificate i ssl_certificate_key odnoszą się do połączenia klienta , a nie połączenia nadrzędnego. Czy tak jest w przypadku?
simonmaddox,
1
Z tego, co rozumiem, tak. W tym przykładzie klient widzi certyfikat dostarczony przez nginx. nginx widzi (i weryfikuje? Nie jestem pewien ...) dostarczony przez serwer, ale nie przekazuje go klientowi.
Jam
3

Dla każdego, kto spotka się z tym w przyszłości, ostatecznie nie użyłem do tego nginx.

Zamiast tego użyłem stunnela w „trybie klienta”. Bardzo łatwy w konfiguracji i robi dokładnie to, czego potrzebuję.

simonmaddox
źródło