Support automatically generating SSL certificates

This commit is contained in:
Dane Everitt 2020-06-30 21:34:47 -07:00
parent ea2630946a
commit e5b844d2c4
No known key found for this signature in database
GPG Key ID: EEA66103B3D71F53
3 changed files with 45 additions and 8 deletions

View File

@ -6,6 +6,7 @@ import (
"github.com/apex/log" "github.com/apex/log"
"github.com/mitchellh/colorstring" "github.com/mitchellh/colorstring"
"github.com/pterodactyl/wings/loggers/cli" "github.com/pterodactyl/wings/loggers/cli"
"golang.org/x/crypto/acme/autocert"
"net/http" "net/http"
"os" "os"
"path" "path"
@ -27,11 +28,19 @@ import (
var configPath = config.DefaultLocation var configPath = config.DefaultLocation
var debug = false var debug = false
var shouldRunProfiler = false var shouldRunProfiler = false
var useAutomaticTls = false
var tlsHostname = ""
var root = &cobra.Command{ var root = &cobra.Command{
Use: "wings", Use: "wings",
Short: "The wings of the pterodactyl game management panel", Short: "The wings of the pterodactyl game management panel",
Long: ``, Long: ``,
PreRun: func(cmd *cobra.Command, args []string) {
if useAutomaticTls && len(tlsHostname) == 0 {
fmt.Println("A TLS hostname must be provided when running wings with automatic TLS, e.g.:\n\n ./wings --auto-tls --tls-hostname my.example.com")
os.Exit(1)
}
},
Run: rootCmdRun, Run: rootCmdRun,
} }
@ -39,6 +48,8 @@ func init() {
root.PersistentFlags().StringVar(&configPath, "config", config.DefaultLocation, "set the location for the configuration file") root.PersistentFlags().StringVar(&configPath, "config", config.DefaultLocation, "set the location for the configuration file")
root.PersistentFlags().BoolVar(&debug, "debug", false, "pass in order to run wings in debug mode") root.PersistentFlags().BoolVar(&debug, "debug", false, "pass in order to run wings in debug mode")
root.PersistentFlags().BoolVar(&shouldRunProfiler, "profile", false, "pass in order to profile wings") root.PersistentFlags().BoolVar(&shouldRunProfiler, "profile", false, "pass in order to profile wings")
root.PersistentFlags().BoolVar(&useAutomaticTls, "auto-tls", false, "pass in order to have wings generate and manage it's own SSL certificates using Let's Encrypt")
root.PersistentFlags().StringVar(&tlsHostname, "tls-hostname", "", "required with --auto-tls, the FQDN for the generated SSL certificate")
root.AddCommand(configureCmd) root.AddCommand(configureCmd)
} }
@ -218,17 +229,38 @@ func rootCmdRun(*cobra.Command, []string) {
} }
log.WithFields(log.Fields{ log.WithFields(log.Fields{
"ssl": c.Api.Ssl.Enabled, "use_ssl": c.Api.Ssl.Enabled,
"host": c.Api.Host, "use_auto_tls": useAutomaticTls && len(tlsHostname) > 0,
"port": c.Api.Port, "host_address": c.Api.Host,
}).Info("configuring webserver...") "host_port": c.Api.Port,
}).Info("configuring internal webserver")
r := router.Configure() r := router.Configure()
addr := fmt.Sprintf("%s:%d", c.Api.Host, c.Api.Port) addr := fmt.Sprintf("%s:%d", c.Api.Host, c.Api.Port)
if c.Api.Ssl.Enabled { if useAutomaticTls && len(tlsHostname) > 0 {
m := autocert.Manager{
Prompt: autocert.AcceptTOS,
Cache: autocert.DirCache(path.Join(c.System.RootDirectory, "/.tls-cache")),
HostPolicy: autocert.HostWhitelist(tlsHostname),
}
log.WithField("hostname", tlsHostname).
Info("webserver is now listening with auto-TLS enabled; certifcates will be automatically generated by Let's Encrypt")
// We don't use the autotls runner here since we need to specify a port other than 443
// to be using for SSL connections for Wings.
s := &http.Server{Addr: addr, TLSConfig: m.TLSConfig(), Handler: r}
go http.ListenAndServe(":http", m.HTTPHandler(nil))
if err := s.ListenAndServeTLS("", ""); err != nil {
log.WithFields(log.Fields{"auto_tls": true, "tls_hostname": tlsHostname, "error": err}).
Fatal("failed to configure HTTP server using auto-tls")
os.Exit(1)
}
} else if c.Api.Ssl.Enabled {
if err := r.RunTLS(addr, c.Api.Ssl.CertificateFile, c.Api.Ssl.KeyFile); err != nil { if err := r.RunTLS(addr, c.Api.Ssl.CertificateFile, c.Api.Ssl.KeyFile); err != nil {
log.WithField("error", err).Fatal("failed to configure HTTPS server") log.WithFields(log.Fields{"auto_tls": false, "error": err}).Fatal("failed to configure HTTPS server")
os.Exit(1) os.Exit(1)
} }
} else { } else {

5
go.mod
View File

@ -32,7 +32,8 @@ require (
github.com/gabriel-vasile/mimetype v0.1.4 github.com/gabriel-vasile/mimetype v0.1.4
github.com/gbrlsnchs/jwt/v3 v3.0.0-rc.0 github.com/gbrlsnchs/jwt/v3 v3.0.0-rc.0
github.com/ghodss/yaml v1.0.0 github.com/ghodss/yaml v1.0.0
github.com/gin-gonic/gin v1.6.2 github.com/gin-gonic/autotls v0.0.0-20200518075542-45033372a9ad
github.com/gin-gonic/gin v1.6.3
github.com/golang/protobuf v1.3.5 // indirect github.com/golang/protobuf v1.3.5 // indirect
github.com/google/uuid v1.1.1 github.com/google/uuid v1.1.1
github.com/gorilla/websocket v1.4.0 github.com/gorilla/websocket v1.4.0
@ -63,7 +64,7 @@ require (
github.com/stretchr/objx v0.2.0 // indirect github.com/stretchr/objx v0.2.0 // indirect
github.com/yuin/goldmark v1.1.30 // indirect github.com/yuin/goldmark v1.1.30 // indirect
go.uber.org/zap v1.15.0 go.uber.org/zap v1.15.0
golang.org/x/crypto v0.0.0-20200429183012-4b2356b1ed79 // indirect golang.org/x/crypto v0.0.0-20200429183012-4b2356b1ed79
golang.org/x/lint v0.0.0-20200302205851-738671d3881b // indirect golang.org/x/lint v0.0.0-20200302205851-738671d3881b // indirect
golang.org/x/net v0.0.0-20200425230154-ff2c4b7c35a0 // indirect golang.org/x/net v0.0.0-20200425230154-ff2c4b7c35a0 // indirect
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a

4
go.sum
View File

@ -81,8 +81,12 @@ github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
github.com/gin-gonic/autotls v0.0.0-20200518075542-45033372a9ad h1:qXUH5CUVcICSzL8DedgF39LCsrVoMFbswxByQVtd5h8=
github.com/gin-gonic/autotls v0.0.0-20200518075542-45033372a9ad/go.mod h1:yLpIL/Gol/Y5/A36WyQNCRIAVuhiuHEtITA6UQ7EghY=
github.com/gin-gonic/gin v1.6.2 h1:88crIK23zO6TqlQBt+f9FrPJNKm9ZEr7qjp9vl/d5TM= github.com/gin-gonic/gin v1.6.2 h1:88crIK23zO6TqlQBt+f9FrPJNKm9ZEr7qjp9vl/d5TM=
github.com/gin-gonic/gin v1.6.2/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= github.com/gin-gonic/gin v1.6.2/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M=
github.com/gin-gonic/gin v1.6.3 h1:ahKqKTFpO5KTPHxWZjEdPScmYaGtLo8Y4DMHoEsnp14=
github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0 h1:MP4Eh7ZCb31lleYCFuwm0oe4/YGak+5l1vA2NOE80nA= github.com/go-logfmt/logfmt v0.4.0 h1:MP4Eh7ZCb31lleYCFuwm0oe4/YGak+5l1vA2NOE80nA=