nginx HTTPS, що обслуговується з тим же конфігурацією, що і 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
  }
}

Відповіді:


262

Ви можете об'єднати це в один серверний блок так:

server {
    listen 80;
    listen 443 default_server ssl;

    # other directives
}

Офіційний How-To


6
Ах, я не мав уявлення, що nginx був досить розумним, щоб ігнорувати директиви SSL, якщо їх завантажували через порт 80. Дивовижно!
ceejayoz

72
nginx - це всі види WIN.
Jauder Ho

5
і якщо у вас є кілька сайтів на одному сервері, варто згадати, що "за замовчуванням" не є обов'язковим
luchaninov

4
Так елегантно боляче ...
Alix Axel

3
тут не працює ... "Простий HTTP-запит було надіслано до порту HTTPS"
gcstr

87

Щоб уточнити прийняту відповідь, потрібно пропустити

SSL on;

і вам просто потрібно наступне для версії nginx після 0.8.21

listen 443 ssl;

Довідка:

Документи Nginx - Налаштування єдиного сервера HTTP / HTTPS


2
Дякую! Я не міг зрозуміти, чому нічого на http не працює. Видалення SSL увімкнено; працювали.
Кріс Каммінгс

27

Я не знаю способу, як ви пропонуєте, але, безумовно, є простий і бездоганний спосіб.

Перенесіть загальні налаштування сервера в окремий файл, тобто "serverFoo.conf", а потім includeрозділіть його окремими server {}блоками:

server {
    listen 80;
    include serverFoo.conf;
}
server {
    listen 443 ssl;
    include serverFoo.conf;
}

2
+1 = працює для мене. (Не вдалося змусити його працювати з іншим методом.)

Крім того, інший приклад не враховує "proxy_pass", якщо він працює як балансир навантаження.
Майк Перселл

Цей варіант чудовий, якщо ваш номер server_nameвідрізняється для кожного порту
iDev247

5
Не використовуйте ssl, використовуйте listen 443 ssl;зараз.
небезпека89

Це здається єдиним рішенням, яке працює з останнім 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;
користувач147787

4

Просто додати до публікації Ігоря / Жадера, якщо ви слухаєте певний IP, ви можете використовувати:

listen xxx.xxx.xxx.xxx;
listen xxx.xxx.xxx.xxx:443 default ssl;
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.