Сборка и настройка nginx c поддержкой ГОСТ TLS
Опубликовано Николай Батищев on 2020-10-20 15:40

СТАТЬЯ УСТАРЕЛА! новая статья <по ссылке>

 

В инструкции описан процесс компиляции nginx 1.18 c поддержкой ГОСТ TLS. На примере Debian 10.
Для получения патча создайте заявку на портале технической поддержки.

1. Установка КриптоПро CSP. 
решение сертифицировано с CSP 5.0r2

tar -xvf ./linux-amd64_deb.tgz && cd ./linux-amd64_deb/
sudo ./install.sh
sudo dpkg -i ./lsb-cprocsp-devel_5.0.12000-6_all.deb

Активация лицензии
sudo /opt/cprocsp/sbin/amd64/cpconfig -license -set "Номер"

Проверка лицензии и количества подключений
/opt/cprocsp/sbin/amd64/cpconfig -license -check "Номер"

Проверка статуса лицензии
/opt/cprocsp/sbin/amd64/cpconfig -license -view

2. Установка дополнительных пакетов, получение исходных текстов

sudo apt-get install build-essential patch

wget https://sourceforge.net/projects/pcre/files/pcre/8.45/pcre-8.45.tar.gz
tar -xvf ./pcre-8.45.tar.gz

wget https://zlib.net/zlib-1.2.13.tar.gz
tar -xvf ./zlib-1.2.13.tar.gz

wget https://www.openssl.org/source/openssl-1.1.1o.tar.gz
tar -xvf ./openssl-1.1.1o.tar.gz

(в случае отсутсвия цепочки добавьте параметр --no-check-certificate для загрузки архивов )

3. Сборка

Наложение патча

wget https://nginx.org/download/nginx-1.18.0.tar.gz
tar -xvf ./nginx-1.18.0.tar.gz
cp ./ng-nginx.1.18.0.patch ./nginx-1.18.0 && cd ./nginx-1.18.0/
patch -p1 < ./ng-nginx.1.18.0.patch

./configure \
--user=nginx \
--group=nginx \
--with-cc-opt='-fstack-protector -fstack-protector-strong --param=ssp-buffer-size=4 -Wformat -Werror=format-security -Werror=implicit-function-declaration -Winit-self -Wp,-D_FORTIFY_SOURCE=2 -fPIC' \
--with-ld-opt='-Wl,-z,relro -Wl,-z,now -Wl,--as-needed -pie -L/opt/cprocsp/lib/amd64 -lrdrsup -lssp -lcapi10 -lcapi20' \
--prefix=/opt/nginx \
--conf-path=/etc/nginx/nginx.conf \
--error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/nginx/access.log \
--lock-path=/var/run/lock/nginx.lock \
--pid-path=/var/run/nginx.pid \
--with-pcre=../pcre-8.45/ \
--with-pcre-jit \
--with-zlib=../zlib-1.2.13/ \
--with-http_ssl_module \
--with-http_sspi_module \
--with-http_stub_status_module \
--with-openssl=../openssl-1.1.1o/ \
--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 no-ocsp' \
--with-stream \
--with-stream_ssl_module \
--with-stream_sspi_module \
--with-http_v2_module

Для rhel based дистрибутивов добавляются опции
--with-pcre-opt=-fPIC --with-zlib-opt=-fPIC

Копирование базовго конфигурационого файла в директорию с кодом.
Пример базовго конфигурационного фала в 7ом разделе
sudo cp ./nginx.conf.sample ./nginx-1.18.0/conf/nginx.conf
make

sudo make install

Создание системного пользователя.
sudo adduser --system --no-create-home --group nginx
sudo chown -R nginx:nginx /var/log/nginx/

Перенос init скрипта.
Информация об инитскриптах для Nginx находится здесь https://www.nginx.com/resources/wiki/start/topics/examples/initscripts/
sudo cp ./nginx.init /etc/init.d/nginx
sudo chmod +x /etc/init.d/nginx
sudo systemctl daemon-reload

4. Работа с ключами и сертификатами

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

Если у вас уже есть контейнер с ключем, то необходимо поместить его в /var/opt/cprocsp/keys/nginx/, изменить права, сделать владельцем пользователя от которого запускается nginx
chmod 700 /var/opt/cprocsp/keys/nginx/key_cont.000
chmod 600 /var/opt/cprocsp/keys/nginx/key_cont.000/*
chown -R nginx:nginx /var/opt/cprocsp/keys/nginx/key_cont.000/

Установка в хранилище всех сертификатов из всех доступных контейнеров
sudo -u nginx /opt/cprocsp/bin/amd64/csptest -absorb -certs -autoprov

Экспорт RSA ключа и сертификата из PFX
sudo -u nginx /opt/cprocsp/bin/amd64/certmgr -inst -provtype 24 -pfx -pin 123 -file ~/test.pfx

Установка корневых и промежуточных сертификатов
sudo -u nginx /opt/cprocsp/bin/amd64/certmgr -inst -store uRoot -file /path/to/root.cer
sudo -u nginx /opt/cprocsp/bin/amd64/certmgr -inst -store uCa -file /path/to/intermediate.cer

Генерация сертификата на тестовом УЦ КриптоПро
sudo -u nginx /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/

Получение серийного номера сертификата
sudo -u nginx /opt/cprocsp/bin/amd64/certmgr -list

Для режима двусторонней авутентификации (MutualTLS) необходимо установить корневые сертификаты клиентов в хранилище, указанное в конфиге (sspi_verify_client on; sspi_client_certificate TrustedCerts;)
sudo -u nginx /opt/cprocsp/bin/amd64/certmgr -inst -store uTrustedCerts -file /path/to/ClientRoot.cer

5. Запуск

Необходимо отредактировать /etc/nginx/nginx.conf, заменить серийный номер в sspi_certificate на свой.
sudo systemctl start nginx

6. Дополнительная информация

Ошибки при запуске логируются в /var/log/nginx/error.log или /var/log/syslog
При успешном запуске nginx откройте страницу https://site.ru и проверьте в адресной строке, что соединение зашифровано.
Так же можно пользоваться утилитой из состава CSP
"C:\Program Files\Crypto Pro\CSP\csptest.exe" -tlsc -server site.ru -port 443 -proto 6 -ciphers ff85:c100:c101:c102 -nosave -v
Более подробно
"C:\Program Files\Crypto Pro\CSP\csptest.exe" -tlsc -help

7. Пример конфигурационного файла

В веб сервере можно использовать и нативный openssl tls (недоступен ГОСТ) так и наш CSP SSPI TLS (не все иностранные шифры поддерживаются)
Поддержку SSPI можно включать для отдельных блоков location/server.


http {
    server {
        listen 443;
        server_name site.ru;
        
        sspi on; # включаем sspi для этой секции server
        sspi_certificate 0x7C00013D42201F55870674C594000100013D421; # GOST Serial, необходимо ставить первым в список
        sspi_certificate 0x00E3CD25AA5310D07F; # RSA cert serial (опционально, необходимо при использовании GOST+RSA На одном порту)
        sspi_protocols TLSv1.2;
#            sspi_verify_client on; #(опционально!) для включения mTLS

#            sspi_client_certificate TrustedCerts; #(опционально!) хранилище довереннных корневых сертификатов для mTLS

        location / {
            proxy_pass https://backend.ru:443;
            proxy_http_version 1.1;
            proxy_sspi on; # включаем sspi для этой секции location 
            proxy_ssl_verify on;
            proxy_ssl_certificate 0x21388B009FAE94BA4639382EB18CA056; # указываем сертификат клиента, требующийся для аутентификайции на бекенде
            proxy_ssl_trusted_certificate Root; #указываем корневое хранилище (можно указать кастомное)
#            proxy_ssl_verify_local_crl_only on; #(опционально!)отключаем онлайн проверку статусов сертификатов
        }

    }
}

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