Add per-device VPN and direct routing policies
This commit is contained in:
@@ -6,6 +6,7 @@ import { createSingboxRuntime } from './singboxRuntime.js';
|
||||
import { buildVersionInfo } from './version.js';
|
||||
import { readNeighborSnapshot } from './adapters/neighbors.js';
|
||||
import { createDeviceTrafficService } from './services/deviceTrafficService.js';
|
||||
import { createDevicePolicyService } from './services/devicePolicyService.js';
|
||||
|
||||
const socketPath = settings.dataplaneSocket;
|
||||
const runtime = createSingboxRuntime({
|
||||
@@ -20,8 +21,40 @@ const traffic = createDeviceTrafficService({
|
||||
downloadChain: settings.trafficDownloadChain,
|
||||
bypassCidrs: settings.bypassCidrs,
|
||||
});
|
||||
const devicePolicy = createDevicePolicyService({
|
||||
chain: settings.devicePolicyChain,
|
||||
tproxyPort: settings.tproxyPort,
|
||||
tproxyMark: settings.tproxyMark,
|
||||
});
|
||||
let ready = false;
|
||||
let trafficTimer = null;
|
||||
const MAX_POLICY_BODY_BYTES = 256 * 1024;
|
||||
|
||||
function readJson(req) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const chunks = [];
|
||||
let size = 0;
|
||||
let tooLarge = false;
|
||||
req.on('data', (chunk) => {
|
||||
size += chunk.length;
|
||||
if (!tooLarge && size > MAX_POLICY_BODY_BYTES) {
|
||||
tooLarge = true;
|
||||
reject(new Error('Device policy request слишком большой'));
|
||||
return;
|
||||
}
|
||||
if (!tooLarge) chunks.push(chunk);
|
||||
});
|
||||
req.on('end', () => {
|
||||
if (tooLarge) return;
|
||||
try {
|
||||
resolve(JSON.parse(Buffer.concat(chunks).toString('utf8') || '{}'));
|
||||
} catch {
|
||||
reject(new Error('Device policy request содержит невалидный JSON'));
|
||||
}
|
||||
});
|
||||
req.on('error', reject);
|
||||
});
|
||||
}
|
||||
|
||||
function sendJson(res, statusCode, payload) {
|
||||
res.writeHead(statusCode, { 'content-type': 'application/json; charset=utf-8' });
|
||||
@@ -35,6 +68,7 @@ const server = http.createServer(async (req, res) => {
|
||||
...await runtime.refresh(),
|
||||
gatewayBackendVersion: versionInfo.components.gatewayBackend,
|
||||
singBoxVersion: versionInfo.runtime.singBox,
|
||||
devicePolicy: devicePolicy.snapshot(),
|
||||
ready,
|
||||
});
|
||||
}
|
||||
@@ -44,6 +78,13 @@ const server = http.createServer(async (req, res) => {
|
||||
if (req.method === 'GET' && req.url === '/device-traffic') {
|
||||
return sendJson(res, 200, traffic.snapshot());
|
||||
}
|
||||
if (req.method === 'GET' && req.url === '/device-policy') {
|
||||
return sendJson(res, 200, devicePolicy.snapshot());
|
||||
}
|
||||
if (req.method === 'PUT' && req.url === '/device-policy') {
|
||||
const body = await readJson(req);
|
||||
return sendJson(res, 200, await devicePolicy.apply(body.devices));
|
||||
}
|
||||
if (req.method === 'POST' && req.url === '/apply') {
|
||||
return sendJson(res, 200, await runtime.apply());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user