Content-Length: 825920 | pFad | https://github.com/sebadob/rauthy/commit/a56c05e560c4b89f88f34240cb79a29e1e8a746c

F8 Merge pull request #302 from sebadob/feat-cust-ip-header-name · sebadob/rauthy@a56c05e · GitHub
Skip to content

Commit

Permalink
Merge pull request #302 from sebadob/feat-cust-ip-header-name
Browse files Browse the repository at this point in the history
feat: extract peer IP from custom header name
  • Loading branch information
sebadob authored Apr 7, 2024
2 parents 3a04dc0 + d92311f commit a56c05e
Show file tree
Hide file tree
Showing 21 changed files with 102 additions and 53 deletions.
9 changes: 9 additions & 0 deletions docs/config/config.html
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,15 @@ <h1 id="reference-config"><a class="header" href="#reference-config">Reference C
# default: false
#UNSAFE_NO_RESET_BINDING=false

# Can be set to extract the remote client peer IP from a custom header name
# instead of the default mechanisms. This is needed when you are running
# behind a proxy which does not set the `X-REAL-IP` or `X-FORWARDED-FOR` headers
# correctly, or for instance when you proxy your requests through a CDN like
# Cloudflare, which adds custom headers in this case.
# For instance, if your requests are proxied through cloudflare, your would
# set `CF-Connecting-IP`.
PEER_IP_HEADER_NAME="CF-Connecting-IP"

#####################################
############# BACKUPS ###############
#####################################
Expand Down
9 changes: 9 additions & 0 deletions docs/print.html
Original file line number Diff line number Diff line change
Expand Up @@ -1301,6 +1301,15 @@ <h4 id="config-adjustments---rest-api"><a class="header" href="#config-adjustmen
# default: false
#UNSAFE_NO_RESET_BINDING=false

# Can be set to extract the remote client peer IP from a custom header name
# instead of the default mechanisms. This is needed when you are running
# behind a proxy which does not set the `X-REAL-IP` or `X-FORWARDED-FOR` headers
# correctly, or for instance when you proxy your requests through a CDN like
# Cloudflare, which adds custom headers in this case.
# For instance, if your requests are proxied through cloudflare, your would
# set `CF-Connecting-IP`.
PEER_IP_HEADER_NAME="CF-Connecting-IP"

#####################################
############# BACKUPS ###############
#####################################
Expand Down
2 changes: 1 addition & 1 deletion docs/searchindex.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/searchindex.json

Large diffs are not rendered by default.

9 changes: 9 additions & 0 deletions rauthy-book/src/config/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,15 @@ extract these values, create Kubernetes Secrets and provide them as environment
# default: false
#UNSAFE_NO_RESET_BINDING=false
# Can be set to extract the remote client peer IP from a custom header name
# instead of the default mechanisms. This is needed when you are running
# behind a proxy which does not set the `X-REAL-IP` or `X-FORWARDED-FOR` headers
# correctly, or for instance when you proxy your requests through a CDN like
# Cloudflare, which adds custom headers in this case.
# For instance, if your requests are proxied through cloudflare, your would
# set `CF-Connecting-IP`.
PEER_IP_HEADER_NAME="CF-Connecting-IP"
#####################################
############# BACKUPS ###############
#####################################
Expand Down
2 changes: 2 additions & 0 deletions rauthy-common/src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,8 @@ lazy_static! {
}
};

pub static ref PEER_IP_HEADER_NAME: Option<String> = env::var("PEER_IP_HEADER_NAME").ok();

pub static ref POW_IT: u64 = env::var("POW_IT")
.unwrap_or_else(|_| String::from("1000000"))
.parse::<u64>()
Expand Down
46 changes: 46 additions & 0 deletions rauthy-common/src/utils.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
use crate::constants::{PEER_IP_HEADER_NAME, PROXY_MODE};
use crate::error_response::{ErrorResponse, ErrorResponseType};
use actix_web::dev::ServiceRequest;
use actix_web::http::header::HeaderMap;
use actix_web::HttpRequest;
use base64::{engine, engine::general_purpose, Engine as _};
use gethostname::gethostname;
Expand Down Expand Up @@ -157,6 +160,49 @@ where
Ok(claims)
}

// TODO unify real_ip_from_req and real_ip_from_svc_req by using an impl Trait
#[inline(always)]
pub fn real_ip_from_req(req: &HttpRequest) -> Option<String> {
if let Some(ip) = ip_from_cust_header(req.headers()) {
Some(ip)
} else if *PROXY_MODE {
req.connection_info()
.realip_remote_addr()
.map(|ip| ip.to_string())
} else {
req.connection_info().peer_addr().map(|ip| ip.to_string())
}
}

#[inline(always)]
pub fn real_ip_from_svc_req(req: &ServiceRequest) -> Option<String> {
if let Some(ip) = ip_from_cust_header(req.headers()) {
Some(ip)
} else if *PROXY_MODE {
req.connection_info()
.realip_remote_addr()
.map(|ip| ip.to_string())
} else {
req.connection_info().peer_addr().map(|ip| ip.to_string())
}
}

#[inline(always)]
fn ip_from_cust_header(headers: &HeaderMap) -> Option<String> {
// If a custom override has been set, try this first and use the default as fallback
if let Some(header_name) = &*PEER_IP_HEADER_NAME {
if let Some(Ok(value)) = headers.get(header_name).map(|s| s.to_str()) {
return Some(value.to_string());
}
error!(
"Was unable to extract the PEER IP from PEER_IP_HEADER_NAME: {} - using fallback",
header_name
);
}

None
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
2 changes: 1 addition & 1 deletion rauthy-handlers/src/clients.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ use actix_web::http::header::{ACCESS_CONTROL_ALLOW_ORIGIN, WWW_AUTHENTICATE};
use actix_web::{delete, get, post, put, web, HttpRequest, HttpResponse};
use rauthy_common::constants::{DYN_CLIENT_REG_TOKEN, ENABLE_DYN_CLIENT_REG};
use rauthy_common::error_response::ErrorResponse;
use rauthy_common::utils::real_ip_from_req;
use rauthy_models::app_state::AppState;
use rauthy_models::entity::api_keys::{AccessGroup, AccessRights};
use rauthy_models::entity::clients::Client;
use rauthy_models::entity::clients_dyn::ClientDyn;
use rauthy_models::entity::colors::ColorEntity;
use rauthy_models::real_ip_from_req;
use rauthy_models::request::{
ColorsRequest, DynamicClientRequest, NewClientRequest, UpdateClientRequest,
};
Expand Down
3 changes: 2 additions & 1 deletion rauthy-handlers/src/events.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
use crate::{real_ip_from_req, ReqPrincipal};
use crate::ReqPrincipal;
use actix_web::{get, post, web, HttpRequest, HttpResponse, Responder};
use actix_web_lab::sse;
use actix_web_validator::Json;
use chrono::Utc;
use rauthy_common::constants::SSE_KEEP_ALIVE;
use rauthy_common::error_response::{ErrorResponse, ErrorResponseType};
use rauthy_common::utils::real_ip_from_req;
use rauthy_models::app_state::AppState;
use rauthy_models::entity::api_keys::{AccessGroup, AccessRights};
use rauthy_models::events::event::Event;
Expand Down
3 changes: 2 additions & 1 deletion rauthy-handlers/src/generic.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{real_ip_from_req, Assets, ReqPrincipal};
use crate::{Assets, ReqPrincipal};
use actix_web::http::header::{HeaderValue, CONTENT_TYPE};
use actix_web::http::{header, StatusCode};
use actix_web::web::Json;
Expand All @@ -8,6 +8,7 @@ use rauthy_common::constants::{
APPLICATION_JSON, CACHE_NAME_LOGIN_DELAY, HEADER_HTML, IDX_LOGIN_TIME, RAUTHY_VERSION,
};
use rauthy_common::error_response::ErrorResponse;
use rauthy_common::utils::real_ip_from_req;
use rauthy_models::app_state::AppState;
use rauthy_models::entity::api_keys::{AccessGroup, AccessRights};
use rauthy_models::entity::app_version::LatestAppVersion;
Expand Down
25 changes: 1 addition & 24 deletions rauthy-handlers/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@

#![forbid(unsafe_code)]

use actix_web::dev::ServiceRequest;
use actix_web::{web, HttpRequest, HttpResponse};
use rauthy_common::constants::{COOKIE_MFA, PROXY_MODE};
use rauthy_common::constants::COOKIE_MFA;
use rauthy_common::error_response::ErrorResponse;
use rauthy_models::entity::api_keys::ApiKey;
use rauthy_models::entity::principal::Principal;
Expand Down Expand Up @@ -95,25 +94,3 @@ fn add_req_mfa_cookie(resp: &mut HttpResponse, email: String) -> Result<(), Erro

Ok(())
}

pub fn real_ip_from_req(req: &HttpRequest) -> Option<String> {
if *PROXY_MODE {
// TODO maybe make this configurable and extract headers in user-configured order?
req.connection_info()
.realip_remote_addr()
.map(|ip| ip.to_string())
} else {
req.connection_info().peer_addr().map(|ip| ip.to_string())
}
}

pub fn real_ip_from_svc_req(req: &ServiceRequest) -> Option<String> {
if *PROXY_MODE {
// TODO maybe make this configurable and extract headers in user-configured order?
req.connection_info()
.realip_remote_addr()
.map(|ip| ip.to_string())
} else {
req.connection_info().peer_addr().map(|ip| ip.to_string())
}
}
2 changes: 1 addition & 1 deletion rauthy-handlers/src/middleware/ip_blacklist.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
use crate::real_ip_from_svc_req;
use actix_web::{
dev::{forward_ready, Service, ServiceRequest, ServiceResponse, Transform},
web, Error,
};
use chrono::Utc;
use futures::future::LocalBoxFuture;
use rauthy_common::error_response::{ErrorResponse, ErrorResponseType};
use rauthy_common::utils::real_ip_from_svc_req;
use rauthy_models::app_state::AppState;
use rauthy_models::events::ip_blacklist_handler::{IpBlacklistCheck, IpBlacklistReq};
use rauthy_models::templates::TooManyRequestsHtml;
Expand Down
2 changes: 1 addition & 1 deletion rauthy-handlers/src/middleware/logging.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use crate::real_ip_from_svc_req;
use actix_web::http::header::HeaderValue;
use actix_web::http::{Method, Uri};
use actix_web::{
Expand All @@ -8,6 +7,7 @@ use actix_web::{
use futures::future::LocalBoxFuture;
use lazy_static::lazy_static;
use rauthy_common::error_response::{ErrorResponse, ErrorResponseType};
use rauthy_common::utils::real_ip_from_svc_req;
use std::env;
use std::future::{ready, Ready};
use std::rc::Rc;
Expand Down
2 changes: 1 addition & 1 deletion rauthy-handlers/src/middleware/principal.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
use crate::real_ip_from_svc_req;
use actix_web::{
dev::{forward_ready, Service, ServiceRequest, ServiceResponse, Transform},
http, web, Error, HttpMessage,
};
use futures::future::LocalBoxFuture;
use rauthy_common::constants::{COOKIE_SESSION, SESSION_VALIDATE_IP, TOKEN_API_KEY};
use rauthy_common::error_response::{ErrorResponse, ErrorResponseType};
use rauthy_common::utils::real_ip_from_svc_req;
use rauthy_models::app_state::AppState;
use rauthy_models::entity::api_keys::{ApiKey, ApiKeyEntity};
use rauthy_models::entity::principal::Principal;
Expand Down
3 changes: 2 additions & 1 deletion rauthy-handlers/src/oidc.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
use crate::{map_auth_step, real_ip_from_req, ReqPrincipal};
use crate::{map_auth_step, ReqPrincipal};
use actix_web::cookie::time::OffsetDateTime;
use actix_web::http::header::{HeaderValue, CONTENT_TYPE};
use actix_web::http::{header, StatusCode};
use actix_web::{get, post, web, HttpRequest, HttpResponse, HttpResponseBuilder, ResponseError};
use chrono::Utc;
use rauthy_common::constants::{APPLICATION_JSON, COOKIE_MFA, HEADER_HTML, SESSION_LIFETIME};
use rauthy_common::error_response::ErrorResponse;
use rauthy_common::utils::real_ip_from_req;
use rauthy_models::app_state::AppState;
use rauthy_models::entity::api_keys::{AccessGroup, AccessRights};
use rauthy_models::entity::auth_provider::AuthProviderTemplate;
Expand Down
3 changes: 2 additions & 1 deletion rauthy-handlers/src/users.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{real_ip_from_req, ReqPrincipal};
use crate::ReqPrincipal;
use actix_web::http::StatusCode;
use actix_web::{cookie, delete, get, post, put, web, HttpRequest, HttpResponse, ResponseError};
use actix_web_validator::Json;
Expand All @@ -7,6 +7,7 @@ use rauthy_common::constants::{
USER_REG_DOMAIN_RESTRICTION,
};
use rauthy_common::error_response::{ErrorResponse, ErrorResponseType};
use rauthy_common::utils::real_ip_from_req;
use rauthy_models::app_state::AppState;
use rauthy_models::entity::api_keys::{AccessGroup, AccessRights};
use rauthy_models::entity::colors::ColorEntity;
Expand Down
3 changes: 1 addition & 2 deletions rauthy-models/src/entity/magic_links.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
use crate::app_state::AppState;
use crate::real_ip_from_req;
use actix_web::{web, HttpRequest};
use rauthy_common::constants::{PWD_CSRF_HEADER, PWD_RESET_COOKIE, UNSAFE_NO_RESET_BINDING};
use rauthy_common::error_response::{ErrorResponse, ErrorResponseType};
use rauthy_common::utils::get_rand;
use rauthy_common::utils::{get_rand, real_ip_from_req};
use serde::{Deserialize, Serialize};
use sqlx::FromRow;
use time::OffsetDateTime;
Expand Down
3 changes: 1 addition & 2 deletions rauthy-models/src/entity/users.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ use crate::entity::users_values::UserValues;
use crate::entity::webauthn::{PasskeyEntity, WebauthnServiceReq};
use crate::events::event::Event;
use crate::language::Language;
use crate::real_ip_from_req;
use crate::request::{
NewUserRegistrationRequest, NewUserRequest, UpdateUserRequest, UpdateUserSelfRequest,
};
Expand All @@ -24,7 +23,7 @@ use rauthy_common::constants::{
};
use rauthy_common::error_response::{ErrorResponse, ErrorResponseType};
use rauthy_common::password_hasher::{ComparePasswords, HashPassword};
use rauthy_common::utils::{get_client_ip, new_store_id};
use rauthy_common::utils::{get_client_ip, new_store_id, real_ip_from_req};
use redhac::{
cache_del, cache_get, cache_get_from, cache_get_value, cache_insert, cache_remove, AckLevel,
};
Expand Down
13 changes: 0 additions & 13 deletions rauthy-models/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ use crate::entity::sessions::Session;
use crate::entity::users::User;
use crate::entity::users_values::UserValues;
use actix_web::http::header::{HeaderName, HeaderValue};
use actix_web::HttpRequest;
use rauthy_common::constants::PROXY_MODE;
use rauthy_common::error_response::{ErrorResponse, ErrorResponseType};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
Expand Down Expand Up @@ -263,14 +261,3 @@ impl ToString for JwtAmrValue {
s.to_string()
}
}

pub fn real_ip_from_req(req: &HttpRequest) -> Option<String> {
if *PROXY_MODE {
// TODO maybe make this configurable and extract headers in user-configured order?
req.connection_info()
.realip_remote_addr()
.map(|ip| ip.to_string())
} else {
req.connection_info().peer_addr().map(|ip| ip.to_string())
}
}
3 changes: 1 addition & 2 deletions rauthy-service/src/password_reset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use actix_web::cookie::SameSite;
use actix_web::{cookie, web, HttpRequest, HttpResponse};
use rauthy_common::constants::{PWD_CSRF_HEADER, PWD_RESET_COOKIE};
use rauthy_common::error_response::{ErrorResponse, ErrorResponseType};
use rauthy_common::utils::get_rand;
use rauthy_common::utils::{get_rand, real_ip_from_req};
use rauthy_models::app_state::AppState;
use rauthy_models::entity::colors::ColorEntity;
use rauthy_models::entity::magic_links::{MagicLink, MagicLinkUsage};
Expand All @@ -13,7 +13,6 @@ use rauthy_models::entity::webauthn;
use rauthy_models::entity::webauthn::WebauthnServiceReq;
use rauthy_models::events::event::Event;
use rauthy_models::language::Language;
use rauthy_models::real_ip_from_req;
use rauthy_models::request::{
PasswordResetRequest, WebauthnRegFinishRequest, WebauthnRegStartRequest,
};
Expand Down
9 changes: 9 additions & 0 deletions rauthy.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,15 @@ OPEN_USER_REG=true
# default: false
#UNSAFE_NO_RESET_BINDING=true

# Can be set to extract the remote client peer IP from a custom header name
# instead of the default mechanisms. This is needed when you are running
# behind a proxy which does not set the `X-REAL-IP` or `X-FORWARDED-FOR` headers
# correctly, or for instance when you proxy your requests through a CDN like
# Cloudflare, which adds custom headers in this case.
# For instance, if your requests are proxied through cloudflare, your would
# set `CF-Connecting-IP`.
#PEER_IP_HEADER_NAME="CF-Connecting-IP"

#####################################
############# BACKUPS ###############
#####################################
Expand Down

0 comments on commit a56c05e

Please sign in to comment.








ApplySandwichStrip

pFad - (p)hone/(F)rame/(a)nonymizer/(d)eclutterfier!      Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

Fetched URL: https://github.com/sebadob/rauthy/commit/a56c05e560c4b89f88f34240cb79a29e1e8a746c

Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy