Support automatically generating SSL certificates

This commit is contained in:
Dane Everitt
2020-06-30 21:34:47 -07:00
parent ea2630946a
commit e5b844d2c4
3 changed files with 45 additions and 8 deletions

View File

@@ -6,6 +6,7 @@ import (
"github.com/apex/log"
"github.com/mitchellh/colorstring"
"github.com/pterodactyl/wings/loggers/cli"
"golang.org/x/crypto/acme/autocert"
"net/http"
"os"
"path"
@@ -27,11 +28,19 @@ import (
var configPath = config.DefaultLocation
var debug = false
var shouldRunProfiler = false
var useAutomaticTls = false
var tlsHostname = ""
var root = &cobra.Command{
Use: "wings",
Short: "The wings of the pterodactyl game management panel",
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,
}
@@ -39,6 +48,8 @@ func init() {
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(&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)
}
@@ -218,17 +229,38 @@ func rootCmdRun(*cobra.Command, []string) {
}
log.WithFields(log.Fields{
"ssl": c.Api.Ssl.Enabled,
"host": c.Api.Host,
"port": c.Api.Port,
}).Info("configuring webserver...")
"use_ssl": c.Api.Ssl.Enabled,
"use_auto_tls": useAutomaticTls && len(tlsHostname) > 0,
"host_address": c.Api.Host,
"host_port": c.Api.Port,
}).Info("configuring internal webserver")
r := router.Configure()
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 {
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)
}
} else {