caddytls,caddyhttp: Placeholders for some TLS and HTTP matchers (#6480)

* Runtime placeholders for caddytls matchers (1/3):

- remove IPs validation in UnmarshalCaddyfile

* Runtime placeholders for caddytls matchers (2/3):

- add placeholder replacement for IPs in Provision

* Runtime placeholders for caddytls matchers (3/3):

- add placeholder replacement for other strings

* Runtime placeholders for caddyhttp matchers (1/1):

- add placeholder replacement for IPs in Provision

* Runtime placeholders for caddyhttp/caddytls matchers:

- move PrivateRandesCIDR under internal
This commit is contained in:
vnxme 2024-08-07 20:02:23 +03:00 committed by GitHub
parent a8b0dfa8da
commit 59cbb2c83a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 57 additions and 41 deletions

14
internal/ranges.go Normal file
View File

@ -0,0 +1,14 @@
package internal
// PrivateRangesCIDR returns a list of private CIDR range
// strings, which can be used as a configuration shortcut.
func PrivateRangesCIDR() []string {
return []string{
"192.168.0.0/16",
"172.16.0.0/12",
"10.0.0.0/8",
"127.0.0.1/8",
"fd00::/8",
"::1",
}
}

View File

@ -29,6 +29,7 @@ import (
"github.com/caddyserver/caddy/v2" "github.com/caddyserver/caddy/v2"
"github.com/caddyserver/caddy/v2/caddyconfig/caddyfile" "github.com/caddyserver/caddy/v2/caddyconfig/caddyfile"
"github.com/caddyserver/caddy/v2/internal"
) )
// MatchRemoteIP matches requests by the remote IP address, // MatchRemoteIP matches requests by the remote IP address,
@ -79,7 +80,7 @@ func (m *MatchRemoteIP) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
return d.Err("the 'forwarded' option is no longer supported; use the 'client_ip' matcher instead") return d.Err("the 'forwarded' option is no longer supported; use the 'client_ip' matcher instead")
} }
if d.Val() == "private_ranges" { if d.Val() == "private_ranges" {
m.Ranges = append(m.Ranges, PrivateRangesCIDR()...) m.Ranges = append(m.Ranges, internal.PrivateRangesCIDR()...)
continue continue
} }
m.Ranges = append(m.Ranges, d.Val()) m.Ranges = append(m.Ranges, d.Val())
@ -173,7 +174,7 @@ func (m *MatchClientIP) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
for d.Next() { for d.Next() {
for d.NextArg() { for d.NextArg() {
if d.Val() == "private_ranges" { if d.Val() == "private_ranges" {
m.Ranges = append(m.Ranges, PrivateRangesCIDR()...) m.Ranges = append(m.Ranges, internal.PrivateRangesCIDR()...)
continue continue
} }
m.Ranges = append(m.Ranges, d.Val()) m.Ranges = append(m.Ranges, d.Val())
@ -250,7 +251,9 @@ func (m MatchClientIP) Match(r *http.Request) bool {
func provisionCidrsZonesFromRanges(ranges []string) ([]*netip.Prefix, []string, error) { func provisionCidrsZonesFromRanges(ranges []string) ([]*netip.Prefix, []string, error) {
cidrs := []*netip.Prefix{} cidrs := []*netip.Prefix{}
zones := []string{} zones := []string{}
repl := caddy.NewReplacer()
for _, str := range ranges { for _, str := range ranges {
str = repl.ReplaceAll(str, "")
// Exclude the zone_id from the IP // Exclude the zone_id from the IP
if strings.Contains(str, "%") { if strings.Contains(str, "%") {
split := strings.Split(str, "%") split := strings.Split(str, "%")

View File

@ -22,6 +22,7 @@ import (
"github.com/caddyserver/caddy/v2" "github.com/caddyserver/caddy/v2"
"github.com/caddyserver/caddy/v2/caddyconfig/caddyfile" "github.com/caddyserver/caddy/v2/caddyconfig/caddyfile"
"github.com/caddyserver/caddy/v2/internal"
) )
func init() { func init() {
@ -92,7 +93,7 @@ func (m *StaticIPRange) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
} }
for d.NextArg() { for d.NextArg() {
if d.Val() == "private_ranges" { if d.Val() == "private_ranges" {
m.Ranges = append(m.Ranges, PrivateRangesCIDR()...) m.Ranges = append(m.Ranges, internal.PrivateRangesCIDR()...)
continue continue
} }
m.Ranges = append(m.Ranges, d.Val()) m.Ranges = append(m.Ranges, d.Val())
@ -121,19 +122,6 @@ func CIDRExpressionToPrefix(expr string) (netip.Prefix, error) {
return prefix, nil return prefix, nil
} }
// PrivateRangesCIDR returns a list of private CIDR range
// strings, which can be used as a configuration shortcut.
func PrivateRangesCIDR() []string {
return []string{
"192.168.0.0/16",
"172.16.0.0/12",
"10.0.0.0/8",
"127.0.0.1/8",
"fd00::/8",
"::1",
}
}
// Interface guards // Interface guards
var ( var (
_ caddy.Provisioner = (*StaticIPRange)(nil) _ caddy.Provisioner = (*StaticIPRange)(nil)

View File

@ -28,6 +28,7 @@ import (
"github.com/caddyserver/caddy/v2/caddyconfig" "github.com/caddyserver/caddy/v2/caddyconfig"
"github.com/caddyserver/caddy/v2/caddyconfig/caddyfile" "github.com/caddyserver/caddy/v2/caddyconfig/caddyfile"
"github.com/caddyserver/caddy/v2/caddyconfig/httpcaddyfile" "github.com/caddyserver/caddy/v2/caddyconfig/httpcaddyfile"
"github.com/caddyserver/caddy/v2/internal"
"github.com/caddyserver/caddy/v2/modules/caddyhttp" "github.com/caddyserver/caddy/v2/modules/caddyhttp"
"github.com/caddyserver/caddy/v2/modules/caddyhttp/headers" "github.com/caddyserver/caddy/v2/modules/caddyhttp/headers"
"github.com/caddyserver/caddy/v2/modules/caddyhttp/rewrite" "github.com/caddyserver/caddy/v2/modules/caddyhttp/rewrite"
@ -688,7 +689,7 @@ func (h *Handler) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
case "trusted_proxies": case "trusted_proxies":
for d.NextArg() { for d.NextArg() {
if d.Val() == "private_ranges" { if d.Val() == "private_ranges" {
h.TrustedProxies = append(h.TrustedProxies, caddyhttp.PrivateRangesCIDR()...) h.TrustedProxies = append(h.TrustedProxies, internal.PrivateRangesCIDR()...)
continue continue
} }
h.TrustedProxies = append(h.TrustedProxies, d.Val()) h.TrustedProxies = append(h.TrustedProxies, d.Val())

View File

@ -26,6 +26,7 @@ import (
"github.com/caddyserver/caddy/v2" "github.com/caddyserver/caddy/v2"
"github.com/caddyserver/caddy/v2/caddyconfig/caddyfile" "github.com/caddyserver/caddy/v2/caddyconfig/caddyfile"
"github.com/caddyserver/caddy/v2/internal"
) )
func init() { func init() {
@ -49,8 +50,17 @@ func (MatchServerName) CaddyModule() caddy.ModuleInfo {
// Match matches hello based on SNI. // Match matches hello based on SNI.
func (m MatchServerName) Match(hello *tls.ClientHelloInfo) bool { func (m MatchServerName) Match(hello *tls.ClientHelloInfo) bool {
// caddytls.TestServerNameMatcher calls this function without any context
var repl *caddy.Replacer
if ctx := hello.Context(); ctx != nil {
repl = ctx.Value(caddy.ReplacerCtxKey).(*caddy.Replacer)
} else {
repl = caddy.NewReplacer()
}
for _, name := range m { for _, name := range m {
if certmagic.MatchWildcard(hello.ServerName, name) { rs := repl.ReplaceAll(name, "")
if certmagic.MatchWildcard(hello.ServerName, rs) {
return true return true
} }
} }
@ -107,16 +117,19 @@ func (MatchRemoteIP) CaddyModule() caddy.ModuleInfo {
// Provision parses m's IP ranges, either from IP or CIDR expressions. // Provision parses m's IP ranges, either from IP or CIDR expressions.
func (m *MatchRemoteIP) Provision(ctx caddy.Context) error { func (m *MatchRemoteIP) Provision(ctx caddy.Context) error {
repl := caddy.NewReplacer()
m.logger = ctx.Logger() m.logger = ctx.Logger()
for _, str := range m.Ranges { for _, str := range m.Ranges {
cidrs, err := m.parseIPRange(str) rs := repl.ReplaceAll(str, "")
cidrs, err := m.parseIPRange(rs)
if err != nil { if err != nil {
return err return err
} }
m.cidrs = append(m.cidrs, cidrs...) m.cidrs = append(m.cidrs, cidrs...)
} }
for _, str := range m.NotRanges { for _, str := range m.NotRanges {
cidrs, err := m.parseIPRange(str) rs := repl.ReplaceAll(str, "")
cidrs, err := m.parseIPRange(rs)
if err != nil { if err != nil {
return err return err
} }
@ -185,22 +198,18 @@ func (m *MatchRemoteIP) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
for d.NextArg() { for d.NextArg() {
val := d.Val() val := d.Val()
var exclamation bool
if len(val) > 1 && val[0] == '!' { if len(val) > 1 && val[0] == '!' {
prefixes, err := m.parseIPRange(val[1:]) exclamation, val = true, val[1:]
if err != nil {
return err
} }
for _, prefix := range prefixes { ranges := []string{val}
m.NotRanges = append(m.NotRanges, prefix.String()) if val == "private_ranges" {
ranges = internal.PrivateRangesCIDR()
} }
if exclamation {
m.NotRanges = append(m.NotRanges, ranges...)
} else { } else {
prefixes, err := m.parseIPRange(val) m.Ranges = append(m.Ranges, ranges...)
if err != nil {
return err
}
for _, prefix := range prefixes {
m.Ranges = append(m.Ranges, prefix.String())
}
} }
} }
@ -233,9 +242,11 @@ func (MatchLocalIP) CaddyModule() caddy.ModuleInfo {
// Provision parses m's IP ranges, either from IP or CIDR expressions. // Provision parses m's IP ranges, either from IP or CIDR expressions.
func (m *MatchLocalIP) Provision(ctx caddy.Context) error { func (m *MatchLocalIP) Provision(ctx caddy.Context) error {
repl := caddy.NewReplacer()
m.logger = ctx.Logger() m.logger = ctx.Logger()
for _, str := range m.Ranges { for _, str := range m.Ranges {
cidrs, err := m.parseIPRange(str) rs := repl.ReplaceAll(str, "")
cidrs, err := m.parseIPRange(rs)
if err != nil { if err != nil {
return err return err
} }
@ -300,13 +311,12 @@ func (m *MatchLocalIP) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
} }
for d.NextArg() { for d.NextArg() {
prefixes, err := m.parseIPRange(d.Val()) val := d.Val()
if err != nil { if val == "private_ranges" {
return err m.Ranges = append(m.Ranges, internal.PrivateRangesCIDR()...)
} continue
for _, prefix := range prefixes {
m.Ranges = append(m.Ranges, prefix.String())
} }
m.Ranges = append(m.Ranges, val)
} }
// No blocks are supported // No blocks are supported