From b5e2841252fdd9ccfbd5a49883288ea51cb3a9b6 Mon Sep 17 00:00:00 2001 From: Willow C Reed Date: Sat, 8 Aug 2026 16:54:43 -0600 Subject: [PATCH] feat: add nat64 config for ipv6-only vms --- .../src/lib/server/backends/proxmox/index.ts | 20 +++++++++++++++++-- .../src/lib/server/backends/types.ts | 2 ++ apps/dashboard/src/lib/server/config.ts | 2 ++ .../src/lib/server/vm-provisioning.ts | 8 ++++++++ 4 files changed, 30 insertions(+), 2 deletions(-) diff --git a/apps/dashboard/src/lib/server/backends/proxmox/index.ts b/apps/dashboard/src/lib/server/backends/proxmox/index.ts index f1f2e13..d507070 100644 --- a/apps/dashboard/src/lib/server/backends/proxmox/index.ts +++ b/apps/dashboard/src/lib/server/backends/proxmox/index.ts @@ -142,10 +142,22 @@ function cloudInitNetworkConfig(params: VmCreateParams, macAddress: string) { ] : []), ...(params.networkConfig?.ipv6 - ? [{ to: '::/0', via: config.vmNetwork.ipv6DefaultGateway, 'on-link': true }] + ? [ + { to: '::/0', via: config.vmNetwork.ipv6DefaultGateway, 'on-link': true }, + ...(params.networkConfig.nat64Prefix + ? [ + { + to: params.networkConfig.nat64Prefix, + via: config.vmNetwork.ipv6DefaultGateway, + 'on-link': true + } + ] + : []) + ] : []) ]; + const nat64Dns64Server = params.networkConfig?.nat64Dns64Server; const yamlContents = stringifyYaml({ version: 2, ethernets: { @@ -156,7 +168,11 @@ function cloudInitNetworkConfig(params: VmCreateParams, macAddress: string) { dhcp6: false, addresses, routes, - nameservers: { addresses: config.vmNetwork.nameservers } + nameservers: { + addresses: nat64Dns64Server + ? [nat64Dns64Server, ...config.vmNetwork.nameservers] + : config.vmNetwork.nameservers + } } } }); diff --git a/apps/dashboard/src/lib/server/backends/types.ts b/apps/dashboard/src/lib/server/backends/types.ts index caeba15..6912a75 100644 --- a/apps/dashboard/src/lib/server/backends/types.ts +++ b/apps/dashboard/src/lib/server/backends/types.ts @@ -63,6 +63,8 @@ export interface VmNetworkConfig { ipv4?: { address: string; prefixLength: number; gateway: string }; ipv6?: { address: string; prefixLength: number }; ipv6Prefix?: string; + nat64Prefix?: string; + nat64Dns64Server?: string; firewallIpSet?: string[]; } diff --git a/apps/dashboard/src/lib/server/config.ts b/apps/dashboard/src/lib/server/config.ts index 16c2195..3835d0e 100644 --- a/apps/dashboard/src/lib/server/config.ts +++ b/apps/dashboard/src/lib/server/config.ts @@ -7,6 +7,8 @@ export const config = { }, vmNetwork: { ipv6DefaultGateway: 'fe80::1040:ffff', + nat64Prefix: '64:ff9b::/96', + nat64Dns64Server: '2602:f41f:10:1040::ffff', nameservers: ['1.1.1.1', '1.0.0.1', '2606:4700:4700::1111', '2606:4700:4700::1001'] } }; diff --git a/apps/dashboard/src/lib/server/vm-provisioning.ts b/apps/dashboard/src/lib/server/vm-provisioning.ts index 27b247f..b0a7997 100644 --- a/apps/dashboard/src/lib/server/vm-provisioning.ts +++ b/apps/dashboard/src/lib/server/vm-provisioning.ts @@ -13,6 +13,7 @@ import { closeRequestDb, initDrizzle, type Database } from '$lib/server/db'; import { baseImages, vms, vmTypes } from '$lib/server/db/schema'; import { allocateVmNetworking, generateMacAddress, releaseVmNetworking } from '$lib/server/ipam'; import { applyDefaultPtrRecords } from '$lib/server/ptr-records'; +import { config } from '$lib/server/config'; export type ProvisionVmInput = { projectId: string; @@ -126,6 +127,13 @@ export async function provisionVm(db: Database, input: ProvisionVmInput) { : {}), ...(ipv6PrefixNetworkAllocation?.prefix ? { ipv6Prefix: ipv6PrefixNetworkAllocation.prefix } + : {}), + ...(!ipv4NetworkAllocation && + (ipv6TransitNetworkAllocation?.address || ipv6PrefixNetworkAllocation?.prefix) + ? { + nat64Prefix: config.vmNetwork.nat64Prefix, + nat64Dns64Server: config.vmNetwork.nat64Dns64Server + } : {}) }, sshKeys: input.sshPublicKeys ?? [],