import { tap, expect } from '@git.zone/tstest/tapbundle'; import { buildFirewallRule, buildIPSetCreate, buildIPSetAddElements, buildIPSetRemoveElements, buildIPSetDelete, buildIPSetMatchRule, } from '../ts/nft.rulebuilder.firewall.js'; tap.test('should build basic firewall drop rule', async () => { const rules = buildFirewallRule('mytable', 'ip', { direction: 'input', action: 'drop', sourceIP: '192.168.1.100', }); expect(rules.length).toEqual(1); expect(rules[0]).toInclude('mytable input'); expect(rules[0]).toInclude('ip saddr 192.168.1.100'); expect(rules[0]).toInclude('drop'); }); tap.test('should build firewall rule with port and protocol', async () => { const rules = buildFirewallRule('mytable', 'ip', { direction: 'input', action: 'accept', destPort: 22, protocol: 'tcp', sourceIP: '10.0.0.0/8', }); expect(rules.length).toEqual(1); expect(rules[0]).toInclude('tcp'); expect(rules[0]).toInclude('ip saddr 10.0.0.0/8'); expect(rules[0]).toInclude('tcp dport 22'); expect(rules[0]).toInclude('accept'); }); tap.test('should build firewall rule with ct state', async () => { const rules = buildFirewallRule('mytable', 'ip', { direction: 'input', action: 'accept', ctStates: ['established', 'related'], }); expect(rules.length).toEqual(1); expect(rules[0]).toInclude('ct state { established, related }'); expect(rules[0]).toInclude('accept'); }); tap.test('should build firewall rule with comment', async () => { const rules = buildFirewallRule('mytable', 'ip', { direction: 'input', action: 'drop', sourceIP: '1.2.3.4', comment: 'block bad actor', }); expect(rules[0]).toInclude('comment "block bad actor"'); }); tap.test('should build firewall rule for both protocols', async () => { const rules = buildFirewallRule('mytable', 'ip', { direction: 'forward', action: 'accept', destPort: 80, protocol: 'both', }); expect(rules.length).toEqual(2); expect(rules[0]).toInclude('tcp'); expect(rules[1]).toInclude('udp'); }); tap.test('should build IP set create command', async () => { const cmds = buildIPSetCreate('mytable', 'ip', { name: 'blocklist', type: 'ipv4_addr', }); expect(cmds.length).toEqual(1); expect(cmds[0]).toInclude('add set ip mytable blocklist'); expect(cmds[0]).toInclude('type ipv4_addr'); }); tap.test('should build IP set with initial elements', async () => { const cmds = buildIPSetCreate('mytable', 'ip', { name: 'trusted', type: 'ipv4_addr', elements: ['10.0.0.1', '10.0.0.2', '10.0.0.3'], }); expect(cmds.length).toEqual(2); expect(cmds[1]).toInclude('add element'); expect(cmds[1]).toInclude('10.0.0.1, 10.0.0.2, 10.0.0.3'); }); tap.test('should build IP set add elements command', async () => { const cmds = buildIPSetAddElements('mytable', 'ip', 'blocklist', ['1.2.3.4', '5.6.7.8']); expect(cmds.length).toEqual(1); expect(cmds[0]).toInclude('add element ip mytable blocklist'); expect(cmds[0]).toInclude('1.2.3.4, 5.6.7.8'); }); tap.test('should return empty for add with no elements', async () => { const cmds = buildIPSetAddElements('mytable', 'ip', 'blocklist', []); expect(cmds.length).toEqual(0); }); tap.test('should build IP set remove elements command', async () => { const cmds = buildIPSetRemoveElements('mytable', 'ip', 'blocklist', ['1.2.3.4']); expect(cmds.length).toEqual(1); expect(cmds[0]).toInclude('delete element ip mytable blocklist'); expect(cmds[0]).toInclude('1.2.3.4'); }); tap.test('should build IP set delete command', async () => { const cmds = buildIPSetDelete('mytable', 'ip', 'blocklist'); expect(cmds.length).toEqual(1); expect(cmds[0]).toInclude('delete set ip mytable blocklist'); }); tap.test('should build IP set match rule', async () => { const cmds = buildIPSetMatchRule('mytable', 'ip', { setName: 'blocklist', direction: 'input', matchField: 'saddr', action: 'drop', }); expect(cmds.length).toEqual(1); expect(cmds[0]).toInclude('ip saddr @blocklist'); expect(cmds[0]).toInclude('drop'); }); export default tap.start();