NAX IPware (A Node Application Agnostic Library)
A node library for server applications retrieving user's real IP address
![coverage-image](https://coveralls.io/repos/neekware/fullerstack/badge.svg)
Overview
Best attempt to get client's IP address while keeping it DRY.
Notice
There is not a good out-of-the-box
solution against fake IP addresses, aka IP Address Spoofing.
You are encouraged to read the Advanced users section of this page and
use trusted proxy prefixes
and/or proxy count
features to match your needs, especially if you are
planning to include ipware
in any authentication, security or anti-fraud
related architecture.
You are also encouraged to use ip filtering alongside ipware
for optimal result.
How to install
npm install @fullerstack/nax-ipware
OR yarn add @fullerstack/nax-ipware
How to use
# In a view or a middleware where the `request` object is available
import {Ipware} from '@fullerstack/nax-ipware';
const ipware = new Ipware();
app.use(function(req, res, next) {
req.ipInfo = ipware.getClientIP(req)
next();
});
Advanced users:
Flags ⇩ | ⇩ Description |
---|
count ⇨ | : Total number of expected proxies (pattern: client, proxy1, ..., proxy2 ) : if count = 0 then client : if count = 1 then client, proxy1 : if count = 2 then client, proxy1, proxy2 : if count = 3 then client, proxy1, proxy2 proxy3 |
proxyList ⇨ | : List of trusted proxies (pattern: client, proxy1, ..., proxy2 ) : if proxyList = ['10.1.'] then client, 10.1.1.1 OR client, proxy1, 10.1.1.1 : if proxyList = ['10.1', '10.2.'] then client, 10.1.1.1 OR client, proxy1, 10.2.2.2 : if proxyList = ['10.1', '10.2.'] then client, 10.1.1.1 10.2.2.2 OR client, 10.1.1.1 10.2.2.2 |
publicOnly ⇨ | : Returns only public and internet routable IP or null |
Output Field ⇩ | ⇩ Description |
---|
ip ⇨ | : IP address of the client |
isPublic ⇨ | : If ip is public and internet routable, true , else false |
isRouteTrusted ⇨ | : If proxy count and/or proxyList provided and matched, true , else false |
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.
export const IPWARE_HEADERS_IP_ATTRIBUTES_ORDER: string[] = [
'X_FORWARDED_FOR',
'HTTP_X_FORWARDED_FOR',
'HTTP_CLIENT_IP',
'HTTP_X_REAL_IP',
'HTTP_X_FORWARDED',
'HTTP_X_CLUSTER_CLIENT_IP',
'HTTP_FORWARDED_FOR',
'HTTP_FORWARDED',
'HTTP_VIA',
'X-REAL-IP',
'X-CLUSTER-CLIENT-IP',
'X_FORWARDED',
'FORWARDED_FOR',
'CF-CONNECTING-IP',
'TRUE-CLIENT-IP',
'FASTLY-CLIENT-IP',
'FORWARDED',
];
You can customize the order by providing your own list during initialization when calling new Ipware(options)
.
You can pass your custom list on every call, when calling the api to fetch the ip.
ipware.getClientIP(request, {
requestHeadersOrder: ['X_FORWARDED_FOR'],
});
ipware.getClientIP(request, {
requestHeadersOrder: ['X_FORWARDED_FOR', 'HTTP_X_FORWARDED_FOR'],
});
Private Prefixes
A default list that holds the private IP prefixes is called IPWARE_PRIVATE_IP_PREFIX
.
This list is used to determine if an IP address is public
or private
.
It is recommended that you send us any private
IP addresses that we have missed, to be included in the default list.
export const IPWARE_PRIVATE_IP_PREFIX: string[] = [
'0.',
'10.',
...[
'100.64.',
'100.65.',
'100.66.',
'100.67.',
],
]
You can customize the private IP prefixes by providing your own list during initialization when calling new Ipware(options)
.
You can pass your custom list on every call, when calling the api to fetch the ip.
ipware.getClientIP(request, {
privateIpPrefixes: ['0.', '10.'],
});
ipware.getClientIP(request, {
privateIpPrefixes: ['0.', '10.', '2001:10:'],
});
Trusted Proxies
If your node 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 during initialization when calling new Ipware(options)
.
You can pass your custom list on every call, when calling the proxy-aware api to fetch the ip.
const ipInfo = ipware.getClientIP(request, {
proxy: {
proxyList: ['177.139.233.132']
},
});
const ipInfo = ipware.getClientIP(request, {
proxy: {
proxyList: ['177.139.233.100', '177.139.233.132']
},
});
const ipInfo = ipware.getClientIP(request, {
proxy: {
proxyList: ['177.139.', '177.140']
},
});
const ipInfo = ipware.getClientIP(request, {
proxy: {
proxyList: ['177.139.233.', '177.139.240']
},
});
const ipInfo = ipware.getClientIP(request, {
proxy: {
proxyList: ['177.139.', '177.140'],
count: 2
},
});
const ipInfo = ipware.getClientIP(request, {
proxy: {
strict: true,
proxyList: ['177.139.233.', '177.139.240']
},
});
In the following example
, your public load balancer (LB) can be seen as a trusted
proxy.
`Real` Client <public> <-> <public> LB (Server) <private> <-----> <private> Node Server
^
|
`Fake` Client <private> <-> <private> LB (Server) <private> -+
Proxy Count
If your node server is behind a known
number of proxies, but your 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 count
during initialization when calling new Ipware(options)
.
You can pass your custom count
on every call, when calling the proxy-aware api to fetch the ip.
const ipInfo = ipware.getClientIP(request, {
proxy: {
count: 1
},
});
const ipInfo = ipware.getClientIP(request, {
proxy: {
count: 1
proxyList: ['177.139.233.']
},
});
const ipInfo = ipware.getClientIP(request, {
proxy: {
strict: true,
count: 1
},
});
In the following example
, your public load balancer (LB) can be seen as the only
proxy.
`Real` Client <public> <-> <public> LB (Server) <private> <---> <private> Node Server
^
|
`Fake` Client <private> ---+
Public IP Address ONLY (routable on the internet)
const ipInfo = ipware.getClientIP(request, {
publicOnly: true
});
Originating Request
If your proxy server has a custom
configuration where the right-most
IP address is that of the originating client, you
can indicate right-most
as the order
when calling any api.
Please note that the de-facto standard
for the originating client IP address is the left-most
as per client, proxy1, proxy2
, and the right-most
proxy is the most
trusted proxy.
Running the tests
To run the tests against the current environment:
yarn nx test nax-ipware
License
Released under a (MIT) license.
Version
X.Y.Z Version
`MAJOR` version -- making incompatible API changes
`MINOR` version -- adding functionality in a backwards-compatible manner
`PATCH` version -- making backwards-compatible bug fixes
Neekware Inc.