zastanawiałem się, czy nginx jest w stanie obsłużyć żądania HTTP i https na tym samym porcie . [*]
To właśnie próbuję zrobić. Korzystam z serwera WWW (lighttpd) obsługującego żądania HTTP oraz programu C obsługującego określoną sekcję drzewa dokumentów za pośrednictwem protokołu https. Te dwa procesy działają na tym samym serwerze.
Na poziomie zapory mogę mieć tylko jeden port przekierowujący ruch na ten serwer . Chciałbym więc skonfigurować nginx na tym serwerze, aby nasłuchiwał żądań na jednym porcie, a następnie:
A) przekierowuje wszystkie żądania http://myhost.com/ *, aby trafiły do localhost: 8080 (gdzie nasłuchuje lighttpd)
B) jeśli użytkownik zażąda adresu URL zaczynającego się na przykład od https: // myhost.com/app, wysyła to żądanie do localhost: 8008 (program w języku C). Pamiętaj, że w takim przypadku ruch między zdalną przeglądarką a nginx musi być szyfrowany.
Czy uważasz, że to może być możliwe? Jeśli tak, to jak to zrobić?
Wiem, jak to zrobić, używając dwóch różnych portów. Wyzwaniem, przed którym stoję, jest zrobienie tego za pomocą tylko jednego portu (niestety nie mam kontroli nad konfiguracją zapory ogniowej w tym konkretnym środowisku, więc jest to ograniczenie, którego nie mogę uniknąć). Korzystanie z technik takich jak odwrotny port do przodu przez ssh w celu ominięcia zapory również nie będzie działać, ponieważ powinno to działać dla zdalnych użytkowników, którzy nie mają nic więcej niż przeglądarkę internetową i łącze internetowe.
Jeśli wykracza to poza możliwości Nginx, czy znasz jakiś inny produkt, który spełniałby te wymagania? (jak dotąd nie udało mi się skonfigurować tego z lighttpd i funtem). Wolałbym także unikać Apache (chociaż jestem gotów go użyć, jeśli jest to jedyny możliwy wybór).
Z góry dzięki, Alex
[*] Żeby było jasne, mówię o obsłudze zaszyfrowanych i nieszyfrowanych połączeń HTTP przez ten sam port. Nie ma znaczenia, czy szyfrowanie odbywa się za pośrednictwem protokołu SSL lub TLS.
Odpowiedzi:
Zgodnie z artykułem Wikipedii na temat kodów stanu, Nginx ma niestandardowy kod błędu, gdy ruch HTTP jest wysyłany do portu https (kod błędu 497)
I zgodnie z dokumentacją nginx na stronie error_page , możesz zdefiniować identyfikator URI, który będzie wyświetlany dla określonego błędu.
W ten sposób możemy utworzyć identyfikator użytkownika, do którego klienci będą wysyłani, gdy pojawi się kod błędu 497.
nginx.conf
Jednak jeśli klient zgłosi żądanie inną metodą niż GET, żądanie to zostanie przekształcone w GET. W ten sposób, aby zachować metodę żądania, za pośrednictwem której klient wszedł; używamy przekierowań przetwarzania błędów, jak pokazano w dokumentach nginx na stronie error_page
I dlatego używamy
301 =307
przekierowania.Korzystając z pokazanego tutaj pliku nginx.conf, możemy nasłuchiwać http i https na tym samym porcie
źródło
Dla tych, którzy mogą szukać:
Dodaj
ssl on;
ierror_page 497 $request_uri;
do swojej definicji serwera.źródło
ssl on;
ierror_page 497 =200 $request_uri;
do definicji serwera. Spowoduje to zmianę kodu stanu na 200.Jeśli chcesz być naprawdę sprytny, możesz użyć funkcji proxy połączenia, aby wąchać pierwszą parę bajtów przychodzącego strumienia danych i przekazać połączenie na podstawie zawartości bajtu 0: jeśli jest to 0x16 (SSL / TLS ' handshake 'byte), przekaż połączenie po stronie SSL, jeśli jest to znak alfabetyczny, wykonaj normalny HTTP. Obowiązuje mój komentarz na temat numeracji portów .
źródło
Tak, jest to możliwe, ale wymaga łatania kodu źródłowego nginx (HoverHell ma rozwiązanie bez łatania). Nginx traktuje to jako błędną konfigurację, a nie prawidłową konfigurację.
Zmienna $ ssl_session_id może być używana do różnic pomiędzy połączeniem zwykłym a ssl.
Łata przeciwko nginx-0.7.65:
Konfiguracja serwera:
źródło
Nie sądzę, żeby było coś, co mogłoby obsłużyć dwa różne protokoły na jednym porcie ...
Zastanawiam się, dlaczego możesz przesłać tylko jeden port, ale poza tym ... nie jest to idealne, ale gdybym był w twoich butach, podałbym wszystko przez https.
źródło
Nie można obsługiwać zarówno HTTP, jak i HTTPS przez ten sam port, ponieważ oba końce połączenia oczekują mówienia w określonym języku i nie są wystarczająco sprytne, aby się dowiedzieć, czy drugi koniec mówi coś innego.
Jako komentarz do odpowiedzi Wil sugerował, ty mógł używać TLS uaktualnić (wierzę nowsze wersje nginx wspierać ją, chociaż nie próbowałem), ale to nie działa HTTP i HTTPS, że po prostu działa HTTP z TLS uaktualnienia. Problemem jest nadal obsługa przeglądarek - większość przeglądarek (wciąż) nie obsługuje tego. Jeśli masz ograniczoną pulę klientów, jest to jednak możliwe.
źródło
Nie jestem pewien, jak to się robi, ale CUPSD odpowiada zarówno na HTTP, jak i https na porcie 631. Jeśli nginx nie może teraz tego zrobić, być może mogą nauczyć się, jak zespół CUPS to robi, ale CUPS jest pod GPL, więc nginx może potrzebować zmiany licencji, jeśli chce wdrożyć taką możliwość i nie może znaleźć kodu, aby to zrobić gdzie indziej.
źródło
Teoretycznie możesz mieć stronę internetową dostępną przez HTTP, która może otworzyć WebSocket na https: 443 w dowolnym miejscu. Początkowym uzgadnianiem WebSocket jest HTTP. Tak, możliwe jest stworzenie niebezpiecznie wyglądającej strony zdolnej do bezpiecznej komunikacji. Możesz to zrobić za pomocą Netty Library .
źródło
Jest to w końcu możliwe do prawidłowego wykonania od 1.15.2. Zobacz informacje tutaj .
W swoim pliku nginx.conf dodaj blok taki jak ten (poza blokiem http):
Następnie możesz utworzyć normalny blok serwera, ale nasłuchując na tych różnych portach:
W ten sposób blok strumienia może wstępnie odczytać i wykryć, czy jest to TLS, czy nie (na tym przykładzie port 8080), a następnie serwer proxy przekazuje go lokalnie do właściwego portu serwera.
źródło