feat(traffic-flow): add NAT fields to flow processing and analytics
Docker images / prepare-release (push) Successful in 10s
Docker images / backend-test (push) Successful in 2m22s
Docker images / frontend-image (push) Successful in 3m30s
Docker images / updater-image (push) Successful in 45s
Docker images / backend-image (push) Successful in 2m51s
Docker images / notify-webhook (push) Skipped
Docker images / publish-release (push) Successful in 9s
Docker images / prepare-release (push) Successful in 10s
Docker images / backend-test (push) Successful in 2m22s
Docker images / frontend-image (push) Successful in 3m30s
Docker images / updater-image (push) Successful in 45s
Docker images / backend-image (push) Successful in 2m51s
Docker images / notify-webhook (push) Skipped
Docker images / publish-release (push) Successful in 9s
- Introduced new fields for NAT source and destination IPs, as well as their respective ports, in the flow data model. - Updated database schema and migration scripts to accommodate the new NAT fields in the `flow_buckets` table. - Enhanced flow analytics and processing functions to utilize the new NAT fields, improving accuracy in traffic flow analysis. - Added tests to validate the handling of NAT data in various scenarios, ensuring robustness in flow processing. Co-authored-by: Cursor <[email protected]>
This commit is contained in:
@@ -13,6 +13,8 @@ export interface ParsedFlow {
|
||||
flowEndMs: number
|
||||
natSrc: string
|
||||
natDst: string
|
||||
natSrcPort: number
|
||||
natDstPort: number
|
||||
}
|
||||
|
||||
export type ParsedFlowInput = Partial<ParsedFlow> & Pick<ParsedFlow, "src" | "dst" | "proto" | "bytes">
|
||||
@@ -33,6 +35,8 @@ export function emptyParsedFlow(): ParsedFlow {
|
||||
flowEndMs: 0,
|
||||
natSrc: "",
|
||||
natDst: "",
|
||||
natSrcPort: 0,
|
||||
natDstPort: 0,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,6 +49,8 @@ export function normalizeParsedFlow(flow: ParsedFlowInput): ParsedFlow {
|
||||
flowEndMs: flow.flowEndMs ?? 0,
|
||||
natSrc: flow.natSrc ?? "",
|
||||
natDst: flow.natDst ?? "",
|
||||
natSrcPort: flow.natSrcPort ?? 0,
|
||||
natDstPort: flow.natDstPort ?? 0,
|
||||
inIface: flow.inIface ?? "",
|
||||
outIface: flow.outIface ?? "",
|
||||
srcPort: flow.srcPort ?? 0,
|
||||
@@ -86,6 +92,12 @@ function ipv4(buf: Buffer, offset: number): string {
|
||||
return `${buf[offset]}.${buf[offset + 1]}.${buf[offset + 2]}.${buf[offset + 3]}`
|
||||
}
|
||||
|
||||
function usableIpfixIp(ip: string): boolean {
|
||||
const t = String(ip ?? "").trim()
|
||||
if (!t) return false
|
||||
return t !== "0.0.0.0" && t.toLowerCase() !== "::" && t.toLowerCase() !== "::0"
|
||||
}
|
||||
|
||||
function ipv6(buf: Buffer, offset: number): string {
|
||||
const parts: string[] = []
|
||||
for (let i = 0; i < 8; i++) parts.push(buf.readUInt16BE(offset + i * 2).toString(16))
|
||||
@@ -214,6 +226,8 @@ function recordFromFields(
|
||||
let flowEndMs = 0
|
||||
let natSrc = ""
|
||||
let natDst = ""
|
||||
let natSrcPort = 0
|
||||
let natDstPort = 0
|
||||
for (const f of fields) {
|
||||
const field = consumeField(buf, off, f.length, limit)
|
||||
if (!field) return null
|
||||
@@ -243,15 +257,21 @@ function recordFromFields(
|
||||
case 225:
|
||||
if (data.length === 4) {
|
||||
natSrc = ipv4(data, 0)
|
||||
if (!src) src = natSrc
|
||||
if (!usableIpfixIp(src) && usableIpfixIp(natSrc)) src = natSrc
|
||||
}
|
||||
break
|
||||
case 226:
|
||||
if (data.length === 4) {
|
||||
natDst = ipv4(data, 0)
|
||||
if (!dst) dst = natDst
|
||||
if (!usableIpfixIp(dst) && usableIpfixIp(natDst)) dst = natDst
|
||||
}
|
||||
break
|
||||
case 227:
|
||||
natSrcPort = readUint(data, 0, data.length)
|
||||
break
|
||||
case 228:
|
||||
natDstPort = readUint(data, 0, data.length)
|
||||
break
|
||||
case 4:
|
||||
proto = readUint(data, 0, data.length)
|
||||
break
|
||||
@@ -308,7 +328,7 @@ function recordFromFields(
|
||||
if (ifaceName && !inIface) inIface = ifaceName
|
||||
return {
|
||||
flow: normalizeParsedFlow({
|
||||
src, dst, proto, srcPort, dstPort, bytes, packets, inIface, outIface, nextHop, flowStartMs, flowEndMs, natSrc, natDst,
|
||||
src, dst, proto, srcPort, dstPort, bytes, packets, inIface, outIface, nextHop, flowStartMs, flowEndMs, natSrc, natDst, natSrcPort, natDstPort,
|
||||
}),
|
||||
next: off,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user