mirror of
https://github.com/stalwartlabs/mail-server.git
synced 2024-11-24 06:19:46 +00:00
Stricter RCPT fail2ban + Do not send SPF failures reports to local domains
Some checks are pending
trivy / Check (push) Waiting to run
Some checks are pending
trivy / Check (push) Waiting to run
This commit is contained in:
parent
b74e6fd021
commit
1561a603ab
3 changed files with 42 additions and 20 deletions
|
@ -542,6 +542,25 @@ impl<T: SessionStream> Session<T> {
|
|||
)
|
||||
.await,
|
||||
) {
|
||||
// Do not send SPF auth failures to local domains, as they are likely relay attempts (which are blocked later on)
|
||||
match self
|
||||
.server
|
||||
.core
|
||||
.storage
|
||||
.directory
|
||||
.is_local_domain(recipient.domain_part())
|
||||
.await
|
||||
{
|
||||
Ok(true) => return Ok(result),
|
||||
Ok(false) => (),
|
||||
Err(err) => {
|
||||
trc::error!(err
|
||||
.caused_by(trc::location!())
|
||||
.span_id(self.data.session_id)
|
||||
.details("Failed to lookup local domain"));
|
||||
}
|
||||
}
|
||||
|
||||
self.send_spf_report(recipient, &rate, !result, spf_output)
|
||||
.await;
|
||||
}
|
||||
|
|
|
@ -304,33 +304,36 @@ impl<T: SessionStream> Session<T> {
|
|||
async fn rcpt_error(&mut self, response: &[u8]) -> Result<(), ()> {
|
||||
tokio::time::sleep(self.params.rcpt_errors_wait).await;
|
||||
self.data.rcpt_errors += 1;
|
||||
self.write(response).await?;
|
||||
if self.data.rcpt_errors < self.params.rcpt_errors_max {
|
||||
Ok(())
|
||||
} else {
|
||||
match self.server.is_rcpt_fail2banned(self.data.remote_ip).await {
|
||||
Ok(true) => {
|
||||
trc::event!(
|
||||
Security(SecurityEvent::BruteForceBan),
|
||||
SpanId = self.data.session_id,
|
||||
RemoteIp = self.data.remote_ip,
|
||||
);
|
||||
}
|
||||
Ok(false) => {
|
||||
let has_too_many_errors = self.data.rcpt_errors >= self.params.rcpt_errors_max;
|
||||
|
||||
match self.server.is_rcpt_fail2banned(self.data.remote_ip).await {
|
||||
Ok(true) => {
|
||||
trc::event!(
|
||||
Security(SecurityEvent::BruteForceBan),
|
||||
SpanId = self.data.session_id,
|
||||
RemoteIp = self.data.remote_ip,
|
||||
);
|
||||
}
|
||||
Ok(false) => {
|
||||
if has_too_many_errors {
|
||||
trc::event!(
|
||||
Smtp(SmtpEvent::TooManyInvalidRcpt),
|
||||
SpanId = self.data.session_id,
|
||||
Limit = self.params.rcpt_errors_max,
|
||||
);
|
||||
}
|
||||
Err(err) => {
|
||||
trc::error!(err
|
||||
.span_id(self.data.session_id)
|
||||
.caused_by(trc::location!())
|
||||
.details("Failed to check if IP should be banned."));
|
||||
}
|
||||
}
|
||||
Err(err) => {
|
||||
trc::error!(err
|
||||
.span_id(self.data.session_id)
|
||||
.caused_by(trc::location!())
|
||||
.details("Failed to check if IP should be banned."));
|
||||
}
|
||||
}
|
||||
|
||||
if !has_too_many_errors {
|
||||
self.write(response).await
|
||||
} else {
|
||||
self.write(b"421 4.3.0 Too many errors, disconnecting.\r\n")
|
||||
.await?;
|
||||
Err(())
|
||||
|
|
|
@ -103,6 +103,7 @@ pub async fn test(params: &mut JMAPTest) {
|
|||
&OAuthCodeRequest::Code {
|
||||
client_id: client_id.to_string(),
|
||||
redirect_uri: "https://localhost".to_string().into(),
|
||||
nonce: "abc1234".to_string().into(),
|
||||
},
|
||||
)
|
||||
.await
|
||||
|
@ -136,7 +137,6 @@ pub async fn test(params: &mut JMAPTest) {
|
|||
|
||||
// Obtain token
|
||||
token_params.insert("redirect_uri".to_string(), "https://localhost".to_string());
|
||||
token_params.insert("nonce".to_string(), "abc1234".to_string());
|
||||
let (token, refresh_token, id_token) =
|
||||
unwrap_oidc_token_response(post(&metadata.token_endpoint, &token_params).await);
|
||||
|
||||
|
|
Loading…
Reference in a new issue