HTTPS nginx, работающий с той же конфигурацией, что и HTTP

195

Есть ли способ разделить директивы конфигурации между двумя server {}блоками nginx ? Я бы хотел избежать дублирования правил, так как HTTPS и HTTP-контент моего сайта обслуживаются с одинаковыми настройками.

В настоящее время это так:

server {
  listen 80;
  ...
}

server {
  listen 443;

  ssl on; # etc.
  ...
}

Могу ли я сделать что-то вроде:

server {
  listen 80, 443;
  ...

  if(port == 443) {
    ssl on; #etc
  }
}
ceejayoz
источник

Ответы:

262

Вы можете объединить это в один блок сервера следующим образом:

server {
    listen 80;
    listen 443 default_server ssl;

    # other directives
}

Официальный How-To

Джодер Хо
источник
6
Ах, я понятия не имел, что nginx достаточно умен, чтобы игнорировать директивы SSL при загрузке через порт 80. Круто!
ceejayoz
72
nginx это все виды WIN.
Джодер Хо
5
и если у вас есть несколько сайтов на одном сервере, стоит упомянуть, что «дефолт» не обязателен
Лучанинов
4
Так элегантно больно ...
Аликс Аксель
3
здесь не работает ... "
Простой
87

Чтобы уточнить принятый ответ, нужно опустить

SSL on;

и вам просто нужно следующее для версии nginx после 0.8.21

listen 443 ssl;

Ссылка:

Nginx Docs - настройка одного HTTP / HTTPS-сервера

Шон Тан
источник
2
Спасибо! Я не мог понять, почему ничего на http не работает. Удаление SSL включено; работал.
Крис Каммингс
27

Я не знаю, как вы предлагаете, но, конечно, есть простой и понятный способ.

Переместите общие настройки сервера в отдельный файл, то есть «serverFoo.conf», а затем includeв отдельные server {}блоки, например:

server {
    listen 80;
    include serverFoo.conf;
}
server {
    listen 443 ssl;
    include serverFoo.conf;
}
DWC
источник
2
+1 = у меня работает. (Не удалось заставить его работать с другим методом.)
Кроме того, другой пример не учитывает 'proxy_pass', если действует как балансировщик нагрузки.
Майк Перселл,
Этот вариант server_name
хорош,
5
Не используйте ssl, используйте listen 443 ssl;сейчас один.
danger89
Это, кажется, единственное решение, которое работает с недавним nginx 1.10.1. По некоторым причинам две listenстроки не интерпретируются правильно, но перемещение их по отдельности server{}исправляет это.
Артур Бодера
9

Расширяя уже полезные ответы, вот более полный пример:

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;
}
Джонатан
источник
2
Я знаю , что это довольно старый ответ, но так как это очень полный , я просто хотел бы отметить, для тех , кто может использовать его , что вы должны отключить протокол SSLv3 , как его уязвимым для пуделя уязвимости: disablessl3.com Вместо этого используйте: ssl_protocols TLSv1 TLSv1 .1 TLSv1.2;
user147787
4

Просто чтобы добавить в пост Игоря / Джодера, если вы слушаете конкретный IP, вы можете использовать:

listen xxx.xxx.xxx.xxx;
listen xxx.xxx.xxx.xxx:443 default ssl;
Мэтт Босток
источник