1 unstable release
new 0.1.0 | Nov 29, 2024 |
---|
#1691 in Network programming
109 downloads per month
10KB
109 lines
real-ip
Get the "real-ip" of an incoming request using the "forwarded", "x-forwarded-for" or "x-real-ip" headers set by reverse proxies.
See the crate documentation for more details and examples.
Example
use http::Request;
use std::net::IpAddr;
use real_ip::{real_ip, IpNet};
// in a real program this info would of course come from the http server
let incoming_ip = IpAddr::from([10, 0, 0, 1]);
let request = Request::builder().header("x-forwarded-for", "192.0.2.1").body(()).unwrap();
// the reverse-proxies in our network that we trust
let trusted_proxies = [
IpAddr::from([10, 0, 0, 1]).into(),
];
let client_ip = real_ip(request.headers(), incoming_ip, &trusted_proxies);
assert_eq!(Some(IpAddr::from([192, 0, 2, 1])), client_ip);
lib.rs
:
Get the "real-ip" of an incoming request.
This uses the "forwarded", "x-forwarded-for" or "x-real-ip" headers set by reverse proxies.
Trusted proxies
To stop clients from being able to spoof the remote ip, you are required to configure the trusted proxies which are allowed to set the forwarded headers.
Trusted proxies are configured as a list of IpNet
s, which can be a single ip or an ip range.
Note that if multiple forwarded-for addresses are present, which can be the case when using nested reverse proxies, all proxies in the chain have to be within the list of trusted proxies.
Examples
A request originating from 192.0.2.1, being proxied through 10.10.10.10 and 10.0.0.1 before reaching our program
#
// in a real program this info would of course come from the http server
let incoming_ip = IpAddr::from([10, 0, 0, 1]);
let request = Request::builder().header("x-forwarded-for", "192.0.2.1, 10.10.10.10").body(()).unwrap();
// the reverse-proxies in our network that we trust
let trusted_proxies = [
IpAddr::from([10, 0, 0, 1]).into(),
IpNet::new_assert(IpAddr::from([10, 10, 10, 0]), 24), // 10.10.10.0/24
];
let client_ip = real_ip(request.headers(), incoming_ip, &trusted_proxies);
assert_eq!(Some(IpAddr::from([192, 0, 2, 1])), client_ip);
A request originating from 192.0.2.1, being proxied through 203.0.113.10 and 10.0.0.1 before reaching our program. But 203.0.113.10 is not a trusted proxy, so we don't accept anything it added to the forwarded headers
#
let incoming_ip = IpAddr::from([10, 0, 0, 1]);
let request = Request::builder().header("forwarded", "for=192.0.2.1, for=203.0.113.10;proto=https").body(()).unwrap();
let trusted_proxies = [
IpAddr::from([10, 0, 0, 1]).into(),
IpNet::new_assert(IpAddr::from([10, 10, 10, 0]), 24),
];
let client_ip = real_ip(request.headers(), incoming_ip, &trusted_proxies);
assert_eq!(Some(IpAddr::from([203, 0, 113, 10])), client_ip);
Dependencies
~1MB
~22K SLoC