mirror of
https://github.com/storytold/artcraft.git
synced 2026-11-05 17:58:55 +00:00
IP bans work!
This commit is contained in:
1 parent
8b95ea3abd
commit
98b71277ac
3 files changed
+44
-4
No files matched your search
@@ -8,6 +8,8 @@ use futures::Future;
|
||||
use crate::threads::ip_banlist_set::IpBanlistSet;
|
||||
use log::warn;
|
||||
use log::info;
|
||||
use crate::http_server::web_utils::ip_address::get_service_request_ip;
|
||||
use actix_web::error::ErrorForbidden;
|
||||
|
||||
// There are two steps in middleware processing.
|
||||
// 1. Middleware initialization, middleware factory gets called with
|
||||
@@ -69,8 +71,15 @@ impl<S, B> Service for IpFilterMiddleware<S>
|
||||
}
|
||||
|
||||
fn call(&mut self, req: ServiceRequest) -> Self::Future {
|
||||
println!("Hi from start. You requested: {}", req.path());
|
||||
info!("Checking IP. There are {} bans currently.", self.ip_banlist.num_bans().unwrap_or(0));
|
||||
let ip_address = get_service_request_ip(&req);
|
||||
|
||||
// NB: Fail open.
|
||||
let is_banned = self.ip_banlist.is_banned(&ip_address).unwrap_or(false);
|
||||
|
||||
if is_banned {
|
||||
warn!("Ip is banned: {}", &ip_address);
|
||||
return Box::pin(ok(req.error_response(ErrorForbidden("Forbidden"))))
|
||||
}
|
||||
|
||||
let fut = self.service.call(req);
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use actix_web::HttpRequest;
|
||||
use actix_web::http::HeaderName;
|
||||
use log::{info};
|
||||
use actix_web::dev::ServiceRequest;
|
||||
|
||||
pub fn get_request_ip(request: &HttpRequest) -> String {
|
||||
match request.headers().get(HeaderName::from_static("x-voder-proxy-for")) {
|
||||
@@ -30,3 +31,33 @@ pub fn get_request_ip(request: &HttpRequest) -> String {
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: De-duplicate
|
||||
pub fn get_service_request_ip(request: &ServiceRequest) -> String {
|
||||
match request.headers().get(HeaderName::from_static("x-voder-proxy-for")) {
|
||||
Some(ip_address) => {
|
||||
// Unfortunately the upstream Rust proxy is replacing the `forwarded` and `x-forwarded-for`
|
||||
// headers, so we populate this custom header as a workaround.
|
||||
info!("Proxied IP address: {:?}", ip_address);
|
||||
ip_address.to_str()
|
||||
.unwrap_or("")
|
||||
.to_string()
|
||||
},
|
||||
None => {
|
||||
// If we're running without the upstream Rust proxy, we can grab 'x-forarded-for', which is
|
||||
// populated by the DigitalOcean load balancer.
|
||||
let ip_address_and_port = request.connection_info()
|
||||
.remote_addr()
|
||||
.unwrap_or("")
|
||||
.to_string();
|
||||
let ip_address = ip_address_and_port.split(":")
|
||||
.collect::<Vec<&str>>()
|
||||
.get(0)
|
||||
.copied()
|
||||
.unwrap_or("")
|
||||
.to_string();
|
||||
info!("Forwarded IP address: {}", &ip_address);
|
||||
ip_address
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -27,11 +27,11 @@ impl IpBanlistSet {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_banned(&self, ip_address: String) -> AnyhowResult<bool> {
|
||||
pub fn is_banned<S: AsRef<str>>(&self, ip_address: S) -> AnyhowResult<bool> {
|
||||
match self.ip_banlist.read() {
|
||||
Err(_) => Err(anyhow!("Can't read lock")),
|
||||
Ok(read) => {
|
||||
let result = read.contains(&ip_address);
|
||||
let result = read.contains(ip_address.as_ref());
|
||||
Ok(result)
|
||||
},
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user