Вопрос или проблема
Мое приложение работает по модели:
HAproxy -> nginx -> Django
С этой моделью мое приложение работает хорошо, HAproxy распределяет нагрузки между запросами к nginx, затем nginx пересылает запросы в Django.
Но в журнале ошибок nginx постоянно возникает ошибка:
2024/09/06 07:54:53 [crit] 9#9: *13 SSL_read() failed (SSL: error:0A000126:SSL routines::unexpected eof while reading) while waiting for request, client: 10.84.112.171, server: 0.0.0.0:8005
где 10.84.112.171 – это IP-адрес хоста HAproxy, похоже, что HAproxy продолжает открывать новые соединения с nginx и быстро закрывает соединение.
Ключевая часть конфигурации HAproxy выглядит так:
frontend desperado
bind *:443 ssl crt /etc/haproxy/my_cert.pem
mode tcp
option forwardfor
option http-server-close
default_backend myservice
backend myservice
mode tcp
option forwardfor
balance roundrobin
server myservice001.mycompay.com:8005 check ssl verify none
server myservice002.mycompay.com:8005 check ssl verify none
Ключевая часть конфигурации nginx выглядит так:
server {
listen 80 default_server;
listen 443 ssl default_server;
ssl_certificate /etc/nginx/ssl/myservice/mycompany.crt;
ssl_certificate_key /etc/nginx/ssl/myservice/mycompany.key;
return 404;
}
server {
listen 80;
server_name myservice.maycompany.com;
return 301 https://myservice.maycompany.com/;
}
server {
listen 8005 ssl;
server_name myservice001.maycompany.com;
charset utf-8;
access_log /var/log/nginx/myservice.access.log;
error_log /var/log/nginx/myservice.error.log info;
gzip_types text/plain text/css text/xml text/javascript application/x-javascript;
client_max_body_size 75M; # подгоните по вкусу
client_body_buffer_size 128k;
ssl_certificate /etc/nginx/ssl/myservice/mycompany.crt;
ssl_certificate_key /etc/nginx/ssl/myservice/mycompany.key;
ssl_prefer_server_ciphers on;
location /static/ {
root /build/git/myservice/myservice; # статические файлы вашего проекта Django
}
# В конечном счете, отправляем все запросы, не относящиеся к медиафайлам, на сервер Django.
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://unix:/var/run/myservice.sock;
proxy_redirect off;
}
}
Я пытался искать в Google, но не нашел никакой полезной информации.
Я предполагаю, что проблема заключается в проверках работоспособности HAproxy. Это должно быть регулярной записью в ваших журналах. Существует много способов изменить поведение проверки. Вы можете добавить HTTP-уровень к этому или снизить его до уровня TCP/IP, используя option tcp-check
. В настоящее время он просто открывает соединение SSL/TLS, и когда оно успешно согласовано, закрывает его, что может сбить с толку nginx, поскольку он ожидал больше.
Ответ или решение
Проблема, с которой вы столкнулись, связана с тем, что HAProxy выполняет проверку состояния серверов в бэкенде, используя SSL-соединения, и после успешной установки соединения сразу его закрывает. Это может вызывать у NGINX недоумение, так как он ожидает, что после, казалось бы, успешной SSL-инициализации будет получен еще какой-то запрос, что и приводит к ошибке SSL_read() failed (SSL: error:0A000126:SSL routines::unexpected eof while reading)
.
Вот несколько шагов, которые помогут устранить данную проблему:
1. Измените метод проверки состояния в HAProxy
В вашем текущем конфиге HAProxy используется по умолчанию проверка состояния на основе уровня SSL. Это может быть изменено путем использования опции option tcp-check
. Эта опция подразумевает проверку на уровне TCP и позволяет избежать закрытия соединения после успешной установки SSL. Вот как это можно сделать:
backend myservice
mode tcp
option forwardfor
option tcp-check
balance roundrobin
server myservice001.mycompany.com:8005 check ssl verify none
server myservice002.mycompany.com:8005 check ssl verify none
2. Проверьте конфигурацию NGINX
Убедитесь, что конфигурация NGINX корректна и соответствует ожиданиям. Ваши настройки утверждают, что сервер слушает на 8005
и ожидает SSL-соединение. Это нормально, но вы также можете добавить более подробное логирование для отладки:
error_log /var/log/nginx/myservice.error.log debug;
Это позволит вам получать более подробные сообщения об ошибках.
3. Проверьте сертификаты и ключи
Проблема может быть связана с сертификатами или ключами. Убедитесь, что ваш SSL-сертификат и ключ правильно настроены и действительны. Вы можете протестировать их с помощью команды OpenSSL:
openssl s_client -connect your-nginx-host:8005
Проверьте, не возникает ли ошибок при установке соединения.
4. Проблемы сети
Если проблема не решается после изменения настроек HAProxy и NGINX, то стоит проверить сетевое взаимодействие. Это включает в себя:
- Убедитесь, что между HAProxy и NGINX нет сетевых ограничений, таких как файрволы, которые могут блокировать соединения.
- Проверьте настройки тайм-аутов на обоих серверах (HAProxy и NGINX). Возможно, они не совпадают и один из них закрывает соединение раньше, чем ожидается.
5. Пользуйтесь режимом HTTP в HAProxy
Еще один способ решения данной проблемы заключается в переходе на HTTP-уровень для бэкенда в HAProxy, если это возможно в вашей архитектуре. Использование HTTP вместо TCP может упростить проверку состояния. Например:
backend myservice
mode http
option httpchk GET /healthcheck
balance roundrobin
server myservice001.mycompany.com:8005 check
server myservice002.mycompany.com:8005 check
Не забудьте создать соответствующий маршрут проверки состояния в вашем приложении.
Заключение
Следуя данным рекомендациям, вы сможете устранить возникшую проблему с SSL в NGINX и улучшить взаимодействие между HAProxy и вашим NGINX-сервером. Если проблемы сохраняются, делайте выводы из сообщений об ошибках и корректируйте конфигурации, чтобы найти корень проблемы.