Expand description
This library aims to extract ip address of http request clients by using different http-header values. Ported from python-ipware developped by @un33k
§⚠️ Warning
This library uses unstable rust API.
![feature(ip)]
§📦 Cargo.toml
[dependencies]
ipware = "0.1"
§🔧 Example
use http::{HeaderMap, HeaderName};
use ipware::{IpWare, IpWareConfig, IpWareProxy};
let ipware = IpWare::new(
IpWareConfig::new(
vec![
HeaderName::from_static("http_x_forwarded_for"),
HeaderName::from_static("x_forwarded_for"),
],
true,
),
IpWareProxy::default(),
);
let mut headers = HeaderMap::new();
headers.insert(
"HTTP_X_FORWARDED_FOR",
"177.139.233.139, 198.84.193.157, 198.84.193.158"
.parse()
.unwrap(),
);
headers.insert(
"X_FORWARDED_FOR",
"177.139.233.138, 198.84.193.157, 198.84.193.158"
.parse()
.unwrap(),
);
headers.insert("REMOTE_ADDR", "177.139.233.133".parse().unwrap());
let (ip_addr, trusted_route) = ipware.get_client_ip(&headers, false);
println!("{} {}", ip_addr.unwrap(), trusted_route);
§🖨️ Output
177.139.233.139 false
§⚙️ Configuration
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 |
§🔢 Http Header Precedence Order
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.
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.
use ipware::IpWareConfig;
use http::HeaderName;
// specific header name
IpWareConfig::new(vec![HeaderName::from_static("http_x_forwarded_for")],true);
// multiple header names
IpWareConfig::new(
vec![
HeaderName::from_static("http_x_forwarded_for"),
HeaderName::from_static("x_forwarded_for"),
],
true,
);
§🤝 Trusted Proxies
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.
// 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::<IpAddr>().unwrap(),
"198.84.193.158".parse::<IpAddr>().unwrap(),
];
let ipware = IpWare::new(IpWareConfig::default(), IpWareProxy::new(0, &proxies));
// usage: non-strict mode (X-Forwarded-For: <fake>, <client>, <proxy1>, <proxy2>)
// The request went through our <proxy1> and <proxy2>, then our server
// We choose the <client> ip address to the left our <proxy1> and ignore other ips
let (ip, trusted_route) = ipware.get_client_ip(&headers, false);
// usage: strict mode (X-Forwarded-For: <client>, <proxy1>, <proxy2>)
// The request went through our <proxy1> and <proxy2>, then our server
// Total ip address are total trusted proxies + client ip
// We don't allow far-end proxies, or fake addresses (exact or None)
let (ip, trusted_route) = ipware.get_client_ip(&headers, true);
§Proxy Count
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.
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!["198.84.193.157".parse::<IpAddr>().unwrap()];
let ipware = IpWare::new(IpWareConfig::default(), IpWareProxy::new(1, &proxies));
// usage: non-strict mode (X-Forwarded-For: <fake>, <client>, <proxy1>, <proxy2>)
// total number of ip addresses are greater than the total count
let (ip, trusted_route) = ipware.get_client_ip(&headers, false);
// usage: strict mode (X-Forwarded-For: <client>, <proxy1>, <proxy2>)
// total number of ip addresses are exactly equal to client ip + proxy_count
let (ip, trusted_route) = ipware.get_client_ip(&headers, true);
§Support for IPv4, Ipv6, and IP:Port patterns and encapsulation
- Library looks for an IpAddr in header values. If this fails algorithm tries to parse a SocketAddr (This on contains ports in addition to IpAddr)
- get_client_ip call returns an IpAddr enum. User can match for V4 or V6 variants. If a V6 ip is retrieved user can utilize `to_ipv4_mapped` to
retrieve wrapped V4 address if available.
§Originating Request
Please note that the [de-facto](https:#developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For) 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:
use ipware::*;
let ipware = IpWare::new(
IpWareConfig::default().leftmost(false),
IpWareProxy::default(),
);
Structs§
- Drain
- A drain iterator for
HeaderMap
. - GetAll
- A view to all values stored in a single entry.
- Header
Map - A set of HTTP headers
- Header
Name - Represents an HTTP header field name
- Header
Value - Represents an HTTP header field value.
- Into
Iter - An owning iterator over the entries of a
HeaderMap
. - Invalid
Header Name - A possible error when converting a
HeaderName
from another type. - Invalid
Header Value - A possible error when converting a
HeaderValue
from a string or byte slice. - IpWare
- IpWare
Config - IpWare
Proxy - Iter
HeaderMap
entry iterator.- IterMut
HeaderMap
mutable entry iterator- Keys
- An iterator over
HeaderMap
keys. - MaxSize
Reached - Error returned when max capacity of
HeaderMap
is exceeded - Occupied
Entry - A view into a single occupied location in a
HeaderMap
. - ToStr
Error - A possible error when converting a
HeaderValue
to a string representation. - Vacant
Entry - A view into a single empty location in a
HeaderMap
. - Value
Drain - An drain iterator of all values associated with a single header name.
- Value
Iter - An iterator of all values associated with a single header name.
- Value
Iter Mut - A mutable iterator of all values associated with a single header name.
- Values
HeaderMap
value iterator.- Values
Mut HeaderMap
mutable value iterator
Enums§
- Entry
- A view into a single location in a
HeaderMap
, which may be vacant or occupied.
Constants§
- ACCEPT
- Advertises which content types the client is able to understand.
- ACCEPT_
CHARSET - Advertises which character set the client is able to understand.
- ACCEPT_
ENCODING - Advertises which content encoding the client is able to understand.
- ACCEPT_
LANGUAGE - Advertises which languages the client is able to understand.
- ACCEPT_
RANGES - Marker used by the server to advertise partial request support.
- ACCESS_
CONTROL_ ALLOW_ CREDENTIALS - Preflight response indicating if the response to the request can be exposed to the page.
- ACCESS_
CONTROL_ ALLOW_ HEADERS - Preflight response indicating permitted HTTP headers.
- ACCESS_
CONTROL_ ALLOW_ METHODS - Preflight header response indicating permitted access methods.
- ACCESS_
CONTROL_ ALLOW_ ORIGIN - Indicates whether the response can be shared with resources with the given origin.
- ACCESS_
CONTROL_ EXPOSE_ HEADERS - Indicates which headers can be exposed as part of the response by listing their names.
- ACCESS_
CONTROL_ MAX_ AGE - Indicates how long the results of a preflight request can be cached.
- ACCESS_
CONTROL_ REQUEST_ HEADERS - Informs the server which HTTP headers will be used when an actual request is made.
- ACCESS_
CONTROL_ REQUEST_ METHOD - Informs the server know which HTTP method will be used when the actual request is made.
- AGE
- Indicates the time in seconds the object has been in a proxy cache.
- ALLOW
- Lists the set of methods support by a resource.
- ALT_SVC
- Advertises the availability of alternate services to clients.
- AUTHORIZATION
- Contains the credentials to authenticate a user agent with a server.
- CACHE_
CONTROL - Specifies directives for caching mechanisms in both requests and responses.
- CACHE_
STATUS - Indicates how caches have handled a response and its corresponding request.
- CDN_
CACHE_ CONTROL - Specifies directives that allow origin servers to control the behavior of CDN caches interposed between them and clients separately from other caches that might handle the response.
- CONNECTION
- Controls whether or not the network connection stays open after the current transaction finishes.
- CONTENT_
DISPOSITION - Indicates if the content is expected to be displayed inline.
- CONTENT_
ENCODING - Used to compress the media-type.
- CONTENT_
LANGUAGE - Used to describe the languages intended for the audience.
- CONTENT_
LENGTH - Indicates the size of the entity-body.
- CONTENT_
LOCATION - Indicates an alternate location for the returned data.
- CONTENT_
RANGE - Indicates where in a full body message a partial message belongs.
- CONTENT_
SECURITY_ POLICY - Allows controlling resources the user agent is allowed to load for a given page.
- CONTENT_
SECURITY_ POLICY_ REPORT_ ONLY - Allows experimenting with policies by monitoring their effects.
- CONTENT_
TYPE - Used to indicate the media type of the resource.
- COOKIE
- Contains stored HTTP cookies previously sent by the server with the Set-Cookie header.
- DATE
- Contains the date and time at which the message was originated.
- DNT
- Indicates the client’s tracking preference.
- ETAG
- Identifier for a specific version of a resource.
- EXPECT
- Indicates expectations that need to be fulfilled by the server in order to properly handle the request.
- EXPIRES
- Contains the date/time after which the response is considered stale.
- FORWARDED
- Contains information from the client-facing side of proxy servers that is altered or lost when a proxy is involved in the path of the request.
- FROM
- Contains an Internet email address for a human user who controls the requesting user agent.
- HOST
- Specifies the domain name of the server and (optionally) the TCP port number on which the server is listening.
- IF_
MATCH - Makes a request conditional based on the E-Tag.
- IF_
MODIFIED_ SINCE - Makes a request conditional based on the modification date.
- IF_
NONE_ MATCH - Makes a request conditional based on the E-Tag.
- IF_
RANGE - Makes a request conditional based on range.
- IF_
UNMODIFIED_ SINCE - Makes the request conditional based on the last modification date.
- LAST_
MODIFIED - Content-Types that are acceptable for the response.
- LINK
- Allows the server to point an interested client to another resource containing metadata about the requested resource.
- LOCATION
- Indicates the URL to redirect a page to.
- MAX_
FORWARDS - Indicates the max number of intermediaries the request should be sent through.
- ORIGIN
- Indicates where a fetch originates from.
- PRAGMA
- HTTP/1.0 header usually used for backwards compatibility.
- PROXY_
AUTHENTICATE - Defines the authentication method that should be used to gain access to a proxy.
- PROXY_
AUTHORIZATION - Contains the credentials to authenticate a user agent to a proxy server.
- PUBLIC_
KEY_ PINS - Associates a specific cryptographic public key with a certain server.
- PUBLIC_
KEY_ PINS_ REPORT_ ONLY - Sends reports of pinning violation to the report-uri specified in the header.
- RANGE
- Indicates the part of a document that the server should return.
- REFERER
- Contains the address of the previous web page from which a link to the currently requested page was followed.
- REFERRER_
POLICY - Governs which referrer information should be included with requests made.
- REFRESH
- Informs the web browser that the current page or frame should be refreshed.
- RETRY_
AFTER - The Retry-After response HTTP header indicates how long the user agent should wait before making a follow-up request. There are two main cases this header is used:
- SEC_
WEBSOCKET_ ACCEPT - The |Sec-WebSocket-Accept| header field is used in the WebSocket opening handshake. It is sent from the server to the client to confirm that the server is willing to initiate the WebSocket connection.
- SEC_
WEBSOCKET_ EXTENSIONS - The |Sec-WebSocket-Extensions| header field is used in the WebSocket opening handshake. It is initially sent from the client to the server, and then subsequently sent from the server to the client, to agree on a set of protocol-level extensions to use for the duration of the connection.
- SEC_
WEBSOCKET_ KEY - The |Sec-WebSocket-Key| header field is used in the WebSocket opening handshake. It is sent from the client to the server to provide part of the information used by the server to prove that it received a valid WebSocket opening handshake. This helps ensure that the server does not accept connections from non-WebSocket clients (e.g., HTTP clients) that are being abused to send data to unsuspecting WebSocket servers.
- SEC_
WEBSOCKET_ PROTOCOL - The |Sec-WebSocket-Protocol| header field is used in the WebSocket opening handshake. It is sent from the client to the server and back from the server to the client to confirm the subprotocol of the connection. This enables scripts to both select a subprotocol and be sure that the server agreed to serve that subprotocol.
- SEC_
WEBSOCKET_ VERSION - The |Sec-WebSocket-Version| header field is used in the WebSocket opening handshake. It is sent from the client to the server to indicate the protocol version of the connection. This enables servers to correctly interpret the opening handshake and subsequent data being sent from the data, and close the connection if the server cannot interpret that data in a safe manner.
- SERVER
- Contains information about the software used by the origin server to handle the request.
- SET_
COOKIE - Used to send cookies from the server to the user agent.
- STRICT_
TRANSPORT_ SECURITY - Tells the client to communicate with HTTPS instead of using HTTP.
- TE
- Informs the server of transfer encodings willing to be accepted as part of the response.
- TRAILER
- Allows the sender to include additional fields at the end of chunked messages.
- TRANSFER_
ENCODING - Specifies the form of encoding used to safely transfer the entity to the client.
- UPGRADE
- Used as part of the exchange to upgrade the protocol.
- UPGRADE_
INSECURE_ REQUESTS - Sends a signal to the server expressing the client’s preference for an encrypted and authenticated response.
- USER_
AGENT - Contains a string that allows identifying the requesting client’s software.
- VARY
- Determines how to match future requests with cached responses.
- VIA
- Added by proxies to track routing.
- WARNING
- General HTTP header contains information about possible problems with the status of the message.
- WWW_
AUTHENTICATE - Defines the authentication method that should be used to gain access to a resource.
- X_
CONTENT_ TYPE_ OPTIONS - Marker used by the server to indicate that the MIME types advertised in
the
content-type
headers should not be changed and be followed. - X_
DNS_ PREFETCH_ CONTROL - Controls DNS prefetching.
- X_
FRAME_ OPTIONS - Indicates whether or not a browser should be allowed to render a page in a frame.
- X_
XSS_ PROTECTION - Stop pages from loading when an XSS attack is detected.
Traits§
- AsHeader
Name - A marker trait used to identify values that can be used as search keys
to a
HeaderMap
. - Into
Header Name - A marker trait used to identify values that can be used as insert keys
to a
HeaderMap
.