This library aims to extract ip address of http request clients by using different http-header values. Ported from python-ipware developped by @un33k
This library uses unstable rust API. ```rust ignore ![feature(ip)] ````
toml
[dependencies]
ipware = "0.1"
```rust use http::{HeaderMap, HeaderName}; use ipware::{IpWare, IpWareConfig, IpWareProxy};
let ipware = IpWare::new( IpWareConfig::new( vec![ HeaderName::fromstatic("httpxforwardedfor"), HeaderName::fromstatic("xforwardedfor"), ], true, ), IpWareProxy::default(), ); let mut headers = HeaderMap::new(); headers.insert( "HTTPXFORWARDEDFOR", "177.139.233.139, 198.84.193.157, 198.84.193.158" .parse() .unwrap(), ); headers.insert( "XFORWARDEDFOR", "177.139.233.138, 198.84.193.157, 198.84.193.158" .parse() .unwrap(), ); headers.insert("REMOTEADDR", "177.139.233.133".parse().unwrap()); let (ipaddr, trustedroute) = ipware.getclientip(&headers, false); println!("{} {}", ipaddr.unwrap(), trusted_route); ```
text
177.139.233.139 false
| Params | Description |
| --------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| proxy_count
| : Total number of expected proxies (pattern: client, proxy1, ..., proxy2
)
: if proxy_count = 0
then client
: if proxy_count = 1
then client, proxy1
: if proxy_count = 2
then client, proxy1, proxy2
: if proxy_count = 3
then client, proxy1, proxy2 proxy3
|
| proxy_list
| : List of trusted proxies (pattern: client, proxy1, ..., proxy2
)
: if proxy_list = ['10.1.']
then client, 10.1.1.1
OR client, proxy1, 10.1.1.1
: if proxy_list = ['10.1', '10.2.']
then client, 10.1.1.1
OR client, proxy1, 10.2.2.2
: if proxy_list = ['10.1', '10.2.']
then client, 10.1.1.1 10.2.2.2
OR client, 10.1.1.1 10.2.2.2
|
| leftmost
| : leftmost = True
is default for de-facto standard.
: leftmost = False
for rare legacy networks that are configured with the rightmost
pattern.
: It converts client, proxy1 proxy2
to proxy2, proxy1, client
|
| Output | Description |
| ----------------: | :------------------------------------------------------------------------------------------- |
| ip
| : Client IP address object of type IPv4Addr or IPv6Addr |
| trusted_route
| : If proxy proxy_count
and/or proxy_list
were provided and matched, true
, else false
|
The client IP address can be found in one or more request headers attributes. The lookup order is top to bottom and the default attributes are as follow.
rust
pub use http::HeaderName;
let request_headers_precedence = vec![
HeaderName::from_static("x_forwarded_for"), /* Load balancers or proxies such as AWS ELB (default client is `left-most` [`<client>, <proxy1>, <proxy2>`]), */
HeaderName::from_static("http_x_forwarded_for"), // Similar to X_FORWARDED_TO
HeaderName::from_static("http_client_ip"), /* Standard headers used by providers such as Amazon EC2, Heroku etc. */
HeaderName::from_static("http_x_real_ip"), /* Standard headers used by providers such as Amazon EC2, Heroku etc. */
HeaderName::from_static("http_x_forwarded"), // Squid and others
HeaderName::from_static("http_x_cluster_client_ip"), /* Rackspace LB and Riverbed Stingray */
HeaderName::from_static("http_forwarded_for"), // RFC 7239
HeaderName::from_static("http_forwarded"), // RFC 7239
HeaderName::from_static("http_via"), // Squid and others
HeaderName::from_static("x-real-ip"), // NGINX
HeaderName::from_static("x-cluster-client-ip"), // Rackspace Cloud Load Balancers
HeaderName::from_static("x_forwarded"), // Squid
HeaderName::from_static("forwarded_for"), // RFC 7239
HeaderName::from_static("cf-connecting-ip"), // CloudFlare
HeaderName::from_static("true-client-ip"), // CloudFlare Enterprise,
HeaderName::from_static("fastly-client-ip"), // Firebase, Fastly
HeaderName::from_static("forwarded"), // RFC 7239
HeaderName::from_static("client-ip"), /* Akamai and Cloudflare: True-Client-IP and Fastly: Fastly-Client-IP */
HeaderName::from_static("remote_addr"), // Default
];
You can customize the order by providing your own list using IpWareConfig. ```rust norun use ipware::IpWareConfig; use http::HeaderName; // specific header name IpWareConfig::new(vec![HeaderName::fromstatic("httpxforwarded_for")],true);
// multiple header names IpWareConfig::new( vec![ HeaderName::fromstatic("httpxforwardedfor"), HeaderName::fromstatic("xforwarded_for"), ], true, ); ```
If your http server is behind one or more known proxy server(s), you can filter out unwanted requests
by providing a trusted proxy list
, or a known proxy count
.
You can customize the proxy IP prefixes by providing your own list by using IpWareProxy. You can pass your custom list on every call, when calling the proxy-aware api to fetch the ip.
```rust no_run // In the above scenario, use your load balancer IP address as a way to filter out unwanted requests. use std::net::IpAddr; use ipware::IpWare; use ipware::IpWareConfig; use ipware::IpWareProxy; use http::HeaderMap;
let headers = HeaderMap::new(); // replace this with your own headers
let proxies = vec![
"198.84.193.157".parse::
// usage: non-strict mode (X-Forwarded-For:
// usage: strict mode (X-Forwarded-For:
If your http server is behind a known
number of proxies, but you deploy on multiple providers and don't want to track proxy IPs, you still can filter out unwanted requests by providing proxy count
.
You can customize the proxy count by providing your proxy_count
using IpWareProxy.
```rust no_run
use ipware::*;
use std::net::IpAddr;
// In the above scenario, the total number of proxies can be used as a way to filter out unwanted requests. // enforce proxy count
let headers = HeaderMap::new(); // replace this with your own headers let proxies = vec![]; let ipware = IpWare::new(IpWareConfig::default(), IpWareProxy::new(1, &proxies));
// enforce proxy count and trusted proxies
let proxies = vec standard
for the originating client IP address is the `leftmost`as per`client, proxy1, proxy2`, and the `rightmost` proxy is the most
trusted proxy.
However, in rare cases your network has a `custom` configuration where the `rightmost` IP address is that of the originating client. If that is the case, then indicate it when creating:
rust no_run
use ipware::*;
let ipware = IpWare::new(
IpWareConfig::default().leftmost(false),
IpWareProxy::default(),
);
Licensed under MIT License (LICENSE).
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this project by you, as defined in the MIT license, shall be licensed as above, without any additional terms or conditions.