feat(firewall): add IP set blocking convenience API with CIDR interval support and optional rule comments
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import type { SmartNftables } from './nft.manager.js';
|
||||
import type { INftFirewallRule, INftIPSetConfig } from './nft.types.js';
|
||||
import type { INftFirewallRule, INftIPSetBlockOptions, INftIPSetConfig } from './nft.types.js';
|
||||
import {
|
||||
buildFirewallRule,
|
||||
buildIPSetCreate,
|
||||
@@ -82,6 +82,41 @@ export class FirewallManager {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience: block many IPs or CIDR subnets using one nftables set and
|
||||
* one matching drop rule. This is substantially cheaper than one rule per IP.
|
||||
*/
|
||||
public async blockIPSet(groupId: string, options: INftIPSetBlockOptions): Promise<void> {
|
||||
const ips = [...new Set(options.ips)].filter(Boolean).sort();
|
||||
if (ips.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
await this.parent.ensureFilterChains();
|
||||
|
||||
const setName = options.setName ?? `${groupId.replace(/[^a-zA-Z0-9_]/g, '_')}_set`;
|
||||
const setType = options.type ?? (this.parent.family === 'ip6' ? 'ipv6_addr' : 'ipv4_addr');
|
||||
const needsIntervalSet = ips.some((ip) => ip.includes('/'));
|
||||
const direction = options.direction ?? 'input';
|
||||
const commands = [
|
||||
...buildIPSetCreate(this.parent.tableName, this.parent.family, {
|
||||
name: setName,
|
||||
type: setType,
|
||||
elements: ips,
|
||||
interval: needsIntervalSet,
|
||||
}),
|
||||
...buildIPSetMatchRule(this.parent.tableName, this.parent.family, {
|
||||
setName,
|
||||
direction,
|
||||
matchField: 'saddr',
|
||||
action: 'drop',
|
||||
comment: options.comment,
|
||||
}),
|
||||
];
|
||||
|
||||
await this.parent.applyRuleGroup(`fw:blockset:${groupId}`, commands);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience: allow only specific IPs on a port.
|
||||
* Adds accept rules for each IP, then a drop rule for everything else on that port.
|
||||
|
||||
Reference in New Issue
Block a user