don't send requests to specified list of IP CIDRs

this can most definitely be improved but this is a decent attempt.
the only annoying this is i couldn't just use a Vec<IPAddress> which
would have significantly simplified all of this, but serde can't
deserialise it on the config side i guess.

i may find a better way to do this in the future, but this should cover
most areas anyways.

Signed-off-by: strawberry <strawberry@puppygock.gay>
This commit is contained in:
strawberry 2024-01-21 22:59:06 -05:00 committed by June
parent 71d247232d
commit fa0c083555
8 changed files with 186 additions and 3 deletions

View file

@ -427,6 +427,10 @@ impl Service<'_> {
&self.config.prevent_media_downloads_from
}
pub fn ip_range_denylist(&self) -> &[String] {
&self.config.ip_range_denylist
}
pub fn supported_room_versions(&self) -> Vec<RoomVersionId> {
let mut room_versions: Vec<RoomVersionId> = vec![];
room_versions.extend(self.stable_room_versions.clone());

View file

@ -1,6 +1,7 @@
mod data;
pub use data::Data;
use ipaddress::IPAddress;
use std::{
collections::{BTreeMap, HashMap, HashSet},
@ -43,7 +44,7 @@ use tokio::{
select,
sync::{mpsc, Mutex, Semaphore},
};
use tracing::{debug, error, warn};
use tracing::{debug, error, info, warn};
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub enum OutgoingKind {
@ -716,6 +717,29 @@ impl Service {
where
T: Debug,
{
if destination.is_ip_literal() {
info!("Destination is an IP literal, checking against IP range denylist.");
let ip = IPAddress::parse(destination.host()).map_err(|e| {
warn!("Failed to parse IP literal from string: {}", e);
Error::BadServerResponse("Invalid IP address")
})?;
let cidr_ranges_s = services().globals.ip_range_denylist().to_vec();
let mut cidr_ranges: Vec<IPAddress> = Vec::new();
for cidr in cidr_ranges_s {
cidr_ranges.push(IPAddress::parse(cidr).expect("we checked this at startup"));
}
for cidr in cidr_ranges {
if ip.includes(&cidr) {
return Err(Error::BadServerResponse(
"Not allowed to send requests to this IP",
));
}
}
}
debug!("Waiting for permit");
let permit = self.maximum_requests.acquire().await;
debug!("Got permit");