«400 неправильных запросов» ответ на (казалось бы) правильный HTTP-запрос

#http #header

Вопрос:

У меня есть устройство, счетчик Гейгера, который запрограммирован на выдачу HTTP-запроса в моей локальной сети на сервер Apache в той же сети. Этот сервер всегда отвечает «400 плохих запросов». В соответствии с этим в журнале ошибок Apache говорится: «AH00566: ошибка запроса: неправильно сформированная строка запроса».

Теперь я копирую эту «искаженную» строку, взятую из вывода wireshark, и ввожу эту строку в браузер (используются как Firefox, так и Chrome): сервер выдает ответ 200 и, конечно же, без ошибок. Так что, по-видимому, HTTP-запрос является правильным. Почему его нет, когда он исходит от счетчика Гейгера?

Должен ли wireshark не давать ответа? Я достиг своего предела в интерпретации wireshark, и я надеюсь, что вы сможете помочь.

Я прилагаю 2 строки из wireshark, запрос и ответ, полностью развернутые, в надежде, что в них содержится то, на что мне нужно обратить внимание.

ИЗМЕНИТЬ: Теперь я добавил модуль mod_log_forensic на свой сервер Apache. Это должно дать мне всю информацию о заголовках до и после их обработки. Облом в том, что он дает мне всю информацию о заголовке, когда запрос выполняется успешно, но ничего не дает, когда он завершается неудачей, как в моих случаях с «неправильными запросами». Я не вижу никаких опций для установки этого модуля :-((


 HTTP request of device at 10.0.0.42 to server at 10.0.0.20:
====================================================================================================
Frame 67003: 165 bytes on wire (1320 bits), 165 bytes captured (1320 bits) on interface 0
    Interface id: 0 (enp3s0)
        Interface name: enp3s0
    Encapsulation type: Ethernet (1)
    Arrival Time: Sep  4, 2021 10:28:38.486223543 CEST
    [Time shift for this packet: 0.000000000 seconds]
    Epoch Time: 1630744118.486223543 seconds
    [Time delta from previous captured frame: 0.317684532 seconds]
    [Time delta from previous displayed frame: 63.093693181 seconds]
    [Time since reference or first frame: 3654.295052488 seconds]
    Frame Number: 67003
    Frame Length: 165 bytes (1320 bits)
    Capture Length: 165 bytes (1320 bits)
    [Frame is marked: False]
    [Frame is ignored: False]
    [Protocols in frame: eth:ethertype:ip:tcp:http]
    [Coloring Rule Name: HTTP]
    [Coloring Rule String: http || tcp.port == 80 || http2]
Ethernet II, Src: Espressi_36:ac:ba (a0:20:a6:36:ac:ba), Dst: AsustekC_c3:68:12 (ac:22:0b:c3:68:12)
    Destination: AsustekC_c3:68:12 (ac:22:0b:c3:68:12)
        Address: AsustekC_c3:68:12 (ac:22:0b:c3:68:12)
        .... ..0. .... .... .... .... = LG bit: Globally unique address (factory default)
        .... ...0 .... .... .... .... = IG bit: Individual address (unicast)
    Source: Espressi_36:ac:ba (a0:20:a6:36:ac:ba)
        Address: Espressi_36:ac:ba (a0:20:a6:36:ac:ba)
        .... ..0. .... .... .... .... = LG bit: Globally unique address (factory default)
        .... ...0 .... .... .... .... = IG bit: Individual address (unicast)
    Type: IPv4 (0x0800)
Internet Protocol Version 4, Src: 10.0.0.42, Dst: 10.0.0.20
    0100 .... = Version: 4
    .... 0101 = Header Length: 20 bytes (5)
    Differentiated Services Field: 0x00 (DSCP: CS0, ECN: Not-ECT)
        0000 00.. = Differentiated Services Codepoint: Default (0)
        .... ..00 = Explicit Congestion Notification: Not ECN-Capable Transport (0)
    Total Length: 151
    Identification: 0x0006 (6)
    Flags: 0x0000
        0... .... .... .... = Reserved bit: Not set
        .0.. .... .... .... = Don't fragment: Not set
        ..0. .... .... .... = More fragments: Not set
        ...0 0000 0000 0000 = Fragment offset: 0
    Time to live: 127
    Protocol: TCP (6)
    Header checksum: 0x271e [validation disabled]
    [Header checksum status: Unverified]
    Source: 10.0.0.42
    Destination: 10.0.0.20
Transmission Control Protocol, Src Port: 17062, Dst Port: 80, Seq: 1, Ack: 1, Len: 111
    Source Port: 17062
    Destination Port: 80
    [Stream index: 347]
    [TCP Segment Len: 111]
    Sequence number: 1    (relative sequence number)
    [Next sequence number: 112    (relative sequence number)]
    Acknowledgment number: 1    (relative ack number)
    0101 .... = Header Length: 20 bytes (5)
    Flags: 0x018 (PSH, ACK)
        000. .... .... = Reserved: Not set
        ...0 .... .... = Nonce: Not set
        .... 0... .... = Congestion Window Reduced (CWR): Not set
        .... .0.. .... = ECN-Echo: Not set
        .... ..0. .... = Urgent: Not set
        .... ...1 .... = Acknowledgment: Set
        .... .... 1... = Push: Set
        .... .... .0.. = Reset: Not set
        .... .... ..0. = Syn: Not set
        .... .... ...0 = Fin: Not set
        [TCP Flags: ·······AP···]
    Window size value: 2920
    [Calculated window size: 2920]
    [Window size scaling factor: -2 (no window scaling used)]
    Checksum: 0xf631 [unverified]
    [Checksum Status: Unverified]
    Urgent pointer: 0
    [SEQ/ACK analysis]
        [iRTT: 0.004491340 seconds]
        [Bytes in flight: 111]
        [Bytes sent since last PSH flag: 111]
    [Timestamps]
        [Time since first frame in this TCP stream: 0.322175872 seconds]
        [Time since previous frame in this TCP stream: 0.317684532 seconds]
    TCP payload (111 bytes)
Hypertext Transfer Protocol
    GET /?AID=0123amp;GID=4567amp;CPM=22amp;ACPM=20.39amp;uSV=0.14 HTTP/1.1n
        [Expert Info (Chat/Sequence): GET /?AID=0123amp;GID=4567amp;CPM=22amp;ACPM=20.39amp;uSV=0.14 HTTP/1.1n]
            [GET /?AID=0123amp;GID=4567amp;CPM=22amp;ACPM=20.39amp;uSV=0.14 HTTP/1.1n]
            [Severity level: Chat]
            [Group: Sequence]
        Request Method: GET
        Request URI: /?AID=0123amp;GID=4567amp;CPM=22amp;ACPM=20.39amp;uSV=0.14
            Request URI Path: /
            Request URI Query: AID=0123amp;GID=4567amp;CPM=22amp;ACPM=20.39amp;uSV=0.14
                Request URI Query Parameter: AID=0123
                Request URI Query Parameter: GID=4567
                Request URI Query Parameter: CPM=22
                Request URI Query Parameter: ACPM=20.39
                Request URI Query Parameter: uSV=0.14
        Request Version: HTTP/1.1
    Host: 10.0.0.20rn
    Connection: closern
    Accept: */*rn
    rn
    [Full request URI: http://10.0.0.20/?AID=0123amp;GID=4567amp;CPM=22amp;ACPM=20.39amp;uSV=0.14]
    [HTTP request 1/1]
    [Response in frame: 67005]

====================================================================================================
====================================================================================================


HTTP response of server at 10.0.0.20 to device at 10.0.0.42 :
====================================================================================================
Frame 67005: 538 bytes on wire (4304 bits), 538 bytes captured (4304 bits) on interface 0
    Interface id: 0 (enp3s0)
        Interface name: enp3s0
    Encapsulation type: Ethernet (1)
    Arrival Time: Sep  4, 2021 10:28:38.486469123 CEST
    [Time shift for this packet: 0.000000000 seconds]
    Epoch Time: 1630744118.486469123 seconds
    [Time delta from previous captured frame: 0.000198404 seconds]
    [Time delta from previous displayed frame: 0.000245580 seconds]
    [Time since reference or first frame: 3654.295298068 seconds]
    Frame Number: 67005
    Frame Length: 538 bytes (4304 bits)
    Capture Length: 538 bytes (4304 bits)
    [Frame is marked: False]
    [Frame is ignored: False]
    [Protocols in frame: eth:ethertype:ip:tcp:http:data-text-lines]
    [Coloring Rule Name: HTTP]
    [Coloring Rule String: http || tcp.port == 80 || http2]
Ethernet II, Src: AsustekC_c3:68:12 (ac:22:0b:c3:68:12), Dst: Espressi_36:ac:ba (a0:20:a6:36:ac:ba)
    Destination: Espressi_36:ac:ba (a0:20:a6:36:ac:ba)
        Address: Espressi_36:ac:ba (a0:20:a6:36:ac:ba)
        .... ..0. .... .... .... .... = LG bit: Globally unique address (factory default)
        .... ...0 .... .... .... .... = IG bit: Individual address (unicast)
    Source: AsustekC_c3:68:12 (ac:22:0b:c3:68:12)
        Address: AsustekC_c3:68:12 (ac:22:0b:c3:68:12)
        .... ..0. .... .... .... .... = LG bit: Globally unique address (factory default)
        .... ...0 .... .... .... .... = IG bit: Individual address (unicast)
    Type: IPv4 (0x0800)
Internet Protocol Version 4, Src: 10.0.0.20, Dst: 10.0.0.42
    0100 .... = Version: 4
    .... 0101 = Header Length: 20 bytes (5)
    Differentiated Services Field: 0x00 (DSCP: CS0, ECN: Not-ECT)
        0000 00.. = Differentiated Services Codepoint: Default (0)
        .... ..00 = Explicit Congestion Notification: Not ECN-Capable Transport (0)
    Total Length: 524
    Identification: 0x8870 (34928)
    Flags: 0x4000, Don't fragment
        0... .... .... .... = Reserved bit: Not set
        .1.. .... .... .... = Don't fragment: Set
        ..0. .... .... .... = More fragments: Not set
        ...0 0000 0000 0000 = Fragment offset: 0
    Time to live: 64
    Protocol: TCP (6)
    Header checksum: 0x9c3e [validation disabled]
    [Header checksum status: Unverified]
    Source: 10.0.0.20
    Destination: 10.0.0.42
Transmission Control Protocol, Src Port: 80, Dst Port: 17062, Seq: 1, Ack: 112, Len: 484
    Source Port: 80
    Destination Port: 17062
    [Stream index: 347]
    [TCP Segment Len: 484]
    Sequence number: 1    (relative sequence number)
    [Next sequence number: 485    (relative sequence number)]
    Acknowledgment number: 112    (relative ack number)
    0101 .... = Header Length: 20 bytes (5)
    Flags: 0x018 (PSH, ACK)
        000. .... .... = Reserved: Not set
        ...0 .... .... = Nonce: Not set
        .... 0... .... = Congestion Window Reduced (CWR): Not set
        .... .0.. .... = ECN-Echo: Not set
        .... ..0. .... = Urgent: Not set
        .... ...1 .... = Acknowledgment: Set
        .... .... 1... = Push: Set
        .... .... .0.. = Reset: Not set
        .... .... ..0. = Syn: Not set
        .... .... ...0 = Fin: Not set
        [TCP Flags: ·······AP···]
    Window size value: 64129
    [Calculated window size: 64129]
    [Window size scaling factor: -2 (no window scaling used)]
    Checksum: 0x25ca [unverified]
    [Checksum Status: Unverified]
    Urgent pointer: 0
    [SEQ/ACK analysis]
        [iRTT: 0.004491340 seconds]
        [Bytes in flight: 484]
        [Bytes sent since last PSH flag: 484]
    [Timestamps]
        [Time since first frame in this TCP stream: 0.322421452 seconds]
        [Time since previous frame in this TCP stream: 0.000198404 seconds]
    TCP payload (484 bytes)
Hypertext Transfer Protocol
    HTTP/1.1 400 Bad Requestrn
        [Expert Info (Chat/Sequence): HTTP/1.1 400 Bad Requestrn]
            [HTTP/1.1 400 Bad Requestrn]
            [Severity level: Chat]
            [Group: Sequence]
        Response Version: HTTP/1.1
        Status Code: 400
        [Status Code Description: Bad Request]
        Response Phrase: Bad Request
    Date: Sat, 04 Sep 2021 08:28:38 GMTrn
    Server: Apache/2.4.18 (Ubuntu)rn
    Content-Length: 302rn
        [Content length: 302]
    Connection: closern
    Content-Type: text/html; charset=iso-8859-1rn
    rn
    [HTTP response 1/1]
    [Time since request: 0.000245580 seconds]
    [Request in frame: 67003]
    [Request URI: http://10.0.0.20/?AID=0123amp;GID=4567amp;CPM=22amp;ACPM=20.39amp;uSV=0.14]
    File Data: 302 bytes
Line-based text data: text/html (10 lines)
    <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">n
    <html><head>n
    <title>400 Bad Request</title>n
    </head><body>n
    <h1>Bad Request</h1>n
    <p>Your browser sent a request that this server could not understand.<br />n
    </p>n
    <hr>n
    <address>Apache/2.4.18 (Ubuntu) Server at meinserver Port 80</address>n
    </body></html>n
 

Ответ №1:

Вопрос нашел ответ в Wireshark: https://ask.wireshark.org/question/24316/where-do-i-even-look-to-find-the-reason-for-a-400-bad-request/?answer=24330#post-id-24330

Проблема в том, что счетчик Гейгера сформировал http-запрос, который не полностью соответствует правилам http: https://datatracker.ietf.org/doc/html/rfc7230#section-3.5

Т. е. он завершил http-запрос только с помощью LF, в то время как он должен был отправить CRLF.

Сервер Microsoft ASP принимает это, в то время как сервер Apache отклоняет это как проблему безопасности (https://httpd.apache.org/security/vulnerabilities_24.html, прокрутите до: «важно: Дефекты разбора пробелов HTTP-запроса Apache (CVE-2016-8743)»)

Можно преодолеть отклонение Apache, вставив HttpProtocolOptions Unsafe в apache2.conf . Протестировано на моем локальном сервере Apache, и это работает!

Интересно, как отнесутся администраторы к вставке слова «Небезопасно» в свои конфигурационные файлы …