wileedot
(named after ACME's most famous customer, Wile E. Coyote) is a drop-in TLS listener implementation that automatically handles certificate management through Let's Encrypt. It provides seamless TLS support for your Go web services with minimal configuration.
- 🔒 Automatic TLS certificate provisioning via Let's Encrypt
- 🔄 Automatic certificate renewal (every 2 months)
- 🔌 Works with existing
net.Listener
implementations - 🎯 Support for multiple domains
- 💾 Persistent certificate storage
- 🔐 TLS 1.2+ enforcement
- 🧵 Thread-safe operations
go get github.com/opd-ai/wileedot
package main
import (
"log"
"net/http"
"github.com/opd-ai/wileedot"
)
func main() {
// Configure the TLS listener
config := tlslistener.Config{
Domain: "example.com",
CertDir: "/etc/certs",
Email: "admin@example.com",
}
// Create the listener
listener, err := tlslistener.New(config)
if err != nil {
log.Fatal(err)
}
defer listener.Close()
// Use with standard http server
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Hello, TLS!"))
})
log.Fatal(http.Serve(listener, nil))
}
baseListener, err := net.Listen("tcp", ":8443")
if err != nil {
log.Fatal(err)
}
config := tlslistener.Config{
Domain: "example.com",
CertDir: "/etc/certs",
Email: "admin@example.com",
BaseListener: baseListener,
}
listener, err := tlslistener.New(config)
config := tlslistener.Config{
Domain: "example.com",
AllowedDomains: []string{"www.example.com", "api.example.com"},
CertDir: "/etc/certs",
Email: "admin@example.com",
}
info, err := listener.GetCertInfo()
if err != nil {
log.Fatal(err)
}
log.Printf("Certificate valid from %v to %v",
info.NotBefore,
info.NotAfter)
Option | Description | Required | Default |
---|---|---|---|
Domain | Primary domain for the certificate | Yes | - |
AllowedDomains | Additional domains for the certificate | No | [] |
CertDir | Directory to store certificates | Yes | - |
Contact email for Let's Encrypt | Yes | - | |
BaseListener | Existing listener to wrap with TLS | No | :443 |
- Go 1.16 or higher
- Write access to the certificate directory
- Port 80 accessible for ACME challenges(You may wish to use
setcap
in order to bind to port 80 without root) - Port 443 accessible for TLS (if using default listener)
- Certificate Directory: Must be persistent and writable
- ACME Challenges: Port 80 must be accessible for domain validation
- Rate Limits: Let's Encrypt has rate limits
- Production Usage: Consider implementing proper logging and monitoring
The listener includes comprehensive error handling for common scenarios:
- Certificate initialization failures
- Renewal errors
- Network issues
- Invalid configurations
Errors are wrapped using github.com/pkg/errors
for better context.
- Enforces TLS 1.2 minimum
- Automatic certificate renewal
- Secure storage of private keys
- Domain validation
- Thread-safe operations
Contributions are welcome! Please feel free to submit a Pull Request.
- Let's Encrypt for providing free certificates
- golang.org/x/crypto/acme/autocert for ACME implementation
- ACME Corporation for inspiring the name through their valued customer
For issues and feature requests, please use the GitHub issue tracker.
If you find this project useful, consider supporting the developer:
Monero Address: 43H3Uqnc9rfEsJjUXZYmam45MbtWmREFSANAWY5hijY4aht8cqYaT2BCNhfBhua5XwNdx9Tb6BEdt4tjUHJDwNW5H7mTiwe
Bitcoin Address: bc1qew5kx0srtp8c4hlpw8ax0gllhnpsnp9ylthpas