Рейтинг:0

Как устранить неполадку 400 Bad Request «клиент отправил неверный метод при чтении строки запроса клиента»

флаг cn

Я настроил nginx для разрыва SSL-соединения и пересылки запросов на http-сервер. Клиент делает несколько фоновых запросов, один из которых завершается с ошибкой 400 неверный запрос всякий раз, когда он пытается согласовать соединение SSL. Если ему не нужно согласовывать соединение - например. если другой фоновый запрос только что успешно отправлен, запрос выполняется успешно. Изучение вкладки сети Chrome не показывает существенной разницы между успешным запросом и неудачным запросом. Мое путешествие опубликовано здесь в этот отчет об ошибке, но вот что я смог перегонять до сих пор:

SSL-соединение

Когда запрос о проблеме выполняется успешно, я могу сказать, что ему не нужно согласовывать SSL-соединение, просмотрев вкладку «Время» сетевого запроса (в Chrome): Время - успешный запрос

С другой стороны, всякий раз, когда запрос терпит неудачу, я вижу, что он пытался согласовать SSL-соединение, как показано на этом изображении: Время — неудавшийся запрос

Обработка Nginx

Проверив журналы доступа к приложениям, я определил, что именно nginx возвращает ошибка 400, неверный запрос ошибка, а не приложение HTTP.Когда запрос завершается неудачно, все журналы nginx являются телом POST. скорее, чем метод HTTP и URL как обычно (я не настраивал формат журнала nginx).

Я включил отладку в журнале ошибок nginx (со строкой error_log /var/log/nginx/error.log отладка;). Это позволяет мне видеть, что происходит во время согласования SSL (хотя я этого не понимаю).

Как я кратко упомянул выше, есть и другие фоновые запросы, которые выполняются успешно, хотя и выполняются реже. После успешного выполнения любого запроса все запросы будут выполняться в течение определенного периода времени (пока им не потребуется согласовать SSL-соединение).

Кроме того, если я использую Скопировать как cURL функциональность из Chrome и запустить запрос как запрос cURL, он всегда завершается успешно. Единственный раз, когда я заметил, что это не удается, - это когда браузер делает запрос.

Журналы отладки Nginx

Вот соответствующий бит из успешного запроса SSL в журналах:

22.10.2021 20:37:59 [отладка] 1858722#1858722: *441 бесплатно: 0000562A9F69F340
22.10.2021, 20:37:59 [отладка] 1858722#1858722: *438 http восходящий запрос: "/api/method/frappe.core.doctype.log_settings.log_settings.has_unseen_error_log?"
22.10.2021, 20:37:59 [отладка] 1858722#1858722: *438 HTTP заголовок восходящего процесса
22.10.2021 20:37:59 [отладка] 1858722#1858722: *438 malloc: 0000562A9F712CB0:131072
22.10.2021, 20:37:59 [отладка] 1858722#1858722: *438 recv: eof:0, avail:-1
22.10.2021, 20:37:59 [отладка] 1858722#1858722: *438 recv: fd:9 678 из 131072
22.10.2021, 20:37:59 [отладка] 1858722#1858722: *438 статус HTTP-прокси 200 «200 OK»
22.10.2021, 20:37:59 [отладка] 1858722#1858722: *438 заголовок http-прокси: «Сервер: gunicorn»
... больше заголовков http-прокси ...
22.10.2021, 20:37:59 [отладка] 1858722#1858722: *438 HTTP-заголовок прокси выполнен
22.10.2021, 20:37:59 [отладка] 1858722#1858722: *438 заголовок фильтра xslt
22.10.2021 20:37:59 [отладка] 1858722#1858722: *438 HTTP/1.1 200 ОК
Сервер: nginx/1.18.0 (Ubuntu)
... HTTP-ответ

Вот неудачные переговоры:

22.10.2021, 20:39:00 [отладка] 1858722#1858722: *446 бесплатно: 0000562A9F69F340
22.10.2021, 20:39:00 [отладка] 1858722#1858722: *446 обработчик запроса ожидания HTTP
22.10.2021, 20:39:00 [отладка] 1858722#1858722: *446 malloc: 0000562A9F69F340:1024
22.10.2021, 20:39:00 [отладка] 1858722#1858722: *446 SSL_read: 812
22.10.2021, 20:39:00 [отладка] 1858722#1858722: *446 SSL_read: -1
22.10.2021, 20:39:00 [отладка] 1858722#1858722: *446 SSL_get_error: 2
22.10.2021, 20:39:00 [отладка] 1858722#1858722: *446 многоразовое соединение: 0
22.10.2021, 20:39:00 [отладка] 1858722#1858722: *446 posix_memalign: 0000562A9F70CEB0:4096 @16
22.10.2021, 20:39:00 [отладка] 1858722#1858722: *446 строка запроса процесса http
22.10.2021, 20:39:00 [информация] 1858722#1858722: *446 клиент отправил неверный метод при чтении строки запроса клиента, клиент: 107.185.20.83, сервер: atlas-dev.ebs.llc, запрос: "doctype= Error+Log&fields=%5B%22%60tabError+Log%60.%60name%60%22%2C%22%60tabError+Log%60.%60owner%60%22%2C%22%60tabError+Log%60.% 60creation%60%22%2C%22%60tabError+Log%60.%60modified%60%22%2C%22%60tabError+Log%60.%60modified_by%60%22%2C%22%60tabError+Log%60. %60_user_tags%60%22%2C%22%60tabError+Log%60.%60_comments%60%22%2C%22%60tabError+Log%60.%60_assign%60%22%2C%22%60tabError+Log%60 .%60_liked_by%60%22%2C%22%60tabError+Log%60.%60docstatus%60%22%2C%22%60tabError+Log%60.%60parent%60%22%2C%22%60tabError+Log% 60.%60parenttype%60%22%2C%22%60tabError+Log%60.%60parentfield%60%22%2C%22%60tabError+Log%60.%60idx%60%22%2C%22%60tabError+Log %60.%60method%60%22%2C%22%60tabError+Log%60.%60seen%60%22%5D&filters=%5B%5D&order_by=%60tabError+Log%60.%60modified%60+desc&start=0&page_length= 20&view=Список&with_comment_count=true"
22.10.2021, 20:39:00 [отладка] 1858722#1858722: *446 http finalize request: 400, "?" а:1, в:1
22.10.2021, 20:39:00 [отладка] 1858722#1858722: *446 таймер событий del: 9: 337737968
22.10.2021, 20:39:00 [отладка] 1858722#1858722: *446 специальный ответ http: 400, "?"
22.10.2021, 20:39:00 [отладка] 1858722#1858722: *446 http set discard body
22.10.2021, 20:39:00 [отладка] 1858722#1858722: *446 заголовок фильтра xslt
22.10.2021, 20:39:00 [отладка] 1858722#1858722: *446 HTTP/1.1 400 Неверный запрос
Сервер: nginx/1.18.0 (Ubuntu)
Дата: пятница, 22 октября 2021 г., 20:39:00 по Гринвичу
Тип содержимого: текст/html
Длина контента: 166
Подключение: близко

Основываясь на том немногом, что я знаю о журнале отладки nginx (то есть ничего), мне кажется, что nginx меняет HTTP-метод и URL-адрес тела во время согласования. Когда он ищет метод HTTP, его больше нет, и он задыхается.

Конфигурация Nginx SSL

Информация о версии: nginx/1.18.0 (Убунту), Убунту 20.04 ЛТС я использую по умолчанию nginx.conf. SSL-часть конфигурации сервера выглядит следующим образом:

слушать 443 ssl;

имя_сервера [ХОСТ];

корень /opt/erpnext/bench/sites;

proxy_buffer_size 128k;
proxy_buffers 4 256 КБ;
proxy_busy_buffers_size 256 КБ;

ssl_certificate /etc/letsencrypt/live/[HOST]/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/[HOST]/privkey.pem;
ssl_session_timeout 5 м;
ssl_session_cache общий: SSL: 10 м;
ssl_session_tickets выключен;
ssl_stapling включен;
ssl_stapling_verify включен;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers EECDH+AESGCM:EDH+AESGCM;
ssl_ecdh_curve secp384r1;
ssl_prefer_server_ciphers включен;

В нижней части файла есть перенаправление SSL, и nginx настроен для сервера веб-сервера HTTP на основе плоского файла на порту 8080 из другой конфигурации.

Как я могу определить, что вызывает проблему? Я знаю, что запрос сформирован правильно, потому что идентичные запросы выполняются... до тех пор, пока не потребуется согласовать SSL-соединение. Помощь?

dave_thompson_085 avatar
флаг jp
{voice='CrocodileDundee'} это не пересмотр. В TLS 1.2 и более ранних версиях повторное согласование — это, в частности, новое рукопожатие для изменения параметров безопасности _существующего_ соединения. Я не думаю, что какой-либо браузер когда-либо инициирует его, хотя другие типы клиентов могут или, по крайней мере, могут; после нескольких уязвимостей (которые привели к тому, что многие системы запретили или заблокировали его) и исправлений (см. rfc5746) в повторном согласовании TLS1.3 было полностью удалено. ...
dave_thompson_085 avatar
флаг jp
... То, что у вас есть, это OT1H (повторное) использование существующего соединения (и сеанса) или OTOH, создающий новое соединение, которое всегда использует начальное рукопожатие/согласование в 1.2 или просто рукопожатие (не нужно отличать как начальный) в 1.3; это рукопожатие может и для браузера почти наверняка использует **возобновление** предыдущего _сеанса_ (в 1.3 фактически PSK, полученный из предыдущего сеанса, для прямой секретности). Однако исправление имени не поможет решить вашу проблему, извините.
jobu1342 avatar
флаг cn
Так ты говоришь, что это согласование нового соединения, а не пересмотр старого? Извините, что не использовал для этого технические термины - как вы догадались, я здесь не в своей тарелке. Конечно, поэтому я ищу помощи!
dave_thompson_085 avatar
флаг jp
Точно! Это не столько неумение использовать технические термины, сколько случайное _неправильное_ использование_ одного из них таким образом, что это может легко ввести в заблуждение именно тех людей, которым вы хотите помочь.
jobu1342 avatar
флаг cn
Я обновил вопрос - спасибо за разъяснение!
jobu1342 avatar
флаг cn
Я только что провел кросс-браузерное и даже кросс-машинное тестирование. не все браузеры терпят неудачу, хотя я не обнаружил никаких шаблонов: НЕУДАЧА: Google Chrome (Win10), Edge (Win10), Opera (Win10, новая установка). Успех: FireFox, Brave, Vivaldi, Google Chrome (Kubuntu 21.10), Google Chrome (Win10). Примечательно, что Google Chrome работает или не работает в зависимости от компьютера. Мои тесты не были исчерпывающими, но они предполагают ошибку, связанную с локальной установкой. Я собираюсь переустановить Chrome на целевой компьютер, чтобы посмотреть, начнет ли он работать.
jobu1342 avatar
флаг cn
Итак... оказывается, мой антивирус работал не на должном уровне. Когда я выключаю AV, я вообще не испытываю этой проблемы.

Ответить или комментировать

Большинство людей не понимают, что склонность к познанию нового открывает путь к обучению и улучшает межличностные связи. В исследованиях Элисон, например, хотя люди могли точно вспомнить, сколько вопросов было задано в их разговорах, они не чувствовали интуитивно связи между вопросами и симпатиями. В четырех исследованиях, в которых участники сами участвовали в разговорах или читали стенограммы чужих разговоров, люди, как правило, не осознавали, что задаваемый вопрос повлияет — или повлиял — на уровень дружбы между собеседниками.