diff --git a/plugin.go b/plugin.go index f8ca326..c689492 100644 --- a/plugin.go +++ b/plugin.go @@ -205,7 +205,13 @@ func parserFor(canon string) func(string) string { func parseForwarded(v string) string { if m := forwardedRegex.FindStringSubmatch(v); len(m) > 1 { // An IPv6 address (and any node-port) MUST be quoted, so trim the quotes. - return strings.Trim(m[1], `"`) + node := strings.Trim(m[1], `"`) + // A bracketed IPv6 address without a port is not a valid IP, so strip the brackets. + if strings.HasPrefix(node, "[") && strings.HasSuffix(node, "]") { + return node[1 : len(node)-1] + } + + return node } return "" diff --git a/tests/proxy_ip_test.go b/tests/proxy_ip_test.go index 2a4fb21..b1b3167 100644 --- a/tests/proxy_ip_test.go +++ b/tests/proxy_ip_test.go @@ -84,6 +84,7 @@ func TestForwarded(t *testing.T) { want string }{ {"for element is extracted", "by=foo;for=3.11.0.1;host=foo.workstation;proto=http", "3.11.0.1"}, + {"bracketed IPv6 without port is unbracketed", `for="[2001:db8:cafe::17]";proto=http`, "2001:db8:cafe::17"}, {"trusted loopback stays loopback", "by=foo;for=127.0.0.1;host=foo.workstation;proto=http", loopback}, {"value without for= falls back to the peer", "foo.workstation", loopback}, } diff --git a/trusted_test.go b/trusted_test.go index a9c1494..fb2232c 100644 --- a/trusted_test.go +++ b/trusted_test.go @@ -29,6 +29,7 @@ func TestIP(t *testing.T) { {tcip, "8.8.8.8", "8.8.8.8"}, // Single address {forwarded, `for="_foo"`, "_foo"}, // Hostname {forwarded, `For="[2001:db8:cafe::17]:4711`, `[2001:db8:cafe::17]:4711`}, // IPv6 address + {forwarded, `for="[2001:db8:cafe::17]"`, `2001:db8:cafe::17`}, // IPv6 address without port {forwarded, `for=192.0.2.60;proto=http;by=203.0.113.43`, `192.0.2.60`}, // Multiple params {forwarded, `for=192.0.2.43, for=198.51.100.17`, "192.0.2.43"}, // Multiple params {forwarded, `for="workstation.local",for=198.51.100.17`, "workstation.local"}, // Hostname