From 84de2dd306bf2a2d59e7f13f23836ce6b7343686 Mon Sep 17 00:00:00 2001 From: Dustyn Blackmore Date: Wed, 16 May 2018 08:31:01 +1000 Subject: [PATCH] Updated index.js 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) --- src/config/interfaces.json | 3 +- src/index.js | 120 +++---------------------------------- src/nfpacket/actions.js | 4 +- src/nfpacket/enums.js | 7 ++- 4 files changed, 18 insertions(+), 116 deletions(-) diff --git a/src/config/interfaces.json b/src/config/interfaces.json index 134ab62..c66eded 100644 --- a/src/config/interfaces.json +++ b/src/config/interfaces.json @@ -1,4 +1,5 @@ { + "detail": "This file should be copied into './config/' and setup as necessary.", "interfaces": { "lo": { "zone": "trusted" @@ -10,7 +11,7 @@ "zone": "trusted" }, "wlp3s0b1": { - "zone": "trusted" + "zone": "untrusted" } } } diff --git a/src/index.js b/src/index.js index 2151f18..879350c 100644 --- a/src/index.js +++ b/src/index.js @@ -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; @@ -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 }; @@ -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) { @@ -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. @@ -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); @@ -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); } @@ -314,7 +212,7 @@ function bindQueueHandlers () { thisPacket.encoding.decode(); - handlePacket(interface, thisPacket); + handlePacket(thisPacket); }); interface.queueInLog = nfq.createQueueHandler(parseInt('200' + interface.number), buffer, (nfpacket) => { @@ -334,7 +232,7 @@ function bindQueueHandlers () { thisPacket.encoding.decode(); - handlePacket(interface, thisPacket); + handlePacket(thisPacket); }); interfaceLoggerQueueOut = nfq.createQueueHandler(parseInt('210' + interface.number), buffer, (nfpacket) => { diff --git a/src/nfpacket/actions.js b/src/nfpacket/actions.js index 9e4fe28..24d78a3 100644 --- a/src/nfpacket/actions.js +++ b/src/nfpacket/actions.js @@ -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 } }) diff --git a/src/nfpacket/enums.js b/src/nfpacket/enums.js index 53e6d5a..adf2857 100644 --- a/src/nfpacket/enums.js +++ b/src/nfpacket/enums.js @@ -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..