Skip to content

CoreDNS .internal Zone Forwarding

This document covers the configuration for resolving .internal hostnames within Kubernetes pods by forwarding DNS queries to OPNsense.

Problem

By default, k3s CoreDNS forwards external DNS queries to the node's upstream DNS (often public DNS like 1.1.1.1). This means .internal hostnames managed by OPNsense (local DNS resolver) cannot be resolved from within pods.

Solution

Configure CoreDNS to forward the .internal zone to OPNsense's DNS resolver.

Configuration

Manifest Location

/root/tower-fleet/manifests/core/coredns-custom.yaml

ConfigMap

apiVersion: v1
kind: ConfigMap
metadata:
  name: coredns-custom
  namespace: kube-system
data:
  internal.server: |
    internal:53 {
        errors
        cache 30
        forward . 10.89.97.1
    }

How It Works

  1. k3s CoreDNS includes import /etc/coredns/custom/*.server in its Corefile
  2. The coredns-custom ConfigMap is mounted to /etc/coredns/custom/
  3. Any file ending in .server is imported as a separate server block
  4. The internal:53 block handles all queries for the .internal zone
  5. These queries are forwarded to OPNsense (10.89.97.1)

Deployment

# Apply the ConfigMap
kubectl apply -f /root/tower-fleet/manifests/core/coredns-custom.yaml

# Restart CoreDNS to pick up changes
kubectl rollout restart deployment coredns -n kube-system

Verification

Test from any pod:

# Get a shell in a pod
kubectl exec -it <pod-name> -n <namespace> -- sh

# Test DNS resolution
nslookup auth.internal
nslookup home.internal

Expected output:

Server:    10.43.0.10
Address:   10.43.0.10:53

Name:      auth.internal
Address:   10.89.97.220

Use Cases

This enables pods to access: - auth.internal - Authentik SSO - home.internal - Home Portal - money.internal - Money Tracker - Any other .internal hostname managed by OPNsense

Adding New Zones

To forward additional zones, add more server blocks to the ConfigMap:

data:
  internal.server: |
    internal:53 {
        errors
        cache 30
        forward . 10.89.97.1
    }
  example.server: |
    example.local:53 {
        errors
        cache 30
        forward . 10.89.97.1
    }

Troubleshooting

DNS Not Resolving

  1. Check CoreDNS logs:

    kubectl logs -n kube-system -l k8s-app=kube-dns
    

  2. Verify ConfigMap is mounted:

    kubectl exec -n kube-system <coredns-pod> -- ls -la /etc/coredns/custom/
    

  3. Restart CoreDNS:

    kubectl rollout restart deployment coredns -n kube-system
    

OPNsense Not Responding

Verify OPNsense DNS is accessible from k3s nodes:

ssh root@10.89.97.201 "nslookup auth.internal 10.89.97.1"