mirror of
https://github.com/fosrl/gerbil.git
synced 2026-10-05 04:09:07 +02:00
Merge pull request #125 from breken-ai/fix/proxy-v4-mapped-source
▚▚ fix(proxy): write IPv4-mapped PROXY sources as TCP4 dotted addresses
This commit is contained in:
+7
-3
@@ -314,10 +314,14 @@ func (p *SNIProxy) buildProxyProtocolHeaderFromInfo(proxyInfo *ProxyProtocolInfo
|
||||
if srcIP == nil {
|
||||
return "PROXY UNKNOWN\r\n"
|
||||
}
|
||||
srcIPStr := proxyInfo.SrcIP
|
||||
|
||||
if srcIP.To4() != nil {
|
||||
// Source is IPv4, use TCP4 protocol
|
||||
if srcIP4 := srcIP.To4(); srcIP4 != nil {
|
||||
// Source is IPv4, use TCP4 protocol. Write it in dotted form: an
|
||||
// IPv4-mapped IPv6 source ("::ffff:a.b.c.d", as sent in a TCP6 line
|
||||
// by a dual-stack upstream) is not a valid TCP4 address.
|
||||
protocol = "TCP4"
|
||||
srcIPStr = srcIP4.String()
|
||||
if targetTCP.IP.To4() != nil {
|
||||
// Target is also IPv4, use as-is
|
||||
targetIP = targetTCP.IP.String()
|
||||
@@ -343,7 +347,7 @@ func (p *SNIProxy) buildProxyProtocolHeaderFromInfo(proxyInfo *ProxyProtocolInfo
|
||||
|
||||
return fmt.Sprintf("PROXY %s %s %s %d %d\r\n",
|
||||
protocol,
|
||||
proxyInfo.SrcIP,
|
||||
srcIPStr,
|
||||
targetIP,
|
||||
proxyInfo.SrcPort,
|
||||
targetTCP.Port)
|
||||
|
||||
@@ -185,3 +185,31 @@ func TestParseProxyProtocolHeaderUnknownPreservesPayload(t *testing.T) {
|
||||
t.Fatalf("Expected payload %q, got %q", payload, got)
|
||||
}
|
||||
}
|
||||
|
||||
// TestBuildProxyProtocolHeaderFromInfoIPv4MappedSource checks that an IPv4
|
||||
// client that a dual-stack upstream (e.g. HAProxy bound to "::") reports as
|
||||
// "PROXY TCP6 ::ffff:a.b.c.d ..." is forwarded with a valid TCP4 line.
|
||||
// PROXY v1 requires TCP4 addresses in dotted-quad form, and parsers such as
|
||||
// go-proxyproto (used by Traefik) reject "TCP4 ::ffff:a.b.c.d".
|
||||
func TestBuildProxyProtocolHeaderFromInfoIPv4MappedSource(t *testing.T) {
|
||||
proxy, err := NewSNIProxy(8443, "", "", "127.0.0.1", 443, nil, true, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create SNI proxy: %v", err)
|
||||
}
|
||||
|
||||
proxyInfo := &ProxyProtocolInfo{
|
||||
Protocol: "TCP6",
|
||||
SrcIP: "::ffff:203.0.113.7",
|
||||
DestIP: "::ffff:10.0.0.1",
|
||||
SrcPort: 51000,
|
||||
DestPort: 443,
|
||||
}
|
||||
|
||||
targetAddr, _ := net.ResolveTCPAddr("tcp", "127.0.0.1:8080")
|
||||
header := proxy.buildProxyProtocolHeaderFromInfo(proxyInfo, targetAddr)
|
||||
|
||||
expected := "PROXY TCP4 203.0.113.7 127.0.0.1 51000 8080\r\n"
|
||||
if header != expected {
|
||||
t.Errorf("Expected header %q, got %q", expected, header)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user