From e07a53046fbf05c0f749835be2fc0ed3f44462b4 Mon Sep 17 00:00:00 2001 From: Saswat Padhi Date: Mon, 6 Feb 2023 22:20:00 +0000 Subject: [PATCH 1/3] [FEAT] Allow insecure certificates on InfluxDB This change allows users to skip TLS certificate verification on their InfluxDB server, if they wish to do so, for instance when using self- signed certificates. Without this change, scrutiny failed to start and paniced with a `x509: certificate signed by unknown authority` error. --- webapp/backend/pkg/config/config.go | 1 + .../pkg/database/scrutiny_repository.go | 19 +++++++++++++++---- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/webapp/backend/pkg/config/config.go b/webapp/backend/pkg/config/config.go index 3961373..605de86 100644 --- a/webapp/backend/pkg/config/config.go +++ b/webapp/backend/pkg/config/config.go @@ -49,6 +49,7 @@ func (c *configuration) Init() error { c.SetDefault("web.influxdb.init_username", "admin") c.SetDefault("web.influxdb.init_password", "password12345") c.SetDefault("web.influxdb.token", "scrutiny-default-admin-token") + c.SetDefault("web.influxdb.tls.insecure_skip_verify", false) c.SetDefault("web.influxdb.retention_policy", true) //c.SetDefault("disks.include", []string{}) diff --git a/webapp/backend/pkg/database/scrutiny_repository.go b/webapp/backend/pkg/database/scrutiny_repository.go index b163c2c..da95914 100644 --- a/webapp/backend/pkg/database/scrutiny_repository.go +++ b/webapp/backend/pkg/database/scrutiny_repository.go @@ -2,6 +2,7 @@ package database import ( "context" + "crypto/tls" "encoding/json" "fmt" "github.com/analogj/scrutiny/webapp/backend/pkg/config" @@ -95,11 +96,20 @@ func NewScrutinyRepository(appConfig config.Interface, globalLogger logrus.Field influxdbUrl := fmt.Sprintf("%s://%s:%s", appConfig.GetString("web.influxdb.scheme"), appConfig.GetString("web.influxdb.host"), appConfig.GetString("web.influxdb.port")) globalLogger.Debugf("InfluxDB url: %s", influxdbUrl) - client := influxdb2.NewClient(influxdbUrl, appConfig.GetString("web.influxdb.token")) + tlsConfig := &tls.Config{ + InsecureSkipVerify: appConfig.GetBool("web.influxdb.tls.insecure_skip_verify"), + } + globalLogger.Infof("InfluxDB certificate verification: %t\n", !tlsConfig.InsecureSkipVerify) + + client := influxdb2.NewClientWithOptions( + influxdbUrl, + appConfig.GetString("web.influxdb.token"), + influxdb2.DefaultOptions().SetTLSConfig(tlsConfig), + ) //if !appConfig.IsSet("web.influxdb.token") { globalLogger.Debugf("Determine Influxdb setup status...") - influxSetupComplete, err := InfluxSetupComplete(influxdbUrl) + influxSetupComplete, err := InfluxSetupComplete(influxdbUrl, tlsConfig) if err != nil { return nil, fmt.Errorf("failed to check influxdb setup status - %w", err) } @@ -218,7 +228,7 @@ func (sr *scrutinyRepository) HealthCheck(ctx context.Context) error { } -func InfluxSetupComplete(influxEndpoint string) (bool, error) { +func InfluxSetupComplete(influxEndpoint string, tlsConfig *tls.Config) (bool, error) { influxUri, err := url.Parse(influxEndpoint) if err != nil { return false, err @@ -228,7 +238,8 @@ func InfluxSetupComplete(influxEndpoint string) (bool, error) { return false, err } - res, err := http.Get(influxUri.String()) + client := &http.Client{Transport: &http.Transport{TLSClientConfig: tlsConfig}} + res, err := client.Get(influxUri.String()) if err != nil { return false, err } From c69770d1dd1ccdd8f4489607623f8f80ae4b1612 Mon Sep 17 00:00:00 2001 From: Saswat Padhi Date: Mon, 6 Feb 2023 22:34:06 +0000 Subject: [PATCH 2/3] Add `insecure_skip_verify` in example.scrutiny.yaml --- example.scrutiny.yaml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/example.scrutiny.yaml b/example.scrutiny.yaml index c93725e..9d8c80a 100644 --- a/example.scrutiny.yaml +++ b/example.scrutiny.yaml @@ -47,6 +47,11 @@ web: # org: 'my-org' # bucket: 'bucket' retention_policy: true + # if you wish to disable TLS certificate verification, + # when using self-signed certificates for example, + # then uncomment the lines below and set `insecure_skip_verify: true` + # tls: + # insecure_skip_verify: false log: file: '' #absolute or relative paths allowed, eg. web.log From cb5226f6e401e1e7bc3dcb0de098782852a86993 Mon Sep 17 00:00:00 2001 From: Saswat Padhi Date: Tue, 7 Feb 2023 08:24:39 +0000 Subject: [PATCH 3/3] Update backend tests failing on insecure_skip_verify --- webapp/backend/pkg/web/server_test.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/webapp/backend/pkg/web/server_test.go b/webapp/backend/pkg/web/server_test.go index 227d3a2..ac775a0 100644 --- a/webapp/backend/pkg/web/server_test.go +++ b/webapp/backend/pkg/web/server_test.go @@ -103,6 +103,7 @@ func (suite *ServerTestSuite) TestHealthRoute() { fakeConfig.EXPECT().GetString("web.influxdb.token").Return("my-super-secret-auth-token").AnyTimes() fakeConfig.EXPECT().GetString("web.influxdb.org").Return("scrutiny").AnyTimes() fakeConfig.EXPECT().GetString("web.influxdb.bucket").Return("metrics").AnyTimes() + fakeConfig.EXPECT().GetBool("web.influxdb.tls.insecure_skip_verify").Return(false).AnyTimes() fakeConfig.EXPECT().GetBool("web.influxdb.retention_policy").Return(false).AnyTimes() if _, isGithubActions := os.LookupEnv("GITHUB_ACTIONS"); isGithubActions { // when running test suite in github actions, we run an influxdb service as a sidecar. @@ -145,6 +146,7 @@ func (suite *ServerTestSuite) TestRegisterDevicesRoute() { fakeConfig.EXPECT().GetString("web.influxdb.token").Return("my-super-secret-auth-token").AnyTimes() fakeConfig.EXPECT().GetString("web.influxdb.org").Return("scrutiny").AnyTimes() fakeConfig.EXPECT().GetString("web.influxdb.bucket").Return("metrics").AnyTimes() + fakeConfig.EXPECT().GetBool("web.influxdb.tls.insecure_skip_verify").Return(false).AnyTimes() fakeConfig.EXPECT().GetBool("web.influxdb.retention_policy").Return(false).AnyTimes() if _, isGithubActions := os.LookupEnv("GITHUB_ACTIONS"); isGithubActions { // when running test suite in github actions, we run an influxdb service as a sidecar. @@ -187,6 +189,7 @@ func (suite *ServerTestSuite) TestUploadDeviceMetricsRoute() { fakeConfig.EXPECT().GetString("web.influxdb.token").Return("my-super-secret-auth-token").AnyTimes() fakeConfig.EXPECT().GetString("web.influxdb.org").Return("scrutiny").AnyTimes() fakeConfig.EXPECT().GetString("web.influxdb.bucket").Return("metrics").AnyTimes() + fakeConfig.EXPECT().GetBool("web.influxdb.tls.insecure_skip_verify").Return(false).AnyTimes() fakeConfig.EXPECT().GetBool("web.influxdb.retention_policy").Return(false).AnyTimes() if _, isGithubActions := os.LookupEnv("GITHUB_ACTIONS"); isGithubActions { // when running test suite in github actions, we run an influxdb service as a sidecar. @@ -244,6 +247,7 @@ func (suite *ServerTestSuite) TestPopulateMultiple() { fakeConfig.EXPECT().GetString("web.influxdb.token").Return("my-super-secret-auth-token").AnyTimes() fakeConfig.EXPECT().GetString("web.influxdb.org").Return("scrutiny").AnyTimes() fakeConfig.EXPECT().GetString("web.influxdb.bucket").Return("metrics").AnyTimes() + fakeConfig.EXPECT().GetBool("web.influxdb.tls.insecure_skip_verify").Return(false).AnyTimes() fakeConfig.EXPECT().GetBool("web.influxdb.retention_policy").Return(false).AnyTimes() if _, isGithubActions := os.LookupEnv("GITHUB_ACTIONS"); isGithubActions { // when running test suite in github actions, we run an influxdb service as a sidecar. @@ -342,6 +346,7 @@ func (suite *ServerTestSuite) TestSendTestNotificationRoute_WebhookFailure() { fakeConfig.EXPECT().GetString("web.influxdb.token").Return("my-super-secret-auth-token").AnyTimes() fakeConfig.EXPECT().GetString("web.influxdb.org").Return("scrutiny").AnyTimes() fakeConfig.EXPECT().GetString("web.influxdb.bucket").Return("metrics").AnyTimes() + fakeConfig.EXPECT().GetBool("web.influxdb.tls.insecure_skip_verify").Return(false).AnyTimes() fakeConfig.EXPECT().GetBool("web.influxdb.retention_policy").Return(false).AnyTimes() fakeConfig.EXPECT().GetStringSlice("notify.urls").AnyTimes().Return([]string{"https://unroutable.domain.example.asdfghj"}) fakeConfig.EXPECT().GetInt(fmt.Sprintf("%s.metrics.notify_level", config.DB_USER_SETTINGS_SUBKEY)).AnyTimes().Return(int(pkg.MetricsNotifyLevelFail)) @@ -387,6 +392,7 @@ func (suite *ServerTestSuite) TestSendTestNotificationRoute_ScriptFailure() { fakeConfig.EXPECT().GetString("web.influxdb.token").Return("my-super-secret-auth-token").AnyTimes() fakeConfig.EXPECT().GetString("web.influxdb.org").Return("scrutiny").AnyTimes() fakeConfig.EXPECT().GetString("web.influxdb.bucket").Return("metrics").AnyTimes() + fakeConfig.EXPECT().GetBool("web.influxdb.tls.insecure_skip_verify").Return(false).AnyTimes() fakeConfig.EXPECT().GetBool("web.influxdb.retention_policy").Return(false).AnyTimes() fakeConfig.EXPECT().GetStringSlice("notify.urls").AnyTimes().Return([]string{"script:///missing/path/on/disk"}) fakeConfig.EXPECT().GetInt(fmt.Sprintf("%s.metrics.notify_level", config.DB_USER_SETTINGS_SUBKEY)).AnyTimes().Return(int(pkg.MetricsNotifyLevelFail)) @@ -432,6 +438,7 @@ func (suite *ServerTestSuite) TestSendTestNotificationRoute_ScriptSuccess() { fakeConfig.EXPECT().GetString("web.influxdb.token").Return("my-super-secret-auth-token").AnyTimes() fakeConfig.EXPECT().GetString("web.influxdb.org").Return("scrutiny").AnyTimes() fakeConfig.EXPECT().GetString("web.influxdb.bucket").Return("metrics").AnyTimes() + fakeConfig.EXPECT().GetBool("web.influxdb.tls.insecure_skip_verify").Return(false).AnyTimes() fakeConfig.EXPECT().GetBool("web.influxdb.retention_policy").Return(false).AnyTimes() fakeConfig.EXPECT().GetStringSlice("notify.urls").AnyTimes().Return([]string{"script:///usr/bin/env"}) fakeConfig.EXPECT().GetInt(fmt.Sprintf("%s.metrics.notify_level", config.DB_USER_SETTINGS_SUBKEY)).AnyTimes().Return(int(pkg.MetricsNotifyLevelFail)) @@ -477,6 +484,7 @@ func (suite *ServerTestSuite) TestSendTestNotificationRoute_ShoutrrrFailure() { fakeConfig.EXPECT().GetString("web.influxdb.token").Return("my-super-secret-auth-token").AnyTimes() fakeConfig.EXPECT().GetString("web.influxdb.org").Return("scrutiny").AnyTimes() fakeConfig.EXPECT().GetString("web.influxdb.bucket").Return("metrics").AnyTimes() + fakeConfig.EXPECT().GetBool("web.influxdb.tls.insecure_skip_verify").Return(false).AnyTimes() fakeConfig.EXPECT().GetBool("web.influxdb.retention_policy").Return(false).AnyTimes() fakeConfig.EXPECT().GetStringSlice("notify.urls").AnyTimes().Return([]string{"discord://invalidtoken@channel"}) fakeConfig.EXPECT().GetInt(fmt.Sprintf("%s.metrics.notify_level", config.DB_USER_SETTINGS_SUBKEY)).AnyTimes().Return(int(pkg.MetricsNotifyLevelFail)) @@ -521,6 +529,7 @@ func (suite *ServerTestSuite) TestGetDevicesSummaryRoute_Nvme() { fakeConfig.EXPECT().GetString("web.influxdb.token").Return("my-super-secret-auth-token").AnyTimes() fakeConfig.EXPECT().GetString("web.influxdb.org").Return("scrutiny").AnyTimes() fakeConfig.EXPECT().GetString("web.influxdb.bucket").Return("metrics").AnyTimes() + fakeConfig.EXPECT().GetBool("web.influxdb.tls.insecure_skip_verify").Return(false).AnyTimes() fakeConfig.EXPECT().GetBool("web.influxdb.retention_policy").Return(false).AnyTimes() fakeConfig.EXPECT().GetStringSlice("notify.urls").AnyTimes().Return([]string{}) fakeConfig.EXPECT().GetInt(fmt.Sprintf("%s.metrics.notify_level", config.DB_USER_SETTINGS_SUBKEY)).AnyTimes().Return(int(pkg.MetricsNotifyLevelFail))