certman

package module
v0.3.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 26, 2022 License: MIT Imports: 5 Imported by: 17

README

Certman

Go project version Build Status Coverage Status Code Climate Go Report Card

GoDoc license

Go TLS certificate reloading for the standard library http server.

Certman watches for changes to your certificate and key files and reloads them on change allowing the server to stay online during certificate changes. Useful for Let's Encrypt but also just in general as there's no reason to bring your servers down just to update certificates and keys.

Limitation

Certman handles only a single certificate and key pair and responds to all requests with this pair. It ignores if the client is sending a server name using SNI. I'm not sure if there's a generic enough way to implement this that handles all use cases and as it's a niche feature I haven't needed so I've left it out (pull requests welcome!). Certman's codebase is small so either fork the repo or copy and paste it into your project and modify it to your needs.

Installation

Using dep for dependency management (https://github.com/golang/dep):

dep ensure github.com/dyson/certman

Using go get:

$ go get github.com/dyson/certman

Usage

Generate a cert and key:

$ openssl req -new -newkey rsa:2048 -days 365 -nodes -x509 -sha256 -keyout /tmp/server.key -out /tmp/server.crt

Basic server passing in a logger to log certman events:

package main

import (
	"crypto/tls"
	"fmt"
	"log"
	"net/http"
	"os"

	"github.com/dyson/certman"
)

func main() {
	logger := log.New(os.Stdout, "", log.LstdFlags)

	cm, err := certman.New("/tmp/server.crt", "/tmp/server.key")
	if err != nil {
		logger.Println(err)
	}
	cm.Logger(logger)
	if err := cm.Watch(); err != nil {
		logger.Println(err)
	}

	http.HandleFunc("/", handler)
	s := &http.Server{
		Addr: ":8080",
		TLSConfig: &tls.Config{
			GetCertificate: cm.GetCertificate,
		},
	}
	if err := s.ListenAndServeTLS("", ""); err != nil {
		logger.Println(err)
	}
}

func handler(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "Hello")
}

Visit https://localhost:8080.

Overwrite exising certificate and key using the openssl gen command above.

Visit https://localhost:8080 again. Notice how existing requests are continued to be served by the old certificate.

Visit https://localhost:8080 in another browser and see the new certificate is being served for new requests.

Running example:

$ go run main.go
2017/08/01 16:05:23 certman: certificate and key loaded
2017/08/01 16:05:23 certman: watching for cert and key change
# Regenerated certificate and key here
2017/08/01 16:06:30 certman: watch event: "/tmp/server.key": WRITE
2017/08/01 16:06:30 certman: can't load cert or key file: tls: private key does not match public key
2017/08/01 16:06:30 certman: watch event: "/tmp/server.key": WRITE
2017/08/01 16:06:30 certman: can't load cert or key file: tls: private key does not match public key
2017/08/01 16:06:32 certman: watch event: "/tmp/server.crt": WRITE
2017/08/01 16:06:32 certman: certificate and key loaded
# Certificate loaded once the certificate and key can both be read correctly and they match

License

See LICENSE file.

Documentation

Overview

Package certman provides live reloading of the certificate and key files used by the standard library http.Server. It defines a type, certMan, with methods watching and getting the files. Only valid certificate and key pairs are loaded and an optional logger can be passed to certman for logging providing it implements the logger interface.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type CertMan added in v0.2.0

type CertMan struct {
	// contains filtered or unexported fields
}

A CertMan represents a certificate manager able to watch certificate and key pairs for changes.

func New added in v0.2.0

func New(certFile, keyFile string) (*CertMan, error)

New creates a new certMan. The certFile and the keyFile are both paths to the location of the files. Relative and absolute paths are accepted.

func (*CertMan) GetCertificate added in v0.2.0

func (cm *CertMan) GetCertificate(hello *tls.ClientHelloInfo) (*tls.Certificate, error)

GetCertificate returns the loaded certificate for use by the TLSConfig fields GetCertificate field in a http.Server.

func (*CertMan) Logger added in v0.2.0

func (cm *CertMan) Logger(logger logger)

Logger sets the logger for certMan to use. It accepts a logger interface.

func (*CertMan) Stop added in v0.2.0

func (cm *CertMan) Stop()

Stop tells certMan to stop watching for changes to the certificate and key files.

func (*CertMan) Watch added in v0.2.0

func (cm *CertMan) Watch() error

Watch starts watching for changes to the certificate and key files. On any change the certificate and key are reloaded. If there is an issue the load will fail and the old (if any) certificates and keys will continue to be used.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL