Назад | Перейти на главную страницу

Как указать nginx обслуживать https только для одного домена, управляемого vhost?

У меня есть экземпляр ec2, работающий под управлением ubuntu и nginx 0.8.4, с vhosts, обслуживающими несколько разных доменов, использующих http, но один использующий SSL / https.

Конфигурация защищенного домена:

server {
    listen 443 ssl;
    server_name "securedomain.tld";

    ssl_certificate     /etc/nginx/certs/securedomain.tld.crt;
    ssl_certificate_key /etc/nginx/certs/securedomain.tld.key;

    if ($host != $server_name) {
        return 444; # this won't work because HTTPS communication has 
                    # been already started, warning message is displayed
    }

    // ...
}

Небезопасная конфигурация домена:

server {
    listen 80; 
    server_name "unsecuredomain.tld";

    // ...
}

Сейчас домен, обслуживаемый с использованием https, догоняет все трафик https для всех управляемых доменов… это означает, что https: //unsecuredomain.tld/ отобразит предупреждение и фактически предоставит содержимое из securedomain.tld :(

Вопрос в том, есть ли способ запретить nginx обслуживать все небезопасные домены, обслуживаемые с использованием https? например, указав, что вы хотите принимать https-соединения только для данного запрошенного хоста…

Подсказка: экземпляр ec2 не может иметь более одного IP-адреса.

Короче: нет. Что касается nginx, вы сказали ему, что все подключения к порту 443 являются SSL-подключениями для этого виртуального хоста, и он просто выполняет то, что вы ему сказали. К тому времени, когда он может увидеть Host: в заголовке запроса, согласование SSL было выполнено (отсутствует SNI, который действительно поможет только в том случае, если у вас есть сертификаты для всех ваших доменов, и браузер с поддержкой SNI использует их).

Как отмечает womble, предупреждение о несоответствии SSL невозможно предотвратить без второго IP-адреса или какой-либо настройки прокси.

Если вы хотите предотвратить передачу содержимого unsecuredomain.tld через SSL, вы должны использовать что-то вроде следующего в определении SSL vhost securedomain.tld вместо того, что у вас есть:

if ($host != $server_name) {
    rewrite ^(.*)$ http://unsecuredomain.tld permanent;
}

и просто откажитесь от них, вместо того, чтобы выдавать другую ошибку HTTP после того, как они уже получили предупреждение браузера и решили продолжить.