Backport #20299. Follow #20298. Only the `GlobalInitInstalled` function should prepare the SSH files for external server or starts the builtin server. * `trustedUserCaKeys` is removed, use `SSH.TrustedUserCAKeys` directly * introduce `ssh.Init`, move the SSH init code from `routers/init.go` to it * `ssh.Init` will start builtin SSH server or prepare external SSH server files
This commit is contained in:
		
							parent
							
								
									c556a83c35
								
							
						
					
					
						commit
						54ef658861
					
				| @ -843,8 +843,9 @@ func loadFromConf(allowEmpty bool, extraConfig string) { | |||||||
| 		SSH.StartBuiltinServer = false | 		SSH.StartBuiltinServer = false | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	trustedUserCaKeys := sec.Key("SSH_TRUSTED_USER_CA_KEYS").Strings(",") | 	SSH.TrustedUserCAKeysFile = sec.Key("SSH_TRUSTED_USER_CA_KEYS_FILENAME").MustString(filepath.Join(SSH.RootPath, "gitea-trusted-user-ca-keys.pem")) | ||||||
| 	for _, caKey := range trustedUserCaKeys { | 
 | ||||||
|  | 	for _, caKey := range SSH.TrustedUserCAKeys { | ||||||
| 		pubKey, _, _, _, err := gossh.ParseAuthorizedKey([]byte(caKey)) | 		pubKey, _, _, _, err := gossh.ParseAuthorizedKey([]byte(caKey)) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			log.Fatal("Failed to parse TrustedUserCaKeys: %s %v", caKey, err) | 			log.Fatal("Failed to parse TrustedUserCaKeys: %s %v", caKey, err) | ||||||
| @ -852,7 +853,7 @@ func loadFromConf(allowEmpty bool, extraConfig string) { | |||||||
| 
 | 
 | ||||||
| 		SSH.TrustedUserCAKeysParsed = append(SSH.TrustedUserCAKeysParsed, pubKey) | 		SSH.TrustedUserCAKeysParsed = append(SSH.TrustedUserCAKeysParsed, pubKey) | ||||||
| 	} | 	} | ||||||
| 	if len(trustedUserCaKeys) > 0 { | 	if len(SSH.TrustedUserCAKeys) > 0 { | ||||||
| 		// Set the default as email,username otherwise we can leave it empty
 | 		// Set the default as email,username otherwise we can leave it empty
 | ||||||
| 		sec.Key("SSH_AUTHORIZED_PRINCIPALS_ALLOW").MustString("username,email") | 		sec.Key("SSH_AUTHORIZED_PRINCIPALS_ALLOW").MustString("username,email") | ||||||
| 	} else { | 	} else { | ||||||
| @ -861,20 +862,6 @@ func loadFromConf(allowEmpty bool, extraConfig string) { | |||||||
| 
 | 
 | ||||||
| 	SSH.AuthorizedPrincipalsAllow, SSH.AuthorizedPrincipalsEnabled = parseAuthorizedPrincipalsAllow(sec.Key("SSH_AUTHORIZED_PRINCIPALS_ALLOW").Strings(",")) | 	SSH.AuthorizedPrincipalsAllow, SSH.AuthorizedPrincipalsEnabled = parseAuthorizedPrincipalsAllow(sec.Key("SSH_AUTHORIZED_PRINCIPALS_ALLOW").Strings(",")) | ||||||
| 
 | 
 | ||||||
| 	if !SSH.Disabled && !SSH.StartBuiltinServer { |  | ||||||
| 		if err = os.MkdirAll(SSH.KeyTestPath, 0o644); err != nil { |  | ||||||
| 			log.Fatal("Failed to create '%s': %v", SSH.KeyTestPath, err) |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		if len(trustedUserCaKeys) > 0 && SSH.AuthorizedPrincipalsEnabled { |  | ||||||
| 			fname := sec.Key("SSH_TRUSTED_USER_CA_KEYS_FILENAME").MustString(filepath.Join(SSH.RootPath, "gitea-trusted-user-ca-keys.pem")) |  | ||||||
| 			if err := os.WriteFile(fname, |  | ||||||
| 				[]byte(strings.Join(trustedUserCaKeys, "\n")), 0o600); err != nil { |  | ||||||
| 				log.Fatal("Failed to create '%s': %v", fname, err) |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	SSH.MinimumKeySizeCheck = sec.Key("MINIMUM_KEY_SIZE_CHECK").MustBool(SSH.MinimumKeySizeCheck) | 	SSH.MinimumKeySizeCheck = sec.Key("MINIMUM_KEY_SIZE_CHECK").MustBool(SSH.MinimumKeySizeCheck) | ||||||
| 	minimumKeySizes := Cfg.Section("ssh.minimum_key_sizes").Keys() | 	minimumKeySizes := Cfg.Section("ssh.minimum_key_sizes").Keys() | ||||||
| 	for _, key := range minimumKeySizes { | 	for _, key := range minimumKeySizes { | ||||||
|  | |||||||
							
								
								
									
										55
									
								
								modules/ssh/init.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								modules/ssh/init.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,55 @@ | |||||||
|  | // Copyright 2022 The Gitea Authors. All rights reserved.
 | ||||||
|  | // Use of this source code is governed by a MIT-style
 | ||||||
|  | // license that can be found in the LICENSE file.
 | ||||||
|  | 
 | ||||||
|  | package ssh | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | 	"net" | ||||||
|  | 	"os" | ||||||
|  | 	"path/filepath" | ||||||
|  | 	"strconv" | ||||||
|  | 	"strings" | ||||||
|  | 
 | ||||||
|  | 	"code.gitea.io/gitea/modules/log" | ||||||
|  | 	"code.gitea.io/gitea/modules/setting" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | func Init() error { | ||||||
|  | 	if setting.SSH.Disabled { | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if setting.SSH.StartBuiltinServer { | ||||||
|  | 		Listen(setting.SSH.ListenHost, setting.SSH.ListenPort, setting.SSH.ServerCiphers, setting.SSH.ServerKeyExchanges, setting.SSH.ServerMACs) | ||||||
|  | 		log.Info("SSH server started on %s. Cipher list (%v), key exchange algorithms (%v), MACs (%v)", | ||||||
|  | 			net.JoinHostPort(setting.SSH.ListenHost, strconv.Itoa(setting.SSH.ListenPort)), | ||||||
|  | 			setting.SSH.ServerCiphers, setting.SSH.ServerKeyExchanges, setting.SSH.ServerMACs, | ||||||
|  | 		) | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	builtinUnused() | ||||||
|  | 
 | ||||||
|  | 	// FIXME: why 0o644 for a directory .....
 | ||||||
|  | 	if err := os.MkdirAll(setting.SSH.KeyTestPath, 0o644); err != nil { | ||||||
|  | 		return fmt.Errorf("failed to create directory %q for ssh key test: %w", setting.SSH.KeyTestPath, err) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if len(setting.SSH.TrustedUserCAKeys) > 0 && setting.SSH.AuthorizedPrincipalsEnabled { | ||||||
|  | 		caKeysFileName := setting.SSH.TrustedUserCAKeysFile | ||||||
|  | 		caKeysFileDir := filepath.Dir(caKeysFileName) | ||||||
|  | 
 | ||||||
|  | 		err := os.MkdirAll(caKeysFileDir, 0o700) // SSH.RootPath by default (That is `~/.ssh` in most cases)
 | ||||||
|  | 		if err != nil { | ||||||
|  | 			return fmt.Errorf("failed to create directory %q for ssh trusted ca keys: %w", caKeysFileDir, err) | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if err := os.WriteFile(caKeysFileName, []byte(strings.Join(setting.SSH.TrustedUserCAKeys, "\n")), 0o600); err != nil { | ||||||
|  | 			return fmt.Errorf("failed to write ssh trusted ca keys to %q: %w", caKeysFileName, err) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
| @ -29,7 +29,7 @@ func listen(server *ssh.Server) { | |||||||
| 	log.Info("SSH Listener: %s Closed", server.Addr) | 	log.Info("SSH Listener: %s Closed", server.Addr) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Unused informs our cleanup routine that we will not be using a ssh port
 | // builtinUnused informs our cleanup routine that we will not be using a ssh port
 | ||||||
| func Unused() { | func builtinUnused() { | ||||||
| 	graceful.GetManager().InformCleanup() | 	graceful.GetManager().InformCleanup() | ||||||
| } | } | ||||||
|  | |||||||
| @ -6,10 +6,8 @@ package routers | |||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"context" | 	"context" | ||||||
| 	"net" |  | ||||||
| 	"reflect" | 	"reflect" | ||||||
| 	"runtime" | 	"runtime" | ||||||
| 	"strconv" |  | ||||||
| 
 | 
 | ||||||
| 	"code.gitea.io/gitea/models" | 	"code.gitea.io/gitea/models" | ||||||
| 	asymkey_model "code.gitea.io/gitea/models/asymkey" | 	asymkey_model "code.gitea.io/gitea/models/asymkey" | ||||||
| @ -158,14 +156,8 @@ func GlobalInitInstalled(ctx context.Context) { | |||||||
| 
 | 
 | ||||||
| 	mustInitCtx(ctx, syncAppPathForGit) | 	mustInitCtx(ctx, syncAppPathForGit) | ||||||
| 
 | 
 | ||||||
| 	if setting.SSH.StartBuiltinServer { | 	mustInit(ssh.Init) | ||||||
| 		ssh.Listen(setting.SSH.ListenHost, setting.SSH.ListenPort, setting.SSH.ServerCiphers, setting.SSH.ServerKeyExchanges, setting.SSH.ServerMACs) | 
 | ||||||
| 		log.Info("SSH server started on %s. Cipher list (%v), key exchange algorithms (%v), MACs (%v)", |  | ||||||
| 			net.JoinHostPort(setting.SSH.ListenHost, strconv.Itoa(setting.SSH.ListenPort)), |  | ||||||
| 			setting.SSH.ServerCiphers, setting.SSH.ServerKeyExchanges, setting.SSH.ServerMACs) |  | ||||||
| 	} else { |  | ||||||
| 		ssh.Unused() |  | ||||||
| 	} |  | ||||||
| 	auth.Init() | 	auth.Init() | ||||||
| 	svg.Init() | 	svg.Init() | ||||||
| } | } | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user