Implement instance blocklist (#85)
Implement instance blocklist Co-authored-by: Felix Ableitner <me@nutomic.com> Reviewed-on: https://yerbamate.dev/LemmyNet/lemmy/pulls/85
This commit is contained in:
parent
9a343cfe8b
commit
164a9c29fe
3 changed files with 47 additions and 25 deletions
4
server/config/defaults.hjson
vendored
4
server/config/defaults.hjson
vendored
|
@ -62,8 +62,10 @@
|
|||
enabled: false
|
||||
# whether tls is required for activitypub. only disable this for debugging, never for producion.
|
||||
tls_enabled: true
|
||||
# comma seperated list of instances with which federation is allowed
|
||||
# comma separated list of instances with which federation is allowed
|
||||
allowed_instances: ""
|
||||
# comma separated list of instances which are blocked from federating
|
||||
blocked_instances: ""
|
||||
}
|
||||
captcha: {
|
||||
enabled: true
|
||||
|
|
|
@ -8,7 +8,7 @@ static CONFIG_FILE: &str = "config/config.hjson";
|
|||
#[derive(Debug, Deserialize, Clone)]
|
||||
pub struct Settings {
|
||||
pub setup: Option<Setup>,
|
||||
pub database: Database,
|
||||
pub database: DatabaseConfig,
|
||||
pub hostname: String,
|
||||
pub bind: IpAddr,
|
||||
pub port: u16,
|
||||
|
@ -17,7 +17,7 @@ pub struct Settings {
|
|||
pub pictrs_url: String,
|
||||
pub rate_limit: RateLimitConfig,
|
||||
pub email: Option<EmailConfig>,
|
||||
pub federation: Federation,
|
||||
pub federation: FederationConfig,
|
||||
pub captcha: CaptchaConfig,
|
||||
}
|
||||
|
||||
|
@ -57,7 +57,7 @@ pub struct CaptchaConfig {
|
|||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Clone)]
|
||||
pub struct Database {
|
||||
pub struct DatabaseConfig {
|
||||
pub user: String,
|
||||
pub password: String,
|
||||
pub host: String,
|
||||
|
@ -67,10 +67,11 @@ pub struct Database {
|
|||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Clone)]
|
||||
pub struct Federation {
|
||||
pub struct FederationConfig {
|
||||
pub enabled: bool,
|
||||
pub tls_enabled: bool,
|
||||
pub allowed_instances: String,
|
||||
pub blocked_instances: String,
|
||||
}
|
||||
|
||||
lazy_static! {
|
||||
|
@ -143,6 +144,20 @@ impl Settings {
|
|||
allowed_instances
|
||||
}
|
||||
|
||||
pub fn get_blocked_instances(&self) -> Vec<String> {
|
||||
let mut blocked_instances: Vec<String> = self
|
||||
.federation
|
||||
.blocked_instances
|
||||
.split(',')
|
||||
.map(|d| d.to_string())
|
||||
.collect();
|
||||
|
||||
// The defaults.hjson config always returns a [""]
|
||||
blocked_instances.retain(|d| !d.eq(""));
|
||||
|
||||
blocked_instances
|
||||
}
|
||||
|
||||
pub fn save_config_file(data: &str) -> Result<String, Error> {
|
||||
fs::write(CONFIG_FILE, data)?;
|
||||
|
||||
|
|
|
@ -76,30 +76,35 @@ fn check_is_apub_id_valid(apub_id: &Url) -> Result<(), LemmyError> {
|
|||
return Err(anyhow!("invalid apub id scheme: {:?}", apub_id.scheme()).into());
|
||||
}
|
||||
|
||||
let mut allowed_instances: Vec<String> = Settings::get().get_allowed_instances();
|
||||
let mut allowed_instances = Settings::get().get_allowed_instances();
|
||||
let blocked_instances = Settings::get().get_blocked_instances();
|
||||
|
||||
// need to allow this explicitly because apub activities might contain objects from our local
|
||||
// instance. replace is needed to remove the port in our federation test setup.
|
||||
let settings = Settings::get();
|
||||
let local_instance = settings.hostname.split(':').collect::<Vec<&str>>();
|
||||
allowed_instances.push(
|
||||
local_instance
|
||||
.first()
|
||||
.context(location_info!())?
|
||||
.to_string(),
|
||||
);
|
||||
|
||||
match apub_id.domain() {
|
||||
Some(d) => {
|
||||
let contains = allowed_instances.contains(&d.to_owned());
|
||||
|
||||
if !contains {
|
||||
return Err(anyhow!("{} not in federation allowlist", d).into());
|
||||
}
|
||||
let domain = apub_id.domain().context(location_info!())?.to_string();
|
||||
if !allowed_instances.is_empty() {
|
||||
// need to allow this explicitly because apub activities might contain objects from our local
|
||||
// instance. split is needed to remove the port in our federation test setup.
|
||||
let settings = Settings::get();
|
||||
let local_instance = settings.hostname.split(':').collect::<Vec<&str>>();
|
||||
allowed_instances.push(
|
||||
local_instance
|
||||
.first()
|
||||
.context(location_info!())?
|
||||
.to_string(),
|
||||
);
|
||||
|
||||
if allowed_instances.contains(&domain) {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(anyhow!("{} not in federation allowlist", domain).into())
|
||||
}
|
||||
} else if !blocked_instances.is_empty() {
|
||||
if blocked_instances.contains(&domain) {
|
||||
Err(anyhow!("{} is in federation blocklist", domain).into())
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
None => Err(anyhow!("federation allowlist is empty").into()),
|
||||
} else {
|
||||
panic!("Invalid config, both allowed_instances and blocked_instances are specified");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue