Skip to content

mod_remoteip: PROXY protocol LOCAL tests, and log EOF before the header at info level (PR 63893) - #805

Closed
notroj wants to merge 1 commit into
apache:trunkfrom
notroj:remoteip-pp-local
Closed

notroj wants to merge 1 commit into
apache:trunkfrom
notroj:remoteip-pp-local

Conversation

@notroj

@notroj notroj commented Oct 8, 2026 •

Copy link
Copy Markdown
Collaborator

Tests for the PROXY protocol v2 LOCAL command (Bugzilla 63893), and a fix
for the remaining log noise from health-check probes that connect and go
away before sending a header.

Analysis by @claude:

The reported symptom is already fixed on trunk. "unsupported command 20"
and the AH03496 400 for a LOCAL header (ver_cmd 0x20) were addressed by
r1874344 (2020, accept LOCAL) and 22dc622fc5 (2026, keep the connection's
own address so nothing dereferences a NULL client_addr). The later reports
on the bug are against 2.4.x, which never received those; the tests here are
the regression check for that backport, which is a separate change.

What still reproduced is comment 12: AH10184 "failed reading input"
with (70014)End of file found, logged at ERR. Measured on a built tree: a
bare TCP connect + FIN with no data reaches the filter (TCP_DEFER_ACCEPT
hands a FIN'd connection up) and its first read is EOF — the shape of a
load balancer's TCP-level health probe, one ERR line per probe.

Fix: APR_EOF while waiting for the header is logged at INFO as the
peer going away, matching mod_ssl's AH02006 for the analogous handshake
case. Every other failure, ECONNRESET included, still logs AH10184 at
ERR. ctx->done is not touched: it continues to mean only that a full
header was read; one probe logs exactly once, since after EOF on the
request-line read the filter is not re-entered.

Tests (test/modules/metadata/test_004_remoteip.py, on a dedicated
listener so the harness's own requests are unaffected; the client address
httpd logs is checked via %a):

  • 004_03 PROXY command, TCPv4 addresses — 200, client is the header's source
  • 004_04 LOCAL, no addresses — 200, client is the peer (the bug's case)
  • 004_05 LOCAL with an address block — 200, addresses ignored, per spec
  • 004_06 signature only, then disconnect — no error logged

Per the spec a LOCAL connection "must [be accepted] as valid … using the
real connection endpoints"; the HTTP health check that follows the header is
what the 400 was failing, so the connection is kept open, not closed.

Also fixed, found by the UBSan job on the first run: the header read loop
memcpy()d every bucket, and at socket EOF the core hands up an EOS bucket
(ptr == NULL, len == 0) before reporting APR_EOF, so a peer disconnecting
mid-header reached memcpy(dst, NULL, 0) — pre-existing, now exposed by
004_06. Metadata buckets are skipped.

test/modules/metadata: 90 passed. Tests and fix are one commit. The
APLOGNO() is left bare for numbering at merge, so the aplogno check is
red by design.

🤖 Generated with Claude Code

…der,

and test the LOCAL command.  PR 63893.

* modules/metadata/mod_remoteip.c (remoteip_input_filter): Log EOF while
  reading the PROXY protocol header at info level, as the peer going away;
  other read errors are still logged as errors.  Skip metadata buckets
  rather than copying from them: the EOS bucket arriving before the EOF
  was passed to memcpy() as a NULL source.

* test/modules/metadata/test_004_remoteip.py (test_metadata_004_03,
  test_metadata_004_04, test_metadata_004_05, test_metadata_004_06): Test
  PROXY protocol v2 with the PROXY and LOCAL commands, with and without an
  address block, and a peer disconnecting after a partial header.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant