diff --git a/go.mod b/go.mod index 2c151819..34b44424 100644 --- a/go.mod +++ b/go.mod @@ -13,11 +13,8 @@ require ( github.com/aws/aws-sdk-go-v2 v1.37.2 github.com/aws/aws-sdk-go-v2/config v1.30.3 github.com/aws/aws-sdk-go-v2/credentials v1.18.3 - github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.2 github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.18.3 - github.com/aws/aws-sdk-go-v2/service/marketplacemetering v1.31.0 github.com/aws/aws-sdk-go-v2/service/s3 v1.86.0 - github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.37.0 github.com/aws/aws-sdk-go-v2/service/sts v1.36.0 github.com/bmatcuk/doublestar/v4 v4.9.1 github.com/cockroachdb/cockroach-go/v2 v2.4.1 @@ -94,6 +91,7 @@ require ( github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.53.0 // indirect github.com/ajg/form v1.5.1 // indirect github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.0 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.2 // indirect github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.2 // indirect github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.2 // indirect github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 // indirect diff --git a/go.sum b/go.sum index 3ccdf107..c3a98d54 100644 --- a/go.sum +++ b/go.sum @@ -85,12 +85,8 @@ github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.2 h1:oxmDEO14N github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.2/go.mod h1:4hH+8QCrk1uRWDPsVfsNDUup3taAjO8Dnx63au7smAU= github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.2 h1:0hBNFAPwecERLzkhhBY+lQKUMpXSKVv4Sxovikrioms= github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.2/go.mod h1:Vcnh4KyR4imrrjGN7A2kP2v9y6EPudqoPKXtnmBliPU= -github.com/aws/aws-sdk-go-v2/service/marketplacemetering v1.31.0 h1:RXdMbI81mtpO/7xXy/wG6S755K4dOXKJIGU8R6dykv0= -github.com/aws/aws-sdk-go-v2/service/marketplacemetering v1.31.0/go.mod h1:EhQvLFnF8aFiA1uDLi63U+RtT4EdJ/rQg+EQtGEojpk= github.com/aws/aws-sdk-go-v2/service/s3 v1.86.0 h1:utPhv4ECQzJIUbtx7vMN4A8uZxlQ5tSt1H1toPI41h8= github.com/aws/aws-sdk-go-v2/service/s3 v1.86.0/go.mod h1:1/eZYtTWazDgVl96LmGdGktHFi7prAcGCrJ9JGvBITU= -github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.37.0 h1:fC0s79wxfsbz/4WCvosbHLk2mb9ICjPyB+lWs6a0TGM= -github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.37.0/go.mod h1:6HxvKCop1trgfFlQGQmlq+WbMM5yPazMN9ClWFWGtDM= github.com/aws/aws-sdk-go-v2/service/sso v1.27.0 h1:j7/jTOjWeJDolPwZ/J4yZ7dUsxsWZEsxNwH5O7F8eEA= github.com/aws/aws-sdk-go-v2/service/sso v1.27.0/go.mod h1:M0xdEPQtgpNT7kdAX4/vOAPkFj60hSQRb7TvW9B0iug= github.com/aws/aws-sdk-go-v2/service/ssooidc v1.32.0 h1:ywQF2N4VjqX+Psw+jLjMmUL2g1RDHlvri3NxHA08MGI= diff --git a/internal/cmd/awscontainer.go b/internal/cmd/awscontainer.go deleted file mode 100644 index 3633fffb..00000000 --- a/internal/cmd/awscontainer.go +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (C) 2019 Nicola Murino -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published -// by the Free Software Foundation, version 3. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -//go:build awscontainer - -package cmd - -import ( - "github.com/spf13/cobra" - "github.com/spf13/viper" -) - -func addAWSContainerFlags(cmd *cobra.Command) { - viper.SetDefault("disable_aws_installation_code", false) - viper.BindEnv("disable_aws_installation_code", "SFTPGO_DISABLE_AWS_INSTALLATION_CODE") //nolint:errcheck - cmd.Flags().BoolVar(&disableAWSInstallationCode, "disable-aws-installation-code", viper.GetBool("disable_aws_installation_code"), - `Disable installation code for the AWS container. -This flag can be set using -SFTPGO_DISABLE_AWS_INSTALLATION_CODE env var too. -`) - viper.BindPFlag("disable_aws_installation_code", cmd.Flags().Lookup("disable-aws-installation-code")) //nolint:errcheck -} diff --git a/internal/cmd/awscontainer_disabled.go b/internal/cmd/awscontainer_disabled.go deleted file mode 100644 index cbdd54be..00000000 --- a/internal/cmd/awscontainer_disabled.go +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (C) 2019 Nicola Murino -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published -// by the Free Software Foundation, version 3. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -//go:build !awscontainer - -package cmd - -import ( - "github.com/spf13/cobra" -) - -func addAWSContainerFlags(_ *cobra.Command) {} diff --git a/internal/cmd/root.go b/internal/cmd/root.go index ba96be58..00759236 100644 --- a/internal/cmd/root.go +++ b/internal/cmd/root.go @@ -85,8 +85,6 @@ var ( loadDataQuotaScan int loadDataClean bool graceTime int - // used if awscontainer build tag is enabled - disableAWSInstallationCode bool rootCmd = &cobra.Command{ Use: "sftpgo", diff --git a/internal/cmd/serve.go b/internal/cmd/serve.go index 519fa78f..348fb834 100644 --- a/internal/cmd/serve.go +++ b/internal/cmd/serve.go @@ -61,7 +61,7 @@ Please take a look at the usage below to customize the startup options`, LoadDataClean: loadDataClean, Shutdown: make(chan bool), } - if err := service.Start(disableAWSInstallationCode); err == nil { + if err := service.Start(); err == nil { service.Wait() if service.Error == nil { os.Exit(0) @@ -144,5 +144,4 @@ func checkServeParamsFromEnvFiles(configDir string) { //nolint:gocyclo func init() { rootCmd.AddCommand(serveCmd) addServeFlags(serveCmd) - addAWSContainerFlags(serveCmd) } diff --git a/internal/service/awscontainer.go b/internal/service/awscontainer.go deleted file mode 100644 index 1f62c3a5..00000000 --- a/internal/service/awscontainer.go +++ /dev/null @@ -1,181 +0,0 @@ -// Copyright (C) 2019 Nicola Murino -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published -// by the Free Software Foundation, version 3. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -//go:build awscontainer - -package service - -import ( - "context" - "errors" - "fmt" - "time" - - "github.com/aws/aws-sdk-go-v2/aws" - awsconfig "github.com/aws/aws-sdk-go-v2/config" - "github.com/aws/aws-sdk-go-v2/feature/ec2/imds" - "github.com/aws/aws-sdk-go-v2/service/marketplacemetering" - "github.com/aws/aws-sdk-go-v2/service/secretsmanager" - "github.com/google/uuid" - - "github.com/drakkan/sftpgo/v2/internal/config" - "github.com/drakkan/sftpgo/v2/internal/dataprovider" - "github.com/drakkan/sftpgo/v2/internal/httpd" - "github.com/drakkan/sftpgo/v2/internal/logger" - "github.com/drakkan/sftpgo/v2/internal/util" -) - -const ( - installCodeName = "SFTPGo_Installation_Code" -) - -var ( - awsProductCode = "" -) - -func registerAWSContainer(disableAWSInstallationCode bool) error { - if awsProductCode == "" { - return errors.New("product code not set") - } - ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) - defer cancel() - - cfg, err := getAWSConfig(ctx) - if err != nil { - return fmt.Errorf("unable to get config to register AWS container: %w", err) - } - if !disableAWSInstallationCode { - if err := setInstallationCode(cfg); err != nil { - return err - } - } - requestNonce, err := uuid.NewRandom() - if err != nil { - return fmt.Errorf("unable to generate nonce for metering API: %w", err) - } - svc := marketplacemetering.NewFromConfig(cfg) - result, err := svc.RegisterUsage(ctx, &marketplacemetering.RegisterUsageInput{ - ProductCode: aws.String(awsProductCode), - PublicKeyVersion: aws.Int32(1), - Nonce: aws.String(requestNonce.String()), - }) - if err != nil { - return fmt.Errorf("unable to register API operation for AWSMarketplace Metering: %w", err) - } - logger.Debug(logSender, "", "API operation for AWSMarketplace Metering registered, token %q", - util.GetStringFromPointer(result.Signature)) - return nil -} - -func getAWSConfig(ctx context.Context) (aws.Config, error) { - cfg, err := awsconfig.LoadDefaultConfig(ctx) - if err != nil { - return cfg, fmt.Errorf("unable to get config to register AWS container: %w", err) - } - if cfg.Region == "" { - svc := imds.NewFromConfig(cfg) - region, err := svc.GetRegion(ctx, &imds.GetRegionInput{}) - if err == nil { - logger.Debug(logSender, "", "AWS region from imds %q", region.Region) - cfg.Region = region.Region - } else { - logger.Warn(logSender, "", "unable to get region from imds, continuing anyway, error: %v", err) - } - } - return cfg, nil -} - -func setInstallationCode(cfg aws.Config) error { - if dataprovider.HasAdmin() { - return nil - } - installationCode := util.GenerateUniqueID() - requestToken, err := uuid.NewRandom() - if err != nil { - return fmt.Errorf("unable to generate client request token: %w", err) - } - - ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) - defer cancel() - - svc := secretsmanager.NewFromConfig(cfg) - _, err = svc.GetSecretValue(ctx, &secretsmanager.GetSecretValueInput{ - SecretId: aws.String(installCodeName), - }) - if err == nil { - // update existing secret - result, err := svc.UpdateSecret(ctx, &secretsmanager.UpdateSecretInput{ - SecretId: aws.String(installCodeName), - ClientRequestToken: aws.String(requestToken.String()), - SecretString: aws.String(installationCode), - }) - if err != nil { - return fmt.Errorf("unable to update installation code: %w", err) - } - logger.Debug(logSender, "", "installation code updated, secret name %q, arn %q, version id %q", - util.GetStringFromPointer(result.Name), util.GetStringFromPointer(result.ARN), - util.GetStringFromPointer(result.VersionId)) - } else { - // create new secret - logger.Debug(logSender, "", "unable to get the current installation secret, trying to create a new one, error: %v", err) - result, err := svc.CreateSecret(ctx, &secretsmanager.CreateSecretInput{ - Name: aws.String(installCodeName), - ClientRequestToken: aws.String(requestToken.String()), - SecretString: aws.String(installationCode), - }) - if err != nil { - return fmt.Errorf("unable to create installation code: %w", err) - } - logger.Debug(logSender, "", "installation code set, secret name %q, arn %q, version id %q", - util.GetStringFromPointer(result.Name), util.GetStringFromPointer(result.ARN), - util.GetStringFromPointer(result.VersionId)) - } - httpdConfig := config.GetHTTPDConfig() - httpdConfig.Setup.InstallationCode = installationCode - httpdConfig.Setup.InstallationCodeHint = "Installation code stored in Secrets Manager" - config.SetHTTPDConfig(httpdConfig) - httpd.SetInstallationCodeResolver(resolveInstallationCode) - - return nil -} - -// function called to validate the user provided secret -func resolveInstallationCode(defaultInstallationCode string) string { - logger.Debug(logSender, "", "resolving installation code") - ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) - defer cancel() - - cfg, err := getAWSConfig(ctx) - if err != nil { - logger.Error(logSender, "", "unable to get config to resolve installation code: %v", err) - return defaultInstallationCode - } - - svc := secretsmanager.NewFromConfig(cfg) - result, err := svc.GetSecretValue(ctx, &secretsmanager.GetSecretValueInput{ - SecretId: aws.String(installCodeName), - }) - if err != nil { - logger.Error(logSender, "", "unable to resolve installation code: %v", err) - return defaultInstallationCode - } - - resolvedCode := util.GetStringFromPointer(result.SecretString) - if resolvedCode == "" { - logger.Error(logSender, "", "resolved installation code is empty") - return defaultInstallationCode - } - logger.Debug(logSender, "", "installation code resolved") - return resolvedCode -} diff --git a/internal/service/awscontainer_disabled.go b/internal/service/awscontainer_disabled.go deleted file mode 100644 index 356a1fff..00000000 --- a/internal/service/awscontainer_disabled.go +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (C) 2019 Nicola Murino -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published -// by the Free Software Foundation, version 3. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -//go:build !awscontainer - -package service - -func registerAWSContainer(_ bool) error { - return nil -} diff --git a/internal/service/service.go b/internal/service/service.go index 3a8d5c81..cb8b00ff 100644 --- a/internal/service/service.go +++ b/internal/service/service.go @@ -89,7 +89,7 @@ func (s *Service) initLogger() { } // Start initializes and starts the service -func (s *Service) Start(disableAWSInstallationCode bool) error { +func (s *Service) Start() error { s.initLogger() logger.Info(logSender, "", "starting SFTPGo %s, config dir: %s, config file: %s, log max size: %d log max backups: %d "+ "log max age: %d log level: %s, log compress: %t, log utc time: %t, load data from: %q, grace time: %d secs", @@ -110,7 +110,7 @@ func (s *Service) Start(disableAWSInstallationCode bool) error { return errors.New(infoString) } - if err := s.initializeServices(disableAWSInstallationCode); err != nil { + if err := s.initializeServices(); err != nil { return err } @@ -120,7 +120,7 @@ func (s *Service) Start(disableAWSInstallationCode bool) error { return nil } -func (s *Service) initializeServices(disableAWSInstallationCode bool) error { +func (s *Service) initializeServices() error { providerConf := config.GetProviderConf() kmsConfig := config.GetKMSConfig() err := kmsConfig.Initialize() @@ -180,12 +180,6 @@ func (s *Service) initializeServices(disableAWSInstallationCode bool) error { } } - if err := registerAWSContainer(disableAWSInstallationCode); err != nil { - logger.Error(logSender, "", "error registering AWS container: %v", err) - logger.ErrorToConsole("error registering AWS container: %v", err) - return err - } - httpConfig := config.GetHTTPConfig() err = httpConfig.Initialize(s.ConfigDir) if err != nil { diff --git a/internal/service/service_portable.go b/internal/service/service_portable.go index 95ec1c17..d3181455 100644 --- a/internal/service/service_portable.go +++ b/internal/service/service_portable.go @@ -69,7 +69,7 @@ func (s *Service) StartPortableMode(sftpdPort, ftpPort, webdavPort, httpPort int configurePortableWebDAVService(webdavPort, webDavCert, webDavKey) configurePortableHTTPService(httpPort, httpsCert, httpsKey) - err = s.Start(true) + err = s.Start() if err != nil { return err }