115 lines
3.0 KiB
TypeScript
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();
|