Getting started¶
This walkthrough serves HTTPS with the package's hardened defaults, then points a client at it — the two ends of a TLS connection, both secured from the same config.
Install¶
The module targets a current Go toolchain and pulls in only cockroachdb/errors.
Serve HTTPS with hardened defaults¶
A Pair is the typed
{Enabled, Cert, Key} triple describing a certificate.
ServerConfig
loads that certificate into the hardened
DefaultConfig and
returns a ready *crypto/tls.Config:
package main
import (
"log"
"net/http"
"gitlab.com/phpboyscout/go/tls"
)
func main() {
pair := tls.Pair{
Enabled: true,
Cert: "/etc/certs/server.pem",
Key: "/etc/certs/server-key.pem",
}
// Advertise HTTP/2 then HTTP/1.1 via ALPN; omit the args for no ALPN.
cfg, err := pair.ServerConfig("h2", "http/1.1")
if err != nil {
log.Fatal(err)
}
srv := &http.Server{Addr: ":8443", TLSConfig: cfg}
// The certificate is already loaded into TLSConfig, so the file
// arguments to ListenAndServeTLS are empty.
log.Fatal(srv.ListenAndServeTLS("", ""))
}
ServerConfig returns an error if the certificate or key cannot be loaded, so a
misconfigured path fails fast at startup rather than on the first handshake.
Connect a hardened client¶
ClientConfig
returns the same hardened config for the client side. With no arguments it trusts
the system root store; pass PEM CA files to trust a private CA as well:
clientCfg, err := tls.ClientConfig() // trust system roots
if err != nil {
log.Fatal(err)
}
client := &http.Client{
Transport: &http.Transport{TLSClientConfig: clientCfg},
}
If your server presents a certificate from a private CA (self-signed or an internal authority), hand the client the CA's PEM file:
Guard on validity¶
Pair.Valid reports
whether TLS is enabled and both paths are set — handy for deciding between an HTTP
and an HTTPS listener at boot:
if pair.Valid() {
// serve TLS with pair.ServerConfig(...)
} else {
// fall back to plain HTTP, or refuse to start
}
Next steps¶
- Harden a server & client — private-CA trust, ALPN, and resolving one certificate across several transports.
- Security threat model — the reasoning behind the defaults you just used.