Explorar el Código

stop autocreating d-lines for throttle violations

This didn't work correctly for IPv6 or custom nets.
/UNDLINE IP can temporarily be used to reset the throttle.
tags/v2.5.0-rc1
Shivaram Lingamneni hace 3 años
padre
commit
84e3b5d77b

+ 0
- 3
default.yaml Ver fichero

247
         window: 10m
247
         window: 10m
248
         # maximum number of new connections per IP/CIDR within the given duration
248
         # maximum number of new connections per IP/CIDR within the given duration
249
         max-connections-per-window: 32
249
         max-connections-per-window: 32
250
-        # how long to ban offenders for. after banning them, the number of connections is
251
-        # reset, which lets you use /UNDLINE to unban people
252
-        throttle-ban-duration: 10m
253
 
250
 
254
         # how wide the CIDR should be for IPv4 (a /32 is a fully specified IPv4 address)
251
         # how wide the CIDR should be for IPv4 (a /32 is a fully specified IPv4 address)
255
         cidr-len-ipv4: 32
252
         cidr-len-ipv4: 32

+ 2
- 1
irc/client.go Ver fichero

21
 	ident "github.com/oragono/go-ident"
21
 	ident "github.com/oragono/go-ident"
22
 	"github.com/oragono/oragono/irc/caps"
22
 	"github.com/oragono/oragono/irc/caps"
23
 	"github.com/oragono/oragono/irc/connection_limits"
23
 	"github.com/oragono/oragono/irc/connection_limits"
24
+	"github.com/oragono/oragono/irc/flatip"
24
 	"github.com/oragono/oragono/irc/history"
25
 	"github.com/oragono/oragono/irc/history"
25
 	"github.com/oragono/oragono/irc/modes"
26
 	"github.com/oragono/oragono/irc/modes"
26
 	"github.com/oragono/oragono/irc/sno"
27
 	"github.com/oragono/oragono/irc/sno"
1477
 			if session.proxiedIP != nil {
1478
 			if session.proxiedIP != nil {
1478
 				ip = session.proxiedIP
1479
 				ip = session.proxiedIP
1479
 			}
1480
 			}
1480
-			client.server.connectionLimiter.RemoveClient(ip)
1481
+			client.server.connectionLimiter.RemoveClient(flatip.FromNetIP(ip))
1481
 			source = ip.String()
1482
 			source = ip.String()
1482
 		}
1483
 		}
1483
 		client.server.logger.Info("connect-ip", fmt.Sprintf("disconnecting session of %s from %s", details.nick, source))
1484
 		client.server.logger.Info("connect-ip", fmt.Sprintf("disconnecting session of %s from %s", details.nick, source))

+ 27
- 31
irc/connection_limits/limiter.go Ver fichero

7
 	"crypto/md5"
7
 	"crypto/md5"
8
 	"errors"
8
 	"errors"
9
 	"fmt"
9
 	"fmt"
10
-	"net"
11
 	"sync"
10
 	"sync"
12
 	"time"
11
 	"time"
13
 
12
 
48
 
47
 
49
 	Throttle     bool
48
 	Throttle     bool
50
 	Window       time.Duration
49
 	Window       time.Duration
51
-	MaxPerWindow int           `yaml:"max-connections-per-window"`
52
-	BanDuration  time.Duration `yaml:"throttle-ban-duration"`
50
+	MaxPerWindow int `yaml:"max-connections-per-window"`
53
 
51
 
54
 	CidrLenIPv4 int `yaml:"cidr-len-ipv4"`
52
 	CidrLenIPv4 int `yaml:"cidr-len-ipv4"`
55
 	CidrLenIPv6 int `yaml:"cidr-len-ipv6"`
53
 	CidrLenIPv6 int `yaml:"cidr-len-ipv6"`
126
 
124
 
127
 // addrToKey canonicalizes `addr` to a string key, and returns
125
 // addrToKey canonicalizes `addr` to a string key, and returns
128
 // the relevant connection limit and throttle max-per-window values
126
 // the relevant connection limit and throttle max-per-window values
129
-func (cl *Limiter) addrToKey(flat flatip.IP) (key limiterKey, limit int, throttle int) {
127
+func (cl *Limiter) addrToKey(addr flatip.IP) (key limiterKey, limit int, throttle int) {
130
 	for _, custom := range cl.config.customLimits {
128
 	for _, custom := range cl.config.customLimits {
131
 		for _, net := range custom.nets {
129
 		for _, net := range custom.nets {
132
-			if net.Contains(flat) {
130
+			if net.Contains(addr) {
133
 				return limiterKey{maskedIP: custom.name, prefixLen: 0}, custom.maxConcurrent, custom.maxPerWindow
131
 				return limiterKey{maskedIP: custom.name, prefixLen: 0}, custom.maxConcurrent, custom.maxPerWindow
134
 			}
132
 			}
135
 		}
133
 		}
136
 	}
134
 	}
137
 
135
 
138
 	var prefixLen int
136
 	var prefixLen int
139
-	if flat.IsIPv4() {
137
+	if addr.IsIPv4() {
140
 		prefixLen = cl.config.CidrLenIPv4
138
 		prefixLen = cl.config.CidrLenIPv4
141
-		flat = flat.Mask(prefixLen, 32)
139
+		addr = addr.Mask(prefixLen, 32)
142
 		prefixLen += 96
140
 		prefixLen += 96
143
 	} else {
141
 	} else {
144
 		prefixLen = cl.config.CidrLenIPv6
142
 		prefixLen = cl.config.CidrLenIPv6
145
-		flat = flat.Mask(prefixLen, 128)
143
+		addr = addr.Mask(prefixLen, 128)
146
 	}
144
 	}
147
 
145
 
148
-	return limiterKey{maskedIP: flat, prefixLen: uint8(prefixLen)}, cl.config.MaxConcurrent, cl.config.MaxPerWindow
146
+	return limiterKey{maskedIP: addr, prefixLen: uint8(prefixLen)}, cl.config.MaxConcurrent, cl.config.MaxPerWindow
149
 }
147
 }
150
 
148
 
151
 // AddClient adds a client to our population if possible. If we can't, throws an error instead.
149
 // AddClient adds a client to our population if possible. If we can't, throws an error instead.
152
-func (cl *Limiter) AddClient(addr net.IP) error {
153
-	flat := flatip.FromNetIP(addr)
154
-
150
+func (cl *Limiter) AddClient(addr flatip.IP) error {
155
 	cl.Lock()
151
 	cl.Lock()
156
 	defer cl.Unlock()
152
 	defer cl.Unlock()
157
 
153
 
158
 	// we don't track populations for exempted addresses or nets - this is by design
154
 	// we don't track populations for exempted addresses or nets - this is by design
159
-	if flatip.IPInNets(flat, cl.config.exemptedNets) {
155
+	if flatip.IPInNets(addr, cl.config.exemptedNets) {
160
 		return nil
156
 		return nil
161
 	}
157
 	}
162
 
158
 
163
-	addrString, maxConcurrent, maxPerWindow := cl.addrToKey(flat)
159
+	addrString, maxConcurrent, maxPerWindow := cl.addrToKey(addr)
160
+
161
+	// check limiter
162
+	var count int
163
+	if cl.config.Count {
164
+		count = cl.limiter[addrString] + 1
165
+		if count > maxConcurrent {
166
+			return ErrLimitExceeded
167
+		}
168
+	}
164
 
169
 
165
-	// XXX check throttle first; if we checked limit first and then checked throttle,
166
-	// we'd have to decrement the limit on an unsuccessful throttle check
167
 	if cl.config.Throttle {
170
 	if cl.config.Throttle {
168
 		details := cl.throttler[addrString] // retrieve mutable throttle state from the map
171
 		details := cl.throttler[addrString] // retrieve mutable throttle state from the map
169
 		// add in constant state to process the limiting operation
172
 		// add in constant state to process the limiting operation
175
 		throttled, _ := g.Touch()                    // actually check the limit
178
 		throttled, _ := g.Touch()                    // actually check the limit
176
 		cl.throttler[addrString] = g.ThrottleDetails // store modified mutable state
179
 		cl.throttler[addrString] = g.ThrottleDetails // store modified mutable state
177
 		if throttled {
180
 		if throttled {
181
+			// back out the limiter add
178
 			return ErrThrottleExceeded
182
 			return ErrThrottleExceeded
179
 		}
183
 		}
180
 	}
184
 	}
181
 
185
 
182
-	// now check limiter
186
+	// success, record in limiter
183
 	if cl.config.Count {
187
 	if cl.config.Count {
184
-		count := cl.limiter[addrString] + 1
185
-		if count > maxConcurrent {
186
-			return ErrLimitExceeded
187
-		}
188
 		cl.limiter[addrString] = count
188
 		cl.limiter[addrString] = count
189
 	}
189
 	}
190
 
190
 
192
 }
192
 }
193
 
193
 
194
 // RemoveClient removes the given address from our population
194
 // RemoveClient removes the given address from our population
195
-func (cl *Limiter) RemoveClient(addr net.IP) {
196
-	flat := flatip.FromNetIP(addr)
197
-
195
+func (cl *Limiter) RemoveClient(addr flatip.IP) {
198
 	cl.Lock()
196
 	cl.Lock()
199
 	defer cl.Unlock()
197
 	defer cl.Unlock()
200
 
198
 
201
-	if !cl.config.Count || flatip.IPInNets(flat, cl.config.exemptedNets) {
199
+	if !cl.config.Count || flatip.IPInNets(addr, cl.config.exemptedNets) {
202
 		return
200
 		return
203
 	}
201
 	}
204
 
202
 
205
-	addrString, _, _ := cl.addrToKey(flat)
203
+	addrString, _, _ := cl.addrToKey(addr)
206
 	count := cl.limiter[addrString]
204
 	count := cl.limiter[addrString]
207
 	count -= 1
205
 	count -= 1
208
 	if count < 0 {
206
 	if count < 0 {
212
 }
210
 }
213
 
211
 
214
 // ResetThrottle resets the throttle count for an IP
212
 // ResetThrottle resets the throttle count for an IP
215
-func (cl *Limiter) ResetThrottle(addr net.IP) {
216
-	flat := flatip.FromNetIP(addr)
217
-
213
+func (cl *Limiter) ResetThrottle(addr flatip.IP) {
218
 	cl.Lock()
214
 	cl.Lock()
219
 	defer cl.Unlock()
215
 	defer cl.Unlock()
220
 
216
 
221
-	if !cl.config.Throttle || flatip.IPInNets(flat, cl.config.exemptedNets) {
217
+	if !cl.config.Throttle || flatip.IPInNets(addr, cl.config.exemptedNets) {
222
 		return
218
 		return
223
 	}
219
 	}
224
 
220
 
225
-	addrString, _, _ := cl.addrToKey(flat)
221
+	addrString, _, _ := cl.addrToKey(addr)
226
 	delete(cl.throttler, addrString)
222
 	delete(cl.throttler, addrString)
227
 }
223
 }
228
 
224
 

+ 8
- 14
irc/connection_limits/limiter_test.go Ver fichero

5
 
5
 
6
 import (
6
 import (
7
 	"crypto/md5"
7
 	"crypto/md5"
8
-	"net"
9
 	"testing"
8
 	"testing"
10
 	"time"
9
 	"time"
11
 
10
 
12
 	"github.com/oragono/oragono/irc/flatip"
11
 	"github.com/oragono/oragono/irc/flatip"
13
 )
12
 )
14
 
13
 
15
-func easyParseIP(ipstr string) (result net.IP) {
16
-	result = net.ParseIP(ipstr)
17
-	if result == nil {
18
-		panic(ipstr)
14
+func easyParseIP(ipstr string) (result flatip.IP) {
15
+	result, err := flatip.ParseIP(ipstr)
16
+	if err != nil {
17
+		panic(err)
19
 	}
18
 	}
20
 	return
19
 	return
21
 }
20
 }
22
 
21
 
23
-func easyParseFlat(ipstr string) (result flatip.IP) {
24
-	r1 := easyParseIP(ipstr)
25
-	return flatip.FromNetIP(r1)
26
-}
27
-
28
 var baseConfig = LimiterConfig{
22
 var baseConfig = LimiterConfig{
29
 	rawLimiterConfig: rawLimiterConfig{
23
 	rawLimiterConfig: rawLimiterConfig{
30
 		Count:         true,
24
 		Count:         true,
56
 	limiter.ApplyConfig(&config)
50
 	limiter.ApplyConfig(&config)
57
 
51
 
58
 	// an ipv4 /32 looks like a /128 to us after applying the 4-in-6 mapping
52
 	// an ipv4 /32 looks like a /128 to us after applying the 4-in-6 mapping
59
-	key, maxConc, maxWin := limiter.addrToKey(easyParseFlat("1.1.1.1"))
53
+	key, maxConc, maxWin := limiter.addrToKey(easyParseIP("1.1.1.1"))
60
 	assertEqual(key.prefixLen, uint8(128), t)
54
 	assertEqual(key.prefixLen, uint8(128), t)
61
 	assertEqual(key.maskedIP[12:], []byte{1, 1, 1, 1}, t)
55
 	assertEqual(key.maskedIP[12:], []byte{1, 1, 1, 1}, t)
62
 	assertEqual(maxConc, 4, t)
56
 	assertEqual(maxConc, 4, t)
63
 	assertEqual(maxWin, 8, t)
57
 	assertEqual(maxWin, 8, t)
64
 
58
 
65
-	testIPv6 := easyParseFlat("2607:5301:201:3100::7426")
59
+	testIPv6 := easyParseIP("2607:5301:201:3100::7426")
66
 	key, maxConc, maxWin = limiter.addrToKey(testIPv6)
60
 	key, maxConc, maxWin = limiter.addrToKey(testIPv6)
67
 	assertEqual(key.prefixLen, uint8(64), t)
61
 	assertEqual(key.prefixLen, uint8(64), t)
68
-	assertEqual(key.maskedIP[:], []byte(easyParseIP("2607:5301:201:3100::")), t)
62
+	assertEqual(flatip.IP(key.maskedIP), easyParseIP("2607:5301:201:3100::"), t)
69
 	assertEqual(maxConc, 4, t)
63
 	assertEqual(maxConc, 4, t)
70
 	assertEqual(maxWin, 8, t)
64
 	assertEqual(maxWin, 8, t)
71
 
65
 
72
-	key, maxConc, maxWin = limiter.addrToKey(easyParseFlat("8.8.4.4"))
66
+	key, maxConc, maxWin = limiter.addrToKey(easyParseIP("8.8.4.4"))
73
 	assertEqual(key.prefixLen, uint8(0), t)
67
 	assertEqual(key.prefixLen, uint8(0), t)
74
 	assertEqual([16]byte(key.maskedIP), md5.Sum([]byte("google")), t)
68
 	assertEqual([16]byte(key.maskedIP), md5.Sum([]byte("google")), t)
75
 	assertEqual(maxConc, 128, t)
69
 	assertEqual(maxConc, 128, t)

+ 9
- 10
irc/connection_limits/throttler_test.go Ver fichero

4
 package connection_limits
4
 package connection_limits
5
 
5
 
6
 import (
6
 import (
7
-	"net"
8
 	"reflect"
7
 	"reflect"
9
 	"testing"
8
 	"testing"
10
 	"time"
9
 	"time"
83
 
82
 
84
 func TestConnectionThrottle(t *testing.T) {
83
 func TestConnectionThrottle(t *testing.T) {
85
 	throttler := makeTestThrottler(32, 64)
84
 	throttler := makeTestThrottler(32, 64)
86
-	addr := net.ParseIP("8.8.8.8")
85
+	addr := easyParseIP("8.8.8.8")
87
 
86
 
88
 	for i := 0; i < 3; i += 1 {
87
 	for i := 0; i < 3; i += 1 {
89
 		err := throttler.AddClient(addr)
88
 		err := throttler.AddClient(addr)
97
 	throttler := makeTestThrottler(32, 64)
96
 	throttler := makeTestThrottler(32, 64)
98
 
97
 
99
 	var err error
98
 	var err error
100
-	err = throttler.AddClient(net.ParseIP("2001:0db8::1"))
99
+	err = throttler.AddClient(easyParseIP("2001:0db8::1"))
101
 	assertEqual(err, nil, t)
100
 	assertEqual(err, nil, t)
102
-	err = throttler.AddClient(net.ParseIP("2001:0db8::2"))
101
+	err = throttler.AddClient(easyParseIP("2001:0db8::2"))
103
 	assertEqual(err, nil, t)
102
 	assertEqual(err, nil, t)
104
-	err = throttler.AddClient(net.ParseIP("2001:0db8::3"))
103
+	err = throttler.AddClient(easyParseIP("2001:0db8::3"))
105
 	assertEqual(err, nil, t)
104
 	assertEqual(err, nil, t)
106
 
105
 
107
-	err = throttler.AddClient(net.ParseIP("2001:0db8::4"))
106
+	err = throttler.AddClient(easyParseIP("2001:0db8::4"))
108
 	assertEqual(err, ErrThrottleExceeded, t)
107
 	assertEqual(err, ErrThrottleExceeded, t)
109
 }
108
 }
110
 
109
 
112
 	throttler := makeTestThrottler(24, 64)
111
 	throttler := makeTestThrottler(24, 64)
113
 
112
 
114
 	var err error
113
 	var err error
115
-	err = throttler.AddClient(net.ParseIP("192.168.1.101"))
114
+	err = throttler.AddClient(easyParseIP("192.168.1.101"))
116
 	assertEqual(err, nil, t)
115
 	assertEqual(err, nil, t)
117
-	err = throttler.AddClient(net.ParseIP("192.168.1.102"))
116
+	err = throttler.AddClient(easyParseIP("192.168.1.102"))
118
 	assertEqual(err, nil, t)
117
 	assertEqual(err, nil, t)
119
-	err = throttler.AddClient(net.ParseIP("192.168.1.103"))
118
+	err = throttler.AddClient(easyParseIP("192.168.1.103"))
120
 	assertEqual(err, nil, t)
119
 	assertEqual(err, nil, t)
121
 
120
 
122
-	err = throttler.AddClient(net.ParseIP("192.168.1.104"))
121
+	err = throttler.AddClient(easyParseIP("192.168.1.104"))
123
 	assertEqual(err, ErrThrottleExceeded, t)
122
 	assertEqual(err, ErrThrottleExceeded, t)
124
 }
123
 }

+ 1
- 2
irc/dline.go Ver fichero

226
 }
226
 }
227
 
227
 
228
 // CheckIP returns whether or not an IP address was banned, and how long it is banned for.
228
 // CheckIP returns whether or not an IP address was banned, and how long it is banned for.
229
-func (dm *DLineManager) CheckIP(netAddr net.IP) (isBanned bool, info IPBanInfo) {
230
-	addr := flatip.FromNetIP(netAddr)
229
+func (dm *DLineManager) CheckIP(addr flatip.IP) (isBanned bool, info IPBanInfo) {
231
 	if addr.IsLoopback() {
230
 	if addr.IsLoopback() {
232
 		return // #671
231
 		return // #671
233
 	}
232
 	}

+ 33
- 0
irc/flatip/adhoc.go Ver fichero

1
+// Copyright 2020 Shivaram Lingamneni <slingamn@cs.stanford.edu>
2
+// Released under the MIT license
3
+
4
+package flatip
5
+
6
+// begin ad-hoc utilities
7
+
8
+// ParseToNormalizedNet attempts to interpret a string either as an IP
9
+// network in CIDR notation, returning an IPNet, or as an IP address,
10
+// returning an IPNet that contains only that address.
11
+func ParseToNormalizedNet(netstr string) (ipnet IPNet, err error) {
12
+	_, ipnet, err = ParseCIDR(netstr)
13
+	if err == nil {
14
+		return
15
+	}
16
+	ip, err := ParseIP(netstr)
17
+	if err == nil {
18
+		ipnet.IP = ip
19
+		ipnet.PrefixLen = 128
20
+	}
21
+	return
22
+}
23
+
24
+// IPInNets is a convenience function for testing whether an IP is contained
25
+// in any member of a slice of IPNet's.
26
+func IPInNets(addr IP, nets []IPNet) bool {
27
+	for _, net := range nets {
28
+		if net.Contains(addr) {
29
+			return true
30
+		}
31
+	}
32
+	return false
33
+}

+ 16
- 31
irc/flatip/flatip.go Ver fichero

1
 // Copyright 2020 Shivaram Lingamneni <slingamn@cs.stanford.edu>
1
 // Copyright 2020 Shivaram Lingamneni <slingamn@cs.stanford.edu>
2
 // Copyright 2009 The Go Authors
2
 // Copyright 2009 The Go Authors
3
+// Released under the MIT license
3
 
4
 
4
 package flatip
5
 package flatip
5
 
6
 
13
 	v4InV6Prefix = []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff}
14
 	v4InV6Prefix = []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff}
14
 
15
 
15
 	IPv6loopback = IP{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}
16
 	IPv6loopback = IP{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}
17
+	IPv6zero     = IP{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
18
+	IPv4zero     = IP{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 0, 0, 0, 0}
16
 
19
 
17
 	ErrInvalidIPString = errors.New("String could not be interpreted as an IP address")
20
 	ErrInvalidIPString = errors.New("String could not be interpreted as an IP address")
18
 )
21
 )
20
 // packed versions of net.IP and net.IPNet; these are pure value types,
23
 // packed versions of net.IP and net.IPNet; these are pure value types,
21
 // so they can be compared with == and used as map keys.
24
 // so they can be compared with == and used as map keys.
22
 
25
 
23
-// IP is the 128-bit representation of the IPv6 address, using the 4-in-6 mapping
24
-// if necessary:
26
+// IP is a 128-bit representation of an IP address, using the 4-in-6 mapping
27
+// to represent IPv4 addresses.
25
 type IP [16]byte
28
 type IP [16]byte
26
 
29
 
27
 // IPNet is a IP network. In a valid value, all bits after PrefixLen are zeroes.
30
 // IPNet is a IP network. In a valid value, all bits after PrefixLen are zeroes.
95
 	}
98
 	}
96
 }
99
 }
97
 
100
 
101
+func (ip IP) IsUnspecified() bool {
102
+	return ip == IPv4zero || ip == IPv6zero
103
+}
104
+
98
 func rawCidrMask(length int) (m IP) {
105
 func rawCidrMask(length int) (m IP) {
99
 	n := uint(length)
106
 	n := uint(length)
100
 	for i := 0; i < 16; i++ {
107
 	for i := 0; i < 16; i++ {
176
 	return ipnet.String()
183
 	return ipnet.String()
177
 }
184
 }
178
 
185
 
186
+// IsZero tests whether ipnet is the zero value of an IPNet, 0::0/0.
187
+// Although this is a valid subnet, it can still be used as a sentinel
188
+// value in some contexts.
189
+func (ipnet IPNet) IsZero() bool {
190
+	return ipnet == IPNet{}
191
+}
192
+
179
 // ParseCIDR parses a string representation of an IP network in CIDR notation,
193
 // ParseCIDR parses a string representation of an IP network in CIDR notation,
180
 // then returns it as an IPNet (along with the original, unmasked address).
194
 // then returns it as an IPNet (along with the original, unmasked address).
181
 func ParseCIDR(netstr string) (ip IP, ipnet IPNet, err error) {
195
 func ParseCIDR(netstr string) (ip IP, ipnet IPNet, err error) {
186
 	}
200
 	}
187
 	return FromNetIP(nip), FromNetIPNet(*nipnet), nil
201
 	return FromNetIP(nip), FromNetIPNet(*nipnet), nil
188
 }
202
 }
189
-
190
-// begin ad-hoc utilities
191
-
192
-// ParseToNormalizedNet attempts to interpret a string either as an IP
193
-// network in CIDR notation, returning an IPNet, or as an IP address,
194
-// returning an IPNet that contains only that address.
195
-func ParseToNormalizedNet(netstr string) (ipnet IPNet, err error) {
196
-	_, ipnet, err = ParseCIDR(netstr)
197
-	if err == nil {
198
-		return
199
-	}
200
-	ip, err := ParseIP(netstr)
201
-	if err == nil {
202
-		ipnet.IP = ip
203
-		ipnet.PrefixLen = 128
204
-	}
205
-	return
206
-}
207
-
208
-// IPInNets is a convenience function for testing whether an IP is contained
209
-// in any member of a slice of IPNet's.
210
-func IPInNets(addr IP, nets []IPNet) bool {
211
-	for _, net := range nets {
212
-		if net.Contains(addr) {
213
-			return true
214
-		}
215
-	}
216
-	return false
217
-}

+ 2
- 1
irc/gateways.go Ver fichero

9
 	"errors"
9
 	"errors"
10
 	"net"
10
 	"net"
11
 
11
 
12
+	"github.com/oragono/oragono/irc/flatip"
12
 	"github.com/oragono/oragono/irc/modes"
13
 	"github.com/oragono/oragono/irc/modes"
13
 	"github.com/oragono/oragono/irc/utils"
14
 	"github.com/oragono/oragono/irc/utils"
14
 )
15
 )
87
 	}
88
 	}
88
 	// successfully added a limiter entry for the proxied IP;
89
 	// successfully added a limiter entry for the proxied IP;
89
 	// remove the entry for the real IP if applicable (#197)
90
 	// remove the entry for the real IP if applicable (#197)
90
-	client.server.connectionLimiter.RemoveClient(session.realIP)
91
+	client.server.connectionLimiter.RemoveClient(flatip.FromNetIP(session.realIP))
91
 
92
 
92
 	// given IP is sane! override the client's current IP
93
 	// given IP is sane! override the client's current IP
93
 	client.server.logger.Info("connect-ip", "Accepted proxy IP for client", proxiedIP.String())
94
 	client.server.logger.Info("connect-ip", "Accepted proxy IP for client", proxiedIP.String())

+ 6
- 0
irc/handlers.go Ver fichero

24
 	"github.com/goshuirc/irc-go/ircmsg"
24
 	"github.com/goshuirc/irc-go/ircmsg"
25
 	"github.com/oragono/oragono/irc/caps"
25
 	"github.com/oragono/oragono/irc/caps"
26
 	"github.com/oragono/oragono/irc/custime"
26
 	"github.com/oragono/oragono/irc/custime"
27
+	"github.com/oragono/oragono/irc/flatip"
27
 	"github.com/oragono/oragono/irc/history"
28
 	"github.com/oragono/oragono/irc/history"
28
 	"github.com/oragono/oragono/irc/jwt"
29
 	"github.com/oragono/oragono/irc/jwt"
29
 	"github.com/oragono/oragono/irc/modes"
30
 	"github.com/oragono/oragono/irc/modes"
2798
 	// get host
2799
 	// get host
2799
 	hostString := msg.Params[0]
2800
 	hostString := msg.Params[0]
2800
 
2801
 
2802
+	// TODO(#1447) consolidate this into the "unban" command
2803
+	if flatip, ipErr := flatip.ParseIP(hostString); ipErr == nil {
2804
+		server.connectionLimiter.ResetThrottle(flatip)
2805
+	}
2806
+
2801
 	// check host
2807
 	// check host
2802
 	hostNet, err := utils.NormalizedNetFromString(hostString)
2808
 	hostNet, err := utils.NormalizedNetFromString(hostString)
2803
 
2809
 

+ 9
- 16
irc/server.go Ver fichero

23
 
23
 
24
 	"github.com/oragono/oragono/irc/caps"
24
 	"github.com/oragono/oragono/irc/caps"
25
 	"github.com/oragono/oragono/irc/connection_limits"
25
 	"github.com/oragono/oragono/irc/connection_limits"
26
+	"github.com/oragono/oragono/irc/flatip"
26
 	"github.com/oragono/oragono/irc/history"
27
 	"github.com/oragono/oragono/irc/history"
27
 	"github.com/oragono/oragono/irc/logger"
28
 	"github.com/oragono/oragono/irc/logger"
28
 	"github.com/oragono/oragono/irc/modes"
29
 	"github.com/oragono/oragono/irc/modes"
160
 		}
161
 		}
161
 	}
162
 	}
162
 
163
 
164
+	flat := flatip.FromNetIP(ipaddr)
165
+
163
 	// check DLINEs
166
 	// check DLINEs
164
-	isBanned, info := server.dlines.CheckIP(ipaddr)
167
+	isBanned, info := server.dlines.CheckIP(flat)
165
 	if isBanned {
168
 	if isBanned {
166
-		server.logger.Info("connect-ip", fmt.Sprintf("Client from %v rejected by d-line", ipaddr))
169
+		server.logger.Info("connect-ip", "Client rejected by d-line", ipaddr.String())
167
 		return true, false, info.BanMessage("You are banned from this server (%s)")
170
 		return true, false, info.BanMessage("You are banned from this server (%s)")
168
 	}
171
 	}
169
 
172
 
170
 	// check connection limits
173
 	// check connection limits
171
-	err := server.connectionLimiter.AddClient(ipaddr)
174
+	err := server.connectionLimiter.AddClient(flat)
172
 	if err == connection_limits.ErrLimitExceeded {
175
 	if err == connection_limits.ErrLimitExceeded {
173
 		// too many connections from one client, tell the client and close the connection
176
 		// too many connections from one client, tell the client and close the connection
174
-		server.logger.Info("connect-ip", fmt.Sprintf("Client from %v rejected for connection limit", ipaddr))
177
+		server.logger.Info("connect-ip", "Client rejected for connection limit", ipaddr.String())
175
 		return true, false, "Too many clients from your network"
178
 		return true, false, "Too many clients from your network"
176
 	} else if err == connection_limits.ErrThrottleExceeded {
179
 	} else if err == connection_limits.ErrThrottleExceeded {
177
-		duration := config.Server.IPLimits.BanDuration
178
-		if duration != 0 {
179
-			server.dlines.AddIP(ipaddr, duration, throttleMessage,
180
-				"Exceeded automated connection throttle", "auto.connection.throttler")
181
-			// they're DLINE'd for 15 minutes or whatever, so we can reset the connection throttle now,
182
-			// and once their temporary DLINE is finished they can fill up the throttler again
183
-			server.connectionLimiter.ResetThrottle(ipaddr)
184
-		}
185
-		server.logger.Info(
186
-			"connect-ip",
187
-			fmt.Sprintf("Client from %v exceeded connection throttle, d-lining for %v", ipaddr, duration))
180
+		server.logger.Info("connect-ip", "Client exceeded connection throttle", ipaddr.String())
188
 		return true, false, throttleMessage
181
 		return true, false, throttleMessage
189
 	} else if err != nil {
182
 	} else if err != nil {
190
 		server.logger.Warning("internal", "unexpected ban result", err.Error())
183
 		server.logger.Warning("internal", "unexpected ban result", err.Error())
211
 		}
204
 		}
212
 		if output.Result == IPBanned {
205
 		if output.Result == IPBanned {
213
 			// XXX roll back IP connection/throttling addition for the IP
206
 			// XXX roll back IP connection/throttling addition for the IP
214
-			server.connectionLimiter.RemoveClient(ipaddr)
207
+			server.connectionLimiter.RemoveClient(flat)
215
 			server.logger.Info("connect-ip", "Rejected client due to ip-check-script", ipaddr.String())
208
 			server.logger.Info("connect-ip", "Rejected client due to ip-check-script", ipaddr.String())
216
 			return true, false, output.BanMessage
209
 			return true, false, output.BanMessage
217
 		} else if output.Result == IPRequireSASL {
210
 		} else if output.Result == IPRequireSASL {

+ 0
- 3
traditional.yaml Ver fichero

220
         window: 10m
220
         window: 10m
221
         # maximum number of new connections per IP/CIDR within the given duration
221
         # maximum number of new connections per IP/CIDR within the given duration
222
         max-connections-per-window: 32
222
         max-connections-per-window: 32
223
-        # how long to ban offenders for. after banning them, the number of connections is
224
-        # reset, which lets you use /UNDLINE to unban people
225
-        throttle-ban-duration: 10m
226
 
223
 
227
         # how wide the CIDR should be for IPv4 (a /32 is a fully specified IPv4 address)
224
         # how wide the CIDR should be for IPv4 (a /32 is a fully specified IPv4 address)
228
         cidr-len-ipv4: 32
225
         cidr-len-ipv4: 32

Loading…
Cancelar
Guardar