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

Nginx. Как отклонить запрос к виртуальному серверу ssl, который не указан в списке?

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

ssl_certificate         tls/domain.crt;
ssl_certificate_key     tls/domain.key;

server {
  listen 1.2.3.4:443 ssl;
  server_name validname.domain.com;
  //
}

server {
  listen 1.2.3.4:443 ssl;
  server_name _;
  // deny all;
  // return 444;
  // return 404;
  //location {
  //  deny all;
  //}
}

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

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

server {
    ...

    if ($host !~* ^validname\.domain\.com$ ) {
        return 444;
    }
    ...
}

Примечание: да, это правда, что обычно if зло, но безопасно использовать if в таком случае. (Прочтите страницу по ссылке, если вам нужно убедиться.)

Вопреки тому, что было предложено, просто добавить следующий блок не получится:

server {
    listen 80;
    listen 443 ssl;
    return 444;
}

потому что сертификат SSL, соответствующий validname.domain.com не будет соответствовать случайному доменному имени. Я пробовал, и nginx вел себя так, как будто блока вообще не было.

Это тоже не сработает:

server {
    listen       443;
    server_name    _;
    return 444; 
}

потому что это сделает каждый HTTPS-соединение на порту 443 не работает, даже если оно должно пройти. Я тоже пробовал это. wget сообщил об ошибке подтверждения SSL.

Большинство ответов здесь о Зачем это не работает, не как чтобы заставить его работать.

Вот как - вам нужно сделать такой универсальный сервер 'default_server' и указать пути к сертификату / ключу, чтобы он мог расшифровать входящий ssl-запрос и соответствовать заголовку Host:

server {
    listen 80 default_server;
    listen 443 ssl default_server;
    server_name _;
    ssl_certificate <path to cert>;
    ssl_certificate_key <path to key>;
    return 404;
}

Обратите внимание на ssl_certificate / ssl_certificate_key там. Если они не указаны, nginx по-прежнему пытается использовать такой default_server и терпит неудачу, поскольку не может принять ssl-соединение без сертификата / ключа. Можно использовать любой сертификат / ключ, например. самоподписанный. ...

Чтобы создать самозаверяющий сертификат:

openssl req -x509 -newkey rsa:4096 -nodes -out cert.pem -keyout key.pem -days 365 

Также см https://serverfault.com/a/841643/87439

Это не работает: рукопожатие SSL происходит до HTTP, поэтому имя в сертификате будет оценено в браузере, прежде чем вы сможете перенаправить или сделать что-либо еще в конфигурации nginx.

Я реализовал вышеупомянутое решение сегодня, и оно сработало без проблем. Все URL-адреса, которые не указаны, теперь удаляются. Размещение этого кода сервера перед фактической записью виртуального сервера было ключевым - все неправильно сформированные URL-адреса теперь переходят на этот сервер «по умолчанию».

... 
server {
     listen       443;
     server_name    _;
     return 444; }

server {
     listen       443;
     server_name  [URL]

Вы можете справиться с этим, сделав сервер, который обрабатывает элементы, не указанные в списке, первым серверным блоком в вашей конфигурации.

http {
    ...

    server {
        listen 80;
        listen 443 ssl;
        return 444;
    }

    server {
        server_name validname.domain.com;
        ...
    }
}

Все домены, не указанные специально, будут обрабатываться этим серверным блоком.