mirror of
https://github.com/caddyserver/caddy.git
synced 2025-10-19 07:43:17 +00:00
caddyhttp: Add trusted_proxies_unix
for trusting unix socket X-Forwarded-*
headers (#7265)
This commit is contained in:
parent
7fb39ec1e5
commit
d7185fd002
4 changed files with 118 additions and 0 deletions
|
@ -51,6 +51,7 @@ type serverOptions struct {
|
|||
StrictSNIHost *bool
|
||||
TrustedProxiesRaw json.RawMessage
|
||||
TrustedProxiesStrict int
|
||||
TrustedProxiesUnix bool
|
||||
ClientIPHeaders []string
|
||||
ShouldLogCredentials bool
|
||||
Metrics *caddyhttp.Metrics
|
||||
|
@ -251,6 +252,12 @@ func unmarshalCaddyfileServerOptions(d *caddyfile.Dispenser) (any, error) {
|
|||
}
|
||||
serverOpts.TrustedProxiesStrict = 1
|
||||
|
||||
case "trusted_proxies_unix":
|
||||
if d.NextArg() {
|
||||
return nil, d.ArgErr()
|
||||
}
|
||||
serverOpts.TrustedProxiesUnix = true
|
||||
|
||||
case "client_ip_headers":
|
||||
headers := d.RemainingArgs()
|
||||
for _, header := range headers {
|
||||
|
@ -342,6 +349,7 @@ func applyServerOptions(
|
|||
server.TrustedProxiesRaw = opts.TrustedProxiesRaw
|
||||
server.ClientIPHeaders = opts.ClientIPHeaders
|
||||
server.TrustedProxiesStrict = opts.TrustedProxiesStrict
|
||||
server.TrustedProxiesUnix = opts.TrustedProxiesUnix
|
||||
server.Metrics = opts.Metrics
|
||||
if opts.ShouldLogCredentials {
|
||||
if server.Logs == nil {
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
{
|
||||
servers {
|
||||
trusted_proxies_unix
|
||||
}
|
||||
}
|
||||
|
||||
example.com {
|
||||
reverse_proxy https://local:8080
|
||||
}
|
||||
----------
|
||||
{
|
||||
"apps": {
|
||||
"http": {
|
||||
"servers": {
|
||||
"srv0": {
|
||||
"listen": [
|
||||
":443"
|
||||
],
|
||||
"routes": [
|
||||
{
|
||||
"match": [
|
||||
{
|
||||
"host": [
|
||||
"example.com"
|
||||
]
|
||||
}
|
||||
],
|
||||
"handle": [
|
||||
{
|
||||
"handler": "subroute",
|
||||
"routes": [
|
||||
{
|
||||
"handle": [
|
||||
{
|
||||
"handler": "reverse_proxy",
|
||||
"transport": {
|
||||
"protocol": "http",
|
||||
"tls": {}
|
||||
},
|
||||
"upstreams": [
|
||||
{
|
||||
"dial": "local:8080"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"terminal": true
|
||||
}
|
||||
],
|
||||
"trusted_proxies_unix": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -202,6 +202,13 @@ type Server struct {
|
|||
// This option is disabled by default.
|
||||
TrustedProxiesStrict int `json:"trusted_proxies_strict,omitempty"`
|
||||
|
||||
// If greater than zero, enables trusting socket connections
|
||||
// (e.g. Unix domain sockets) as coming from a trusted
|
||||
// proxy.
|
||||
//
|
||||
// This option is disabled by default.
|
||||
TrustedProxiesUnix bool `json:"trusted_proxies_unix,omitempty"`
|
||||
|
||||
// Enables access logging and configures how access logs are handled
|
||||
// in this server. To minimally enable access logs, simply set this
|
||||
// to a non-null, empty struct.
|
||||
|
@ -941,6 +948,17 @@ func determineTrustedProxy(r *http.Request, s *Server) (bool, string) {
|
|||
return false, ""
|
||||
}
|
||||
|
||||
if s.TrustedProxiesUnix && r.RemoteAddr == "@" {
|
||||
if s.TrustedProxiesStrict > 0 {
|
||||
ipRanges := []netip.Prefix{}
|
||||
if s.trustedProxies != nil {
|
||||
ipRanges = s.trustedProxies.GetIPRanges(r)
|
||||
}
|
||||
return true, strictUntrustedClientIp(r, s.ClientIPHeaders, ipRanges, "@")
|
||||
} else {
|
||||
return true, trustedRealClientIP(r, s.ClientIPHeaders, "@")
|
||||
}
|
||||
}
|
||||
// Parse the remote IP, ignore the error as non-fatal,
|
||||
// but the remote IP is required to continue, so we
|
||||
// just return early. This should probably never happen
|
||||
|
|
|
@ -297,6 +297,39 @@ func TestServer_DetermineTrustedProxy_TrustedLoopback(t *testing.T) {
|
|||
assert.Equal(t, clientIP, "31.40.0.10")
|
||||
}
|
||||
|
||||
func TestServer_DetermineTrustedProxy_UnixSocket(t *testing.T) {
|
||||
server := &Server{
|
||||
ClientIPHeaders: []string{"X-Forwarded-For"},
|
||||
TrustedProxiesUnix: true,
|
||||
}
|
||||
|
||||
req := httptest.NewRequest("GET", "/", nil)
|
||||
req.RemoteAddr = "@"
|
||||
req.Header.Set("X-Forwarded-For", "2.2.2.2, 3.3.3.3")
|
||||
|
||||
trusted, clientIP := determineTrustedProxy(req, server)
|
||||
|
||||
assert.True(t, trusted)
|
||||
assert.Equal(t, "2.2.2.2", clientIP)
|
||||
}
|
||||
|
||||
func TestServer_DetermineTrustedProxy_UnixSocketStrict(t *testing.T) {
|
||||
server := &Server{
|
||||
ClientIPHeaders: []string{"X-Forwarded-For"},
|
||||
TrustedProxiesUnix: true,
|
||||
TrustedProxiesStrict: 1,
|
||||
}
|
||||
|
||||
req := httptest.NewRequest("GET", "/", nil)
|
||||
req.RemoteAddr = "@"
|
||||
req.Header.Set("X-Forwarded-For", "2.2.2.2, 3.3.3.3")
|
||||
|
||||
trusted, clientIP := determineTrustedProxy(req, server)
|
||||
|
||||
assert.True(t, trusted)
|
||||
assert.Equal(t, "3.3.3.3", clientIP)
|
||||
}
|
||||
|
||||
func TestServer_DetermineTrustedProxy_UntrustedPrefix(t *testing.T) {
|
||||
loopbackPrefix, _ := netip.ParsePrefix("127.0.0.1/8")
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue