У меня есть сервер, на котором запущены как Nginx, так и Apache в настройке прокси, Nginx обслуживает статический контент, а Apache - динамический контент, который работает очень хорошо.
В этой конфигурации в настоящее время размещены две версии одного и того же сайта, давайте назовем их production.com и staging.com.
Я только что закончил настройку сайта production.com с использованием SSL, который также работает очень хорошо, но обнаружил, что если бы я перешел на staging.com также с использованием SSL, я бы получил содержимое корневого веб-сайта production.com. , что явно неверно.
Мне сказали использовать обработчик по умолчанию как для SSL, так и для не-SSL, что устранило бы такое поведение, но здесь у меня проблемы.
Прямо сейчас у меня есть эта конфигурация, включенная в nginx.conf
default_80.confserver {
listen 80;
server_name "";
return 444;
}
default_443.conf server {
listen 443 default_server ssl;
server_name "";
return 444;
}
staging.com.conf server {
listen 80;
server_name staging.com;
access_log /var/log/nginx/staging.com.log;
# static content folders
location ^~ /(images|css|js) {
root /var/www/staging.com/current;
access_log /var/log/nginx/staging.com.static.log;
}
# static content files
location ~* \.(js|css|rdf|xml|ico|txt|jpg|gif|png|jpeg)$ {
root /var/www/staging.com/current;
access_log /var/log/nginx/staging.com.static.log;
}
# proxy the rest to apache
location / {
proxy_pass http://127.0.0.1:8080/;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size 10m;
client_body_buffer_size 128k;
proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;
}
}
production.com.conf server {
listen 80;
server_name production.com;
rewrite ^ https://$server_name$request_uri? permanent;
}
server {
listen 443 ssl;
server_name production.com;
access_log /var/log/nginx/production.com.log;
ssl_certificate /etc/httpd/conf.d/SSL/ev.crt;
ssl_certificate_key /etc/httpd/conf.d/SSL/server.key;
keepalive_timeout 60;
# static content folders
location ^~ /(images|css|js) {
root /var/www/production.com/current;
access_log /var/log/nginx/production.com.static.log;
}
# static content files
location ~* \.(js|css|rdf|xml|ico|txt|jpg|gif|png|jpeg)$ {
root /var/www/production.com/current;
access_log /var/log/nginx/production.com.static.log;
}
# proxy the rest to apache
location / {
# proxy settings
proxy_pass http://127.0.0.1:8080/;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size 10m;
client_body_buffer_size 128k;
proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;
}
}
Эти настройки уничтожают все виды SSL-доступа к любому из двух сайтов, и если я удалю директиву default_server из default_443.conf, она будет работать для обоих сайтов.
Итак, вопрос в том, как отключить SSL-доступ (https://staging.com возвращает 444) для staging.com и включает его на production.com?
С уважением, Ларс
Во-первых, убедитесь, что ваша версия Nginx поддерживает SNI, если вы используете один из этих странных дистрибутивов (вы должны увидеть, что поддержка TLS SNI включена вверху):
nginx -V
Я разместил настройку ниже, вот результаты на моем ящике (/var/www/production/index.html содержит PRODUCTION и /var/www/staging/index.html, STAGING)
http://192.168.56.101 сброс подключения (444)
https://192.168.56.101 сброс подключения (444)
http://staging.example.com СТАДИЯ
https://staging.example.com перенаправление на http
http://production.example.com перенаправление на https
https://production.example.com ПРОИЗВОДСТВО
Для справки, я использовал стабильную версию nginx из репозиториев debian (0.7.67), но у меня очень похожая установка на 1.0. Что-то работает почти так же. Если вы не можете заставить его работать, сообщите нам свою точную версию.
В вашем случае вы, вероятно, захотите изменить оба значения по умолчанию на default_server. Вы также можете сделать перезапись постоянной и, возможно, изменить ее на return 301, если ваша версия nginx это позволяет.
/ и т.д. / nginx / сайты-включен / по умолчанию
server {
listen 80 default;
return 444;
}
server {
listen 443 default;
ssl on;
ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem;
ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key;
return 444;
}
/ и т. д. / nginx / сайты с поддержкой / производство
server {
listen 80; ## listen for ipv4
server_name production.example.com;
rewrite ^ https://production.example.com$request_uri?;
}
server {
listen 443;
server_name production.example.com;
ssl on;
ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem;
ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key;
keepalive_timeout 60;
location / {
proxy_pass http://127.0.0.1:81;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
/ и т.д. / nginx / сайты с поддержкой / постановка
server {
listen 80;
server_name staging.example.com;
keepalive_timeout 60;
location / {
proxy_pass http://127.0.0.1:81;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
server {
listen 443; ## listen for ipv4
server_name staging.example.com;
ssl on;
ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem;
ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key;
keepalive_timeout 60;
rewrite ^(.*) http://staging.example.com$1;
}
/ и т.д. / apache2 / сайты с поддержкой / производство
<VirtualHost *:81>
ServerAdmin webmaster@localhost
ServerAlias production.example.com
DocumentRoot /var/www/production
<Directory />
Options FollowSymLinks
AllowOverride None
</Directory>
<Directory /var/www/production>
Options Indexes FollowSymLinks MultiViews
AllowOverride None
Order allow,deny
allow from all
</Directory>
ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
<Directory "/usr/lib/cgi-bin">
AllowOverride None
Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
Order allow,deny
Allow from all
</Directory>
ErrorLog ${APACHE_LOG_DIR}/error.log
# Possible values include: debug, info, notice, warn, error, crit,
# alert, emerg.
LogLevel warn
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
/ и т.д. / apache2 / сайты с поддержкой / постановка
<VirtualHost *:81>
ServerAdmin webmaster@localhost
ServerAlias staging.example.com
DocumentRoot /var/www/staging
<Directory />
Options FollowSymLinks
AllowOverride None
</Directory>
<Directory /var/www/staging>
Options Indexes FollowSymLinks MultiViews
AllowOverride None
Order allow,deny
allow from all
</Directory>
ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
<Directory "/usr/lib/cgi-bin">
AllowOverride None
Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
Order allow,deny
Allow from all
</Directory>
ErrorLog ${APACHE_LOG_DIR}/error.log
# Possible values include: debug, info, notice, warn, error, crit,
# alert, emerg.
LogLevel warn
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
/etc/apache2/ports.conf
NameVirtualHost *:81
Listen 81
Я (с помощью 3molo на IRC) решил это, добавив серверный блок с использованием ssl для staging.com с переписью на HTTP, что, на мой взгляд, является одобренным обходным путем.
server {
listen 443 ssl;
server_name staging.com;
ssl_certificate /etc/httpd/conf.d/SSL/ev.crt;
ssl_certificate_key /etc/httpd/conf.d/SSL/server.key;
keepalive_timeout 60;
rewrite ^ http://$server_name$request_uri? permanent;
}
Но проблема все еще остается, почему Nginx обслуживает контент, когда $ http_host и server_name не совпадают? Если у кого-то есть ответ на этот вопрос, я с радостью его выслушаю.
Если staging.com и production.com указывают на одни и те же IP-адреса, это не зависит от вас, поскольку SSL согласовывается до отправки заголовка Host клиентом.
Если возможно, используйте один IP-адрес для каждого сайта, а если нет, вы можете, однако, иметь возможность «if $ host = staging.com ..» в контексте сервера для production.com.