From eecaba20310483f64e0e4500fa3ac85e23ced18e Mon Sep 17 00:00:00 2001 From: Cum Gun Date: Thu, 2 Nov 2017 16:26:41 +0100 Subject: [PATCH] Configurable SSH key exchange algorithm and MAC suite (#2806) --- conf/app.ini | 6 ++++++ modules/setting/setting.go | 12 ++++++++++++ modules/ssh/ssh.go | 6 ++++-- routers/init.go | 4 ++-- 4 files changed, 24 insertions(+), 4 deletions(-) diff --git a/conf/app.ini b/conf/app.ini index 491f38164bd..07c60ea0a9f 100644 --- a/conf/app.ini +++ b/conf/app.ini @@ -128,6 +128,12 @@ SSH_ROOT_PATH = ; For built-in SSH server only, choose the ciphers to support for SSH connections, ; for system SSH this setting has no effect SSH_SERVER_CIPHERS = aes128-ctr, aes192-ctr, aes256-ctr, aes128-gcm@openssh.com, arcfour256, arcfour128 +; For built-in SSH server only, choose the key exchange algorithms to support for SSH connections, +; for system SSH this setting has no effect +SSH_SERVER_KEY_EXCHANGES = diffie-hellman-group1-sha1, diffie-hellman-group14-sha1, ecdh-sha2-nistp256, ecdh-sha2-nistp384, ecdh-sha2-nistp521, curve25519-sha256@libssh.org +; For built-in SSH server only, choose the MACs to support for SSH connections, +; for system SSH this setting has no effect +SSH_SERVER_MACS = hmac-sha2-256-etm@openssh.com, hmac-sha2-256, hmac-sha1, hmac-sha1-96 ; Directory to create temporary files when test public key using ssh-keygen, ; default is system temporary directory. SSH_KEY_TEST_PATH = diff --git a/modules/setting/setting.go b/modules/setting/setting.go index a1106132dfd..3b9aff44e25 100644 --- a/modules/setting/setting.go +++ b/modules/setting/setting.go @@ -98,6 +98,8 @@ var ( ListenPort int `ini:"SSH_LISTEN_PORT"` RootPath string `ini:"SSH_ROOT_PATH"` ServerCiphers []string `ini:"SSH_SERVER_CIPHERS"` + ServerKeyExchanges []string `ini:"SSH_SERVER_KEY_EXCHANGES"` + ServerMACs []string `ini:"SSH_SERVER_MACS"` KeyTestPath string `ini:"SSH_KEY_TEST_PATH"` KeygenPath string `ini:"SSH_KEYGEN_PATH"` AuthorizedKeysBackup bool `ini:"SSH_AUTHORIZED_KEYS_BACKUP"` @@ -110,6 +112,8 @@ var ( Domain: "", Port: 22, ServerCiphers: []string{"aes128-ctr", "aes192-ctr", "aes256-ctr", "aes128-gcm@openssh.com", "arcfour256", "arcfour128"}, + ServerKeyExchanges: []string{"diffie-hellman-group1-sha1", "diffie-hellman-group14-sha1", "ecdh-sha2-nistp256", "ecdh-sha2-nistp384", "ecdh-sha2-nistp521", "curve25519-sha256@libssh.org"}, + ServerMACs: []string{"hmac-sha2-256-etm@openssh.com", "hmac-sha2-256", "hmac-sha1", "hmac-sha1-96"}, KeygenPath: "ssh-keygen", } @@ -732,6 +736,14 @@ func NewContext() { if len(serverCiphers) > 0 { SSH.ServerCiphers = serverCiphers } + serverKeyExchanges := sec.Key("SSH_SERVER_KEY_EXCHANGES").Strings(",") + if len(serverKeyExchanges) > 0 { + SSH.ServerKeyExchanges = serverKeyExchanges + } + serverMACs := sec.Key("SSH_SERVER_MACS").Strings(",") + if len(serverMACs) > 0 { + SSH.ServerMACs = serverMACs + } SSH.KeyTestPath = os.TempDir() if err = Cfg.Section("server").MapTo(&SSH); err != nil { log.Fatal(4, "Failed to map SSH settings: %v", err) diff --git a/modules/ssh/ssh.go b/modules/ssh/ssh.go index 62edaf15bc6..aea46daad4c 100644 --- a/modules/ssh/ssh.go +++ b/modules/ssh/ssh.go @@ -151,10 +151,12 @@ func listen(config *ssh.ServerConfig, host string, port int) { } // Listen starts a SSH server listens on given port. -func Listen(host string, port int, ciphers []string) { +func Listen(host string, port int, ciphers []string, keyExchanges []string, macs []string) { config := &ssh.ServerConfig{ Config: ssh.Config{ - Ciphers: ciphers, + Ciphers: ciphers, + KeyExchanges: keyExchanges, + MACs: macs, }, PublicKeyCallback: func(conn ssh.ConnMetadata, key ssh.PublicKey) (*ssh.Permissions, error) { pkey, err := models.SearchPublicKeyByContent(strings.TrimSpace(string(ssh.MarshalAuthorizedKey(key)))) diff --git a/routers/init.go b/routers/init.go index d0d455ea574..18a6d03d08e 100644 --- a/routers/init.go +++ b/routers/init.go @@ -81,7 +81,7 @@ func GlobalInit() { checkRunMode() if setting.InstallLock && setting.SSH.StartBuiltinServer { - ssh.Listen(setting.SSH.ListenHost, setting.SSH.ListenPort, setting.SSH.ServerCiphers) - log.Info("SSH server started on %s:%d. Cipher list (%v)", setting.SSH.ListenHost, setting.SSH.ListenPort, setting.SSH.ServerCiphers) + ssh.Listen(setting.SSH.ListenHost, setting.SSH.ListenPort, setting.SSH.ServerCiphers, setting.SSH.ServerKeyExchanges, setting.SSH.ServerMACs) + log.Info("SSH server started on %s:%d. Cipher list (%v), key exchange algorithms (%v), MACs (%v)", setting.SSH.ListenHost, setting.SSH.ListenPort, setting.SSH.ServerCiphers, setting.SSH.ServerKeyExchanges, setting.SSH.ServerMACs) } }