Files
smithy-pelican-router-webho…/services/natQueue.js
2026-03-23 17:54:41 +02:00

92 lines
2.6 KiB
JavaScript

import { error, info, success } from "../util/Console.js";
const queue = [];
let running = false;
function enqueue(task) {
queue.push(task);
if (!running) processQueue();
}
async function processQueue() {
if (queue.length === 0) { running = false; return; }
running = true;
const t = queue.shift();
try { await t(); } catch (err) { error('Q error ' + err); }
setImmediate(processQueue);
}
async function opnsenseRequest(method, path, body = null) {
const auth = Buffer.from(`${process.env.OPNSENSE_KEY}:${process.env.OPNSENSE_SECRET}`).toString('base64');
const opts = {
method,
headers: {
'Authorization': `Basic ${auth}`,
},
};
if (body) {
opts.headers['Content-Type'] = 'application/json';
opts.body = JSON.stringify(body);
}
const res = await fetch(`${process.env.OPNSENSE_HOST}${path}`, opts);
const text = await res.text();
try {
return JSON.parse(text);
} catch {
error(`got non-json response: ${text}`);
return null;
}
}
async function applyRules() {
await opnsenseRequest('POST', '/api/firewall/d_nat/apply');
}
export function enqueueNatAdd(ip, port, proto = 'tcp/udp') {
enqueue(async () => {
info(`adding rule udp+tcp at ${ip}:${port}`);
await opnsenseRequest('POST', '/api/firewall/d_nat/addRule', {
rule: {
interface: 'wan',
protocol: 'tcp/udp',
destination: {
network: 'wanip',
port: `${port}`,
},
target: ip,
'local-port': `${port}`,
descr: `pelican-${ip}-${port}`,
disabled: '0',
}
});
await applyRules();
success(`added rule udp+tcp at ${ip}:${port}`);
});
}
export function enqueueNatRemove(ip, port, proto = 'tcp/udp') {
enqueue(async () => {
info(`deleting rule udp+tcp at ${ip}:${port}`);
const result = await opnsenseRequest('POST', '/api/firewall/d_nat/searchRule', {
current: 1,
rowCount: 1000,
searchPhrase: `pelican-${ip}-${port}`,
});
const rows = result?.rows || [];
for (const rule of rows) {
if (rule.descr === `pelican-${ip}-${port}`) {
let res = await opnsenseRequest('POST', `/api/firewall/d_nat/delRule/${rule.uuid}`);
info(JSON.stringify(res));
success(`deleted rule udp+tcp at ${ip}:${port}`);
}
}
await applyRules();
success('Successfully applied rules');
});
}