Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Autodetermine if work-path needs to be specified in SSH authorized_keys #23301

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions docs/content/doc/administration/config-cheat-sheet.en-us.md
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,9 @@ The following configuration set `Content-Type: application/vnd.android.package-a
- `SSH_CREATE_AUTHORIZED_PRINCIPALS_FILE`: **false/true**: Gitea will create a authorized_principals file by default when it is not using the internal ssh server and `SSH_AUTHORIZED_PRINCIPALS_ALLOW` is not `off`.
- `SSH_AUTHORIZED_PRINCIPALS_BACKUP`: **false/true**: Enable SSH Authorized Principals Backup when rewriting all keys, default is true if `SSH_AUTHORIZED_PRINCIPALS_ALLOW` is not `off`.
- `SSH_AUTHORIZED_KEYS_COMMAND_TEMPLATE`: **{{.AppPath}} --config={{.CustomConf}} serv key-{{.Key.ID}}**: Set the template for the command to passed on authorized keys. Possible keys are: AppPath, AppWorkPath, CustomConf, CustomPath, Key - where Key is a `models/asymkey.PublicKey` and the others are strings which are shellquoted.
- Gitea will add `--work-path={{.AppWorkPath}}` to the default template
if it determines that this is needed, however, you may need to add this explicitly
to any non-default template if your `APP_DATA_PATH` is not an absolute path.
- `SSH_SERVER_CIPHERS`: **[email protected], aes128-ctr, aes192-ctr, aes256-ctr, [email protected], [email protected]**: For the built-in SSH server, choose the ciphers to support for SSH connections, for system SSH this setting has no effect.
- `SSH_SERVER_KEY_EXCHANGES`: **curve25519-sha256, ecdh-sha2-nistp256, ecdh-sha2-nistp384, ecdh-sha2-nistp521, diffie-hellman-group14-sha256, diffie-hellman-group14-sha1**: For the built-in SSH server, choose the key exchange algorithms to support for SSH connections, for system SSH this setting has no effect.
- `SSH_SERVER_MACS`: **[email protected], hmac-sha2-256, hmac-sha1**: For the built-in SSH server, choose the MACs to support for SSH connections, for system SSH this setting has no effect
Expand Down
11 changes: 9 additions & 2 deletions modules/setting/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ var (
AppSubURL string
// AppDataPath is the default path for storing data.
// It maps to ini:"APP_DATA_PATH" in [server] and defaults to AppWorkPath + "/data"
AppDataPath string
AppDataPath string
AppDataPathDependentOnWorkPath bool // This is a helper marker used to inform if the AppDataPath is dependent on a user-provided or auto-determined work path
// LocalURL is the url for locally running applications to contact Gitea. It always has a '/' suffix
// It maps to ini:"LOCAL_ROOT_URL" in [server]
LocalURL string
Expand Down Expand Up @@ -323,8 +324,14 @@ func loadServerFrom(rootCfg ConfigProvider) {
}
StaticRootPath = sec.Key("STATIC_ROOT_PATH").MustString(StaticRootPath)
StaticCacheTime = sec.Key("STATIC_CACHE_TIME").MustDuration(6 * time.Hour)
AppDataPath = sec.Key("APP_DATA_PATH").MustString(path.Join(AppWorkPath, "data"))
AppDataPathDependentOnWorkPath = false
AppDataPath = sec.Key("APP_DATA_PATH").MustString("")
if AppDataPath == "" {
AppDataPath = path.Join(AppWorkPath, "data")
AppDataPathDependentOnWorkPath = appWorkPathIsNotDefault
}
if !filepath.IsAbs(AppDataPath) {
AppDataPathDependentOnWorkPath = appWorkPathIsNotDefault
log.Info("The provided APP_DATA_PATH: %s is not absolute - it will be made absolute against the work path: %s", AppDataPath, AppWorkPath)
AppDataPath = filepath.ToSlash(filepath.Join(AppWorkPath, AppDataPath))
}
Expand Down
14 changes: 10 additions & 4 deletions modules/setting/setting.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ var (
// If that is not set it is the default set here by the linker or failing that the directory of AppPath.
//
// AppWorkPath is used as the base path for several other paths.
AppWorkPath string
AppWorkPath string
appWorkPathIsNotDefault bool

// Other global setting objects

Expand Down Expand Up @@ -80,8 +81,8 @@ func getAppPath() (string, error) {

func getWorkPath(appPath string) string {
workPath := AppWorkPath

if giteaWorkPath, ok := os.LookupEnv("GITEA_WORK_DIR"); ok {
appWorkPathIsNotDefault = true
workPath = giteaWorkPath
}
if len(workPath) == 0 {
Expand All @@ -94,6 +95,7 @@ func getWorkPath(appPath string) string {
}
workPath = strings.ReplaceAll(workPath, "\\", "/")
if !filepath.IsAbs(workPath) {
appWorkPathIsNotDefault = true
log.Info("Provided work path %s is not absolute - will be made absolute against the current working directory", workPath)

absPath, err := filepath.Abs(workPath)
Expand Down Expand Up @@ -145,10 +147,14 @@ func IsRunUserMatchCurrentUser(runUser string) (string, bool) {

// SetCustomPathAndConf will set CustomPath and CustomConf with reference to the
// GITEA_CUSTOM environment variable and with provided overrides before stepping
// back to the default
// back to the defaultAppWorkPath =
func SetCustomPathAndConf(providedCustom, providedConf, providedWorkPath string) {
if len(providedWorkPath) != 0 {
AppWorkPath = filepath.ToSlash(providedWorkPath)
providedWorkPath = filepath.ToSlash(providedWorkPath)
if providedWorkPath != AppWorkPath {
appWorkPathIsNotDefault = true
AppWorkPath = providedWorkPath
}
}
if giteaCustom, ok := os.LookupEnv("GITEA_CUSTOM"); ok {
CustomPath = giteaCustom
Expand Down
37 changes: 22 additions & 15 deletions modules/setting/ssh.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ var SSH = struct {
AuthorizedKeysBackup bool `ini:"SSH_AUTHORIZED_KEYS_BACKUP"`
AuthorizedPrincipalsBackup bool `ini:"SSH_AUTHORIZED_PRINCIPALS_BACKUP"`
AuthorizedKeysCommandTemplate string `ini:"SSH_AUTHORIZED_KEYS_COMMAND_TEMPLATE"`
AuthorizedKeysCommandWorkPathTemplate string `ini:"-"`
AuthorizedKeysCommandTemplateTemplate *template.Template `ini:"-"`
MinimumKeySizeCheck bool `ini:"-"`
MinimumKeySizes map[string]int `ini:"-"`
Expand All @@ -51,20 +52,21 @@ var SSH = struct {
PerWriteTimeout time.Duration `ini:"SSH_PER_WRITE_TIMEOUT"`
PerWritePerKbTimeout time.Duration `ini:"SSH_PER_WRITE_PER_KB_TIMEOUT"`
}{
Disabled: false,
StartBuiltinServer: false,
Domain: "",
Port: 22,
ServerCiphers: []string{"[email protected]", "aes128-ctr", "aes192-ctr", "aes256-ctr", "[email protected]", "[email protected]"},
ServerKeyExchanges: []string{"curve25519-sha256", "ecdh-sha2-nistp256", "ecdh-sha2-nistp384", "ecdh-sha2-nistp521", "diffie-hellman-group14-sha256", "diffie-hellman-group14-sha1"},
ServerMACs: []string{"[email protected]", "hmac-sha2-256", "hmac-sha1"},
KeygenPath: "",
MinimumKeySizeCheck: true,
MinimumKeySizes: map[string]int{"ed25519": 256, "ed25519-sk": 256, "ecdsa": 256, "ecdsa-sk": 256, "rsa": 2047},
ServerHostKeys: []string{"ssh/gitea.rsa", "ssh/gogs.rsa"},
AuthorizedKeysCommandTemplate: "{{.AppPath}} --config={{.CustomConf}} serv key-{{.Key.ID}}",
PerWriteTimeout: PerWriteTimeout,
PerWritePerKbTimeout: PerWritePerKbTimeout,
Disabled: false,
StartBuiltinServer: false,
Domain: "",
Port: 22,
ServerCiphers: []string{"[email protected]", "aes128-ctr", "aes192-ctr", "aes256-ctr", "[email protected]", "[email protected]"},
ServerKeyExchanges: []string{"curve25519-sha256", "ecdh-sha2-nistp256", "ecdh-sha2-nistp384", "ecdh-sha2-nistp521", "diffie-hellman-group14-sha256", "diffie-hellman-group14-sha1"},
ServerMACs: []string{"[email protected]", "hmac-sha2-256", "hmac-sha1"},
KeygenPath: "",
MinimumKeySizeCheck: true,
MinimumKeySizes: map[string]int{"ed25519": 256, "ed25519-sk": 256, "ecdsa": 256, "ecdsa-sk": 256, "rsa": 2047},
ServerHostKeys: []string{"ssh/gitea.rsa", "ssh/gogs.rsa"},
AuthorizedKeysCommandTemplate: "{{.AppPath}} --config={{.CustomConf}} serv key-{{.Key.ID}}",
AuthorizedKeysCommandWorkPathTemplate: "{{.AppPath}} --config={{.CustomConf}} --work-path={{.AppWorkPath}} serv key-{{.Key.ID}}",
PerWriteTimeout: PerWriteTimeout,
PerWritePerKbTimeout: PerWritePerKbTimeout,
}

func parseAuthorizedPrincipalsAllow(values []string) ([]string, bool) {
Expand Down Expand Up @@ -184,7 +186,12 @@ func loadSSHFrom(rootCfg ConfigProvider) {
}

SSH.ExposeAnonymous = sec.Key("SSH_EXPOSE_ANONYMOUS").MustBool(false)
SSH.AuthorizedKeysCommandTemplate = sec.Key("SSH_AUTHORIZED_KEYS_COMMAND_TEMPLATE").MustString(SSH.AuthorizedKeysCommandTemplate)
// Now if the AppData path is dependent on the work path we need to set a different default Template
if AppDataPathDependentOnWorkPath {
SSH.AuthorizedKeysCommandTemplate = sec.Key("SSH_AUTHORIZED_KEYS_COMMAND_TEMPLATE").MustString(SSH.AuthorizedKeysCommandWorkPathTemplate)
} else {
SSH.AuthorizedKeysCommandTemplate = sec.Key("SSH_AUTHORIZED_KEYS_COMMAND_TEMPLATE").MustString(SSH.AuthorizedKeysCommandTemplate)
}

SSH.AuthorizedKeysCommandTemplateTemplate = template.Must(template.New("").Parse(SSH.AuthorizedKeysCommandTemplate))

Expand Down