Files
smartnftables/test/test.rulebuilder-ratelimit.ts
2026-03-26 10:32:05 +00:00

115 lines
3.0 KiB
TypeScript

import { tap, expect } from '@git.zone/tstest/tapbundle';
import {
buildRateLimitRule,
buildPerIpRateLimitRule,
buildConnectionRateRule,
} from '../ts/nft.rulebuilder.ratelimit.js';
tap.test('should build global rate limit rule', async () => {
const rules = buildRateLimitRule('mytable', 'ip', {
port: 80,
protocol: 'tcp',
rate: '100/second',
});
expect(rules.length).toEqual(1);
expect(rules[0]).toInclude('limit rate over 100/second');
expect(rules[0]).toInclude('tcp dport 80');
expect(rules[0]).toInclude('drop');
});
tap.test('should build rate limit with burst', async () => {
const rules = buildRateLimitRule('mytable', 'ip', {
port: 8080,
rate: '50/second',
burst: 20,
});
expect(rules[0]).toInclude('burst 20 packets');
});
tap.test('should build rate limit with custom action', async () => {
const rules = buildRateLimitRule('mytable', 'ip', {
port: 80,
rate: '100/second',
action: 'reject',
});
expect(rules[0]).toInclude('reject');
expect(rules[0]).not.toInclude('drop');
});
tap.test('should build per-IP rate limit using meters', async () => {
const rules = buildRateLimitRule('mytable', 'ip', {
port: 80,
protocol: 'tcp',
rate: '10/second',
perSourceIP: true,
});
expect(rules.length).toEqual(1);
expect(rules[0]).toInclude('meter');
expect(rules[0]).toInclude('ip saddr');
expect(rules[0]).toInclude('limit rate over 10/second');
});
tap.test('should build per-IP rate limit via convenience function', async () => {
const rules = buildPerIpRateLimitRule('mytable', 'ip', {
port: 443,
rate: '50/second',
});
expect(rules[0]).toInclude('meter');
expect(rules[0]).toInclude('ip saddr');
});
tap.test('should build rate limit on custom chain', async () => {
const rules = buildRateLimitRule('mytable', 'ip', {
port: 80,
rate: '100/second',
chain: 'forward',
});
expect(rules[0]).toInclude('mytable forward');
});
tap.test('should build connection rate rule', async () => {
const rules = buildConnectionRateRule('mytable', 'ip', {
port: 22,
protocol: 'tcp',
rate: '5/second',
});
expect(rules.length).toEqual(1);
expect(rules[0]).toInclude('ct state new');
expect(rules[0]).toInclude('tcp dport 22');
expect(rules[0]).toInclude('limit rate over 5/second');
expect(rules[0]).toInclude('drop');
});
tap.test('should build per-IP connection rate rule', async () => {
const rules = buildConnectionRateRule('mytable', 'ip', {
port: 80,
rate: '10/second',
perSourceIP: true,
});
expect(rules[0]).toInclude('meter connrate');
expect(rules[0]).toInclude('ip saddr');
expect(rules[0]).toInclude('ct state new');
});
tap.test('should build rate limit for both protocols', async () => {
const rules = buildRateLimitRule('mytable', 'ip', {
port: 53,
protocol: 'both',
rate: '100/second',
});
expect(rules.length).toEqual(2);
expect(rules[0]).toInclude('tcp');
expect(rules[1]).toInclude('udp');
});
export default tap.start();