How can I keep my certs up-to-date? Can't challenge on port 80


(Chuck Connors) #1

I’m in a bit of a spot. My ISP blocks port 80 for home use but 443 is open. Caddy appears to use port 80 only for challenges. I can’t get Let’s Encrypt certs using Caddy. I have Let’s Encrypt running in a docker and I can get LE certs that way and I can point Caddy at those certs so Caddy does indeed work. I cannot, however, run LE and Caddy at the same time as they both use the same ports.

How can I keep my certs updated if both Caddy and LE container both use the same ports? I am using duckdns.org subdomain for my domain. I use Goddady for domain names for some side projects. I noticed https://caddyserver.com/docs/tls.dns.godaddy . Can I purchase a new domain and just use Godaddy? Somehow Caddy will generate a cert based on being able to get my DNS records from Godaddy?

I have a dynamic IP address. Can I use CNAME from Godaddy to duckdns.org and still be able to get the cert from Godaddy?

Thanks for the help. I’m awfully green when it comes to doing this sort of thing and would gratefully appreciate any information you can provide.


(Matthew Fay) #2

How does your LE container get its certificates? As far as I know, TLS-SNI (port 443) validation is still not available, so HTTP (port 80) and DNS validation are the only methods to validate new certificates.

Looks like you’ve already found out about the DNS challenge! That is the go-to when HTTP validation is unavailable.

Yes, you can. I believe their API functions just fine for Caddy’s DNS validation.

This is only a personal recommendation, but I’d suggest buying your domain from a more reputable seller like Gandi or even Google Domains, and pointing it at a free DNS provider like Cloudflare, which is also supported (I use them myself). I like to keep my domain registrar separate from my domain name servers.

The DNS challenge involves LetsEncrypt telling Caddy to set a specific TXT record on the authoritative nameserver. You provide Caddy with API keys to your DNS provider, which Caddy uses to set the record automatically, then tells LetsEncrypt to verify the record is present. It can take up to a minute or two depending on DNS provider, whereas HTTP validation usually only takes seconds.

Being able to set the public DNS record proves you either own, or were delegated control, of the domain.

Yes - you can add a DNS CNAME record pointing to your Duck DNS subdomain and continue using their dynamic DNS.


(Chuck Connors) #3

Thank you for this information. Excuse my ignorance, but if I go the Gandi/Google Domains route, I set up DNS at Cloudflare and I somehow use CNAME at Cloudflare to point to my duckdns.org subdomain so that I can keep my ip updated for the new domain name?


(Matthew Fay) #4

Yes. Setting a CNAME record on your new domain name will tell anyone requesting the IP address to use whatever IP address the CNAME target has.

So, if example.duckdns.org has an A record of 10.0.0.1, and subdomain.example.com has a CNAME of example.duckdns.org, anyone browsing to subdomain.example.com will visit 10.0.0.1.

Note that CNAMEs are prohibited for apex records, you can’t CNAME example.com directly - you can only CNAME a subdomain. This is a specification of the DNS system itself. Cloudflare get around this by letting you set the CNAME record in their control panel, but on the technical side of things, answering DNS requests as though it were actually an A record.


(Chuck Connors) #5

Thanks for all the great information. Just so I understand, I’d need to do something like this in cloudflare control panel:

CNAME subdomain1 is an alias of mycoolsubdomain.duckdns.org
CNAME subdomain2 is an alias of mycoolsubdomain.duckdns.org

With TTL set to automatic and status as DNS only. Is that right?


(Chuck Connors) #6

Disregard the previous message. I got that working fine. Now I’m trying to set up tls with cloudflare and am running into problems trying to get the auth stuff in there. Here’s my Caddyfile:

mysub.mynewdomain.com:443 {
        tls {
                dns cloudflare
                CLOUDFLARE_EMAIL {myemail@email.com}
                CLOUDFLARE_API_KEY {11111111111111111111111111111111}
        }
        proxy /  localhost:8123 {
                websocket
                transparent
        }
}

The error I’m getting is:

2018/09/11 11:12:22 Caddyfile:13 - Error during parsing: Unknown directive 'CLOUDFLARE_EMAIL'

I’ve tried moving things around but keep getting errors. I’m trying to wrap my head around the syntax but sure could use a helping hand. Many thanks!


(Joel) #7

Those values should be set as environment variables to the caddy process, not included in the Caddyfile. If you are running caddy in docker you could add a couple of -e arguments to your docker run command to export those environment variables to processes running in the container:

docker run -e CLOUDFLARE_EMAIL=myemail@email.com -e CLOUDFLARE_API_KEY=11111111111111111111111111111111 ...

Or if you must include them in your Caddyfile you should be able to specify them as:

mysub.mynewdomain.com:443 {
        tls {
                dns cloudflare myemail@email.com 11111111111111111111111111111111
        }
        proxy /  localhost:8123 {
                websocket
                transparent
        }
}

Note: I haven’t actually tested this syntax with the cloudflare provider but it seems to work the same way as the digitalocean DNS provider & I have tested that with a similar setup.


(Chuck Connors) #8

Thanks for this information. It did not work as you suggested but I did just set the environment variables on the command line and it worked perfectly! I haven’t set up docker for this yet as I am just trying to get things sorted with my Caddyfile. Things are working great now.

I also would like to add that you guys are fantastic! I tried for several days to get NGINX reverse proxy working and had questions that no one cared to respond to. You guys have a great community and are helping everyone including dummies like me! haha


(Joel) #9

I’m happy things are working okay for you now! That’s very interesting, would you mind sharing what error you get when using that syntax? I expected it to work partly because I saw that a user here was able to use that syntax successfully.

Glad you like the community here, I just drop in occasionally but @Whitestrake is always here helping out anyone who needs it.