Add auto TLS instructions

Matt Holt 2016-08-19 22:47:44 -06:00
parent 1ab91b7ef9
commit f779535543

@ -80,4 +80,40 @@ type UDPServer interface {
If your server only uses TCP, the `*Packet()` methods may be no-ops (i.e. they return `nil`). The inverse is true for non-TCP servers. A server may also use both TCP and UDP, and implement all four methods.
Once this interface is implemented and configuration is properly applied from Caddyfile directives, your server type is ready to roll. Put it under test and add it to the Caddy download page!
Once this interface is implemented and configuration is properly applied from Caddyfile directives, your server type is ready to roll.
### Automatic TLS
Server types that _can_ use TLS should enable TLS automatically before we add it to the Caddy download page. Import the [`caddytls`](https://godoc.org/github.com/mholt/caddy/caddytls) package to use Caddy's magic TLS features. This can seem a little confusing to integrate at first, but once it's working you'll love it and realize it's soooo worth it.
- You will need a way to store Caddy TLS configurations for your server instances. Typically this just means adding a field to your server's config struct.
- That same server config struct type should implement the [`caddytls.ConfigHolder`](https://godoc.org/github.com/mholt/caddy/caddytls#ConfigHolder) interface. This is just a few getter methods.
- Call [`RegisterConfigGetter()`](https://godoc.org/github.com/mholt/caddy/caddytls#RegisterConfigGetter) in your package's init() so that the caddytls package knows how to ask for a config when it is parsing the Caddyfile for your server type. (Your "config getter" will have to make a new `caddytls.Config` if one does not already exist for the given Controller.)
- Add the `tls` directive to your server type's list of directives. Usually it goes near the front of the list.
When you are instantiating your actual server value and need a [`tls.Config`](https://golang.org/pkg/crypto/tls/#Config), you can call `caddytls.MakeTLSConfig(tlsConfigs)` where `tlsConfigs` is a `[]caddytls.Config`. This function will convert a list of Caddy TLS configs to a single standard library tls.Config for you. You can then use this in a call to [`tls.NewListener()`](https://golang.org/pkg/crypto/tls/#NewListener).
Finally, you typically want to enable TLS while the Caddyfile is being parsed. For example, the HTTP server configures HTTPS right after the `tls` directive is executed. You should use your package's `init()` function to register a parsing callback that goes through the configurations and configures TLS:
```go
// replace "http" with your own server type name
caddy.RegisterParsingCallback("http", "tls", activateHTTPS)
```
This code executes the `activateHTTPS()` function after the `tls` directive is finished setting up. Your server type should have a similar function that enables TLS in a way that makes sense to it. To give you an idea, the HTTP server's activateHTTPS function does the following:
1. Prints a message to stdout, "Activating privacy features..." (if the operator is present; i.e. `caddy.Started() == false`) because the process can take a few seconds
2. Sets the `Managed` field to `true` on all configs that should be fully managed
3. Calls [`ObtainCert()`](https://godoc.org/github.com/mholt/caddy/caddytls#Config.ObtainCert) for each config (this method only obtains certificates if the config qualifies and has its Managed field set to true).
4. Configures the server struct to use the newly-obtained certificates by setting the `Enabled` field of the TLS config to `true` and calling [`caddytls.CacheManagedCertificate()`](https://godoc.org/github.com/mholt/caddy/caddytls#CacheManagedCertificate) which actually loads the cert into memory for use
5. Calls [`caddytls.SetDefaultTLSParams()`](https://godoc.org/github.com/mholt/caddy/caddytls#SetDefaultTLSParams) to make sure all the necessary fields have a value
6. Calls [`caddytls.RenewManagedCertificates(true)`](https://godoc.org/github.com/mholt/caddy/caddytls#RenewManagedCertificates) to ensure that all certificates that were loaded into memory have been renewed if necessary
That's a lot to do, but you can also [look at how the HTTP server does it](https://github.com/mholt/caddy/blob/c75ee0000e1677737e0f05efe8de4c101814b848/caddyhttp/httpserver/https.go#L12) (<-- this is a permalink, so the latest code may be better) for guidance.
To help preserve perfect forward secrecy, you should call [`caddytls.RotateSessionTicketKeys()`](https://godoc.org/github.com/mholt/caddy/caddytls#RotateSessionTicketKeys) when instantiating your server value, passing in the TLS config. Be sure to close the channel it returns when your server is stopped.
Everything else about TLS: renewals, OCSP, and other maintenance, happen for you, since those are the same for all server types. All these steps simply hook your server type up to Caddy's TLS package so that it knows how to do its job.
Test your integration of the caddytls package thoroughly. Once it's working well, let's add your server type to the download page!