83
index.js
83
index.js
@@ -120,6 +120,45 @@ function buildBPFFilter() {
|
||||
return filters.length > 0 ? filters.join(' and ') : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate and format IP address for Elasticsearch
|
||||
* Returns null if invalid
|
||||
*/
|
||||
function validateIPAddress(ipString) {
|
||||
if (!ipString || typeof ipString !== 'string') return null;
|
||||
|
||||
// IPv4 validation regex
|
||||
const ipv4Regex = /^(\d{1,3}\.){3}\d{1,3}$/;
|
||||
|
||||
// IPv6 validation - check if it contains colons and valid hex characters
|
||||
const ipv6Regex = /^([0-9a-fA-F]{0,4}:){2,7}[0-9a-fA-F]{0,4}$/;
|
||||
|
||||
// Check if it's a valid IPv4
|
||||
if (ipv4Regex.test(ipString)) {
|
||||
const parts = ipString.split('.');
|
||||
const allValid = parts.every(part => {
|
||||
const num = parseInt(part, 10);
|
||||
return num >= 0 && num <= 255;
|
||||
});
|
||||
return allValid ? ipString : null;
|
||||
}
|
||||
|
||||
// Check if it's a valid IPv6
|
||||
if (ipv6Regex.test(ipString)) {
|
||||
return ipString;
|
||||
}
|
||||
|
||||
// Try to convert MAC-like format to IPv6 (fe:80:... -> fe80::...)
|
||||
// Some decoders might return IPv6 in an incorrect format
|
||||
if (ipString.includes(':') && ipString.length > 20) {
|
||||
// This might be a malformed IPv6, try to detect and skip
|
||||
logger.debug(`Skipping malformed IP address: ${ipString}`);
|
||||
return null;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if content is ASCII/readable
|
||||
*/
|
||||
@@ -321,7 +360,22 @@ async function processPacket(buffer, interfaceInfo) {
|
||||
const ipRet = decoders.IPV4(buffer, ret.offset);
|
||||
|
||||
if (ipRet) {
|
||||
const srcAddr = validateIPAddress(ipRet.info.srcaddr);
|
||||
const dstAddr = validateIPAddress(ipRet.info.dstaddr);
|
||||
|
||||
// Only add IP fields if addresses are valid
|
||||
if (srcAddr && dstAddr) {
|
||||
packet.ip = {
|
||||
version: 4,
|
||||
src: srcAddr,
|
||||
dst: dstAddr,
|
||||
protocol: ipRet.info.protocol,
|
||||
ttl: ipRet.info.ttl,
|
||||
length: ipRet.info.totallen
|
||||
};
|
||||
} else {
|
||||
// Store raw addresses if validation fails
|
||||
packet.ip_raw = {
|
||||
version: 4,
|
||||
src: ipRet.info.srcaddr,
|
||||
dst: ipRet.info.dstaddr,
|
||||
@@ -329,6 +383,8 @@ async function processPacket(buffer, interfaceInfo) {
|
||||
ttl: ipRet.info.ttl,
|
||||
length: ipRet.info.totallen
|
||||
};
|
||||
logger.debug(`Invalid IPv4 addresses: ${ipRet.info.srcaddr} -> ${ipRet.info.dstaddr}`);
|
||||
}
|
||||
|
||||
// Decode TCP
|
||||
if (ipRet.info.protocol === PROTOCOL.IP.TCP) {
|
||||
@@ -402,13 +458,29 @@ async function processPacket(buffer, interfaceInfo) {
|
||||
const ipv6Ret = decoders.IPV6(buffer, ret.offset);
|
||||
|
||||
if (ipv6Ret) {
|
||||
const srcAddr = validateIPAddress(ipv6Ret.info.srcaddr);
|
||||
const dstAddr = validateIPAddress(ipv6Ret.info.dstaddr);
|
||||
|
||||
// Only add IP fields if addresses are valid
|
||||
if (srcAddr && dstAddr) {
|
||||
packet.ip = {
|
||||
version: 6,
|
||||
src: srcAddr,
|
||||
dst: dstAddr,
|
||||
protocol: ipv6Ret.info.protocol,
|
||||
hop_limit: ipv6Ret.info.hoplimit
|
||||
};
|
||||
} else {
|
||||
// Store raw addresses if validation fails
|
||||
packet.ip_raw = {
|
||||
version: 6,
|
||||
src: ipv6Ret.info.srcaddr,
|
||||
dst: ipv6Ret.info.dstaddr,
|
||||
protocol: ipv6Ret.info.protocol,
|
||||
hop_limit: ipv6Ret.info.hoplimit
|
||||
};
|
||||
logger.debug(`Invalid IPv6 addresses: ${ipv6Ret.info.srcaddr} -> ${ipv6Ret.info.dstaddr}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -510,6 +582,17 @@ async function initializeElasticsearch() {
|
||||
hop_limit: { type: 'integer' }
|
||||
}
|
||||
},
|
||||
ip_raw: {
|
||||
properties: {
|
||||
version: { type: 'integer' },
|
||||
src: { type: 'keyword' },
|
||||
dst: { type: 'keyword' },
|
||||
protocol: { type: 'integer' },
|
||||
ttl: { type: 'integer' },
|
||||
length: { type: 'integer' },
|
||||
hop_limit: { type: 'integer' }
|
||||
}
|
||||
},
|
||||
tcp: {
|
||||
properties: {
|
||||
src_port: { type: 'integer' },
|
||||
|
||||
Referencia en una nueva incidencia
Block a user