Use actix-remote-ip to identify remote IP address

This commit is contained in:
Pierre Hubert 2024-01-05 10:10:02 +01:00
parent 087e1b2070
commit 0a9bd1f289
4 changed files with 34 additions and 28 deletions

12
Cargo.lock generated
View File

@ -154,6 +154,17 @@ dependencies = [
"syn 2.0.41",
]
[[package]]
name = "actix-remote-ip"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7629b357d4705cf3f1e31f989f48ecd56027112f7d52dcf06dd96ee197065f8e"
dependencies = [
"actix-web",
"futures-util",
"log",
]
[[package]]
name = "actix-router"
version = "0.5.1"
@ -900,6 +911,7 @@ dependencies = [
"actix-files",
"actix-http",
"actix-multipart",
"actix-remote-ip",
"actix-web",
"actix-web-actors",
"async-recursion",

View File

@ -14,6 +14,7 @@ actix-web = "4.4.0"
actix-files = "0.6.2"
actix-multipart = "0.6.1"
actix-web-actors = "4.2.0"
actix-remote-ip = "0.1.0"
actix-http = "3.3.1"
serde = { version = "1.0.163", features = ["derive"] }
serde_json = "1.0.108"

View File

@ -1,4 +1,5 @@
use actix_http::header::{HeaderName, HeaderValue};
use actix_remote_ip::RemoteIP;
use std::collections::HashMap;
use std::str::FromStr;
@ -15,7 +16,6 @@ use crate::data::error::{Res, ResultBoxError};
use crate::data::user_token::UserAccessToken;
use crate::helpers::{account_helper, admin_access_token_helper, api_helper};
use crate::routes::RequestResult;
use crate::utils::network_utils::match_ip;
/// Http request handler
///
@ -29,11 +29,16 @@ pub struct HttpRequestHandler {
client: Option<APIClient>,
curr_user_token: Option<UserAccessToken>,
curr_admin_token: Option<AdminAccessToken>,
remote_ip: RemoteIP,
}
impl HttpRequestHandler {
/// Construct a new request handler
pub fn new(req: HttpRequest, body: HashMap<String, RequestValue>) -> HttpRequestHandler {
pub fn new(
req: HttpRequest,
body: HashMap<String, RequestValue>,
remote_ip: RemoteIP,
) -> HttpRequestHandler {
HttpRequestHandler {
request: req,
body,
@ -42,6 +47,7 @@ impl HttpRequestHandler {
client: None,
curr_user_token: None,
curr_admin_token: None,
remote_ip,
}
}
@ -184,28 +190,7 @@ impl BaseRequestHandler for HttpRequestHandler {
/// Get the remote IP address
fn remote_ip(&self) -> String {
let mut ip = self.request.peer_addr().unwrap().ip().to_string();
// We check if the request comes from a trusted reverse proxy
if let Some(proxy) = conf().proxy.as_ref() {
if match_ip(proxy, &ip) {
if let Some(header) = self.request.headers().get("X-Forwarded-For") {
let header: Vec<String> = header
.to_str()
.unwrap()
.to_string()
.split(",")
.map(|f| f.to_string())
.collect();
if header.len() > 0 {
ip = header[0].to_string();
}
}
}
}
ip
self.remote_ip.0.to_string()
}
fn user_access_token(&self) -> Option<&UserAccessToken> {

View File

@ -1,3 +1,4 @@
use actix_remote_ip::{RemoteIP, RemoteIPConfig};
use std::collections::HashMap;
use std::pin::Pin;
@ -252,7 +253,7 @@ async fn process_simple_route(route: &Route, req: &mut HttpRequestHandler) -> Re
}
/// Process an incoming request
async fn process_request(custom_req: CustomRequest) -> HttpResponse {
async fn process_request(custom_req: CustomRequest, remote_ip: RemoteIP) -> HttpResponse {
let req = &custom_req.req;
let (route, _) = find_route(&req.uri().to_string(), None).await;
@ -274,7 +275,7 @@ async fn process_request(custom_req: CustomRequest) -> HttpResponse {
requests_limit_helper::clean_cache().unwrap();
// Execute the request
let mut request = HttpRequestHandler::new(custom_req.req, custom_req.body);
let mut request = HttpRequestHandler::new(custom_req.req, custom_req.body, remote_ip);
match process_simple_route(&route, &mut request).await {
// Set default error response if required
@ -357,6 +358,8 @@ pub fn start_server(conf: &Config) -> std::io::Result<()> {
let serve_storage_file = conf.serve_storage_file;
let proxy = conf.proxy.clone();
let server = HttpServer::new(move || {
let mut app = App::new();
@ -367,8 +370,13 @@ pub fn start_server(conf: &Config) -> std::io::Result<()> {
));
}
// User WebSocket route
app.service(actix_web::web::resource("/ws").to(user_ws_controller::ws_route))
app
// Remote IP configuration
.app_data(web::Data::new(RemoteIPConfig {
proxy: proxy.clone(),
}))
// User WebSocket route
.service(actix_web::web::resource("/ws").to(user_ws_controller::ws_route))
// RTC Relay WebSocket route
.service(actix_web::web::resource("/rtc_proxy/ws").to(rtc_relay_controller::open_ws))
// Option