nginx HTTPS obsługujący tę samą konfigurację co HTTP

195

Czy istnieje sposób na współdzielenie dyrektyw konfiguracyjnych przez dwa server {}bloki nginx ? Chciałbym uniknąć powielania reguł, ponieważ zawartość HTTPS i HTTP mojej witryny jest obsługiwana z taką samą konfiguracją.

Obecnie wygląda to tak:

server {
  listen 80;
  ...
}

server {
  listen 443;

  ssl on; # etc.
  ...
}

Czy mogę zrobić coś w stylu:

server {
  listen 80, 443;
  ...

  if(port == 443) {
    ssl on; #etc
  }
}
ceejayoz
źródło

Odpowiedzi:

262

Możesz połączyć to w jeden blok serwera tak:

server {
    listen 80;
    listen 443 default_server ssl;

    # other directives
}

Oficjalny poradnik

Jauder Ho
źródło
6
Ach, nie miałem pojęcia, że ​​nginx jest wystarczająco inteligentny, aby zignorować dyrektywy SSL, jeśli zostanie załadowany przez port 80. Świetnie!
ceejayoz
72
nginx to wszelkiego rodzaju WIN.
Jauder Ho
5
a jeśli masz kilka witryn na jednym serwerze, warto wspomnieć, że „domyślny” nie jest obowiązkowy
luchaninov
4
Tak elegancki, że boli ...
Alix Axel
3
tutaj nie działa ... „Zwykłe żądanie HTTP zostało wysłane do portu HTTPS”
gcstr
87

Aby wyjaśnić przyjętą odpowiedź, musisz ją pominąć

SSL on;

i potrzebujesz tylko następujących wersji dla wersji nginx po wersji 0.8.21

listen 443 ssl;

Odniesienie:

Dokumenty Nginx - Konfigurowanie pojedynczego serwera HTTP / HTTPS

Sean Tan
źródło
2
Dziękuję Ci! Nie mogłem zrozumieć, dlaczego nic na http nie działa. Usuwanie SSL włączone; pracował
Chris Cummings
27

Nie znam sposobu takiego jak sugerujesz, ale z pewnością jest to łatwy i łatwy do utrzymania sposób.

Przenieś wspólne ustawienia serwera do osobnego pliku, tj. „ServerFoo.conf”, a następnie includew osobnych server {}blokach, tak jak to:

server {
    listen 80;
    include serverFoo.conf;
}
server {
    listen 443 ssl;
    include serverFoo.conf;
}
dwc
źródło
2
+1 = działa dla mnie. (Nie można zmusić go do pracy z inną metodą.)
Również drugi przykład nie uwzględnia „proxy_pass”, jeśli działa jako moduł równoważenia obciążenia.
Mike Purcell
Ta opcja jest świetna, jeśli twój server_namejest inny dla każdego portu
iDev247
5
Nie używaj ssl na, używaj listen 443 ssl;od teraz jednego.
niebezpieczne89
Wydaje się, że jest to jedyne rozwiązanie działające z najnowszą wersją nginx 1.10.1. Z jakiegoś powodu dwie listenlinie nie są poprawnie interpretowane, ale przeniesienie ich do osobnych server{}naprawia.
Artur Bodera,
9

Poniżej obszerniejszy przykład stanowi rozwinięcie już pomocnych odpowiedzi:

server {

    # Listen on port 80 and 443
    # on both IPv4 and IPv6
    listen 80;
    listen [::]:80 ipv6only=on;
    listen 443 ssl;
    listen [::]:443 ipv6only=on ssl;

    # Set website folder
    root /path/to/your/website;

    # Enable SSL
    ssl_certificate your-cert.pem;
    ssl_certificate_key your-cert.key;
    ssl_session_timeout 5m;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv3:+EXP;
    ssl_prefer_server_ciphers on;
}
Jonathan
źródło
2
Wiem, że to dość stary odpowiedź, ale ponieważ jest to bardzo kompletny Chciałem tylko zwrócić uwagę na innych, którzy mogą wykorzystywać go, że należy wyłączyć protokół SSLv3 jak jego podatny na luki pudel: disablessl3.com Zamiast używać: ssl_protocols TLSv1 TLSv1 .1 TLSv1.2;
user147787
4

Aby dodać do posta Igora / Jaudera, jeśli słuchasz określonego adresu IP, możesz użyć:

listen xxx.xxx.xxx.xxx;
listen xxx.xxx.xxx.xxx:443 default ssl;
Matt Bostock
źródło