Изменение используемого SSL-сертификата в зависимости от IP-адреса клиента в Nginx

Вопрос или проблема

У меня есть два SSL-сертификата, foo.crt и bar.crt. Оба сертификата используют один и тот же ключ, foo.key. Я хочу, чтобы мой Nginx отправлял foo.crt в качестве SSL-сертификата, когда IP-адрес клиента соответствует 192.168.1.0/24, и bar.crt, когда нет.

Я пытался использовать модуль Geo и директиву if следующим образом:

geo $local {
    default 0;
    192.168.1.0/24 1;
}
...
server {
    ssl_certificate bar.crt;
    ssl_certificate_key foo.key;
    if ($local) {
        ssl_certificate foo.crt;
    }
    ...
}

Однако Nginx выдает ошибку "ssl_certificate" directive is not allowed here.

Есть ли способ сделать это без директивы if?

Возможно, что-то вроде этого (не тестировалось):

geo $cert {
    default bar.crt;
    192.168.1.0/24 foo.crt;
}
...
server {
    ssl_certificate $cert;
    ssl_certificate_key foo.key;
    ...
}

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

По умолчанию права были 744. Используйте команду:
chmod -R 755 path/to/file

Ответ или решение

Теория

Настройка SSL-сертификатов, зависящих от IP-адреса клиента в Nginx, усложняется тем, что выбор сертификата происходит до установления SSL-соединения и выполнения других директив. Это значит, что использование условных инструкций (таких как if) непосредственно в контексте выбора сертификата не допускается, как указано в ошибке: "ssl_certificate" directive is not allowed here.

Пример

Один из возможных подходов к решению задачи — использовать серверные блоки, которые слушают на одном и том же порту, но обрабатывают разные сценарии в зависимости от свойства SNI (Server Name Indication). Однако в данном случае IP-адреса — главный фактор, и такие предложения, включая geo с переменными, не поддерживаются для выбора сертификата.

Таким образом, решение заключается в использовании независимых от Nginx инструментов, например, стороннего обходного решения для управления TLS/SSL, таких как специализированные прокси-серверы или шлюзы, настроенные для выполнения аналогичной логики.

Применение

Для достижения смены сертификата на основе источника IP, можно рассмотреть использование отдельного экземпляра Nginx для каждой специфики клиентов. Например:

  1. Создайте два отдельных серверных блока:

    server {
       listen 443 ssl;
       ssl_certificate foo.crt;
       ssl_certificate_key foo.key;
    
       # Ограничь до 192.168.1.0/24
       allow 192.168.1.0/24;
       deny all;
    
       ...
    }
    
    server {
       listen 443 ssl;
       ssl_certificate bar.crt;
       ssl_certificate_key foo.key;
    
       # Запрет для 192.168.1.0/24 для использования этого блока
       deny 192.168.1.0/24;
    
       ...
    }
  2. Отдельные серверные блоки с настройками SSL помогут обеспечить правильный выбор сертификата на основе IP-адреса, в то время как сеть будет защищена прихотью корпоративной политики.

Если требуется гибкость, превышающая возможности Nginx, рассмотрите переход на более сложные технологические решения, такие как используемые в специализированных балансировщиках нагрузки с возможностью настройки сложной логики на уровне SSL/TLS.

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

Оцените материал
Добавить комментарий

Капча загружается...