mirror of
https://github.com/ergochat/ergo.git
synced 2024-11-23 04:19:25 +01:00
Merge pull request #1425 from slingamn/issue1421_customlimits.2
fix #1421
This commit is contained in:
commit
23a7221137
22
default.yaml
22
default.yaml
@ -263,13 +263,23 @@ server:
|
|||||||
# - "192.168.1.1"
|
# - "192.168.1.1"
|
||||||
# - "2001:0db8::/32"
|
# - "2001:0db8::/32"
|
||||||
|
|
||||||
# custom connection limits for certain IPs/networks. note that CIDR
|
# custom connection limits for certain IPs/networks.
|
||||||
# widths defined here override the default CIDR width --- the limit
|
|
||||||
# will apply to the entire CIDR no matter how large or small it is
|
|
||||||
custom-limits:
|
custom-limits:
|
||||||
# "8.8.0.0/16":
|
#"irccloud":
|
||||||
# max-concurrent-connections: 128
|
# nets:
|
||||||
# max-connections-per-window: 1024
|
# - "192.184.9.108" # highgate.irccloud.com
|
||||||
|
# - "192.184.9.110" # ealing.irccloud.com
|
||||||
|
# - "192.184.9.112" # charlton.irccloud.com
|
||||||
|
# - "192.184.10.118" # brockwell.irccloud.com
|
||||||
|
# - "192.184.10.9" # tooting.irccloud.com
|
||||||
|
# - "192.184.8.73" # hathersage.irccloud.com
|
||||||
|
# - "192.184.8.103" # stonehaven.irccloud.com
|
||||||
|
# - "5.254.36.57" # tinside.irccloud.com
|
||||||
|
# - "5.254.36.56/29" # additional ipv4 net
|
||||||
|
# - "2001:67c:2f08::/48"
|
||||||
|
# - "2a03:5180:f::/64"
|
||||||
|
# max-concurrent-connections: 2048
|
||||||
|
# max-connections-per-window: 2048
|
||||||
|
|
||||||
# pluggable IP ban mechanism, via subprocess invocation
|
# pluggable IP ban mechanism, via subprocess invocation
|
||||||
# this can be used to check new connections against a DNSBL, for example
|
# this can be used to check new connections against a DNSBL, for example
|
||||||
|
@ -19,14 +19,17 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type CustomLimitConfig struct {
|
type CustomLimitConfig struct {
|
||||||
|
Nets []string
|
||||||
MaxConcurrent int `yaml:"max-concurrent-connections"`
|
MaxConcurrent int `yaml:"max-concurrent-connections"`
|
||||||
MaxPerWindow int `yaml:"max-connections-per-window"`
|
MaxPerWindow int `yaml:"max-connections-per-window"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// tuples the key-value pair of a CIDR and its custom limit/throttle values
|
// tuples the key-value pair of a CIDR and its custom limit/throttle values
|
||||||
type customLimit struct {
|
type customLimit struct {
|
||||||
CustomLimitConfig
|
name string
|
||||||
ipNet net.IPNet
|
maxConcurrent int
|
||||||
|
maxPerWindow int
|
||||||
|
nets []net.IPNet
|
||||||
}
|
}
|
||||||
|
|
||||||
// LimiterConfig controls the automated connection limits.
|
// LimiterConfig controls the automated connection limits.
|
||||||
@ -71,14 +74,29 @@ func (config *LimiterConfig) postprocess() (err error) {
|
|||||||
return fmt.Errorf("Could not parse limiter exemption list: %v", err.Error())
|
return fmt.Errorf("Could not parse limiter exemption list: %v", err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
for netStr, customLimitConf := range config.CustomLimits {
|
for identifier, customLimitConf := range config.CustomLimits {
|
||||||
|
nets := make([]net.IPNet, len(customLimitConf.Nets))
|
||||||
|
for i, netStr := range customLimitConf.Nets {
|
||||||
normalizedNet, err := utils.NormalizedNetFromString(netStr)
|
normalizedNet, err := utils.NormalizedNetFromString(netStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Could not parse custom limit specification: %v", err.Error())
|
return fmt.Errorf("Bad net %s in custom-limits block %s: %w", netStr, identifier, err)
|
||||||
|
}
|
||||||
|
nets[i] = normalizedNet
|
||||||
|
}
|
||||||
|
if len(customLimitConf.Nets) == 0 {
|
||||||
|
// see #1421: this is the legacy config format where the
|
||||||
|
// dictionary key of the block is a CIDR string
|
||||||
|
normalizedNet, err := utils.NormalizedNetFromString(identifier)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Custom limit block %s has no defined nets", identifier)
|
||||||
|
}
|
||||||
|
nets = []net.IPNet{normalizedNet}
|
||||||
}
|
}
|
||||||
config.customLimits = append(config.customLimits, customLimit{
|
config.customLimits = append(config.customLimits, customLimit{
|
||||||
CustomLimitConfig: customLimitConf,
|
maxConcurrent: customLimitConf.MaxConcurrent,
|
||||||
ipNet: normalizedNet,
|
maxPerWindow: customLimitConf.MaxPerWindow,
|
||||||
|
name: "*" + identifier,
|
||||||
|
nets: nets,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,8 +123,10 @@ type Limiter struct {
|
|||||||
func (cl *Limiter) addrToKey(addr net.IP) (key string, limit int, throttle int) {
|
func (cl *Limiter) addrToKey(addr net.IP) (key string, limit int, throttle int) {
|
||||||
// `key` will be a CIDR string like "8.8.8.8/32" or "2001:0db8::/32"
|
// `key` will be a CIDR string like "8.8.8.8/32" or "2001:0db8::/32"
|
||||||
for _, custom := range cl.config.customLimits {
|
for _, custom := range cl.config.customLimits {
|
||||||
if custom.ipNet.Contains(addr) {
|
for _, net := range custom.nets {
|
||||||
return custom.ipNet.String(), custom.MaxConcurrent, custom.MaxPerWindow
|
if net.Contains(addr) {
|
||||||
|
return custom.name, custom.maxConcurrent, custom.maxPerWindow
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,7 +32,8 @@ var baseConfig = LimiterConfig{
|
|||||||
Exempted: []string{"localhost"},
|
Exempted: []string{"localhost"},
|
||||||
|
|
||||||
CustomLimits: map[string]CustomLimitConfig{
|
CustomLimits: map[string]CustomLimitConfig{
|
||||||
"8.8.0.0/16": {
|
"google": {
|
||||||
|
Nets: []string{"8.8.0.0/16"},
|
||||||
MaxConcurrent: 128,
|
MaxConcurrent: 128,
|
||||||
MaxPerWindow: 256,
|
MaxPerWindow: 256,
|
||||||
},
|
},
|
||||||
@ -57,7 +58,7 @@ func TestKeying(t *testing.T) {
|
|||||||
assertEqual(maxWin, 8, t)
|
assertEqual(maxWin, 8, t)
|
||||||
|
|
||||||
key, maxConc, maxWin = limiter.addrToKey(easyParseIP("8.8.4.4"))
|
key, maxConc, maxWin = limiter.addrToKey(easyParseIP("8.8.4.4"))
|
||||||
assertEqual(key, "8.8.0.0/16", t)
|
assertEqual(key, "*google", t)
|
||||||
assertEqual(maxConc, 128, t)
|
assertEqual(maxConc, 128, t)
|
||||||
assertEqual(maxWin, 256, t)
|
assertEqual(maxWin, 256, t)
|
||||||
}
|
}
|
||||||
|
@ -236,13 +236,23 @@ server:
|
|||||||
# - "192.168.1.1"
|
# - "192.168.1.1"
|
||||||
# - "2001:0db8::/32"
|
# - "2001:0db8::/32"
|
||||||
|
|
||||||
# custom connection limits for certain IPs/networks. note that CIDR
|
# custom connection limits for certain IPs/networks.
|
||||||
# widths defined here override the default CIDR width --- the limit
|
|
||||||
# will apply to the entire CIDR no matter how large or small it is
|
|
||||||
custom-limits:
|
custom-limits:
|
||||||
# "8.8.0.0/16":
|
#"irccloud":
|
||||||
# max-concurrent-connections: 128
|
# nets:
|
||||||
# max-connections-per-window: 1024
|
# - "192.184.9.108" # highgate.irccloud.com
|
||||||
|
# - "192.184.9.110" # ealing.irccloud.com
|
||||||
|
# - "192.184.9.112" # charlton.irccloud.com
|
||||||
|
# - "192.184.10.118" # brockwell.irccloud.com
|
||||||
|
# - "192.184.10.9" # tooting.irccloud.com
|
||||||
|
# - "192.184.8.73" # hathersage.irccloud.com
|
||||||
|
# - "192.184.8.103" # stonehaven.irccloud.com
|
||||||
|
# - "5.254.36.57" # tinside.irccloud.com
|
||||||
|
# - "5.254.36.56/29" # additional ipv4 net
|
||||||
|
# - "2001:67c:2f08::/48"
|
||||||
|
# - "2a03:5180:f::/64"
|
||||||
|
# max-concurrent-connections: 2048
|
||||||
|
# max-connections-per-window: 2048
|
||||||
|
|
||||||
# pluggable IP ban mechanism, via subprocess invocation
|
# pluggable IP ban mechanism, via subprocess invocation
|
||||||
# this can be used to check new connections against a DNSBL, for example
|
# this can be used to check new connections against a DNSBL, for example
|
||||||
|
Loading…
Reference in New Issue
Block a user