Enhance configuration and documentation for CIDR and IP handling. Updated config.example.yaml to include additional whitelisted IPs and new server entries. Improved GATEWAY_RUN.md to clarify CIDR and single IP usage. Implemented parseCIDROrIP function in config.go for better validation of IP formats in whitelist and trusted proxies.
This commit is contained in:
@@ -83,18 +83,34 @@ func (c *Config) Validate() error {
|
||||
return fmt.Errorf("at least one server entry is required")
|
||||
}
|
||||
for i, s := range c.WhitelistCIDRs {
|
||||
if _, err := netip.ParsePrefix(strings.TrimSpace(s)); err != nil {
|
||||
if _, err := parseCIDROrIP(s); err != nil {
|
||||
return fmt.Errorf("whitelist_cidrs[%d]: %w", i, err)
|
||||
}
|
||||
}
|
||||
for i, s := range c.TrustedProxies {
|
||||
if _, err := netip.ParsePrefix(strings.TrimSpace(s)); err != nil {
|
||||
if _, err := parseCIDROrIP(s); err != nil {
|
||||
return fmt.Errorf("trusted_proxies[%d]: %w", i, err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// parseCIDROrIP accepts a CIDR ("10.0.0.0/8") or a single IP ("87.103.241.8" → /32 or /128).
|
||||
func parseCIDROrIP(s string) (netip.Prefix, error) {
|
||||
s = strings.TrimSpace(s)
|
||||
if s == "" {
|
||||
return netip.Prefix{}, fmt.Errorf("empty")
|
||||
}
|
||||
if p, err := netip.ParsePrefix(s); err == nil {
|
||||
return p, nil
|
||||
}
|
||||
addr, err := netip.ParseAddr(s)
|
||||
if err != nil {
|
||||
return netip.Prefix{}, fmt.Errorf("%w (use CIDR like %s/32 for IPv4)", err, s)
|
||||
}
|
||||
return addr.Prefix(addr.BitLen())
|
||||
}
|
||||
|
||||
// Parsed holds compiled CIDR lists and server map.
|
||||
type Parsed struct {
|
||||
Config *Config
|
||||
@@ -108,7 +124,7 @@ type Parsed struct {
|
||||
func (c *Config) Parse() (*Parsed, error) {
|
||||
var wl []netip.Prefix
|
||||
for _, s := range c.WhitelistCIDRs {
|
||||
p, err := netip.ParsePrefix(strings.TrimSpace(s))
|
||||
p, err := parseCIDROrIP(s)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -116,7 +132,7 @@ func (c *Config) Parse() (*Parsed, error) {
|
||||
}
|
||||
var tr []netip.Prefix
|
||||
for _, s := range c.TrustedProxies {
|
||||
p, err := netip.ParsePrefix(strings.TrimSpace(s))
|
||||
p, err := parseCIDROrIP(s)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -31,6 +31,26 @@ servers:
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseCIDRorIP(t *testing.T) {
|
||||
for _, tc := range []struct {
|
||||
in string
|
||||
want string
|
||||
}{
|
||||
{"87.103.241.8", "87.103.241.8/32"},
|
||||
{"87.103.241.8/32", "87.103.241.8/32"},
|
||||
{"10.0.0.0/8", "10.0.0.0/8"},
|
||||
{"2001:db8::1", "2001:db8::1/128"},
|
||||
} {
|
||||
p, err := parseCIDROrIP(tc.in)
|
||||
if err != nil {
|
||||
t.Fatalf("%q: %v", tc.in, err)
|
||||
}
|
||||
if p.String() != tc.want {
|
||||
t.Fatalf("%q: got %s want %s", tc.in, p, tc.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateDuplicateAlias(t *testing.T) {
|
||||
c := &Config{
|
||||
Servers: []Server{
|
||||
|
||||
Reference in New Issue
Block a user