diff --git a/server/db/pg/schema/schema.ts b/server/db/pg/schema/schema.ts index 34562e7d..e8077754 100644 --- a/server/db/pg/schema/schema.ts +++ b/server/db/pg/schema/schema.ts @@ -215,7 +215,8 @@ export const siteResources = pgTable("siteResources", { alias: varchar("alias"), aliasAddress: varchar("aliasAddress"), tcpPortRangeString: varchar("tcpPortRangeString"), - udpPortRangeString: varchar("udpPortRangeString") + udpPortRangeString: varchar("udpPortRangeString"), + disableIcmp: boolean("disableIcmp").notNull().default(false) }); export const clientSiteResources = pgTable("clientSiteResources", { diff --git a/server/db/sqlite/schema/schema.ts b/server/db/sqlite/schema/schema.ts index ab754bc9..de8ad8d0 100644 --- a/server/db/sqlite/schema/schema.ts +++ b/server/db/sqlite/schema/schema.ts @@ -236,7 +236,8 @@ export const siteResources = sqliteTable("siteResources", { alias: text("alias"), aliasAddress: text("aliasAddress"), tcpPortRangeString: text("tcpPortRangeString"), - udpPortRangeString: text("udpPortRangeString") + udpPortRangeString: text("udpPortRangeString"), + disableIcmp: integer("disableIcmp", { mode: "boolean" }) }); export const clientSiteResources = sqliteTable("clientSiteResources", { diff --git a/server/lib/ip.ts b/server/lib/ip.ts index 2bf3e0e8..21c148ac 100644 --- a/server/lib/ip.ts +++ b/server/lib/ip.ts @@ -466,6 +466,7 @@ export function generateAliasConfig(allSiteResources: SiteResource[]): Alias[] { export type SubnetProxyTarget = { sourcePrefix: string; // must be a cidr destPrefix: string; // must be a cidr + disableIcmp?: boolean; rewriteTo?: string; // must be a cidr portRange?: { min: number; @@ -504,6 +505,7 @@ export function generateSubnetProxyTargets( ...parsePortRangeString(siteResource.tcpPortRangeString, "tcp"), ...parsePortRangeString(siteResource.udpPortRangeString, "udp") ]; + const disableIcmp = siteResource.disableIcmp ?? false; if (siteResource.mode == "host") { let destination = siteResource.destination; @@ -515,7 +517,8 @@ export function generateSubnetProxyTargets( targets.push({ sourcePrefix: clientPrefix, destPrefix: destination, - portRange + portRange, + disableIcmp }); } @@ -525,14 +528,16 @@ export function generateSubnetProxyTargets( sourcePrefix: clientPrefix, destPrefix: `${siteResource.aliasAddress}/32`, rewriteTo: destination, - portRange + portRange, + disableIcmp }); } } else if (siteResource.mode == "cidr") { targets.push({ sourcePrefix: clientPrefix, destPrefix: siteResource.destination, - portRange + portRange, + disableIcmp }); } } diff --git a/server/routers/siteResource/createSiteResource.ts b/server/routers/siteResource/createSiteResource.ts index 370037cb..f2e343cd 100644 --- a/server/routers/siteResource/createSiteResource.ts +++ b/server/routers/siteResource/createSiteResource.ts @@ -47,7 +47,8 @@ const createSiteResourceSchema = z roleIds: z.array(z.int()), clientIds: z.array(z.int()), tcpPortRangeString: portRangeStringSchema, - udpPortRangeString: portRangeStringSchema + udpPortRangeString: portRangeStringSchema, + disableIcmp: z.boolean().optional() }) .strict() .refine( @@ -158,7 +159,8 @@ export async function createSiteResource( roleIds, clientIds, tcpPortRangeString, - udpPortRangeString + udpPortRangeString, + disableIcmp } = parsedBody.data; // Verify the site exists and belongs to the org @@ -245,7 +247,8 @@ export async function createSiteResource( alias, aliasAddress, tcpPortRangeString, - udpPortRangeString + udpPortRangeString, + disableIcmp }) .returning(); diff --git a/server/routers/siteResource/listAllSiteResourcesByOrg.ts b/server/routers/siteResource/listAllSiteResourcesByOrg.ts index 4fc96533..7b2e0233 100644 --- a/server/routers/siteResource/listAllSiteResourcesByOrg.ts +++ b/server/routers/siteResource/listAllSiteResourcesByOrg.ts @@ -99,6 +99,7 @@ export async function listAllSiteResourcesByOrg( alias: siteResources.alias, tcpPortRangeString: siteResources.tcpPortRangeString, udpPortRangeString: siteResources.udpPortRangeString, + disableIcmp: siteResources.disableIcmp, siteName: sites.name, siteNiceId: sites.niceId, siteAddress: sites.address diff --git a/server/routers/siteResource/updateSiteResource.ts b/server/routers/siteResource/updateSiteResource.ts index fb2065c5..376d9c0a 100644 --- a/server/routers/siteResource/updateSiteResource.ts +++ b/server/routers/siteResource/updateSiteResource.ts @@ -58,7 +58,8 @@ const updateSiteResourceSchema = z roleIds: z.array(z.int()), clientIds: z.array(z.int()), tcpPortRangeString: portRangeStringSchema, - udpPortRangeString: portRangeStringSchema + udpPortRangeString: portRangeStringSchema, + disableIcmp: z.boolean().optional() }) .strict() .refine( @@ -165,7 +166,8 @@ export async function updateSiteResource( roleIds, clientIds, tcpPortRangeString, - udpPortRangeString + udpPortRangeString, + disableIcmp } = parsedBody.data; const [site] = await db @@ -233,7 +235,8 @@ export async function updateSiteResource( enabled: enabled, alias: alias && alias.trim() ? alias : null, tcpPortRangeString: tcpPortRangeString, - udpPortRangeString: udpPortRangeString + udpPortRangeString: udpPortRangeString, + disableIcmp: disableIcmp }) .where( and( @@ -357,8 +360,12 @@ export async function handleMessagingForUpdatedSiteResource( existingSiteResource.alias !== updatedSiteResource.alias; const portRangesChanged = existingSiteResource && - (existingSiteResource.tcpPortRangeString !== updatedSiteResource.tcpPortRangeString || - existingSiteResource.udpPortRangeString !== updatedSiteResource.udpPortRangeString); + (existingSiteResource.tcpPortRangeString !== + updatedSiteResource.tcpPortRangeString || + existingSiteResource.udpPortRangeString !== + updatedSiteResource.udpPortRangeString || + existingSiteResource.disableIcmp !== + updatedSiteResource.disableIcmp); // if the existingSiteResource is undefined (new resource) we don't need to do anything here, the rebuild above handled it all diff --git a/src/app/[orgId]/settings/resources/client/page.tsx b/src/app/[orgId]/settings/resources/client/page.tsx index 1628e689..eacab1d2 100644 --- a/src/app/[orgId]/settings/resources/client/page.tsx +++ b/src/app/[orgId]/settings/resources/client/page.tsx @@ -69,7 +69,8 @@ export default async function ClientResourcesPage( siteNiceId: siteResource.siteNiceId, niceId: siteResource.niceId, tcpPortRangeString: siteResource.tcpPortRangeString || null, - udpPortRangeString: siteResource.udpPortRangeString || null + udpPortRangeString: siteResource.udpPortRangeString || null, + disableIcmp: siteResource.disableIcmp || false, }; } ); diff --git a/src/components/ClientResourcesTable.tsx b/src/components/ClientResourcesTable.tsx index 8ca1cc21..758b6e12 100644 --- a/src/components/ClientResourcesTable.tsx +++ b/src/components/ClientResourcesTable.tsx @@ -43,6 +43,7 @@ export type InternalResourceRow = { niceId: string; tcpPortRangeString: string | null; udpPortRangeString: string | null; + disableIcmp: boolean; }; type ClientResourcesTableProps = { diff --git a/src/components/CreateInternalResourceDialog.tsx b/src/components/CreateInternalResourceDialog.tsx index adbb7f61..894315b8 100644 --- a/src/components/CreateInternalResourceDialog.tsx +++ b/src/components/CreateInternalResourceDialog.tsx @@ -42,6 +42,7 @@ import { SelectTrigger, SelectValue } from "@app/components/ui/select"; +import { Switch } from "@app/components/ui/switch"; import { useEnvContext } from "@app/hooks/useEnvContext"; import { toast } from "@app/hooks/useToast"; import { createApiClient, formatAxiosError } from "@app/lib/api"; @@ -179,6 +180,7 @@ export default function CreateInternalResourceDialog({ alias: z.string().nullish(), tcpPortRangeString: portRangeStringSchema, udpPortRangeString: portRangeStringSchema, + disableIcmp: z.boolean().optional(), roles: z .array( z.object({ @@ -308,6 +310,7 @@ export default function CreateInternalResourceDialog({ alias: "", tcpPortRangeString: "*", udpPortRangeString: "*", + disableIcmp: false, roles: [], users: [], clients: [] @@ -355,6 +358,7 @@ export default function CreateInternalResourceDialog({ alias: "", tcpPortRangeString: "*", udpPortRangeString: "*", + disableIcmp: false, roles: [], users: [], clients: [] @@ -408,6 +412,7 @@ export default function CreateInternalResourceDialog({ : undefined, tcpPortRangeString: data.tcpPortRangeString, udpPortRangeString: data.udpPortRangeString, + disableIcmp: data.disableIcmp ?? false, roleIds: data.roles ? data.roles.map((r) => parseInt(r.id)) : [], @@ -836,7 +841,7 @@ export default function CreateInternalResourceDialog({