fix: add explicit tailnet gateway bind

This commit is contained in:
Peter Steinberger
2026-01-21 20:35:39 +00:00
parent 45c1ccdfcf
commit b5fd66c92d
30 changed files with 143 additions and 71 deletions

View File

@@ -218,14 +218,14 @@ describe("legacy config detection", () => {
expect(res.config?.gateway?.auth?.mode).toBe("token");
expect((res.config?.gateway as { token?: string })?.token).toBeUndefined();
});
it("migrates gateway.bind from 'tailnet' to 'auto'", async () => {
it("keeps gateway.bind tailnet", async () => {
vi.resetModules();
const { migrateLegacyConfig } = await import("./config.js");
const res = migrateLegacyConfig({
gateway: { bind: "tailnet" as const },
});
expect(res.changes).toContain("Migrated gateway.bind from 'tailnet' to 'auto'.");
expect(res.config?.gateway?.bind).toBe("auto");
expect(res.changes).not.toContain("Migrated gateway.bind from 'tailnet' to 'auto'.");
expect(res.config?.gateway?.bind).toBe("tailnet");
});
it('rejects telegram.dmPolicy="open" without allowFrom "*"', async () => {
vi.resetModules();

View File

@@ -143,21 +143,4 @@ export const LEGACY_CONFIG_MIGRATIONS_PART_3: LegacyConfigMigration[] = [
delete raw.identity;
},
},
{
id: "bind-tailnet->auto",
describe: "Remap gateway bind 'tailnet' to 'auto'",
apply: (raw, changes) => {
const migrateBind = (obj: Record<string, unknown> | null | undefined, key: string) => {
if (!obj) return;
const bind = obj.bind;
if (bind === "tailnet") {
obj.bind = "auto";
changes.push(`Migrated ${key}.bind from 'tailnet' to 'auto'.`);
}
};
const gateway = getRecord(raw.gateway);
migrateBind(gateway, "gateway");
},
},
];

View File

@@ -1,4 +1,4 @@
export type GatewayBindMode = "auto" | "lan" | "loopback" | "custom";
export type GatewayBindMode = "auto" | "lan" | "loopback" | "custom" | "tailnet";
export type GatewayTlsConfig = {
/** Enable TLS for the gateway server. */
@@ -189,9 +189,10 @@ export type GatewayConfig = {
mode?: "local" | "remote";
/**
* Bind address policy for the Gateway WebSocket + Control UI HTTP server.
* - auto: Tailnet IPv4 if available, else 0.0.0.0 (fallback to all interfaces)
* - auto: Loopback (127.0.0.1) if available, else 0.0.0.0 (fallback to all interfaces)
* - lan: 0.0.0.0 (all interfaces, no fallback)
* - loopback: 127.0.0.1 (local-only)
* - tailnet: Tailnet IPv4 if available (100.64.0.0/10), else loopback
* - custom: User-specified IP, fallback to 0.0.0.0 if unavailable (requires customBindHost)
* Default: loopback (127.0.0.1).
*/

View File

@@ -270,7 +270,13 @@ export const ClawdbotSchema = z
port: z.number().int().positive().optional(),
mode: z.union([z.literal("local"), z.literal("remote")]).optional(),
bind: z
.union([z.literal("auto"), z.literal("lan"), z.literal("loopback"), z.literal("custom")])
.union([
z.literal("auto"),
z.literal("lan"),
z.literal("loopback"),
z.literal("custom"),
z.literal("tailnet"),
])
.optional(),
controlUi: z
.object({