mirror of
https://github.com/stalwartlabs/mail-server.git
synced 2025-10-27 12:55:52 +08:00
Added context to SMTP rate limiter keys
This commit is contained in:
parent
26e00b44a8
commit
3c7caddd98
7 changed files with 27 additions and 18 deletions
|
|
@ -74,7 +74,7 @@ pub const KV_RATE_LIMIT_RCPT: u8 = 2;
|
|||
pub const KV_RATE_LIMIT_SCAN: u8 = 3;
|
||||
pub const KV_RATE_LIMIT_LOITER: u8 = 4;
|
||||
pub const KV_RATE_LIMIT_AUTH: u8 = 5;
|
||||
pub const KV_RATE_LIMIT_HASH: u8 = 6;
|
||||
pub const KV_RATE_LIMIT_SMTP: u8 = 6;
|
||||
pub const KV_RATE_LIMIT_CONTACT: u8 = 7;
|
||||
pub const KV_RATE_LIMIT_HTTP_AUTHENTICATED: u8 = 8;
|
||||
pub const KV_RATE_LIMIT_HTTP_ANONYMOUS: u8 = 9;
|
||||
|
|
|
|||
|
|
@ -152,7 +152,7 @@ impl ManageStore for Server {
|
|||
Some("rate-scan") => vec![KV_RATE_LIMIT_SCAN].into(),
|
||||
Some("rate-loiter") => vec![KV_RATE_LIMIT_LOITER].into(),
|
||||
Some("rate-auth") => vec![KV_RATE_LIMIT_AUTH].into(),
|
||||
Some("rate-hash") => vec![KV_RATE_LIMIT_HASH].into(),
|
||||
Some("rate-smtp") => vec![KV_RATE_LIMIT_SMTP].into(),
|
||||
Some("rate-contact") => vec![KV_RATE_LIMIT_CONTACT].into(),
|
||||
Some("rate-http-authenticated") => {
|
||||
vec![KV_RATE_LIMIT_HTTP_AUTHENTICATED].into()
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ use common::{
|
|||
config::smtp::*,
|
||||
expr::{functions::ResolveVariable, *},
|
||||
listener::SessionStream,
|
||||
ThrottleKey, KV_RATE_LIMIT_HASH,
|
||||
ThrottleKey, KV_RATE_LIMIT_SMTP,
|
||||
};
|
||||
use queue::QueueQuota;
|
||||
use trc::SmtpEvent;
|
||||
|
|
@ -17,11 +17,11 @@ use utils::config::Rate;
|
|||
use super::Session;
|
||||
|
||||
pub trait NewKey: Sized {
|
||||
fn new_key(&self, e: &impl ResolveVariable) -> ThrottleKey;
|
||||
fn new_key(&self, e: &impl ResolveVariable, context: &str) -> ThrottleKey;
|
||||
}
|
||||
|
||||
impl NewKey for QueueQuota {
|
||||
fn new_key(&self, e: &impl ResolveVariable) -> ThrottleKey {
|
||||
fn new_key(&self, e: &impl ResolveVariable, _: &str) -> ThrottleKey {
|
||||
let mut hasher = blake3::Hasher::new();
|
||||
|
||||
if (self.keys & THROTTLE_RCPT) != 0 {
|
||||
|
|
@ -72,7 +72,7 @@ impl NewKey for QueueQuota {
|
|||
}
|
||||
|
||||
impl NewKey for QueueRateLimiter {
|
||||
fn new_key(&self, e: &impl ResolveVariable) -> ThrottleKey {
|
||||
fn new_key(&self, e: &impl ResolveVariable, context: &str) -> ThrottleKey {
|
||||
let mut hasher = blake3::Hasher::new();
|
||||
|
||||
if (self.keys & THROTTLE_RCPT) != 0 {
|
||||
|
|
@ -129,8 +129,9 @@ impl NewKey for QueueRateLimiter {
|
|||
if (self.keys & THROTTLE_LOCAL_IP) != 0 {
|
||||
hasher.update(e.resolve_variable(V_LOCAL_IP).to_string().as_bytes());
|
||||
}
|
||||
hasher.update(&self.rate.period.as_secs().to_ne_bytes()[..]);
|
||||
hasher.update(&self.rate.requests.to_ne_bytes()[..]);
|
||||
hasher.update(&self.rate.period.as_secs().to_be_bytes()[..]);
|
||||
hasher.update(&self.rate.requests.to_be_bytes()[..]);
|
||||
hasher.update(context.as_bytes());
|
||||
|
||||
ThrottleKey {
|
||||
hash: hasher.finalize().into(),
|
||||
|
|
@ -170,7 +171,7 @@ impl<T: SessionStream> Session<T> {
|
|||
}
|
||||
|
||||
// Build throttle key
|
||||
let key = t.new_key(self);
|
||||
let key = t.new_key(self, "inbound");
|
||||
|
||||
// Check rate
|
||||
match self
|
||||
|
|
@ -178,7 +179,7 @@ impl<T: SessionStream> Session<T> {
|
|||
.core
|
||||
.storage
|
||||
.lookup
|
||||
.is_rate_allowed(KV_RATE_LIMIT_HASH, key.hash.as_slice(), &t.rate, false)
|
||||
.is_rate_allowed(KV_RATE_LIMIT_SMTP, key.hash.as_slice(), &t.rate, false)
|
||||
.await
|
||||
{
|
||||
Ok(Some(_)) => {
|
||||
|
|
@ -220,7 +221,7 @@ impl<T: SessionStream> Session<T> {
|
|||
.storage
|
||||
.lookup
|
||||
.is_rate_allowed(
|
||||
KV_RATE_LIMIT_HASH,
|
||||
KV_RATE_LIMIT_SMTP,
|
||||
hasher.finalize().as_bytes(),
|
||||
rate,
|
||||
false,
|
||||
|
|
|
|||
|
|
@ -129,7 +129,7 @@ impl HasQueueQuota for Server {
|
|||
.await
|
||||
.unwrap_or(false)
|
||||
{
|
||||
let key = quota.new_key(envelope);
|
||||
let key = quota.new_key(envelope, "");
|
||||
if let Some(max_size) = quota.size {
|
||||
let used_size = self
|
||||
.core
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
use std::future::Future;
|
||||
|
||||
use common::{
|
||||
config::smtp::QueueRateLimiter, expr::functions::ResolveVariable, Server, KV_RATE_LIMIT_HASH,
|
||||
config::smtp::QueueRateLimiter, expr::functions::ResolveVariable, Server, KV_RATE_LIMIT_SMTP,
|
||||
};
|
||||
use store::write::now;
|
||||
|
||||
|
|
@ -37,13 +37,13 @@ impl IsAllowed for Server {
|
|||
.await
|
||||
.unwrap_or(false)
|
||||
{
|
||||
let key = throttle.new_key(envelope);
|
||||
let key = throttle.new_key(envelope, "outbound");
|
||||
|
||||
match self
|
||||
.core
|
||||
.storage
|
||||
.lookup
|
||||
.is_rate_allowed(KV_RATE_LIMIT_HASH, key.as_ref(), &throttle.rate, false)
|
||||
.is_rate_allowed(KV_RATE_LIMIT_SMTP, key.as_ref(), &throttle.rate, false)
|
||||
.await
|
||||
{
|
||||
Ok(Some(next_refill)) => {
|
||||
|
|
|
|||
|
|
@ -41,9 +41,19 @@ impl HttpStoreGet for Arc<HttpStore> {
|
|||
fn contains(&self, key: &str) -> bool {
|
||||
#[cfg(feature = "test_mode")]
|
||||
{
|
||||
if key.contains("open") || key.contains("tank") {
|
||||
if self.config.url.contains("phishtank.com")
|
||||
|| self.config.url.contains("openphish.com")
|
||||
{
|
||||
return (self.config.url.contains("open") && key.contains("open"))
|
||||
|| (self.config.url.contains("tank") && key.contains("tank"));
|
||||
} else if self.config.url.contains("disposable.github.io") {
|
||||
return key.ends_with("guerrillamail.com") || key.ends_with("disposable.org");
|
||||
} else if self.config.url.contains("free_email_provider_domains.txt") {
|
||||
return key.ends_with("gmail.com")
|
||||
|| key.ends_with("googlemail.com")
|
||||
|| key.ends_with("yahoomail.com")
|
||||
|| key.ends_with("outlook.com")
|
||||
|| key.ends_with("freemail.org");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -119,8 +119,6 @@ allow-invalid-certs = true
|
|||
"url-redirectors" = {"bit.ly", "redirect.io", "redirect.me", "redirect.org", "redirect.com", "redirect.net", "t.ly", "tinyurl.com"}
|
||||
"spam-traps" = {"spamtrap@*"}
|
||||
"trusted-domains" = {"stalw.art"}
|
||||
"freemail-providers" = {"gmail.com", "googlemail.com", "yahoomail.com", "outlook.com", "*freemail.org"}
|
||||
"disposable-providers" = {"guerrillamail.com", "*disposable.org"}
|
||||
"surbl-hashbl" = {"bit.ly", "drive.google.com", "lnkiy.in"}
|
||||
"#;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue