Writing a TCP/UDP server type for Caddy

@miekg Just add those directives to your list of allowed directives :slight_smile: It should just work, assuming your DNS server imports it as one of the “standard” plugins.

I do this too, but :exclamation: make sure to use Let’s Encrypt’s staging endpoint :bangbang:

Or you could just set up GitHub - letsencrypt/pebble: A miniature version of Boulder, Pebble is a small RFC 8555 ACME test server not suited for a production certificate authority. as a lightweight ACME CA on your local computer (haven’t tried this yet).

@pieterlouw I’ve been thinking about this… indeed, the server type will need to know what hostnames to support. Maybe you could add a hosts (or server_names or something…) directive or something to your server types, that registers the host names to apply for that block of the Caddyfile? I’d rather not tack it onto the tls directive because it gets confusing when used with HTTP where the host is often specified in the site name, but if we did, it would be called sni I think.

@miekg, thanks will try this.

I’m curious, do you have auto tls built into coredns?

Do you mean the Caddyfile will look something like this:

proxy :12017 :22017 {
    hosts example.com
}

“…that registers the host names to apply for that block”, by that you mean I register the hostnames in the action function for the hosts directive to be used in the callback function specified in caddy.RegisterParsingCallback("net", "tls", activateTLS) ?

Also, how would I need to handle tls if the user want to specify it’s own certificate instead of using the auto feature?

But I think i need just the middleware in a git repo, not sure if it will work will all of caddy in a repo.
Also I need to pass ServerType to (for instance) to startshutdown.go’s registration function - would be nice to find some middleware groun here that sharing plugins becomes easier (at least the non-middleware ones - bind comes to mind)

No, but we’re planning it: Let's encrypt for TLS? · Issue #582 · coredns/coredns · GitHub

1 Like

Nice. We should be able to share notes as I guess it will be very similar for both server types

sgtm.

Note I want to do some details differently, like spinning for TLS certs while starting up (similar to the https_google protocol in middleware/proxy). I.e. If let’s encrypt is down, CoreDNS should just start up and flag that middleware as unhealthy.

1 Like

Yes! That, precisely.

Take a look at how the https.go file in the httpserver package does it. There’s a function called caddytls.QualifiesForManagedTLS that you can call and it will do the heavy lifting of figuring out if you should set the Managed field of the TLSConfig to true.

No, I think it should just work. :thinking: Let me know if it doesn’t though. You should just need to import the package: https://github.com/mholt/caddy/blob/36d2027493a65e76463d7075d37cd0a139dcb7f7/caddyhttp/caddyhttp.go#L32 and then add it to your list of directives: https://github.com/mholt/caddy/blob/36d2027493a65e76463d7075d37cd0a139dcb7f7/caddyhttp/httpserver/plugin.go#L443-L444

Sweet ***** that works:

diff --git a/middleware.cfg b/middleware.cfg
index 75985cf..4a30a87 100644
--- a/middleware.cfg
+++ b/middleware.cfg
@@ -42,3 +42,4 @@
 200:proxy:proxy
 210:whoami:whoami
 220:erratic:erratic
+500:startup:github.com/mholt/caddy/startupshutdown

go gen; go build

I repeat the line for shutdown and have that working as well.

except there not dns server plugins, but they don’t need to, because no middleware.

Yep. Any server type can be shutdown or started, which is why it doesn’t need to be tied to a specific server type.

TLS knows the »SNI extension«. That is, the server name will be sent before the handshake completes, in cleartext. (That’s why you shouldn’t run stuff like SecureDrop or the like on its own domain.) It’s stored here:

ClientHelloInfo.ServerName

2 Likes

Hey @pieterlouw - I talked to someone at my university today named Jordan who wants to get on board and help with your TCP/UDP server plugin. Might be a few weeks out still, but he’ll contact you soon I think!

That’s great news!

3 posts were split to a new topic: TLS storage plugin type for sharing certs

So I’ve done quite a bit to add tls to the plugin.

I have registered the callback and the config getter caddy.RegisterParsingCallback(serverType, "tls", activateTLS)

caddytls.RegisterConfigGetter(serverType, func(c *caddy.Controller) *caddytls.Config {return GetConfig(c).TLS})

The activateTLS follow all the steps stated in the wiki guide.

I also added a tlshost directive to set the hostname the tls will use i.e

echo :22017 {
    tlshost echo.caddynet.com
}

Before I call tls.Listen I do the necessary call to caddytls.MakeTLSConfig to get the tlsConfig to use in tls.Listen

When I start caddy I get the Let’s Encrypt questionaire. (I cancelled as I’m not on an owned domain)

I tried to test with the self-signed option like this

echo :22017 {
    tlshost localhost
    tls self_signed
}

But then I recive an error: tls: neither Certificates nor GetCertificate set in Config when I call tls.Listen from my server.
I have double checked and debugged quit for a while now and can’t exactly figure out what I’m doing wrong here. Have I missed something?

caddy-net (main repo)
caddy-net (tls branch) [EDIT: tls brand merged and deleted]

I’d suggest going into config.go and see what configMap looks like by printing it: https://github.com/mholt/caddy/blob/4e1229e7c9bd5643ed079f3dafa25df4e426da56/caddytls/config.go#L350

And make sure this line gets executed: https://github.com/mholt/caddy/blob/4e1229e7c9bd5643ed079f3dafa25df4e426da56/caddytls/config.go#L267

Make sure everything checks out there. Hope that helps!

Edit: How do you feel about just using the directive name host instead of tlshost? In theory the hostname wouldn’t have to be limited to TLS.

Thanks,

After adding some traces I could see configMap loaded and the line mentioned did execute.
It turns out that I used the wrong function when creating a listener for tls.
I used tls.Listen() but when I switched to tls.NewListener() it works. (Still unsure why exactly…)

I don’t have a problem naming the directive host - I named it tlshost as I thought that was the only reason a host would need to be specified. Do you see a reason why it maybe could be plural (hosts)?

I’ll finish off the tls for the proxy and merge then I guess it’s just tests that left.[EDIT: I have implemented tls for the proxy as well and merged to master]

I might need help with testing auto-TLS as at the momenet I don’t own a domain of my own.

Pieter