From 43dd71bfdfa5f834b658e385ea99e44e4f8cc316 Mon Sep 17 00:00:00 2001 From: Alessio Onori Date: Fri, 9 Sep 2022 17:46:04 +0200 Subject: [PATCH 1/5] added ibm xforce integration --- package.json | 1 + src/actions/start.ts | 36 ++++++++- src/prometheus.ts | 11 ++- src/types.ts | 8 +- yarn.lock | 186 ++++++++++++++++++++++++++++++++++++++++++- 5 files changed, 235 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index abffae2..608f8ce 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,7 @@ "cloudflare": "^2.9.1", "commander": "^4.0.0", "express": "^4.18.1", + "got": "^11", "node-virustotal": "^3.35.0", "prom-client": "^14.0.1" }, diff --git a/src/actions/start.ts b/src/actions/start.ts index 29b9183..1dc3250 100644 --- a/src/actions/start.ts +++ b/src/actions/start.ts @@ -6,7 +6,8 @@ import { register } from 'prom-client'; import { InputConfig } from '../types'; import { evalIntervalMinutes } from '../constants'; import vt from 'node-virustotal' -import Cloudflare = require('cloudflare') +import cloudflare from 'cloudflare' +import got from 'got' const logger = LoggerSingleton.getInstance() @@ -23,20 +24,46 @@ function lookup(vtApi: any, promClient: Prometheus, domain: string){ const parsed = JSON.parse(res) const reports = parsed.data.attributes.last_analysis_stats.malicious + parsed.data.attributes.last_analysis_stats.suspicious logger.info(`${domain} reports: ${reports}`); - promClient.setVTReports(domain,reports) + promClient.setVTReport(domain,reports) return; }) logger.debug(`lookup for the domain ${domain} DONE`) } +async function ibmLookup(apiToken: string, apiPassword: string ,promClient: Prometheus, domain: string){ + logger.debug(`triggering a ibm lookup for the domain ${domain}`) + const url = `https://api.xforce.ibmcloud.com/api/url/${domain}`; + const options = { + headers: { + 'accept': 'application/json', + 'Authorization': 'Basic ZGQ0YTM0OGEtZmYzNy00YWZjLWEyMWItMDI3MzE0OWYxZDY3OjRmOTQ1YmRiLTk2MTYtNDY3My05YWY4LWUyNDI1OTllODc1NA==' + }, + }; + + try { + const response: any = await got(url,options).json(); + const score: number = response.result.score + logger.info(`${domain} ibm score, 1 is good: ${score}`); + promClient.setIbmScore(domain,score) + + } catch (error) { + logger.error(`Error on ibm processing ${domain}`); + logger.error(error); + process.exit(-1) + } + + logger.debug(`lookup for the domain ${domain} DONE`) +} + export async function startAction(cmd): Promise { const cfg = new Config().parse(cmd.config); LoggerSingleton.setInstance(cfg.logLevel) const domainsSet = new Set() + if(cfg.targetDomains.cloudflare.enabled){ - const cf = new Cloudflare({ + const cf = cloudflare({ token: cfg.targetDomains.cloudflare.apiKey }); @@ -56,7 +83,7 @@ export async function startAction(cmd): Promise { manualList.forEach(domain=>domainsSet.add(domain)) const targetDomains = Array.from( domainsSet.values() ) - logger.debug(targetDomains.toString()) + logger.info(targetDomains.toString()) const server = express(); server.get('/healthcheck', @@ -77,6 +104,7 @@ export async function startAction(cmd): Promise { setInterval( () => targetDomains.forEach(domain => { lookup(api,promClient,domain) + if(cfg.ibmXforce.enabled) ibmLookup(cfg.ibmXforce.apiToken,cfg.ibmXforce.apiPassword,promClient,domain) }), evalInterval ) diff --git a/src/prometheus.ts b/src/prometheus.ts index 357c82a..692de58 100644 --- a/src/prometheus.ts +++ b/src/prometheus.ts @@ -5,6 +5,7 @@ import { PromClient } from './types'; export class Prometheus implements PromClient { private virustotalReports: promClient.Gauge<"domain">; + private IbmScore: promClient.Gauge<"domain">; private readonly logger: Logger = LoggerSingleton.getInstance() @@ -21,9 +22,12 @@ export class Prometheus implements PromClient { promClient.collectDefaultMetrics(); } - setVTReports(domain: string, reports: number): void{ + setVTReport(domain: string, reports: number): void{ this.virustotalReports.set({domain}, reports); } + setIbmScore(domain: string, score: number): void{ + this.IbmScore.set({domain}, score); + } _initMetrics(): void { this.virustotalReports = new promClient.Gauge({ @@ -31,5 +35,10 @@ export class Prometheus implements PromClient { help: 'Virustotal bad status report for a specific domain', labelNames: ['domain'] }); + this.virustotalReports = new promClient.Gauge({ + name: 'ibm_xforce_score', + help: 'Ibm xforce score for a specific domain, 1 is good', + labelNames: ['domain'] + }); } } diff --git a/src/types.ts b/src/types.ts index 30aa921..f5c88bd 100644 --- a/src/types.ts +++ b/src/types.ts @@ -13,8 +13,14 @@ export interface InputConfig { virusTotal: { apiKey: string; }; + ibmXforce: { + enabled: boolean; + apiToken: string; + apiPassword: string; + }; } export interface PromClient { - setVTReports(domain: string, reports: number): void; + setVTReport(domain: string, reports: number): void; + setIbmScore(domain: string, score: number): void; } \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index d535f7d..6aa8ed3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -91,6 +91,18 @@ "@jridgewell/resolve-uri" "^3.0.3" "@jridgewell/sourcemap-codec" "^1.4.10" +"@sindresorhus/is@^4.0.0": + version "4.6.0" + resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-4.6.0.tgz#3c7c9c46e678feefe7a2e5bb609d3dbd665ffb3f" + integrity sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw== + +"@szmarczak/http-timer@^4.0.5": + version "4.0.6" + resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-4.0.6.tgz#b4a914bb62e7c272d4e5989fe4440f812ab1d807" + integrity sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w== + dependencies: + defer-to-connect "^2.0.0" + "@tsconfig/node10@^1.0.7": version "1.0.9" resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.9.tgz#df4907fc07a886922637b15e02d4cebc4c0021b2" @@ -119,6 +131,16 @@ "@types/connect" "*" "@types/node" "*" +"@types/cacheable-request@^6.0.1": + version "6.0.2" + resolved "https://registry.yarnpkg.com/@types/cacheable-request/-/cacheable-request-6.0.2.tgz#c324da0197de0a98a2312156536ae262429ff6b9" + integrity sha512-B3xVo+dlKM6nnKTcmm5ZtY/OL8bOAOd2Olee9M1zft65ox50OzjEHW91sDiU9j6cvW8Ejg1/Qkf4xd2kugApUA== + dependencies: + "@types/http-cache-semantics" "*" + "@types/keyv" "*" + "@types/node" "*" + "@types/responselike" "*" + "@types/connect@*": version "3.4.35" resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.35.tgz#5fcf6ae445e4021d1fc2219a4873cc73a3bb2ad1" @@ -150,11 +172,23 @@ "@types/qs" "*" "@types/serve-static" "*" +"@types/http-cache-semantics@*": + version "4.0.1" + resolved "https://registry.yarnpkg.com/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz#0ea7b61496902b95890dc4c3a116b60cb8dae812" + integrity sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ== + "@types/json-schema@^7.0.3": version "7.0.11" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.11.tgz#d421b6c527a3037f7c84433fd2c4229e016863d3" integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ== +"@types/keyv@*": + version "3.1.4" + resolved "https://registry.yarnpkg.com/@types/keyv/-/keyv-3.1.4.tgz#3ccdb1c6751b0c7e52300bcdacd5bcbf8faa75b6" + integrity sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg== + dependencies: + "@types/node" "*" + "@types/mime@*": version "3.0.1" resolved "https://registry.yarnpkg.com/@types/mime/-/mime-3.0.1.tgz#5f8f2bca0a5863cb69bc0b0acd88c96cb1d4ae10" @@ -180,6 +214,13 @@ resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.4.tgz#cd667bcfdd025213aafb7ca5915a932590acdcdc" integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw== +"@types/responselike@*", "@types/responselike@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@types/responselike/-/responselike-1.0.0.tgz#251f4fe7d154d2bad125abe1b429b23afd262e29" + integrity sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA== + dependencies: + "@types/node" "*" + "@types/serve-static@*": version "1.15.0" resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.15.0.tgz#c7930ff61afb334e121a9da780aac0d9b8f34155" @@ -454,6 +495,24 @@ bytes@3.1.2: resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== +cacheable-lookup@^5.0.3: + version "5.0.4" + resolved "https://registry.yarnpkg.com/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz#5a6b865b2c44357be3d5ebc2a467b032719a7005" + integrity sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA== + +cacheable-request@^7.0.2: + version "7.0.2" + resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-7.0.2.tgz#ea0d0b889364a25854757301ca12b2da77f91d27" + integrity sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew== + dependencies: + clone-response "^1.0.2" + get-stream "^5.1.0" + http-cache-semantics "^4.0.0" + keyv "^4.0.0" + lowercase-keys "^2.0.0" + normalize-url "^6.0.1" + responselike "^2.0.0" + call-bind@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" @@ -499,6 +558,13 @@ chownr@^2.0.0: resolved "https://registry.yarnpkg.com/chownr/-/chownr-2.0.0.tgz#15bfbe53d2eab4cf70f18a8cd68ebe5b3cb1dece" integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ== +clone-response@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.3.tgz#af2032aa47816399cf5f0a1d0db902f517abb8c3" + integrity sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA== + dependencies: + mimic-response "^1.0.0" + cloudflare@^2.9.1: version "2.9.1" resolved "https://registry.yarnpkg.com/cloudflare/-/cloudflare-2.9.1.tgz#9911b2a9ee3bfc2fc4f239c1f991892667e26309" @@ -671,11 +737,23 @@ debug@4, debug@^4.0.1, debug@^4.1.1: dependencies: ms "2.1.2" +decompress-response@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc" + integrity sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ== + dependencies: + mimic-response "^3.1.0" + deep-is@^0.1.3: version "0.1.4" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== +defer-to-connect@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-2.0.1.tgz#8016bdb4143e4632b77a3449c6236277de520587" + integrity sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg== + delayed-stream@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" @@ -765,6 +843,13 @@ encoding@>=0.1.4, encoding@~0.1.12: dependencies: iconv-lite "^0.6.2" +end-of-stream@^1.1.0: + version "1.4.4" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" + integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== + dependencies: + once "^1.4.0" + enquirer@^2.3.5: version "2.3.6" resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" @@ -1090,6 +1175,13 @@ get-stream@^3.0.0: resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" integrity sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ== +get-stream@^5.1.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" + integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== + dependencies: + pump "^3.0.0" + getpass@^0.1.1: version "0.1.7" resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" @@ -1123,6 +1215,23 @@ globals@^13.6.0, globals@^13.9.0: dependencies: type-fest "^0.20.2" +got@^11: + version "11.8.5" + resolved "https://registry.yarnpkg.com/got/-/got-11.8.5.tgz#ce77d045136de56e8f024bebb82ea349bc730046" + integrity sha512-o0Je4NvQObAuZPHLFoRSkdG2lTgtcynqymzg2Vupdx6PorhaT5MCbIyXG6d4D94kk8ZG57QeosgdiqfJWhEhlQ== + dependencies: + "@sindresorhus/is" "^4.0.0" + "@szmarczak/http-timer" "^4.0.5" + "@types/cacheable-request" "^6.0.1" + "@types/responselike" "^1.0.0" + cacheable-lookup "^5.0.3" + cacheable-request "^7.0.2" + decompress-response "^6.0.0" + http2-wrapper "^1.0.0-beta.5.2" + lowercase-keys "^2.0.0" + p-cancelable "^2.0.0" + responselike "^2.0.0" + got@^6.3.0: version "6.7.1" resolved "https://registry.yarnpkg.com/got/-/got-6.7.1.tgz#240cd05785a9a18e561dc1b44b41c763ef1e8db0" @@ -1185,6 +1294,11 @@ has@^1.0.3: dependencies: function-bind "^1.1.1" +http-cache-semantics@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390" + integrity sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ== + http-errors@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" @@ -1205,6 +1319,14 @@ http-signature@~1.2.0: jsprim "^1.2.2" sshpk "^1.7.0" +http2-wrapper@^1.0.0-beta.5.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/http2-wrapper/-/http2-wrapper-1.0.3.tgz#b8f55e0c1f25d4ebd08b3b0c2c079f9590800b3d" + integrity sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg== + dependencies: + quick-lru "^5.1.1" + resolve-alpn "^1.0.0" + https-proxy-agent@^5.0.0: version "5.0.1" resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" @@ -1363,6 +1485,11 @@ jsbn@~0.1.0: resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" integrity sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg== +json-buffer@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" + integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== + json-schema-traverse@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" @@ -1405,6 +1532,13 @@ jsprim@^1.2.2: json-schema "0.4.0" verror "1.10.0" +keyv@^4.0.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.0.tgz#dbce9ade79610b6e641a9a65f2f6499ba06b9bc6" + integrity sha512-2YvuMsA+jnFGtBareKqgANOEKe1mk3HKiXu2fRmAfyxG0MJAywNhi5ttWA3PMjl4NmpyjZNbFifR2vNjW1znfA== + dependencies: + json-buffer "3.0.1" + kuler@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/kuler/-/kuler-2.0.0.tgz#e2c570a3800388fb44407e851531c1d670b061b3" @@ -1449,6 +1583,11 @@ lowercase-keys@^1.0.0: resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA== +lowercase-keys@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479" + integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA== + lru-cache@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" @@ -1525,6 +1664,16 @@ mimelib@>=0.2.17: addressparser "~1.0.1" encoding "~0.1.12" +mimic-response@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" + integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== + +mimic-response@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9" + integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ== + minimatch@^3.0.4, minimatch@^3.1.1: version "3.1.2" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" @@ -1597,6 +1746,11 @@ node-virustotal@^3.35.0: speedconcat "^1.0.2" tar ">=4.4.2" +normalize-url@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-6.1.0.tgz#40d0885b535deffe3f3147bec877d05fe4c5668a" + integrity sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A== + oauth-sign@~0.9.0: version "0.9.0" resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" @@ -1619,7 +1773,7 @@ on-finished@2.4.1: dependencies: ee-first "1.1.1" -once@^1.3.0: +once@^1.3.0, once@^1.3.1, once@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== @@ -1645,6 +1799,11 @@ optionator@^0.9.1: type-check "^0.4.0" word-wrap "^1.2.3" +p-cancelable@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-2.1.1.tgz#aab7fbd416582fa32a3db49859c122487c5ed2cf" + integrity sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg== + parent-module@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" @@ -1717,6 +1876,14 @@ psl@^1.1.28: resolved "https://registry.yarnpkg.com/psl/-/psl-1.9.0.tgz#d0df2a137f00794565fcaf3b2c00cd09f8d5a5a7" integrity sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag== +pump@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + punycode@^2.1.0, punycode@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" @@ -1734,6 +1901,11 @@ qs@~6.5.2: resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.3.tgz#3aeeffc91967ef6e35c0e488ef46fb296ab76aad" integrity sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA== +quick-lru@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932" + integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA== + ramda@^0.26.1: version "0.26.1" resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.26.1.tgz#8d41351eb8111c55353617fc3bbffad8e4d35d06" @@ -1816,6 +1988,11 @@ require-from-string@^2.0.2: resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== +resolve-alpn@^1.0.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/resolve-alpn/-/resolve-alpn-1.2.1.tgz#b7adbdac3546aaaec20b45e7d8265927072726f9" + integrity sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g== + resolve-from@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" @@ -1830,6 +2007,13 @@ resolve@^1.1.6: path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" +responselike@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/responselike/-/responselike-2.0.1.tgz#9a0bc8fdc252f3fb1cca68b016591059ba1422bc" + integrity sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw== + dependencies: + lowercase-keys "^2.0.0" + rimraf@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" From 6420b9e44e84a13d1102ca1c229a58a742a8bf29 Mon Sep 17 00:00:00 2001 From: Alessio Onori Date: Fri, 9 Sep 2022 18:15:34 +0200 Subject: [PATCH 2/5] fix --- src/actions/start.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/actions/start.ts b/src/actions/start.ts index 1dc3250..a4d4e16 100644 --- a/src/actions/start.ts +++ b/src/actions/start.ts @@ -36,7 +36,7 @@ async function ibmLookup(apiToken: string, apiPassword: string ,promClient: Prom const options = { headers: { 'accept': 'application/json', - 'Authorization': 'Basic ZGQ0YTM0OGEtZmYzNy00YWZjLWEyMWItMDI3MzE0OWYxZDY3OjRmOTQ1YmRiLTk2MTYtNDY3My05YWY4LWUyNDI1OTllODc1NA==' + 'Authorization': 'Basic xxx' }, }; From 4286cea0fc055c3bbfd28254eb3009db10bd9ebf Mon Sep 17 00:00:00 2001 From: Alessio Onori Date: Mon, 19 Sep 2022 11:26:33 +0200 Subject: [PATCH 3/5] implementation complete --- README.md | 24 +++- charts/virustotal-prometheus/Chart.yaml | 4 +- .../templates/alertrules.yaml | 10 +- charts/virustotal-prometheus/values.yaml | 4 + config/main.sample.yaml | 6 +- package.json | 2 +- src/actions/start.ts | 128 +++++++++++------- src/logger.ts | 7 +- src/prometheus.ts | 6 +- src/types.ts | 2 +- 10 files changed, 130 insertions(+), 63 deletions(-) diff --git a/README.md b/README.md index 94269d8..0259204 100644 --- a/README.md +++ b/README.md @@ -2,4 +2,26 @@ # virustotal-prometheus -Monitor VirusTotal reports and expose Prometheus metrics +App to monitor (mainly) VirusTotal reports and to expose Prometheus metrics. + +The application is K8s ready, and it provides also a ServiceMonitor and a PrometheusRule configurations that can be used by your Prometheus/Alertmanager. + +## Intelligence sources + +- VirusTotal +- IBM Xforce (optional) + +## Domain List + +It can be configured via a [config file](/config/main.sample.yaml). + +### Api sources for the domain list +- Cloudflare (optional): +the domain list can be dynamically enriched via Clodflare. Please set up this connection with a read-only apiKey. + +## How to Run + +``` +yarn +yarn start -c path_to_config_file +``` \ No newline at end of file diff --git a/charts/virustotal-prometheus/Chart.yaml b/charts/virustotal-prometheus/Chart.yaml index fba1654..89b7feb 100644 --- a/charts/virustotal-prometheus/Chart.yaml +++ b/charts/virustotal-prometheus/Chart.yaml @@ -1,5 +1,5 @@ description: Virustotal Prometheus name: virustotal-prometheus -version: v0.2.0 -appVersion: v0.2.0 +version: v0.3.0 +appVersion: v0.3.0 apiVersion: v2 diff --git a/charts/virustotal-prometheus/templates/alertrules.yaml b/charts/virustotal-prometheus/templates/alertrules.yaml index 1730d9e..e9967d3 100644 --- a/charts/virustotal-prometheus/templates/alertrules.yaml +++ b/charts/virustotal-prometheus/templates/alertrules.yaml @@ -23,5 +23,13 @@ spec: for: 2m labels: severity: warning - origin: {{ .Values.prometheusRules.origin }} + origin: {{ .Values.prometheusRules.origin }} + - alert: IbmXforceBadScore + annotations: + message: 'Domain {{`{{ $labels.domain }}`}} might have been flagged as problematic, please visit https://www.exchange.xforce.ibmcloud.com/url/{{`{{ $labels.domain }}`}} to doublecheck.' + expr: max without(instance,pod) (last_over_time(ibm_xforce_score[10m])) > 1 + for: 2m + labels: + severity: warning + origin: {{ .Values.prometheusRules.origin }} {{ end }} diff --git a/charts/virustotal-prometheus/values.yaml b/charts/virustotal-prometheus/values.yaml index 730564e..ec9f5f0 100644 --- a/charts/virustotal-prometheus/values.yaml +++ b/charts/virustotal-prometheus/values.yaml @@ -16,6 +16,10 @@ config: - example.com virusTotal: apiKey: secret + ibmXforce: + enabled: false + apiKey: xxx + apiPassword: xxx serviceMonitor: enabled: true diff --git a/config/main.sample.yaml b/config/main.sample.yaml index 80e43fb..5f8682d 100644 --- a/config/main.sample.yaml +++ b/config/main.sample.yaml @@ -8,4 +8,8 @@ targetDomains: manualList: - example.com virusTotal: - apiKey: secret \ No newline at end of file + apiKey: secret +ibmXforce: + enabled: false + apiKey: xxx + apiPassword: xxx \ No newline at end of file diff --git a/package.json b/package.json index 608f8ce..e5dc00c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "virustotal-prometheus", - "version": "0.2.0", + "version": "0.3.0", "description": "Monitor VirusTotal reports and expose Prometheus metrics", "repository": "git@github.com:w3f/report-scanner.git", "author": "W3F Infrastructure Team ", diff --git a/src/actions/start.ts b/src/actions/start.ts index a4d4e16..e0ebf8d 100644 --- a/src/actions/start.ts +++ b/src/actions/start.ts @@ -9,14 +9,26 @@ import vt from 'node-virustotal' import cloudflare from 'cloudflare' import got from 'got' -const logger = LoggerSingleton.getInstance() +interface lookupConfig { + vtApi: any; + ibmApiKey?: string; + ibmPassword?: string; + ibmEnabled: boolean; + promClient: Prometheus; +} + +var logger = LoggerSingleton.getInstance() +async function lookup(config: lookupConfig, domain: string): Promise { + vtLookup(config.vtApi,config.promClient,domain) + if(config.ibmEnabled) await ibmLookup(config.ibmApiKey,config.ibmPassword,config.promClient,domain) +} -function lookup(vtApi: any, promClient: Prometheus, domain: string){ - logger.debug(`triggering a lookup for the domain ${domain}`) +function vtLookup(vtApi: any, promClient: Prometheus, domain: string){ + logger.debug(`triggering a Virustotal lookup for the domain ${domain}`) vtApi.domainLookup(domain,function(err, res){ if (err) { - logger.error(`Error on processing ${domain}`); + logger.error(`Error on VT processing ${domain}`); logger.error(err); process.exit(-1) } @@ -25,87 +37,103 @@ function lookup(vtApi: any, promClient: Prometheus, domain: string){ const reports = parsed.data.attributes.last_analysis_stats.malicious + parsed.data.attributes.last_analysis_stats.suspicious logger.info(`${domain} reports: ${reports}`); promClient.setVTReport(domain,reports) - return; + logger.debug(`VT lookup for the domain ${domain} DONE`) }) - logger.debug(`lookup for the domain ${domain} DONE`) } -async function ibmLookup(apiToken: string, apiPassword: string ,promClient: Prometheus, domain: string){ - logger.debug(`triggering a ibm lookup for the domain ${domain}`) +async function ibmLookup(apiKey: string, apiPassword: string ,promClient: Prometheus, domain: string){ + logger.debug(`triggering an IBM lookup for the domain ${domain}`) const url = `https://api.xforce.ibmcloud.com/api/url/${domain}`; + const options = { headers: { 'accept': 'application/json', - 'Authorization': 'Basic xxx' + 'Authorization': `Basic ${Buffer.from(`${apiKey}:${apiPassword}`).toString("base64")}` }, }; try { const response: any = await got(url,options).json(); - const score: number = response.result.score - logger.info(`${domain} ibm score, 1 is good: ${score}`); + logger.info(JSON.stringify(response)) + const score: number = response.result.score? response.result.score : 1 //unkown is treated as OK + logger.info(`${domain} ibm score, 1 is OK: ${score}`); promClient.setIbmScore(domain,score) - + logger.debug(`IBM lookup for the domain ${domain} DONE`) + } catch (error) { + const errorMessage: string = error.toString() + if(errorMessage.includes("404")){ + logger.warn(`IBM api is not capable of processing ${domain}`) + logger.warn(errorMessage); + } else{ + logger.error(`Error on IBM processing ${domain}`); + logger.error(error); + process.exit(-1) + } + } +} + +function configureServerEndpoints(server: express.Express): void { + server.get('/healthcheck', + async (req: express.Request, res: express.Response): Promise => { + res.status(200).send('OK!') + }) + server.get('/metrics', async (req: express.Request, res: express.Response) => { + res.set('Content-Type', register.contentType) + res.end(await register.metrics()) + }) +} + +async function cfAddDomains(apiKey: string, domains: Set): Promise { + const cf = cloudflare({ + token: apiKey + }); + + try { + const zones = await cf.zones.browse() + zones.result.forEach(element => { + domains.add(element.name) + }); } catch (error) { - logger.error(`Error on ibm processing ${domain}`); + logger.error(`Error on processing the clouflare api`); logger.error(error); process.exit(-1) } - - logger.debug(`lookup for the domain ${domain} DONE`) } export async function startAction(cmd): Promise { const cfg = new Config().parse(cmd.config); - LoggerSingleton.setInstance(cfg.logLevel) + logger = LoggerSingleton.getNewInstance(cfg.logLevel) const domainsSet = new Set() - if(cfg.targetDomains.cloudflare.enabled){ - const cf = cloudflare({ - token: cfg.targetDomains.cloudflare.apiKey - }); - - try { - const zones = await cf.zones.browse() - zones.result.forEach(element => { - domainsSet.add(element.name) - }); - } catch (error) { - logger.error(`Error on processing the clouflare api`); - logger.error(error); - process.exit(-1) - } + await cfAddDomains(cfg.targetDomains.cloudflare.apiKey,domainsSet) } - const manualList = cfg.targetDomains.manualList ? cfg.targetDomains.manualList : [] manualList.forEach(domain=>domainsSet.add(domain)) const targetDomains = Array.from( domainsSet.values() ) - - logger.info(targetDomains.toString()) + logger.info(`Target List: ${targetDomains.toString()}`) const server = express(); - server.get('/healthcheck', - async (req: express.Request, res: express.Response): Promise => { - res.status(200).send('OK!') - }) - server.get('/metrics', async (req: express.Request, res: express.Response) => { - res.set('Content-Type', register.contentType) - res.end(await register.metrics()) - }) + configureServerEndpoints(server) server.listen(cfg.port); - - const api = vt.makeAPI(); - api.setKey(cfg.virusTotal.apiKey) + const promClient = new Prometheus(); const evalInterval = cfg.evalIntervalMinutes? cfg.evalIntervalMinutes*1000*60 : evalIntervalMinutes - targetDomains.forEach(domain=>lookup(api,promClient,domain)) + + const vtApi = vt.makeAPI(); + vtApi.setKey(cfg.virusTotal.apiKey) + + const lookupConfig = { + vtApi: vtApi, + ibmApiKey: cfg.ibmXforce.apiKey, + ibmPassword: cfg.ibmXforce.apiPassword, + ibmEnabled: cfg.ibmXforce.enabled, + promClient: promClient + } + targetDomains.forEach(domain => lookup(lookupConfig,domain)) setInterval( - () => targetDomains.forEach(domain => { - lookup(api,promClient,domain) - if(cfg.ibmXforce.enabled) ibmLookup(cfg.ibmXforce.apiToken,cfg.ibmXforce.apiPassword,promClient,domain) - }), + () => targetDomains.forEach(domain => lookup(lookupConfig,domain)), evalInterval ) } diff --git a/src/logger.ts b/src/logger.ts index 2f5969d..528b2c5 100644 --- a/src/logger.ts +++ b/src/logger.ts @@ -5,15 +5,16 @@ export class LoggerSingleton { private constructor() { //do nothing } - public static setInstance(level: string): void { - LoggerSingleton.instance = createLogger(level) - } public static getInstance(level?: string): Logger { if (!LoggerSingleton.instance) { LoggerSingleton.instance = createLogger(level) } return LoggerSingleton.instance } + public static getNewInstance(level?: string): Logger { + LoggerSingleton.instance = createLogger(level) + return LoggerSingleton.instance + } } export type Logger = LoggerW3f diff --git a/src/prometheus.ts b/src/prometheus.ts index 692de58..7b9cb92 100644 --- a/src/prometheus.ts +++ b/src/prometheus.ts @@ -5,7 +5,7 @@ import { PromClient } from './types'; export class Prometheus implements PromClient { private virustotalReports: promClient.Gauge<"domain">; - private IbmScore: promClient.Gauge<"domain">; + private ibmScore: promClient.Gauge<"domain">; private readonly logger: Logger = LoggerSingleton.getInstance() @@ -26,7 +26,7 @@ export class Prometheus implements PromClient { this.virustotalReports.set({domain}, reports); } setIbmScore(domain: string, score: number): void{ - this.IbmScore.set({domain}, score); + this.ibmScore.set({domain}, score); } _initMetrics(): void { @@ -35,7 +35,7 @@ export class Prometheus implements PromClient { help: 'Virustotal bad status report for a specific domain', labelNames: ['domain'] }); - this.virustotalReports = new promClient.Gauge({ + this.ibmScore = new promClient.Gauge({ name: 'ibm_xforce_score', help: 'Ibm xforce score for a specific domain, 1 is good', labelNames: ['domain'] diff --git a/src/types.ts b/src/types.ts index f5c88bd..4f98e82 100644 --- a/src/types.ts +++ b/src/types.ts @@ -15,7 +15,7 @@ export interface InputConfig { }; ibmXforce: { enabled: boolean; - apiToken: string; + apiKey: string; apiPassword: string; }; } From 108b5cc144dc117a5060ac6ee0eeb84df84bd20c Mon Sep 17 00:00:00 2001 From: Alessio Onori Date: Mon, 19 Sep 2022 11:32:05 +0200 Subject: [PATCH 4/5] updated deps, fixed lint --- src/actions/start.ts | 22 +++++++++++----------- yarn.lock | 37 +++++++++++++++++++------------------ 2 files changed, 30 insertions(+), 29 deletions(-) diff --git a/src/actions/start.ts b/src/actions/start.ts index e0ebf8d..5ddf3a1 100644 --- a/src/actions/start.ts +++ b/src/actions/start.ts @@ -9,7 +9,7 @@ import vt from 'node-virustotal' import cloudflare from 'cloudflare' import got from 'got' -interface lookupConfig { +interface LookupConfig { vtApi: any; ibmApiKey?: string; ibmPassword?: string; @@ -17,14 +17,9 @@ interface lookupConfig { promClient: Prometheus; } -var logger = LoggerSingleton.getInstance() +let logger = LoggerSingleton.getInstance() -async function lookup(config: lookupConfig, domain: string): Promise { - vtLookup(config.vtApi,config.promClient,domain) - if(config.ibmEnabled) await ibmLookup(config.ibmApiKey,config.ibmPassword,config.promClient,domain) -} - -function vtLookup(vtApi: any, promClient: Prometheus, domain: string){ +function vtLookup(vtApi: any, promClient: Prometheus, domain: string): void { logger.debug(`triggering a Virustotal lookup for the domain ${domain}`) vtApi.domainLookup(domain,function(err, res){ if (err) { @@ -41,7 +36,7 @@ function vtLookup(vtApi: any, promClient: Prometheus, domain: string){ }) } -async function ibmLookup(apiKey: string, apiPassword: string ,promClient: Prometheus, domain: string){ +async function ibmLookup(apiKey: string, apiPassword: string ,promClient: Prometheus, domain: string): Promise { logger.debug(`triggering an IBM lookup for the domain ${domain}`) const url = `https://api.xforce.ibmcloud.com/api/url/${domain}`; @@ -54,7 +49,7 @@ async function ibmLookup(apiKey: string, apiPassword: string ,promClient: Promet try { const response: any = await got(url,options).json(); - logger.info(JSON.stringify(response)) + logger.debug(JSON.stringify(response)) const score: number = response.result.score? response.result.score : 1 //unkown is treated as OK logger.info(`${domain} ibm score, 1 is OK: ${score}`); promClient.setIbmScore(domain,score) @@ -63,7 +58,7 @@ async function ibmLookup(apiKey: string, apiPassword: string ,promClient: Promet const errorMessage: string = error.toString() if(errorMessage.includes("404")){ logger.warn(`IBM api is not capable of processing ${domain}`) - logger.warn(errorMessage); + logger.debug(errorMessage); } else{ logger.error(`Error on IBM processing ${domain}`); logger.error(error); @@ -72,6 +67,11 @@ async function ibmLookup(apiKey: string, apiPassword: string ,promClient: Promet } } +async function lookup(config: LookupConfig, domain: string): Promise { + vtLookup(config.vtApi,config.promClient,domain) + if(config.ibmEnabled) await ibmLookup(config.ibmApiKey,config.ibmPassword,config.promClient,domain) +} + function configureServerEndpoints(server: express.Express): void { server.get('/healthcheck', async (req: express.Request, res: express.Response): Promise => { diff --git a/yarn.lock b/yarn.lock index 6aa8ed3..8a47862 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10,9 +10,9 @@ "@babel/highlight" "^7.10.4" "@babel/helper-validator-identifier@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz#9c97e30d31b2b8c72a1d08984f2ca9b574d7a076" - integrity sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g== + version "7.19.1" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz#7eea834cf32901ffdc1a7ee555e2f9c27e249ca2" + integrity sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w== "@babel/highlight@^7.10.4": version "7.18.6" @@ -154,9 +154,9 @@ integrity sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag== "@types/express-serve-static-core@^4.17.18": - version "4.17.30" - resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.30.tgz#0f2f99617fa8f9696170c46152ccf7500b34ac04" - integrity sha512-gstzbTWro2/nFed1WXtf+TtrpwxH7Ggs4RLYTLbeVgIkUQOI3WG/JKjgeOU1zXDvezllupjrf8OPIdvTbIaVOQ== + version "4.17.31" + resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.31.tgz#a1139efeab4e7323834bb0226e62ac019f474b2f" + integrity sha512-DxMhY+NAsTwMMFHBTtJFNp5qiHKJ7TeqOo23zVEM9alT1Ml27Q3xcTH0xwxn7Q0BbMcVEJOs/7aQtUWupUQN3Q== dependencies: "@types/node" "*" "@types/qs" "*" @@ -195,9 +195,9 @@ integrity sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA== "@types/node@*": - version "18.7.14" - resolved "https://registry.yarnpkg.com/@types/node/-/node-18.7.14.tgz#0fe081752a3333392d00586d815485a17c2cf3c9" - integrity sha512-6bbDaETVi8oyIARulOE9qF1/Qdi/23z6emrUh0fNJRUmjznqrixD4MpGDdgOFk5Xb0m2H6Xu42JGdvAxaJR/wA== + version "18.7.18" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.7.18.tgz#633184f55c322e4fb08612307c274ee6d5ed3154" + integrity sha512-m+6nTEOadJZuTPkKR/SYK3A2d7FZrgElol9UP1Kae90VVU4a6mxnPuLiIW1m4Cq4gZ/nWb9GrdVXJCoCazDAbg== "@types/node@14.18.24": version "14.18.24" @@ -1162,9 +1162,9 @@ functional-red-black-tree@^1.0.1: integrity sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g== get-intrinsic@^1.0.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.2.tgz#336975123e05ad0b7ba41f152ee4aadbea6cf598" - integrity sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA== + version "1.1.3" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.3.tgz#063c84329ad93e83893c7f4f243ef63ffa351385" + integrity sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A== dependencies: function-bind "^1.1.1" has "^1.0.3" @@ -2027,9 +2027,9 @@ safe-buffer@5.2.1, safe-buffer@^5.0.1, safe-buffer@^5.1.2, safe-buffer@~5.2.0: integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== safe-stable-stringify@^2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/safe-stable-stringify/-/safe-stable-stringify-2.3.1.tgz#ab67cbe1fe7d40603ca641c5e765cb942d04fc73" - integrity sha512-kYBSfT+troD9cDA85VDnHZ1rpHC50O0g1e6WlGHVCz/g+JS+9WKLj+XwFYyR8UbrZN8ll9HUpDAAddY58MGisg== + version "2.4.0" + resolved "https://registry.yarnpkg.com/safe-stable-stringify/-/safe-stable-stringify-2.4.0.tgz#95fadb1bcf8057a1363e11052122f5da36a69215" + integrity sha512-eehKHKpab6E741ud7ZIMcXhKcP6TSIezPkNZhy5U8xC6+VvrRdUA2tMgxGxaGl4cz7c2Ew5+mg5+wNB16KQqrA== "safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: version "2.1.2" @@ -2458,10 +2458,11 @@ winston-transport@^4.5.0: triple-beam "^1.3.0" winston@^3.3.3: - version "3.8.1" - resolved "https://registry.yarnpkg.com/winston/-/winston-3.8.1.tgz#76f15b3478cde170b780234e0c4cf805c5a7fb57" - integrity sha512-r+6YAiCR4uI3N8eQNOg8k3P3PqwAm20cLKlzVD9E66Ch39+LZC+VH1UKf9JemQj2B3QoUHfKD7Poewn0Pr3Y1w== + version "3.8.2" + resolved "https://registry.yarnpkg.com/winston/-/winston-3.8.2.tgz#56e16b34022eb4cff2638196d9646d7430fdad50" + integrity sha512-MsE1gRx1m5jdTTO9Ld/vND4krP2To+lgDoMEHGGa4HIlAUyXJtfc7CxQcGXVyz2IBpw5hbFkj2b/AtUdQwyRew== dependencies: + "@colors/colors" "1.5.0" "@dabh/diagnostics" "^2.0.2" async "^3.2.3" is-stream "^2.0.0" From 0f546677cf308cd8e8f607d716afbcde8868bb9f Mon Sep 17 00:00:00 2001 From: Alessio Onori Date: Mon, 19 Sep 2022 11:40:18 +0200 Subject: [PATCH 5/5] added promrule condition --- charts/virustotal-prometheus/templates/alertrules.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/charts/virustotal-prometheus/templates/alertrules.yaml b/charts/virustotal-prometheus/templates/alertrules.yaml index e9967d3..346a5ac 100644 --- a/charts/virustotal-prometheus/templates/alertrules.yaml +++ b/charts/virustotal-prometheus/templates/alertrules.yaml @@ -24,6 +24,7 @@ spec: labels: severity: warning origin: {{ .Values.prometheusRules.origin }} + {{ if eq .Values.config.ibmXforce.enabled true }} - alert: IbmXforceBadScore annotations: message: 'Domain {{`{{ $labels.domain }}`}} might have been flagged as problematic, please visit https://www.exchange.xforce.ibmcloud.com/url/{{`{{ $labels.domain }}`}} to doublecheck.' @@ -31,5 +32,6 @@ spec: for: 2m labels: severity: warning - origin: {{ .Values.prometheusRules.origin }} + origin: {{ .Values.prometheusRules.origin }} + {{ end }} {{ end }}