add federation allow list

This commit is contained in:
Jade Ellis 2025-01-18 15:21:55 +00:00
parent eb7d893c86
commit 371103fb35
No known key found for this signature in database
GPG key ID: 8705A2A3EBF77BD2
15 changed files with 101 additions and 94 deletions

View file

@ -71,10 +71,8 @@ async fn banned_room_check(
if let Some(room_id) = room_id {
if services.rooms.metadata.is_banned(room_id).await
|| services
.server
.config
.forbidden_remote_server_names
.contains(&room_id.server_name().unwrap().to_owned())
.moderation
.is_remote_server_forbidden(room_id.server_name().unwrap())
{
warn!(
"User {user_id} who is not an admin attempted to send an invite for or \
@ -111,12 +109,7 @@ async fn banned_room_check(
return Err!(Request(Forbidden("This room is banned on this homeserver.")));
}
} else if let Some(server_name) = server_name {
if services
.server
.config
.forbidden_remote_server_names
.contains(&server_name.to_owned())
{
if services.moderation.is_remote_server_forbidden(server_name) {
warn!(
"User {user_id} who is not an admin tried joining a room which has the server \
name {server_name} that is globally forbidden. Rejecting.",

View file

@ -1,6 +1,6 @@
use axum::extract::State;
use conduwuit::{
at, is_equal_to,
at,
utils::{
result::{FlatOk, LogErr},
stream::{BroadbandExt, TryIgnore, WidebandExt},
@ -241,11 +241,8 @@ pub(crate) async fn ignored_filter(
if IGNORED_MESSAGE_TYPES.binary_search(&pdu.kind).is_ok()
&& (services.users.user_is_ignored(&pdu.sender, user_id).await
|| services
.server
.config
.forbidden_remote_server_names
.iter()
.any(is_equal_to!(pdu.sender().server_name())))
.moderation
.is_remote_server_forbidden(pdu.sender().server_name()))
{
return None;
}

View file

@ -317,12 +317,7 @@ fn auth_server_checks(services: &Services, x_matrix: &XMatrix) -> Result<()> {
}
let origin = &x_matrix.origin;
if services
.server
.config
.forbidden_remote_server_names
.contains(origin)
{
if services.moderation.is_remote_server_forbidden(origin) {
return Err!(Request(Forbidden(debug_warn!(
"Federation requests from {origin} denied."
))));

View file

@ -36,21 +36,14 @@ pub(crate) async fn create_invite_route(
}
if let Some(server) = body.room_id.server_name() {
if services
.server
.config
.forbidden_remote_server_names
.contains(&server.to_owned())
{
if services.moderation.is_remote_server_forbidden(server) {
return Err!(Request(Forbidden("Server is banned on this homeserver.")));
}
}
if services
.server
.config
.forbidden_remote_server_names
.contains(body.origin())
.moderation
.is_remote_server_forbidden(body.origin())
{
warn!(
"Received federated/remote invite from banned server {} for room ID {}. Rejecting.",

View file

@ -42,10 +42,8 @@ pub(crate) async fn create_join_event_template_route(
.await?;
if services
.server
.config
.forbidden_remote_server_names
.contains(body.origin())
.moderation
.is_remote_server_forbidden(body.origin())
{
warn!(
"Server {} for remote user {} tried joining room ID {} which has a server name that \
@ -58,12 +56,7 @@ pub(crate) async fn create_join_event_template_route(
}
if let Some(server) = body.room_id.server_name() {
if services
.server
.config
.forbidden_remote_server_names
.contains(&server.to_owned())
{
if services.moderation.is_remote_server_forbidden(server) {
return Err!(Request(Forbidden(warn!(
"Room ID server name {server} is banned on this homeserver."
))));

View file

@ -34,10 +34,8 @@ pub(crate) async fn create_knock_event_template_route(
.await?;
if services
.server
.config
.forbidden_remote_server_names
.contains(body.origin())
.moderation
.is_remote_server_forbidden(body.origin())
{
warn!(
"Server {} for remote user {} tried knocking room ID {} which has a server name \
@ -50,12 +48,7 @@ pub(crate) async fn create_knock_event_template_route(
}
if let Some(server) = body.room_id.server_name() {
if services
.server
.config
.forbidden_remote_server_names
.contains(&server.to_owned())
{
if services.moderation.is_remote_server_forbidden(server) {
return Err!(Request(Forbidden("Server is banned on this homeserver.")));
}
}

View file

@ -270,10 +270,8 @@ pub(crate) async fn create_join_event_v1_route(
body: Ruma<create_join_event::v1::Request>,
) -> Result<create_join_event::v1::Response> {
if services
.server
.config
.forbidden_remote_server_names
.contains(body.origin())
.moderation
.is_remote_server_forbidden(body.origin())
{
warn!(
"Server {} tried joining room ID {} through us who has a server name that is \
@ -285,12 +283,7 @@ pub(crate) async fn create_join_event_v1_route(
}
if let Some(server) = body.room_id.server_name() {
if services
.server
.config
.forbidden_remote_server_names
.contains(&server.to_owned())
{
if services.moderation.is_remote_server_forbidden(server) {
warn!(
"Server {} tried joining room ID {} through us which has a server name that is \
globally forbidden. Rejecting.",
@ -318,21 +311,14 @@ pub(crate) async fn create_join_event_v2_route(
body: Ruma<create_join_event::v2::Request>,
) -> Result<create_join_event::v2::Response> {
if services
.server
.config
.forbidden_remote_server_names
.contains(body.origin())
.moderation
.is_remote_server_forbidden(body.origin())
{
return Err!(Request(Forbidden("Server is banned on this homeserver.")));
}
if let Some(server) = body.room_id.server_name() {
if services
.server
.config
.forbidden_remote_server_names
.contains(&server.to_owned())
{
if services.moderation.is_remote_server_forbidden(server) {
warn!(
"Server {} tried joining room ID {} through us which has a server name that is \
globally forbidden. Rejecting.",

View file

@ -22,10 +22,8 @@ pub(crate) async fn create_knock_event_v1_route(
body: Ruma<send_knock::v1::Request>,
) -> Result<send_knock::v1::Response> {
if services
.server
.config
.forbidden_remote_server_names
.contains(body.origin())
.moderation
.is_remote_server_forbidden(body.origin())
{
warn!(
"Server {} tried knocking room ID {} who has a server name that is globally \
@ -37,12 +35,7 @@ pub(crate) async fn create_knock_event_v1_route(
}
if let Some(server) = body.room_id.server_name() {
if services
.server
.config
.forbidden_remote_server_names
.contains(&server.to_owned())
{
if services.moderation.is_remote_server_forbidden(server) {
warn!(
"Server {} tried knocking room ID {} which has a server name that is globally \
forbidden. Rejecting.",

View file

@ -1335,12 +1335,22 @@ pub struct Config {
/// sender user's server name, inbound federation X-Matrix origin, and
/// outbound federation handler.
///
/// Additionally, it will hide messages from these servers for all users
/// on this server.
///
/// Basically "global" ACLs.
///
/// default: []
#[serde(default)]
pub forbidden_remote_server_names: HashSet<OwnedServerName>,
/// The inverse of `forbidden_remote_server_names`. By default, allows all
/// servers. `forbidden_remote_server_names` takes precidence.
///
/// default: []
#[serde(default)]
pub allowed_remote_server_names: HashSet<OwnedServerName>,
/// List of forbidden server names that we will block all outgoing federated
/// room directory requests for. Useful for preventing our users from
/// wandering into bad servers or spaces.

View file

@ -65,13 +65,7 @@ where
return Err!(Config("allow_federation", "Federation is disabled."));
}
if self
.services
.server
.config
.forbidden_remote_server_names
.contains(dest)
{
if self.services.moderation.is_remote_server_forbidden(dest) {
return Err!(Request(Forbidden(debug_warn!("Federation with {dest} is not allowed."))));
}

View file

@ -4,7 +4,7 @@ use std::sync::Arc;
use conduwuit::{Result, Server};
use crate::{client, resolver, server_keys, Dep};
use crate::{client, moderation, resolver, server_keys, Dep};
pub struct Service {
services: Services,
@ -15,6 +15,7 @@ struct Services {
client: Dep<client::Service>,
resolver: Dep<resolver::Service>,
server_keys: Dep<server_keys::Service>,
moderation: Dep<moderation::Service>,
}
impl crate::Service for Service {
@ -25,6 +26,7 @@ impl crate::Service for Service {
client: args.depend::<client::Service>("client"),
resolver: args.depend::<resolver::Service>("resolver"),
server_keys: args.depend::<server_keys::Service>("server_keys"),
moderation: args.depend::<moderation::Service>("moderation"),
},
}))
}

View file

@ -15,6 +15,7 @@ pub mod federation;
pub mod globals;
pub mod key_backups;
pub mod media;
pub mod moderation;
pub mod presence;
pub mod pusher;
pub mod resolver;

View file

@ -0,0 +1,54 @@
use std::sync::Arc;
use conduwuit::{implement, Result, Server};
use ruma::ServerName;
use crate::{globals, Dep};
pub struct Service {
services: Services,
}
struct Services {
pub server: Arc<Server>,
pub globals: Dep<globals::Service>,
}
impl crate::Service for Service {
fn build(args: crate::Args<'_>) -> Result<Arc<Self>> {
Ok(Arc::new(Self {
services: Services {
server: args.server.clone(),
globals: args.depend::<globals::Service>("globals"),
},
}))
}
fn name(&self) -> &str { crate::service::make_name(std::module_path!()) }
}
#[implement(Service)]
#[must_use]
pub fn is_remote_server_forbidden(&self, server_name: &ServerName) -> bool {
// Forbidden if NOT (allowed is empty OR allowed contains server OR is self)
// OR forbidden contains server
!(self
.services
.server
.config
.allowed_remote_server_names
.is_empty()
|| self
.services
.server
.config
.allowed_remote_server_names
.contains(server_name)
|| server_name == self.services.globals.server_name())
|| self
.services
.server
.config
.forbidden_remote_server_names
.contains(server_name)
}

View file

@ -30,8 +30,9 @@ pub use self::{
sender::{EDU_LIMIT, PDU_LIMIT},
};
use crate::{
account_data, client, federation, globals, presence, pusher, rooms,
rooms::timeline::RawPduId, users, Dep,
account_data, client, federation, globals, presence, pusher,
rooms::{self, timeline::RawPduId},
users, Dep,
};
pub struct Service {

View file

@ -12,8 +12,8 @@ use tokio::sync::Mutex;
use crate::{
account_data, admin, appservice, client, config, emergency, federation, globals, key_backups,
manager::Manager,
media, presence, pusher, resolver, rooms, sending, server_keys, service,
service::{Args, Map, Service},
media, moderation, presence, pusher, resolver, rooms, sending, server_keys,
service::{self, Args, Map, Service},
sync, transaction_ids, uiaa, updates, users,
};
@ -31,6 +31,7 @@ pub struct Services {
pub pusher: Arc<pusher::Service>,
pub resolver: Arc<resolver::Service>,
pub rooms: rooms::Service,
pub moderation: Arc<moderation::Service>,
pub federation: Arc<federation::Service>,
pub sending: Arc<sending::Service>,
pub server_keys: Arc<server_keys::Service>,
@ -98,6 +99,7 @@ impl Services {
typing: build!(rooms::typing::Service),
user: build!(rooms::user::Service),
},
moderation: build!(moderation::Service),
federation: build!(federation::Service),
sending: build!(sending::Service),
server_keys: build!(server_keys::Service),