initial
This commit is contained in:
82
ts/nft.rulebuilder.nat.ts
Normal file
82
ts/nft.rulebuilder.nat.ts
Normal file
@@ -0,0 +1,82 @@
|
||||
import type { TNftFamily, TNftProtocol, INftDnatRule, INftSnatRule, INftMasqueradeRule } from './nft.types.js';
|
||||
|
||||
/**
|
||||
* Expand a protocol spec into concrete protocol strings.
|
||||
*/
|
||||
function expandProtocols(protocol?: TNftProtocol): string[] {
|
||||
switch (protocol ?? 'tcp') {
|
||||
case 'tcp': return ['tcp'];
|
||||
case 'udp': return ['udp'];
|
||||
case 'both': return ['tcp', 'udp'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Build DNAT rules for port forwarding.
|
||||
* Generates DNAT + optional masquerade for each protocol.
|
||||
* Direct port of Rust build_dnat_rule.
|
||||
*/
|
||||
export function buildDnatRules(
|
||||
tableName: string,
|
||||
family: TNftFamily,
|
||||
rule: INftDnatRule,
|
||||
): string[] {
|
||||
const protocols = expandProtocols(rule.protocol);
|
||||
const commands: string[] = [];
|
||||
|
||||
for (const proto of protocols) {
|
||||
// DNAT rule
|
||||
commands.push(
|
||||
`nft add rule ${family} ${tableName} prerouting ${proto} dport ${rule.sourcePort} dnat to ${rule.targetHost}:${rule.targetPort}`
|
||||
);
|
||||
|
||||
// Masquerade (SNAT) unless preserveSourceIP is set
|
||||
if (!rule.preserveSourceIP) {
|
||||
commands.push(
|
||||
`nft add rule ${family} ${tableName} postrouting ${proto} dport ${rule.targetPort} masquerade`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return commands;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build an SNAT rule to rewrite source address.
|
||||
*/
|
||||
export function buildSnatRule(
|
||||
tableName: string,
|
||||
family: TNftFamily,
|
||||
rule: INftSnatRule,
|
||||
): string[] {
|
||||
const protocols = expandProtocols(rule.protocol);
|
||||
const commands: string[] = [];
|
||||
|
||||
for (const proto of protocols) {
|
||||
commands.push(
|
||||
`nft add rule ${family} ${tableName} postrouting ${proto} dport ${rule.targetPort} snat to ${rule.sourceAddress}`
|
||||
);
|
||||
}
|
||||
|
||||
return commands;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a masquerade rule for outgoing NAT.
|
||||
*/
|
||||
export function buildMasqueradeRule(
|
||||
tableName: string,
|
||||
family: TNftFamily,
|
||||
rule: INftMasqueradeRule,
|
||||
): string[] {
|
||||
const protocols = expandProtocols(rule.protocol);
|
||||
const commands: string[] = [];
|
||||
|
||||
for (const proto of protocols) {
|
||||
commands.push(
|
||||
`nft add rule ${family} ${tableName} postrouting ${proto} dport ${rule.targetPort} masquerade`
|
||||
);
|
||||
}
|
||||
|
||||
return commands;
|
||||
}
|
||||
Reference in New Issue
Block a user