1 个不稳定版本
0.1.0 | 2023年4月3日 |
---|
7 在 #client-ip
每月 下载 24 次
67KB
1K SLoC
ipware
这个库旨在通过不同的HTTP头部值提取HTTP请求客户端的IP地址。由 python-ipware 开发者 @un33k 转换而来。
⚠️ 警告
此库使用不稳定的Rust API。
![feature(ip)]
📦 Cargo.toml
[dependencies]
ipware = "0.1"
🔧 示例
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);
🖨️ 输出
177.139.233.139 false
⚙️ 配置
参数 | 描述 |
---|---|
proxy_count |
: 预期代理的总数(模式:client, proxy1, ..., proxy2 ): 如果 proxy_count = 0 ,则 client : 如果 proxy_count = 1 ,则 client, proxy1 : 如果 proxy_count = 2 ,则 client, proxy1, proxy2 : 如果 proxy_count = 3 ,则 client, proxy1, proxy2 proxy3 |
proxy_list |
: 受信任代理列表(模式:client, proxy1, ..., proxy2 ): 如果 proxy_list = ['10.1.'] ,则 client, 10.1.1.1 或 client, proxy1, 10.1.1.1 :如果 proxy_list = ['10.1', '10.2.'] ,则 client, 10.1.1.1 或 client, proxy1, 10.2.2.2
:如果 proxy_list = ['10.1', '10.2.'] ,则 client, 10.1.1.1 10.2.2.2 或 client, 10.1.1.1 10.2.2.2
|
最左边 |
:leftmost = True 是事实上的标准的默认值。
: leftmost = False 用于配置了 rightmost 模式的罕见旧网络。
:它将 client, proxy1 proxy2 转换为 proxy2, proxy1, client 。
|
输出 | 描述 |
---|---|
ip |
:客户端 IP 地址对象,类型为 IPv4Addr 或 IPv6Addr。 |
可信路由 |
:如果提供了代理 proxy_count 和/或 proxy_list 并匹配,则为 true ,否则为 false 。
|
HTTP Header 优先级顺序
:
客户端 IP 地址可以在一个或多个请求头属性中找到。查找顺序是从上到下,默认属性如下。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
];
:
您可以通过使用 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,
);
:🤝 可信代理
:
如果您的 HTTP 服务器位于一个或多个已知代理服务器之后,您可以通过提供trusted proxy list
或已知的代理 count
来过滤掉不需要的请求。
:
您可以通过使用 IpWareProxy 提供自己的列表来自定义代理 IP 前缀。您可以在每次调用时传递自定义列表,当调用代理感知的 API 来获取 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);
代理计数
:
如果您的 HTTP 服务器位于一个已知
数量的代理之后,但您在多个提供商上部署且不想跟踪代理 IP,您仍然可以通过提供代理 count
来过滤掉不需要的请求。
:
您可以通过使用 IpWareProxy 提供的proxy_count
来自定义代理计数。
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);
:支持 IPv4、IPv6 和 IP:Port 模式和封装。
- 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.
原始请求
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(),
);
:📝 许可证
:
在 MIT 许可证下许可(LICENSE)。:🚧 贡献
除非您明确表示不同,否则根据MIT许可证定义,您有意提交的、旨在包含在本项目中的任何贡献,均应按上述方式许可,不附加任何额外条款或条件。
依赖项
~575KB