webserver-llc / angie

Angie - drop-in replacement for Nginx
https://angie.software/en/
BSD 2-Clause "Simplified" License
1.11k stars 64 forks source link

LibreSSL и 1.6.0 #89

Open asyslinux opened 2 days ago

asyslinux commented 2 days ago

Здравствуйте. На сайте https://angie.software/installation/sourcebuild/ я видел, что для поддержки HTTP3 упоминаются BoringSSL и QuicTLS, сегодня я собрал Angie с LibreSSL - всё собралось без ошибок, вроде всё работает.

Могут ли быть навскидку какие-то подводные камни при использовании HTTP3 в Angie с LibreSSL?

Спасибо.

vlhomutov commented 2 days ago

Добрый день. Скорее всего вы собрались с LibreSSl в рамках режима совместимости, который имеет ряд ограничений - не работает 0RTT, также возможны неудачные хендшейки с такой ошибкой: SSL_do_handshake() failed (SSL: error:10000132:SSL routines:OPENSSL_internal:UNEXPECTED_COMPATIBILITY_MODE), если клиент и сервер собраны с разными библиотеками.

BoringSSL и QuicTLS рекомендуются, т.к. предоставляют QUIC API. Обычный OpenSSL (и LibreSSL) также могут использоваться, но см. выше.

Если в LibreSSL добавили в каком-то виде поддержку BoringSSL-style QUIC API, то должно работать. В целом мы не проводили тестирование LibreSSL, поэтому не можем рассказать деталей.

Если не трудно, расскажитье, почему и на какой платформе вы используете LibreSSL.

asyslinux commented 1 day ago

Здравствуйте. Я посмотрел - LibreSSL implements the BoringSSL QUIC API. То есть это там есть уже с 2022 года, но детально не изучал тоже этот вопрос.

Почему решили использовать Angie:

Платформа Debian 9/10/11/12 amd64 (под 9-ку я тоже смог собрать angie, правда без молотка не обошлось)

1) Он у Вас построен на 1.27 Nginx - все-таки это свежее, мне нравится.

2) У Вас есть HTTP3 из коробки. И мы планируем как раз его начать использовать в продакшене.

3) Мне лично как бородатому админу(хотя я не только админ) понравились ваши чистые правила debian/rules - удобно и просто на базе ваших исходников полученных из apt source angie, убрать или добавить в сборке модули, а так же то, что angie собирается как бы по отдельным путям и может спокойно существовать в одной ОС вместе с обычным nginx, что облегчает процесс миграции.

4) У меня собрались с angie и корректно работают вот такие специфические модули:

 https://github.com/ip2location/ip2location-nginx
 https://github.com/ip2location/ip2proxy-nginx

 В них правда оформление не соответствует стилю модуля к nginx, поэтому пришлось в debian/rules добавить:
     override_dh_shlibdeps:
        dh_shlibdeps --dpkg-shlibdeps-params=--ignore-missing-info

Кстати, было бы не плохо иметь поддержку этих модулей у Вас прямо из коробки в будущем. Если нужна какая-то дополнительная информация по сборке этих модулей(там к ним еще отдельно библиотеки надо собирать в своих отдельных deb пакетах), то я могу ответить на ваши вопросы.

  1. ACME - я еще не тестировал, но вы просто молодцы - ну наконец-то нашлись люди, которые сделали веб-сервер типа nginx автономным по SSL сертификатам, как caddy.

Кстати ваша функция enable=on/off у acme очень будет даже удобна я думаю. У меня есть несколько серверов в кластере, поэтому теоретически можно одному angie поручить выписку, а другим angie отключить, но оставить настройки.

Если я правильно понимаю, то к примеру если есть 4 Angie на 4-х серверах, у них общая файловая система, и если 1-ый будет выписывать сертификаты, то у меня все-таки вопрос - подхватят ли и применят ли новые файлы с сертификатами и ключами с общей папки в ФС автоматически остальные 3 запущенных Angie, когда в общей папке заменятся файлы с сертификатами и ключами после выписки? Или же другим 3-м Angie придется делать полный перезапуск?

Если это вдруг не предусмотрено, было бы здорово, чтобы angie использовал inotify (IN_CLOSE_WRITE например) и мониторил каталог с сертификатами и ключами на изменения, как только файлик заменится, angie бы сам перечитывал и применял новые сертификаты и ключи без перезапуска, конечно с задержкой, так как сначала появится ключ, а потом только сертификат, то есть нужна сверка, что ключ и сертификат подходят друг к другу(но это уже детали).

Что касается LibreSSL - вот часть информации из сборки:

configuring additional modules
adding module in ip2location
 +  was configured
adding module in ip2proxy
 + ngx_http_ip2proxy_module was configured
adding module in ip2proxy
 + ngx_http_ip2proxy_module was configured
using cached PCRE2 library ... found
using cached OpenSSL library ... found
using cached OpenSSL QUIC support ... found
using cached OpenSSL version for ACME support ... found
using cached zlib library ... found
creating objs/Makefile
collecting build environment information... ok

Configuration summary
  + using threads
  + using system PCRE2 library
  + using system OpenSSL library
  + using system zlib library
root@srv:/etc/garnet# angie -V
Angie version: Angie/1.6.0
nginx version: nginx/1.27.0
built with LibreSSL 3.9.2
TLS SNI support enabled
configure arguments: --prefix=/etc/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=/run/nginx.lock --modules-path=/usr/lib/angie/modules --pid-path=/run/nginx.pid --sbin-path=/usr/sbin/angie --http-acme-client-path=/var/lib/angie/acme --http-client-body-temp-path=/var/cache/nginx/client_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --user=www-data --user=www-data --add-module=ip2location --add-module=ip2proxy --with-file-aio --with-http_acme_module --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-http_v3_module --with-mail --with-mail_ssl_module --with-stream --with-stream_mqtt_preread_module --with-stream_rdp_preread_module --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-threads --feature-cache=../angie-feature-cache --with-cc-opt='-I../libressl/include -g -O2 -ffile-prefix-map=/root/compile/angie/angie-1.6.0=. -fstack-protector-strong -Wformat -Werror=format-security' --with-ld-opt='-Wl,-z,relro -Wl,-z,now -L../libressl/build/ssl -L../libressl/build/crypto'
VBart commented 1 day ago

@asyslinux нет, автоматически он не подхватит новые сертификаты с диска без хотя бы релоада конфигурации. К сожалению, в nginx и в Angie, как следствие, в принципе нет поддержки механима inotify и его добавление - это отдельная большая работа.

asyslinux commented 1 day ago

@asyslinux нет, автоматически он не подхватит новые сертификаты с диска без хотя бы релоада конфигурации. К сожалению, в nginx и в Angie, как следствие, в принципе нет поддержки механима inotify и его добавление - это отдельная большая работа.

Спасибо за ответ. Это вообще мелочи на самом деле, решается внешним сервисом типа incron - просто мониторить им только файлы сертификатов, так как они появляются после ключей, и посылать команду на reload в Angie.

vlhomutov commented 1 day ago

Что касается LibreSSL - вот часть информации из сборки:

Да, действительно они уже некоторое время как добавили поддержку BoringSSL Quic API [1] О каких-то специфичных проблемах нам не известно, если на что-то наткнётесь - сообщайте.

[1] https://undeadly.org/cgi?action=article;sid=20221006105921 "Experimental support for the BoringSSL QUIC API":

asyslinux commented 1 day ago

Спасибо, обязательно сообщу, у меня есть на чём проверить - web сайт с трафиком в 75-100 миллионов визитов в месяц, на нём точно быстро увидим, если что-то не так. В том числе сообщу если все будет отлично.

asyslinux commented 1 day ago

Здравствуйте.

Платформа Debian 12 (На других не проверял, но скорее всего все тоже самое будет) / Angie 1.6.0

С LibreSSL обнаружилась такая проблема:

Если подключить модуль load_module modules/ngx_http_lua_module.so; , то будет вот что:

root@srv:~# angie -t
angie: [emerg] dlopen() "/etc/nginx/modules/ngx_http_lua_module.so" failed (/etc/nginx/modules/ngx_http_lua_module.so: undefined symbol: SSL_client_hello_get0_ext) in /etc/nginx/nginx.conf:17

Далее я попробовал собрать с BoringSSL, и у меня это никак не получается, ./configure не находит в упор BoringSSL:

./configure --with-debug --with-http_v3_module --with-cc-opt="-I../boringssl/include" --with-ld-opt="-L../boringssl/build/ssl -L../boringssl/build/crypto"

...

checking for OpenSSL library ... not found
checking for OpenSSL library in /usr/local/ ... not found
checking for OpenSSL library in /usr/pkg/ ... not found
checking for OpenSSL library in /opt/local/ ... not found
checking for OpenSSL library in /opt/homebrew/ ... not found

...

./configure: error: SSL modules require the OpenSSL library.
You can either do not enable the modules, or install the OpenSSL library
into the system, or build the OpenSSL library statically from the source
with Angie by using --with-openssl=<path> option.

Собственно как собиралось с нуля:

git clone https://boringssl.googlesource.com/boringssl
mkdir -p boringssl/build && cd boringssl/build
cmake ../
make -j 8

cd ../..

wget -c https://download.angie.software/files/angie-1.6.0.tar.gz
tar xzf angie-1.6.0.tar.gz
cd angie-1.6.0/

./configure --with-debug --with-http_v3_module --with-cc-opt="-I../boringssl/include" --with-ld-opt="-L../boringssl/build/ssl -L../boringssl/build/crypto"

Подскажите пожалуйста в чем дело, так как LibreSSL аналогично собирается. Спасибо.

VBart commented 1 day ago

Если подключить модуль load_module modules/ngx_http_lua_module.so; , то будет вот что:

А модуль вы также сами собирали с LibreSSL?

asyslinux commented 1 day ago

Эмм, я использовал просто debian/rules и прописал там только вот это:

CC_OPT ?= -I../libressl/include $(CFLAGS)
LD_OPT ?= -L../libressl/build/ssl -L../libressl/build/crypto

Этого недостаточно?

vlhomutov commented 1 day ago

Здравствуйте.

Далее я попробовал собрать с BoringSSL, и у меня это никак не получается, ./configure не находит в упор BoringSSL:

./configure --with-debug --with-http_v3_module --with-cc-opt="-I../boringssl/include" --with-ld-opt="-L../boringssl/build/ssl -L../boringssl/build/crypto"

...

checking for OpenSSL library ... not found
checking for OpenSSL library in /usr/local/ ... not found
checking for OpenSSL library in /usr/pkg/ ... not found
checking for OpenSSL library in /opt/local/ ... not found
checking for OpenSSL library in /opt/homebrew/ ... not found

...

./configure: error: SSL modules require the OpenSSL library.
You can either do not enable the modules, or install the OpenSSL library
into the system, or build the OpenSSL library statically from the source
with Angie by using --with-openssl=<path> option.

Подскажите пожалуйста в чем дело, так как LibreSSL аналогично собирается. Спасибо.

BoringSSL с некоторых пор требует наличия C++ рантайма. См. тут: https://mailman.nginx.org/pipermail/nginx/2024-February/5N5IXG7BI66D5AIKORCYPVVVJTZYMUR6.html https://boringssl.googlesource.com/boringssl/+/c52806157c97105da7fdc2b021d0a0fcd5186bf3 (надо добавить -lstdc++)

VBart commented 1 day ago

Эмм, я использовал просто debian/rules и прописал там только вот это:

CC_OPT ?= -I../libressl/include $(CFLAGS)
LD_OPT ?= -L../libressl/build/ssl -L../libressl/build/crypto

Этого недостаточно?

Подозреваю, что и сам lua должен быть в этом случае собран с LibreSSL... вряд ли при сборке модуля собирается вся цепочка.

asyslinux commented 1 day ago

Если просто добавить -lstdc++ без указания --with-cc - то снова OpenSSL not found будет в ./configure

Компилятор Clang:

                  --with-cc=clang

CONFIGURE_ADD ?=
CONFIGURE_ENV ?=
CC_OPT ?= -I../boringssl/include $(CFLAGS)
LD_OPT ?= -L../boringssl/build/ssl -L../boringssl/build/crypto -lstdc++

./configure подцепил BoringSSL, но с ним уже не собирается например:

module-upload-2-3-0/ngx_http_upload_module.c:15:19: error: typedef redefinition with different types ('ngx_md5_t' vs 'struct md5_state_st')
typedef ngx_md5_t MD5_CTX;
                  ^
../boringssl/include/openssl/base.h:352:29: note: previous definition is here
typedef struct md5_state_st MD5_CTX;
                            ^
module-upload-2-3-0/ngx_http_upload_module.c:192:17: error: field has incomplete type 'MD5_CTX' (aka 'struct md5_state_st')
    MD5_CTX     md5;
                ^
../boringssl/include/openssl/base.h:352:16: note: forward declaration of 'struct md5_state_st'
typedef struct md5_state_st MD5_CTX;

Компилятор G++:

                  --with-cc=g++

CONFIGURE_ADD ?=
CONFIGURE_ENV ?=
CC_OPT ?= -I../boringssl/include $(CFLAGS)
LD_OPT ?= -L../boringssl/build/ssl -L../boringssl/build/crypto -lstdc++

./configure подцепил BoringSSL, но с ним уже не собирается например:

In file included from src/http/ngx_http.h:33,
                 from module-brotli-v1-0-0rc/filter/ngx_http_brotli_filter_module.c:9:
module-brotli-v1-0-0rc/filter/ngx_http_brotli_filter_module.c: In function 'ngx_int_t ngx_http_brotli_header_filter(ngx_http_request_t*)':
src/http/ngx_http_config.h:58:80: error: invalid conversion from 'void*' to 'ngx_http_brotli_conf_t*' [-fpermissive]
   58 | #define ngx_http_get_module_loc_conf(r, module)  (r)->loc_conf[module.ctx_index]
      |                                                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
      |                                                                                |
      |                                                                                void*
asyslinux commented 1 day ago

Попробую дальше QuicTLS еще, а потом буду разбираться с LibreSSL + Lua

asyslinux commented 1 day ago

QuicTLS (3.1.5) - всё собралось без проблем и без указания --with-cc= на всех Debian 9/10/11/12

P.S. В сборке под Debian 9 отключены некоторые модули, они в нем просто не собираются.

CONFIGURE_ADD ?=
CONFIGURE_ENV ?=
CC_OPT ?= -I../quictls/include $(CFLAGS)
LD_OPT ?= -L../quictls/build/lib64
MAKE_TARGET ?=modules
OBJS_DIR ?=
root@srv:~# angie -V
Angie version: Angie/1.6.0
nginx version: nginx/1.27.0
built with OpenSSL 3.1.5+quic 30 Jan 2024
TLS SNI support enabled

Мало того, с Lua нет проблем сразу. Если подключить модуль load_module modules/ngx_http_lua_module.so; , то все в порядке:

# angie -t
angie: the configuration file /etc/nginx/nginx.conf syntax is ok
angie: configuration file /etc/nginx/nginx.conf test is successful
asyslinux commented 21 hours ago

C LibreSSL заставить работать lua пока не получилось. В LibreSSL вообще нет изначально SSL_client_hello_get0 функций.

Модуль lua версии 0.10.26 внутри себя имеет обработку:

#ifdef LIBRESSL_VERSION_NUMBER
        ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
                      "LibreSSL does not support by ssl_client_hello_by_lua*");
        return NGX_CONF_ERROR;

И в норме должно все бы работать, кроме некоторых функций типа ssl_client_hello_by_lua, а не ругаться при запуске сразу на undefined symbol. В общем я создал тикет разработчикам lua модуля, посмотрим что скажут.