13 ธันวาคม 2568

Traefik dnsChallenge with RFC2136 (Bind9)

 .env
RFC2136_NAMESERVER=<your_nameserver>
RFC2136_TSIG_KEY=<tsig_key>
RFC2136_TSIG_ALGORITHM=<tsig_algorithm>
RFC2136_TSIG_SECRET=<tsig_secret>

docker-compose.yml
- TRAEFIK_CERTIFICATESRESOLVERS_RFC2136_ACME_DNSCHALLENGE_RFC2136_NAMESERVER=${RFC2136_NAMESERVER}
- TRAEFIK_CERTIFICATESRESOLVERS_RFC2136_ACME_DNSCHALLENGE_RFC2136_TSIG_KEY=${RFC2136_TSIG_KEY}
- TRAEFIK_CERTIFICATESRESOLVERS_RFC2136_ACME_DNSCHALLENGE_RFC2136_TSIG_ALGORITHM=${RFC2136_TSIG_ALGORITHM}
- TRAEFIK_CERTIFICATESRESOLVERS_RFC2136_ACME_DNSCHALLENGE_RFC2136_TSIG_SECRET=${RFC2136_TSIG_SECRET}

traefik_config.yml
certificatesResolvers:
  rfc2136:
    acme:
      dnsChallenge:
        provider: "rfc2136"
      email: "<your_email>"
      storage: "/letsencrypt/rfc2136.json"

ref: https://go-acme.github.io/lego/dns/rfc2136/

HmacSHA1   = "hmac-sha1."
HmacSHA224 = "hmac-sha224."
HmacSHA256 = "hmac-sha256."
HmacSHA384 = "hmac-sha384."
HmacSHA512 = "hmac-sha512."

Traefik dnsChallenge with Spaceship DNS

 .env
SPACESHIP_API_KEY=<your_spaceship_api_key>
SPACESHIP_API_SECRET=<your_spaceship_api_secret>

docker-compose.yml
- TRAEFIK_CERTIFICATESRESOLVERS_SPACESHIP_ACME_DNSCHALLENGE_SPACESHIP_API_KEY=${SPACESHIP_API_KEY}
- TRAEFIK_CERTIFICATESRESOLVERS_SPACESHIP_ACME_DNSCHALLENGE_SPACESHIP_API_SECRET=$(SPACESHIP_API_SECRET)

traefik_config.yml
certificatesResolvers:
  spaceship:
    acme:
      dnsChallenge:
        provider: "spaceship"
      email: "<your_email>"
      storage: "letsencrypt/spaceship.json"

ref: https://go-acme.github.io/lego/dns/spaceship/

Traefik dnsChallenge with Clouflare DNS

 .env
LETSENCRYPT_TOKEN=<your_cloudflare_api_token>

docker-compose.yml
- TRAEFIK_CERTIFICATESRESOLVERS_CLOUDFLARE_ACME_DNSCHALLENGE_CLOUDFLARE_DNS_API_TOKEN=${LETSENCRYPT_TOKEN}

traefik_config.yml
certificatesResolvers:
  cloudflare:
    acme:
      dnsChallenge:
        provider: "cloudflare"
      email: "<your_email>"
      storage: "/letsencrypt/cloudflare.json"

ref: https://go-acme.github.io/lego/dns/cloudflare/

04 ธันวาคม 2568

SSL script with Certbot and RFC2136

 #!/bin/bash

# Certificate management script with Certbot and RFC2136

DOMAIN='*.example.com'  # Replace with your domain
EMAIL='your-email@example.com' # Replace with your email for notifications
DNS_SERVER='10.0.0.1' # Replace with your DNS server IP
KEY_NAME='your-key-name'  # Must match the key name on your DNS server
KEY_SECRET='your-base64-secret'  # Base64 encoded secret
KEY_ALGORITHM='HMAC-SHA512'  # or HMAC-MD5, HMAC-SHA1, HMAC-SHA256, HMAC-SHA384
PROPAGATION_SECONDS=20  # Time to wait for DNS propagation

# Create temporary rfc2136 credentials file on host
TMP_CREDS=$(mktemp)
cat > "$TMP_CREDS" <<EOF
dns_rfc2136_server = $DNS_SERVER
dns_rfc2136_name = $KEY_NAME
dns_rfc2136_secret = $KEY_SECRET
dns_rfc2136_algorithm = $KEY_ALGORITHM
EOF
chmod 600 "$TMP_CREDS"

echo "Created temporary credentials file: $TMP_CREDS"
echo "Issuing new certificate for $DOMAIN with Certbot (RFC2136)..."

docker run --rm -it \
    -v ./letsencrypt:/etc/letsencrypt \
    -v "$TMP_CREDS:/tmp/rfc2136.ini:ro" \
    certbot/dns-rfc2136 \
    certonly \
    --dns-rfc2136 \
    --dns-rfc2136-credentials /tmp/rfc2136.ini \
    --dns-rfc2136-propagation-seconds $PROPAGATION_SECONDS \
    --email "$EMAIL" \
    --agree-tos \
    --non-interactive \
    -d "$DOMAIN"

# Clean up temporary file
rm -f "$TMP_CREDS"
echo "Cleaned up temporary credentials file"
echo "Done!"

SSL script with acme.sh and RFC2136

 #!/bin/bash

# Certificate management script with acme.sh and RFC2136

NSUPDATE_SERVER='10.0.0.1' # Replace with your DNS server IP
NSUPDATE_ZONE='example.com' # Replace with your DNS zone
DOMAIN='*.example.com'  # Replace with your domain
KEY_NAME='your-key-name' # Must match the key name on your DNS server
KEY_SECRET='your-base64-secret' # Base64 encoded secret
KEY_ALGORITHM='hmac-sha512' # or hmac-md5, hmac-sha1, hmac-sha256, hmac-sha384

# Create nsupdate key content
NSUPDATE_KEY_CONTENT="key \"$KEY_NAME\" {
    algorithm $KEY_ALGORITHM;
    secret \"$KEY_SECRET\";
};"

echo "Issuing new certificate for $DOMAIN with acme.sh (RFC2136)..."
docker run --rm -it \
    -e NSUPDATE_SERVER="$NSUPDATE_SERVER" \
    -e NSUPDATE_KEY='/tmp/nsupdate.key' \
    -e NSUPDATE_ZONE="$NSUPDATE_ZONE" \
    -v ./acme.sh:/acme.sh \
    neilpang/acme.sh \
    sh -c "echo '$NSUPDATE_KEY_CONTENT' > /tmp/nsupdate.key && acme.sh --issue --server letsencrypt -k ec-256 --dns dns_nsupdate -d $DOMAIN"

echo "Done!"

02 ธันวาคม 2568

Block Adguard Home admin but allow DOH

 location /dns-query {
    proxy_pass https://10.0.0.103/dns-query;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

location / {
    return 404;
}

20 มีนาคม 2568

Mikrotik container : ZeroTier network controller user interface

No public IP address is required; an internet connection alone is sufficient.

/container mounts
add dst=/opt/key-networks/ztncui/etc name=ztncui src=/ztncui
add dst=/var/lib/zerotier-one name=zerotier-one src=/zerotier-one

/container envs
add key=NODE_ENV name=zerotier value=production
add key=HTTPS_PORT name=zerotier value=3443
add key=ZTNCUI_PASSWD name=zerotier value=password

/container
add comment=zeerotier envlist=zerotier interface=veth-zerotier logging=yes mounts=ztncui,zerotier-one start-on-boot=yes workdir=/

WARNING: IF YOU DO NOT SET PASSWORD, YOU HAVE TO USE container shell <CONTAINER ID>, and then cat /var/log/docker-ztncui.log to get your random password. This is gatekeeper.

ref
- https://gist.github.com/dnburgess/b839c2230890068c30bb5ed5ee2d22ba
- https://github.com/key-networks/ztncui-aio