Пример случая. У меня есть веб-сервер с одним IPV4-адресом. Я размещаю около 50 веб-сайтов, и только два из них имеют ssl-сертификаты. Я настроил vhosts для 2 веб-сайтов ssl, и все в порядке, за исключением одной большой проблемы - если я посещаю другие 48 сайтов с префиксом https: // (у них нет сертификатов ssl), я вижу свой последний веб-сайт с сертификатом SSL .
Можно ли запретить префикс https на сайтах без SSL? Или есть только одно решение - использовать выделенные IP-адреса. Если у меня есть выделенный IP-адрес, я использую следующую конфигурацию:
server {
listen 111.222.333.444:443 ssl;
}
Таким образом, если я использую https на веб-сайте без SSL, ничего не произойдет.
Nginx использует «сервер по умолчанию», который выбирает для обслуживания страниц, когда нет другого ближайшего совпадения. Если вы не указали используемый по умолчанию сервер, я считаю, что он использует первый из найденных (который в вашем случае является одним из ваших HTTPS-сайтов). Таким образом, вы должны иметь возможность создать сервер vhost по умолчанию с вашим IPv4-адресом для TLS (вы больше используете только TLS, а не SSL, верно?) И заставить его прослушивать IP-адрес, который будет улавливать случайные запросы HTTPS. Возможно, вам также потребуется добавить туда элемент server_name для ваших 48 незащищенных сайтов, но он может работать и без этого.
#Your catch-all HTTPS server:
server {
listen 104.218.234.204:443 default_server;
server_name ruel.in ruel.pro;
root /var/www/ruel.pro;
index index.html;
ssl on;
ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem;
ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key;
ssl_dhparam /etc/ssl/private/dhparams_4096.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
}
#Regular HTTP server
server {
listen ruel.in:80;
server_name ruel.in;
root /var/www/ruel.in;
index index.php index.html index.htm;
...
}
#Regular HTTP server
server {
listen ruel.pro:80;
server_name ruel.pro;
root /var/www/ruel.pro;
index index.php index.html index.htm;
...
}
#Your HTTPS server
server {
listen dallas.ruhnet.net:443 ssl;
server_name dallas.ruhnet.net;
...
}
Другая альтернатива - продолжайте и настройте их все с помощью HTTPS! В проекте Let's Encrypt (https://www.letsencrypt.org) вы можете бесплатно получить доверенные сертификаты для всех остальных сайтов. И это довольно просто.
Я знаком с проблемой.
Мы в основном хотим любой ценой избежать того, чтобы первое определение сервера в нашем файле конфигурации служило сервером для всех SSL-соединений. Мы все знаем, что он это делает (в отличие от http и использования конфигурации default_server, которая хорошо работает).
Это не может быть достигнуто декларативно в Nginx для SSL (пока), поэтому мы должны закодировать это с помощью IF ...
Переменная $host
это имя хоста из строки запроса или заголовка http. Переменная $server_name
- это имя серверного блока, в котором мы сейчас находимся.
Итак, если эти два не равны, вы обслужили этот блок сервера SSL для другого хоста, поэтому он должен быть заблокирован.
Мы можем реализовать это в каждом серверном блоке (конечно, с общим включением).
Код не содержит конкретных ссылок на IP-адреса или имена серверов, поэтому его можно легко повторно использовать для других конфигураций сервера без изменений.
Пример:
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
###
### Section: SSL
#
## Check if this certificate is really served for this server_name
## http://serverfault.com/questions/578648/properly-setting-up-a-default-nginx-server-for-https
if ($host != $server_name) {
#return 404 "this is an invalid request";
return 444;
}
# ...