@hackthedev/dsync-ipsec 1.0.0 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +157 -1
- package/index.mjs +33 -17
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,2 +1,158 @@
|
|
|
1
1
|
# dSyncIPSec
|
|
2
|
-
|
|
2
|
+
This library comes with features meant to prevent abuse in form of spam and other malicious activities and comes with the following detections and features:
|
|
3
|
+
|
|
4
|
+
- Block known abusers, bogon IPs, datacenters, crawlers, proxies, satelites, Tor IPs and VPNs.
|
|
5
|
+
- Possibility to block traffic from entire Countries
|
|
6
|
+
- Whitelist and Blacklist feature based on IP address and Company Domains
|
|
7
|
+
|
|
8
|
+
The library was designed for usage with `express` and filtering abusive and (potentially) malicious traffic based on the IP address.
|
|
9
|
+
|
|
10
|
+
> [!IMPORTANT]
|
|
11
|
+
>
|
|
12
|
+
> It is highly recommended that you cache or store the API response!!!!
|
|
13
|
+
|
|
14
|
+
------
|
|
15
|
+
|
|
16
|
+
## Setup
|
|
17
|
+
|
|
18
|
+
```js
|
|
19
|
+
import dSyncIPSec from "@hackthedev/dsync-ipsec"
|
|
20
|
+
|
|
21
|
+
// will use default settings
|
|
22
|
+
export let ipsec = new dSyncIPSec();
|
|
23
|
+
|
|
24
|
+
// alternatively, with settings already specified.
|
|
25
|
+
// settings shown here are the default settings.
|
|
26
|
+
export let ipsec = new dSyncIPSec({
|
|
27
|
+
blockBogon: true,
|
|
28
|
+
blockDatacenter: true,
|
|
29
|
+
blockSatelite: true,
|
|
30
|
+
blockCrawler: true,
|
|
31
|
+
blockProxy: true,
|
|
32
|
+
blockVPN: true,
|
|
33
|
+
blockTor: true,
|
|
34
|
+
blockAbuser: true,
|
|
35
|
+
// some arrays
|
|
36
|
+
whitelistedUrls: [],
|
|
37
|
+
whitelistedIps: [],
|
|
38
|
+
blockedCountryCodes: [],
|
|
39
|
+
whitelistedCompanyDomains: [],
|
|
40
|
+
blacklistedIps = [
|
|
41
|
+
"::1",
|
|
42
|
+
"127.0.0.1",
|
|
43
|
+
"localhost"
|
|
44
|
+
]
|
|
45
|
+
});
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
------
|
|
49
|
+
|
|
50
|
+
## Updating settings
|
|
51
|
+
|
|
52
|
+
```js
|
|
53
|
+
// you can only specify the keys that you actually want to update
|
|
54
|
+
ipsec.updateRule({
|
|
55
|
+
blockBogon: true,
|
|
56
|
+
blockSatelite: true,
|
|
57
|
+
blockCrawler: true,
|
|
58
|
+
blockProxy: true,
|
|
59
|
+
blockVPN: true,
|
|
60
|
+
blockTor: true,
|
|
61
|
+
blockAbuser: true,
|
|
62
|
+
|
|
63
|
+
whitelistedUrls: [],
|
|
64
|
+
whitelistedIps: [],
|
|
65
|
+
blacklistedIps: [],
|
|
66
|
+
companyDomainWhitelist: [],
|
|
67
|
+
});
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
------
|
|
71
|
+
|
|
72
|
+
## Filtering express traffic
|
|
73
|
+
|
|
74
|
+
```js
|
|
75
|
+
await ipsec.filterExpressTraffic(app)
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
------
|
|
79
|
+
|
|
80
|
+
## Manually getting IP Info
|
|
81
|
+
|
|
82
|
+
```js
|
|
83
|
+
await lookupIP("1.1.1.1")
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Example response object:
|
|
87
|
+
|
|
88
|
+
```json
|
|
89
|
+
{
|
|
90
|
+
"ip": "1.1.1.1",
|
|
91
|
+
"rir": "APNIC",
|
|
92
|
+
"is_bogon": false,
|
|
93
|
+
"is_mobile": false,
|
|
94
|
+
"is_satellite": false,
|
|
95
|
+
"is_crawler": false,
|
|
96
|
+
"is_datacenter": true,
|
|
97
|
+
"is_tor": false,
|
|
98
|
+
"is_proxy": false,
|
|
99
|
+
"is_vpn": false,
|
|
100
|
+
"is_abuser": true,
|
|
101
|
+
"datacenter": {
|
|
102
|
+
"datacenter": "kamatera.com",
|
|
103
|
+
"network": "1.1.1.1/24",
|
|
104
|
+
"country": "HK",
|
|
105
|
+
"city": "Hong Kong",
|
|
106
|
+
"postal": "0"
|
|
107
|
+
},
|
|
108
|
+
"company": {
|
|
109
|
+
"name": "APNIC Research and Development",
|
|
110
|
+
"abuser_score": "0.0156 (Elevated)",
|
|
111
|
+
"domain": "apnic.net",
|
|
112
|
+
"type": "business",
|
|
113
|
+
"network": "1.1.1.0 - 1.1.1.255",
|
|
114
|
+
"whois": "https://api.ipapi.is/?whois=1.1.1.0"
|
|
115
|
+
},
|
|
116
|
+
"abuse": {
|
|
117
|
+
"name": "APNIC Research and Development",
|
|
118
|
+
"address": "6 Cordelia St",
|
|
119
|
+
"email": "helpdesk@apnic.net",
|
|
120
|
+
"phone": "+61-7-38583100"
|
|
121
|
+
},
|
|
122
|
+
"asn": {
|
|
123
|
+
"asn": 13335,
|
|
124
|
+
"abuser_score": "0.0267 (Elevated)",
|
|
125
|
+
"route": "1.1.1.0/24",
|
|
126
|
+
"descr": "CLOUDFLARENET, US",
|
|
127
|
+
"country": "us",
|
|
128
|
+
"active": true,
|
|
129
|
+
"org": "Cloudflare, Inc.",
|
|
130
|
+
"domain": "cloudflare.com",
|
|
131
|
+
"abuse": "abuse@cloudflare.com",
|
|
132
|
+
"type": "hosting",
|
|
133
|
+
"created": "2010-07-14",
|
|
134
|
+
"updated": "2017-02-17",
|
|
135
|
+
"rir": "ARIN",
|
|
136
|
+
"whois": "https://api.ipapi.is/?whois=AS13335"
|
|
137
|
+
},
|
|
138
|
+
"location": {
|
|
139
|
+
"is_eu_member": false,
|
|
140
|
+
"calling_code": "61",
|
|
141
|
+
"currency_code": "AUD",
|
|
142
|
+
"continent": "OC",
|
|
143
|
+
"country": "Australia",
|
|
144
|
+
"country_code": "AU",
|
|
145
|
+
"state": "New South Wales",
|
|
146
|
+
"city": "Sydney",
|
|
147
|
+
"latitude": -33.86785,
|
|
148
|
+
"longitude": 151.20732,
|
|
149
|
+
"zip": "1001",
|
|
150
|
+
"timezone": "Australia/Sydney",
|
|
151
|
+
"local_time": "2026-01-16T15:26:18+11:00",
|
|
152
|
+
"local_time_unix": 1768537578,
|
|
153
|
+
"is_dst": true
|
|
154
|
+
},
|
|
155
|
+
"elapsed_ms": 0.16
|
|
156
|
+
}
|
|
157
|
+
```
|
|
158
|
+
|
package/index.mjs
CHANGED
|
@@ -30,13 +30,12 @@ export default class dSyncIPSec {
|
|
|
30
30
|
this.blockVPN = blockVPN;
|
|
31
31
|
this.blockTor = blockTor;
|
|
32
32
|
this.blockAbuser = blockAbuser;
|
|
33
|
-
this.blockedCountryCodes = blockedCountryCodes;
|
|
34
33
|
|
|
35
|
-
this.urlWhitelist =
|
|
36
|
-
this.ipWhitelist =
|
|
37
|
-
this.ipBlacklist =
|
|
38
|
-
this.companyDomainWhitelist =
|
|
39
|
-
this.blockedCountriesByCode =
|
|
34
|
+
this.urlWhitelist = whitelistedUrls
|
|
35
|
+
this.ipWhitelist = whitelistedIps
|
|
36
|
+
this.ipBlacklist = blacklistedIps
|
|
37
|
+
this.companyDomainWhitelist = whitelistedCompanyDomains
|
|
38
|
+
this.blockedCountriesByCode = blockedCountryCodes
|
|
40
39
|
}
|
|
41
40
|
|
|
42
41
|
updateRule({
|
|
@@ -48,6 +47,12 @@ export default class dSyncIPSec {
|
|
|
48
47
|
blockVPN = null,
|
|
49
48
|
blockTor = null,
|
|
50
49
|
blockAbuser = null,
|
|
50
|
+
|
|
51
|
+
whitelistedUrls = null,
|
|
52
|
+
whitelistedIps = null,
|
|
53
|
+
blockedCountryCodes = null,
|
|
54
|
+
whitelistedCompanyDomains = null,
|
|
55
|
+
blacklistedIps = null,
|
|
51
56
|
}){
|
|
52
57
|
|
|
53
58
|
if(blockBogon !== null) this.blockBogon = blockBogon
|
|
@@ -58,28 +63,39 @@ export default class dSyncIPSec {
|
|
|
58
63
|
if(blockVPN !== null) this.blockVPN = blockVPN
|
|
59
64
|
if(blockTor !== null) this.blockTor = blockTor
|
|
60
65
|
if(blockAbuser !== null) this.blockAbuser = blockAbuser
|
|
66
|
+
|
|
67
|
+
if (whitelistedUrls !== null) this.urlWhitelist = whitelistedUrls
|
|
68
|
+
if (whitelistedIps !== null) this.ipWhitelist = whitelistedIps
|
|
69
|
+
if (blacklistedIps !== null) this.ipBlacklist = blacklistedIps
|
|
70
|
+
if (blockedCountryCodes !== null) this.blockedCountriesByCode = blockedCountryCodes
|
|
61
71
|
}
|
|
62
72
|
|
|
73
|
+
|
|
63
74
|
whitelistIP(ip, allowDuplicates = false){
|
|
64
75
|
if(!ip) throw new Error("Unable to whitelist ip as no ip was provided.");
|
|
65
|
-
if(!this.ipWhitelist
|
|
66
|
-
|
|
76
|
+
if(!ArrayTools.matches(this.ipWhitelist, ip) && !allowDuplicates)
|
|
77
|
+
ArrayTools.addEntry(this.ipWhitelist, ip);
|
|
78
|
+
if(ArrayTools.matches(this.ipBlacklist, ip))
|
|
79
|
+
this.ipBlacklist = ArrayTools.removeEntry(this.ipBlacklist, ip);
|
|
67
80
|
}
|
|
68
81
|
|
|
69
82
|
blacklistIp(ip, allowDuplicates = false){
|
|
70
83
|
if(!ip) throw new Error("Unable to blacklist ip as no ip was provided.");
|
|
71
|
-
if(!this.ipBlacklist
|
|
72
|
-
|
|
84
|
+
if(!ArrayTools.matches(this.ipBlacklist, ip) && !allowDuplicates)
|
|
85
|
+
ArrayTools.addEntry(this.ipBlacklist, ip);
|
|
86
|
+
if(ArrayTools.matches(this.ipWhitelist, ip))
|
|
87
|
+
this.ipWhitelist = ArrayTools.removeEntry(this.ipWhitelist, ip);
|
|
73
88
|
}
|
|
74
89
|
|
|
90
|
+
|
|
75
91
|
isBlacklistedIp(ip){
|
|
76
92
|
if(!ip) throw new Error("Coudlnt check ip blacklist as no ip was provided.")
|
|
77
|
-
return this.ipBlacklist
|
|
93
|
+
return ArrayTools.matches(this.ipBlacklist, ip)
|
|
78
94
|
}
|
|
79
95
|
|
|
80
96
|
isWhitelistedIp(ip){
|
|
81
97
|
if(!ip) throw new Error("Coudlnt check ip blacklist as no ip was provided.")
|
|
82
|
-
return this.ipWhitelist
|
|
98
|
+
return ArrayTools.matches(this.ipWhitelist, ip)
|
|
83
99
|
}
|
|
84
100
|
|
|
85
101
|
async filterExpressTraffic(app){
|
|
@@ -94,15 +110,15 @@ export default class dSyncIPSec {
|
|
|
94
110
|
if(!reqPath) throw new Error("Unable to get request path from req parameter as it wasnt specified or null");
|
|
95
111
|
|
|
96
112
|
// first check for ip blacklist
|
|
97
|
-
if(this.ipBlacklist
|
|
113
|
+
if(ArrayTools.matches(this.ipBlacklist, ipInfo?.ip)) return res.sendStatus(403);
|
|
98
114
|
|
|
99
115
|
// then we can check for whitelisted urls as these bypass normal checks
|
|
100
116
|
// url whitelist
|
|
101
|
-
if(this.urlWhitelist
|
|
117
|
+
if(ArrayTools.matches(this.urlWhitelist, reqPath)) return next();
|
|
102
118
|
// let whitelisted ips pass
|
|
103
|
-
if(this.ipWhitelist
|
|
119
|
+
if(ArrayTools.matches(this.ipWhitelist, ipInfo?.ip)) return next();
|
|
104
120
|
// company domain whitelist
|
|
105
|
-
if(this.companyDomainWhitelist
|
|
121
|
+
if(ArrayTools.matches(this.companyDomainWhitelist, ipInfo?.company?.domain)) return next();
|
|
106
122
|
|
|
107
123
|
// looking kinda beautiful
|
|
108
124
|
if (ipInfo?.is_bogon && this.blockBogon) return res.sendStatus(403);
|
|
@@ -116,7 +132,7 @@ export default class dSyncIPSec {
|
|
|
116
132
|
|
|
117
133
|
if (
|
|
118
134
|
ipInfo.location?.country_code &&
|
|
119
|
-
this.blockedCountriesByCode
|
|
135
|
+
ArrayTools.matches(this.blockedCountriesByCode, ipInfo?.location?.country_code?.toLowerCase())
|
|
120
136
|
) return res.sendStatus(403);
|
|
121
137
|
|
|
122
138
|
// continue
|