111 lines
3.6 KiB
JavaScript
111 lines
3.6 KiB
JavaScript
import assert from "node:assert/strict";
|
|
import { readFile } from "node:fs/promises";
|
|
import { dirname, resolve } from "node:path";
|
|
import test from "node:test";
|
|
import { fileURLToPath } from "node:url";
|
|
|
|
const devicePlaneRoot = resolve(
|
|
dirname(fileURLToPath(import.meta.url)),
|
|
"../../..",
|
|
);
|
|
|
|
test("single-NIC ingress source has no host publication and a fixed ipvlan", async () => {
|
|
const baseline = await readFile(
|
|
resolve(devicePlaneRoot, "docker-compose.device-edge.yml"),
|
|
"utf8",
|
|
);
|
|
const ingress = await readFile(
|
|
resolve(devicePlaneRoot, "docker-compose.device-edge.ingress.yml"),
|
|
"utf8",
|
|
);
|
|
|
|
assert.match(
|
|
baseline,
|
|
/DEVICE_EDGE_RELAY_HEALTH_HOST: 127\.0\.0\.1/,
|
|
);
|
|
assert.doesNotMatch(baseline, /^\s+ports:/m);
|
|
assert.doesNotMatch(baseline, /device-edge-control/);
|
|
|
|
for (const required of [
|
|
'DEVICE_EDGE_RELAY_INGRESS_ENABLED: "true"',
|
|
"DEVICE_EDGE_RELAY_UPSTREAM_HOST: device-edge-backhaul",
|
|
'DEVICE_EDGE_RELAY_UPSTREAM_PORT: "19921"',
|
|
"name: nodedc-device-edge-ingress",
|
|
"driver: ipvlan",
|
|
"parent: enp1s0f0",
|
|
"ipvlan_mode: l2",
|
|
"ipv4_address: 192.168.71.253",
|
|
"subnet: 192.168.68.0/22",
|
|
"gateway: 192.168.68.1",
|
|
"gw_priority: 100",
|
|
"DEVICE_EDGE_RELAY_SOURCE_POLICY: public-ipv4-only",
|
|
'DEVICE_EDGE_RELAY_MAX_TRACKED_SOURCE_ADDRESSES: "2048"',
|
|
'DEVICE_EDGE_RELAY_MAX_BYTES_PER_DIRECTION: "262144"',
|
|
]) {
|
|
assert.ok(ingress.includes(required), `missing ingress boundary: ${required}`);
|
|
}
|
|
|
|
for (const forbidden of [
|
|
"ports:",
|
|
"network_mode: host",
|
|
"privileged: true",
|
|
"DEVICE_EDGE_RELAY_COMMAND",
|
|
"0.0.0.0:9921:9921",
|
|
]) {
|
|
assert.ok(
|
|
!ingress.includes(forbidden),
|
|
`forbidden ingress boundary: ${forbidden}`,
|
|
);
|
|
}
|
|
});
|
|
|
|
test("ingress descriptor keeps address approval and router exposure gated", async () => {
|
|
const descriptor = JSON.parse(await readFile(
|
|
resolve(
|
|
devicePlaneRoot,
|
|
"deployment/device-edge-ingress-ipvlan-v1.json",
|
|
),
|
|
"utf8",
|
|
));
|
|
|
|
assert.equal(descriptor.component, "device-edge");
|
|
assert.deepEqual(descriptor.selectedServices, ["device-edge-relay"]);
|
|
assert.deepEqual(
|
|
descriptor.preservedServices,
|
|
["device-edge-backhaul", "tailnet"],
|
|
);
|
|
assert.equal(descriptor.ingressIpv4Approval, "approved-outside-dhcp-pool");
|
|
assert.equal(descriptor.hostPortPublication, "disabled");
|
|
assert.equal(descriptor.healthPublication, "disabled");
|
|
assert.equal(descriptor.privateUpstream, "device-edge-backhaul:19921");
|
|
assert.equal(descriptor.protocolInspection, "gateway-owned");
|
|
assert.equal(descriptor.discoveryLifecycle, "quarantine");
|
|
assert.equal(descriptor.commandTransport, "disabled");
|
|
assert.equal(descriptor.gelios, "untouched");
|
|
assert.equal(descriptor.amneziaHostFullTunnel, "preserved");
|
|
assert.equal(descriptor.routerNatFirewall, "separate-manual-gate");
|
|
});
|
|
|
|
test("admission-gate descriptor pins the fail-closed relay boundary", async () => {
|
|
const descriptor = JSON.parse(await readFile(
|
|
resolve(
|
|
devicePlaneRoot,
|
|
"deployment/device-edge-admission-gate-v1.json",
|
|
),
|
|
"utf8",
|
|
));
|
|
|
|
assert.equal(
|
|
descriptor.schemaVersion,
|
|
"nodedc.device-edge.admission-gate.v1",
|
|
);
|
|
assert.equal(descriptor.sourceAdmission, "public-ipv4-only");
|
|
assert.equal(descriptor.maxTrackedSourceAddresses, 2048);
|
|
assert.equal(descriptor.maxBytesPerDirection, 262144);
|
|
assert.equal(descriptor.hostPortPublication, "disabled");
|
|
assert.equal(descriptor.healthPublication, "disabled");
|
|
assert.equal(descriptor.commandTransport, "disabled");
|
|
assert.equal(descriptor.gelios, "untouched");
|
|
assert.equal(descriptor.routerNatFirewall, "separate-manual-gate");
|
|
});
|