joohoi / acme-dns

Limited DNS server with RESTful HTTP API to handle ACME DNS challenges easily and securely.
MIT License
2.18k stars 233 forks source link

SERVFAIL looking up TXT for _acme-challenge.auth.mydomain.de #194

Closed p-baum closed 5 years ago

p-baum commented 5 years ago

I don't know what I'm doing wrong but I can't for life of me get this working with docker. The best I can get is:

Creating network "acmedns_default" with the default driver
Creating acme-dns ... done
Attaching to acme-dns
acme-dns   | time="2019-10-30T14:06:45Z" level=info msg="Using config file" file=/etc/acme-dns/config.cfg
acme-dns   | time="2019-10-30T14:06:45Z" level=info msg="Connected to database"
acme-dns   | time="2019-10-30T14:06:45Z" level=debug msg="Adding new record to domain" domain=auth.hauscloud.de. recordtype=A
acme-dns   | time="2019-10-30T14:06:45Z" level=debug msg="Adding new record to domain" domain=auth.hauscloud.de. recordtype=NS
acme-dns   | time="2019-10-30T14:06:45Z" level=debug msg="Adding new record to domain" domain=auth.hauscloud.de. recordtype=SOA
acme-dns   | time="2019-10-30T14:06:45Z" level=info msg="Listening DNS" addr="127.0.0.1:53" proto=tcp4
acme-dns   | time="2019-10-30T14:06:45Z" level=info msg="2019/10/30 14:06:45 [INFO][cache:0xc00008c640] Started certificate maintenance routine"
acme-dns   | time="2019-10-30T14:06:46Z" level=info msg="2019/10/30 14:06:46 [INFO][auth.hauscloud.de] Obtain certificate"
acme-dns   | time="2019-10-30T14:06:46Z" level=info msg="[INFO] [auth.hauscloud.de] acme: Obtaining bundled SAN certificate"
acme-dns   | time="2019-10-30T14:06:46Z" level=info msg="[INFO] [auth.hauscloud.de] AuthURL: https://acme-staging-v02.api.letsencrypt.org/acme/authz-v3/17802585"
acme-dns   | time="2019-10-30T14:06:46Z" level=info msg="[INFO] [auth.hauscloud.de] acme: Could not find solver for: tls-alpn-01"
acme-dns   | time="2019-10-30T14:06:46Z" level=info msg="[INFO] [auth.hauscloud.de] acme: Could not find solver for: http-01"
acme-dns   | time="2019-10-30T14:06:46Z" level=info msg="[INFO] [auth.hauscloud.de] acme: use dns-01 solver"
acme-dns   | time="2019-10-30T14:06:46Z" level=info msg="[INFO] [auth.hauscloud.de] acme: Preparing to solve DNS-01"
acme-dns   | time="2019-10-30T14:06:46Z" level=info msg="[INFO] [auth.hauscloud.de] acme: Trying to solve DNS-01"
acme-dns   | time="2019-10-30T14:06:46Z" level=info msg="[INFO] [auth.hauscloud.de] acme: Checking DNS record propagation using [127.0.0.11:53]"
acme-dns   | time="2019-10-30T14:06:46Z" level=info msg="[INFO] Wait for propagation [timeout: 1m0s, interval: 2s]"
acme-dns   | time="2019-10-30T14:06:46Z" level=info msg="[INFO] [auth.hauscloud.de] acme: Cleaning DNS-01 challenge"
acme-dns   | time="2019-10-30T14:06:47Z" level=info msg="[INFO] Unable to deactivate the authorization: https://acme-staging-v02.api.letsencrypt.org/acme/authz-v3/17802585"
acme-dns   | time="2019-10-30T14:06:47Z" level=info msg="2019/10/30 14:06:47 [ERROR][auth.hauscloud.de] failed to obtain certificate: acme: Error -> One or more domains had a problem:"
acme-dns   | time="2019-10-30T14:06:47Z" level=info msg="[auth.hauscloud.de] acme: error: 400 :: urn:ietf:params:acme:error:dns :: DNS problem: SERVFAIL looking up TXT for _acme-challenge.auth.hauscloud.de, url: (attempt 1/3; challenge=dns-01)"
acme-dns   | time="2019-10-30T14:06:48Z" level=info msg="[INFO] [auth.hauscloud.de] acme: Obtaining bundled SAN certificate"
acme-dns   | time="2019-10-30T14:06:48Z" level=info msg="[INFO] [auth.hauscloud.de] AuthURL: https://acme-staging-v02.api.letsencrypt.org/acme/authz-v3/17802593"
acme-dns   | time="2019-10-30T14:06:48Z" level=info msg="[INFO] [auth.hauscloud.de] acme: Could not find solver for: tls-alpn-01"
acme-dns   | time="2019-10-30T14:06:48Z" level=info msg="[INFO] [auth.hauscloud.de] acme: Could not find solver for: http-01"
acme-dns   | time="2019-10-30T14:06:48Z" level=info msg="[INFO] [auth.hauscloud.de] acme: use dns-01 solver"
acme-dns   | time="2019-10-30T14:06:48Z" level=info msg="[INFO] [auth.hauscloud.de] acme: Preparing to solve DNS-01"
acme-dns   | time="2019-10-30T14:06:48Z" level=info msg="[INFO] [auth.hauscloud.de] acme: Trying to solve DNS-01"
acme-dns   | time="2019-10-30T14:06:48Z" level=info msg="[INFO] [auth.hauscloud.de] acme: Checking DNS record propagation using [127.0.0.11:53]"
acme-dns   | time="2019-10-30T14:06:48Z" level=info msg="[INFO] Wait for propagation [timeout: 1m0s, interval: 2s]"
acme-dns   | time="2019-10-30T14:06:48Z" level=info msg="[INFO] [auth.hauscloud.de] acme: Cleaning DNS-01 challenge"
acme-dns   | time="2019-10-30T14:06:48Z" level=info msg="[INFO] Unable to deactivate the authorization: https://acme-staging-v02.api.letsencrypt.org/acme/authz-v3/17802593"
acme-dns   | time="2019-10-30T14:06:48Z" level=info msg="2019/10/30 14:06:48 [ERROR][auth.hauscloud.de] failed to obtain certificate: acme: Error -> One or more domains had a problem:"
acme-dns   | time="2019-10-30T14:06:48Z" level=info msg="[auth.hauscloud.de] acme: error: 400 :: urn:ietf:params:acme:error:dns :: DNS problem: SERVFAIL looking up TXT for _acme-challenge.auth.hauscloud.de, url: (attempt 2/3; challenge=dns-01)"
acme-dns   | time="2019-10-30T14:06:49Z" level=info msg="[INFO] [auth.hauscloud.de] acme: Obtaining bundled SAN certificate"
acme-dns   | time="2019-10-30T14:06:50Z" level=info msg="[INFO] [auth.hauscloud.de] AuthURL: https://acme-staging-v02.api.letsencrypt.org/acme/authz-v3/17802598"
acme-dns   | time="2019-10-30T14:06:50Z" level=info msg="[INFO] [auth.hauscloud.de] acme: Could not find solver for: tls-alpn-01"
acme-dns   | time="2019-10-30T14:06:50Z" level=info msg="[INFO] [auth.hauscloud.de] acme: Could not find solver for: http-01"
acme-dns   | time="2019-10-30T14:06:50Z" level=info msg="[INFO] [auth.hauscloud.de] acme: use dns-01 solver"
acme-dns   | time="2019-10-30T14:06:50Z" level=info msg="[INFO] [auth.hauscloud.de] acme: Preparing to solve DNS-01"
acme-dns   | time="2019-10-30T14:06:50Z" level=info msg="[INFO] [auth.hauscloud.de] acme: Trying to solve DNS-01"
acme-dns   | time="2019-10-30T14:06:50Z" level=info msg="[INFO] [auth.hauscloud.de] acme: Checking DNS record propagation using [127.0.0.11:53]"
acme-dns   | time="2019-10-30T14:06:50Z" level=info msg="[INFO] Wait for propagation [timeout: 1m0s, interval: 2s]"
acme-dns   | time="2019-10-30T14:06:50Z" level=info msg="[INFO] [auth.hauscloud.de] acme: Cleaning DNS-01 challenge"
acme-dns   | time="2019-10-30T14:06:50Z" level=info msg="[INFO] Unable to deactivate the authorization: https://acme-staging-v02.api.letsencrypt.org/acme/authz-v3/17802598"
acme-dns   | time="2019-10-30T14:06:50Z" level=info msg="2019/10/30 14:06:50 [ERROR][auth.hauscloud.de] failed to obtain certificate: acme: Error -> One or more domains had a problem:"
acme-dns   | time="2019-10-30T14:06:50Z" level=info msg="[auth.hauscloud.de] acme: error: 400 :: urn:ietf:params:acme:error:dns :: DNS problem: SERVFAIL looking up TXT for _acme-challenge.auth.hauscloud.de, url: (attempt 3/3; challenge=dns-01)"
acme-dns   | time="2019-10-30T14:06:51Z" level=fatal msg="auth.hauscloud.de: obtaining certificate: failed to obtain certificate: acme: Error -> One or more domains had a problem:\n[auth.hauscloud.de] acme: error: 400 :: urn:ietf:params:acme:error:dns :: DNS problem: SERVFAIL looking up TXT for _acme-challenge.auth.hauscloud.de, url: \n"
acme-dns exited with code 1

At namecheap I have the following records:

A record: auth.hauscloud.de > 78.46.189.59 NS record: auth > auth.hauscloud.de (namecheap adds the domain)

my latest conf attempt looks like this:

[general]
# DNS interface. Note that systemd-resolved may reserve port 53 on 127.0.0.53
# In this case acme-dns will error out and you will need to define the listening interface
# for example: listen = "127.0.0.1:53"
listen = "127.0.0.1:53"
# protocol, "both", "both4", "both6", "udp", "udp4", "udp6" or "tcp", "tcp4", "tcp6"
protocol = "tcp4"
# domain name to serve the requests off of
domain = "auth.hauscloud.de"
# zone name server
nsname = "auth.hauscloud.de"
# admin email address, where @ is substituted with .
nsadmin = "admin.hauscloud.de"
# predefined records served in addition to the TXT
records = [
    # domain pointing to the public IP of your acme-dns server 
    "auth.hauscloud.de. A 78.46.189.59",
    # specify that acmedns.hauscloud.de will resolve any *.auth.hauscloud.de records
    "auth.hauscloud.de. NS auth.hauscloud.de.",
]
# debug messages from CORS etc
debug = true

[database]
# Database engine to use, sqlite3 or postgres
engine = "sqlite3"
# Connection string, filename for sqlite3 and postgres://$username:$password@$host/$db_name for postgres
# Please note that the default Docker image uses path /var/lib/acme-dns/acme-dns.db for sqlite3
connection = "/var/lib/acme-dns/acme-dns.db"
# connection = "postgres://user:password@localhost/acmedns_db"

[api]
# listen ip eg. 127.0.0.1
ip = "127.0.0.1"
# disable registration endpoint
disable_registration = false
# listen port, eg. 443 for default HTTPS
port = "80"
# possible values: "letsencrypt", "letsencryptstaging", "cert", "none"
tls = "letsencryptstaging"
# only used if tls = "cert"
tls_cert_privkey = "/etc/tls/example.org/privkey.pem"
tls_cert_fullchain = "/etc/tls/example.org/fullchain.pem"
# only used if tls = "letsencrypt"
acme_cache_dir = "api-certs"
# CORS AllowOrigins, wildcards can be used
corsorigins = [
    "*"
]
# use HTTP header to get the client ip
use_header = false
# header name to pull the ip address / list of ip addresses from
header_name = "X-Forwarded-For"

[logconfig]
# logging level: "error", "warning", "info" or "debug"
loglevel = "debug"
# possible values: stdout, TODO file & integrations
logtype = "stdout"
# file path for logfile TODO
# logfile = "./acme-dns.log"
# format, either "json" or "text"
logformat = "text"

It is unclear to me what IP addresses I should use for 'api' and 'general' section so i have tried all permutations i can think of.

Why does it never work?

joohoi commented 5 years ago

This happens most likely because Let's Encrypt cannot request records from your acme-dns instance. The listen configuration directive should be an address that a client can connect from the public internet.

If your server has the IP address that you pointed to with the NS record, you should use that for the listen address, but in some environments the interfaces might be behind port forwarding firewall.

p-baum commented 5 years ago

OK. Thankyou for the quick response.

I changed listen to my external IP address. Now I get this:

Creating network "acmedns_default" with the default driver
Creating acme-dns ... done
Attaching to acme-dns
acme-dns   | time="2019-10-30T15:45:59Z" level=info msg="Using config file" file=/etc/acme-dns/config.cfg
acme-dns   | time="2019-10-30T15:45:59Z" level=info msg="Connected to database"
acme-dns   | time="2019-10-30T15:45:59Z" level=debug msg="Adding new record to domain" domain=auth.hauscloud.de. recordtype=A
acme-dns   | time="2019-10-30T15:45:59Z" level=debug msg="Adding new record to domain" domain=auth.hauscloud.de. recordtype=NS
acme-dns   | time="2019-10-30T15:45:59Z" level=debug msg="Adding new record to domain" domain=auth.hauscloud.de. recordtype=SOA
acme-dns   | time="2019-10-30T15:45:59Z" level=info msg="Listening DNS" addr="78.46.189.59:53" proto=tcp4
acme-dns   | time="2019-10-30T15:45:59Z" level=fatal msg="listen tcp4 78.46.189.59:53: bind: cannot assign requested address"
acme-dns exited with code 1

my docker-compose looks like this:

version: '3'

services:
  acmedns:
    image: joohoi/acme-dns:latest
    container_name: "acme-dns"
    ports:
      - "78.46.189.59:53:53"
      - "80:80"
    volumes:
      - "/root/acmedns/config:/etc/acme-dns:ro"
      - "/root/acmedns/data:/var/lib/acme-dns"

The hosts netstat looks like this:

root@hc1:~# netstat -pant
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 127.0.0.53:53           0.0.0.0:*               LISTEN      18343/systemd-resol 
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      1122/sshd           
tcp        0      0 78.46.189.59:22         101.51.149.248:61798    ESTABLISHED 29938/sshd: [accept 
tcp        0      0 78.46.189.59:22         112.85.42.237:40244     ESTABLISHED 29935/sshd: [accept 
tcp        0    340 78.46.189.59:22         81.171.75.163:46392     ESTABLISHED 29939/sshd: root@pt 
tcp        0      1 78.46.189.59:22         112.85.42.237:22636     FIN_WAIT1   -                   
tcp6       0      0 :::22                   :::*                    LISTEN      1122/sshd           
tcp6       0      0 :::2376                 :::*                    LISTEN      7280/dockerd 
p-baum commented 5 years ago

I finally got it running:

The working combination is:

docker-compose.yml

    ports:
      - "$EXTERNAL_HOST_IP:53:53/tcp"
      - "$EXTERNAL_HOST_IP:53:53/udp"
      - "80:80"

config.cng

[general]
listen = "0.0.0.0:53"
[api]
ip = "0.0.0.0"
mskwon commented 4 years ago

Hi everyone,

I also struggled with this situation, only for me I wasn't using just docker-compose but also had a couple layers in between - like this: Router <-> keepalived <-> nginx <-> acme-dns

The answer that is in this thread still applies, but instead of $EXTERNAL_HOST_IP you can put in the docker host ip address - for example, if the host running docker has an ip address of 192.168.0.55 assigned to it by your network dhcp server and you are routing via port 5353 then you can use this in the ports section:

  ports:
    - "192.168.0.55:5353:53

Just a heads up!