LetsEncrypt in Go
The essence of the problem is that LetsEncrypt certificates are valid for 3 months, and are updated every month. It’s easy enough to automate the renewal of certonly certificates via cron, but there’s no easy way for Go to automatically pick up new updated certificates.
The cycle is optional. It is needed if you want the server not to crash when there is an error in the new certificate, the https service will go out when the certificate disappears, and will come to life if a normal certificate appears.
There is no easy way in net / http package to stop http or https server. Therefore, I was inspired by this post . I copied the code ListenAndServeTLS and some more code from net / http, and got a working pyrahttp.ListenAndServeLetsEncrypt .
http.Server gets my net.Listener implementation. It in Accept () calls TCPListener.Accept () with Deadline in one minute. In the case of a deadline or a new connection, listner checks the certificate file, and if it is updated, it returns a ReloadError, which leads to a server reboot in ListenAndServeLetsEncrypt .
I hope now more happy servers on Go will be able to survive to their two or three years without a restart.
If you have several domains, subdomains, servers (virtual), and you are considering how to start using LetsEncrypt, then I chose the solution when I have one server with the LetsEncrypt code, and for all the rest I have to /.well-known/acme-challenge proxied to LetsEncrypt server. This allows you to get one certificate on several servers, which I can later combine into one server or put it behind a common proxy.
More precisely, there is now
// log.Println(http.ListenAndServeTLS(":7544",
// "/home/user/cert/game01.example.com/fullchain.pem",
// "/home/user/cert/game01.example.com/privkey.pem", nil))
for {
log.Println(pyrahttp.ListenAndServeLetsEncrypt(":7544",
"/home/user/cert/game01.example.com/fullchain.pem",
"/home/user/cert/game01.example.com/privkey.pem", nil))
time.Sleep(time.Second * 5)
}
The cycle is optional. It is needed if you want the server not to crash when there is an error in the new certificate, the https service will go out when the certificate disappears, and will come to life if a normal certificate appears.
How it works
There is no easy way in net / http package to stop http or https server. Therefore, I was inspired by this post . I copied the code ListenAndServeTLS and some more code from net / http, and got a working pyrahttp.ListenAndServeLetsEncrypt .
http.Server gets my net.Listener implementation. It in Accept () calls TCPListener.Accept () with Deadline in one minute. In the case of a deadline or a new connection, listner checks the certificate file, and if it is updated, it returns a ReloadError, which leads to a server reboot in ListenAndServeLetsEncrypt .
I hope now more happy servers on Go will be able to survive to their two or three years without a restart.
Installation / Upgrade
go get -u github.com/CossackPyra/pyrahttp
PS
If you have several domains, subdomains, servers (virtual), and you are considering how to start using LetsEncrypt, then I chose the solution when I have one server with the LetsEncrypt code, and for all the rest I have to /.well-known/acme-challenge proxied to LetsEncrypt server. This allows you to get one certificate on several servers, which I can later combine into one server or put it behind a common proxy.