Настройка SSL для второй витрины в NGINX

Привет! Что имеем:
— Сервер с установкой CS-CART
— Витрина 1 с SSL-сертификатом 1
— Витрина 2 с SSL-сертификатом 2

Завел вторую витрину, все сделал по мануалам: сослался на директорию витрины 1, прописал в конфиге NGINX алиас в server_name. Для 80 порта (HTTP) все сработало — вторая витрина открывается и все хорошо. Для 443 порта такой трюк не прокатил — браузер не пускает на вторую витрину через HTTPS, потому что она пытается использовать SSL-сертификат витрины №1.

Сам конфиг

`# 80

server {
listen 10.10.10.10:80;

server_name VITRINA1.ru www.VITRINA1.ru VITRINA2.ru www.VITRINA2.ru;
charset utf-8;

index index.php index.html;
disable_symlinks if_not_owner from=$root_path;
include /etc/nginx/vhosts-includes/*.conf;
include /etc/nginx/vhosts-resources/VITRINA1.ru/*.conf;

ssi on;
set $root_path /var/www/USER/data/www/VITRINA1.ru;
root $root_path;

############################################################################

#   Сжатие
gzip on;
gzip_disable "msie6";
gzip_comp_level 6;
gzip_min_length  1100;
gzip_buffers 16 8k;
gzip_proxied any;
gzip_types text/plain application/xml application/javascript text/css text/js text/xml application/x-javascript text/javascript application/json application/xml+rss;

############################################################################

#   Прочие настройки
client_max_body_size            100m;
client_body_buffer_size         128k;
client_header_timeout           3m;
client_body_timeout             3m;
send_timeout                    3m;
client_header_buffer_size       1k;
large_client_header_buffers     4 16k;

############################################################################

access_log  /var/www/httpd-logs/VITRINA1.ru.access.log combined;
error_log   /var/www/httpd-logs/VITRINA1.ru.error.log notice;

############################################################################

error_page 598 = @backend;

############################################################################

location @backend {
    try_files $uri $uri/ /$2$3 /$3 /index.php  =404;
    #   Путь к сокету PHP-FPM
    fastcgi_pass unix:/var/www/php-fpm/USER.sock;
    #
    fastcgi_index index.php;
    fastcgi_read_timeout 360;
	fastcgi_split_path_info ^((?U).+\.ph(?:p\d*|tml))(/?.+)$;

    #   Добавляем содержимое fastcgi_params.conf
    ################################################################################
    fastcgi_param  QUERY_STRING       $query_string;
    fastcgi_param  REQUEST_METHOD     $request_method;
    fastcgi_param  CONTENT_TYPE       $content_type;
    fastcgi_param  CONTENT_LENGTH     $content_length;
    fastcgi_param  SCRIPT_NAME        $fastcgi_script_name;
    fastcgi_param  REQUEST_URI        $request_uri;
    fastcgi_param  DOCUMENT_URI       $document_uri;
    fastcgi_param  DOCUMENT_ROOT      $document_root;
    fastcgi_param  SERVER_PROTOCOL    $server_protocol;
    fastcgi_param  HTTPS              $https if_not_empty;
    fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;
    fastcgi_param  SERVER_SOFTWARE    nginx/$nginx_version;
    fastcgi_param  REMOTE_ADDR        $remote_addr;
    fastcgi_param  REMOTE_PORT        $remote_port;
    fastcgi_param  SERVER_ADDR        $server_addr;
    fastcgi_param  SERVER_PORT        $server_port;
    fastcgi_param  SERVER_NAME        $server_name;
    fastcgi_param  SCRIPT_FILENAME    $document_root$fastcgi_script_name;
    fastcgi_param  REDIRECT_STATUS    200;
    fastcgi_param  PHP_ADMIN_VALUE    "sendmail_path = /usr/sbin/sendmail -t -i -f user@user.ru";
    ################################################################################
}

############################################################################

location  / {
    index  index.php index.html index.htm;
    try_files $uri $uri/ /index.php?$args;
}

############################################################################

location ~ ^/(\w+/)?(\w+/)?api/ {
    rewrite ^/(\w+/)?(\w+/)?api/(.*)$ /api.php?_d=$3&ajax_custom=1&$args last;
    rewrite_log off;
}

############################################################################

location ~ ^/(\w+/)?(\w+/)?var/database/ {
    return 404;
}

location ~ ^/(\w+/)?(\w+/)?var/backups/ {
    return 404;
}

location ~ ^/(\w+/)?(\w+/)?var/restore/ {
    return 404;
}

location ~ ^/(\w+/)?(\w+/)?var/themes_repository/ {
    allow all;
    location ~* \.(tpl|php.?)$ {
        return 404;
    }
}

location ~ ^/(\w+/)?(\w+/)?var/ {
    return 404;
    location ~* /(\w+/)?(\w+/)?(.+\.(js|css|png|jpe?g|gz|yml|xml))$ {
        try_files $uri $uri/ /$2$3 /$3 /index.php?$args;
        allow all;
        access_log off;
        expires 1M;
        add_header Cache-Control public;
        add_header Access-Control-Allow-Origin *;
    }
}

############################################################################

location ~ ^/(\w+/)?(\w+/)?app/payments/ {
    return 404;
    location ~ \.php$ {
        return 598;
    }
}

location ~ ^/(\w+/)?(\w+/)?app/addons/rus_exim_1c/ {
    return 404;
    location ~ \.php$ {
        return 598;
    }
}

location ~ ^/(\w+/)?(\w+/)?app/ {
    return 404;
}

############################################################################

location ~* /(\w+/)?(\w+/)?(.+\.(jpe?g|jpg|ico|gif|png|css|js|pdf|txt|tar|woff|svg|ttf|eot|csv|zip|xml|yml))$ {
    access_log off;
    try_files $uri $uri/ /$2$3 /$3 /index.php?$args;
    expires max;
    add_header Access-Control-Allow-Origin *;
    add_header Cache-Control public;
}

############################################################################

location ~ ^/(\w+/)?(\w+/)?design/ {
    allow all;
    location ~* \.(tpl|php.?)$ {
        return 404;
    }
}

############################################################################

location ~ ^/(\w+/)?(\w+/)?images/ {
    allow all;
    location ~* \.(php.?)$ {
        return 404;
    }
}

############################################################################

location ~ ^/(\w+/)?(\w+/)?js/ {
    allow all;
    location ~* \.(php.?)$ {
        return 404;
    }
}

############################################################################

location ~ ^/(\w+/)?(\w+/)?init.php {
    return 404;
}

location ~* \.(tpl.?)$ {
    return 404;
}

location ~ /\.(ht|git) {
    return 404;
}

location ~* \.php$ {
    return 598 ;
}

################################################################################

}`

443

server {
listen 10.10.10.10:443;

server_name VITRINA1.ru www.VITRINA1.ru VITRINA2.ru www.VITRINA2.ru;
charset utf-8;

ssl on;
ssl_certificate "/var/www/httpd-cert/USER/VITRINA1.ru.crtca";
ssl_certificate_key "/var/www/httpd-cert/USER/VITRINA1.ru.key";
ssl_ciphers EECDH:+AES256:-3DES:RSA+AES:!NULL:!RC4;
ssl_prefer_server_ciphers on;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
add_header Strict-Transport-Security "max-age=31536000;";
ssl_dhparam /etc/ssl/certs/dhparam4096.pem;

index index.php index.html;
disable_symlinks if_not_owner from=$root_path;
include /etc/nginx/vhosts-includes/*.conf;
include /etc/nginx/vhosts-resources/VITRINA1.ru/*.conf;

ssi on;
set $root_path /var/www/USER/data/www/VITRINA1.ru;
root $root_path;

############################################################################

#   Сжатие
gzip on;
gzip_disable "msie6";
gzip_comp_level 6;
gzip_min_length  1100;
gzip_buffers 16 8k;
gzip_proxied any;
gzip_types text/plain application/xml application/javascript text/css text/js text/xml application/x-javascript text/javascript application/json application/xml+rss;

############################################################################

#   Прочие настройки
client_max_body_size            100m;
client_body_buffer_size         128k;
client_header_timeout           3m;
client_body_timeout             3m;
send_timeout                    3m;
client_header_buffer_size       1k;
large_client_header_buffers     4 16k;

############################################################################

access_log  /var/www/httpd-logs/VITRINA1.ru.access.log combined;
error_log   /var/www/httpd-logs/VITRINA1.ru.error.log notice;

############################################################################

error_page 598 = @backend;

############################################################################

location @backend {
    try_files $uri $uri/ /$2$3 /$3 /index.php  =404;
    #   Путь к сокету PHP-FPM
    fastcgi_pass unix:/var/www/php-fpm/USER.sock;
    #
    fastcgi_index index.php;
    fastcgi_read_timeout 360;
	fastcgi_split_path_info ^((?U).+\.ph(?:p\d*|tml))(/?.+)$;

    #   Добавляем содержимое fastcgi_params.conf
    ################################################################################
    fastcgi_param  QUERY_STRING       $query_string;
    fastcgi_param  REQUEST_METHOD     $request_method;
    fastcgi_param  CONTENT_TYPE       $content_type;
    fastcgi_param  CONTENT_LENGTH     $content_length;
    fastcgi_param  SCRIPT_NAME        $fastcgi_script_name;
    fastcgi_param  REQUEST_URI        $request_uri;
    fastcgi_param  DOCUMENT_URI       $document_uri;
    fastcgi_param  DOCUMENT_ROOT      $document_root;
    fastcgi_param  SERVER_PROTOCOL    $server_protocol;
    fastcgi_param  HTTPS              $https if_not_empty;
    fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;
    fastcgi_param  SERVER_SOFTWARE    nginx/$nginx_version;
    fastcgi_param  REMOTE_ADDR        $remote_addr;
    fastcgi_param  REMOTE_PORT        $remote_port;
    fastcgi_param  SERVER_ADDR        $server_addr;
    fastcgi_param  SERVER_PORT        $server_port;
    fastcgi_param  SERVER_NAME        $server_name;
    fastcgi_param  SCRIPT_FILENAME    $document_root$fastcgi_script_name;
    fastcgi_param  REDIRECT_STATUS    200;
    fastcgi_param  PHP_ADMIN_VALUE    "sendmail_path = /usr/sbin/sendmail -t -i -f user@user.ru";
    ################################################################################
}

############################################################################

location  / {
    index  index.php index.html index.htm;
    try_files $uri $uri/ /index.php?$args;
}

############################################################################

location ~ ^/(\w+/)?(\w+/)?api/ {
    rewrite ^/(\w+/)?(\w+/)?api/(.*)$ /api.php?_d=$3&ajax_custom=1&$args last;
    rewrite_log off;
}

############################################################################

location ~ ^/(\w+/)?(\w+/)?var/database/ {
    return 404;
}

location ~ ^/(\w+/)?(\w+/)?var/backups/ {
    return 404;
}

location ~ ^/(\w+/)?(\w+/)?var/restore/ {
    return 404;
}

location ~ ^/(\w+/)?(\w+/)?var/themes_repository/ {
    allow all;
    location ~* \.(tpl|php.?)$ {
        return 404;
    }
}

location ~ ^/(\w+/)?(\w+/)?var/ {
    return 404;
    location ~* /(\w+/)?(\w+/)?(.+\.(js|css|png|jpe?g|gz|yml|xml))$ {
        try_files $uri $uri/ /$2$3 /$3 /index.php?$args;
        allow all;
        access_log off;
        expires 1M;
        add_header Cache-Control public;
        add_header Access-Control-Allow-Origin *;
    }
}

############################################################################

location ~ ^/(\w+/)?(\w+/)?app/payments/ {
    return 404;
    location ~ \.php$ {
        return 598;
    }
}

location ~ ^/(\w+/)?(\w+/)?app/addons/rus_exim_1c/ {
    return 404;
    location ~ \.php$ {
        return 598;
    }
}

location ~ ^/(\w+/)?(\w+/)?app/ {
    return 404;
}

############################################################################

location ~* /(\w+/)?(\w+/)?(.+\.(jpe?g|jpg|ico|gif|png|css|js|pdf|txt|tar|woff|svg|ttf|eot|csv|zip|xml|yml))$ {
    access_log off;
    try_files $uri $uri/ /$2$3 /$3 /index.php?$args;
    expires max;
    add_header Access-Control-Allow-Origin *;
    add_header Cache-Control public;
}

############################################################################

location ~ ^/(\w+/)?(\w+/)?design/ {
    allow all;
    location ~* \.(tpl|php.?)$ {
        return 404;
    }
}

############################################################################

location ~ ^/(\w+/)?(\w+/)?images/ {
    allow all;
    location ~* \.(php.?)$ {
        return 404;
    }
}

############################################################################

location ~ ^/(\w+/)?(\w+/)?js/ {
    allow all;
    location ~* \.(php.?)$ {
        return 404;
    }
}

############################################################################

location ~ ^/(\w+/)?(\w+/)?init.php {
    return 404;
}

location ~* \.(tpl.?)$ {
    return 404;
}

location ~ /\.(ht|git) {
    return 404;
}

location ~* \.php$ {
    return 598 ;
}

################################################################################

}`

Вопрос — как запустить вторую витрину на этом же сервере с другим SSL-сертификатом? Что писать в конфиг?

Когда тестил CS Cart, то для каждой витрины свой конфиг NGINX создавал, как раз-таки из-за безопасного соединения.

Отличия в конфигах (кроме алиаса в основном) было в том, что у каждого прописан свой SSL. Таким образом работала каждая витрина со своим SSL, но не знаю, насколько костыльный этот способ.

Засунуть в один конфиг параметры SSL на две витрины у меня тоже не получилось.

Попробовал добавить сертификат от второй витрины в конфиг первой — нет. Попробовал настроить 443 порт в конфиге второй витрины — не работает. Согласен, немного нелогично.

Странно, что про этот момент вообще в мануалах нигде не говорится. Я подозреваю, что это делается через SNI или через Subject Alternative Name Certificate. Вряд ли я первый, кто настраивает вторую витрину с отдельным SSL-сертификатом.

1 лайк

Походу я слишком перемудрил.

В итоге дублировал конфиг основной витрины в конфиг дополнительной, поменял server_name и пути к логам / ssl-сертификатам. Все заработало.

Опять же вопрос, насколько это костыльно :grinning:

1 лайк

Вполне может быть, что это и не костыль вовсе, а правильное решение вопроса)

1 лайк

Если вы формируете сертификат через Lets Ecript есть возможность указать несколько доменов в одном сертификате, тогда вы можете использовать один сертификат и один конфиг. В случае когда вы используете сертификат для каждого домена то выход один - использовать раздельный конфиг для каждого домена. Для уменьшения конфига вы можете вынести локейшены на отдельный порт и проксировать домены на этот порт, но конструкция достаточно сложная и нужна только если у вас будет очень много доменов. Да, тогда вы сможете менять настройки в одном месте, но если это 2-3 домена это того не стоит.

Относительно костылей. На конференции по хайлоад системам автор Игорь Сысоев дал рекомендации кокраз о таком способе ведения конфигов, как самые эффективные, так как ядру проще “понять” такие правила во время формирования ответа, так же рекомендуется уменьшить количество инклюдов и писать все правила в конфиг-файл. Понятно что речь идет в первую очередь для крупных проектов и главное чтобы вам было удобнее и понятно как работают правила.

1 лайк