Documentation
¶
Overview ¶
Package letsencrypt provides a module for automatic SSL certificate generation via Let's Encrypt for the modular framework.
Package letsencrypt provides a module for automatic SSL certificate generation via Let's Encrypt for the modular framework.
This module integrates Let's Encrypt ACME protocol support into the modular framework, enabling automatic SSL/TLS certificate provisioning, renewal, and management. It supports multiple challenge types and DNS providers for flexible certificate acquisition.
Features ¶
The letsencrypt module provides the following capabilities:
- Automatic SSL certificate acquisition from Let's Encrypt
- Support for HTTP-01 and DNS-01 challenge types
- Multiple DNS provider integrations (Cloudflare, Route53, DigitalOcean, etc.)
- Automatic certificate renewal before expiration
- Certificate storage and management
- Staging and production environment support
- Service interface for integration with HTTP servers
Challenge Types ¶
The module supports two ACME challenge types:
- HTTP-01: Domain validation via HTTP endpoints
- DNS-01: Domain validation via DNS TXT records
Supported DNS Providers ¶
When using DNS-01 challenges, the following providers are supported:
- Cloudflare
- AWS Route53
- DigitalOcean
- Google Cloud DNS
- Azure DNS
- Namecheap
Configuration ¶
The module can be configured through the LetsEncryptConfig structure:
config := &LetsEncryptConfig{ Email: "admin@example.com", Domains: []string{"example.com", "www.example.com"}, ChallengeType: "http-01", // or "dns-01" DNSProvider: "cloudflare", // for DNS challenges CADirectory: CAProduction, // or CAStaging for testing CertificatePath: "/etc/ssl/certs", // certificate storage path KeyPath: "/etc/ssl/private", // private key storage path DNSProviderConfig: &CloudflareConfig{ APIToken: "your-cloudflare-token", }, }
Service Registration ¶
The module registers itself as a certificate service:
// Get the certificate service certService := app.GetService("letsencrypt.certificates").(letsencrypt.CertificateService) // Get a certificate for a domain cert, err := certService.GetCertificate("example.com") // Configure TLS with automatic certificates tlsConfig := &tls.Config{ GetCertificate: certService.GetCertificate, }
Usage Examples ¶
Basic HTTP server with automatic HTTPS:
// Configure Let's Encrypt module config := &LetsEncryptConfig{ Email: "admin@example.com", Domains: []string{"example.com"}, ChallengeType: "http-01", CADirectory: CAProduction, } // Get certificate service certService := app.GetService("letsencrypt.certificates").(CertificateService) // Create TLS config with automatic certificates tlsConfig := &tls.Config{ GetCertificate: certService.GetCertificate, } // Start HTTPS server server := &http.Server{ Addr: ":443", TLSConfig: tlsConfig, Handler: httpHandler, } server.ListenAndServeTLS("", "")
DNS challenge with Cloudflare:
config := &LetsEncryptConfig{ Email: "admin@example.com", Domains: []string{"example.com", "*.example.com"}, ChallengeType: "dns-01", DNSProvider: "cloudflare", DNSProviderConfig: &CloudflareConfig{ APIToken: os.Getenv("CLOUDFLARE_API_TOKEN"), }, }
Certificate Management ¶
The module automatically handles:
- Certificate acquisition on first request
- Certificate renewal (default: 30 days before expiration)
- Certificate storage and loading
- OCSP stapling support
- Certificate chain validation
Security Considerations ¶
- Use staging environment for testing to avoid rate limits - Store API credentials securely (environment variables, secrets) - Ensure proper file permissions for certificate storage - Monitor certificate expiration and renewal logs - Use strong private keys (RSA 2048+ or ECDSA P-256+)
Package letsencrypt provides a module for automatic SSL certificate generation via Let's Encrypt for the modular framework.
Index ¶
- Constants
- Variables
- type CertificateService
- type ChallengeHandler
- type CloudflareConfig
- type DNSProviderConfig
- type DigitalOceanConfig
- type HTTPProviderConfig
- type LetsEncryptConfig
- type LetsEncryptModule
- func (m *LetsEncryptModule) Config() interface{}
- func (m *LetsEncryptModule) Domains() []string
- func (m *LetsEncryptModule) GetCertificate(clientHello *tls.ClientHelloInfo) (*tls.Certificate, error)
- func (m *LetsEncryptModule) GetCertificateForDomain(domain string) (*tls.Certificate, error)
- func (m *LetsEncryptModule) Name() string
- func (m *LetsEncryptModule) RevokeCertificate(domain string) error
- func (m *LetsEncryptModule) Start(ctx context.Context) error
- func (m *LetsEncryptModule) Stop(ctx context.Context) error
- type Route53Config
- type User
Constants ¶
const ( // CAStaging is the URL for Let's Encrypt's staging environment. // Use this for testing to avoid hitting production rate limits. // Certificates from staging are not trusted by browsers. CAStaging = "https://acme-staging-v02.api.letsencrypt.org/directory" // CAProduction is the URL for Let's Encrypt's production environment. // Use this for production deployments. Has strict rate limits. // Certificates from production are trusted by all major browsers. CAProduction = "https://acme-v02.api.letsencrypt.org/directory" )
Constants for Let's Encrypt URLs
const ModuleName = "letsencrypt"
ModuleName is the unique identifier for the letsencrypt module.
Variables ¶
var ( // Configuration errors ErrEmailRequired = errors.New("email address is required for Let's Encrypt registration") ErrDomainsRequired = errors.New("at least one domain is required") ErrConflictingProviders = errors.New("cannot specify both HTTP and DNS challenge providers") ErrServerNameEmpty = errors.New("server name is empty") ErrNoCertificateFound = errors.New("no certificate found for domain") ErrCloudflareConfigMissing = errors.New("cloudflare provider configuration is missing") ErrRoute53ConfigMissing = errors.New("route53 provider configuration is missing") ErrDigitalOceanConfigMissing = errors.New("digitalocean provider configuration is missing") ErrDigitalOceanTokenRequired = errors.New("digitalocean auth token is required") ErrDNSConfigMissing = errors.New("DNS provider configuration is missing or invalid") ErrUnsupportedDNSProvider = errors.New("unsupported DNS provider") ErrGoogleCloudProjectRequired = errors.New("google Cloud DNS project ID is required") ErrAzureDNSConfigIncomplete = errors.New("azure DNS provider requires client_id, client_secret, subscription_id, tenant_id, and resource_group") ErrNamecheapConfigIncomplete = errors.New("namecheap DNS provider requires api_user, api_key, and username") ErrHTTPChallengeNotConfigured = errors.New("HTTP challenge handler not configured") // Certificate errors ErrCertificateFileNotFound = errors.New("certificate file not found") ErrKeyFileNotFound = errors.New("key file not found") ErrPEMDecodeFailure = errors.New("failed to decode PEM block containing certificate") )
Static error definitions for the letsencrypt module
Functions ¶
This section is empty.
Types ¶
type CertificateService ¶
type CertificateService interface { // GetCertificate returns a certificate for the given ClientHello GetCertificate(*tls.ClientHelloInfo) (*tls.Certificate, error) // GetCertificateForDomain returns a certificate for the specified domain GetCertificateForDomain(domain string) (*tls.Certificate, error) // Domains returns a list of domains this service can provide certificates for Domains() []string }
CertificateService defines the interface for a service that can provide TLS certificates
type ChallengeHandler ¶
type ChallengeHandler interface { // PresentChallenge is called when a challenge token needs to be made available PresentChallenge(domain, token, keyAuth string) error // CleanupChallenge is called when a challenge token needs to be removed CleanupChallenge(domain, token, keyAuth string) error }
ChallengeHandler defines the interface for handlers that can handle ACME challenges
type CloudflareConfig ¶
type CloudflareConfig struct { Email string `yaml:"email" json:"email" env:"EMAIL"` APIKey string `yaml:"api_key" json:"api_key" env:"API_KEY"` APIToken string `yaml:"api_token" json:"api_token" env:"API_TOKEN"` }
CloudflareConfig holds the configuration for Cloudflare DNS API
type DNSProviderConfig ¶
type DNSProviderConfig struct { // Provider is the name of the DNS provider (e.g., "cloudflare", "route53", etc.) Provider string `yaml:"provider" json:"provider" env:"PROVIDER"` // Parameters is a map of provider-specific configuration parameters Parameters map[string]string `yaml:"parameters" json:"parameters" env:"PARAMETERS"` // Provider-specific configurations Cloudflare *CloudflareConfig `yaml:"cloudflare,omitempty" json:"cloudflare,omitempty"` Route53 *Route53Config `yaml:"route53,omitempty" json:"route53,omitempty"` DigitalOcean *DigitalOceanConfig `yaml:"digitalocean,omitempty" json:"digitalocean,omitempty"` }
DNSProviderConfig defines the configuration for DNS challenge providers
type DigitalOceanConfig ¶
type DigitalOceanConfig struct {
AuthToken string `yaml:"auth_token" json:"auth_token" env:"AUTH_TOKEN"`
}
DigitalOceanConfig holds the configuration for DigitalOcean DNS API
type HTTPProviderConfig ¶
type HTTPProviderConfig struct { // Use the built-in HTTP server for challenges UseBuiltIn bool `yaml:"use_built_in" json:"use_built_in" env:"USE_BUILT_IN"` // Port to use for the HTTP challenge server (default: 80) Port int `yaml:"port" json:"port" env:"PORT"` }
HTTPProviderConfig defines the configuration for HTTP challenge providers
type LetsEncryptConfig ¶
type LetsEncryptConfig struct { // Email is the email address to use for registration with Let's Encrypt Email string `yaml:"email" json:"email" env:"EMAIL"` // Domains is a list of domain names to obtain certificates for Domains []string `yaml:"domains" json:"domains" env:"DOMAINS"` // UseStaging determines whether to use Let's Encrypt's staging environment // Set to true for testing to avoid rate limits UseStaging bool `yaml:"use_staging" json:"use_staging" env:"USE_STAGING"` // UseProduction is the opposite of UseStaging, for clarity in configuration UseProduction bool `yaml:"use_production" json:"use_production" env:"USE_PRODUCTION"` // StoragePath is the directory where certificates and account information will be stored StoragePath string `yaml:"storage_path" json:"storage_path" env:"STORAGE_PATH"` // RenewBefore sets how long before expiry certificates should be renewed (in days) RenewBefore int `yaml:"renew_before" json:"renew_before" env:"RENEW_BEFORE"` // RenewBeforeDays is an alias for RenewBefore for backward compatibility RenewBeforeDays int `yaml:"renew_before_days" json:"renew_before_days" env:"RENEW_BEFORE_DAYS"` // AutoRenew enables automatic certificate renewal AutoRenew bool `yaml:"auto_renew" json:"auto_renew" env:"AUTO_RENEW"` // UseDNS indicates whether to use DNS challenges instead of HTTP UseDNS bool `yaml:"use_dns" json:"use_dns" env:"USE_DNS"` // DNSProvider configuration for DNS challenges DNSProvider *DNSProviderConfig `yaml:"dns_provider,omitempty" json:"dns_provider,omitempty"` // DNSConfig is a map of DNS provider specific configuration parameters DNSConfig map[string]string `yaml:"dns_config,omitempty" json:"dns_config,omitempty" env:"DNS_CONFIG"` // HTTPProvider configuration for HTTP challenges HTTPProvider *HTTPProviderConfig `yaml:"http_provider,omitempty" json:"http_provider,omitempty"` // HTTPChallengeHandler is an HTTP handler for HTTP-01 challenges HTTPChallengeHandler http.Handler `yaml:"-" json:"-"` // CustomCACertificate is a custom CA certificate to be trusted CustomCACertificate []byte `yaml:"-" json:"-"` }
LetsEncryptConfig defines the configuration for the Let's Encrypt module.
func (*LetsEncryptConfig) Validate ¶
func (c *LetsEncryptConfig) Validate() error
Validate checks if the configuration is valid and sets default values where appropriate.
type LetsEncryptModule ¶
type LetsEncryptModule struct {
// contains filtered or unexported fields
}
LetsEncryptModule provides automatic SSL certificate management using Let's Encrypt. It handles certificate acquisition, renewal, and storage with support for multiple challenge types and DNS providers.
The module implements the following interfaces:
- modular.Module: Basic module lifecycle
- modular.Configurable: Configuration management
- modular.ServiceAware: Service dependency management
- modular.Startable: Startup logic
- modular.Stoppable: Shutdown logic
- CertificateService: Certificate management interface
Certificate operations are thread-safe and support concurrent requests.
func New ¶
func New(config *LetsEncryptConfig) (*LetsEncryptModule, error)
New creates a new Let's Encrypt module
func (*LetsEncryptModule) Config ¶
func (m *LetsEncryptModule) Config() interface{}
Config returns the module's configuration
func (*LetsEncryptModule) Domains ¶
func (m *LetsEncryptModule) Domains() []string
Domains returns the list of domains this service can provide certificates for
func (*LetsEncryptModule) GetCertificate ¶
func (m *LetsEncryptModule) GetCertificate(clientHello *tls.ClientHelloInfo) (*tls.Certificate, error)
GetCertificate implements the CertificateService.GetCertificate method to be used with tls.Config.GetCertificate
func (*LetsEncryptModule) GetCertificateForDomain ¶
func (m *LetsEncryptModule) GetCertificateForDomain(domain string) (*tls.Certificate, error)
GetCertificateForDomain returns a certificate for the specified domain
func (*LetsEncryptModule) Name ¶
func (m *LetsEncryptModule) Name() string
Name returns the name of the module
func (*LetsEncryptModule) RevokeCertificate ¶
func (m *LetsEncryptModule) RevokeCertificate(domain string) error
RevokeCertificate revokes a certificate for the specified domain
type Route53Config ¶
type Route53Config struct { AccessKeyID string `yaml:"access_key_id" json:"access_key_id" env:"ACCESS_KEY_ID"` SecretAccessKey string `yaml:"secret_access_key" json:"secret_access_key" env:"SECRET_ACCESS_KEY"` Region string `yaml:"region" json:"region" env:"REGION"` HostedZoneID string `yaml:"hosted_zone_id" json:"hosted_zone_id" env:"HOSTED_ZONE_ID"` }
Route53Config holds the configuration for AWS Route53 DNS API
type User ¶
type User struct { Email string Registration *registration.Resource Key crypto.PrivateKey // Changed from certcrypto.PrivateKey to crypto.PrivateKey }
User implements the ACME User interface for Let's Encrypt
func (*User) GetPrivateKey ¶
func (u *User) GetPrivateKey() crypto.PrivateKey
GetPrivateKey returns the private key for the user
func (*User) GetRegistration ¶
func (u *User) GetRegistration() *registration.Resource
GetRegistration returns the registration resource