Очень часто необходимо разместить сразу несколько HTTPS сайтов с разными сертификатами на одном IP-адресе, однако большинство хостеров заявляют, что это невозможно физически и в таком случае требуется покупать очень дорогой wildcard-сертификат. В данном HOWTO мы развенчаем этот миф с использованием веб-сервера nginx и технологии SNI.
Введение
Для реализации задуманного нам потребуются:
- сервер с root-доступом и установленным nginx версии 0.8 и выше (рекомендуется 1.4.x);
- сертификаты для нескольких доменов.
Если у вас веб-сервер не nginx, а например Apache или lighttpd, то вы не сможете разместить несколько HTTPS сайтов на одном IP с использованием технологии SNI, поэтому установите перед ними nginx в качестве фронтенда.
Далее мы будем считать, что у вас имеется хотя бы базовый опыт администрирования веб-сервера nginx.
Установка сертификатов
Не имеет значение какие у вас сертификаты и где они будут расположены, но мы рекомендуем разместить все сертификаты в отдельном каталоге, например, /etc/keys/.
На все сертификаты и их приватные (закрытые) ключи следует установить владельца и группу root:root, а также права доступа chmod 600 для того, чтобы никто не смог похитить закрытую часть ключа.
Первоначальная инициализация nginx всегда выполняется с правами root, поэтому для сервера не будет проблемой считать конфигурационные файлы и сертификаты.
В нашем примере мы рассмотрим сертификаты srv1_example_org.crt, srv2_example_org.crt и их закрытые ключи srv1_example_org.key и srv2_example_org.key соответственно. Каждый выдан только для своего домена (srv1.example.org и srv2.example.org).
Настройка HTTPS Virtual Hosts
Создаём в каталоге /etc/nginx/sites-available/ конфиги для наших доменов srv1.example.org и srv2.example.org: srv1.conf и srv2.conf.
Листинг файла srv1.conf:
upstream backend-srv1 {server unix:/var/run/php5-srv1.sock;}
server {
listen 80;
server_name www.srv1.example.org srv1.example.org;
access_log /var/log/nginx/srv1.log;
error_log /var/log/nginx/srv1_error.log;
rewrite ^(.*) https://srv1.example.org$1 permanent;
server_tokens off;
}
server {
listen 443 ssl;
ssl on;
ssl_certificate /etc/keys/srv1_example_org.crt;
ssl_certificate_key /etc/keys/srv1_example_org.key;
ssl_session_timeout 5m;
ssl_protocols SSLv2 SSLv3 TLSv1;
ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
ssl_prefer_server_ciphers on;
server_name srv1.example.org;
root /home/srv1/www;
access_log /var/log/nginx/srv1.log;
error_log /var/log/nginx/srv1_error.log;
index index.php;
rewrite_log on;
server_tokens off;
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass backend-srv1;
}
}
Листинг файла srv2.conf:
upstream backend-srv2 {server unix:/var/run/php5-srv2.sock;}
server {
listen 80;
server_name www.srv2.example.org srv2.example.org;
access_log /var/log/nginx/srv2.log;
error_log /var/log/nginx/srv2_error.log;
rewrite ^(.*) https://srv2.example.org$1 permanent;
server_tokens off;
}
server {
listen 443 ssl;
ssl on;
ssl_certificate /etc/keys/srv2_example_org.crt;
ssl_certificate_key /etc/keys/srv2_example_org.key;
ssl_session_timeout 5m;
ssl_protocols SSLv2 SSLv3 TLSv1;
ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
ssl_prefer_server_ciphers on;
server_name srv2.example.org;
root /home/srv2/www;
access_log /var/log/nginx/srv2.log;
error_log /var/log/nginx/srv2_error.log;
index index.php;
rewrite_log on;
server_tokens off;
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass backend-srv2;
}
}
Перезапустите веб-сервер:
sudo service nginx restart
На этом настройка завершена. Теперь nginx будет использовать разные сертификаты для сайтов srv1.example.org и srv2.example.org, а также выполнять принудительное перенаправление (редирект) с HTTP версии на HTTPS с кодом 301 (moved permanently).