nestjs-ip-filter
v0.2.0
Published
A NestJS Guard for filtering IP addresses
Downloads
677
Maintainers
Readme
NestJS IP Filter
Now we can filter the incoming requests by setting the whitelist and the blacklist IP addresses.
It will work using the built-in feature in NestJS, Guard, so it works like a charm as it should be and as much as it should do.
The Guard recognizes the requester's IP address using @supercharge/request-ip package.
How to install
Simply, install using NPM by the following command.
npm install nestjs-ip-filter
Usage
Use Regex for the IP list
In Express-based framework, the incoming IP address will have prefix
::ffff:
characters. So if you have put(^192.168.)
into the whitelist, it won't work because that regex describes it must have number1
as a first character. So for now, you should put that prefix for your regex string like(^::ffff:192.168.)
. Will patch the source codes in the near future.
You can use the Regex format string for the IP ranges.
For a simple example, if you want to allow the private network hosts in 192.168.0.1/16
, you can write the Regex string like the below.
# 192.168.0.0 ~ 192.168.255.255
(^192.168.)
Check the other use cases.
# 192.168.0.100 ~ 192.168.0.110
(^192.168.0.1[0-1]0)
# 172.16.16.10, 172.16.17.10, 172.16.18.10
(^172.16.1[6-8].10)
# 110~119.*
(^11[0-9].*)
And, writing in this way also works on this package.
But be aware of that you should write the Regex string very carefully to avoid allowing unwanted incoming IP addresses.
Basic usage for Whitelist
You can initialize the dedicated Guard using non-async or async mode, as the other NestJS packages support.
Use register
for the static IP address list.
IpFilter.register({
whitelist: [
'(^::1)',
'(^192.168.)',
'127.0.0.1',
],
}),
Or, use registerAsync
for the provided IP addresses from the other Provider, such as ConfigModule or RepositoryModule for your database.
// If it would like to get the whitelist IPs from a config file,
// and if MyConfigModule provides that
IpFilter.registerAsync({
imports: [ MyConfigModule ],
inject: [ MyConfigService ],
useFactory: async (myConfigService: MyConfigService) => ({
whitelist: myConfigService.getWhitelist(),
}),
}),
Yeah, you can use your method to provide some async data.
After setting up the IpFilter
module with the register*
method, this will accept only the incoming requests for the given whitelist IP addresses.
Blacklist
You can deny the requests that are from the blacklist IPs.
Use blacklist
option to let the Guard know the list.
// If it would like to get the whitelist IPs from a config file,
// and if MyConfigModule provides that
IpFilter.registerAsync({
imports: [ MyConfigModule ],
inject: [ MyConfigService ],
useFactory: async (myConfigService: MyConfigService) => ({
whitelist: myConfigService.getWhitelist(),
blacklist: myConfigService.getBlacklist(),
}),
}),
Then its NestJS Guard will deny all the IPs which are from the blacklist.
Use IpFilterDenyException when denying a request
You can handle the denial condition by catching the HTTP exception.
If you want to throw that IpFilterDenyException
when denial, set the option useDenyException
to true
.
// If it would like to get the whitelist IPs from a config file,
// and if MyConfigModule provides that
IpFilter.registerAsync({
imports: [ MyConfigModule ],
inject: [ MyConfigService ],
useFactory: async (myConfigService: MyConfigService) => ({
whitelist: myConfigService.getWhitelist(),
blacklist: myConfigService.getBlacklist(),
useDenyException: true,
}),
}),
Then it will throw IpFilterDenyException
when the request is denied for the given whitelist or the blacklist.
So that, you can handle the denied request and can send a custom response on that handler, using NestJS Exception Filter.
When the Guard throws an exception, it will also carry some informative data like the incoming IP address, current whitelist and blacklist.
Inject IpFilterService
If you want, you can inject IpFilterService
into your code and can see current options you put when you initialize it. And, you can set the whitelist and the blacklist too.
Inject the service using the IPFILTER_TOKEN
module.
@Injectable()
export class SomeService {
constructor(
@inject(IPFILTER_TOKEN)
private readonly ipFilterService: IpFilterService
) {}
// ...
}
Then you can edit the whitelist, blacklist IP addresses dynamically.
this.ipFilterService.whitelist = [ {NEW_WHITELIST} ];
this.ipFilterService.blacklist = [ {NEW_BLACKLIST} ];
Example project
This repository contains an example project of this nestjs-ip-filter
package.
Move to example
directory and run the following commands.
npm ci
npm start:debug
Then, the example project will run in 3001 port.
With the curl
command, you can do a simple test for the project.
curl -X GET -H "Content-Type: application/json" http://localhost:3001/ipfilter
It will result like the below, if your localhost IP is accepted for the whitelist.
{"whitelist":["(^::1)","(^192.168.)","127.0.0.1"],"blacklist":[]}
If it denies, it will result like the below. Check the ipFilterData
field.
{"statusCode":403,"timestamp":"2022-06-13T09:29:40.452Z","ipFilterData":{"clientIp":"::ffff:127.0.0.1","whitelist":["(^::1)","(^192.168.)"],"blacklist":[]},"path":"/ipfilter"}
Our exception filter put that additional field on the typical HttpException results.
You can test the projects with your local host IP address, by editing the whitelist and the blacklist.
License
It follows the MIT license.