Sign inSign up

skoep/unbound

By skoep

•Updated 4 months ago

An Unbound DNS resolver on current Debian with very simple and secure configuration.

Image
Networking
Security
0

2.1K

skoep/unbound repository overview

⁠Welcome to Unbound

This container image provides an unbound DNS resolver with particularly simple and secure configuration. Domain information is retrieved alternately from Google and Cloudflare using encryption, ensuring that no one can read or modify it during transmission across the internet.

⁠Versioning (Tag)

Versioning is highly dependent on the current Debian version and the Unbound version available for it.

MajorMinorPatchDebianUnboundAdditional Information
110Trixie (13.2)1.22.0(nothing)
111Trixie (13.2)1.22.0Add Link Local Addresses for Access
120Trixie (13.3)1.22.0New Trixie Version and add Configuration Values
121Trixie (13.3)1.22.0Many more Configuration Values :o)
130Trixie (13.4)1.22.0New Trixie Version
141Trixie (13.5)1.22.0New Trixie Version and add Configuration Values

⁠Configuration

On each startup, the entrypoint checks whether the file /etc/unbound/unbound.conf.d/skoep-system.conf exists. If it does not, the entire contents of the configuration directory are deleted, and a default configuration is applied. The configuration is also rewritten if the environment variable OVERRIDE_CONFIG=true is set.

The default configuration for the Access Control is set as follows (ACCESS_CONTROL must be empty to use the default settings):

  • IPv4: 10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,169.254.0.0/16
  • IPv6: fd00::/8,fe80::/10

The servers of Google and Cloudflare are used as query servers. They are queried using TLS encryption and are not filtered. Port 853 must be opened to the internet by the container.

Retrieving entries with internal addresses is not permitted by default. This container allows this using the environment variable PRIVATE_DOMAIN for specified domains. If multiple domains are to be specified, they must be separated by commas. Example: PRIVATE_DOMAIN=intern1.example.com,intern2.example.com.

This container is designed to be as simple as possible, but sometimes you need the ability to override individual domain entries with local IPs. This can be easily achieved with the following commands: LOCAL_DATA=1+test1.example.com+192.168.1.21,1+test2.example.com+192.168.1.22 and LOCAL_DATA_PTR=test1.example.com+192.168.1.21,test2.example.com+192.168.1.22. Both parameters are independent of each other. The first number in LOCAL_DATA means the following: 1 = IPv4 A Record, 2 = IPv6 AAAA Record, 3 = CNAME. Multiple entries are separated by commas.

⁠Environment Variables

VariableDefaultDescription
OVERRIDE_CONFIGfalseSet to true if you want to override the configuration
DNS_PORT5335Use Port
DNS_IPv4trueUse IPv4 (true or false)
DNS_IPv6falseUse IPv6 (true or false)
DNS_UDPtrueUse UDP (true or false)
DNS_TCPtrueUse TCP (true or false)
CACHE_MSG4mThis cache stores DNS message replies (msg-cache-size)
CACHE_RRSET8mMemory allocated for storing RRsets (Resource Record Sets) (rrset-cache-size)
CACHE_HOSTS5000Number of hosts for which information is cached (infra-cache-numhosts)
PRIVATE_DOMAIN(empty)List of private Domains (private-domain)
ACCESS_CONTROL(empty)List of allowed IPs (access-control)
LOCAL_DATA(empty)List of overwritten or new entries (local-data)
LOCAL_DATA_PTR(empty)List of overwritten or new entries (local-data-ptr)

⁠Example of a Compose file:

services:
  unbound:
    image: docker.io/skoep/unbound:latest
    container_name: unbound
    hostname: unbound
    domainname: example.com
    restart: unless-stopped
    ports:
      - "5335:5335/tcp"
      - "5335:5335/udp"
    environment:
      - TZ=Europe/Berlin

Or if you want to use the direct DNS port, IPv4 and IPv6 on your host. Configuration overwritten after every start:

services:
  unbound:
    image: docker.io/skoep/unbound:latest
    container_name: unbound
    hostname: unbound
    domainname: example.com
    restart: unless-stopped
    ports:
      - "53:53/tcp"
      - "53:53/udp"
    environment:
      - TZ=Europe/Berlin
      - OVERRIDE_CONFIG=true
      - DNS_PORT=53
      - DNS_IPv4=true
      - DNS_IPv6=true

⁠Example of a quadlet for Podman:

[Unit]
Description=Unbound DNS Resolver

[Container]
AutoUpdate=registry

Image=docker.io/skoep/unbound:latest
ContainerName=unbound
HostName=unbound
LogDriver=none
PodmanArgs=--cpus=0.5 --memory=64m
Network=pasta:-t,5335:5335,-u,5335:5335

Environment=TZ=Europe/Berlin
Environment=OVERRIDE_CONFIG=true
Environment=DNS_IPv4=true
Environment=ACCESS_CONTROL=192.168.100.0/24
Environment=PRIVATE_DOMAIN=intern.example.com

[Service]
Restart=always
TimeoutStartSec=1

[Quadlet]
DefaultDependencies=false

[Install]
WantedBy=default.target

⁠FAQ

questions and answers

⁠How much memory should I allocate to the system?

This depends on the configured cache size. CACHE_RRSET should always be twice the size of CACHE_MSG, and the total allocated memory should be two to three times the size of CACHE_RRSET + CACHE_MSG. If the default values are used, then the ideal amount of memory for the container would be 36MB. If you want to be absolutely sure, take four times the amount (48MB).

⁠How much disk space does the container require?

The container is very economical. 256MB to 512MB is sufficient.

⁠Why am I getting an error when using port 53?

Please note that containers running as a rootless user cannot simply open ports below 1024. This is because ports 0 to 1023 are privileged, and the operating system does not allow unprivileged containers to use them. However, this can be overridden with a simple command to move the limit. For this to take effect, a reboot is essential after setting the file.

echo "net.ipv4.ip_unprivileged_port_start=53" | sudo tee /etc/sysctl.d/01-SetUnprivilegedPort.conf

Tag summary

Content type

Image

Digest

sha256:835f55d56…

Size

84.7 MB

Last updated

4 months ago

docker pull skoep/unbound