Skip to content

Commit

Permalink
Updated index.js
Browse files Browse the repository at this point in the history
Removed some old unused code.
Tweaked some missing properties to nfpacket.

Updated interfaces.json src/config template

Updated enums.js
Now use standards from nfq.

Updated actions.js
Reference to correct enums (enums.js)
  • Loading branch information
Dustyn Blackmore committed May 15, 2018
1 parent a6e86fb commit 84de2dd
Show file tree
Hide file tree
Showing 4 changed files with 18 additions and 116 deletions.
3 changes: 2 additions & 1 deletion src/config/interfaces.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"detail": "This file should be copied into './config/' and setup as necessary.",
"interfaces": {
"lo": {
"zone": "trusted"
Expand All @@ -10,7 +11,7 @@
"zone": "trusted"
},
"wlp3s0b1": {
"zone": "trusted"
"zone": "untrusted"
}
}
}
120 changes: 9 additions & 111 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,6 @@ const nft = require('./nftables')({ exec: exec });
const netFilterPacket = require('./nfpacket')({ nfq: nfq, pcapIPv4: IPv4 });
const actions = require('./actions')({ fs: fs });

// These are the NFQUEUE result handler options.
const NF_DROP = 0; // Drop the packet (There is no response or closure)
const NF_ACCEPT = 1; // Accept packet (but no longer seen / disowned by conntrack)
const NF_REQUEUE = 4; // Requeue packet (Which we then use a mark to determine the action)

// Protocol Numbers can be found here, however; libpcap has limited support..
// https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml
const PC_ICMP = 1;
const PC_IGMP = 2;
const PC_TCP = 6;
const PC_UDP = 17;

// The buffer size we will use binding to nfqueues.
const buffer = 131070;

Expand Down Expand Up @@ -132,100 +120,9 @@ function handleActions (action, packet) {
}
}

function determineVerdict (interface, packet, direction) {
let verdict = {
policy: NF_DROP,
};

// Check if the source port is as our otherwise accepted outgoing destination port, but only on incoming connections
// (Basically; established / releated comms)
// Required since 'logging' change complexity - but REQUIRES refactor
// if (direction === 'incoming' && typeof rules['outgoing'][packet.payloadDecoded.protocol.toString()][interface.zone].ports !== 'undefined') {
// if (typeof rules['outgoing'][packet.payloadDecoded.protocol.toString()][interface.zone].ports[packet.payloadDecoded.payload.sport] !== 'undefined') {
// console.log('Incoming packet which has a sourceport listed in destination port lists');
// if (rules['outgoing'][packet.payloadDecoded.protocol.toString()][interface.zone].ports[packet.payloadDecoded.payload.sport].policy && rules['outgoing'][packet.payloadDecoded.protocol.toString()][interface.zone].ports[packet.payloadDecoded.payload.sport].policy === 'allow') {
// console.log("Possible Related Connection: %s", JSON.stringify(packet));
// verdict.policy = NF_ACCEPT;

// return verdict;
// }
// }
// }

// Check we even handle this protocol
if (rules[direction][packet.payloadDecoded.protocol.toString()]) {
// Check if the global (blanket) rule applies
if (rules[direction][packet.payloadDecoded.protocol.toString()].global.policy && rules[direction][packet.payloadDecoded.protocol.toString()].global.policy === 'allow') {
// Trigger the callback, if it exists..
if (rules[direction][packet.payloadDecoded.protocol.toString()].global.action) {
handleActions(rules[direction][packet.payloadDecoded.protocol.toString()].global.action, packet);
if (rules[direction][packet.payloadDecoded.protocol.toString()].global.action === 'log') {
verdict.mark = 9999;
}
}
// Check if the global setting has any specific ports
if (rules[direction][packet.payloadDecoded.protocol.toString()].global.ports) {
// Check, if there are ports, if the port is allowed.
if (rules[direction][packet.payloadDecoded.protocol.toString()].global.ports[packet.payloadDecoded.payload.dport]) {
// Check if the policy is allow
if (rules[direction][packet.payloadDecoded.protocol.toString()].global.ports[packet.payloadDecoded.payload.dport].policy && rules[direction][packet.payloadDecoded.protocol.toString()].global.ports[packet.payloadDecoded.payload.dport].policy === 'allow') {
// Set to accept packet.
verdict.policy = NF_ACCEPT;
}
// Finally - if the port is allowed, check if there's a callback to trigger.
if (rules[direction][packet.payloadDecoded.protocol.toString()].global.ports[packet.payloadDecoded.payload.dport].action) {
handleActions(rules[direction][packet.payloadDecoded.protocol.toString()].global.ports[packet.payloadDecoded.payload.dport].action, packet);
if (rules[direction][packet.payloadDecoded.protocol.toString()].global.ports[packet.payloadDecoded.payload.dport].action === 'log') {
verdict.mark = 9999;
}
}
// Do not further traverse ruleset, or this function ; wasted cycles.
return verdict;
}
// The global default is enabled, yet there is no ports key..
// (Likely) means this is a port-less protocol, or a blanket 'allow' rule is in place.
} else {
verdict.policy = NF_ACCEPT;
return verdict;
}
// Else, as if globally accepted we don't need to traverse other zones.
}
// Check if the protocol is zone allowed.
if (rules[direction][packet.payloadDecoded.protocol.toString()][interface.zone].policy && rules[direction][packet.payloadDecoded.protocol.toString()][interface.zone].policy === 'allow') {
// Trigger the protocol zone callback, if it exists.
if (rules[direction][packet.payloadDecoded.protocol.toString()][interface.zone].action) {
handleActions(rules[direction][packet.payloadDecoded.protocol.toString()][interface.zone].action, packet);
if (rules[direction][packet.payloadDecoded.protocol.toString()][interface.zone].action === 'log') {
verdict.mark = 9999;
}
}
// Check if the protocol's zone setting has any specific ports
if (rules[direction][packet.payloadDecoded.protocol.toString()][interface.zone].ports) {
// Check, if there are ports, if the port is allowed.
if (rules[direction][packet.payloadDecoded.protocol.toString()][interface.zone].ports[packet.payloadDecoded.payload.dport].policy && rules[direction][packet.payloadDecoded.protocol.toString()][interface.zone].ports[packet.payloadDecoded.payload.dport].policy === 'allow') {
verdict.policy = NF_ACCEPT;
// Finally - if the port is allowed, check if there's a callback to trigger.
if (rules[direction][packet.payloadDecoded.protocol.toString()][interface.zone].ports[packet.payloadDecoded.payload.dport].action) {
handleActions(rules[direction][packet.payloadDecoded.protocol.toString()][interface.zone].ports[packet.payloadDecoded.payload.dport].action, packet);
if (rules[direction][packet.payloadDecoded.protocol.toString()][interface.zone].ports[packet.payloadDecoded.payload.dport].action === 'log') {
verdict.mark = 9999;
}
}
}
// The global default is enabled, yet there are no ports.. which likely
// Means this is a port-less protocol.
} else {
verdict.policy = NF_ACCEPT;
}
}
}

return verdict;
}

function handlePacket (interface, packet) {
function handlePacket (packet) {
let verdict = {
policy: NF_DROP,
policy: packet.state.enums.netfilterVerdict.NF_DROP,
mark: 0
};

Expand All @@ -247,7 +144,7 @@ function handlePacket (interface, packet) {
// Check if the policy is allow
if (rules[packet.getDirection()][packet.state.nfpacketDecoded.protocol.toString()].global.ports[packet.state.nfpacketDecoded.payload.dport].policy && rules[packet.getDirection()][packet.state.nfpacketDecoded.protocol.toString()].global.ports[packet.state.nfpacketDecoded.payload.dport].policy === 'allow') {
// Set to accept packet.
verdict.policy = NF_ACCEPT;
verdict.policy = packet.state.enums.netfilterVerdict.NF_ACCEPT;
}
// Finally - if the port is allowed, check if there's a callback to trigger.
if (rules[packet.getDirection()][packet.state.nfpacketDecoded.protocol.toString()].global.ports[packet.state.nfpacketDecoded.payload.dport].action) {
Expand All @@ -262,7 +159,7 @@ function handlePacket (interface, packet) {
// The global default is enabled, yet there is no ports key..
// (Likely) means this is a port-less protocol, or a blanket 'allow' rule is in place.
} else {
verdict.policy = NF_ACCEPT;
verdict.policy = packet.state.enums.netfilterVerdict.NF_ACCEPT;
packet.state.nfpacket.setVerdict(verdict.policy, verdict.mark);
}
// Else, as if globally accepted we don't need to traverse other zones.
Expand All @@ -280,7 +177,7 @@ function handlePacket (interface, packet) {
if (rules[packet.getDirection()][packet.state.nfpacketDecoded.protocol.toString()][packet.getInterface().zone].ports) {
// Check, if there are ports, if the port is allowed.
if (rules[packet.getDirection()][packet.state.nfpacketDecoded.protocol.toString()][packet.getInterface().zone].ports[packet.state.nfpacketDecoded.payload.dport] && rules[packet.getDirection()][packet.state.nfpacketDecoded.protocol.toString()][packet.getInterface().zone].ports[packet.state.nfpacketDecoded.payload.dport].policy && rules[packet.getDirection()][packet.state.nfpacketDecoded.protocol.toString()][packet.getInterface().zone].ports[packet.state.nfpacketDecoded.payload.dport].policy === 'allow') {
verdict.policy = NF_ACCEPT;
verdict.policy = packet.state.enums.netfilterVerdict.NF_ACCEPT;
// Finally - if the port is allowed, check if there's a callback to trigger.
if (rules[packet.getDirection()][packet.state.nfpacketDecoded.protocol.toString()][packet.getInterface().zone].ports[packet.state.nfpacketDecoded.payload.dport].action) {
handleActions(rules[packet.getDirection()][packet.state.nfpacketDecoded.protocol.toString()][packet.getInterface().zone].ports[packet.state.nfpacketDecoded.payload.dport].action, packet);
Expand All @@ -292,11 +189,12 @@ function handlePacket (interface, packet) {
// The global default is enabled, yet there are no ports.. which likely
// Means this is a port-less protocol.
} else {
verdict.policy = NF_ACCEPT;
verdict.policy = packet.state.enums.netfilterVerdict.NF_ACCEPT;
}
}
}

console.log(verdict.policy);
packet.state.nfpacket.setVerdict(verdict.policy, verdict.mark);
}

Expand All @@ -314,7 +212,7 @@ function bindQueueHandlers () {

thisPacket.encoding.decode();

handlePacket(interface, thisPacket);
handlePacket(thisPacket);
});

interface.queueInLog = nfq.createQueueHandler(parseInt('200' + interface.number), buffer, (nfpacket) => {
Expand All @@ -334,7 +232,7 @@ function bindQueueHandlers () {

thisPacket.encoding.decode();

handlePacket(interface, thisPacket);
handlePacket(thisPacket);
});

interfaceLoggerQueueOut = nfq.createQueueHandler(parseInt('210' + interface.number), buffer, (nfpacket) => {
Expand Down
4 changes: 2 additions & 2 deletions src/nfpacket/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ const actions = (dependencies) => (state) => ({
},
reject: () => {
state.nfpacket
? state.nfpacket.setVerdict(dependencies.enums.NF_REJECT)
? state.nfpacket.setVerdict(dependencies.enums.NF_DROP)
: false
},
requeue: () => {
state.nfpacket
? state.nfpacket.setVerdict(dependencies.enums.NF_REQUEUE)
? state.nfpacket.setVerdict(dependencies.enums.NF_REPEAT)
: false
}
})
Expand Down
7 changes: 5 additions & 2 deletions src/nfpacket/enums.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
module.exports = {
netfilterVerdict: {
// These are the NFQUEUE result handler options.
NF_REJECT: 0,
NF_DROP: 0,
NF_ACCEPT: 1, // Accept packet (but no longer seen / disowned by conntrack,
NF_REQUEUE: 4, // Requeue packet (Which we then use a mark to determine the action,
NF_STOLEN: 2,
NF_QUEUE: 3,
NF_REPEAT: 4, // Requeue packet (Which we then use a mark to determine the action,
NF_STOP :5
},
protocols: {
// Protocol Numbers can be found here, however; libpcap has limited support..
Expand Down

0 comments on commit 84de2dd

Please sign in to comment.