Skip to content

Commit

Permalink
fixed include/excludeMonitor for monitorRPKI (#441) and improved tests
Browse files Browse the repository at this point in the history
  • Loading branch information
massimocandela committed Jan 4, 2021
1 parent 0a1b591 commit a363fad
Show file tree
Hide file tree
Showing 9 changed files with 100 additions and 49 deletions.
3 changes: 1 addition & 2 deletions src/connectors/connectorRIS.js
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ export default class ConnectorRIS extends Connector {

if (monitoredPrefixes
.filter(
i => (ipUtils._isEqualPrefix(i.prefix, '0:0:0:0:0:0:0:0/0') || ipUtils._isEqualPrefix(i.prefix,'0.0.0.0/0'))
i => (ipUtils.isEqualPrefix(i.prefix, '0:0:0:0:0:0:0:0/0') || ipUtils.isEqualPrefix(i.prefix,'0.0.0.0/0'))
).length === 2) {

delete params.prefix;
Expand Down Expand Up @@ -307,6 +307,5 @@ export default class ConnectorRIS extends Connector {
} else if (message.type === 'ris_error') {
throw new Error("Error from RIS: " + message.data.message);
}

}
};
77 changes: 51 additions & 26 deletions src/connectors/connectorTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@

import Connector from "./connector";
import {AS, Path} from "../model";
import ipUtils from "ip-sub";

export default class ConnectorTest extends Connector{

Expand Down Expand Up @@ -451,41 +452,65 @@ export default class ConnectorTest extends Connector{

static transform = (message) => {
if (message.type === 'ris_message') {
message = message.data;
const components = [];
const announcements = message["announcements"] || [];
const withdrawals = message["withdrawals"] || [];
const aggregator = message["aggregator"] || null;
const peer = message["peer"];
try {
message = message.data;
const components = [];
const announcements = message["announcements"] || [];
const aggregator = message["aggregator"] || null;
const withdrawals = message["withdrawals"] || [];
const peer = message["peer"];
const communities = message["community"] || [];
const timestamp = message["timestamp"] * 1000;
let path, originAS;

for (let announcement of announcements){
const nextHop = announcement["next_hop"];
const prefixes = announcement["prefixes"] || [];
let path = new Path(message["path"].map(i => new AS(i)));
let originAS = path.getLast();
if (message["path"] && message["path"].length) {
path = new Path(message["path"].map(i => new AS(i)));
originAS = path.getLast();
} else {
path = new Path([]);
originAS = null;
}

if (originAS && path.length()) {
for (let announcement of announcements) {
const nextHop = announcement["next_hop"];

if (ipUtils.isValidIP(nextHop)) {
const prefixes = (announcement["prefixes"] || [])
.filter(prefix => ipUtils.isValidPrefix(prefix));

for (let prefix of prefixes) {
components.push({
type: "announcement",
prefix,
peer,
path,
originAS,
nextHop,
aggregator,
timestamp,
communities
});
}
}
}
}

for (let prefix of prefixes){
for (let prefix of withdrawals) {
components.push({
type: "announcement",
type: "withdrawal",
prefix,
peer,
path,
originAS,
nextHop,
aggregator
timestamp
})
}
}

for (let prefix of withdrawals){
components.push({
type: "withdrawal",
prefix,
peer
})
return components;
} catch (error) {
throw new Error(`Error during transform (${this.name}): ` + error.message);
}

return components;
} else if (message.type === 'ris_error') {
throw new Error("Error from RIS: " + message.data.message);
}
};
}
2 changes: 1 addition & 1 deletion src/inputs/input.js
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ export default class Input {
getMoreSpecificMatch = (prefix, includeIgnoredMorespecifics) => {

for (let p of this.prefixes) {
if (ipUtils._isEqualPrefix(p.prefix, prefix)) { // Used internal method to avoid validation overhead
if (ipUtils.isEqualPrefix(p.prefix, prefix)) {
return p;
} else {

Expand Down
27 changes: 22 additions & 5 deletions src/monitors/monitor.js
Original file line number Diff line number Diff line change
Expand Up @@ -253,18 +253,35 @@ export default class Monitor {
return m;
}
}

return null;
};

_included = (matched) => {
if (matched.includeMonitors.length > 0) {
return matched.includeMonitors.includes(this.name);
} else {
return !matched.excludeMonitors.includes(this.name);
}
};

getMoreSpecificMatch = (prefix, includeIgnoredMorespecifics) => {
getMoreSpecificMatch = (prefix, includeIgnoredMorespecifics, verbose=false) => {
const matched = this.input.getMoreSpecificMatch(prefix, includeIgnoredMorespecifics);

if (matched) {
if (matched.includeMonitors.length > 0 && !matched.includeMonitors.includes(this.name)) {
return null;
}
const included = this._included(matched);

return (matched.excludeMonitors.includes(this.name)) ? null : matched;
if (verbose) {
return {
matched,
included
};
} else if (included) {
return matched;
}
}

return null;
};

}
3 changes: 1 addition & 2 deletions src/monitors/monitorHijack.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ export default class MonitorHijack extends Monitor {
const message = alerts[0].matchedMessage;
const asnText = matchedRule.asn;

return (ipUtils._isEqualPrefix(message.prefix, matchedRule.prefix)) ?
return (ipUtils.isEqualPrefix(message.prefix, matchedRule.prefix)) ?
`The prefix ${matchedRule.prefix} (${matchedRule.description}) is announced by ${message.originAS} instead of ${asnText}` :
`A new prefix ${message.prefix} is announced by ${message.originAS}. ` +
`It should be instead ${matchedRule.prefix} (${matchedRule.description}) announced by ${asnText}`;
Expand All @@ -80,7 +80,6 @@ export default class MonitorHijack extends Monitor {
}
}


monitor = (message) =>
new Promise((resolve, reject) => {

Expand Down
6 changes: 4 additions & 2 deletions src/monitors/monitorNewPrefix.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
*/

import Monitor from "./monitor";
import ipUtils from "ip-sub";

export default class MonitorNewPrefix extends Monitor {

Expand All @@ -56,7 +57,6 @@ export default class MonitorNewPrefix extends Monitor {
const matchedRule = alerts[0].matchedRule;

return `Possible change of configuration. A new prefix ${message.prefix} is announced by ${message.originAS}. It is a more specific of ${matchedRule.prefix} (${matchedRule.description})`;

}

return false;
Expand All @@ -68,7 +68,9 @@ export default class MonitorNewPrefix extends Monitor {
const messagePrefix = message.prefix;
const matchedRule = this.getMoreSpecificMatch(messagePrefix, false);

if (matchedRule && !matchedRule.ignore && matchedRule.asn.includes(message.originAS) && matchedRule.prefix !== messagePrefix) {
if (matchedRule && !matchedRule.ignore &&
matchedRule.asn.includes(message.originAS) &&
!ipUtils.isEqualPrefix(matchedRule.prefix, messagePrefix)) {

this.publishAlert(message.originAS.getId() + "-" + message.prefix,
matchedRule.asn.getId(),
Expand Down
28 changes: 18 additions & 10 deletions src/monitors/monitorRPKI.js
Original file line number Diff line number Diff line change
Expand Up @@ -179,19 +179,27 @@ export default class MonitorRPKI extends Monitor {
};

monitor = (message) => {
try {
const messageOrigin = message.originAS;
const prefix = message.prefix;

const messageOrigin = message.originAS;
const prefix = message.prefix;
const matchedPrefixRule = this.getMoreSpecificMatch(prefix, false, true);

const matchedPrefixRule = this.getMoreSpecificMatch(prefix, false);

if (matchedPrefixRule && !matchedPrefixRule.ignore) {
this.validate(message, matchedPrefixRule);
} else {
const matchedASRule = this.getMonitoredAsMatch(messageOrigin);
if (matchedASRule) {
this.validate(message, matchedASRule);
if (matchedPrefixRule.matched) { // There is a prefix match
if (!matchedPrefixRule.matched.ignore && matchedPrefixRule.included) { // The prefix match is not excluded in any way
this.validate(message, matchedPrefixRule.matched);
}
} else { // No prefix match
const matchedASRule = this.getMonitoredAsMatch(messageOrigin); // Try AS match
if (matchedASRule) {
this.validate(message, matchedASRule);
}
}
} catch (error) {
this.logger.log({
level: 'error',
message: error
});
}

return Promise.resolve(true);
Expand Down
2 changes: 1 addition & 1 deletion src/monitors/monitorVisibility.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ export default class MonitorVisibility extends Monitor {
const messagePrefix = message.prefix;
const matchedRule = this.getMoreSpecificMatch(messagePrefix, false);

if (matchedRule && !matchedRule.ignore && ipUtils._isEqualPrefix(matchedRule.prefix, messagePrefix)) {
if (matchedRule && !matchedRule.ignore && ipUtils.isEqualPrefix(matchedRule.prefix, messagePrefix)) {

let key = matchedRule.prefix;

Expand Down
1 change: 1 addition & 0 deletions tests/reports_tests/testsReportHttp.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ describe("Reports 2", function() {
server.use(restify.plugins.bodyParser({ mapParams: true }));
let expectedData = [
"The prefix 2a00:5884::/32 (alarig fix test) is announced by AS15563 instead of AS204092, and AS45. Top 1 most used AS paths: [2,3,15563].",
"A new prefix 165.254.255.0/25 is announced by AS15562, and AS4. It should be instead 165.254.255.0/24 (description 2) announced by AS15562. Top 1 most used AS paths: [2,3,[15562,4]].",
"A new prefix 2a00:5884:ffff::/48 is announced by AS208585. It should be instead 2a00:5884::/32 (alarig fix test) announced by AS204092, and AS45. Top 1 most used AS paths: [2,3,208585].",
];

Expand Down

0 comments on commit a363fad

Please sign in to comment.