1 个不稳定版本

0.1.0 2023年4月3日

7#client-ip

每月 下载 24

MIT 许可证

67KB
1K SLoC

ipware

Crates.io Documentation License

这个库旨在通过不同的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.1client, proxy1, 10.1.1.1

如果 proxy_list = ['10.1', '10.2.'],则 client, 10.1.1.1client, proxy1, 10.2.2.2

如果 proxy_list = ['10.1', '10.2.'],则 client, 10.1.1.1 10.2.2.2client, 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