feat(checks): add proxy protocol fingerprint check (#52) - #60
Conversation
Add a protocol-category check that auto-detects which proxy protocol a server actually speaks by probing it with SOCKS5, SOCKS4 and HTTP CONNECT greetings on separate connections, then validates the result against the user-configured --proxy-type. - SOCKS5 probe sends a no-auth method negotiation (05 01 00) and matches on a 0x05 version reply. - SOCKS4 probe sends a CONNECT for a fixed target and matches on the 0x00 reply version byte (distinct from the 0x04 request version). - HTTP CONNECT probe matches on an "HTTP/" reply prefix. - evaluateFingerprint is a pure helper: it reports the detected protocol, passes when declared matches (with https satisfying http detection, since both are HTTP CONNECT at the application layer), fails with a concrete --proxy-type suggestion on mismatch, errors when no greeting is answered, and handles auto-detection. Registered in core/checks/register.go and added to the README checks table. Tests use a hermetic net.Listener mock that replies per protocol dialect; no external network is required.
francomano
left a comment
There was a problem hiding this comment.
Richiesta di modifica: probeTimeout viene passato solo a net.DialTimeout; dopo la connessione, io.ReadFull e conn.Read non hanno una deadline. Un endpoint che accetta la TCP connection e non risponde può bloccare il check oltre 5 secondi (e oltre il timeout della diagnosi), in contrasto con la descrizione della PR. Imposta una read/write deadline per ogni connessione (e verifica con un test di peer silenzioso).
francomano
left a comment
There was a problem hiding this comment.
English version of my change request: probeTimeout is passed only to net.DialTimeout; after a connection is established, io.ReadFull and conn.Read have no deadline. An endpoint that accepts the TCP connection but never responds can block the check for more than five seconds (and beyond the diagnosis timeout), contrary to the PR description. Please set read/write deadlines on every connection and cover this with a silent-peer test.
Implements #52.
What
Adds a new protocol-category check,
proxy_fingerprint, that auto-detects which proxy protocol a server actually speaks and validates it against the configured--proxy-type.How
The check opens one fresh TCP connection per protocol and sends a minimal greeting, classifying the peer by how it replies:
05 01 000x050x00(distinct from the0x04request version)CONNECT 1.1.1.1:53 HTTP/1.1HTTP/Each probe is independent so a misbehaving peer cannot starve the others; a 5s per-handshake deadline bounds the whole check.
evaluateFingerprintis a pure, testable helper that decides the verdict:passed, reports the detected protocol and suggests pinning--proxy-type.passed.passed(both are HTTP CONNECT at the application layer; the plaintext probe cannot distinguish TLS-to-proxy).failedwith a concrete--proxy-type <detected>suggestion.error(endpoint offline, expects TLS, or unsupported protocol).failed, reports the multiprotocol result.Direct connections are skipped, consistent with the other proxy-only checks.
Files
core/checks/proxy_fingerprint/check.go— the check, probes, and pure verdict helper.core/checks/proxy_fingerprint/check_test.go— hermeticnet.Listenermock per protocol dialect; no external network.core/checks/register.go— registered inRegisterDefaults.README.md— row added to the built-in checks table.Tests
14 tests: detection of each protocol, declared-matches, https/http reconciliation, mismatch-with-suggestion, auto-detection, unreachable-endpoint error, skip-direct, and the pure verdict helper paths.