An Unbound DNS resolver on current Debian with very simple and secure configuration.
2.1K
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 is highly dependent on the current Debian version and the Unbound version available for it.
| Major | Minor | Patch | Debian | Unbound | Additional Information |
|---|---|---|---|---|---|
| 1 | 1 | 0 | Trixie (13.2) | 1.22.0 | (nothing) |
| 1 | 1 | 1 | Trixie (13.2) | 1.22.0 | Add Link Local Addresses for Access |
| 1 | 2 | 0 | Trixie (13.3) | 1.22.0 | New Trixie Version and add Configuration Values |
| 1 | 2 | 1 | Trixie (13.3) | 1.22.0 | Many more Configuration Values :o) |
| 1 | 3 | 0 | Trixie (13.4) | 1.22.0 | New Trixie Version |
| 1 | 4 | 1 | Trixie (13.5) | 1.22.0 | New Trixie Version and add Configuration Values |
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):
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.
| Variable | Default | Description |
|---|---|---|
| OVERRIDE_CONFIG | false | Set to true if you want to override the configuration |
| DNS_PORT | 5335 | Use Port |
| DNS_IPv4 | true | Use IPv4 (true or false) |
| DNS_IPv6 | false | Use IPv6 (true or false) |
| DNS_UDP | true | Use UDP (true or false) |
| DNS_TCP | true | Use TCP (true or false) |
| CACHE_MSG | 4m | This cache stores DNS message replies (msg-cache-size) |
| CACHE_RRSET | 8m | Memory allocated for storing RRsets (Resource Record Sets) (rrset-cache-size) |
| CACHE_HOSTS | 5000 | Number 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) |
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
[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
questions and answers
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).
The container is very economical. 256MB to 512MB is sufficient.
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
Content type
Image
Digest
sha256:835f55d56…
Size
84.7 MB
Last updated
4 months ago
docker pull skoep/unbound