diff --git a/common/common.go b/common/common.go index 8ea849216745e340c6f204757714c903f6f76cc0..6cfa90c072a0bd893c38e37817676c8f4396bc10 100644 --- a/common/common.go +++ b/common/common.go @@ -412,9 +412,8 @@ func (c *Configuration) IsAtomicUploadEnabled() bool { } // GetProxyListener returns a wrapper for the given listener that supports the -// HAProxy Proxy Protocol or nil if the proxy protocol is not configured +// HAProxy Proxy Protocol func (c *Configuration) GetProxyListener(listener net.Listener) (*proxyproto.Listener, error) { - var proxyListener *proxyproto.Listener var err error if c.ProxyProtocol > 0 { var policyFunc func(upstream net.Addr) (proxyproto.Policy, error) @@ -436,12 +435,12 @@ func (c *Configuration) GetProxyListener(listener net.Listener) (*proxyproto.Lis } } } - proxyListener = &proxyproto.Listener{ + return &proxyproto.Listener{ Listener: listener, Policy: policyFunc, - } + }, nil } - return proxyListener, nil + return nil, errors.New("proxy protocol not configured") } // ExecuteStartupHook runs the startup hook if defined diff --git a/common/common_test.go b/common/common_test.go index af3103801e2bd83c765733032ceb07e3207450d9..620aad25cbec98412e67d47e6075245315fe02bc 100644 --- a/common/common_test.go +++ b/common/common_test.go @@ -557,8 +557,13 @@ func TestQuotaScans(t *testing.T) { func TestProxyProtocolVersion(t *testing.T) { c := Configuration{ - ProxyProtocol: 1, + ProxyProtocol: 0, } + _, err := c.GetProxyListener(nil) + if assert.Error(t, err) { + assert.Contains(t, err.Error(), "proxy protocol not configured") + } + c.ProxyProtocol = 1 proxyListener, err := c.GetProxyListener(nil) assert.NoError(t, err) assert.Nil(t, proxyListener.Policy) diff --git a/config/config.go b/config/config.go index b64479629c82fdb78b752db826515ec31dbb71e0..2ab611c364092c5643c47fb6c012c353eb1c5550 100644 --- a/config/config.go +++ b/config/config.go @@ -46,13 +46,16 @@ var ( ApplyProxyConfig: true, } defaultFTPDBinding = ftpd.Binding{ - Address: "", - Port: 0, - ApplyProxyConfig: true, - TLSMode: 0, - ForcePassiveIP: "", - ClientAuthType: 0, - TLSCipherSuites: nil, + Address: "", + Port: 0, + ApplyProxyConfig: true, + TLSMode: 0, + ForcePassiveIP: "", + ClientAuthType: 0, + TLSCipherSuites: nil, + PassiveConnectionsSecurity: 0, + ActiveConnectionsSecurity: 0, + Debug: false, } defaultWebDAVDBinding = webdavd.Binding{ Address: "", @@ -745,6 +748,18 @@ func getFTPDBindingFromEnv(idx int) { isSet = true } + pasvSecurity, ok := lookupIntFromEnv(fmt.Sprintf("SFTPGO_FTPD__BINDINGS__%v__PASSIVE_CONNECTIONS_SECURITY", idx)) + if ok { + binding.PassiveConnectionsSecurity = int(pasvSecurity) + isSet = true + } + + activeSecurity, ok := lookupIntFromEnv(fmt.Sprintf("SFTPGO_FTPD__BINDINGS__%v__ACTIVE_CONNECTIONS_SECURITY", idx)) + if ok { + binding.ActiveConnectionsSecurity = int(activeSecurity) + isSet = true + } + debug, ok := lookupBoolFromEnv(fmt.Sprintf("SFTPGO_FTPD__BINDINGS__%v__DEBUG", idx)) if ok { binding.Debug = debug diff --git a/config/config_test.go b/config/config_test.go index 3d92222cde4e24026f980371078d1dc0fbc8deb8..c67a7456376f578297e1a4dea0bd85a9e368f4b8 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -522,12 +522,14 @@ func TestFTPDBindingsFromEnv(t *testing.T) { os.Setenv("SFTPGO_FTPD__BINDINGS__0__TLS_MODE", "2") os.Setenv("SFTPGO_FTPD__BINDINGS__0__FORCE_PASSIVE_IP", "127.0.1.2") os.Setenv("SFTPGO_FTPD__BINDINGS__0__TLS_CIPHER_SUITES", "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256") + os.Setenv("SFTPGO_FTPD__BINDINGS__0__PASSIVE_CONNECTIONS_SECURITY", "1") os.Setenv("SFTPGO_FTPD__BINDINGS__9__ADDRESS", "127.0.1.1") os.Setenv("SFTPGO_FTPD__BINDINGS__9__PORT", "2203") os.Setenv("SFTPGO_FTPD__BINDINGS__9__TLS_MODE", "1") os.Setenv("SFTPGO_FTPD__BINDINGS__9__FORCE_PASSIVE_IP", "127.0.1.1") os.Setenv("SFTPGO_FTPD__BINDINGS__9__CLIENT_AUTH_TYPE", "2") os.Setenv("SFTPGO_FTPD__BINDINGS__9__DEBUG", "1") + os.Setenv("SFTPGO_FTPD__BINDINGS__9__ACTIVE_CONNECTIONS_SECURITY", "1") t.Cleanup(func() { os.Unsetenv("SFTPGO_FTPD__BINDINGS__0__ADDRESS") @@ -536,12 +538,14 @@ func TestFTPDBindingsFromEnv(t *testing.T) { os.Unsetenv("SFTPGO_FTPD__BINDINGS__0__TLS_MODE") os.Unsetenv("SFTPGO_FTPD__BINDINGS__0__FORCE_PASSIVE_IP") os.Unsetenv("SFTPGO_FTPD__BINDINGS__0__TLS_CIPHER_SUITES") + os.Unsetenv("SFTPGO_FTPD__BINDINGS__0__ACTIVE_CONNECTIONS_SECURITY") os.Unsetenv("SFTPGO_FTPD__BINDINGS__9__ADDRESS") os.Unsetenv("SFTPGO_FTPD__BINDINGS__9__PORT") os.Unsetenv("SFTPGO_FTPD__BINDINGS__9__TLS_MODE") os.Unsetenv("SFTPGO_FTPD__BINDINGS__9__FORCE_PASSIVE_IP") os.Unsetenv("SFTPGO_FTPD__BINDINGS__9__CLIENT_AUTH_TYPE") os.Unsetenv("SFTPGO_FTPD__BINDINGS__9__DEBUG") + os.Unsetenv("SFTPGO_FTPD__BINDINGS__9__ACTIVE_CONNECTIONS_SECURITY") }) configDir := ".." @@ -559,6 +563,8 @@ func TestFTPDBindingsFromEnv(t *testing.T) { require.Equal(t, "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256", bindings[0].TLSCipherSuites[0]) require.Equal(t, "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", bindings[0].TLSCipherSuites[1]) require.False(t, bindings[0].Debug) + require.Equal(t, 1, bindings[0].PassiveConnectionsSecurity) + require.Equal(t, 0, bindings[0].ActiveConnectionsSecurity) require.Equal(t, 2203, bindings[1].Port) require.Equal(t, "127.0.1.1", bindings[1].Address) require.True(t, bindings[1].ApplyProxyConfig) // default value @@ -566,6 +572,8 @@ func TestFTPDBindingsFromEnv(t *testing.T) { require.Equal(t, "127.0.1.1", bindings[1].ForcePassiveIP) require.Equal(t, 2, bindings[1].ClientAuthType) require.Nil(t, bindings[1].TLSCipherSuites) + require.Equal(t, 0, bindings[1].PassiveConnectionsSecurity) + require.Equal(t, 1, bindings[1].ActiveConnectionsSecurity) require.True(t, bindings[1].Debug) } diff --git a/docs/full-configuration.md b/docs/full-configuration.md index ebec0830f14ecc2f0da2686adfe1ab5fe9e35d70..55c685ffdbf11c0efe8e67112da6f282649d860b 100644 --- a/docs/full-configuration.md +++ b/docs/full-configuration.md @@ -116,6 +116,8 @@ The configuration file contains the following sections: - `force_passive_ip`, ip address. External IP address to expose for passive connections. Leavy empty to autodetect. If not empty, it must be a valid IPv4 address. Defaut: "". - `client_auth_type`, integer. Set to `1` to require a client certificate and verify it. Set to `2` to request a client certificate during the TLS handshake and verify it if given, in this mode the client is allowed not to send a certificate. At least one certification authority must be defined in order to verify client certificates. If no certification authority is defined, this setting is ignored. Default: 0. - `tls_cipher_suites`, list of strings. List of supported cipher suites for TLS version 1.2. If empty, a default list of secure cipher suites is used, with a preference order based on hardware performance. Note that TLS 1.3 ciphersuites are not configurable. The supported ciphersuites names are defined [here](https://github.com/golang/go/blob/master/src/crypto/tls/cipher_suites.go#L52). Any invalid name will be silently ignored. The order matters, the ciphers listed first will be the preferred ones. Default: empty. + - `passive_connections_security`, integer. Defines the security checks for passive data connections. Set to `0` to require matching peer IP addresses of control and data connection. Set to `1` to disable any checks. Please note that if you run the FTP service behind a proxy you must enable the proxy protocol for both control and data connections. Default: `0`. + - `active_connections_security`, integer. Defines the security checks for active data connections. The supported values are the same as described for `passive_connections_security`. Please note that disabling the security checks you will make the FTP service vulnerable to bounce attacks on active data connections, so change the default value only if you are on a trusted/internal network. Default: `0`. - `debug`, boolean. If enabled any FTP command will be logged. This will generate a lot of logs. Enable only if you are investigating a client compatibility issue or something similar. You shouldn't leave this setting enabled for production servers. Default `false`. - `banner`, string. Greeting banner displayed when a connection first comes in. Leave empty to use the default banner. Default `SFTPGo ready`, for example `SFTPGo 1.0.0-dev ready`. - `banner_file`, path to the banner file. The contents of the specified file, if any, are displayed when someone connects to the server. It can be a path relative to the config dir or an absolute one. If set, it overrides the banner string provided by the `banner` option. Leave empty to disable. diff --git a/ftpd/ftpd.go b/ftpd/ftpd.go index 1c90e1d08b2d2948570a6b78b3990291871aa0f9..07493d57b47b2257ef853e239dd0d2a540e550f5 100644 --- a/ftpd/ftpd.go +++ b/ftpd/ftpd.go @@ -51,6 +51,16 @@ type Binding struct { // any invalid name will be silently ignored. // The order matters, the ciphers listed first will be the preferred ones. TLSCipherSuites []string `json:"tls_cipher_suites" mapstructure:"tls_cipher_suites"` + // PassiveConnectionsSecurity defines the security checks for passive data connections. + // Supported values: + // - 0 require matching peer IP addresses of control and data connection. This is the default + // - 1 disable any checks + PassiveConnectionsSecurity int `json:"passive_connections_security" mapstructure:"passive_connections_security"` + // ActiveConnectionsSecurity defines the security checks for active data connections. + // The supported values are the same as described for PassiveConnectionsSecurity. + // Please note that disabling the security checks you will make the FTP service vulnerable to bounce attacks + // on active data connections, so change the default value only if you are on a trusted/internal network + ActiveConnectionsSecurity int `json:"active_connections_security" mapstructure:"active_connections_security"` // Debug enables the FTP debug mode. In debug mode, every FTP command will be logged Debug bool `json:"debug" mapstructure:"debug"` ciphers []uint16 @@ -77,6 +87,16 @@ func (b *Binding) IsValid() bool { return b.Port > 0 } +func (b *Binding) checkSecuritySettings() error { + if b.PassiveConnectionsSecurity < 0 || b.PassiveConnectionsSecurity > 1 { + return fmt.Errorf("invalid passive_connections_security: %v", b.PassiveConnectionsSecurity) + } + if b.ActiveConnectionsSecurity < 0 || b.ActiveConnectionsSecurity > 1 { + return fmt.Errorf("invalid active_connections_security: %v", b.ActiveConnectionsSecurity) + } + return nil +} + func (b *Binding) checkPassiveIP() error { if b.ForcePassiveIP != "" { ip := net.ParseIP(b.ForcePassiveIP) diff --git a/ftpd/ftpd_test.go b/ftpd/ftpd_test.go index 50a753e9db99cf55ccfcd5ec677119118d2b4b8e..76db3184797b791e8c89a7ef9cce605eb4fbd4d5 100644 --- a/ftpd/ftpd_test.go +++ b/ftpd/ftpd_test.go @@ -2289,13 +2289,13 @@ func TestActiveModeDisabled(t *testing.T) { if assert.NoError(t, err) { code, response, err := client.SendCustomCommand("PORT 10,2,0,2,4,31") assert.NoError(t, err) - assert.Equal(t, ftp.StatusCommandOK, code) - assert.Equal(t, "PORT command successful", response) + assert.Equal(t, ftp.StatusBadArguments, code) + assert.Equal(t, "Your request does not meet the configured security requirements", response) code, response, err = client.SendCustomCommand("EPRT |1|132.235.1.2|6275|") assert.NoError(t, err) - assert.Equal(t, ftp.StatusCommandOK, code) - assert.Equal(t, "EPRT command successful", response) + assert.Equal(t, ftp.StatusBadArguments, code) + assert.Equal(t, "Your request does not meet the configured security requirements", response) err = client.Quit() assert.NoError(t, err) diff --git a/ftpd/internal_test.go b/ftpd/internal_test.go index 9eeeb39b14dc85b9c6477449af95ad4e5a8f63a5..d3fc51b3731b49f2da3b3232e6880821b643f1f3 100644 --- a/ftpd/internal_test.go +++ b/ftpd/internal_test.go @@ -13,6 +13,7 @@ import ( "github.com/eikenb/pipeat" ftpserver "github.com/fclairamb/ftpserverlib" + "github.com/pires/go-proxyproto" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -393,6 +394,19 @@ func TestInitialization(t *testing.T) { _, err = server.GetSettings() assert.Error(t, err) + binding.PassiveConnectionsSecurity = 100 + binding.ActiveConnectionsSecurity = 100 + server = NewServer(c, configDir, binding, 0) + _, err = server.GetSettings() + if assert.Error(t, err) { + assert.Contains(t, err.Error(), "invalid passive_connections_security") + } + binding.PassiveConnectionsSecurity = 1 + server = NewServer(c, configDir, binding, 0) + _, err = server.GetSettings() + if assert.Error(t, err) { + assert.Contains(t, err.Error(), "invalid active_connections_security") + } binding = Binding{ Port: 2121, ForcePassiveIP: "192.168.1", @@ -467,6 +481,35 @@ func TestServerGetSettings(t *testing.T) { binding.TLSMode = 2 assert.Equal(t, "Implicit", binding.GetTLSDescription()) + certPath := filepath.Join(os.TempDir(), "test.crt") + keyPath := filepath.Join(os.TempDir(), "test.key") + err = os.WriteFile(certPath, []byte(ftpsCert), os.ModePerm) + assert.NoError(t, err) + err = os.WriteFile(keyPath, []byte(ftpsKey), os.ModePerm) + assert.NoError(t, err) + + common.Config.ProxyAllowed = nil + c.CertificateFile = certPath + c.CertificateKeyFile = keyPath + server = NewServer(c, configDir, binding, 0) + server.binding.Port = 9021 + settings, err = server.GetSettings() + assert.NoError(t, err) + assert.NotNil(t, settings.Listener) + + listener, err := net.Listen("tcp", ":0") + assert.NoError(t, err) + listener, err = server.WrapPassiveListener(listener) + assert.NoError(t, err) + + _, ok := listener.(*proxyproto.Listener) + assert.True(t, ok) + + err = os.Remove(certPath) + assert.NoError(t, err) + err = os.Remove(keyPath) + assert.NoError(t, err) + common.Config = oldConfig } diff --git a/ftpd/server.go b/ftpd/server.go index 8419b80f0e7eb2c7f09c4ba8af3620a658ed0d1d..d14c35fa6d1e150f58c8bf13a2bbb82bf3f3bbdc 100644 --- a/ftpd/server.go +++ b/ftpd/server.go @@ -86,6 +86,9 @@ func (s *Server) GetSettings() (*ftpserver.Settings, error) { if err := s.binding.checkPassiveIP(); err != nil { return nil, err } + if err := s.binding.checkSecuritySettings(); err != nil { + return nil, err + } var portRange *ftpserver.PortRange if s.config.PassivePortRange.Start > 0 && s.config.PassivePortRange.End > s.config.PassivePortRange.Start { portRange = &ftpserver.PortRange{ @@ -94,7 +97,7 @@ func (s *Server) GetSettings() (*ftpserver.Settings, error) { } } var ftpListener net.Listener - if common.Config.ProxyProtocol > 0 && s.binding.ApplyProxyConfig { + if s.binding.HasProxy() { listener, err := net.Listen("tcp", s.binding.GetAddress()) if err != nil { logger.Warn(logSender, "", "error starting listener on address %v: %v", s.binding.GetAddress(), err) @@ -105,6 +108,9 @@ func (s *Server) GetSettings() (*ftpserver.Settings, error) { logger.Warn(logSender, "", "error enabling proxy listener: %v", err) return nil, err } + if s.binding.TLSMode == 2 && s.tlsConfig != nil { + ftpListener = tls.NewListener(ftpListener, s.tlsConfig) + } } if s.binding.TLSMode < 0 || s.binding.TLSMode > 2 { @@ -130,6 +136,8 @@ func (s *Server) GetSettings() (*ftpserver.Settings, error) { EnableHASH: s.config.HASHSupport > 0, EnableCOMB: s.config.CombineSupport > 0, DefaultTransferType: ftpserver.TransferTypeBinary, + ActiveConnectionsCheck: ftpserver.DataConnectionRequirement(s.binding.ActiveConnectionsSecurity), + PasvConnectionsCheck: ftpserver.DataConnectionRequirement(s.binding.PassiveConnectionsSecurity), }, nil } @@ -199,6 +207,14 @@ func (s *Server) AuthUser(cc ftpserver.ClientContext, username, password string) return connection, nil } +// WrapPassiveListener implements the MainDriverExtensionPassiveWrapper interface +func (s *Server) WrapPassiveListener(listener net.Listener) (net.Listener, error) { + if s.binding.HasProxy() { + return common.Config.GetProxyListener(listener) + } + return listener, nil +} + // VerifyConnection checks whether a user should be authenticated using a client certificate without prompting for a password func (s *Server) VerifyConnection(cc ftpserver.ClientContext, user string, tlsConn *tls.Conn) (ftpserver.ClientDriver, error) { if !s.binding.isMutualTLSEnabled() { diff --git a/go.mod b/go.mod index 6b6679620412d2ed771b5bd6792ce5a92778a8d8..7c13bab56526cd223195d41f0a21838d7f0ed703 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/Azure/azure-storage-blob-go v0.14.0 github.com/GehirnInc/crypt v0.0.0-20200316065508-bb7000b8a962 github.com/alexedwards/argon2id v0.0.0-20210511081203-7d35d68092b8 - github.com/aws/aws-sdk-go v1.40.12 + github.com/aws/aws-sdk-go v1.40.15 github.com/cockroachdb/cockroach-go/v2 v2.1.1 github.com/eikenb/pipeat v0.0.0-20210603033007-44fc3ffce52b github.com/fatih/color v1.12.0 // indirect @@ -26,11 +26,11 @@ require ( github.com/hashicorp/go-retryablehttp v0.7.0 github.com/hashicorp/yamux v0.0.0-20210707203944-259a57b3608c // indirect github.com/jlaffaye/ftp v0.0.0-20201112195030-9aae4d151126 - github.com/klauspost/compress v1.13.1 - github.com/klauspost/cpuid/v2 v2.0.8 // indirect + github.com/klauspost/compress v1.13.3 + github.com/klauspost/cpuid/v2 v2.0.9 // indirect github.com/kr/text v0.2.0 // indirect github.com/lestrrat-go/backoff/v2 v2.0.8 // indirect - github.com/lestrrat-go/jwx v1.2.4 + github.com/lestrrat-go/jwx v1.2.5 github.com/lib/pq v1.10.2 github.com/mattn/go-isatty v0.0.13 // indirect github.com/mattn/go-sqlite3 v1.14.8 @@ -62,13 +62,15 @@ require ( golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac google.golang.org/api v0.52.0 - google.golang.org/genproto v0.0.0-20210729151513-df9385d47c1b // indirect + google.golang.org/genproto v0.0.0-20210804223703-f1db76f3300d // indirect google.golang.org/grpc v1.39.0 google.golang.org/protobuf v1.27.1 gopkg.in/natefinch/lumberjack.v2 v2.0.0 ) replace ( + github.com/eikenb/pipeat => github.com/drakkan/pipeat v0.0.0-20210805162858-70e57fa8a639 + github.com/fclairamb/ftpserverlib => github.com/drakkan/ftpserverlib v0.0.0-20210805132427-425f32d9dc15 github.com/jlaffaye/ftp => github.com/drakkan/ftp v0.0.0-20201114075148-9b9adce499a9 golang.org/x/crypto => github.com/drakkan/crypto v0.0.0-20210515063737-edf1d3b63536 golang.org/x/net => github.com/drakkan/net v0.0.0-20210725074420-30b60d4a1e60 diff --git a/go.sum b/go.sum index 2cf34e17cca5e70b0078d8677fc6a263e7e49b05..61ede6307988f0570ae3ff5d993fce8da7df4c9d 100644 --- a/go.sum +++ b/go.sum @@ -118,8 +118,8 @@ github.com/aws/aws-sdk-go v1.15.27/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZo github.com/aws/aws-sdk-go v1.23.20/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.38.35/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= github.com/aws/aws-sdk-go v1.38.68/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= -github.com/aws/aws-sdk-go v1.40.12 h1:66+IAWhl+aaZCW1+ndS/GNfAxy8tJca2cMoIF2O325I= -github.com/aws/aws-sdk-go v1.40.12/go.mod h1:585smgzpB/KqRA+K3y/NL/oYRqQvpNJYvLm+LY1U59Q= +github.com/aws/aws-sdk-go v1.40.15 h1:aqQCwW8meVzLCacWX8NEPg8bBkL0ZlcMSbhwrsg6eNE= +github.com/aws/aws-sdk-go v1.40.15/go.mod h1:585smgzpB/KqRA+K3y/NL/oYRqQvpNJYvLm+LY1U59Q= github.com/aws/aws-sdk-go-v2 v1.7.0/go.mod h1:tb9wi5s61kTDA5qCkcDbt3KRVV74GGslQkl/DRdX/P4= github.com/aws/aws-sdk-go-v2/service/cloudwatch v1.5.0/go.mod h1:acH3+MQoiMzozT/ivU+DbRg7Ooo2298RdRaWcOv+4vM= github.com/aws/smithy-go v1.5.0/go.mod h1:SObp3lf9smib00L/v3U2eAKG8FyQ7iLrJnQiAmR5n+E= @@ -176,15 +176,17 @@ github.com/drakkan/crypto v0.0.0-20210515063737-edf1d3b63536 h1:3DJdhj83IA3NjlVz github.com/drakkan/crypto v0.0.0-20210515063737-edf1d3b63536/go.mod h1:M1JpE4lvRI5LLrE7yTCWfhbsy5rx3oZVjGZad4XMwWc= github.com/drakkan/ftp v0.0.0-20201114075148-9b9adce499a9 h1:LPH1dEblAOO/LoG7yHPMtBLXhQmjaga91/DDjWk9jWA= github.com/drakkan/ftp v0.0.0-20201114075148-9b9adce499a9/go.mod h1:2lmrmq866uF2tnje75wQHzmPXhmSWUt7Gyx2vgK1RCU= +github.com/drakkan/ftpserverlib v0.0.0-20210805132427-425f32d9dc15 h1:J7FZPDILyOMYtShuM5hH3GLTL1cCDtoJ1InsxEyl798= +github.com/drakkan/ftpserverlib v0.0.0-20210805132427-425f32d9dc15/go.mod h1:+Doq95UijHTIaJcWREhyu9dyQOqyoULbVU3OXgs8wEI= github.com/drakkan/net v0.0.0-20210725074420-30b60d4a1e60 h1:qGPbhCgKiOglRLoNPgAwdTOp3xW3TC96RSGLkmVdsd0= github.com/drakkan/net v0.0.0-20210725074420-30b60d4a1e60/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +github.com/drakkan/pipeat v0.0.0-20210805162858-70e57fa8a639 h1:8tfGdb4kg/YCvAbIrsMazgoNtnqdOqQVDKW12uUCuuU= +github.com/drakkan/pipeat v0.0.0-20210805162858-70e57fa8a639/go.mod h1:kltMsfRMTHSFdMbK66XdS8mfMW77+FZA1fGY1xYMF84= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= -github.com/eikenb/pipeat v0.0.0-20210603033007-44fc3ffce52b h1:h7A/b/M1yuYqQwZmRf+9BKuUJQgkgdvXYAwVl7L7WBo= -github.com/eikenb/pipeat v0.0.0-20210603033007-44fc3ffce52b/go.mod h1:kltMsfRMTHSFdMbK66XdS8mfMW77+FZA1fGY1xYMF84= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= @@ -197,8 +199,6 @@ github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5Kwzbycv github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= github.com/fatih/color v1.12.0 h1:mRhaKNwANqRgUBGKmnI5ZxEk7QXmjQeCcuYFMX2bfcc= github.com/fatih/color v1.12.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= -github.com/fclairamb/ftpserverlib v0.15.0 h1:3MmdkZy8orZwemZLgwIdCwcyac3hCH2PcBFo5S/F7AM= -github.com/fclairamb/ftpserverlib v0.15.0/go.mod h1:+Doq95UijHTIaJcWREhyu9dyQOqyoULbVU3OXgs8wEI= github.com/fclairamb/go-log v0.1.0 h1:fNoqk8w62i4EDEuRzDgHdDVTqMYSyr3DS981R7F2x/Y= github.com/fclairamb/go-log v0.1.0/go.mod h1:iqmym8aI6xBbZXnZSPjElrmQrlEwjwEemOmIzKaTBM8= github.com/form3tech-oss/jwt-go v3.2.2+incompatible h1:TcekIExNqud5crz4xD2pavyTgWiPvpYe4Xau31I0PRk= @@ -474,11 +474,11 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.11.12/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.12.2/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= -github.com/klauspost/compress v1.13.1 h1:wXr2uRxZTJXHLly6qhJabee5JqIhTRoLBhDOA74hDEQ= -github.com/klauspost/compress v1.13.1/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= +github.com/klauspost/compress v1.13.3 h1:BtAvtV1+h0YwSVwWoYXMREPpYu9VzTJ9QDI1TEg/iQQ= +github.com/klauspost/compress v1.13.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.0.8 h1:bhR2mgIlno/Sfk4oUbH4sPlc83z1yGrN9bvqiq3C33I= -github.com/klauspost/cpuid/v2 v2.0.8/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/klauspost/cpuid/v2 v2.0.9 h1:lgaqFMSdTdQYdZ04uHyN2d/eKdOMyi2YLSvlQIBFYa4= +github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -507,8 +507,8 @@ github.com/lestrrat-go/httpcc v1.0.0/go.mod h1:tGS/u00Vh5N6FHNkExqGGNId8e0Big+++ github.com/lestrrat-go/iter v1.0.1 h1:q8faalr2dY6o8bV45uwrxq12bRa1ezKrB6oM9FUgN4A= github.com/lestrrat-go/iter v1.0.1/go.mod h1:zIdgO1mRKhn8l9vrZJZz9TUMMFbQbLeTsbqPDrJ/OJc= github.com/lestrrat-go/jwx v1.1.6/go.mod h1:c+R8G7qsaFNmTzYjU98A+sMh8Bo/MJqO9GnpqR+X024= -github.com/lestrrat-go/jwx v1.2.4 h1:EuVGI/hPUSRstxWpWjVcklOe1odJLVrFY9zt4k1pa30= -github.com/lestrrat-go/jwx v1.2.4/go.mod h1:CAe9Z479rJwIYDR2DqWwMm9c+gCNoYB6+0wBxPkEh0Q= +github.com/lestrrat-go/jwx v1.2.5 h1:0Akd9qTHrla8eqCV54Z4wRVv54WI54dUHN5D2+mIayc= +github.com/lestrrat-go/jwx v1.2.5/go.mod h1:CAe9Z479rJwIYDR2DqWwMm9c+gCNoYB6+0wBxPkEh0Q= github.com/lestrrat-go/option v0.0.0-20210103042652-6f1ecfceda35/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= github.com/lestrrat-go/option v1.0.0 h1:WqAWL8kh8VcSoD6xjSH34/1m8yxluXQbDeKNfvFeEO4= github.com/lestrrat-go/option v1.0.0/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= @@ -1085,8 +1085,8 @@ google.golang.org/genproto v0.0.0-20210624174822-c5cf32407d0a/go.mod h1:SzzZ/N+n google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= google.golang.org/genproto v0.0.0-20210721163202-f1cecdd8b78a/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= google.golang.org/genproto v0.0.0-20210722135532-667f2b7c528f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= -google.golang.org/genproto v0.0.0-20210729151513-df9385d47c1b h1:4xoALQmXxqVdDdLimpPyPeDdsJzo+nFTJw9euAMpqgM= -google.golang.org/genproto v0.0.0-20210729151513-df9385d47c1b/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= +google.golang.org/genproto v0.0.0-20210804223703-f1db76f3300d h1:Y9fT4WNRxuD0qofEPeWJwNC5kYLBcSXx0m91zyCMzYY= +google.golang.org/genproto v0.0.0-20210804223703-f1db76f3300d/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= google.golang.org/grpc v1.8.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= diff --git a/sftpd/server.go b/sftpd/server.go index cfe9728b30b333826b2c1ee3fc85746f71b83747..e3f7a0c43c41c4af30ade78da202ff3f1db16c10 100644 --- a/sftpd/server.go +++ b/sftpd/server.go @@ -226,16 +226,14 @@ func (c *Configuration) Initialize(configDir string) error { return } - if binding.ApplyProxyConfig { + if binding.ApplyProxyConfig && common.Config.ProxyProtocol > 0 { proxyListener, err := common.Config.GetProxyListener(listener) if err != nil { logger.Warn(logSender, "", "error enabling proxy listener: %v", err) exitChannel <- err return } - if proxyListener != nil { - listener = proxyListener - } + listener = proxyListener } exitChannel <- c.serve(listener, serverConfig) diff --git a/sftpgo.json b/sftpgo.json index 306f5d0cd5a8dcf54141a86004b63a2b161dca0e..47d9c172c9e8ed0cc8567fee81956bae8ba5883a 100644 --- a/sftpgo.json +++ b/sftpgo.json @@ -84,6 +84,8 @@ "force_passive_ip": "", "client_auth_type": 0, "tls_cipher_suites": [], + "passive_connections_security": 0, + "active_connections_security": 0, "debug": false } ],