Chcę przepisać wszystkie żądania HTTP na moim serwerze internetowym na żądania https, zacząłem od następujących czynności:
serwer { słuchaj 80; Lokalizacja / { przepisać ^ (. *) https: //mysite.com$1 permanent; } ...
Jednym z problemów jest to, że usuwa wszystkie informacje z subdomeny (np. Node1.mysite.com/folder). Jak mogę przepisać powyższe, aby przekierować wszystko do https i utrzymać subdomenę?
Odpowiedzi:
Prawidłowy sposób w nowych wersjach nginx
Okazało się, że moja pierwsza odpowiedź na to pytanie była w pewnym momencie poprawna, ale zmieniła się w kolejną pułapkę - aby być na bieżąco, sprawdź opodatkowanie pułapki przepisania
Zostałem poprawiony przez wielu użytkowników SE, więc zasługa należy do nich, ale co ważniejsze, oto poprawny kod:
źródło
$host
zamiast,$server_name
jeśli używasz subdomen.UWAGA: Najlepszym sposobem na to jest https://serverfault.com/a/401632/3641 - ale powtórzono tutaj:
W najprostszym przypadku twój host zostanie ustawiony jako usługa, do której chcesz je wysłać - spowoduje to przekierowanie 301 do przeglądarki i adres URL przeglądarki zostanie odpowiednio zaktualizowany.
Poniżej znajduje się poprzednia odpowiedź, która jest nieefektywna z powodu wyrażenia regularnego, prosty 301 jest świetny, jak pokazuje @kmindi
Używam nginx 0.8.39 i nowszych, i użyłem następujących:
Wysyła stałe przekierowanie do klienta.
źródło
Myślę, że najlepszym i jedynym sposobem powinno być użycie HTTP 301 Przeniesione Trwale przekierowanie w następujący sposób:
HTTP 301 Przeniesiony stałe przekierowania jest najbardziej skuteczne, ponieważ nie ma regex być ocenione, zgodnie z wymienionymi pitfails .
Nowy przeniesiony HTTP 308 na stałe zachowuje metodę żądania i jest obsługiwany przez główne przeglądarki . Na przykład użycie
308
uniemożliwia przeglądarkom zmianę metody żądania zPOST
naGET
dla żądania przekierowania.Jeśli chcesz zachować nazwę hosta i subdomenę, to jest właśnie ten sposób.
To nadal działa, jeśli nie masz DNS , ponieważ używam go również lokalnie. Proszę na przykład o
http://192.168.0.100/index.php
i zostaniesz przekierowany do dokładniehttps://192.168.0.100/index.php
.Używam
listen [::]:80
na moim hoście, ponieważbindv6only
ustawiłemfalse
, więc wiąże się również z gniazdem ipv4. zmień na,listen 80
jeśli nie chcesz IPv6 lub chcesz powiązać gdzie indziej.Rozwiązanie firmy Saif Bechan korzysta z tego,
server_name
który w moim przypadku jest hostem lokalnym, ale nie jest osiągalny przez sieć.Rozwiązanie Michaela Neale'a jest dobre, ale według pułapek istnieje lepsze rozwiązanie z przekierowaniem 301;)
źródło
W bloku serwera możesz również wykonać następujące czynności:
źródło
Powyższe nie działało w przypadku tworzenia nowych subdomen przez cały czas. np. AAA.example.com BBB.example.com dla około 30 subdomen.
W końcu otrzymałem konfigurację działającą z następującymi elementami:
źródło
301 https://*/
lub przedwcześnie anuluje żądanie w innych odpowiedziach tutaj.server_name _;
z$host
odpowiedzią, która załatwiła sprawę. +1_
rzeczywistej domeny, np..domain.com
Miałem dwa serwery, a nginx przypadkowo przekierował jeden z moich serwerów na serwer domyślny.Dawno, dawno temu zamieściłem komentarz do poprawnej odpowiedzi z bardzo ważną korektą, ale uważam, że konieczne jest podkreślenie tej korekty we własnej odpowiedzi. Żadna z poprzednich odpowiedzi nie jest bezpieczna w użyciu, jeśli w dowolnym momencie skonfigurowałeś niezabezpieczony HTTP i oczekujesz treści użytkownika, masz formularze, hostujesz interfejs API lub skonfigurowałeś dowolną stronę internetową, narzędzie, aplikację lub narzędzie do komunikowania się z twoją witryną.
Problem występuje, gdy
POST
żądanie jest wysyłane do serwera. Jeśli odpowiedź serwera z prostym30x
przekierowaniem zawartość POST zostanie utracona. Dzieje się tak, że przeglądarka / klient uaktualni żądanie do SSL, ale obniży jePOST
doGET
żądania. TePOST
parametry zostaną utracone i nieprawidłowe żądanie zostanie wykonana na serwerze.Rozwiązanie jest proste. Musisz użyć
HTTP 1.1 307
przekierowania. Jest to szczegółowo opisane w RFC 7231 S6.4.7:Rozwiązaniem, zaadaptowanym z przyjętego rozwiązania, jest użycie
307
w kodzie przekierowania:źródło
Udało mi się to zrobić w następujący sposób:
https://stackoverflow.com/a/36777526/6076984
źródło
Używam ngnix za AWS ELB. ELB rozmawia z ngnix przez http. Ponieważ ELB nie ma możliwości wysyłania przekierowań do klientów, sprawdzam nagłówek X-Forwarded-Proto i przekierowuję:
źródło
Jeśli
return 301 https://$host$request_uri;
domyślną odpowiedzią jest port 80, serwer może prędzej czy później uzyskać listę otwartych serwerów proxy [1] i zacząć być wykorzystywany do wysyłania ruchu w inne miejsce w Internecie. Jeśli twoje dzienniki wypełnią się takimi komunikatami, to wiesz, że to się stało:Problem polega na tym
$host
, że wywoła echo wszystkiego, co przeglądarka wyśle wHost
nagłówku, a nawet nazwę hosta z wiersza otwierającego HTTP, na przykład:Z powodu tego problemu niektóre inne odpowiedzi tutaj zalecają użycie
$server_name
zamiast$host
.$server_name
zawsze ocenia się co ty umieścić wserver_name
deklaracji. Ale jeśli masz wiele subdomen lub używasz symbolu wieloznacznego, to nie zadziała, ponieważ$server_name
używa tylko pierwszego wpisu poserver_name
deklaracji, a co ważniejsze, po prostu wyśle echo znaku zastępczego (nie rozwija go).Jak więc obsługiwać wiele domen przy jednoczesnym zachowaniu bezpieczeństwa? W moich własnych systemach poradziłem sobie z tym dylematem, najpierw wymieniając
default_server
blok, który nie używa$host
, a następnie wymieniając blok symboli wieloznacznych, który:(Możesz również podać więcej niż jedną domenę w drugim bloku).
Dzięki tej kombinacji niedopasowane domeny zostaną przekierowane gdzieś na stałe (zawsze
example.com
), a domeny, które pasują do Twojej, trafią we właściwe miejsce. Twój serwer nie będzie przydatny jako otwarty serwer proxy, więc nie będziesz przyciągał problemów.Jeśli czujesz się jak w domu, przypuszczam, że możesz również
default_server
dopasować blok do żadnej z twoich legalnych domen i podać coś obraźliwego. . . .[1] Technicznie „proxy” jest niewłaściwym słowem, ponieważ twój serwer nie wychodzi i nie spełnia wymagań klientów, po prostu wysyła przekierowanie, ale nie jestem pewien, jakie byłoby właściwe słowo. Nie jestem również pewien, jaki jest cel, ale wypełnia on dzienniki hałasem oraz zużywa procesor i przepustowość, więc równie dobrze możecie położyć temu kres.
źródło
Wygląda na to, że nikt tak naprawdę nie miał 100% racji. Aby mieć port 80 wnioski pójść do ich 443 ekwiwalentów na cały serwer, trzeba użyć wysłuchać dyrektywą, nie dyrektywy server_name określić catch-all nazwy. Zobacz także https://nginx.org/en/docs/http/request_processing.html
I upewnij się, że sprawdziłeś, co jest już w /etc/nginx/conf.d/, ponieważ najczęściej miałem problemy z tym, że default.conf zwrócił jakiś istniejący vhost. Moja kolejność pracy z problemami nginx zawsze zaczyna się od przeniesienia domyślnego pliku, umieszczając go z powrotem, komentując wiersz po wierszu, aby zobaczyć, gdzie idzie źle.
źródło
źródło