feat: add local DNS override toggle component and action
Implements a user interface toggle component to control the override_local_dns setting in Headscale. This allows administrators to force clients to use the configured DNS servers instead of their local DNS configuration. - Added ToggleOverrideLocalDns component - Added corresponding action handler in dns-actions.ts - Added section to the DNS overview panel - Updated interface to reflect config changes immediately Fixes #125
This commit is contained in:
parent
6f40f9cfac
commit
908039464a
36
app/routes/dns/components/toggle-override-local-dns.tsx
Normal file
36
app/routes/dns/components/toggle-override-local-dns.tsx
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
import Dialog from '~/components/Dialog';
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
isEnabled: boolean;
|
||||||
|
isDisabled: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function Modal({ isEnabled, isDisabled }: Props) {
|
||||||
|
return (
|
||||||
|
<Dialog>
|
||||||
|
<Dialog.Button
|
||||||
|
isDisabled={isDisabled}
|
||||||
|
className={isEnabled ? "text-red-500 border-red-500" : ""}
|
||||||
|
>
|
||||||
|
{isEnabled ? 'Disable' : 'Enable'} Local DNS Override
|
||||||
|
</Dialog.Button>
|
||||||
|
<Dialog.Panel isDisabled={isDisabled}>
|
||||||
|
<Dialog.Title>
|
||||||
|
{isEnabled ? 'Disable' : 'Enable'} Local DNS Override
|
||||||
|
</Dialog.Title>
|
||||||
|
<Dialog.Text>
|
||||||
|
{isEnabled
|
||||||
|
? 'Devices will no longer have their local DNS settings overridden by Headscale.'
|
||||||
|
: 'Headscale will override local DNS settings on connected devices, forcing them to use the server\'s DNS configuration.'
|
||||||
|
}
|
||||||
|
</Dialog.Text>
|
||||||
|
<input type="hidden" name="action_id" value="toggle_override_local_dns" />
|
||||||
|
<input
|
||||||
|
type="hidden"
|
||||||
|
name="new_state"
|
||||||
|
value={isEnabled ? 'disabled' : 'enabled'}
|
||||||
|
/>
|
||||||
|
</Dialog.Panel>
|
||||||
|
</Dialog>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -33,6 +33,8 @@ export async function dnsAction({
|
|||||||
return removeRecord(formData, context);
|
return removeRecord(formData, context);
|
||||||
case 'add_record':
|
case 'add_record':
|
||||||
return addRecord(formData, context);
|
return addRecord(formData, context);
|
||||||
|
case 'toggle_override_local_dns':
|
||||||
|
return toggleOverrideLocalDns(formData, context);
|
||||||
default:
|
default:
|
||||||
return data({ success: false }, 400);
|
return data({ success: false }, 400);
|
||||||
}
|
}
|
||||||
@ -221,3 +223,19 @@ async function addRecord(formData: FormData, context: LoadContext) {
|
|||||||
|
|
||||||
await hp_getIntegration()?.onConfigChange();
|
await hp_getIntegration()?.onConfigChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function toggleOverrideLocalDns(formData: FormData, context: LoadContext) {
|
||||||
|
const newState = formData.get('new_state')?.toString();
|
||||||
|
if (!newState) {
|
||||||
|
return data({ success: false }, 400);
|
||||||
|
}
|
||||||
|
|
||||||
|
await context.hs.patch([
|
||||||
|
{
|
||||||
|
path: 'dns.override_local_dns',
|
||||||
|
value: newState === 'enabled',
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
await hp_getIntegration()?.onConfigChange();
|
||||||
|
}
|
||||||
@ -9,6 +9,7 @@ import ManageRecords from './components/manage-records';
|
|||||||
import RenameTailnet from './components/rename-tailnet';
|
import RenameTailnet from './components/rename-tailnet';
|
||||||
import ToggleMagic from './components/toggle-magic';
|
import ToggleMagic from './components/toggle-magic';
|
||||||
import { dnsAction } from './dns-actions';
|
import { dnsAction } from './dns-actions';
|
||||||
|
import ToggleOverrideLocalDns from './components/toggle-override-local-dns';
|
||||||
|
|
||||||
// We do not want to expose every config value
|
// We do not want to expose every config value
|
||||||
export async function loader({ context }: LoaderFunctionArgs<LoadContext>) {
|
export async function loader({ context }: LoaderFunctionArgs<LoadContext>) {
|
||||||
@ -25,6 +26,7 @@ export async function loader({ context }: LoaderFunctionArgs<LoadContext>) {
|
|||||||
splitDns: config.dns.nameservers.split,
|
splitDns: config.dns.nameservers.split,
|
||||||
searchDomains: config.dns.search_domains,
|
searchDomains: config.dns.search_domains,
|
||||||
extraRecords: config.dns.extra_records,
|
extraRecords: config.dns.extra_records,
|
||||||
|
overrideLocalDns: config.dns.override_local_dns,
|
||||||
};
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -59,6 +61,17 @@ export default function Page() {
|
|||||||
<RenameTailnet name={data.baseDomain} isDisabled={isDisabled} />
|
<RenameTailnet name={data.baseDomain} isDisabled={isDisabled} />
|
||||||
<ManageNS nameservers={allNs} isDisabled={isDisabled} />
|
<ManageNS nameservers={allNs} isDisabled={isDisabled} />
|
||||||
<ManageRecords records={data.extraRecords} isDisabled={isDisabled} />
|
<ManageRecords records={data.extraRecords} isDisabled={isDisabled} />
|
||||||
|
<div className="flex flex-col w-2/3">
|
||||||
|
<h1 className="text-2xl font-medium mb-4">Local DNS Override</h1>
|
||||||
|
<p className="mb-4">
|
||||||
|
When enabled, Headscale will override the local DNS configuration
|
||||||
|
of connected clients, forcing them to use the configured DNS servers.
|
||||||
|
</p>
|
||||||
|
<ToggleOverrideLocalDns
|
||||||
|
isEnabled={data.overrideLocalDns || false}
|
||||||
|
isDisabled={isDisabled}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
<ManageDomains
|
<ManageDomains
|
||||||
searchDomains={data.searchDomains}
|
searchDomains={data.searchDomains}
|
||||||
isDisabled={isDisabled}
|
isDisabled={isDisabled}
|
||||||
|
|||||||
@ -273,6 +273,8 @@ dns:
|
|||||||
|
|
||||||
# List of DNS servers to expose to clients.
|
# List of DNS servers to expose to clients.
|
||||||
nameservers:
|
nameservers:
|
||||||
|
override_local_dns: false
|
||||||
|
|
||||||
global:
|
global:
|
||||||
- 1.1.1.1
|
- 1.1.1.1
|
||||||
- 1.0.0.1
|
- 1.0.0.1
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user