diff --git a/.codeclimate.yml b/.codeclimate.yml index 1fd0569..0b9e04c 100644 --- a/.codeclimate.yml +++ b/.codeclimate.yml @@ -1,15 +1,15 @@ engines: eslint: enabled: true - channel: "eslint-8" + channel: 'eslint-8' config: - config: ".eslintrc.yaml" + config: '.eslintrc.yaml' ratings: - paths: - - "**.js" + paths: + - '**.js' checks: method-complexity: config: - threshold: 10 \ No newline at end of file + threshold: 10 diff --git a/.eslintrc.yaml b/.eslintrc.yaml index fe947ea..9fe535c 100644 --- a/.eslintrc.yaml +++ b/.eslintrc.yaml @@ -2,24 +2,10 @@ env: node: true es6: true mocha: true - es2020: true - -plugins: - - haraka + es2022: true extends: - - eslint:recommended - - plugin:haraka/recommended + - '@haraka' rules: - indent: [2, 2, {"SwitchCase": 1}] - -root: true - -globals: - OK: true - CONT: true - DENY: true - DENYSOFT: true - DENYDISCONNECT: true - DENYSOFTDISCONNECT: true + no-unused-vars: 1 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3c40dcc..7924e85 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,6 +2,7 @@ name: CI on: push: + pull_request: env: CI: true @@ -14,23 +15,10 @@ jobs: # uses: haraka/.github/.github/workflows/coverage.yml@master # secrets: inherit - test: - needs: lint - runs-on: ${{ matrix.os }} - strategy: - matrix: - os: [ ubuntu-latest, windows-latest ] - node-version: [ 14, 16, 18 ] - fail-fast: false + ubuntu: + needs: [lint] + uses: haraka/.github/.github/workflows/ubuntu.yml@master - steps: - - uses: actions/checkout@v3 - - - uses: actions/setup-node@v3 - name: Node ${{ matrix.node-version }} on ${{ matrix.os }} - with: - node-version: ${{ matrix.node-version }} - - - run: npm install - - - run: npm test + windows: + needs: [lint] + uses: haraka/.github/.github/workflows/windows.yml@master diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 3627451..8314a66 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -2,10 +2,10 @@ name: CodeQL on: push: - branches: [ master ] + branches: [master] pull_request: # The branches below must be a subset of the branches above - branches: [ master ] + branches: [master] schedule: - cron: '18 7 * * 4' diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index d489fbd..e81c15f 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -13,4 +13,4 @@ env: jobs: publish: uses: haraka/.github/.github/workflows/publish.yml@master - secrets: inherit \ No newline at end of file + secrets: inherit diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..8ded5e0 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,2 @@ +singleQuote: true +semi: false diff --git a/.release b/.release index 0890e94..afb1db8 160000 --- a/.release +++ b/.release @@ -1 +1 @@ -Subproject commit 0890e945e4e061c96c7b2ab45017525904c17728 +Subproject commit afb1db801607dda5e859f39b600f0dd0111e4651 diff --git a/Changes.md b/CHANGELOG.md similarity index 61% rename from Changes.md rename to CHANGELOG.md index 22e6776..1b95b3e 100644 --- a/Changes.md +++ b/CHANGELOG.md @@ -1,18 +1,28 @@ +# Changelog + +The format is based on [Keep a Changelog](https://keepachangelog.com/). + ### Unreleased +### [2.0.3] - 2023-12-13 + +- ci: use shared ci workflows +- confirm maxmind db has loaded before registering hook #23 +- populate [files] in package.json +- dep: eslint-plugin-haraka -> @haraka/eslint-config +- lint: remove duplicate / stale rules from .eslintrc +- doc: renamed Changes.md -> CHANGELOG.md ### 2.0.2 - 2023-02-07 - fix: catching DNS timeout exception - ### 2.0.1 - 2022-05-27 - fix: when adding headers, assure ASN is string - fix: when adding header, look in correct location for asn.org - when create conn note, only assign properties with values - ### 2.0.0 - 2022-05-23 - style: replace most callbacks with async/await @@ -20,7 +30,6 @@ - asn.ini: switch default dns provider to rspamd - dep: remove async - ### 1.0.9 - 2022-05-22 - ci: add GitHub Actions CI, #17 @@ -30,7 +39,6 @@ - style: more es6/7 - dep(async): bump version to 3.2 - ### 1.0.8 - 2018-01-22 - parse maxmind ASN w/o Org data @@ -39,18 +47,15 @@ - added parse_rspamd test - emit rspamd DNS provider results (when enabled) - ### 1.0.7 - 2017-02-06 - updated eslint to use eslint-plugin-haraka - aggregate results before emitting - ### 1.0.6 - 2016-10-20 -* when protocols[setting]=false, don't enable that protocol - * ie, do what the config implies - +- when protocols[setting]=false, don't enable that protocol + - ie, do what the config implies ### 1.0.5 - 2016-10-08 @@ -62,5 +67,8 @@ ### 1.0.0 - 2016-07-21 - -[2.0.2]: https://github.com/haraka/haraka-plugin-asn/releases/tag/2.0.2 +[1.0.9]: https://github.com/haraka/haraka-plugin-asn/releases/tag/v1.0.9 +[2.0.0]: https://github.com/haraka/haraka-plugin-asn/releases/tag/v2.0.0 +[2.0.1]: https://github.com/haraka/haraka-plugin-asn/releases/tag/2.0.1 +[2.0.2]: https://github.com/haraka/haraka-plugin-asn/releases/tag/v2.0.2 +[2.0.3]: https://github.com/haraka/haraka-plugin-asn/releases/tag/2.0.3 diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md new file mode 100644 index 0000000..028df07 --- /dev/null +++ b/CONTRIBUTORS.md @@ -0,0 +1,8 @@ +# Contributors + +This handcrafted artisinal software is brought to you by: + +|
msimerson (26) |
analogic (1) |
lnedry (1) | +| :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | + +this file is maintained by [.release](https://github.com/msimerson/.release) diff --git a/README.md b/README.md index a3cc681..cfd26db 100644 --- a/README.md +++ b/README.md @@ -6,21 +6,18 @@ look up ASN from local GeoIP databases and/or DNS based providers. - ### DNS providers -* origin.asn.cymru.com -* asn.routeviews.org -* asn.rspamd.com - +- origin.asn.cymru.com +- asn.routeviews.org +- asn.rspamd.com ### Databases -* MaxMind ASN database +- MaxMind ASN database PS: Run something like [maxmind-geolite-mirror](https://www.npmjs.com/package/maxmind-geolite-mirror) weekly to keep your database files up-to-date. - [ci-img]: https://github.com/haraka/haraka-plugin-asn/actions/workflows/ci.yml/badge.svg [ci-url]: https://github.com/haraka/haraka-plugin-asn/actions/workflows/ci.yml [clim-img]: https://codeclimate.com/github/haraka/haraka-plugin-asn/badges/gpa.svg diff --git a/index.js b/index.js index e25f317..44e5344 100644 --- a/index.js +++ b/index.js @@ -1,232 +1,237 @@ // determine the ASN of the connecting IP -// node built-ins -const dns = require('dns').promises; -const fs = require('fs/promises'); -const path = require('path') - -let test_ip = '66.128.51.163'; -const providers = []; -let conf_providers = [ 'origin.asn.cymru.com', 'asn.routeviews.org', 'asn.rspamd.com' ]; +const dns = require('node:dns').promises +const fs = require('node:fs/promises') +const path = require('node:path') + +let test_ip = '66.128.51.163' +const providers = [] +let conf_providers = [ + 'origin.asn.cymru.com', + 'asn.routeviews.org', + 'asn.rspamd.com', +] exports.register = async function () { - this.registered = false; + this.registered = false - this.load_asn_ini(); + this.load_asn_ini() - await this.test_and_register_dns_providers(); - await this.test_and_register_geoip(); + await this.test_and_register_dns_providers() + await this.test_and_register_geoip() if (this.cfg.header.asn) { - this.register_hook('data_post', 'add_header_asn'); + this.register_hook('data_post', 'add_header_asn') } if (this.cfg.header.provider) { - this.register_hook('data_post', 'add_header_provider'); + this.register_hook('data_post', 'add_header_provider') } } exports.test_and_register_dns_providers = async function () { - if (!this.cfg.protocols.dns) return; // disabled in config + if (!this.cfg.protocols.dns) return // disabled in config for (const zone of conf_providers) { try { const res = await this.get_dns_results(zone, test_ip) if (!res) { - this.logerror(this, `${zone} failed`); - continue; + this.logerror(this, `${zone} failed`) + continue } - this.logdebug(this, `${zone} succeeded`); + this.logdebug(this, `${zone} succeeded`) - if (!providers.includes(zone)) providers.push(zone); - if (this.registered) continue; - this.registered = true; - this.register_hook('lookup_rdns', 'lookup_via_dns'); - } - catch (err) { - this.logerror(this, `zone ${zone} encountered ${err.message}`); + if (!providers.includes(zone)) providers.push(zone) + if (this.registered) continue + this.registered = true + this.register_hook('lookup_rdns', 'lookup_via_dns') + } catch (err) { + this.logerror(this, `zone ${zone} encountered ${err.message}`) } } return providers } exports.load_asn_ini = function () { - const plugin = this; - plugin.cfg = plugin.config.get('asn.ini', { - booleans: [ - '+header.asn', - '-header.provider', - '+protocols.dns', - '+protocols.geoip', - ] - }, - function () { - plugin.load_asn_ini(); - }); - - const c = plugin.cfg; + const plugin = this + plugin.cfg = plugin.config.get( + 'asn.ini', + { + booleans: [ + '+header.asn', + '-header.provider', + '+protocols.dns', + '+protocols.geoip', + ], + }, + function () { + plugin.load_asn_ini() + }, + ) + + const c = plugin.cfg if (c.main.providers !== undefined) { if (c.main.providers === '') { - conf_providers = []; - } - else { - conf_providers = c.main.providers.split(/[\s,;]+/); + conf_providers = [] + } else { + conf_providers = c.main.providers.split(/[\s,;]+/) } } - if (c.main.test_ip) test_ip = c.main.test_ip; - - // backwards compat with old config settings (Sunset 3.0) - if (c.main.asn_header !== undefined) c.header.asn = c.main.asn_header; - if (c.main.provider_header !== undefined) c.header.provider = c.main.provider_header; + if (c.main.test_ip) test_ip = c.main.test_ip } exports.get_dns_results = async function (zone, ip) { - const query = `${ip.split('.').reverse().join('.')}.${zone}`; + const query = `${ip.split('.').reverse().join('.')}.${zone}` const timeout = (prom, time, exception) => { - let timer; + let timer return Promise.race([ prom, - new Promise((_r, rej) => timer = setTimeout(rej, time, exception)) - ]).finally(() => clearTimeout(timer)); + new Promise((_r, rej) => (timer = setTimeout(rej, time, exception))), + ]).finally(() => clearTimeout(timer)) } try { const addrs = await timeout( dns.resolveTxt(query), (this.cfg.main.timeout || 4) * 1000, - new Error(`${zone} timeout`) - ); + new Error(`${zone} timeout`), + ) if (!addrs || !addrs[0]) { - this.logerror(this, `no results for ${query}`); + this.logerror(this, `no results for ${query}`) return } - const first = addrs[0]; + const first = addrs[0] - this.logdebug(this, `${zone} answers: ${first}`); + this.logdebug(this, `${zone} answers: ${first}`) - return this.get_result(zone, first); - } - catch (err) { - this.logerror(this, `error: ${err} running: ${query}`); + return this.get_result(zone, first) + } catch (err) { + this.logerror(this, `error: ${err} running: ${query}`) } - } exports.get_result = function (zone, first) { - switch (zone) { - case 'origin.asn.cymru.com' : return this.parse_cymru(first.join('')); - case 'asn.routeviews.org' : return this.parse_routeviews(first); - case 'asn.rspamd.com' : return this.parse_rspamd(first.join('')); - case 'origin.asn.spameatingmonkey.net': return this.parse_monkey(first.join('')); + case 'origin.asn.cymru.com': + return this.parse_cymru(first.join('')) + case 'asn.routeviews.org': + return this.parse_routeviews(first) + case 'asn.rspamd.com': + return this.parse_rspamd(first.join('')) + case 'origin.asn.spameatingmonkey.net': + return this.parse_monkey(first.join('')) } - this.logerror(this, `unrecognized ASN provider: ${zone}`); - return; + this.logerror(this, `unrecognized ASN provider: ${zone}`) + return } exports.lookup_via_dns = function (next, connection) { - const plugin = this; - if (connection.remote.is_private) return next(); + if (connection.remote.is_private) return next() const promises = [] for (const zone of providers) { - promises.push(new Promise(resolve => { - // connection.logdebug(plugin, `zone: ${zone}`); - - try { - - plugin.get_dns_results(zone, connection.remote.ip).then(r => { - if (!r) return resolve(); - - const results = { emit: true }; - - // store asn & net from any source - if (r.asn) results.asn = r.asn; - if (r.net) results.net = r.net; - - // store provider specific results - switch (zone) { - case 'origin.asn.cymru.com': - results.cymru = r; - break; - case 'asn.routeviews.org': - results.routeviews = r; - break; - case 'origin.asn.spameatingmonkey.net': - results.monkey = r; - break; - case 'asn.rspamd.com': - results.rspamd = r; - break; - } - - connection.results.add(plugin, results); - resolve(results); - }) - } - catch (err) { - connection.results.add(plugin, { err }) - resolve(); - } - })) + promises.push( + new Promise((resolve) => { + // connection.logdebug(plugin, `zone: ${zone}`); + + try { + this.get_dns_results(zone, connection.remote.ip).then((r) => { + if (!r) return resolve() + + const results = { emit: true } + + // store asn & net from any source + if (r.asn) results.asn = r.asn + if (r.net) results.net = r.net + + // store provider specific results + switch (zone) { + case 'origin.asn.cymru.com': + results.cymru = r + break + case 'asn.routeviews.org': + results.routeviews = r + break + case 'origin.asn.spameatingmonkey.net': + results.monkey = r + break + case 'asn.rspamd.com': + results.rspamd = r + break + } + + connection.results.add(this, results) + resolve(results) + }) + } catch (err) { + connection.results.add(this, { err }) + resolve() + } + }), + ) } Promise.all(promises).then(next) } exports.parse_routeviews = function (thing) { - let labels; + let labels if (typeof thing === 'string' && /,/.test(thing)) { - labels = thing.split(','); - return { asn: labels[0], net: `${labels[1]}/${labels[2]}` }; + labels = thing.split(',') + return { asn: labels[0], net: `${labels[1]}/${labels[2]}` } } // this is a correct result (node >= 0.10.26) // 99.177.75.208.asn.routeviews.org. IN TXT "40431" "208.75.176.0" "21" if (Array.isArray(thing)) { - labels = thing; - } - else { + labels = thing + } else { // this is what node (< 0.10.26) returns // 99.177.75.208.asn.routeviews.org. IN TXT "40431208.75.176.021" - labels = thing.split(/ /); + labels = thing.split(/ /) } if (labels.length !== 3) { - this.logerror(this, `result length not 3: ${labels.length} string="${thing}"`); - return; + this.logerror( + this, + `result length not 3: ${labels.length} string="${thing}"`, + ) + return } - return { asn: labels[0], net: `${labels[1]}/${labels[2]}` }; + return { asn: labels[0], net: `${labels[1]}/${labels[2]}` } } exports.parse_cymru = function (str) { - const r = str.split(/\s+\|\s*/); + const r = str.split(/\s+\|\s*/) // 99.177.75.208.origin.asn.cymru.com. 14350 IN TXT // "40431 | 208.75.176.0/21 | US | arin | 2007-03-02" // "10290 | 12.129.48.0/24 | US | arin |" if (r.length < 4) { - this.logerror(this, `cymru: bad result length ${r.length} string="${str}"`); - return; + this.logerror(this, `cymru: bad result length ${r.length} string="${str}"`) + return } - return { asn: r[0], net: r[1], country: r[2], assignor: r[3], date: r[4] }; + return { asn: r[0], net: r[1], country: r[2], assignor: r[3], date: r[4] } } exports.parse_monkey = function (str) { - const plugin = this; - const r = str.split(/\s+\|\s+/); + const plugin = this + const r = str.split(/\s+\|\s+/) // "74.125.44.0/23 | AS15169 | Google Inc. | 2000-03-30" // "74.125.0.0/16 | AS15169 | Google Inc. | 2000-03-30 | US" if (r.length < 3) { - plugin.logerror(plugin, `monkey: bad result length ${r.length} string="${str}"`); - return; + plugin.logerror( + plugin, + `monkey: bad result length ${r.length} string="${str}"`, + ) + return } return { asn: r[1].substring(2), @@ -234,81 +239,81 @@ exports.parse_monkey = function (str) { org: r[2], date: r[3], country: r[4], - }; + } } exports.parse_rspamd = function (str) { - const plugin = this; - const r = str.split(/\s*\|\s*/); + const plugin = this + const r = str.split(/\s*\|\s*/) // 8.8.8.8.asn.rspamd.com. 14350 IN TXT // "15169|8.8.8.0/24|US|arin|" if (r.length < 4) { - plugin.logerror(plugin, `rspamd: bad result length ${r.length} string="${str}"`); - return; + plugin.logerror( + plugin, + `rspamd: bad result length ${r.length} string="${str}"`, + ) + return } - return { asn: r[0], net: r[1], country: r[2], assignor: r[3], date: r[4] }; + return { asn: r[0], net: r[1], country: r[2], assignor: r[3], date: r[4] } } exports.add_header_asn = function (next, connection) { - - const asn = connection.results.get('asn'); - if (!asn?.asn) return next(); - if (!connection.transaction) return next(); + const asn = connection.results.get('asn') + if (!asn?.asn) return next() + if (!connection.transaction) return next() if (asn.net) { - connection.transaction.add_header('X-Haraka-ASN', `${asn.asn} ${asn.net}`); - } - else { - connection.transaction.add_header('X-Haraka-ASN', `${asn.asn}`); + connection.transaction.add_header('X-Haraka-ASN', `${asn.asn} ${asn.net}`) + } else { + connection.transaction.add_header('X-Haraka-ASN', `${asn.asn}`) } if (asn.org) { - connection.transaction.add_header('X-Haraka-ASN-Org', `${asn.org}`); + connection.transaction.add_header('X-Haraka-ASN-Org', `${asn.org}`) } - next(); + next() } exports.add_header_provider = function (next, connection) { - - const asn = connection.results.get('asn'); - if (!asn?.asn) return next(); + const asn = connection.results.get('asn') + if (!asn?.asn) return next() for (const p in asn) { - if (!asn[p].asn) continue; // ignore non-object results + if (!asn[p].asn) continue // ignore non-object results - const name = `X-Haraka-ASN-${p.toUpperCase()}`; - const values = []; + const name = `X-Haraka-ASN-${p.toUpperCase()}` + const values = [] for (const k in asn[p]) { - values.push(`${k}=${asn[p][k]}`); + values.push(`${k}=${asn[p][k]}`) } - if (values.length === 0) continue; - connection.transaction.add_header(name, values.join(' ')); + if (values.length === 0) continue + connection.transaction.add_header(name, values.join(' ')) } - next(); + next() } exports.test_and_register_geoip = async function () { - if (!this.cfg.protocols.geoip) return; // disabled in config + if (!this.cfg.protocols.geoip) return // disabled in config try { - this.maxmind = require('maxmind'); + this.maxmind = require('maxmind') if (await this.load_dbs()) { - this.register_hook('connect', 'lookup_via_maxmind'); + this.register_hook('connect', 'lookup_via_maxmind') } - } - catch (e) { - this.logerror(e); - this.logerror("unable to load maxmind, try\n\n\t'npm install -g maxmind@0.6'\n\n"); + } catch (e) { + this.logerror(e) + this.logerror( + "unable to load maxmind, try\n\n\t'npm install -g maxmind@0.6'\n\n", + ) } } exports.load_dbs = async function () { - - this.dbsLoaded = 0; - const dbdir = this.cfg.main.dbdir || '/usr/local/share/GeoIP/'; - const dbPath = path.join(dbdir, `GeoLite2-ASN.mmdb`); + this.dbsLoaded = 0 + const dbdir = this.cfg.main.dbdir || '/usr/local/share/GeoIP/' + const dbPath = path.join(dbdir, `GeoLite2-ASN.mmdb`) try { await fs.access(dbPath) @@ -318,14 +323,13 @@ exports.load_dbs = async function () { watchForUpdates: true, cache: { max: 1000, // max items in cache - maxAge: 1000 * 60 * 60 // life time in milliseconds - } + maxAge: 1000 * 60 * 60, // life time in milliseconds + }, }) - this.loginfo(`loaded maxmind db ${dbPath}`); - this.dbsLoaded++; - } - catch (e) { + this.loginfo(`loaded maxmind db ${dbPath}`) + this.dbsLoaded++ + } catch (e) { console.error(e) this.loginfo(`missing [access to] DB ${dbPath}`) } @@ -334,15 +338,19 @@ exports.load_dbs = async function () { } exports.lookup_via_maxmind = function (next, connection) { - if (!this.maxmind || !this.dbsLoaded) return next(); + if (!this.maxmind || !this.dbsLoaded) return next() const asn = this.lookup.get(connection.remote.ip) if (asn?.autonomous_system_number || asn?.autonomous_system_organization) { connection.results.add(this, { - ...(asn.autonomous_system_number ? { asn: asn.autonomous_system_number } : {}), - ...(asn.autonomous_system_organization ? { org: asn.autonomous_system_organization } : {}), - }); + ...(asn.autonomous_system_number + ? { asn: asn.autonomous_system_number } + : {}), + ...(asn.autonomous_system_organization + ? { org: asn.autonomous_system_organization } + : {}), + }) } - next(); + next() } diff --git a/package.json b/package.json index 425d9cd..49e297a 100644 --- a/package.json +++ b/package.json @@ -1,13 +1,21 @@ { "name": "haraka-plugin-asn", - "version": "2.0.2", + "version": "2.0.3", "description": "look up ASN of remote MTA", "main": "index.js", + "files": [ + "CHANGELOG.md", + "config" + ], "scripts": { - "test": "npx mocha --exit", - "lint": "npx eslint *.js test", - "lintfix": "npx eslint --fix *.js test", - "versions": "npx dependency-version-checker check" + "format": "npm run prettier:fix && npm run lint:fix", + "lint": "npx eslint@^8 *.js test", + "lint:fix": "npx eslint@^8 *.js test --fix", + "prettier": "npx prettier . --check", + "prettier:fix": "npx prettier . --write --log-level=warn", + "test": "npx mocha@^10 --exit", + "versions": "npx dependency-version-checker check", + "versions:fix": "npx dependency-version-checker update" }, "repository": { "type": "git", @@ -26,12 +34,10 @@ }, "homepage": "https://github.com/haraka/haraka-plugin-asn#readme", "dependencies": { - "maxmind": "^4.3.6" + "maxmind": "^4.3.19" }, "devDependencies": { - "eslint": ">=8", - "eslint-plugin-haraka": ">=1.0.14", - "haraka-test-fixtures": ">=1.0.34", - "mocha": ">=9" + "@haraka/eslint-config": "^1.1.5", + "haraka-test-fixtures": "^1.3.7" } } diff --git a/test/asn.js b/test/asn.js index 28f7f83..874209b 100644 --- a/test/asn.js +++ b/test/asn.js @@ -1,191 +1,194 @@ -'use strict'; +'use strict' -// node build-in modules -const assert = require('assert'); +const assert = require('node:assert') // npm installed modules -const fixtures = require('haraka-test-fixtures'); +const fixtures = require('haraka-test-fixtures') describe('parse_monkey', function () { - - const asn = new fixtures.plugin('asn'); + const asn = new fixtures.plugin('asn') it('parses AS 15169/23', function () { assert.deepEqual( asn.parse_monkey('74.125.44.0/23 | AS15169 | Google Inc. | 2000-03-30'), - { net: '74.125.44.0/23', asn: '15169', org: 'Google Inc.', - date: '2000-03-30', country: undefined, - } + { + net: '74.125.44.0/23', + asn: '15169', + org: 'Google Inc.', + date: '2000-03-30', + country: undefined, + }, ) }) it('parses AS 15169/16', function () { assert.deepEqual( - asn.parse_monkey('74.125.0.0/16 | AS15169 | Google Inc. | 2000-03-30 | US'), - { net: '74.125.0.0/16', asn: '15169', org: 'Google Inc.', - date: '2000-03-30', country: 'US', - } + asn.parse_monkey( + '74.125.0.0/16 | AS15169 | Google Inc. | 2000-03-30 | US', + ), + { + net: '74.125.0.0/16', + asn: '15169', + org: 'Google Inc.', + date: '2000-03-30', + country: 'US', + }, ) }) }) describe('parse_routeviews', function () { - - const asn = new fixtures.plugin('asn'); + const asn = new fixtures.plugin('asn') it('40431 string, asn-only', function () { - assert.deepEqual( - asn.parse_routeviews('40431'), - undefined - ) + assert.deepEqual(asn.parse_routeviews('40431'), undefined) }) it('40431 string', function () { - assert.deepEqual( - asn.parse_routeviews('40431 208.75.176.0 21'), - { - asn: '40431', net: '208.75.176.0/21', - } - ); - }); + assert.deepEqual(asn.parse_routeviews('40431 208.75.176.0 21'), { + asn: '40431', + net: '208.75.176.0/21', + }) + }) it('15169 CSV string', function () { - assert.deepEqual( - asn.parse_routeviews('15169,8.8.8.0,24'), { asn: '15169', net: '8.8.8.0/24' } - ) + assert.deepEqual(asn.parse_routeviews('15169,8.8.8.0,24'), { + asn: '15169', + net: '8.8.8.0/24', + }) }) it('40431 array', function () { - assert.deepEqual( - asn.parse_routeviews(['40431','208.75.176.0','21']), - { asn: '40431', net: '208.75.176.0/21' } - ) + assert.deepEqual(asn.parse_routeviews(['40431', '208.75.176.0', '21']), { + asn: '40431', + net: '208.75.176.0/21', + }) }) }) describe('parse_cymru', function () { - - const asn = new fixtures.plugin('asn'); + const asn = new fixtures.plugin('asn') it('40431', function () { assert.deepEqual( asn.parse_cymru('40431 | 208.75.176.0/21 | US | arin | 2007-03-02'), - { asn: '40431', net: '208.75.176.0/21', country: 'US', - assignor: 'arin', date: '2007-03-02', - } - ); - }); + { + asn: '40431', + net: '208.75.176.0/21', + country: 'US', + assignor: 'arin', + date: '2007-03-02', + }, + ) + }) it('10290', function () { - assert.deepEqual( - asn.parse_cymru('10290 | 12.129.48.0/24 | US | arin |'), - { asn: '10290', net: '12.129.48.0/24', country: 'US', - assignor: 'arin', date: '', - } - ) + assert.deepEqual(asn.parse_cymru('10290 | 12.129.48.0/24 | US | arin |'), { + asn: '10290', + net: '12.129.48.0/24', + country: 'US', + assignor: 'arin', + date: '', + }) }) }) describe('parse_rspamd', function () { - - const asn = new fixtures.plugin('asn'); + const asn = new fixtures.plugin('asn') it('40431', function () { - assert.deepEqual( - asn.parse_rspamd('15169|8.8.8.0/24|US|arin|'), - { - asn: '15169', net: '8.8.8.0/24', country: 'US', - assignor: 'arin', date: '', - } - ) + assert.deepEqual(asn.parse_rspamd('15169|8.8.8.0/24|US|arin|'), { + asn: '15169', + net: '8.8.8.0/24', + country: 'US', + assignor: 'arin', + date: '', + }) }) }) describe('get_dns_results', function () { - - const asn = new fixtures.plugin('asn'); - asn.cfg = { main: { }, protocols: { dns: true } }; - asn.connection = fixtures.connection.createConnection(); + const asn = new fixtures.plugin('asn') + asn.cfg = { main: {}, protocols: { dns: true } } + asn.connection = fixtures.connection.createConnection() it('origin.asn.cymru.com', function (done) { - this.timeout(4000) - asn.get_dns_results('origin.asn.cymru.com', '8.8.8.8').then(obj => { + this.timeout(5000) + asn.get_dns_results('origin.asn.cymru.com', '8.8.8.8').then((obj) => { if (obj) { - assert.equal('15169', obj.asn); - assert.equal('8.8.8.0/24', obj.net); - } - else { - assert.equal('something', obj); + assert.equal('15169', obj.asn) + assert.equal('8.8.8.0/24', obj.net) + } else { + assert.equal('something', obj) } - done(); + done() }) }) it('asn.routeviews.org', function (done) { - asn.get_dns_results('asn.routeviews.org', '8.8.8.8').then(obj => { + this.timeout(5000) + asn.get_dns_results('asn.routeviews.org', '8.8.8.8').then((obj) => { if (obj) { if (obj.asn && obj.asn === '15169') { - assert.equal('15169', obj.asn); + assert.equal('15169', obj.asn) } + } else { + assert.ok('Node DNS (c-ares) bug') } - else { - assert.ok("Node DNS (c-ares) bug"); - } - done(); - }); - }); + done() + }) + }) it('asn.rspamd.com', function (done) { - this.timeout(3000); + this.timeout(5000) asn.get_dns_results('asn.rspamd.com', '8.8.8.8').then((obj, zone) => { if (obj) { - assert.equal('15169', obj.asn); - assert.equal('8.8.8.0/24', obj.net); + assert.equal('15169', obj.asn) + assert.equal('8.8.8.0/24', obj.net) + } else { + assert.equal('something', obj) } - else { - assert.equal('something', obj); - } - done(); + done() }) }) it('origin.asn.spameatingmonkey.net', (done) => { - this.timeout(3000); - asn.get_dns_results('origin.asn.spameatingmonkey.net', '8.8.8.8').then((obj, zone) => { - if (obj) { - assert.equal('15169', obj.asn); - assert.equal('8.8.8.0/24', obj.net); - } - else { - assert.equal('something', obj); - } - done(); - }) + this.timeout(5000) + asn + .get_dns_results('origin.asn.spameatingmonkey.net', '8.8.8.8') + .then((obj, zone) => { + if (obj) { + assert.equal('15169', obj.asn) + assert.equal('8.8.8.0/24', obj.net) + } else { + assert.equal('something', obj) + } + done() + }) }) }) describe('lookup_via_dns', function () { it('returns results from active providers', function (done) { - const asn = new fixtures.plugin('asn'); - asn.cfg = { main: { }, protocols: { dns: true } }; - const connection = fixtures.connection.createConnection(); - connection.remote.ip='66.128.51.163'; + this.timeout(5000) + const asn = new fixtures.plugin('asn') + asn.cfg = { main: {}, protocols: { dns: true } } + const connection = fixtures.connection.createConnection() + connection.remote.ip = '66.128.51.163' asn.test_and_register_dns_providers().then((providers) => { asn.lookup_via_dns((r) => { assert.ok(r.length) done() - }, - connection) + }, connection) }) }) }) describe('maxmind geoip db', () => { - it('test_and_register_geoip', (done) => { - const asn = new fixtures.plugin('asn'); - asn.cfg = { main: { }, protocols: { geoip: true } }; + const asn = new fixtures.plugin('asn') + asn.cfg = { main: {}, protocols: { geoip: true } } asn.test_and_register_geoip().then((r) => { // console.log(r) assert.ok(asn.maxmind) @@ -194,44 +197,40 @@ describe('maxmind geoip db', () => { }) it('lookup_via_maxmind, IPv4', (done) => { - const asn = new fixtures.plugin('asn'); - asn.cfg = { main: { }, protocols: { geoip: true } }; - asn.connection = fixtures.connection.createConnection(); - asn.connection.remote.ip='8.8.8.8'; + const asn = new fixtures.plugin('asn') + asn.cfg = { main: {}, protocols: { geoip: true } } + asn.connection = fixtures.connection.createConnection() + asn.connection.remote.ip = '8.8.8.8' asn.test_and_register_geoip().then(() => { asn.lookup_via_maxmind(() => { if (asn.dbsLoaded) { - const res = asn.connection.results.get('asn'); - assert.equal(res.asn, 15169); - assert.equal(res.org, 'GOOGLE'); - } - else { - console.error('no DBs found'); + const res = asn.connection.results.get('asn') + assert.equal(res.asn, 15169) + assert.equal(res.org, 'GOOGLE') + } else { + console.error('no DBs found') } - done(); - }, - asn.connection); + done() + }, asn.connection) }) }) it('maxmind AS with org', (done) => { - const asn = new fixtures.plugin('asn'); - asn.cfg = { main: { }, protocols: { geoip: true } }; - asn.connection = fixtures.connection.createConnection(); - asn.connection.remote.ip='1.1.1.1'; + const asn = new fixtures.plugin('asn') + asn.cfg = { main: {}, protocols: { geoip: true } } + asn.connection = fixtures.connection.createConnection() + asn.connection.remote.ip = '1.1.1.1' asn.test_and_register_geoip().then(() => { try { asn.lookup_via_maxmind(() => { if (asn.dbsLoaded) { - const res = asn.connection.results.get('asn'); - assert.equal(res?.asn, 13335); - assert.equal(res?.org, 'CLOUDFLARENET'); + const res = asn.connection.results.get('asn') + assert.equal(res?.asn, 13335) + assert.equal(res?.org, 'CLOUDFLARENET') } done() - }, - asn.connection); - } - catch (e) { + }, asn.connection) + } catch (e) { console.error(e) done() }