Skip to content

Commit

Permalink
Semistandard Implemented
Browse files Browse the repository at this point in the history
Included Semistandard dev dependency.

Changes reflect bringing codebase to semistandard-standard.
  • Loading branch information
Dustyn Blackmore committed May 20, 2018
1 parent f921d10 commit 45a54a7
Show file tree
Hide file tree
Showing 14 changed files with 3,306 additions and 94 deletions.
1,912 changes: 1,912 additions & 0 deletions package-lock.json

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,8 @@
"dependencies": {
"nfqueue": "https://github.com/dmblack/node-nfqueue.git",
"pcap": "https://github.com/dmblack/node_pcap.git"
},
"devDependencies": {
"semistandard": "^12.0.1"
}
}
10 changes: 5 additions & 5 deletions src/actions/filesystem.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,18 @@ function write (fs, content) {
return new Promise((resolve, reject) => {
fs.appendFile('./logs/logger.log', content + '\n', (error) => {
if (error) {
reject(error)
reject(error);
} else {
resolve()
resolve();
}
})
})
});
});
}

const filesystem = (fs) => ({
log: (content) => {
return write(fs, content);
}
})
});

module.exports = filesystem;
4 changes: 2 additions & 2 deletions src/actions/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ const actions = (dependencies) => {
{},
actions,
filesystem(dependencies.fs)
)
);
}

return false;
}
};

module.exports = actions;
81 changes: 40 additions & 41 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ const sysClassNetInterfaces = '/sys/class/net/';
const fs = require('fs');
const nfq = require('nfqueue');
const IPv4 = require('pcap/decode/ipv4');
const pcap = require('pcap');
const { exec } = require('child_process');
const nft = require('./nftables')({ exec: exec });
const netFilterPacket = require('./nfpacket')({ nfq: nfq, pcapIPv4: IPv4 });
Expand All @@ -16,28 +15,28 @@ process.stdout.write('\x1Bc');
let rules = require('./../config/rules.json').rules;
let systemInterfaces = require('./../config/interfaces.json').interfaces;

let configWatch = fs.watch('./config', checkConfig);
fs.watch('./config', checkConfig);

function checkConfig (err, filename) {
function checkConfig (eventType, filename) {
setTimeout(() => {
switch (filename) {
case 'rules.json':
console.log('Rules Configuration Changed - Reloding..')
console.log('Rules Configuration Changed - Reloding..');
fs.readFile('./config/rules.json', 'utf8', (err, data) => {
if (err) throw err;
let newRules = JSON.parse(data);
rules = newRules.rules;
});
break;
case 'interfaces.json':
console.log('Interfaces Configuration Changed - Reloding..')
console.log('Interfaces Configuration Changed - Reloding..');
fs.readFile('./config/interfaces.json', 'utf8', (err, data) => {
if (err) throw err;
let newInterfaces = JSON.parse(data);
Object.keys(newInterfaces.interfaces).forEach(interface => {
Object.keys(newInterfaces.interfaces).forEach(newNetworkInterface => {
interfaces.forEach(thisInterface => {
if (thisInterface.name === interface && thisInterface.zone !== newInterfaces.interfaces[interface].zone) {
thisInterface.zone = newInterfaces.interfaces[interface].zone;
if (thisInterface.name === newNetworkInterface && thisInterface.zone !== newInterfaces.interfaces[newNetworkInterface].zone) {
thisInterface.zone = newInterfaces.interfaces[newNetworkInterface].zone;
}
});
});
Expand All @@ -62,16 +61,16 @@ let interfaces = [];
function insertFinalCounters () {
return Promise.all([
nft.add('rule ip filter input counter'),
nft.add('rule ip filter output counter'),
nft.add('rule ip filter output counter')
]);
}

function insertInterfaceRules (interface) {
function insertInterfaceRules (networkInterface) {
return Promise.all([
nft.add('rule ip filter input iif ' + interface.name + ' counter nftrace set 1 queue num ' + interface.number),
// nft.add('rule ip filter input iif ' + interface.name + ' meta mark 9999 counter nftrace set 1 queue num 200' + interface.number),
nft.add('rule ip filter output oif ' + interface.name + ' counter nftrace set 1 queue num 100' + interface.number),
// nft.add('rule ip filter output oif ' + interface.name + ' meta mark 9999 counter nftrace set 1 queue num 210' + interface.number)
nft.add('rule ip filter input iif ' + networkInterface.name + ' counter nftrace set 1 queue num ' + networkInterface.number),
// nft.add('rule ip filter input iif ' + networkInterface.name + ' meta mark 9999 counter nftrace set 1 queue num 200' + networkInterface.number),
nft.add('rule ip filter output oif ' + networkInterface.name + ' counter nftrace set 1 queue num 100' + networkInterface.number)
// nft.add('rule ip filter output oif ' + networkInterface.name + ' meta mark 9999 counter nftrace set 1 queue num 210' + networkInterface.number)
]);
}

Expand All @@ -94,25 +93,25 @@ function runPromiseArrayInSequence (arr) {
return promiseChain.then((chainedResult) => {
return currentPromise(chainedResult)
.then((res) => res);
})
});
}, Promise.resolve());
}

function setupInterfaces () {
let interfacePromises = [];

getInterfaces(sysClassNetInterfaces).forEach(interface => {
let zone = 'untrusted'
if (systemInterfaces[interface] && systemInterfaces[interface].zone) {
zone = systemInterfaces[interface].zone || 'untrusted';
getInterfaces(sysClassNetInterfaces).forEach(networkInterface => {
let zone = 'untrusted';
if (systemInterfaces[networkInterface] && systemInterfaces[networkInterface].zone) {
zone = systemInterfaces[networkInterface].zone || 'untrusted';
}
let newInterface = { name: interface, number: interfaces.length + 1, zone };
interfacePromises.push(() => insertInterfaceRules(newInterface))
let newInterface = { name: networkInterface, number: interfaces.length + 1, zone };
interfacePromises.push(() => insertInterfaceRules(newInterface));
interfaces.push(newInterface);
});

return runPromiseArrayInSequence(interfacePromises)
};
return runPromiseArrayInSequence(interfacePromises);
}

function handleActions (action, packet) {
switch (action) {
Expand Down Expand Up @@ -155,24 +154,24 @@ function handlePacket (packet) {
} else {
packet.verdict = packet.enums.netfilterVerdict.NF_ACCEPT;
return packet.verdicts.getVerdict();
//packet.nfpacket.setVerdict(packet.verdict, packet.mark);
// packet.nfpacket.setVerdict(packet.verdict, packet.mark);
}
// Else, as if globally accepted we don't need to traverse other zones.
}
// Check if the protocol is zone allowed.
if (rules[packet.direction][packet.nfpacketDecoded.protocol.toString()][packet.interface.zone].policy && rules[packet.direction][packet.nfpacketDecoded.protocol.toString()][packet.interface.zone].policy === 'allow') {
if (rules[packet.direction][packet.nfpacketDecoded.protocol.toString()][packet.networkInterface.zone].policy && rules[packet.direction][packet.nfpacketDecoded.protocol.toString()][packet.networkInterface.zone].policy === 'allow') {
// Trigger the protocol zone callback, if it exists.
if (rules[packet.direction][packet.nfpacketDecoded.protocol.toString()][packet.interface.zone].action) {
handleActions(rules[packet.direction][packet.nfpacketDecoded.protocol.toString()][packet.interface.zone].action, packet);
if (rules[packet.direction][packet.nfpacketDecoded.protocol.toString()][packet.networkInterface.zone].action) {
handleActions(rules[packet.direction][packet.nfpacketDecoded.protocol.toString()][packet.networkInterface.zone].action, packet);
}
// Check if the protocol's zone setting has any specific ports
if (rules[packet.direction][packet.nfpacketDecoded.protocol.toString()][packet.interface.zone].ports) {
if (rules[packet.direction][packet.nfpacketDecoded.protocol.toString()][packet.networkInterface.zone].ports) {
// Check, if there are ports, if the port is allowed.
if (rules[packet.direction][packet.nfpacketDecoded.protocol.toString()][packet.interface.zone].ports[packet.nfpacketDecoded.payload.dport] && rules[packet.direction][packet.nfpacketDecoded.protocol.toString()][packet.interface.zone].ports[packet.nfpacketDecoded.payload.dport].policy && rules[packet.direction][packet.nfpacketDecoded.protocol.toString()][packet.interface.zone].ports[packet.nfpacketDecoded.payload.dport].policy === 'allow') {
if (rules[packet.direction][packet.nfpacketDecoded.protocol.toString()][packet.networkInterface.zone].ports[packet.nfpacketDecoded.payload.dport] && rules[packet.direction][packet.nfpacketDecoded.protocol.toString()][packet.networkInterface.zone].ports[packet.nfpacketDecoded.payload.dport].policy && rules[packet.direction][packet.nfpacketDecoded.protocol.toString()][packet.networkInterface.zone].ports[packet.nfpacketDecoded.payload.dport].policy === 'allow') {
packet.verdict = packet.enums.netfilterVerdict.NF_ACCEPT;
// Finally - if the port is allowed, check if there's a callback to trigger.
if (rules[packet.direction][packet.nfpacketDecoded.protocol.toString()][packet.interface.zone].ports[packet.nfpacketDecoded.payload.dport].action) {
handleActions(rules[packet.direction][packet.nfpacketDecoded.protocol.toString()][packet.interface.zone].ports[packet.nfpacketDecoded.payload.dport].action, packet);
if (rules[packet.direction][packet.nfpacketDecoded.protocol.toString()][packet.networkInterface.zone].ports[packet.nfpacketDecoded.payload.dport].action) {
handleActions(rules[packet.direction][packet.nfpacketDecoded.protocol.toString()][packet.networkInterface.zone].ports[packet.nfpacketDecoded.payload.dport].action, packet);
}
}
// The global default is enabled, yet there are no ports.. which likely
Expand Down Expand Up @@ -204,11 +203,11 @@ function handlePacket (packet) {
// packet.nfpacket.setVerdict(packet.verdict, packet.mark);
}
}
if (rules['outgoing'][packet.nfpacketDecoded.protocol.toString()][packet.interface.zone] && rules['outgoing'][packet.nfpacketDecoded.protocol.toString()][packet.interface.zone].ports && rules['outgoing'][packet.nfpacketDecoded.protocol.toString()][packet.interface.zone].ports[packet.nfpacketDecoded.payload.sport] && rules['outgoing'][packet.nfpacketDecoded.protocol.toString()][packet.interface.zone].ports[packet.nfpacketDecoded.payload.sport].policy && rules['outgoing'][packet.nfpacketDecoded.protocol.toString()][packet.interface.zone].ports[packet.nfpacketDecoded.payload.sport].policy === 'allow') {
if (rules['outgoing'][packet.nfpacketDecoded.protocol.toString()][packet.networkInterface.zone] && rules['outgoing'][packet.nfpacketDecoded.protocol.toString()][packet.networkInterface.zone].ports && rules['outgoing'][packet.nfpacketDecoded.protocol.toString()][packet.networkInterface.zone].ports[packet.nfpacketDecoded.payload.sport] && rules['outgoing'][packet.nfpacketDecoded.protocol.toString()][packet.networkInterface.zone].ports[packet.nfpacketDecoded.payload.sport].policy && rules['outgoing'][packet.nfpacketDecoded.protocol.toString()][packet.networkInterface.zone].ports[packet.nfpacketDecoded.payload.sport].policy === 'allow') {
packet.verdict = packet.enums.netfilterVerdict.NF_ACCEPT;
// Finally - if the port is allowed, check if there's a callback to trigger.
if (rules['outgoing'][packet.nfpacketDecoded.protocol.toString()][packet.interface.zone].ports[packet.nfpacketDecoded.payload.sport].action) {
handleActions(rules['outgoing'][packet.nfpacketDecoded.protocol.toString()][packet.interface.zone].ports[packet.nfpacketDecoded.payload.sport].action, packet);
if (rules['outgoing'][packet.nfpacketDecoded.protocol.toString()][packet.networkInterface.zone].ports[packet.nfpacketDecoded.payload.sport].action) {
handleActions(rules['outgoing'][packet.nfpacketDecoded.protocol.toString()][packet.networkInterface.zone].ports[packet.nfpacketDecoded.payload.sport].action, packet);
}
}
}
Expand All @@ -225,12 +224,12 @@ function updateOutput () {
}

function bindQueueHandlers () {
interfaces.forEach(interface => {
interface.queueIn = nfq.createQueueHandler(parseInt(interface.number), buffer, (nfpacket) => {
interfaces.forEach(networkInterface => {
networkInterface.queueIn = nfq.createQueueHandler(parseInt(networkInterface.number), buffer, (nfpacket) => {
packetsIn++;
let thisPacket = netFilterPacket(nfpacket);
thisPacket.direction = 'incoming';
thisPacket.interface = interface;
thisPacket.networkInterface = networkInterface;

thisPacket.encoding.decode();

Expand All @@ -243,11 +242,11 @@ function bindQueueHandlers () {
verdict();
});

interface.queueOut = nfq.createQueueHandler(parseInt('100' + interface.number), buffer, (nfpacket) => {
networkInterface.queueOut = nfq.createQueueHandler(parseInt('100' + networkInterface.number), buffer, (nfpacket) => {
packetsOut++;
let thisPacket = netFilterPacket(nfpacket);
thisPacket.direction = 'outgoing';
thisPacket.interface = interface;
thisPacket.networkInterface = networkInterface;

thisPacket.encoding.decode();

Expand All @@ -266,7 +265,7 @@ console.log('Flushing rules...');
nft.flush().then(
(resolved) => {
console.log('Injecting NFTables base ruleset...');
nft.inject('./src/config/rules-base.nft')
nft.inject('./src/config/rules-base.nft');
},
(reject) => console.log('Failed to flush rules: ' + reject)
).then(
Expand All @@ -291,4 +290,4 @@ nft.flush().then(
(err) => console.log('Failed to insert final counters: ' + err)
);

const outputInterval = setInterval(updateOutput, 250);
setInterval(updateOutput, 250);
4 changes: 2 additions & 2 deletions src/nfpacket/encoding.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ const encoding = (dependencies) => (state) => ({
let IPv4 = dependencies || null;
let nfpacketDecoded = IPv4
? new IPv4().decode(state.nfpacket.payload, 0)
: false
: false;
state.nfpacketDecoded = nfpacketDecoded;
if (state.nfpacketDecoded.payload.data) {
let tempBuffer = Buffer.from(state.nfpacketDecoded.payload.data);
state.nfpacketDecoded.payloadBufferDecodoed = tempBuffer.toString();
}
state.nfpacketDecoded.payloadDecoded = state.nfpacketDecoded.payload.toString();
}
})
});

module.exports = encoding;
6 changes: 3 additions & 3 deletions src/nfpacket/enums.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ module.exports = {
NF_STOLEN: 2,
NF_QUEUE: 3,
NF_REPEAT: 4, // Requeue packet (Which we then use a mark to determine the action,
NF_STOP :5
NF_STOP: 5
},
protocols: {
// Protocol Numbers can be found here, however; libpcap has limited support..
// https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml
PC_ICMP: 1,
PC_IGMP: 2,
PC_TCP: 6,
PC_UDP: 17,
PC_UDP: 17
}
}
};
2 changes: 1 addition & 1 deletion src/nfpacket/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,4 @@ module.exports = (dependencies) => (nfpacket) => {
}

return false;
}
};
19 changes: 8 additions & 11 deletions src/nfpacket/verdicts.js
Original file line number Diff line number Diff line change
@@ -1,35 +1,32 @@
module.exports = (dependencies) => (state) => ({
accept: () => {
state.nfpacket
return state.nfpacket
? state.nfpacket.setVerdict(state.enums.netfilterVerdict.NF_ACCEPT, state.mark)
: false
: false;
},
reject: () => {
// This allows us to admin-prohibit and immediately reject outgoing, intead of droop (timeout).
if (state.direction === 'outgoing') {
state.nfpacket.setVerdict(state.enums.netfilterVerdict.NF_REPEAT, 777)
return state.nfpacket.setVerdict(state.enums.netfilterVerdict.NF_REPEAT, 777);
} else {
state.nfpacket
return state.nfpacket
? state.nfpacket.setVerdict(state.enums.netfilterVerdict.NF_DROP, state.mark)
: false
: false;
}
},
requeue: () => {
state.nfpacket
return state.nfpacket
? state.nfpacket.setVerdict(state.enums.netfilterVerdict.NF_REPEAT, state.mark)
: false
: false;
},
getVerdict: () => {
switch (state.verdict) {
case state.enums.netfilterVerdict.NF_ACCEPT:
return state.verdicts.accept;
break;
case state.enums.netfilterVerdict.NF_REPEAT:
return state.verdicts.requeue;
break;
default:
return state.verdicts.reject;
break;
}
}
})
});
5 changes: 2 additions & 3 deletions src/nftables/index.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
const rules = require('./rules');

const nft = (dependencies) => {

if (Object.keys(dependencies).includes('exec')) {
return Object.assign(
{},
nft,
rules(dependencies.exec)
)
);
}

return false;
}
};

module.exports = nft;
Loading

0 comments on commit 45a54a7

Please sign in to comment.