From e5ead383e59f884ff825d3c9b05a47336c231fd7 Mon Sep 17 00:00:00 2001 From: gunnaraasen Date: Wed, 22 Jul 2015 16:49:12 -0700 Subject: [PATCH 1/2] Add HTTPS option and logger to admin service --- etc/config.sample.toml | 5 +++- services/admin/config.go | 10 ++++--- services/admin/config_test.go | 6 +++++ services/admin/service.go | 51 ++++++++++++++++++++++++++++++----- 4 files changed, 62 insertions(+), 10 deletions(-) diff --git a/etc/config.sample.toml b/etc/config.sample.toml index 7aa78980f1..f5ee41590e 100644 --- a/etc/config.sample.toml +++ b/etc/config.sample.toml @@ -64,12 +64,15 @@ reporting-disabled = false ### ### [admin] ### -### Controls the availability of the built-in, web-based admin interface. +### Controls the availability of the built-in, web-based admin interface. If HTTPS is +### enabled for the admin interface, HTTPS must also be enabled on the [http] service. ### [admin] enabled = true bind-address = ":8083" + https-enabled = false + https-certificate = "/etc/ssl/influxdb.pem" ### ### [http] diff --git a/services/admin/config.go b/services/admin/config.go index 0f9b6997a2..860dff864a 100644 --- a/services/admin/config.go +++ b/services/admin/config.go @@ -6,12 +6,16 @@ const ( ) type Config struct { - Enabled bool `toml:"enabled"` - BindAddress string `toml:"bind-address"` + Enabled bool `toml:"enabled"` + BindAddress string `toml:"bind-address"` + HttpsEnabled bool `toml:"https-enabled"` + HttpsCertificate string `toml:"https-certificate"` } func NewConfig() Config { return Config{ - BindAddress: DefaultBindAddress, + BindAddress: DefaultBindAddress, + HttpsEnabled: false, + HttpsCertificate: "/etc/ssl/influxdb.pem", } } diff --git a/services/admin/config_test.go b/services/admin/config_test.go index 70f63bebf2..1b0422505c 100644 --- a/services/admin/config_test.go +++ b/services/admin/config_test.go @@ -13,6 +13,8 @@ func TestConfig_Parse(t *testing.T) { if _, err := toml.Decode(` enabled = true bind-address = ":8083" +https-enabled = true +https-certificate = "/dev/null" `, &c); err != nil { t.Fatal(err) } @@ -22,5 +24,9 @@ bind-address = ":8083" t.Fatalf("unexpected enabled: %v", c.Enabled) } else if c.BindAddress != ":8083" { t.Fatalf("unexpected bind address: %s", c.BindAddress) + } else if c.HttpsEnabled != true { + t.Fatalf("unexpected https enabled: %v", c.HttpsEnabled) + } else if c.HttpsCertificate != "/dev/null" { + t.Fatalf("unexpected https certificate: %v", c.HttpsCertificate) } } diff --git a/services/admin/service.go b/services/admin/service.go index 6f83f8634f..7fb897b42a 100644 --- a/services/admin/service.go +++ b/services/admin/service.go @@ -1,9 +1,12 @@ package admin import ( + "crypto/tls" "fmt" + "log" "net" "net/http" + "os" "strings" // Register static assets via statik. @@ -15,25 +18,56 @@ import ( type Service struct { listener net.Listener addr string + https bool + cert string err chan error + + logger *log.Logger } // NewService returns a new instance of Service. func NewService(c Config) *Service { return &Service{ - addr: c.BindAddress, - err: make(chan error), + addr: c.BindAddress, + https: c.HttpsEnabled, + cert: c.HttpsCertificate, + err: make(chan error), + logger: log.New(os.Stderr, "[admin] ", log.LstdFlags), } } // Open starts the service func (s *Service) Open() error { // Open listener. - listener, err := net.Listen("tcp", s.addr) - if err != nil { - return err + if s.https { + cert, err := tls.LoadX509KeyPair(s.cert, s.cert) + if err != nil { + s.logger.Printf("Failed to load HTTPS certificate '%s': %s", s.cert, err) + s.logger.Println("Reverting to HTTP") + } + + listener, err := tls.Listen("tcp", s.addr, &tls.Config{ + Certificates: []tls.Certificate{cert}, + }) + if err != nil { + s.logger.Printf("Failed to bind HTTPS on %s: %s", s.addr, err) + s.logger.Println("Reverting to HTTP") + } + + s.logger.Println("listening on HTTPS:", listener.Addr().String()) + s.listener = listener + } + + // Assume that the HTTPS configuration failed + if s.listener == nil { + listener, err := net.Listen("tcp", s.addr) + if err != nil { + return err + } + + s.logger.Println("listening on HTTP:", listener.Addr().String()) + s.listener = listener } - s.listener = listener // Begin listening for requests in a separate goroutine. go s.serve() @@ -48,6 +82,11 @@ func (s *Service) Close() error { return nil } +// SetLogger sets the internal logger to the logger passed in. +func (s *Service) SetLogger(l *log.Logger) { + s.logger = l +} + // Err returns a channel for fatal errors that occur on the listener. func (s *Service) Err() <-chan error { return s.err } From 8ab9424295bf954a93ff982d91d864f8f4aff036 Mon Sep 17 00:00:00 2001 From: gunnaraasen Date: Thu, 23 Jul 2015 15:00:33 -0700 Subject: [PATCH 2/2] Return error if HTTPS fails --- services/admin/service.go | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/services/admin/service.go b/services/admin/service.go index 7fb897b42a..0964d55bbb 100644 --- a/services/admin/service.go +++ b/services/admin/service.go @@ -42,24 +42,19 @@ func (s *Service) Open() error { if s.https { cert, err := tls.LoadX509KeyPair(s.cert, s.cert) if err != nil { - s.logger.Printf("Failed to load HTTPS certificate '%s': %s", s.cert, err) - s.logger.Println("Reverting to HTTP") + return err } listener, err := tls.Listen("tcp", s.addr, &tls.Config{ Certificates: []tls.Certificate{cert}, }) if err != nil { - s.logger.Printf("Failed to bind HTTPS on %s: %s", s.addr, err) - s.logger.Println("Reverting to HTTP") + return err } s.logger.Println("listening on HTTPS:", listener.Addr().String()) s.listener = listener - } - - // Assume that the HTTPS configuration failed - if s.listener == nil { + } else { listener, err := net.Listen("tcp", s.addr) if err != nil { return err