GuiderNätverk och VPNPrivat DNS med Unbound

Kör din egen privata DNS-resolver med Unbound

Unbound på Debian 13 som en privat resolver med DNSSEC-validering, öppen bara för dina egna WireGuard-enheter, så att ingen extern DNS-leverantör ser alla namn du slår upp.

Testad på Unbound 1.26 (Debians paket) och 1.25 (Alpine-container) på Debian 13 (trixie) på en server hos Melonslab Uppdaterad 25 september 2026

Rekommenderad server för guiden

VC-S Micro · 2 vCPU · 8 GB Minne · 250 GB Lagring

Månadsvis, ingen bindningstid 7 dagars öppet köp

90 kr/mån

Beställ nu
På den här sidan

Det här sätter du upp

Varje webbplats, app och uppdateringskontroll börjar med en DNS-uppslagning, och den som svarar ser en lista över allt dina enheter ansluter till. Oftast är det din internetleverantör, eller en publik resolver som Cloudflares eller Googles.

Här svarar din egen server i stället. Unbound slår själv upp namnen, direkt hos de servrar som ansvarar för varje domän, och kontrollerar DNSSEC-signaturer, så att förfalskade svar avvisas. Var och en av de servrarna ser bara uppslagningar för sina egna domäner, och uppslagningarna kommer från din servers adress i stället för från dina enheter.

Unbound svarar bara själva servern och enheterna på din WireGuard-VPN, ingen annan. Det spelar roll: en resolver som svarar vem som helst missbrukas för att översvämma andra nätverk med trafik.

Varje steg nedan har körts på en server hos Melonslab med Debian 13, både med Debians paket och i en rootless container. En WireGuard-enhet slog upp namn genom tunneln före och efter en omstart av servern, och uppslagningar från internet nekades.

Paket eller container

Våra andra appguider körs i rootless Podman. För Unbound är Debians paket det enklare valet: det kör redan Unbound som en egen användare utan privilegier så snart den har öppnat port 53, och säkerhetsuppdateringarna ingår i dina vanliga apt-uppdateringar. Om du hellre vill ha den i en container också följer du stegen för container i stället för steg 1 och 2.

Innan du börjar

Du behöver en server med WireGuard uppsatt som i WireGuard-guiden, med tunneladressen 10.8.0.1.

1. Installera Unbound

apt update
apt install -y unbound bind9-dnsutils

Unbound startar direkt och svarar bara själva servern. Debian ställer in den så att den validerar DNSSEC, och håller rotnyckeln aktuell. bind9-dnsutils innehåller dig, för att testa.

2. Låt Unbound svara VPN:en

Skapa /etc/unbound/unbound.conf.d/vpn.conf:

server:
    # Answer the server itself and devices on the VPN, nobody else
    interface: 127.0.0.1
    interface: ::1
    interface: 10.8.0.1
    ip-freebind: yes
    access-control: 10.8.0.0/24 allow

    # Give away as little as possible
    hide-identity: yes
    hide-version: yes
    qname-minimisation: yes

    # Answer faster from what is already known
    aggressive-nsec: yes
    prefetch: yes

Kontrollera konfigurationen och starta om Unbound:

unbound-checkconf
systemctl restart unbound

Unbound lyssnar nu på loopback-adresserna och på tunneladressen 10.8.0.1, aldrig på din servers publika adresser. ip-freebind låter Unbound lyssna på 10.8.0.1 vid uppstart, även innan WireGuard har skapat adressen. access-control släpper in VPN:ens adresser; själva servern är tillåten som standard, och alla andra nekas.

qname-minimisation frågar varje server bara efter så mycket av ett namn som den behöver: servrarna för .com tillfrågas om example.com, inte om www.example.com.

3. Testa den på servern

dig @127.0.0.1 example.com

Svarets flags-rad ska innehålla ad, som betyder att Unbound kontrollerade DNSSEC-signaturerna. En domän med medvetet trasiga signaturer ska misslyckas:

dig @127.0.0.1 dnssec-failed.org

Den ska rapportera status: SERVFAIL.

4. Använd den från dina enheter

Ändra raden DNS i varje enhets WireGuard-konfiguration, från steg 7 i WireGuard-guiden, till:

DNS = 10.8.0.1

Läs in den nya konfigurationen på enheten igen: visa den som QR-kod med qrencode -t ansiutf8 < /etc/wireguard/phone.conf och skanna den, eller importera filen på en bärbar dator. Den här adressen räcker även för IPv6: frågan går över IPv4 inne i tunneln, och svaren innehåller IPv6-adresser.

Kontrollera att din server slår upp namnen själv genom att köra det här på en bärbar dator som är ansluten till VPN:en:

dig +short TXT proto.on.quad9.net @10.8.0.1

Kommandot skriver inte ut något. Quad9, en DNS-leverantör, svarar bara på det här namnet för uppslagningar som går genom dess egna resolvrar: frågar du Quad9 direkt, med @9.9.9.9 i stället för @10.8.0.1, skriver kommandot ut "do53-udp". Det tomma svaret betyder att uppslagningen inte gick genom Quad9: din server hittade svaret själv.

5. Kontrollera att den inte är öppen

Från en dator utanför VPN:en, inte från servern:

dig @203.0.113.10 example.com

Byt 203.0.113.10 mot din servers publika adress. Du ska få "connection refused" och inget svar på frågan.

Felsökning

Enheterna tappar DNS när VPN:en är ansluten. Kontrollera raden DNS = 10.8.0.1, och att systemctl status unbound visar att den körs. ss -lnup | grep :53 ska lista 10.8.0.1:53. Använder du ufw som i säkerhetsguiden, behöver den ufw allow in on wg0.

unbound-checkconf rapporterar ett fel. Den anger filen och raden med problemet. Rätta det innan du startar om: Unbound fortsätter med sin nuvarande konfiguration fram till dess, och en omstart med en trasig konfiguration slår ut den.

En webbplats slutar ladda, och dig ger SERVFAIL för den. Oftast är domänens DNSSEC-signaturer trasiga, och Unbound avvisar svar den inte kan kontrollera. Det skyddar dig mot förfalskade svar; domänens ägare behöver åtgärda det.

I en rootless container i stället

NLnet Labs, som gör Unbound, publicerar ingen containeravbild. Det gör Alpine Linux infrastrukturteam: docker.io/alpinelinux/unbound är Alpines eget Unbound-paket på en minimal Alpine, som byggs om regelbundet från sin källkod. Om du väljer en annan avbild, kontrollera att den fortfarande uppdateras: mvance/unbound, den mest nedladdade, har inte uppdaterats sedan oktober 2024.

De här stegen ersätter steg 1 och 2. Om du redan har installerat Debians paket stänger du av det först med systemctl disable --now unbound.

Som root tillåter du vanliga användare att använda port 53 och att binda till tunneladressen innan den finns:

cat > /etc/sysctl.d/50-unprivileged-ports.conf <<EOF
net.ipv4.ip_unprivileged_port_start = 53
net.ipv4.ip_nonlocal_bind = 1
EOF
sysctl --system

Det ersätter filen från Podman-guiden, och 53 täcker även port 80 och 443. Containern publicerar sin port bara på 10.8.0.1, och vid uppstart kan den starta innan WireGuard har skapat den adressen; ip_nonlocal_bind låter den binda ändå.

Skapa en användare för den och byt till den:

useradd -m -s /bin/bash dns
loginctl enable-linger dns
machinectl shell dns@

Skapa ~/unbound.conf, som här är hela Unbounds konfiguration:

server:
    # Inside the container. Only the VPN address is published (see unbound.container).
    interface: 0.0.0.0
    access-control: 10.8.0.0/24 allow
    auto-trust-anchor-file: /etc/unbound/root.key
    use-syslog: no
    # The container cannot raise the send buffer, so use the system default
    so-sndbuf: 0

    # Give away as little as possible
    hide-identity: yes
    hide-version: yes
    qname-minimisation: yes

    # Answer faster from what is already known
    aggressive-nsec: yes
    prefetch: yes

Och ~/.config/containers/systemd/unbound.container, efter mkdir -p ~/.config/containers/systemd:

[Unit]
Description=Unbound, a private DNS resolver for the VPN

[Container]
ContainerName=unbound
Image=docker.io/alpinelinux/unbound:latest
Volume=%h/unbound.conf:/etc/unbound/unbound.conf:ro
PublishPort=10.8.0.1:53:53/udp
PublishPort=10.8.0.1:53:53/tcp
AutoUpdate=registry

[Service]
Restart=always

[Install]
WantedBy=default.target

Starta den, kontrollera konfigurationen och slå på Podmans dagliga uppdateringar:

systemctl --user daemon-reload
systemctl --user start unbound
podman exec unbound unbound-checkconf
systemctl --user enable --now podman-auto-update.timer

Containern hämtar den aktuella DNSSEC-rotnyckeln varje gång den startar. Containern ser varje enhets riktiga adress, så access-control fungerar som i steg 2: en fråga från en adress utanför VPN:en nekas.

Den svarar bara på 10.8.0.1, inte på serverns loopback-adress, så testa den på servern med dig -b 10.8.0.1 @10.8.0.1 example.com och fortsätt från steg 4. Om containern inte startar och dess logg visar "Failed to bind port 53" saknas en av de två inställningarna ovan: "Permission denied" pekar på den första, "Cannot assign requested address" på den andra.

Privat DNS på VPN:en du själv kör

Med Unbound på en server hos Melonslab besvaras dina enheters DNS-uppslagningar i Sverige, av en server som bara du använder.

Kör det på din egen server

VC-S Micro

90 kr/mån

vCPU
2
Minne
8 GB
Lagring
250 GB
Trafik
10 TB
Standard
HDD · RAID 10
  • Full root-åtkomst
  • Nativt /64 IPv6
  • RAID-skyddad lagring
  • Malmö, Sverige
  • Månadsvis, ingen bindningstid
  • 7 dagars öppet köp
Alla guider