nginx GOST binary packages
Опубликовано Николай Батищев on 2023-08-17 16:35

Начиная с CSP 5.0.12900 в состав дистрибутива CSP входят бинарные пакеты nginx с поддержкой GOST TLS.

Для использования серверного TLS требуется серверная лицензия типа "TLS Server".

1. Установка.

Подготовка дистрибутива

tar -xvf ./linux-amd64.tar.gz && cd ./linux-amd64/

Установка CSP и пакета nginx при помощи скрипта

sudo ./install.sh cprocsp-nginx
* по умолчанию устанавливается пакет с корневыми сертификатами Минкомсвязи

Активация лицензии

sudo /opt/cprocsp/sbin/amd64/cpconfig -license -set "Номер"

В строке License type при проверке лицензии должно быть именно "TLS Server"

/opt/cprocsp/sbin/amd64/cpconfig -license -view
...
License type: TLS Server.

2. Управление PKI.

Создавайте ключи без паролей!

Информация о сертификатах

sudo -u cpnginx /opt/cprocsp/bin/amd64/certmgr -list

Установка корневых и промежуточных сертификатов

sudo -u cpnginx /opt/cprocsp/bin/amd64/certmgr -inst -store uRoot -file /path/to/root.cer
sudo -u cpnginx /opt/cprocsp/bin/amd64/certmgr -inst -store uCa -file /path/to/intermediate.cer

Создание сертификата на тестовом УЦ КриптоПро

sudo -u cpnginx /opt/cprocsp/bin/amd64/cryptcp -creatcert -provtype 80 -rdn "CN=site.ru" -cont '\\.\HDIMAGE\srv' -certusage 1.3.6.1.5.5.7.3.1 -ku -du -both -exprt -ca http://testgost2012.cryptopro.ru/certsrv/

Если у вас уже есть контейнер с ключом, то необходимо поместить его в /var/opt/cprocsp/keys/cpnginx/, изменить права, сделать владельцем пользователя, от которого запускается cpnginx

chmod 700 /var/opt/cprocsp/keys/cpnginx/key_cont.000
chmod 600 /var/opt/cprocsp/keys/cpnginx/key_cont.000/*
chown -R cpnginx:cpnginx /var/opt/cprocsp/keys/cpnginx/key_cont.000/

Установка в хранилище всех сертификатов из всех доступных контейнеров

sudo -u cpnginx /opt/cprocsp/bin/amd64/csptest -absorb -certs -autoprov

Экспорт RSA ключа и сертификата из PFX

sudo -u cpnginx /opt/cprocsp/bin/amd64/certmgr -inst -provtype 24 -pfx -pin 123 -file ~/test.pfx

3. Общая информация. 

ГОСТ TLS реализован через интерфейс SSPI, классические директивы заменены на наши, мы постарались сохранить их в привычном виде.

Web server запускается и работает от пользователя cpnginx. Ключи, сертификаты должны быть установлены в хранилища, принадлежащие ему. Команды удобно запускать следующим образом: sudo -u cpnginx command.

Cервис называется cpnginx, соответсвенно перезапуск sudo systemctl restart cpnginx

4. Конфигурация. 

В общем случае, необходимо выпустить сертификаты, создать файл /etc/opt/cprocsp/cpnginx/conf.d/sspi.conf с содержимым из базового примера с актуальными данными и перезапустить сервер

Для использования функционала GOST+RSA на одном server{} необходимы две директивы sspi_certificate ГОСТ - первый, RSA - второй.

Для режима двусторонней аутентификации (MutualTLS) необходимо установить корневые сертификаты клиентов в хранилище, указанное в конфиге (sspi_verify_client on; sspi_client_certificate TrustedCerts;)

sudo -u cpnginx /opt/cprocsp/bin/amd64/certmgr -inst -store uTrustedCerts -file /path/to/ClientRoot.cer

Базовый пример, использованы все доступные параметры

server {
    listen 443 sspi; #включаем SSPI
    server_name nginx.corp.ru;

    sspi_certificate 0x7C00013D42201F55870674C594000100013D421; # GOST Serial
    sspi_certificate 0x00E3CD25AA5310D07F; # RSA cert serial
    sspi_protocols TLSv1.2;
    sspi_verify_client on;
    sspi_client_certificate TrustedCerts;
    sspi_client_verify_local_crl_only on;
        location / {
        proxy_pass https://upstream.corp.loc:443;
        proxy_http_version 1.1;
        proxy_sspi on;
        proxy_ssl_verify on;
        proxy_ssl_server_name on;
        proxy_ssl_certificate 0x21388B009FAE94BA4639382EB18CA056;
        proxy_ssl_trusted_certificate Root;
        proxy_ssl_verify_local_crl_only on;
    }
}

Stream пример

stream {
    server {
        listen 192.168.0.1:4443 sspi;
        sspi_certificate 0x7C0006F3DC6BF72CC17C72484D00010006F3DC;
        sspi_protocols TLSv1.2;

        sspi_verify_client on;
        sspi_client_certificate TrustedCerts;
        sspi_client_verify_local_crl_only on;

        proxy_pass 192.168.63.80:443;

            proxy_ssl_server_name on;
            proxy_ssl_name 192.168.63.80;
            proxy_sspi on;
            proxy_ssl_verify on;
            proxy_ssl_trusted_certificate Root;
            proxy_ssl_certificate 0x7C00013DED1933521BF075F083000100013DED;
            proxy_ssl_verify_local_crl_only on;
    }
}

5. Перечень доступных директив и переменных.

Для секции server

  • sspi_certificate - задаёт серийный номер сертификата сервера, сертификат должен быть установлен в личное хранилище пользователя cpnginx со ссылкой на приватный ключ
  • sspi_protocols - задаёт версии протокола TLS, рекомендуем использовать TLSv1.2, версии ниже официально признаны устаревшими, TLSv1.3 по умолчанию не включен, в текущей версии функционал считается экспериментальным.
  • sspi_verify_client on - включаяет двусторонний TLS (MutualTLS) для текущего блока server{}
  • sspi_client_certificate - задаёт хранилище с корневыми сертификата для mTLS (необходимо устанавливать только самоподписанные корневые, промежутчоные не нужны)
  • sspi_client_verify_local_crl_only on; - отключает онлайн проверку на отзыв пользовательских сертификатов

Для секции location

  • proxy_sspi on; - включает SSPI для текущего location, необходимо для клиентского ГОСТ TLS соединения с апстримом
  • proxy_ssl_certificate - задаёт сертификат клиента, требующийся для аутентификации на апстриме
  • proxy_ssl_trusted_certificate - задаёт хранилище с корневым сертификатом
  • proxy_ssl_verify_local_crl_only on; - отключает онлайн проверку на отзыв текущих сертификатов

Доступные переменные

  • $sspi_protocol - версия TLS
  • $sspi_alpn_protocol - версия TLS ALPN
  • $sspi_cipher - используемый ciphersuite
  • $sspi_client_s_dn - компоненты имени клиентского сертификата, использованного при подключении
  • $sspi_client_s_dn_base64 - компоненты имени в Base64
  • $sspi_client_i_dn - компоненты имени издателя клиентского сертификата
  • $sspi_client_i_dn_base64 - компоненты имени издателя клиентского сертификата в Base64
  • $sspi_client_v_start - дата и время начала действия клиентского сертификата
  • $sspi_client_v_end - дата и время окончания действия клиентского сертификата
  • $sspi_client_EKU - Extended Key Usage клиентского сертификата
  • $sspi_client_serial - cерийный номер клиентского сертификата
  • $sspi_client_escaped_cert - клиентский сертификат целиком в Base64
  • $sspi_client_fingerprint - отпечаток клиентского сертификат
  • $sspi_client_ms_upn - User Principal Name клиентского сертификата

6. Дополнения.

Ограничение используемых ciphersuites

sudo /opt/cprocsp/sbin/amd64/cpconfig -ini '\config\Parameters' -add multistring tls_server_cipher_list \
TLS_RSA_WITH_AES_128_GCM_SHA256 \
TLS_RSA_WITH_AES_256_GCM_SHA384 \
TLS_GOSTR341112_256_WITH_28147_CNT_IMIT \
TLS_GOSTR341112_256_WITH_KUZNYECHIK_CTR_OMAC \
TLS_GOSTR341112_256_WITH_MAGMA_CTR_OMAC \
TLS_GOSTR341112_256_WITH_28147_CNT_IMIT_IANA && \
sudo systemctl restart cprocsp && \
sudo systemctl restart cpnginx

Особенности работы с CRL

В режиме двустороннего TLS cpnginx проверяет сертификаты клиентов на отзыв. Для этого с CDP (Crl Distribution Point) загружается и кешируется актуальный CRL. Кеш не обновляется до истечения CRL. То есть, если вы отзовёте клиентский сертификат и опубликуете внеочередной CRL, клиент будет аутентифицироваться до момента истечения CRL в кеше. Рекомендуем оптимизировать расписание публикации CRL, возможно задействовать delta CRL на стороне УЦ.
На стороне cpnginx можно либо отключить кеш совсем (не рекомендуется), в этом случае CRL будет загружаться при каждом handshake.

sudo /opt/cprocsp/sbin/amd64/cpconfig -ini '\Cryptography\Capilite\cache_settings' -add long max_elements 0 && \
sudo systemctl restart cprocsp && \
sudo systemctl restart cpnginx

Либо очистить кеш и перезапустить cpnginx

sudo -u cpnginx /opt/cprocsp/bin/amd64/certmgr -del -all -crl -store uCache && \
sudo systemctl restart cpnginx

Особенности взаимодествия с IIS mTLS upstream

upd: в современных версиях IIS в GUI есть необходимая опция в свойствах мандата

Если вы настраиваете mTLS в IIS через GUI, по умолчанию он работает через renegotiation, cpnginx такой режим не поддерживает, необходимо отключать renegotiation на сервере IIS.

  1. Введите netsh
  2. Введите http
  3. Введите show sslcert. Вы увидите все SSL мандаты на этой машине
    netsh http show sslcert output
  4. Запишите IP:порт и хэш сертификата, для которого необходимо включить client certificate negotiations. Необходимо удалить мандат и добавить его снова с параметром Negotiate Client Certificate. В примере IP:port is 0.0.0.0:44300 а сертификат хеш это 71472159d7233d56bc90cea6d0c26f7a29db1112.
  1. Введите delete sslcert ipport=[IP:port from above]
  2. Введите add sslcert ipport=[IP:port которые записывали] certhash=[certificate hash который записывали] appid={[произвольный GUID (можно использовать из предыдущего вывода)]} certstorename=MY verifyclientcertrevocation=enable verifyrevocationwithcachedclientcertonly=disable clientcertnegotiation=enable
  3. Теперь необходимо убедиться, что все получилось, введите show sslcert снова. Вы должны увидеть такой же вывод, но с включенным параметром Negotiate Client Certificate:
    enter image description here

Расположение файлов

binary: /opt/cprocsp/sbin/amd64/cpnginx

config: /etc/opt/cprocsp/cpnginx/cpnginx.conf
             /etc/opt/cprocsp/cpnginx/conf.d/default.conf

html:   /var/opt/cprocsp/cpnginx/html/index.html

logs:    /var/log/cpnginx

Флаги компилятора и включенные модули

/opt/cprocsp/sbin/amd64/cpnginx -V
nginx version: nginx/1.22.1
built by gcc 9.3.1 20200408 (Red Hat 9.3.1-2) (GCC)
built with OpenSSL 1.1.1q 5 Jul 2022
TLS SNI support enabled
configure arguments:
--with-http_ssl_module
--with-http_sspi_module
--with-http_stub_status_module
--with-stream
--with-stream_ssl_module
--with-stream_ssl_preread_module
--with-stream_sspi_module
--with-http_v2_module
--with-openssl-opt='no-gost no-comp no-dtls no-deprecated no-dynamic-engine no-engine no-hw-padlock no-nextprotoneg no-psk no-tests no-ts no-ui-console'
--error-log-path=/var/log/cpnginx/error.log
--http-log-path=/var/log/cpnginx/access.log
--lock-path=/var/run/lock/cpnginx.lock
--pid-path=/var/run/cpnginx.pid
--prefix=/var/opt/cprocsp/cpnginx
--sbin-path=/opt/cprocsp/sbin/amd64/cpnginx
--conf-path=/etc/opt/cprocsp/cpnginx/cpnginx.conf
--with-debug --with-http_sub_module
--user=cpnginx
--modules-path=/opt/cprocsp/lib/amd64
--with-cc-opt='-g -O2 --param=ssp-buffer-size=4 -Wformat -Werror=format-security -Werror=implicit-function-declaration -Winit-self -Wp,-D_FORTIFY_SOURCE=2 -fPIC -fstack-protector -fstack-protector-strong -fstack-protector-all --param=ssp-buffer-size=4 -Wp,-D_FORTIFY_SOURCE=2 -fPIC'
--with-ld-opt='-Wl,-z,relro -Wl,-z,now -Wl,--as-needed -pie -Wl,-z,relro -Wl,-z,now -Wl,--as-needed -pie -fstack-protector -fstack-protector-strong -fstack-protector-all -L/opt/cprocsp/lib/amd64 `test -f /dailybuildsbranches/CSP_5_0r3s/64release/CSP/SSP/.libs/libssp.so && echo /dailybuildsbranches/CSP_5_0r3s/64release/CSP/SSP/.libs/libssp.so` `test -f /dailybuildsbranches/CSP_5_0r3s/64release/reader/source/support/.libs/librdrsup.so && echo /dailybuildsbranches/CSP_5_0r3s/64release/reader/source/support/.libs/librdrsup.so` `test -f /dailybuildsbranches/CSP_5_0r3s/64release/CSP/capilite/.libs/libcapi20.so && echo /dailybuildsbranches/CSP_5_0r3s/64release/CSP/capilite/.libs/libcapi20.so`'
--with-pcre=../pcre2-10.42 --with-pcre-opt=-fPIC
--with-pcre-jit --with-zlib=../zlib-1.2.13 --with-zlib-opt=-fPIC
--with-openssl=../openssl-1.1.1q --with-http_gunzip_module
--with-http_gzip_static_module

(30 плюсик(ов))
Класс!
Не очень :(

Коментарии (0)