mirror of
https://github.com/nttgin/BGPalerter.git
synced 2024-05-19 06:50:08 +00:00
@@ -43,6 +43,13 @@ monitors:
|
||||
params:
|
||||
thresholdMinPeers: 2
|
||||
|
||||
- file: monitorRPKI
|
||||
channel: rpki
|
||||
name: rpki-monitor
|
||||
params:
|
||||
thresholdMinPeers: 1
|
||||
checkUncovered: false
|
||||
|
||||
reports:
|
||||
- file: reportFile
|
||||
channels:
|
||||
@@ -51,6 +58,7 @@ reports:
|
||||
- visibility
|
||||
- path
|
||||
- misconfiguration
|
||||
- rpki
|
||||
params:
|
||||
persistAlertData: false
|
||||
alertDataDirectory: alertdata/
|
||||
@@ -62,6 +70,7 @@ reports:
|
||||
# - visibility
|
||||
# - path
|
||||
# - misconfiguration
|
||||
# - rpki
|
||||
# params:
|
||||
# showPaths: 5 # Amount of AS_PATHs to report in the alert
|
||||
# senderEmail: bgpalerter@xxxx
|
||||
@@ -91,6 +100,7 @@ reports:
|
||||
# - visibility
|
||||
# - path
|
||||
# - misconfiguration
|
||||
# - rpki
|
||||
# params:
|
||||
# showPaths: 0 # Amount of AS_PATHs to report in the alert
|
||||
# colors:
|
||||
@@ -108,6 +118,7 @@ reports:
|
||||
# - visibility
|
||||
# - path
|
||||
# - misconfiguration
|
||||
# - rpki
|
||||
# params:
|
||||
# host: localhost
|
||||
# port: 9092
|
||||
@@ -122,6 +133,7 @@ reports:
|
||||
# - path
|
||||
# - asn-monitor
|
||||
# - misconfiguration
|
||||
# - rpki
|
||||
# params:
|
||||
# host: localhost
|
||||
# port: 514
|
||||
@@ -139,6 +151,7 @@ reports:
|
||||
# - visibility
|
||||
# - path
|
||||
# - misconfiguration
|
||||
# - rpki
|
||||
# params:
|
||||
# severity:
|
||||
# hijack: critical
|
||||
@@ -160,6 +173,7 @@ reports:
|
||||
# - visibility
|
||||
# - path
|
||||
# - misconfiguration
|
||||
# - rpki
|
||||
# params:
|
||||
# hooks:
|
||||
# default: _YOUR_WEBEX_WEBHOOK_URL_
|
||||
@@ -171,6 +185,7 @@ reports:
|
||||
# - visibility
|
||||
# - path
|
||||
# - misconfiguration
|
||||
# - rpki
|
||||
# params:
|
||||
# templates: # See here how to write a template https://github.com/nttgin/BGPalerter/blob/master/docs/context.md
|
||||
# default: '{"text": "${summary}"}'
|
||||
|
@@ -222,8 +222,11 @@ Parameters for this monitor module:
|
||||
|
||||
#### monitorAS
|
||||
|
||||
This monitor will listen for all announcements produced by the monitored Autonomous Systems and will detect when a prefix, which is not in the monitored prefixes list, is announced.
|
||||
This is useful if you want to be alerted in case your AS starts announcing something you didn't intend to announce (e.g. misconfiguration, typo).
|
||||
This monitor will listen for all announcements produced by the monitored Autonomous Systems and for all the announcements
|
||||
involving any of the monitored prefixes (independently from who is announcing them) and it will trigger an alert if any of the announcements is RPKI invalid or not covered by ROAs (optional).
|
||||
|
||||
This monitor is particularly useful while you are deploying RPKI since it will let you know if any of your announcements are
|
||||
invalid, and after RPKI deployment, in order to be sure that all future BGP configuration will be covered by ROAs.
|
||||
|
||||
|
||||
> Example:
|
||||
@@ -256,6 +259,44 @@ Parameters for this monitor module:
|
||||
|thresholdMinPeers| Minimum number of peers that need to see the BGP update before to trigger an alert. |
|
||||
|maxDataSamples| Maximum number of collected BGP messages for each alert which doesn't reach yet the `thresholdMinPeers`. Default to 1000. As soon as the `thresholdMinPeers` is reached, the collected BGP messages are flushed, independently from the value of `maxDataSamples`.|
|
||||
|
||||
|
||||
#### monitorRPKI
|
||||
|
||||
This monitor will listen for all announcements produced by the monitored Autonomous Systems and will detect when a prefix, which is not in the monitored prefixes list, is announced.
|
||||
This is useful if you want to be alerted in case your AS starts announcing something you didn't intend to announce (e.g. misconfiguration, typo).
|
||||
|
||||
|
||||
> Example:
|
||||
> The prefixes list of BGPalerter has an options.monitorASns list declared, such as:
|
||||
> ```yaml
|
||||
> 50.82.0.0/20:
|
||||
> asn: 58302
|
||||
> description: an example
|
||||
> ignoreMorespecifics: false
|
||||
>
|
||||
> options:
|
||||
> monitorASns:
|
||||
> 58302:
|
||||
> group: default
|
||||
> ```
|
||||
> If in config.yml monitorRPKI is enabled, you will receive alerts every time:
|
||||
> * 50.82.0.0/20 is announced and it is not covered by ROAs or the announcement is RPKI invalid;
|
||||
> * AS58302 announces something that is not covered by ROAs or the announcement is RPKI invalid;
|
||||
|
||||
|
||||
Example of alert:
|
||||
> The route 103.21.244.0/24 announced by AS13335 is not RPKI valid.
|
||||
|
||||
Parameters for this monitor module:
|
||||
|
||||
|Parameter| Description|
|
||||
|---|---|
|
||||
|thresholdMinPeers| Minimum number of peers that need to see the BGP update before to trigger an alert. |
|
||||
|checkUncovered| If set to true, the monitor will alert also for prefixes not covered by ROAs in addition of RPKI invalid prefixes. |
|
||||
|preCacheROAs| This parameter allows to download locally VRPs lists. This is suggested in the case you want to validate many BGP updates (e.g. for research purposes). For normal production monitoring do NOT set this parameter. |
|
||||
|refreshVrpListMinutes| If `preCacheROAs` is set to true, this parameter allows to specify a refresh time for the VRPs lists (it has to be > 15 minutes) |
|
||||
|
||||
|
||||
### Reports
|
||||
|
||||
Possible reports are:
|
||||
|
7
package-lock.json
generated
7
package-lock.json
generated
@@ -3537,7 +3537,6 @@
|
||||
"version": "1.4.4",
|
||||
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
|
||||
"integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"once": "^1.4.0"
|
||||
}
|
||||
@@ -7397,9 +7396,9 @@
|
||||
}
|
||||
},
|
||||
"rpki-validator": {
|
||||
"version": "1.0.15",
|
||||
"resolved": "https://registry.npmjs.org/rpki-validator/-/rpki-validator-1.0.15.tgz",
|
||||
"integrity": "sha512-YG2S0mcKi8sEAYHzo3CeT/2ovasXsn8WjTLPlpwOwLYuvzknH0Rhs9ZeBtM7dmPds0iCAlHjulLpFRIv24pUxw==",
|
||||
"version": "1.0.16",
|
||||
"resolved": "https://registry.npmjs.org/rpki-validator/-/rpki-validator-1.0.16.tgz",
|
||||
"integrity": "sha512-b8geGsGeiFANWoG5fOyVq0AC4MhG0nT9ypIhMIpCsKQd5TzOLL7nVi42I1OrvREBgIyDC2t3SsYvIP88F6d+pA==",
|
||||
"requires": {
|
||||
"axios": "^0.19.2",
|
||||
"brembo": "^2.0.3",
|
||||
|
@@ -30,8 +30,8 @@
|
||||
"chai": "^4.2.0",
|
||||
"chai-subset": "^1.6.0",
|
||||
"mocha": "^7.1.2",
|
||||
"pkg": "^4.4.8",
|
||||
"nodemon": "^2.0.3",
|
||||
"pkg": "^4.4.8",
|
||||
"read-last-lines": "^1.7.2"
|
||||
},
|
||||
"dependencies": {
|
||||
@@ -47,7 +47,7 @@
|
||||
"nodemailer": "^6.4.6",
|
||||
"path": "^0.12.7",
|
||||
"restify": "^8.5.1",
|
||||
"rpki-validator": "^1.0.15",
|
||||
"rpki-validator": "^1.0.16",
|
||||
"semver": "^7.3.2",
|
||||
"syslog-client": "^1.1.1",
|
||||
"ws": "^7.2.5",
|
||||
|
@@ -382,6 +382,44 @@ export default class ConnectorTest extends Connector{
|
||||
}
|
||||
];
|
||||
break;
|
||||
|
||||
case "rpki":
|
||||
updates = [
|
||||
{
|
||||
data: {
|
||||
announcements: [{
|
||||
prefixes: ["82.112.100.0/24"], // Valid
|
||||
next_hop: "124.0.0.3"
|
||||
}],
|
||||
peer: "124.0.0.4",
|
||||
path: [1, 2, 3, 4321, 2914]
|
||||
},
|
||||
type: "ris_message"
|
||||
},
|
||||
{
|
||||
data: {
|
||||
announcements: [{
|
||||
prefixes: ["8.8.8.8/22"], // Not covered
|
||||
next_hop: "124.0.0.3"
|
||||
}],
|
||||
peer: "124.0.0.4",
|
||||
path: [1, 2, 3, 4321, 5060, 2914]
|
||||
},
|
||||
type: "ris_message"
|
||||
},
|
||||
{
|
||||
data: {
|
||||
announcements: [{
|
||||
prefixes: ["103.21.244.0/24"], // Invalid
|
||||
next_hop: "124.0.0.3"
|
||||
}],
|
||||
peer: "124.0.0.4",
|
||||
path: [1, 2, 3, 4321, 13335]
|
||||
},
|
||||
type: "ris_message"
|
||||
}
|
||||
];
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
11
src/env.js
11
src/env.js
@@ -106,12 +106,21 @@ let config = {
|
||||
params: {
|
||||
thresholdMinPeers: 2
|
||||
}
|
||||
},
|
||||
{
|
||||
file: "monitorRPKI",
|
||||
channel: "rpki",
|
||||
name: "rpki-monitor",
|
||||
params: {
|
||||
thresholdMinPeers: 1,
|
||||
checkUncovered: false
|
||||
}
|
||||
}
|
||||
],
|
||||
reports: [
|
||||
{
|
||||
file: "reportFile",
|
||||
channels: ["hijack", "newprefix", "visibility", "path", "misconfiguration"]
|
||||
channels: ["hijack", "newprefix", "visibility", "path", "misconfiguration", "rpki"]
|
||||
}
|
||||
],
|
||||
notificationIntervalSeconds: 14400,
|
||||
|
@@ -184,6 +184,16 @@ export default class Monitor {
|
||||
return alert;
|
||||
};
|
||||
|
||||
getMonitoredAsMatch = (originAS) => {
|
||||
const monitored = this.input.getMonitoredASns();
|
||||
|
||||
for (let m of monitored) {
|
||||
if (originAS.includes(m.asn)) {
|
||||
return m;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
getMoreSpecificMatch = (prefix, includeIgnoredMorespecifics) => {
|
||||
const matched = this.input.getMoreSpecificMatch(prefix, includeIgnoredMorespecifics);
|
||||
|
||||
|
@@ -41,7 +41,7 @@ export default class MonitorAS extends Monitor {
|
||||
};
|
||||
|
||||
updateMonitoredResources = () => {
|
||||
this.monitored = this.input.getMonitoredASns();
|
||||
// nothing
|
||||
};
|
||||
|
||||
filter = (message) => {
|
||||
@@ -75,22 +75,12 @@ export default class MonitorAS extends Monitor {
|
||||
return false;
|
||||
};
|
||||
|
||||
_getMonitoredAS = (message) => {
|
||||
const monitored = this.monitored;
|
||||
|
||||
for (let m of monitored) {
|
||||
if (message.originAS.includes(m.asn)) {
|
||||
return m;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
monitor = (message) =>
|
||||
new Promise((resolve, reject) => {
|
||||
|
||||
const messageOrigin = message.originAS;
|
||||
const messagePrefix = message.prefix;
|
||||
const matchedRule = this._getMonitoredAS(message);
|
||||
const matchedRule = this.getMonitoredAsMatch(messageOrigin);
|
||||
|
||||
if (matchedRule) {
|
||||
|
||||
|
@@ -8,37 +8,53 @@ export default class MonitorRPKI extends Monitor {
|
||||
this.input.onChange(() => {
|
||||
this.updateMonitoredResources();
|
||||
});
|
||||
|
||||
this.validationQueue = [];
|
||||
|
||||
rpki.preCache(60)
|
||||
.then(() => {
|
||||
setInterval(this.validateBatch, 400);
|
||||
})
|
||||
|
||||
if (this.params.preCacheROAs) {
|
||||
rpki.preCache(Math.max(this.params.refreshVrpListMinutes, 15))
|
||||
.then(() => {
|
||||
console.log("Downloaded");
|
||||
// setInterval(this.validateBatch, 400);
|
||||
})
|
||||
.catch(() => {
|
||||
this.logger.log({
|
||||
level: 'error',
|
||||
message: "One of the VRPs lists cannot be downloaded. Anyway, the RPKI monitoring should be working."
|
||||
});
|
||||
});
|
||||
} else {
|
||||
setInterval(this.validateBatch, 400);
|
||||
}
|
||||
};
|
||||
|
||||
updateMonitoredResources = () => {
|
||||
// nothing
|
||||
this.monitored = this.input.getMonitoredASns();
|
||||
};
|
||||
|
||||
validateBatch = () => {
|
||||
const queue = this.validationQueue;
|
||||
this.validationQueue = [];
|
||||
|
||||
queue.forEach(this.validate);
|
||||
validateBatch = () => {
|
||||
this.validationQueue.forEach(this.validate);
|
||||
this.validationQueue = [];
|
||||
};
|
||||
|
||||
filter = (message) => {
|
||||
return message.type === 'announcement' && message.originAS.numbers.length == 1;
|
||||
return message.type === 'announcement' && message.originAS.numbers.length === 1;
|
||||
};
|
||||
|
||||
squashAlerts = (alerts) => {
|
||||
|
||||
const message = alerts[0].matchedMessage;
|
||||
const covering = (alerts[0].extra.covering && alerts[0].extra.covering[0]) ? alerts[0].extra.covering[0] : false;
|
||||
const firstAlert = alerts[0];
|
||||
const message = firstAlert.matchedMessage;
|
||||
const extra = firstAlert.extra;
|
||||
const covering = (extra.covering && extra.covering[0]) ? extra.covering[0] : false;
|
||||
const coveringString = (covering) ? `Valid ROA: origin AS${covering.origin} prefix ${covering.prefix} max length ${covering.maxLength}` : '';
|
||||
|
||||
return `The route ${message.prefix} announced by ${message.originAS} is not RPKI valid. Accepted with AS path: ${message.path}. ${coveringString}`;
|
||||
if (extra.valid === null && this.params.checkUncovered) {
|
||||
return `The route ${message.prefix} announced by ${message.originAS} is not covered by a ROA. Accepted with AS path: ${message.path}`;
|
||||
} else {
|
||||
return `The route ${message.prefix} announced by ${message.originAS} is not RPKI valid. Accepted with AS path: ${message.path}. ${coveringString}`;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -46,31 +62,54 @@ export default class MonitorRPKI extends Monitor {
|
||||
const prefix = message.prefix;
|
||||
const origin = message.originAS.getValue();
|
||||
|
||||
const result = rpki.validateFromCacheSync(prefix, origin, true);
|
||||
rpki.validate(prefix, origin, true)
|
||||
.then(result => {
|
||||
if (result) {
|
||||
const key = "a" + [prefix, origin]
|
||||
.join("AS")
|
||||
.replace(/\./g, "_")
|
||||
.replace(/\:/g, "_")
|
||||
.replace(/\//g, "_");
|
||||
|
||||
if (result.valid === false) {
|
||||
this.publishAlert(key,
|
||||
prefix,
|
||||
matchedRule,
|
||||
message,
|
||||
{ covering: result.covering, valid: result.valid });
|
||||
} else if (result.valid === null && this.params.checkUncovered) {
|
||||
this.publishAlert(key,
|
||||
prefix,
|
||||
matchedRule,
|
||||
message,
|
||||
{ covering: null, valid: null });
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
this.logger.log({
|
||||
level: 'error',
|
||||
message: error
|
||||
});
|
||||
});
|
||||
|
||||
if (result.valid === false) {
|
||||
const key = "a" + [prefix, origin]
|
||||
.join("AS")
|
||||
.replace(/\./g, "_")
|
||||
.replace(/\:/g, "_")
|
||||
.replace(/\//g, "_");
|
||||
|
||||
this.publishAlert(key,
|
||||
prefix,
|
||||
matchedRule,
|
||||
message,
|
||||
{ covering: result.covering });
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
monitor = (message) => {
|
||||
const prefix = message.prefix;
|
||||
const matchedRule = this.input.getMoreSpecificMatch(prefix, false);
|
||||
|
||||
if (matchedRule) {
|
||||
this.validationQueue.push({ message, matchedRule });
|
||||
const messageOrigin = message.originAS;
|
||||
const prefix = message.prefix;
|
||||
const matchedASRule = this.getMonitoredAsMatch(messageOrigin);
|
||||
const matchedPrefixRule = this.getMoreSpecificMatch(prefix, false);
|
||||
|
||||
if (matchedPrefixRule) {
|
||||
this.validationQueue.push({ message, matchedRule: matchedPrefixRule });
|
||||
} else if (matchedASRule) {
|
||||
this.validationQueue.push({ message, matchedRule: matchedASRule });
|
||||
}
|
||||
|
||||
return Promise.resolve(true);
|
||||
};
|
||||
|
||||
|
@@ -39,7 +39,7 @@ export default class MonitorSwUpdates extends Monitor {
|
||||
};
|
||||
|
||||
updateMonitoredResources = () => {
|
||||
// throw new Error('The method updateMonitoredResources must be implemented in ' + this.name);
|
||||
// nothing
|
||||
};
|
||||
|
||||
filter = (message) => {
|
||||
|
@@ -145,11 +145,20 @@ export default class Report {
|
||||
|
||||
case "misconfiguration":
|
||||
context.asn = content.data[0].matchedRule.asn.toString();
|
||||
break;
|
||||
|
||||
case "rpki":
|
||||
matched = content.data[0].matchedRule;
|
||||
context.asn = matched.asn.toString();
|
||||
context.prefix = matched.prefix;
|
||||
context.description = matched.description;
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
matched = content.data[0].matchedRule;
|
||||
context.prefix = matched.prefix;
|
||||
context.description = matched.description;
|
||||
context.asn = matched.asn.toString();
|
||||
}
|
||||
|
||||
return context;
|
||||
|
@@ -97,7 +97,7 @@ describe("Composition", function() {
|
||||
|
||||
it("loading monitors", function () {
|
||||
|
||||
expect(config.monitors.length).to.equal(6);
|
||||
expect(config.monitors.length).to.equal(7);
|
||||
|
||||
expect(config.monitors[0]).to
|
||||
.containSubset({
|
||||
@@ -144,6 +144,18 @@ describe("Composition", function() {
|
||||
}
|
||||
});
|
||||
|
||||
expect(config.monitors[5]).to
|
||||
.containSubset({
|
||||
"channel": "rpki",
|
||||
"name": "rpki-monitor",
|
||||
"params": {
|
||||
"thresholdMinPeers": 1,
|
||||
"preCacheROAs": false,
|
||||
"refreshVrpListMinutes": 15,
|
||||
"checkUncovered": true
|
||||
}
|
||||
});
|
||||
|
||||
expect(config.monitors[config.monitors.length - 1]).to
|
||||
.containSubset({
|
||||
"channel": "software-update",
|
||||
@@ -297,7 +309,7 @@ describe("Composition", function() {
|
||||
]
|
||||
});
|
||||
|
||||
expect(input.asns.map(i => i.asn.getValue())).to.eql([ 2914, 3333, 65000 ]);
|
||||
expect(input.asns.map(i => i.asn.getValue())).to.eql([ 2914, 3333, 13335, 65000 ]);
|
||||
});
|
||||
});
|
||||
|
||||
|
@@ -477,8 +477,6 @@ describe("Alerting", function () {
|
||||
|
||||
}).timeout(asyncTimeout);
|
||||
|
||||
|
||||
|
||||
it("asn monitoring reporting", function (done) {
|
||||
|
||||
pubSub.publish("test-type", "misconfiguration");
|
||||
@@ -529,6 +527,57 @@ describe("Alerting", function () {
|
||||
|
||||
}).timeout(asyncTimeout);
|
||||
|
||||
it("RPKI monitoring", function (done) {
|
||||
|
||||
pubSub.publish("test-type", "rpki");
|
||||
|
||||
const expectedData = {
|
||||
|
||||
"a103_21_244_0_24AS13335": {
|
||||
id: "a103_21_244_0_24AS13335",
|
||||
origin: 'rpki-monitor',
|
||||
affected: '103.21.244.0/24',
|
||||
message: 'The route 103.21.244.0/24 announced by AS13335 is not RPKI valid. Accepted with AS path: [1,2,3,4321,13335]. Valid ROA: origin AS0 prefix 103.21.244.0/23 max length 23',
|
||||
},
|
||||
|
||||
"a8_8_8_8_22AS2914": {
|
||||
id: "a8_8_8_8_22AS2914",
|
||||
origin: 'rpki-monitor',
|
||||
affected: '8.8.8.8/22',
|
||||
message: 'The route 8.8.8.8/22 announced by AS2914 is not covered by a ROA. Accepted with AS path: [1,2,3,4321,5060,2914]',
|
||||
}
|
||||
};
|
||||
|
||||
let rpkiTestCompleted = false;
|
||||
pubSub.subscribe("rpki", function (type, message) {
|
||||
|
||||
if (!rpkiTestCompleted) {
|
||||
message = JSON.parse(JSON.stringify(message));
|
||||
const id = message.id;
|
||||
|
||||
expect(Object.keys(expectedData).includes(id)).to.equal(true);
|
||||
expect(expectedData[id] != null).to.equal(true);
|
||||
|
||||
expect(message).to
|
||||
.containSubset(expectedData[id]);
|
||||
|
||||
expect(message).to.contain
|
||||
.keys([
|
||||
"latest",
|
||||
"earliest"
|
||||
]);
|
||||
|
||||
delete expectedData[id];
|
||||
if (Object.keys(expectedData).length === 0) {
|
||||
setTimeout(() => {
|
||||
rpkiTestCompleted = true;
|
||||
done();
|
||||
}, 5000);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}).timeout(asyncTimeout);
|
||||
|
||||
it("fading alerting", function (done) {
|
||||
|
||||
|
@@ -37,6 +37,16 @@ monitors:
|
||||
params:
|
||||
thresholdMinPeers: 2
|
||||
|
||||
- file: monitorRPKI
|
||||
channel: rpki
|
||||
name: rpki-monitor
|
||||
params:
|
||||
thresholdMinPeers: 1
|
||||
preCacheROAs: false
|
||||
refreshVrpListMinutes: 15
|
||||
checkUncovered: true
|
||||
|
||||
|
||||
reports:
|
||||
- file: reportFile
|
||||
channels:
|
||||
@@ -45,14 +55,12 @@ reports:
|
||||
- visibility
|
||||
- path
|
||||
- misconfiguration
|
||||
- rpki
|
||||
params:
|
||||
persistAlertData: false
|
||||
alertDataDirectory: alertdata/
|
||||
|
||||
notificationIntervalSeconds: 1800 # Repeat the same alert (which keeps being triggered) after x seconds
|
||||
alertOnlyOnce: false
|
||||
fadeOffSeconds: 10
|
||||
checkFadeOffGroupsSeconds: 2
|
||||
|
||||
|
||||
# The file containing the monitored prefixes. Please see monitored_prefixes_test.yml for an example
|
||||
# This is an array (use new lines and dashes!)
|
||||
@@ -76,6 +84,11 @@ processMonitors:
|
||||
host: null
|
||||
port: 8011
|
||||
|
||||
|
||||
notificationIntervalSeconds: 1800 # Repeat the same alert (which keeps being triggered) after x seconds
|
||||
alertOnlyOnce: false
|
||||
fadeOffSeconds: 10
|
||||
checkFadeOffGroupsSeconds: 2
|
||||
pidFile: bgpalerter.pid
|
||||
multiProcess: false
|
||||
maxMessagesPerSecond: 6000
|
@@ -101,4 +101,6 @@ options:
|
||||
2914:
|
||||
group: default
|
||||
3333:
|
||||
group: default
|
||||
13335:
|
||||
group: default
|
Reference in New Issue
Block a user