Nginx. Как я отклоняю запрос к не включенному в список ssl виртуальному серверу?

Если это - всего 2 машины, можно рассмотреть использование DRBD для синхронизации между обеими машинами. Затем просто используйте PHP для решения случайным образом или алгоритмически который сервер вытянуть от во время запроса. Простое но осуществимое решение.

12
задан 27 March 2012 в 16:26
6 ответов

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

7
ответ дан 2 December 2019 в 21:32

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

http {
    ...

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

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

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

0
ответ дан 2 December 2019 в 21:32

I implemented the above solution today, and it worked swimmingly. All URL's not specified are dropped, now. Placing this server code before the actual virtual server entry was key - all mal-formed URL's now go to this 'default' server.

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

server {
     listen       443;
     server_name  [URL]
1
ответ дан 2 December 2019 в 21:32

The answer by cjc already correctly pointed out the problem with trying to match host names when SSL is enabled. However, it is possible to do it, like this:

server {
    ...

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

Note: yes it is true that generally if is evil, but it is safe to use if in this case. (Read the linked page if you need to convince yourself.)

Contrarily to what has been suggested, just adding the following block won't work:

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

because an SSL certificate that matches validname.domain.com won't match some random domain name. I've tried it, and nginx acted like the block was not present at all.

This also won't work:

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

because it will make every single HTTPS connection on port 443 fail, even those that should go through. I've tried this one too. wget reported an SSL handshake error.

12
ответ дан 2 December 2019 в 21:32

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

Вот как - вам нужно чтобы сделать такой универсальный сервер '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

4
ответ дан 2 December 2019 в 21:32

В настоящее время ответ на этот вопрос может быть обновлен.

Для Nginx ≥ 1.19.4: http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_reject_handshake

server {
    listen               443 ssl;
    ssl_reject_handshake on;
}

server {
    listen              443 ssl;
    server_name         example.com;
    ssl_certificate     example.com.crt;
    ssl_certificate_key example.com.key;
}

Для Nginx < 1.19.4: Используя https://git.hakase.app/Hakase/openssl-patch

http {
    # control options
    strict_sni on;
    strict_sni_header on;

    # fake server block
    server {
        server_name  localhost;
        listen       80;
        listen       443 ssl default_server; # "default_server" is necessary
        ssl_certificate /root/cert.crt; # Can be any certificate here
        ssl_certificate_key /root/cert.key; # Can be any certificate here

        location / {
            return 444;
        }
    }

    # normal server blocks
    server {
        server_name  normal_domain.tld;
        listen       80;
        listen       443 ssl;
        ssl_certificate /root/cert.crt; # Your real certificate here
        ssl_certificate_key /root/cert/cert.key; # Your real certificate here

        location / {
            echo "Hello World!";   
        }
    }
}

Для новичков, которые не знакомы с применением патча к Nginx, вы можете проверить это: https://blog.sion .moe/methods-to-prevent-leaking-websites-origin-server-ip-behind-cdn/

9
ответ дан 2 December 2020 в 08:33

Теги

Похожие вопросы