UNPKG

koa-ip-geo

Version:

IP and GeoLocation filter middleware for koa, support allow lists and block lists.

385 lines (285 loc) 12.9 kB
# koa-ip-geo IP and GeoLocation filter middleware for [koa][koa-url], support allow lists and block lists. [![NPM Version][npm-image]][npm-url] [![NPM Downloads][downloads-image]][downloads-url] [![Git Issues][issues-img]][issues-url] [![Closed Issues][closed-issues-img]][closed-issues-url] [![deps status][daviddm-img]][daviddm-url] [![Code Quality: Javascript][lgtm-badge]][lgtm-badge-url] [![Total alerts][lgtm-alerts]][lgtm-alerts-url] [![Caretaker][caretaker-image]][caretaker-url] [![MIT license][license-img]][license-url] ## News and Changes ### Major (breaking) Changes - Version 2 - This new version 2.x.x is adapted for [Koa2][koajs-url] - as it uses the **async/await** pattern this new version works only with [node.js][nodejs-url] **v7.6.0** and above. ## Quick Start ### Installation ```bash $ npm install koa-ip-geo --save ``` You also need the **Maxmind GeoLite2 Free Database** (city or country). We recommend the 'country' version, because it is smaller. [Check their website to get the database][geodb-url]. Alternatively you can now also use **ip2location Databases** (city or country). We recommend the 'country' version, because it is smaller. [Check their website to get the database][ip2location-url]. ### Basic Usage This example has a allow for local IP addresses and a allow for Austrian IP addresses: ```js const Koa = require('koa'); const ipGeo = require('koa-ip-geo'); const app = new Koa(); // if you are using maxminds geo ip database app.use(ipGeo({ geoDB: 'path/to/geodb.mmdb', getDBtype: 'maxmind', allowIP: '192.168.0.*', allowCountry: ['AT'] })); app.use(...); app.listen(3000); ``` If you waht to use the ip2location database instead, please change the config to: ```js // using ip2location database app.use(ipGeo({ geoDB: 'path/to/ip2location.bin', getDBtype: 'ip2location', allowIP: '192.168.0.*', allowCountry: ['AT'] })); app.use(...); app.listen(3000); ``` ### Advanced Options ##### Allow IP address Very basic IP filtering: ```js app.use(ipGeo('192.168.0.*')); ``` Filtering more than one IP address range: ```js app.use(ipGeo('192.168.0.* 8.8.8.[0-3]')); ``` or ```js app.use(ipGeo(['192.168.0.*', '8.8.8.[0-3]'])); ``` >**Notes:** > In the previous examples you saw just a single string or an array as a parameter passed to the middleware. For simplicity, in this case this will be interpreted as a 'allowIP'-parameter. Explicitly specifying a 'allowIP'-parameter would be the 'correct' and more readable way: ```js app.use(ipGeo({ allowIP: ['192.168.0.*', '8.8.8.*'] })); ``` ##### Block IP adresses example ```js app.use(ipGeo({ blockIP: ['8.8.8.*', '1.80.*'], })); ``` ##### Allow countries In order to determine country origin, we need also to specify the geoDB database: ```js app.use(ipGeo({ geoDB: 'path/to/geodb.mmdb', allowCountry: ['US', 'UK', 'DE', 'AT'] })); ``` >**Notes:** > The geoDB database will only be loaded if necessary. So if you specify a database but do not filter by country or continent, the database will not be loaded. ##### Block countries ```js app.use(ipGeo({ geoDB: 'path/to/geodb.mmdb', blockCountry: ['CN', 'RU'] })); ``` ##### Allow continents ```js app.use(ipGeo({ geoDB: 'path/to/geodb.mmdb', allowContinent: ['NA', 'EU'] })); ``` ##### Block continents ```js app.use(ipGeo({ geoDB: 'path/to/geodb.mmdb', blockContinent: ['AS'] })); ``` ##### Pass Geo-IP data into context ... If you need Geo-IP data later in your koa context (ctx. ...), just set the 'context' option to true. ```js app.use(ipGeo({ geoDB: 'path/to/geodb.mmdb', allowCountry: ['US', 'UK', 'DE', 'AT'], context: true })); // you can and then later access geo-ip data in the context of your request: ... let city = ctx.geoCity; // city name let country = ctx.geoCountry; // country name let continent = ctx.geoContinent; // continent name let countrycode = ctx.geoCountryCode // country code (ISO_3166-2) let continentCode = ctx.geoContinentCode; // continent code let latitude = ctx.geoLatitude; // latitude let longitude = ctx.geoLongitude; // longitude ... ``` ##### More complex example: ```js app.use(ipGeo({ blockIP: ['8.8.8.*'], geoDB: 'path/to/geodb.mmdb', allowCountry: ['UK', 'US', 'FR', 'DE', 'AT'], forbidden: '403 - Custom Forbidden Message', development: (process.env.NODE_ENV === 'Development') })); ``` ##### Custom messages Example with custom forbidden (= rejection) message (function): ```js forbidden = async function (ctx, next) { ctx.set('X-Seriously', 'yes'); return 'Seriously - No Access'; } app.use(ipGeo({ allowIP: '192.168.0.*', forbidden: forbidden })) ``` ### GeoLite2 Database > This middleware works with **Maxmind GeoLite2 Free Database** (city or country). We recommend the 'country' version, because it is smaller. [Check their website to get the database][geodb-url]. > Alternatively you now can also use **ip2location Lite Databases** (city or country). We recommend the 'country' version, because it is smaller. [Check their website to get the database][ip2location-url]. > > `koa-ip-geo` loads the entire database file into memory as a single node `Buffer`. It also uses an in-memory cache when reading complex data structures out of this buffer in the interests of performance. So very roughly speaking, you should assume this module will consume `size_of_mmdb_file * 1.25` of memory. ### Option Reference | option | Description | Example | | -------------- | --------------------- | ---------------------- | | geoDB | path to maxmind or ip2location database | 'GeoLite2-City.mmdb' | | geoDBtype | 'maxmind' or 'ip2location' - defaults to maxmind | 'maxmind' | | allowIP | Array of IP addresses (or space separated string) | ['192.168.0.*', '8.8.8.[0-3]'] | | blockIP | Array of IP addresses (or space separated string) | ['8.8.8.*', '1.80.*'] | | allowCountry | Array of [ISO 3166-2 country code][iso3166-2-url] (or space separated string) | ['US', 'AT'] | | blockCountry | Array of [ISO 3166-2 country code][iso3166-2-url] (or space separated string) | ['CN', 'RU'] | | allowContinent | Array of continent code (or space separated string) | ['EU', 'NA'] | | blockContinent | Array of continent code (or space separated string) | ['AS', 'OC', 'AF'] | | forbidden | custom 'forbidden' message (string or function) | '403 - Forbidden' | | context | set true, if you need geoIP information in the context | defaults to false | | development | if true, no filztering is done | defaults to false | ### Formats ##### IP Addresses Possible Formats: - x.x.x.x for a specific IP address - x.x.x.* for a IP range - x.x.*.* for a IP range - x.x.* for a IP range also works perfectly - x.x.x.[0-127] this is also a range of IP addresses. > **Notice:** > CIDR notation (e.g. `x.x.x.x/18`) is not supported at the moment. ##### Country Codes Please use the [ISO 3166-2 country code][iso3166-2-url] like 'US', 'UK', .... ##### Continent Codes - AF - Africa - AS - Asia - EU - Europe - NA - North America - OC - Oceania - SA - South America ## Version history | Version | Date | Comment | | -------------- | -------------- | -------- | | 2.3.1 | 2020-10-04 | bugfix ip handling | | 2.3.0 | 2020-10-04 | now also support for ip2location databases | | 2.2.0 | 2020-06-17 | interface adaption allow/block (preserving backwards compatibility) | | 2.1.2 | 2019-02-23 | typescript definitions adapted | | 2.1.1 | 2019-02-22 | typescript definitions modification | | 2.1.0 | 2019-02-22 | added typescript definitions | | 2.0.4 | 2018-11-03 | improved code quality | | 2.0.3 | 2018-11-03 | dependencies update, updated docs | | 2.0.2 | 2017-12-23 | removed console.log | | 2.0.1 | 2017-11-20 | fixed typos README.md | | 2.0.0 | 2017-11-20 | made for Koa2, version bump, updated dependencies | | 1.2.1 | 2015-09-25 | udated README, more examples, typos, ... | | 1.2.0 | 2015-09-23 | now also space separated string possible | | 1.1.2 | 2015-09-19 | updated DOCs - whiteListIP, examples, typos | | 1.1.0 | 2015-09-19 | added geoIP data to koa context (as an option) | | 1.0.0 | 2015-09-18 | initial release | #### Changes Version 2.0.0 This new version is now for Koa2! So this means, this version is a breaking change! Be sure to also use [node.js][nodejs-url] v7.6.0 or above. #### Changes Version 1.2.0 - you can now pass arrays as well as space separated strings to each allow/block: ```js app.use(ipGeo({ blockIP: ['192.168.0.*', '8.8.8.*'] })); ``` is now the same as ```js app.use(ipGeo({ blockIP: '192.168.0.* 8.8.8.*' })); ``` - added synonym for `localhost` = IPv4 `127.0.0.1` = IPv6 `::1` - all three will be handled the same way, you only have to provide ONE of those addresses. E.g.: ```js app.use(ipGeo({ allowIP: 'localhost' })); ``` will allow `127.0.0.1` and `::1` and vice versa. ## Comments If you have ideas or comments, please do not hesitate to contact me. Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue][issue-url]. Sincerely, Sebastian Hildebrandt, [+innovations](http://www.plus-innovations.com) ## Credits Written by Sebastian Hildebrandt [sebhildebrandt](https://github.com/sebhildebrandt) This package is heavenly inspired by [koa-ip][koaip-url] and [koa-ip-filter][koaipfilter-url]. Check them out also. ## License [![MIT license][license-img]][license-url] >The [`MIT`][license-url] License (MIT) > >Copyright © 2018-2020 Sebastian Hildebrandt, [+innovations](http://www.plus-innovations.com). > >Permission is hereby granted, free of charge, to any person obtaining a copy >of this software and associated documentation files (the "Software"), to deal >in the Software without restriction, including without limitation the rights >to use, copy, modify, merge, publish, distribute, sublicense, and/or sell >copies of the Software, and to permit persons to whom the Software is >furnished to do so, subject to the following conditions: > >The above copyright notice and this permission notice shall be included in >all copies or substantial portions of the Software. > >THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR >IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, >FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE >AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER >LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, >OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN >THE SOFTWARE. [npm-image]: https://img.shields.io/npm/v/koa-ip-geo.svg?style=flat-square [npm-url]: https://npmjs.org/package/koa-ip-geo [downloads-image]: https://img.shields.io/npm/dm/koa-ip-geo.svg?style=flat-square [downloads-url]: https://npmjs.org/package/koa-ip-geo [license-url]: https://github.com/sebhildebrandt/koa-ip-geo/blob/master/LICENSE [license-img]: https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square [npmjs-license]: https://img.shields.io/npm/l/koa-ip-geo.svg?style=flat-square [issue-url]: https://github.com/sebhildebrandt/koa-ip-geo/issues/new [koa-url]: https://github.com/koajs/koa [iso3166-2-url]: https://en.wikipedia.org/wiki/ISO_3166-2 [geodb-url]: https://dev.maxmind.com/geoip/geoip2/geolite2/ [ip2location-url]: https://lite.ip2location.com/database/ip-country/ [koaip-url]: https://github.com/MangroveTech/koa-ip [koaipfilter-url]: https://github.com/tunnckoCore/koa-ip-filter [daviddm-url]: https://david-dm.org/sebhildebrandt/koa-ip-geo [daviddm-img]: https://img.shields.io/david/sebhildebrandt/koa-ip-geo.svg?style=flat-square [issues-img]: https://img.shields.io/github/issues/sebhildebrandt/koa-ip-geo.svg?style=flat-square [issues-url]: https://github.com/sebhildebrandt/koa-ip-geo/issues [closed-issues-img]: https://img.shields.io/github/issues-closed-raw/sebhildebrandt/koa-ip-geo.svg?style=flat-square [closed-issues-url]: https://github.com/sebhildebrandt/koa-ip-geo/issues?q=is%3Aissue+is%3Aclosed [nodejs-url]: https://nodejs.org/en/ [koajs-url]: http://koajs.com/ [lgtm-badge]: https://img.shields.io/lgtm/grade/javascript/g/sebhildebrandt/koa-ip-geo.svg?style=flat-square [lgtm-badge-url]: https://lgtm.com/projects/g/sebhildebrandt/koa-ip-geo/context:javascript [lgtm-alerts]: https://img.shields.io/lgtm/alerts/g/sebhildebrandt/koa-ip-geo.svg?style=flat-square [lgtm-alerts-url]: https://lgtm.com/projects/g/sebhildebrandt/koa-ip-geo/alerts [caretaker-url]: https://github.com/sebhildebrandt [caretaker-image]: https://img.shields.io/badge/caretaker-sebhildebrandt-blue.svg?style=flat-square