feat(api): wire DNS propagation for traffic-inspector custom hosts (fix1)

This commit is contained in:
diegosouzapw
2026-05-28 11:23:48 -03:00
parent 785f8e4117
commit 8e518ae008
2 changed files with 59 additions and 6 deletions

View File

@@ -1,5 +1,5 @@
/**
* DELETE /api/tools/traffic-inspector/hosts/[host] — remove a custom host
* DELETE /api/tools/traffic-inspector/hosts/[host] — remove a custom host + DNS cleanup
* PATCH /api/tools/traffic-inspector/hosts/[host] — toggle enabled flag
*
* LOCAL_ONLY enforced by routeGuard.
@@ -8,6 +8,8 @@
import { buildErrorBody, sanitizeErrorMessage } from "@omniroute/open-sse/utils/error.ts";
import { z } from "zod";
import { removeCustomHost, toggleCustomHost, listCustomHosts } from "@/lib/db/inspectorCustomHosts";
import { getCachedPassword } from "@/mitm/manager";
import { removeDNSEntries } from "@/mitm/dns/dnsConfig";
interface Params {
params: Promise<{ host: string }>;
@@ -23,7 +25,6 @@ export async function DELETE(_request: Request, { params }: Params): Promise<Res
try {
removeCustomHost(decodedHost);
return new Response(null, { status: 204 });
} catch (err) {
const msg = sanitizeErrorMessage(err);
return new Response(JSON.stringify(buildErrorBody(500, msg || "Failed to remove host")), {
@@ -31,6 +32,33 @@ export async function DELETE(_request: Request, { params }: Params): Promise<Res
headers: { "content-type": "application/json" },
});
}
// DNS cleanup — only possible when the MITM proxy is running (password cached).
const sudoPassword = getCachedPassword();
if (sudoPassword) {
try {
await removeDNSEntries([decodedHost], sudoPassword);
} catch {
// DNS cleanup failure is non-fatal: DB record was removed.
// Return 204 with a header warning rather than failing.
return new Response(null, {
status: 204,
headers: {
"x-dns-warning": `DNS entry for ${decodedHost} could not be removed — restart the proxy or remove manually`,
},
});
}
} else {
return new Response(null, {
status: 204,
headers: {
"x-dns-warning":
"DNS routing requires the MITM proxy to be running with a cached sudo password",
},
});
}
return new Response(null, { status: 204 });
}
export async function PATCH(request: Request, { params }: Params): Promise<Response> {

View File

@@ -1,10 +1,10 @@
/**
* GET /api/tools/traffic-inspector/hosts — list custom host capture entries
* POST /api/tools/traffic-inspector/hosts — add a host (DB record)
* POST /api/tools/traffic-inspector/hosts — add a host (DB record + DNS propagation)
*
* The DB record enables the MITM proxy to SNI-certify the host on demand.
* DNS /etc/hosts edits are out of scope for this route — clients that need
* OS-level redirect must use the Custom Hosts setup guide (requires sudo).
* When a cached sudo password is available (MITM proxy running), DNS /etc/hosts
* entries are also added so OS traffic is redirected to the local proxy.
*
* LOCAL_ONLY enforced by routeGuard.
*/
@@ -12,6 +12,8 @@
import { buildErrorBody, sanitizeErrorMessage } from "@omniroute/open-sse/utils/error.ts";
import { InspectorCustomHostSchema } from "@/shared/schemas/inspector";
import { listCustomHosts, addCustomHost } from "@/lib/db/inspectorCustomHosts";
import { getCachedPassword } from "@/mitm/manager";
import { addDNSEntries } from "@/mitm/dns/dnsConfig";
export async function GET(): Promise<Response> {
try {
@@ -57,5 +59,28 @@ export async function POST(request: Request): Promise<Response> {
});
}
return Response.json({ ok: true, host }, { status: 201 });
// DNS propagation — only possible when the MITM proxy is running (password cached).
const sudoPassword = getCachedPassword();
if (sudoPassword) {
try {
await addDNSEntries([host], sudoPassword);
} catch (err) {
// DNS failure is non-fatal: DB record was saved; warn but do not fail the request.
const msg = sanitizeErrorMessage(err);
return Response.json(
{ ok: true, host, warning: `DNS routing entry could not be added: ${msg}` },
{ status: 201 }
);
}
return Response.json({ ok: true, host }, { status: 201 });
}
return Response.json(
{
ok: true,
host,
warning: "DNS routing requires the MITM proxy to be running with a cached sudo password",
},
{ status: 201 }
);
}