ssh: remove the ability to fully customize the software version

many clients rely on the version string to enable/disable some features.
We only allow to hide the version number, clients must be able to reliably
identify SFTPGo

Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
This commit is contained in:
Nicola Murino 2024-04-20 17:15:15 +02:00
parent a38fd26cf6
commit ad7dcdb628
No known key found for this signature in database
GPG key ID: 935D2952DEC4EECF
4 changed files with 12 additions and 8 deletions

View file

@ -139,7 +139,7 @@ The configuration file contains the following sections:
- `address`, string. Leave blank to listen on all available network interfaces. Default: ""
- `apply_proxy_config`, boolean. If enabled the common proxy configuration, if any, will be applied. Default `true`
- `max_auth_tries` integer. Maximum number of authentication attempts permitted per connection. If set to a negative number, the number of attempts is unlimited. If set to zero, the number of attempts is limited to 6.
- `banner`, string. Identification string used by the server. Leave empty to use the default banner. Default `SFTPGo_<version>`, for example `SSH-2.0-SFTPGo_0.9.5`
- `banner`, string. Allow some degree of customization for the advertised software version. Set to `short` to hide the SFTPGo version number, if different from `short` the default will be used. The default is `SFTPGo_<version>`, for example `SSH-2.0-SFTPGo_2.6.0`, if set to `short` the identification string will be `SSH-2.0-SFTPGo`. In previous SFTPGo releases we allowed to customize the whole software version, this is a bad idea because many clients rely on the version string to enable/disable some features.
- `host_keys`, list of strings. It contains the daemon's private host keys. Each host key can be defined as a path relative to the configuration directory or an absolute one. If empty, the daemon will search or try to generate `id_rsa`, `id_ecdsa` and `id_ed25519` keys inside the configuration directory. If you configure absolute paths to files named `id_rsa`, `id_ecdsa` and/or `id_ed25519` then SFTPGo will try to generate these keys using the default settings.
- `host_certificates`, list of strings. Public host certificates. Each certificate can be defined as a path relative to the configuration directory or an absolute one. Certificate's public key must match a private host key otherwise it will be silently ignored. Default: empty.
- `host_key_algorithms`, list of strings. Public key algorithms that the server will accept for host key authentication. The supported values are: `rsa-sha2-512-cert-v01@openssh.com`, `rsa-sha2-256-cert-v01@openssh.com`, `ssh-rsa-cert-v01@openssh.com`, `ssh-dss-cert-v01@openssh.com`, `ecdsa-sha2-nistp256-cert-v01@openssh.com`, `ecdsa-sha2-nistp384-cert-v01@openssh.com`, `ecdsa-sha2-nistp521-cert-v01@openssh.com`, `ssh-ed25519-cert-v01@openssh.com`, `ecdsa-sha2-nistp256`, `ecdsa-sha2-nistp384`, `ecdsa-sha2-nistp521`, `rsa-sha2-512`, `rsa-sha2-256`, `ssh-rsa`, `ssh-dss`, `ssh-ed25519`. Certificate algorithms are listed for backward compatibility purposes only, they are not used. Default values: `rsa-sha2-512`, `rsa-sha2-256`, `ecdsa-sha2-nistp256`, `ecdsa-sha2-nistp384`, `ecdsa-sha2-nistp521`, `ssh-ed25519`.

View file

@ -58,7 +58,6 @@ const (
var (
globalConf globalConfig
defaultSFTPDBanner = fmt.Sprintf("SFTPGo_%v", version.Get().Version)
defaultFTPDBanner = fmt.Sprintf("SFTPGo %v ready", version.Get().Version)
defaultInstallCodeHint = "Installation code"
defaultSFTPDBinding = sftpd.Binding{
@ -255,7 +254,7 @@ func Init() {
SFTPD: sftpd.Configuration{
Bindings: []sftpd.Binding{defaultSFTPDBinding},
MaxAuthTries: 0,
Banner: defaultSFTPDBanner,
Banner: "",
HostKeys: []string{},
HostCertificates: []string{},
HostKeyAlgorithms: []string{},
@ -761,9 +760,6 @@ func isExternalAuthScopeValid() bool {
}
func resetInvalidConfigs() {
if strings.TrimSpace(globalConf.SFTPD.Banner) == "" {
globalConf.SFTPD.Banner = defaultSFTPDBanner
}
if strings.TrimSpace(globalConf.FTPD.Banner) == "" {
globalConf.FTPD.Banner = defaultFTPDBanner
}

View file

@ -141,7 +141,7 @@ func TestEmptyBanner(t *testing.T) {
err = config.LoadConfig(configDir, confName)
assert.NoError(t, err)
sftpdConf = config.GetSFTPDConfig()
assert.NotEmpty(t, strings.TrimSpace(sftpdConf.Banner))
assert.Empty(t, strings.TrimSpace(sftpdConf.Banner))
err = os.Remove(configFilePath)
assert.NoError(t, err)

View file

@ -41,6 +41,7 @@ import (
"github.com/drakkan/sftpgo/v2/internal/metric"
"github.com/drakkan/sftpgo/v2/internal/plugin"
"github.com/drakkan/sftpgo/v2/internal/util"
"github.com/drakkan/sftpgo/v2/internal/version"
"github.com/drakkan/sftpgo/v2/internal/vfs"
)
@ -233,6 +234,13 @@ func (c *Configuration) ShouldBind() bool {
return false
}
func (c *Configuration) getServerVersion() string {
if c.Banner == "short" {
return "SSH-2.0-SFTPGo"
}
return fmt.Sprintf("SSH-2.0-SFTPGo_%v", version.Get().Version)
}
func (c *Configuration) getServerConfig() *ssh.ServerConfig {
serverConfig := &ssh.ServerConfig{
NoClientAuth: false,
@ -250,7 +258,7 @@ func (c *Configuration) getServerConfig() *ssh.ServerConfig {
return sp, nil
},
ServerVersion: fmt.Sprintf("SSH-2.0-%s", c.Banner),
ServerVersion: c.getServerVersion(),
}
if c.PasswordAuthentication {