connectban: never flood-ban loopback (127.0.0.1/::1) and add a connectban_exempt glob/cidr list
This commit is contained in:
parent
59b0439b79
commit
7d57e4ed34
3 changed files with 19 additions and 0 deletions
|
|
@ -421,6 +421,8 @@ amu_target = both
|
||||||
# connectban_ipv4cidr = 32 # range width for IPv4 counting (default /32)
|
# connectban_ipv4cidr = 32 # range width for IPv4 counting (default /32)
|
||||||
# connectban_ipv6cidr = 128 # range width for IPv6 counting (default /128)
|
# connectban_ipv6cidr = 128 # range width for IPv6 counting (default /128)
|
||||||
# connectban_banmessage = Too many connections from your address
|
# connectban_banmessage = Too many connections from your address
|
||||||
|
# connectban_exempt = 10.0.0.0/8 # never ban this glob/CIDR (repeatable);
|
||||||
|
# # loopback (127.0.0.0/8, ::1) is always exempt
|
||||||
# --- hashident: replace ident with a stable opaque token per IP ---
|
# --- hashident: replace ident with a stable opaque token per IP ---
|
||||||
# hashident = yes
|
# hashident = yes
|
||||||
# hashident_key = CHANGE_THIS_SECRET # HMAC key; makes the mapping unforgeable
|
# hashident_key = CHANGE_THIS_SECRET # HMAC key; makes the mapping unforgeable
|
||||||
|
|
|
||||||
|
|
@ -67,12 +67,25 @@ fn range_of(ip: IpAddr, v4cidr: u8, v6cidr: u8) -> (String, String) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Whether `ip` matches a configured `connectban_exempt` glob/CIDR (repeatable).
|
||||||
|
fn connectban_exempt(s: &Server, ip: IpAddr) -> bool {
|
||||||
|
let ipstr = ip.to_string();
|
||||||
|
s.conf_all("connectban_exempt")
|
||||||
|
.iter()
|
||||||
|
.any(|m| crate::modules::connclass::ip_matches(m, &ipstr))
|
||||||
|
}
|
||||||
|
|
||||||
/// Record a new connection from `ip`, z-lining its range if it crosses the limit.
|
/// Record a new connection from `ip`, z-lining its range if it crosses the limit.
|
||||||
/// No-op when connectban is disabled or still inside the boot-grace window.
|
/// No-op when connectban is disabled or still inside the boot-grace window.
|
||||||
pub fn on_connect(s: &mut Server, ip: IpAddr) {
|
pub fn on_connect(s: &mut Server, ip: IpAddr) {
|
||||||
if !s.conf_bool("connectban", false) {
|
if !s.conf_bool("connectban", false) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// never connect-ban loopback (local services, bridges, admin tooling all dial in
|
||||||
|
// over 127.0.0.1 / ::1) or an admin-configured exempt range
|
||||||
|
if ip.is_loopback() || connectban_exempt(s, ip) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
let threshold = s.conf_num("connectban_threshold", 10u32).max(2);
|
let threshold = s.conf_num("connectban_threshold", 10u32).max(2);
|
||||||
let v4 = s.conf_num("connectban_ipv4cidr", 32u8).clamp(1, 32);
|
let v4 = s.conf_num("connectban_ipv4cidr", 32u8).clamp(1, 32);
|
||||||
let v6 = s.conf_num("connectban_ipv6cidr", 128u8).clamp(1, 128);
|
let v6 = s.conf_num("connectban_ipv6cidr", 128u8).clamp(1, 128);
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,10 @@ fn cfg(s: &Server) -> Option<(u32, u64)> {
|
||||||
/// Record a connection from `ip`; returns true when it exceeds the limit (the
|
/// Record a connection from `ip`; returns true when it exceeds the limit (the
|
||||||
/// caller should refuse it). No-op → false when connflood is unconfigured.
|
/// caller should refuse it). No-op → false when connflood is unconfigured.
|
||||||
pub fn over_limit(s: &mut Server, ip: IpAddr) -> bool {
|
pub fn over_limit(s: &mut Server, ip: IpAddr) -> bool {
|
||||||
|
// loopback (local services / bridges / admin) is never connection-throttled
|
||||||
|
if ip.is_loopback() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
let Some((max, secs)) = cfg(s) else {
|
let Some((max, secs)) = cfg(s) else {
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue