Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up

golang autocert library for letsencrypt

License

NotificationsYou must be signed in to change notification settings

foomo/simplecert

Repository files navigation

     _                 _                    _ ___(_)_ __ ___  _ __ | | ___  ___ ___ _ __| |_/ __| | '_ ` _ \| '_ \| |/ _ \/ __/ _ \ '__| __|\__ \ | | | | | | |_) | |  __/ (_|  __/ |  | |_|___/_|_| |_| |_| .__/|_|\___|\___\___|_|   \__|                |_|

Golang Library for automatic LetsEncrypt SSL Certificates

Go Report CardLicenseGolangLinuxmacOSwindowsGoDoc

Obtains certificates automatically, and manages renewal and hot reload for your Golang application.It uses theLEGO Library to perform ACME challenges,and themkcert utility to generate self-signed trusted certificates for local development.

Main goals:

  • ease of use: simplicity and integration with go standard library
  • transparency: products of intermediate steps are preserved, dedicated logfile for simplecert
  • flexibility: configurable design and cross platform support

UPDATE: The vendored lego version has been updated to v2.2.0 and now supports issuing wildcard certificates by using ACMEv2 challenges.

You need to supply the following data to simplecert: Domains, Contact Email and a Directory to store the certs in (CacheDir).On startup, call the simplecert.Init() function and pass your config.You will receive a certReloader instance, that has a GetCertificateFunc to allow hot reloading the cert upon renewal.See Usage for a detailed example.

A new certificate will be obtained automatically if the domains have changed, both in local and in production mode.

For more advanced usage, see the config section for all configuration options.

Index

Install

go get -u -v github.com/foomo/simplecert

API

Simplecert provides a few wrappers similar tohttp.ListenAndServe from the go standard library:

For running on a production server:

funcListenAndServeTLS(addrstring,handler http.Handler,mailstring,cleanupfunc(),domains...string)error

For local development:

funcListenAndServeTLSLocal(addrstring,handler http.Handler,cleanupfunc(),domains...string)error

The custom wrapper allows to pass asimplecert.Config and atls.Config:

funcListenAndServeTLSCustom(addrstring,handler http.Handler,cfg*Config,tlsconf*tls.Config,cleanupfunc(),domains...string)error

There is a util for redirecting HTTP requests to HTTPS:

funcRedirect(w http.ResponseWriter,req*http.Request)

And a function to initialize simplecert after applying the desired configuration:

funcInit(cfg*Config,cleanupfunc()) (*CertReloader,error)

The cleanup function will be called upon receiving the syscall.SIGINT or syscall.SIGABRT signal and can be used to stop your backend gracefully. If you don't need it, simpy pass nil.

Local Development

To make local development less of a pain, simplecert integratesmkcert,to obtain self signed certificates for your desired domains, trusted by your computer.

Follow theinstallation instructions to install the mkcert commandline tool.

In order to use simplecert for local development, set theLocal field in the config to true.

Certificates generated for local development are not checked for expiry,the certificates generated by mkcert are valid for 10 years!

Important:

Using wildcard certificates in local mode does not work out of the box, since /etc/hosts doesn't support resolving wild card entries.

You'll have to use other services like dnsmasq. Just edit dnsmasq.conf and add the following line:

address=/yourdomain.com/127.0.0.1

This will resolve all requests to domains that end onyourdomain.com with127.0.0.1.

Host Entries

To resolve the domain name for your certificate to your localhost,simplecert adds an entry for each domain name to your/etc/hosts file.

This can be disabled by setting theUpdateHosts field in the config to false.

Usage

Simplecert has a default configuration available:simplecert.Default

You will need to update theDomains,CacheDir andSSLEmail and you are ready to go.

// init simplecertcfg:=simplecert.Defaultcfg.Domains= []string{"yourdomain.com","www.yourdomain.com"}cfg.CacheDir="/etc/letsencrypt/live/yourdomain.com"cfg.SSLEmail="you@emailprovider.com"cfg.DNSProvider="cloudflare"certReloader,err:=simplecert.Init(cfg,nil)iferr!=nil {log.Fatal("simplecert init failed: ",err)}// channel to handle errorserrChan:=make(chanerror)// redirect HTTP to HTTPS// CAUTION: This has to be done AFTER simplecert setup// Otherwise Port 80 will be blocked and cert registration fails!log.Println("starting HTTP Listener on Port 80")gofunc(){errChan<-http.ListenAndServe(":80",http.HandlerFunc(simplecert.Redirect))}()// init strict tlsConfig with certReloader// you could also use a default &tls.Config{}, but be warned this is highly insecure// our foomo/tlsconfig provides a simple interface to configure the tls for different scenariostlsconf:=tlsconfig.NewServerTLSConfig(tlsconfig.TLSModeServerStrict)// now set GetCertificate to the reloaders GetCertificateFunc to enable hot reloadtlsconf.GetCertificate=certReloader.GetCertificateFunc()// init servers:=&http.Server{Addr:":443",TLSConfig:tlsconf,}// start serving in a new goroutinegofunc() {errChan<-s.ListenAndServeTLS("","")}()// fatal on any errorslog.Fatal(<-errChan)

Challenges

Simplecert uses the letsencrypt ACMEv2 API and supports HTTP, TLS and DNS Challenges.

For the DNS challenge, an API token of an provider must be exported as environment variable.

Graceful service shutdown and restart

In case of using the HTTP or TLS challenges, port 80 or 443 must temporarily be freed.

Thesimplecert.Config contains two functions that can be set to accomplish this:

  • WillRenewCertificate, called just before the certificate will be renewed.
  • DidRenewCertificate, called after the certificate was renewed.

These functions can be used to gracefully stop the running service,and bring it back up once the certificate renewal is complete.

If you want to exchange the certificates manually on disk and force the running service to reload them,simply send aSIGHUP signal to your running instance:

kill -HUP <pid>

Backup mechanism

Simplecert creates a backup of your old certificate when it is being renewed.

All data is stored in the configured CacheDir.

In case something goes wrong while renewing, simplecert will rollback to the original cert.

Configuration

You can pass a custom simplecert.Config to suit your needs.

Parameters are explained below.

// Config allows configuration of simplecerttypeConfigstruct {// renew the certificate X hours before it expires// LetsEncrypt Certs are valid for 90 DaysRenewBeforeint// Interval for checking if cert is closer to expiration than RenewBeforeCheckInterval time.Duration// SSLEmail for contactSSLEmailstring// ACME Directory URL.// Can be set to https://acme-staging.api.letsencrypt.org/directory for testingDirectoryURLstring// Endpoints for webroot challenge// CAUTION: challenge must be received on port 80 and 443// if you choose different ports here you must redirect the trafficHTTPAddressstringTLSAddressstring// UNIX Permission for the CacheDir and all files insideCacheDirPerm os.FileMode// Domains for which to obtain the certificateDomains []string// Path of the CacheDirCacheDirstring// DNSProvider name for DNS challenges (optional)// see: https://godoc.org/github.com/go-acme/lego/providers/dnsDNSProviderstring// Local runmodeLocalbool// UpdateHosts adds the domains to /etc/hosts if running in local modeUpdateHostsbool// Handler funcs for graceful service shutdown and restoringWillRenewCertificatefunc()DidRenewCertificatefunc()FailedToRenewCertificatefunc(error)}

Examples

The examples directory contains two simple use cases.

A custom initialization:

go run examples/custom/main.go

And a simple example for local development with a locally trusted certificate (requiresmkcert to be installed):

go run examples/simple/main.go

Debug

Simplecert writes all its logs to thesimplecert.log file inside the configured cache directory.

It will contain information about certificate status and renewal, as well as errors that occured.

Troubleshooting

  • If you get an error that looks like the following during obtaining a certificate, please check your firewall configuration, and ensure the ports for performing the challenge (HTTP: 80, TLS: 443, DNS: 53) are reachable from the outside world.
urn:ietf:params:acme:error:connection :: Timeout during connect (likely firewall problem), url: ...
  • Dependency errors

The LEGO package imports various api clients for providing the DNS challenges - unfortunately this leads to frequent incompatibilities, in code that is not under our control.In case this happens usually googling the error message is sufficient to find the go module replace directive that pins the needed version.Please open an issue if you could not fix a dependency error on your own.

  • Container Pitfalls

Be careful with containers that are configured to automatically restart on errors!When obtaining (or storing) a certificate fails for whatever reason, and your container will crash and restart automatically, you might get blocked due to the letsencrypt APIs rate limits.

Another common pitfall is to forget mounting the cache directory into your container, this way simplecert will obtain a new cert on every deployment, which will also likely cause rate limit issues after a while.

You can read more about the letsencrypt API rate limits here:https://letsencrypt.org/docs/rate-limits/

License

MIT


[8]ページ先頭

©2009-2025 Movatter.jp