-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(autotls): added autotls extension (#17)
- Loading branch information
Showing
5 changed files
with
238 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
package autotls | ||
|
||
import ( | ||
"crypto/tls" | ||
"net/http" | ||
"time" | ||
|
||
"golang.org/x/crypto/acme/autocert" | ||
) | ||
|
||
// Manager is a wrapper around autocert.Manager that provides automatic | ||
// management of SSL/TLS certificates. It embeds autocert.Manager to | ||
// inherit its methods and functionalities, allowing for seamless | ||
// integration and usage of automatic certificate management in your | ||
// application. | ||
type Manager struct { | ||
*autocert.Manager | ||
} | ||
|
||
// New creates a new AutoSSL instance with the provided options. | ||
// It initializes an autocert.Manager with the AcceptTOS prompt. | ||
// If no cache is provided in the options, it defaults to using a directory cache. | ||
// | ||
// Parameters: | ||
// | ||
// opts - A variadic list of Option functions to configure the autocert.Manager. | ||
// | ||
// Returns: | ||
// | ||
// A pointer to an AutoSSL instance with the configured autocert.Manager. | ||
func New(opts ...Option) *Manager { | ||
cm := &autocert.Manager{ | ||
Prompt: autocert.AcceptTOS, | ||
} | ||
|
||
for _, opt := range opts { | ||
opt(cm) | ||
} | ||
|
||
if cm.Cache == nil { | ||
cm.Cache = autocert.DirCache(".") | ||
} | ||
|
||
return &Manager{ | ||
Manager: cm, | ||
} | ||
} | ||
|
||
// Configure sets up the HTTP and HTTPS servers with the necessary handlers and TLS configurations. | ||
// It modifies the HTTP server to use the AutoSSL manager's HTTP handler and ensures the HTTPS server | ||
// has a TLS configuration with at least TLS 1.2. It also sets the GetCertificate function for the | ||
// HTTPS server's TLS configuration to use the AutoSSL manager's GetCertificate method. | ||
// | ||
// Parameters: | ||
// - httpSrv: A pointer to the HTTP server to be configured. | ||
// - httpsSrv: A pointer to the HTTPS server to be configured. | ||
func (m *Manager) Configure(httpSrv *http.Server, httpsSrv *http.Server) { | ||
if httpSrv != nil && httpsSrv != nil { | ||
httpSrv.Handler = m.Manager.HTTPHandler(httpSrv.Handler) | ||
|
||
if httpSrv.ReadHeaderTimeout == 0 { | ||
httpSrv.ReadHeaderTimeout = 3 * time.Second // prevent Potential slowloris attack | ||
} | ||
|
||
if httpsSrv.ReadHeaderTimeout == 0 { | ||
httpsSrv.ReadHeaderTimeout = 3 * time.Second // prevent Potential slowloris attack | ||
} | ||
|
||
if httpsSrv.TLSConfig == nil { | ||
httpsSrv.TLSConfig = &tls.Config{ | ||
MinVersion: tls.VersionTLS12, | ||
MaxVersion: 0, | ||
} | ||
} | ||
|
||
httpsSrv.TLSConfig.GetCertificate = m.Manager.GetCertificate | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
package autotls | ||
|
||
import ( | ||
"context" | ||
"crypto/tls" | ||
"net/http" | ||
"testing" | ||
"time" | ||
|
||
"github.com/stretchr/testify/require" | ||
"golang.org/x/crypto/acme/autocert" | ||
) | ||
|
||
func TestNew(t *testing.T) { | ||
as := New() | ||
|
||
require.NotNil(t, as) | ||
require.NotNil(t, as.Manager) | ||
require.True(t, as.Prompt("")) | ||
require.NotNil(t, as.Manager.Cache) | ||
} | ||
|
||
func TestConfigure(t *testing.T) { | ||
as := New() | ||
require.NotNil(t, as) | ||
|
||
httpSrv := &http.Server{} // skipcq: GO-S2112 | ||
httpsSrv := &http.Server{} // skipcq: GO-S2112,GSC-G402 | ||
|
||
as.Configure(httpSrv, httpsSrv) | ||
|
||
require.NotNil(t, httpSrv.Handler) | ||
require.NotNil(t, httpsSrv.TLSConfig) | ||
|
||
require.Equal(t, 3*time.Second, httpSrv.ReadHeaderTimeout) | ||
require.Equal(t, 3*time.Second, httpsSrv.ReadHeaderTimeout) | ||
|
||
require.Equal(t, uint16(tls.VersionTLS12), httpsSrv.TLSConfig.MinVersion) | ||
require.Equal(t, uint16(0), httpsSrv.TLSConfig.MaxVersion) | ||
|
||
require.NotNil(t, httpsSrv.TLSConfig.GetCertificate) | ||
|
||
httpSrv = &http.Server{ | ||
ReadHeaderTimeout: 1 * time.Second, | ||
} | ||
httpsSrv = &http.Server{ | ||
ReadHeaderTimeout: 1 * time.Second, | ||
TLSConfig: &tls.Config{ // skipcq: GSC-G402 | ||
MinVersion: tls.VersionTLS10, | ||
MaxVersion: tls.VersionTLS13, | ||
}, | ||
} | ||
|
||
as.Configure(httpSrv, httpsSrv) | ||
require.NotNil(t, httpSrv.Handler) | ||
require.NotNil(t, httpsSrv.TLSConfig) | ||
|
||
require.Equal(t, 1*time.Second, httpSrv.ReadHeaderTimeout) | ||
require.Equal(t, 1*time.Second, httpsSrv.ReadHeaderTimeout) | ||
|
||
require.Equal(t, uint16(tls.VersionTLS10), httpsSrv.TLSConfig.MinVersion) | ||
require.Equal(t, uint16(tls.VersionTLS13), httpsSrv.TLSConfig.MaxVersion) | ||
|
||
require.NotNil(t, httpsSrv.TLSConfig.GetCertificate) | ||
} | ||
|
||
func TestOptions(t *testing.T) { | ||
as := New(WithCache(autocert.DirCache(".")), WithHosts("abc.com")) | ||
|
||
require.NotNil(t, as) | ||
require.IsType(t, autocert.DirCache("."), as.Manager.Cache) | ||
require.Nil(t, as.Manager.HostPolicy(context.TODO(), "abc.com")) | ||
require.NotNil(t, as.Manager.HostPolicy(context.TODO(), "123.com")) | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
package autotls | ||
|
||
import "golang.org/x/crypto/acme/autocert" | ||
|
||
// Option is a function type that takes a pointer to autocert.Manager as an argument. | ||
// It is used to configure the autocert.Manager with various options. | ||
type Option func(*autocert.Manager) | ||
|
||
// WithCache sets the cache for the autocert.Manager. | ||
// It takes an autocert.Cache as an argument and returns an Option | ||
// that configures the autocert.Manager to use the provided cache. | ||
// | ||
// Example usage: | ||
// | ||
// cache := autocert.DirCache("/path/to/cache") | ||
// manager := &autocert.Manager{ | ||
// Prompt: autocert.AcceptTOS, | ||
// Cache: cache, | ||
// } | ||
// option := WithCache(cache) | ||
// option(manager) | ||
// | ||
// Parameters: | ||
// - cache: The autocert.Cache to be used by the autocert.Manager. | ||
func WithCache(cache autocert.Cache) Option { | ||
return func(cm *autocert.Manager) { | ||
cm.Cache = cache | ||
} | ||
} | ||
|
||
// WithHosts returns an Option that sets the HostPolicy of the autocert.Manager | ||
// to whitelist the provided hosts. This ensures that the manager will only | ||
// respond to requests for the specified hosts. | ||
// | ||
// Parameters: | ||
// | ||
// hosts - A variadic string parameter representing the hostnames to be whitelisted. | ||
func WithHosts(hosts ...string) Option { | ||
return func(cm *autocert.Manager) { | ||
cm.HostPolicy = autocert.HostWhitelist(hosts...) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters