ip whitelist
This commit is contained in:
+91
-7
@@ -1,5 +1,5 @@
|
||||
use crate::{
|
||||
auth::{client_ip::ClientIpPolicy, AuthorizationService},
|
||||
auth::{client_ip::ClientIpPolicy, ip_whitelist, AuthorizationService},
|
||||
config::Config,
|
||||
logs::{follower::LiveMessage, index::HistoryStore},
|
||||
};
|
||||
@@ -142,17 +142,101 @@ async fn authorize(
|
||||
peer: SocketAddr,
|
||||
headers: &HeaderMap,
|
||||
) -> Result<IpAddr, Response> {
|
||||
validate_origin(&state.config.public_origin, headers)
|
||||
.map_err(|_| error(StatusCode::FORBIDDEN, "origin_denied"))?;
|
||||
validate_origin(&state.config.public_origin, headers).map_err(|_| {
|
||||
tracing::debug!(
|
||||
event = "authorization_decision",
|
||||
result = "denied",
|
||||
reason = "origin_denied",
|
||||
peer_ip = %peer.ip()
|
||||
);
|
||||
error(StatusCode::FORBIDDEN, "origin_denied")
|
||||
})?;
|
||||
let ip = state
|
||||
.ip_policy
|
||||
.extract(peer.ip(), headers)
|
||||
.map_err(|_| error(StatusCode::BAD_REQUEST, "invalid_client_ip"))?;
|
||||
.map_err(|extract_error| {
|
||||
tracing::debug!(
|
||||
event = "authorization_decision",
|
||||
result = "denied",
|
||||
reason = "invalid_client_ip",
|
||||
peer_ip = %peer.ip(),
|
||||
error = %extract_error
|
||||
);
|
||||
error(StatusCode::BAD_REQUEST, "invalid_client_ip")
|
||||
})?;
|
||||
if state.auth.is_allowed(ip).await {
|
||||
Ok(ip)
|
||||
} else {
|
||||
Err(error(StatusCode::FORBIDDEN, "access_denied"))
|
||||
let allowed_player_ips = state.auth.allowed_ips().await;
|
||||
tracing::debug!(
|
||||
event = "authorization_decision",
|
||||
result = "allowed",
|
||||
source = "player_join",
|
||||
client_ip = %ip,
|
||||
peer_ip = %peer.ip(),
|
||||
?allowed_player_ips
|
||||
);
|
||||
return Ok(ip);
|
||||
}
|
||||
let allowed_player_ips = state.auth.allowed_ips().await;
|
||||
if let Some(path) = state.config.ip_whitelist_file.clone() {
|
||||
let log_path = path.clone();
|
||||
let result = tokio::task::spawn_blocking(move || ip_whitelist::check(&path, ip)).await;
|
||||
match result {
|
||||
Ok(Ok(check)) if check.matched => {
|
||||
tracing::debug!(
|
||||
event = "authorization_decision",
|
||||
result = "allowed",
|
||||
source = "ip_whitelist_file",
|
||||
client_ip = %ip,
|
||||
peer_ip = %peer.ip(),
|
||||
path = %log_path.display(),
|
||||
allowed_override_networks = ?check.entries,
|
||||
?allowed_player_ips
|
||||
);
|
||||
return Ok(ip);
|
||||
}
|
||||
Ok(Ok(check)) => tracing::debug!(
|
||||
event = "ip_whitelist_checked",
|
||||
result = "no_match",
|
||||
client_ip = %ip,
|
||||
path = %log_path.display(),
|
||||
allowed_override_networks = ?check.entries,
|
||||
?allowed_player_ips
|
||||
),
|
||||
Ok(Err(error)) => tracing::warn!(
|
||||
event = "ip_whitelist_read_failed",
|
||||
client_ip = %ip,
|
||||
path = %log_path.display(),
|
||||
?allowed_player_ips,
|
||||
%error
|
||||
),
|
||||
Err(error) => tracing::warn!(
|
||||
event = "ip_whitelist_check_failed",
|
||||
client_ip = %ip,
|
||||
path = %log_path.display(),
|
||||
?allowed_player_ips,
|
||||
%error
|
||||
),
|
||||
}
|
||||
} else {
|
||||
tracing::debug!(
|
||||
event = "ip_whitelist_disabled",
|
||||
client_ip = %ip,
|
||||
?allowed_player_ips
|
||||
);
|
||||
}
|
||||
tracing::debug!(
|
||||
event = "authorization_decision",
|
||||
result = "denied",
|
||||
reason = "no_authorization_match",
|
||||
client_ip = %ip,
|
||||
peer_ip = %peer.ip(),
|
||||
?allowed_player_ips
|
||||
);
|
||||
Err((
|
||||
StatusCode::FORBIDDEN,
|
||||
Json(serde_json::json!({"error":"access_denied", "client_ip":ip})),
|
||||
)
|
||||
.into_response())
|
||||
}
|
||||
fn validate_origin(expected: &str, headers: &HeaderMap) -> Result<(), ()> {
|
||||
if let Some(origin) = headers.get(header::ORIGIN) {
|
||||
|
||||
Reference in New Issue
Block a user