Simple Podman container running dnscrypt-proxy on Alpine Linux, using DoH resolvers from dnscry.pt.
sudo pacman -Syu podman podman-compose podman-docker --noconfirmsudo apt update
sudo apt install -y podman crun curl jq ca-certificatessudo dnf -y install podman curl jq ca-certificatesClone dnscrypt_pod repo:
git clone https://github.com/cyberanchor/dnscrypt_pod
cd dnscrypt_podDownload the x86_64 release tarball and extract the binary:
wget https://github.com/DNSCrypt/dnscrypt-proxy/releases/download/2.1.15/dnscrypt-proxy-linux_x86_64-2.1.15.tar.gz
tar -xzf dnscrypt-proxy-linux_x86_64-2.1.15.tar.gz
cp -f linux-x86_64/dnscrypt-proxy ./dnscrypt-proxypodman build -t localhost/dnscrypt_proxy:latest .Bind container port 5353 to host 5354 (TCP+UDP) for local testing:
podman run --rm --name test_dnscrypt \
-p 127.0.0.1:5354:5353/udp \
-p 127.0.0.1:5354:5353/tcp \
localhost/dnscrypt_proxy:latestExpose on host 5353 (TCP+UDP):
podman run --rm --name dnscrypt_proxy \
--cap-drop=ALL \
--cap-add=NET_BIND_SERVICE \
--security-opt=no-new-privileges \
-p 5353:5353/udp \
-p 5353:5353/tcp \
localhost/dnscrypt_proxy:latestpodman images
podman image inspect localhost/dnscrypt_proxy:latest
podman rmi localhost/dnscrypt_proxy:latest
podman rmi -f <IMAGE_ID>podman ps
podman ps -a
podman logs dnscrypt_proxy
podman logs --tail 50 dnscrypt_proxy
podman stop dnscrypt_proxy
podman rm dnscrypt_proxy
podman rm -f dnscrypt_proxyRuntime diagnostics:
podman inspect dnscrypt_proxy
podman stats --no-stream
podman top dnscrypt_proxyFetch resolvers.json.
curl https://www.dnscry.pt/resolvers.json -O resolvers.jsonCurl resolvers.json and get last modified date.
curl -sI "https://www.dnscry.pt/resolvers.json" | grep -i '^last-modified:'Create dnscrypt-proxy.toml [static.*] blocks from resolvers with DoH IPv4 stamps, excluding banned country codes.
jq -r '
def banned:["LA","IN","US","KR","CA","TH","BD","AZ","AU","MX","AL","GB","UA","NG","HK","FR","CO","SG","JP","ZA","IL","PK","PE","MU","ID","IE","MY","TR","VN","AE","CH","EC","RU","CL","TW","NZ","BR","PH"];
def sect($h): ($h|sub("\\.dnscry\\.pt$";"")|gsub("\\."; "-") + "-doh");
.[]
| select((.country_code // "") as $cc | (banned|index($cc)|not))
| select(.doh_ipv4_stamp? != null and (.doh_ipv4_stamp|length>0))
| " # \(.host) | \(.ipv4) | \(.country_code) | \(.country_name) | \(.location) | \(.asnv4) | \(.asnv4_name) - DoH\n [static.\u0027\(sect(.host))\u0027]\n stamp = \u0027\(.doh_ipv4_stamp)\u0027\n"
' resolvers.jsonjq -r '[.[] | select(.host and .ipv4) | "\(.host) \(.ipv4)"] | .[]' resolvers.jsonjq -r '
def banned:["LA","IN","US","KR","CA","TH","BD","AZ","AU","MX","AL","GB","UA","NG","HK","FR","CO","SG","JP","ZA","IL","PK","PE","MU","ID","IE","MY","TR","VN","AE","CH","EC","RU","CL","TW","NZ","BR","PH"];
[.[]
| select((.country_code//"") as $cc | (banned|index($cc)|not))
| select(.host and .ipv4)
| "\(.host) \(.ipv4)"
] | .[]
' resolvers.jsonjq -r '.[] | [.host,.ipv4,.country_code,.country_name,.location,.asnv4,.asnv4_name,.doh_ipv4_stamp] | join(" | ")' resolvers.jsonTarget: rootless Podman + stable restarts + predictable container name.
Notes
--replaceavoids failures if a stale container name exists.KillMode=noneprevents systemd from killing the container runtime incorrectly in some setups.- Keep
--rmif you want a clean container on every restart (logs stay in journald).
Create/update: ~/.config/systemd/user/dnscrypt-proxy.service
[Unit]
Description=DNSCrypt-Proxy Container
After=network-online.target
Wants=network-online.target podman.socket
[Service]
ExecStartPre=/usr/bin/systemctl --user start podman.socket
ExecStart=/usr/bin/podman run \
--rm \
--replace \
--name dnscrypt_proxy \
--cap-drop=ALL \
--cap-add=NET_BIND_SERVICE \
--security-opt=no-new-privileges \
-p 5353:5353/tcp \
-p 5353:5353/udp \
localhost/dnscrypt_proxy:latest
ExecStop=/usr/bin/podman stop -t 10 dnscrypt_proxy
Restart=always
RestartSec=10s
KillMode=none
[Install]
WantedBy=default.targetReload and restart:
systemctl --user daemon-reload
systemctl --user enable --now dnscrypt-proxy.service
systemctl --user restart dnscrypt-proxy.service
systemctl --user status dnscrypt-proxy.serviceThese assume the container is mapped to 127.0.0.1:5354.
ss -lntu | grep 5354dig @127.0.0.1 -p 5354 google.com A +tcp +time=2 +tries=1
dig @127.0.0.1 -p 5354 google.com A +notcp +time=2 +tries=1dig @127.0.0.1 -p 5354 google.com A +tcp +time=2 +tries=1 | grep -E 'status:|Query time:|SERVER:'
dig @127.0.0.1 -p 5354 google.com A +tcp +time=2 +tries=1 | grep -E 'status:|Query time:|SERVER:'for d in google.com cloudflare.com github.com wikipedia.org; do
dig @127.0.0.1 -p 5354 "$d" A +tcp +time=2 +tries=1 | grep -E 'status:|Query time:|SERVER:'
donepodman ps | grep dnscrypt_proxy || echo "stopped"podman logs dnscrypt_proxy --tail 50
# or via systemd journal:
journalctl --user -u dnscrypt-proxy.service -n 100 --no-pagersystemctl --user restart dnscrypt-proxy.service
ss -lntu | grep 5353
dig @127.0.0.1 -p 5353 google.com A +tcp +time=2 +tries=1