92 lines
2.6 KiB
JavaScript
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');
|
|
});
|
|
} |