@push.rocks/smartnftables 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/changelog.md +10 -0
  2. package/dist_ts/00_commitinfo_data.d.ts +8 -0
  3. package/dist_ts/00_commitinfo_data.js +9 -0
  4. package/dist_ts/index.d.ts +10 -0
  5. package/dist_ts/index.js +14 -0
  6. package/dist_ts/nft.executor.d.ts +32 -0
  7. package/dist_ts/nft.executor.js +59 -0
  8. package/dist_ts/nft.manager.d.ts +59 -0
  9. package/dist_ts/nft.manager.firewall.d.ts +49 -0
  10. package/dist_ts/nft.manager.firewall.js +121 -0
  11. package/dist_ts/nft.manager.js +132 -0
  12. package/dist_ts/nft.manager.nat.d.ts +34 -0
  13. package/dist_ts/nft.manager.nat.js +61 -0
  14. package/dist_ts/nft.manager.ratelimit.d.ts +26 -0
  15. package/dist_ts/nft.manager.ratelimit.js +39 -0
  16. package/dist_ts/nft.rulebuilder.firewall.d.ts +30 -0
  17. package/dist_ts/nft.rulebuilder.firewall.js +119 -0
  18. package/dist_ts/nft.rulebuilder.nat.d.ts +15 -0
  19. package/dist_ts/nft.rulebuilder.nat.js +51 -0
  20. package/dist_ts/nft.rulebuilder.ratelimit.d.ts +16 -0
  21. package/dist_ts/nft.rulebuilder.ratelimit.js +61 -0
  22. package/dist_ts/nft.rulebuilder.table.d.ts +13 -0
  23. package/dist_ts/nft.rulebuilder.table.js +27 -0
  24. package/dist_ts/nft.types.d.ts +88 -0
  25. package/dist_ts/nft.types.js +2 -0
  26. package/dist_ts/plugins.d.ts +6 -0
  27. package/dist_ts/plugins.js +9 -0
  28. package/license +21 -0
  29. package/package.json +57 -0
  30. package/readme.md +357 -0
  31. package/ts/00_commitinfo_data.ts +8 -0
  32. package/ts/index.ts +59 -0
  33. package/ts/nft.executor.ts +74 -0
  34. package/ts/nft.manager.firewall.ts +148 -0
  35. package/ts/nft.manager.nat.ts +76 -0
  36. package/ts/nft.manager.ratelimit.ts +43 -0
  37. package/ts/nft.manager.ts +157 -0
  38. package/ts/nft.rulebuilder.firewall.ts +173 -0
  39. package/ts/nft.rulebuilder.nat.ts +82 -0
  40. package/ts/nft.rulebuilder.ratelimit.ts +89 -0
  41. package/ts/nft.rulebuilder.table.ts +30 -0
  42. package/ts/nft.types.ts +102 -0
  43. package/ts/plugins.ts +16 -0
@@ -0,0 +1,39 @@
1
+ import { buildRateLimitRule, buildConnectionRateRule } from './nft.rulebuilder.ratelimit.js';
2
+ /**
3
+ * Manages rate limiting rules using nft meters and limit expressions.
4
+ */
5
+ export class RateLimitManager {
6
+ constructor(parent) {
7
+ this.parent = parent;
8
+ }
9
+ /**
10
+ * Add a rate limit rule (global or per-IP).
11
+ */
12
+ async addRateLimit(groupId, rule) {
13
+ await this.parent.ensureFilterChains();
14
+ const commands = buildRateLimitRule(this.parent.tableName, this.parent.family, rule);
15
+ await this.parent.applyRuleGroup(`ratelimit:${groupId}`, commands);
16
+ }
17
+ /**
18
+ * Remove a rate limit rule group.
19
+ */
20
+ async removeRateLimit(groupId) {
21
+ await this.parent.removeRuleGroup(`ratelimit:${groupId}`);
22
+ }
23
+ /**
24
+ * Add a new-connection rate limit rule.
25
+ * Limits the rate of new TCP/UDP connections (ct state new).
26
+ */
27
+ async addConnectionRateLimit(groupId, rule) {
28
+ await this.parent.ensureFilterChains();
29
+ const commands = buildConnectionRateRule(this.parent.tableName, this.parent.family, rule);
30
+ await this.parent.applyRuleGroup(`connrate:${groupId}`, commands);
31
+ }
32
+ /**
33
+ * Remove a connection rate limit rule group.
34
+ */
35
+ async removeConnectionRateLimit(groupId) {
36
+ await this.parent.removeRuleGroup(`connrate:${groupId}`);
37
+ }
38
+ }
39
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmZ0Lm1hbmFnZXIucmF0ZWxpbWl0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvbmZ0Lm1hbmFnZXIucmF0ZWxpbWl0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUVBLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSx1QkFBdUIsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBRTdGOztHQUVHO0FBQ0gsTUFBTSxPQUFPLGdCQUFnQjtJQUMzQixZQUFvQixNQUFxQjtRQUFyQixXQUFNLEdBQU4sTUFBTSxDQUFlO0lBQUcsQ0FBQztJQUU3Qzs7T0FFRztJQUNJLEtBQUssQ0FBQyxZQUFZLENBQUMsT0FBZSxFQUFFLElBQXVCO1FBQ2hFLE1BQU0sSUFBSSxDQUFDLE1BQU0sQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO1FBQ3ZDLE1BQU0sUUFBUSxHQUFHLGtCQUFrQixDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsU0FBUyxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQ3JGLE1BQU0sSUFBSSxDQUFDLE1BQU0sQ0FBQyxjQUFjLENBQUMsYUFBYSxPQUFPLEVBQUUsRUFBRSxRQUFRLENBQUMsQ0FBQztJQUNyRSxDQUFDO0lBRUQ7O09BRUc7SUFDSSxLQUFLLENBQUMsZUFBZSxDQUFDLE9BQWU7UUFDMUMsTUFBTSxJQUFJLENBQUMsTUFBTSxDQUFDLGVBQWUsQ0FBQyxhQUFhLE9BQU8sRUFBRSxDQUFDLENBQUM7SUFDNUQsQ0FBQztJQUVEOzs7T0FHRztJQUNJLEtBQUssQ0FBQyxzQkFBc0IsQ0FBQyxPQUFlLEVBQUUsSUFBNEI7UUFDL0UsTUFBTSxJQUFJLENBQUMsTUFBTSxDQUFDLGtCQUFrQixFQUFFLENBQUM7UUFDdkMsTUFBTSxRQUFRLEdBQUcsdUJBQXVCLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxTQUFTLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDMUYsTUFBTSxJQUFJLENBQUMsTUFBTSxDQUFDLGNBQWMsQ0FBQyxZQUFZLE9BQU8sRUFBRSxFQUFFLFFBQVEsQ0FBQyxDQUFDO0lBQ3BFLENBQUM7SUFFRDs7T0FFRztJQUNJLEtBQUssQ0FBQyx5QkFBeUIsQ0FBQyxPQUFlO1FBQ3BELE1BQU0sSUFBSSxDQUFDLE1BQU0sQ0FBQyxlQUFlLENBQUMsWUFBWSxPQUFPLEVBQUUsQ0FBQyxDQUFDO0lBQzNELENBQUM7Q0FDRiJ9
@@ -0,0 +1,30 @@
1
+ import type { TNftFamily, INftFirewallRule, INftIPSetConfig } from './nft.types.js';
2
+ /**
3
+ * Build an nft firewall rule for input/output/forward chains.
4
+ */
5
+ export declare function buildFirewallRule(tableName: string, family: TNftFamily, rule: INftFirewallRule): string[];
6
+ /**
7
+ * Build commands to create an nft named set (IP set).
8
+ */
9
+ export declare function buildIPSetCreate(tableName: string, family: TNftFamily, config: INftIPSetConfig): string[];
10
+ /**
11
+ * Build command to add elements to an existing set.
12
+ */
13
+ export declare function buildIPSetAddElements(tableName: string, family: TNftFamily, setName: string, elements: string[]): string[];
14
+ /**
15
+ * Build command to remove elements from a set.
16
+ */
17
+ export declare function buildIPSetRemoveElements(tableName: string, family: TNftFamily, setName: string, elements: string[]): string[];
18
+ /**
19
+ * Build command to delete an entire set.
20
+ */
21
+ export declare function buildIPSetDelete(tableName: string, family: TNftFamily, setName: string): string[];
22
+ /**
23
+ * Build a rule that matches against a named set.
24
+ */
25
+ export declare function buildIPSetMatchRule(tableName: string, family: TNftFamily, options: {
26
+ setName: string;
27
+ direction: 'input' | 'output' | 'forward';
28
+ matchField: 'saddr' | 'daddr';
29
+ action: 'accept' | 'drop' | 'reject';
30
+ }): string[];
@@ -0,0 +1,119 @@
1
+ /**
2
+ * Build an nft firewall rule for input/output/forward chains.
3
+ */
4
+ export function buildFirewallRule(tableName, family, rule) {
5
+ const chain = rule.direction;
6
+ const parts = [`nft add rule ${family} ${tableName} ${chain}`];
7
+ // Connection tracking states
8
+ if (rule.ctStates && rule.ctStates.length > 0) {
9
+ parts.push(`ct state { ${rule.ctStates.join(', ')} }`);
10
+ }
11
+ // Protocol and port matching
12
+ const protocols = expandProtocols(rule.protocol);
13
+ const commands = [];
14
+ for (const proto of protocols) {
15
+ const ruleParts = [...parts];
16
+ if (rule.protocol) {
17
+ ruleParts.push(proto);
18
+ }
19
+ if (rule.sourceIP) {
20
+ ruleParts.push(`ip saddr ${rule.sourceIP}`);
21
+ }
22
+ if (rule.destIP) {
23
+ ruleParts.push(`ip daddr ${rule.destIP}`);
24
+ }
25
+ if (rule.sourcePort != null) {
26
+ ruleParts.push(`${proto} sport ${rule.sourcePort}`);
27
+ }
28
+ if (rule.destPort != null) {
29
+ // If protocol wasn't explicitly set but we have a port, we need the protocol
30
+ if (!rule.protocol) {
31
+ ruleParts.push(`tcp dport ${rule.destPort}`);
32
+ }
33
+ else {
34
+ ruleParts.push(`${proto} dport ${rule.destPort}`);
35
+ }
36
+ }
37
+ if (rule.comment) {
38
+ ruleParts.push(`comment "${rule.comment}"`);
39
+ }
40
+ ruleParts.push(rule.action);
41
+ commands.push(ruleParts.join(' '));
42
+ }
43
+ // If no protocol expansion needed (no protocol-specific fields)
44
+ if (commands.length === 0) {
45
+ const ruleParts = [...parts];
46
+ if (rule.sourceIP) {
47
+ ruleParts.push(`ip saddr ${rule.sourceIP}`);
48
+ }
49
+ if (rule.destIP) {
50
+ ruleParts.push(`ip daddr ${rule.destIP}`);
51
+ }
52
+ if (rule.comment) {
53
+ ruleParts.push(`comment "${rule.comment}"`);
54
+ }
55
+ ruleParts.push(rule.action);
56
+ commands.push(ruleParts.join(' '));
57
+ }
58
+ return commands;
59
+ }
60
+ /**
61
+ * Build commands to create an nft named set (IP set).
62
+ */
63
+ export function buildIPSetCreate(tableName, family, config) {
64
+ const commands = [];
65
+ // Create the set
66
+ commands.push(`nft add set ${family} ${tableName} ${config.name} { type ${config.type} \\; }`);
67
+ // Add initial elements if provided
68
+ if (config.elements && config.elements.length > 0) {
69
+ commands.push(`nft add element ${family} ${tableName} ${config.name} { ${config.elements.join(', ')} }`);
70
+ }
71
+ return commands;
72
+ }
73
+ /**
74
+ * Build command to add elements to an existing set.
75
+ */
76
+ export function buildIPSetAddElements(tableName, family, setName, elements) {
77
+ if (elements.length === 0)
78
+ return [];
79
+ return [
80
+ `nft add element ${family} ${tableName} ${setName} { ${elements.join(', ')} }`
81
+ ];
82
+ }
83
+ /**
84
+ * Build command to remove elements from a set.
85
+ */
86
+ export function buildIPSetRemoveElements(tableName, family, setName, elements) {
87
+ if (elements.length === 0)
88
+ return [];
89
+ return [
90
+ `nft delete element ${family} ${tableName} ${setName} { ${elements.join(', ')} }`
91
+ ];
92
+ }
93
+ /**
94
+ * Build command to delete an entire set.
95
+ */
96
+ export function buildIPSetDelete(tableName, family, setName) {
97
+ return [
98
+ `nft delete set ${family} ${tableName} ${setName}`
99
+ ];
100
+ }
101
+ /**
102
+ * Build a rule that matches against a named set.
103
+ */
104
+ export function buildIPSetMatchRule(tableName, family, options) {
105
+ return [
106
+ `nft add rule ${family} ${tableName} ${options.direction} ip ${options.matchField} @${options.setName} ${options.action}`
107
+ ];
108
+ }
109
+ // ─── Internal helpers ─────────────────────────────────────────────
110
+ function expandProtocols(protocol) {
111
+ if (!protocol)
112
+ return [];
113
+ switch (protocol) {
114
+ case 'tcp': return ['tcp'];
115
+ case 'udp': return ['udp'];
116
+ case 'both': return ['tcp', 'udp'];
117
+ }
118
+ }
119
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmZ0LnJ1bGVidWlsZGVyLmZpcmV3YWxsLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvbmZ0LnJ1bGVidWlsZGVyLmZpcmV3YWxsLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUVBOztHQUVHO0FBQ0gsTUFBTSxVQUFVLGlCQUFpQixDQUMvQixTQUFpQixFQUNqQixNQUFrQixFQUNsQixJQUFzQjtJQUV0QixNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDO0lBQzdCLE1BQU0sS0FBSyxHQUFhLENBQUMsZ0JBQWdCLE1BQU0sSUFBSSxTQUFTLElBQUksS0FBSyxFQUFFLENBQUMsQ0FBQztJQUV6RSw2QkFBNkI7SUFDN0IsSUFBSSxJQUFJLENBQUMsUUFBUSxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO1FBQzlDLEtBQUssQ0FBQyxJQUFJLENBQUMsY0FBYyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDekQsQ0FBQztJQUVELDZCQUE2QjtJQUM3QixNQUFNLFNBQVMsR0FBRyxlQUFlLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQ2pELE1BQU0sUUFBUSxHQUFhLEVBQUUsQ0FBQztJQUU5QixLQUFLLE1BQU0sS0FBSyxJQUFJLFNBQVMsRUFBRSxDQUFDO1FBQzlCLE1BQU0sU0FBUyxHQUFHLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQztRQUU3QixJQUFJLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztZQUNsQixTQUFTLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ3hCLENBQUM7UUFFRCxJQUFJLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztZQUNsQixTQUFTLENBQUMsSUFBSSxDQUFDLFlBQVksSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUM7UUFDOUMsQ0FBQztRQUVELElBQUksSUFB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
@@ -0,0 +1,15 @@
1
+ import type { TNftFamily, INftDnatRule, INftSnatRule, INftMasqueradeRule } from './nft.types.js';
2
+ /**
3
+ * Build DNAT rules for port forwarding.
4
+ * Generates DNAT + optional masquerade for each protocol.
5
+ * Direct port of Rust build_dnat_rule.
6
+ */
7
+ export declare function buildDnatRules(tableName: string, family: TNftFamily, rule: INftDnatRule): string[];
8
+ /**
9
+ * Build an SNAT rule to rewrite source address.
10
+ */
11
+ export declare function buildSnatRule(tableName: string, family: TNftFamily, rule: INftSnatRule): string[];
12
+ /**
13
+ * Build a masquerade rule for outgoing NAT.
14
+ */
15
+ export declare function buildMasqueradeRule(tableName: string, family: TNftFamily, rule: INftMasqueradeRule): string[];
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Expand a protocol spec into concrete protocol strings.
3
+ */
4
+ function expandProtocols(protocol) {
5
+ switch (protocol ?? 'tcp') {
6
+ case 'tcp': return ['tcp'];
7
+ case 'udp': return ['udp'];
8
+ case 'both': return ['tcp', 'udp'];
9
+ }
10
+ }
11
+ /**
12
+ * Build DNAT rules for port forwarding.
13
+ * Generates DNAT + optional masquerade for each protocol.
14
+ * Direct port of Rust build_dnat_rule.
15
+ */
16
+ export function buildDnatRules(tableName, family, rule) {
17
+ const protocols = expandProtocols(rule.protocol);
18
+ const commands = [];
19
+ for (const proto of protocols) {
20
+ // DNAT rule
21
+ commands.push(`nft add rule ${family} ${tableName} prerouting ${proto} dport ${rule.sourcePort} dnat to ${rule.targetHost}:${rule.targetPort}`);
22
+ // Masquerade (SNAT) unless preserveSourceIP is set
23
+ if (!rule.preserveSourceIP) {
24
+ commands.push(`nft add rule ${family} ${tableName} postrouting ${proto} dport ${rule.targetPort} masquerade`);
25
+ }
26
+ }
27
+ return commands;
28
+ }
29
+ /**
30
+ * Build an SNAT rule to rewrite source address.
31
+ */
32
+ export function buildSnatRule(tableName, family, rule) {
33
+ const protocols = expandProtocols(rule.protocol);
34
+ const commands = [];
35
+ for (const proto of protocols) {
36
+ commands.push(`nft add rule ${family} ${tableName} postrouting ${proto} dport ${rule.targetPort} snat to ${rule.sourceAddress}`);
37
+ }
38
+ return commands;
39
+ }
40
+ /**
41
+ * Build a masquerade rule for outgoing NAT.
42
+ */
43
+ export function buildMasqueradeRule(tableName, family, rule) {
44
+ const protocols = expandProtocols(rule.protocol);
45
+ const commands = [];
46
+ for (const proto of protocols) {
47
+ commands.push(`nft add rule ${family} ${tableName} postrouting ${proto} dport ${rule.targetPort} masquerade`);
48
+ }
49
+ return commands;
50
+ }
51
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmZ0LnJ1bGVidWlsZGVyLm5hdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL25mdC5ydWxlYnVpbGRlci5uYXQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBRUE7O0dBRUc7QUFDSCxTQUFTLGVBQWUsQ0FBQyxRQUF1QjtJQUM5QyxRQUFRLFFBQVEsSUFBSSxLQUFLLEVBQUUsQ0FBQztRQUMxQixLQUFLLEtBQUssQ0FBQyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUMzQixLQUFLLEtBQUssQ0FBQyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUMzQixLQUFLLE1BQU0sQ0FBQyxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLENBQUM7SUFDckMsQ0FBQztBQUNILENBQUM7QUFFRDs7OztHQUlHO0FBQ0gsTUFBTSxVQUFVLGNBQWMsQ0FDNUIsU0FBaUIsRUFDakIsTUFBa0IsRUFDbEIsSUFBa0I7SUFFbEIsTUFBTSxTQUFTLEdBQUcsZUFBZSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUNqRCxNQUFNLFFBQVEsR0FBYSxFQUFFLENBQUM7SUFFOUIsS0FBSyxNQUFNLEtBQUssSUFBSSxTQUFTLEVBQUUsQ0FBQztRQUM5QixZQUFZO1FBQ1osUUFBUSxDQUFDLElBQUksQ0FDWCxnQkFBZ0IsTUFBTSxJQUFJLFNBQVMsZUFBZSxLQUFLLFVBQVUsSUFBSSxDQUFDLFVBQVUsWUFBWSxJQUFJLENBQUMsVUFBVSxJQUFJLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FDakksQ0FBQztRQUVGLG1EQUFtRDtRQUNuRCxJQUFJLENBQUMsSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUM7WUFDM0IsUUFBUSxDQUFDLElBQUksQ0FDWCxnQkFBZ0IsTUFBTSxJQUFJLFNBQVMsZ0JBQWdCLEtBQUssVUFBVSxJQUFJLENBQUMsVUFBVSxhQUFhLENBQy9GLENBQUM7UUFDSixDQUFDO0lBQ0gsQ0FBQztJQUVELE9BQU8sUUFBUSxDQUFDO0FBQ2xCLENBQUM7QUFFRDs7R0FFRztBQUNILE1BQU0sVUFBVSxhQUFhLENBQzNCLFNBQWlCLEVBQ2pCLE1BQWtCLEVBQ2xCLElBQWtCO0lBRWxCLE1BQU0sU0FBUyxHQUFHLGVBQWUsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDakQsTUFBTSxRQUFRLEdBQWEsRUFBRSxDQUFDO0lBRTlCLEtBQUssTUFBTSxLQUFLLElBQUksU0FBUyxFQUFFLENBQUM7UUFDOUIsUUFBUSxDQUFDLElBQUksQ0FDWCxnQkFBZ0IsTUFBTSxJQUFJLFNBQVMsZ0JBQWdCLEtBQUssVUFBVSxJQUFJLENBQUMsVUFBVSxZQUFZLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FDbEgsQ0FBQztJQUNKLENBQUM7SUFFRCxPQUFPLFFBQVEsQ0FBQztBQUNsQixDQUFDO0FBRUQ7O0dBRUc7QUFDSCxNQUFNLFVBQVUsbUJBQW1CLENBQ2pDLFNBQWlCLEVBQ2pCLE1BQWtCLEVBQ2xCLElBQXdCO0lBRXhCLE1BQU0sU0FBUyxHQUFHLGVBQWUsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDakQsTUFBTSxRQUFRLEdBQWEsRUFBRSxDQUFDO0lBRTlCLEtBQUssTUFBTSxLQUFLLElBQUksU0FBUyxFQUFFLENBQUM7UUFDOUIsUUFBUSxDQUFDLElBQUksQ0FDWCxnQkFBZ0IsTUFBTSxJQUFJLFNBQVMsZ0JBQWdCLEtBQUssVUFBVSxJQUFJLENBQUMsVUFBVSxhQUFhLENBQy9GLENBQUM7SUFDSixDQUFDO0lBRUQsT0FBTyxRQUFRLENBQUM7QUFDbEIsQ0FBQyJ9
@@ -0,0 +1,16 @@
1
+ import type { TNftFamily, INftRateLimitRule, INftConnectionRateRule } from './nft.types.js';
2
+ /**
3
+ * Build a rate limit rule.
4
+ * Packets exceeding the rate are subjected to the specified action (default: drop).
5
+ */
6
+ export declare function buildRateLimitRule(tableName: string, family: TNftFamily, rule: INftRateLimitRule): string[];
7
+ /**
8
+ * Build a per-IP rate limit rule using nft meters.
9
+ * Convenience wrapper around buildRateLimitRule with perSourceIP=true.
10
+ */
11
+ export declare function buildPerIpRateLimitRule(tableName: string, family: TNftFamily, rule: Omit<INftRateLimitRule, 'perSourceIP'>): string[];
12
+ /**
13
+ * Build a new-connection rate limit rule.
14
+ * Limits the rate of new connections (ct state new) on the given port.
15
+ */
16
+ export declare function buildConnectionRateRule(tableName: string, family: TNftFamily, rule: INftConnectionRateRule): string[];
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Expand a protocol spec into concrete protocol strings.
3
+ */
4
+ function expandProtocols(protocol) {
5
+ switch (protocol ?? 'tcp') {
6
+ case 'tcp': return ['tcp'];
7
+ case 'udp': return ['udp'];
8
+ case 'both': return ['tcp', 'udp'];
9
+ }
10
+ }
11
+ /**
12
+ * Build a rate limit rule.
13
+ * Packets exceeding the rate are subjected to the specified action (default: drop).
14
+ */
15
+ export function buildRateLimitRule(tableName, family, rule) {
16
+ const protocols = expandProtocols(rule.protocol);
17
+ const chain = rule.chain ?? 'input';
18
+ const action = rule.action ?? 'drop';
19
+ const commands = [];
20
+ for (const proto of protocols) {
21
+ const portMatch = rule.port != null ? ` ${proto} dport ${rule.port}` : '';
22
+ const burstClause = rule.burst != null ? ` burst ${rule.burst} packets` : '';
23
+ if (rule.perSourceIP) {
24
+ // Per-IP rate limiting using nft meters
25
+ const meterName = `meter_${proto}_${rule.port ?? 'all'}`;
26
+ commands.push(`nft add rule ${family} ${tableName} ${chain}${portMatch} meter ${meterName} { ip saddr limit rate over ${rule.rate}${burstClause} } ${action}`);
27
+ }
28
+ else {
29
+ // Global rate limiting
30
+ commands.push(`nft add rule ${family} ${tableName} ${chain}${portMatch} limit rate over ${rule.rate}${burstClause} ${action}`);
31
+ }
32
+ }
33
+ return commands;
34
+ }
35
+ /**
36
+ * Build a per-IP rate limit rule using nft meters.
37
+ * Convenience wrapper around buildRateLimitRule with perSourceIP=true.
38
+ */
39
+ export function buildPerIpRateLimitRule(tableName, family, rule) {
40
+ return buildRateLimitRule(tableName, family, { ...rule, perSourceIP: true });
41
+ }
42
+ /**
43
+ * Build a new-connection rate limit rule.
44
+ * Limits the rate of new connections (ct state new) on the given port.
45
+ */
46
+ export function buildConnectionRateRule(tableName, family, rule) {
47
+ const protocols = expandProtocols(rule.protocol);
48
+ const commands = [];
49
+ for (const proto of protocols) {
50
+ const portMatch = rule.port != null ? ` ${proto} dport ${rule.port}` : '';
51
+ if (rule.perSourceIP) {
52
+ const meterName = `connrate_${proto}_${rule.port ?? 'all'}`;
53
+ commands.push(`nft add rule ${family} ${tableName} input ct state new${portMatch} meter ${meterName} { ip saddr limit rate over ${rule.rate} } drop`);
54
+ }
55
+ else {
56
+ commands.push(`nft add rule ${family} ${tableName} input ct state new${portMatch} limit rate over ${rule.rate} drop`);
57
+ }
58
+ }
59
+ return commands;
60
+ }
61
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmZ0LnJ1bGVidWlsZGVyLnJhdGVsaW1pdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL25mdC5ydWxlYnVpbGRlci5yYXRlbGltaXQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBRUE7O0dBRUc7QUFDSCxTQUFTLGVBQWUsQ0FBQyxRQUFpQztJQUN4RCxRQUFRLFFBQVEsSUFBSSxLQUFLLEVBQUUsQ0FBQztRQUMxQixLQUFLLEtBQUssQ0FBQyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUMzQixLQUFLLEtBQUssQ0FBQyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUMzQixLQUFLLE1BQU0sQ0FBQyxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLENBQUM7SUFDckMsQ0FBQztBQUNILENBQUM7QUFFRDs7O0dBR0c7QUFDSCxNQUFNLFVBQVUsa0JBQWtCLENBQ2hDLFNBQWlCLEVBQ2pCLE1BQWtCLEVBQ2xCLElBQXVCO0lBRXZCLE1BQU0sU0FBUyxHQUFHLGVBQWUsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDakQsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLEtBQUssSUFBSSxPQUFPLENBQUM7SUFDcEMsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLE1BQU0sSUFBSSxNQUFNLENBQUM7SUFDckMsTUFBTSxRQUFRLEdBQWEsRUFBRSxDQUFDO0lBRTlCLEtBQUssTUFBTSxLQUFLLElBQUksU0FBUyxFQUFFLENBQUM7UUFDOUIsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLElBQUksSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksS0FBSyxVQUFVLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1FBQzFFLE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxLQUFLLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQyxVQUFVLElBQUksQ0FBQyxLQUFLLFVBQVUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1FBRTdFLElBQUksSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1lBQ3JCLHdDQUF3QztZQUN4QyxNQUFNLFNBQVMsR0FBRyxTQUFTLEtBQUssSUFBSSxJQUFJLENBQUMsSUFBSSxJQUFJLEtBQUssRUFBRSxDQUFDO1lBQ3pELFFBQVEsQ0FBQyxJQUFJLENBQ1gsZ0JBQWdCLE1BQU0sSUFBSSxTQUFTLElBQUksS0FBSyxHQUFHLFNBQVMsVUFBVSxTQUFTLCtCQUErQixJQUFJLENBQUMsSUFBSSxHQUFHLFdBQVcsTUFBTSxNQUFNLEVBQUUsQ0FDaEosQ0FBQztRQUNKLENBQUM7YUFBTSxDQUFDO1lBQ04sdUJBQXVCO1lBQ3ZCLFFBQVEsQ0FBQyxJQUFJLENBQ1gsZ0JBQWdCLE1BQU0sSUFBSSxTQUFTLElBQUksS0FBSyxHQUFHLFNBQVMsb0JBQW9CLElBQUksQ0FBQyxJQUFJLEdBQUcsV0FBVyxJQUFJLE1BQU0sRUFBRSxDQUNoSCxDQUFDO1FBQ0osQ0FBQztJQUNILENBQUM7SUFFRCxPQUFPLFFBQVEsQ0FBQztBQUNsQixDQUFDO0FBRUQ7OztHQUdHO0FBQ0gsTUFBTSxVQUFVLHVCQUF1QixDQUNyQyxTQUFpQixFQUNqQixNQUFrQixFQUNsQixJQUE0QztJQUU1QyxPQUFPLGtCQUFrQixDQUFDLFNBQVMsRUFBRSxNQUFNLEVBQUUsRUFBRSxHQUFHLElBQUksRUFBRSxXQUFXLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztBQUMvRSxDQUFDO0FBRUQ7OztHQUdHO0FBQ0gsTUFBTSxVQUFVLHVCQUF1QixDQUNyQyxTQUFpQixFQUNqQixNQUFrQixFQUNsQixJQUE0QjtJQUU1QixNQUFNLFNBQVMsR0FBRyxlQUFlLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQ2pELE1BQU0sUUFBUSxHQUFhLEVBQUUsQ0FBQztJQUU5QixLQUFLLE1BQU0sS0FBSyxJQUFJLFNBQVMsRUFBRSxDQUFDO1FBQzlCLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxJQUFJLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLEtBQUssVUFBVSxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztRQUUxRSxJQUFJLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUNyQixNQUFNLFNBQVMsR0FBRyxZQUFZLEtBQUssSUFBSSxJQUFJLENBQUMsSUFBSSxJQUFJLEtBQUssRUFBRSxDQUFDO1lBQzVELFFBQVEsQ0FBQyxJQUFJLENBQ1gsZ0JBQWdCLE1BQU0sSUFBSSxTQUFTLHNCQUFzQixTQUFTLFVBQVUsU0FBUywrQkFBK0IsSUFBSSxDQUFDLElBQUksU0FBUyxDQUN2SSxDQUFDO1FBQ0osQ0FBQzthQUFNLENBQUM7WUFDTixRQUFRLENBQUMsSUFBSSxDQUNYLGdCQUFnQixNQUFNLElBQUksU0FBUyxzQkFBc0IsU0FBUyxvQkFBb0IsSUFBSSxDQUFDLElBQUksT0FBTyxDQUN2RyxDQUFDO1FBQ0osQ0FBQztJQUNILENBQUM7SUFFRCxPQUFPLFFBQVEsQ0FBQztBQUNsQixDQUFDIn0=
@@ -0,0 +1,13 @@
1
+ import type { TNftFamily } from './nft.types.js';
2
+ /**
3
+ * Build commands to create the nftables table and NAT chains (prerouting + postrouting).
4
+ */
5
+ export declare function buildTableSetup(tableName: string, family?: TNftFamily): string[];
6
+ /**
7
+ * Build commands to create filter chains (input, forward, output).
8
+ */
9
+ export declare function buildFilterChains(tableName: string, family?: TNftFamily): string[];
10
+ /**
11
+ * Build command to delete the entire nftables table.
12
+ */
13
+ export declare function buildTableCleanup(tableName: string, family?: TNftFamily): string[];
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Build commands to create the nftables table and NAT chains (prerouting + postrouting).
3
+ */
4
+ export function buildTableSetup(tableName, family = 'ip') {
5
+ return [
6
+ `nft add table ${family} ${tableName}`,
7
+ `nft add chain ${family} ${tableName} prerouting { type nat hook prerouting priority 0 \\; }`,
8
+ `nft add chain ${family} ${tableName} postrouting { type nat hook postrouting priority 100 \\; }`,
9
+ ];
10
+ }
11
+ /**
12
+ * Build commands to create filter chains (input, forward, output).
13
+ */
14
+ export function buildFilterChains(tableName, family = 'ip') {
15
+ return [
16
+ `nft add chain ${family} ${tableName} input { type filter hook input priority 0 \\; policy accept \\; }`,
17
+ `nft add chain ${family} ${tableName} forward { type filter hook forward priority 0 \\; policy accept \\; }`,
18
+ `nft add chain ${family} ${tableName} output { type filter hook output priority 0 \\; policy accept \\; }`,
19
+ ];
20
+ }
21
+ /**
22
+ * Build command to delete the entire nftables table.
23
+ */
24
+ export function buildTableCleanup(tableName, family = 'ip') {
25
+ return [`nft delete table ${family} ${tableName}`];
26
+ }
27
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmZ0LnJ1bGVidWlsZGVyLnRhYmxlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvbmZ0LnJ1bGVidWlsZGVyLnRhYmxlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUVBOztHQUVHO0FBQ0gsTUFBTSxVQUFVLGVBQWUsQ0FBQyxTQUFpQixFQUFFLFNBQXFCLElBQUk7SUFDMUUsT0FBTztRQUNMLGlCQUFpQixNQUFNLElBQUksU0FBUyxFQUFFO1FBQ3RDLGlCQUFpQixNQUFNLElBQUksU0FBUyx5REFBeUQ7UUFDN0YsaUJBQWlCLE1BQU0sSUFBSSxTQUFTLDZEQUE2RDtLQUNsRyxDQUFDO0FBQ0osQ0FBQztBQUVEOztHQUVHO0FBQ0gsTUFBTSxVQUFVLGlCQUFpQixDQUFDLFNBQWlCLEVBQUUsU0FBcUIsSUFBSTtJQUM1RSxPQUFPO1FBQ0wsaUJBQWlCLE1BQU0sSUFBSSxTQUFTLG9FQUFvRTtRQUN4RyxpQkFBaUIsTUFBTSxJQUFJLFNBQVMsd0VBQXdFO1FBQzVHLGlCQUFpQixNQUFNLElBQUksU0FBUyxzRUFBc0U7S0FDM0csQ0FBQztBQUNKLENBQUM7QUFFRDs7R0FFRztBQUNILE1BQU0sVUFBVSxpQkFBaUIsQ0FBQyxTQUFpQixFQUFFLFNBQXFCLElBQUk7SUFDNUUsT0FBTyxDQUFDLG9CQUFvQixNQUFNLElBQUksU0FBUyxFQUFFLENBQUMsQ0FBQztBQUNyRCxDQUFDIn0=
@@ -0,0 +1,88 @@
1
+ export type TNftProtocol = 'tcp' | 'udp' | 'both';
2
+ export type TNftFamily = 'ip' | 'ip6' | 'inet';
3
+ export type TNftChainHook = 'prerouting' | 'postrouting' | 'input' | 'output' | 'forward';
4
+ export type TNftChainType = 'nat' | 'filter';
5
+ export type TNftPolicy = 'accept' | 'drop';
6
+ export type TFirewallAction = 'accept' | 'drop' | 'reject';
7
+ export type TCtState = 'new' | 'established' | 'related' | 'invalid';
8
+ export interface INftDnatRule {
9
+ sourcePort: number;
10
+ targetHost: string;
11
+ targetPort: number;
12
+ protocol?: TNftProtocol;
13
+ preserveSourceIP?: boolean;
14
+ }
15
+ export interface INftSnatRule {
16
+ sourceAddress: string;
17
+ targetPort: number;
18
+ protocol?: TNftProtocol;
19
+ }
20
+ export interface INftMasqueradeRule {
21
+ targetPort: number;
22
+ protocol?: TNftProtocol;
23
+ }
24
+ export interface INftRateLimitRule {
25
+ /** Port to rate-limit on. If omitted, applies to all ports. */
26
+ port?: number;
27
+ protocol?: TNftProtocol;
28
+ /** Rate expression, e.g. "100/second", "10 mbytes/second" */
29
+ rate: string;
30
+ /** Burst allowance in packets or bytes */
31
+ burst?: number;
32
+ /** If true, track rate per source IP using nft meters */
33
+ perSourceIP?: boolean;
34
+ /** Action for packets exceeding rate. Default: 'drop' */
35
+ action?: TFirewallAction;
36
+ /** Chain to apply the rule to. Default: 'input' */
37
+ chain?: 'input' | 'forward' | 'prerouting';
38
+ }
39
+ export interface INftConnectionRateRule {
40
+ /** Port to limit new connections on */
41
+ port?: number;
42
+ protocol?: TNftProtocol;
43
+ /** New connection rate, e.g. "10/second" */
44
+ rate: string;
45
+ /** If true, track per source IP */
46
+ perSourceIP?: boolean;
47
+ }
48
+ export interface INftFirewallRule {
49
+ direction: 'input' | 'output' | 'forward';
50
+ action: TFirewallAction;
51
+ sourceIP?: string;
52
+ destIP?: string;
53
+ sourcePort?: number;
54
+ destPort?: number;
55
+ protocol?: TNftProtocol;
56
+ ctStates?: TCtState[];
57
+ comment?: string;
58
+ }
59
+ export interface INftIPSetConfig {
60
+ name: string;
61
+ type: 'ipv4_addr' | 'ipv6_addr' | 'inet_service';
62
+ elements?: string[];
63
+ comment?: string;
64
+ }
65
+ export interface INftRuleGroup {
66
+ id: string;
67
+ commands: string[];
68
+ createdAt: number;
69
+ }
70
+ export interface ISmartNftablesOptions {
71
+ /** nftables table name. Default: 'smartnftables' */
72
+ tableName?: string;
73
+ /** Address family. Default: 'ip' */
74
+ family?: TNftFamily;
75
+ /** If true, generate commands but never execute them */
76
+ dryRun?: boolean;
77
+ }
78
+ export interface INftStatus {
79
+ initialized: boolean;
80
+ tableName: string;
81
+ family: TNftFamily;
82
+ isRoot: boolean;
83
+ activeGroups: number;
84
+ groups: Record<string, {
85
+ ruleCount: number;
86
+ createdAt: number;
87
+ }>;
88
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmZ0LnR5cGVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvbmZ0LnR5cGVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiIifQ==
@@ -0,0 +1,6 @@
1
+ import * as childProcess from 'node:child_process';
2
+ import * as util from 'node:util';
3
+ export { childProcess, util, };
4
+ import * as smartlog from '@push.rocks/smartlog';
5
+ import * as smartpromise from '@push.rocks/smartpromise';
6
+ export { smartlog, smartpromise, };
@@ -0,0 +1,9 @@
1
+ // node native scope
2
+ import * as childProcess from 'node:child_process';
3
+ import * as util from 'node:util';
4
+ export { childProcess, util, };
5
+ // @push.rocks scope
6
+ import * as smartlog from '@push.rocks/smartlog';
7
+ import * as smartpromise from '@push.rocks/smartpromise';
8
+ export { smartlog, smartpromise, };
9
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGx1Z2lucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL3BsdWdpbnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsb0JBQW9CO0FBQ3BCLE9BQU8sS0FBSyxZQUFZLE1BQU0sb0JBQW9CLENBQUM7QUFDbkQsT0FBTyxLQUFLLElBQUksTUFBTSxXQUFXLENBQUM7QUFFbEMsT0FBTyxFQUNMLFlBQVksRUFDWixJQUFJLEdBQ0wsQ0FBQztBQUVGLG9CQUFvQjtBQUNwQixPQUFPLEtBQUssUUFBUSxNQUFNLHNCQUFzQixDQUFDO0FBQ2pELE9BQU8sS0FBSyxZQUFZLE1BQU0sMEJBQTBCLENBQUM7QUFDekQsT0FBTyxFQUNMLFFBQVEsRUFDUixZQUFZLEdBQ2IsQ0FBQyJ9
package/license ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Task Venture Capital GmbH
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/package.json ADDED
@@ -0,0 +1,57 @@
1
+ {
2
+ "name": "@push.rocks/smartnftables",
3
+ "version": "1.0.1",
4
+ "private": false,
5
+ "description": "A TypeScript module for managing nftables rules including NAT, firewall, and rate limiting with a high-level API.",
6
+ "main": "dist_ts/index.js",
7
+ "typings": "dist_ts/index.d.ts",
8
+ "type": "module",
9
+ "author": "Lossless GmbH",
10
+ "license": "MIT",
11
+ "scripts": {
12
+ "test": "(tstest test/**/test*.ts --verbose --timeout 60)",
13
+ "build": "(tsbuild tsfolders)",
14
+ "format": "(gitzone format)",
15
+ "buildDocs": "tsdoc"
16
+ },
17
+ "devDependencies": {
18
+ "@git.zone/tsbuild": "^4.4.0",
19
+ "@git.zone/tsrun": "^2.0.2",
20
+ "@git.zone/tstest": "^3.6.0",
21
+ "@types/node": "^25.5.0",
22
+ "typescript": "^6.0.2"
23
+ },
24
+ "dependencies": {
25
+ "@push.rocks/smartlog": "^3.2.1",
26
+ "@push.rocks/smartpromise": "^4.2.3"
27
+ },
28
+ "files": [
29
+ "ts/**/*",
30
+ "dist/**/*",
31
+ "dist_*/**/*",
32
+ "dist_ts/**/*",
33
+ "assets/**/*",
34
+ "readme.md",
35
+ "changelog.md"
36
+ ],
37
+ "keywords": [
38
+ "nftables",
39
+ "firewall",
40
+ "nat",
41
+ "rate limiting",
42
+ "network",
43
+ "linux",
44
+ "packet filter",
45
+ "port forwarding",
46
+ "ip sets",
47
+ "kernel firewall"
48
+ ],
49
+ "homepage": "https://code.foss.global/push.rocks/smartnftables#readme",
50
+ "repository": {
51
+ "type": "git",
52
+ "url": "https://code.foss.global/push.rocks/smartnftables.git"
53
+ },
54
+ "bugs": {
55
+ "url": "https://code.foss.global/push.rocks/smartnftables/issues"
56
+ }
57
+ }