Make command in authorized keys a template (#16003)
Fix #15595 Replaces #15978 Signed-off-by: Andrew Thornton <art27@cantab.net> Co-authored-by: techknowlogick <techknowlogick@gitea.io>
This commit is contained in:
parent
ebf253b841
commit
95352e6bd5
3 changed files with 60 additions and 43 deletions
|
@ -270,6 +270,7 @@ The following configuration set `Content-Type: application/vnd.android.package-a
|
||||||
- `SSH_AUTHORIZED_PRINCIPALS_ALLOW`: **off** or **username, email**: \[off, username, email, anything\]: Specify the principals values that users are allowed to use as principal. When set to `anything` no checks are done on the principal string. When set to `off` authorized principal are not allowed to be set.
|
- `SSH_AUTHORIZED_PRINCIPALS_ALLOW`: **off** or **username, email**: \[off, username, email, anything\]: Specify the principals values that users are allowed to use as principal. When set to `anything` no checks are done on the principal string. When set to `off` authorized principal are not allowed to be set.
|
||||||
- `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_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_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.PublicKey` and the others are strings which are shellquoted.
|
||||||
- `SSH_SERVER_CIPHERS`: **aes128-ctr, aes192-ctr, aes256-ctr, aes128-gcm@openssh.com, arcfour256, arcfour128**: For the built-in SSH server, 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 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`: **diffie-hellman-group1-sha1, diffie-hellman-group14-sha1, ecdh-sha2-nistp256, ecdh-sha2-nistp384, ecdh-sha2-nistp521, curve25519-sha256@libssh.org**: 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_KEY_EXCHANGES`: **diffie-hellman-group1-sha1, diffie-hellman-group14-sha1, ecdh-sha2-nistp256, ecdh-sha2-nistp384, ecdh-sha2-nistp521, curve25519-sha256@libssh.org**: 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`: **hmac-sha2-256-etm@openssh.com, hmac-sha2-256, hmac-sha1, hmac-sha1-96**: For the built-in SSH server, 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**: For the built-in SSH server, choose the MACs to support for SSH connections, for system SSH this setting has no effect
|
||||||
|
|
|
@ -38,7 +38,6 @@ import (
|
||||||
|
|
||||||
const (
|
const (
|
||||||
tplCommentPrefix = `# gitea public key`
|
tplCommentPrefix = `# gitea public key`
|
||||||
tplCommand = "%s --config=%s serv key-%d"
|
|
||||||
tplPublicKey = tplCommentPrefix + "\n" + `command=%s,no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty %s` + "\n"
|
tplPublicKey = tplCommentPrefix + "\n" + `command=%s,no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty %s` + "\n"
|
||||||
|
|
||||||
authorizedPrincipalsFile = "authorized_principals"
|
authorizedPrincipalsFile = "authorized_principals"
|
||||||
|
@ -88,7 +87,16 @@ func (key *PublicKey) OmitEmail() string {
|
||||||
|
|
||||||
// AuthorizedString returns formatted public key string for authorized_keys file.
|
// AuthorizedString returns formatted public key string for authorized_keys file.
|
||||||
func (key *PublicKey) AuthorizedString() string {
|
func (key *PublicKey) AuthorizedString() string {
|
||||||
return fmt.Sprintf(tplPublicKey, util.ShellEscape(fmt.Sprintf(tplCommand, util.ShellEscape(setting.AppPath), util.ShellEscape(setting.CustomConf), key.ID)), key.Content)
|
sb := &strings.Builder{}
|
||||||
|
_ = setting.SSH.AuthorizedKeysCommandTemplateTemplate.Execute(sb, map[string]interface{}{
|
||||||
|
"AppPath": util.ShellEscape(setting.AppPath),
|
||||||
|
"AppWorkPath": util.ShellEscape(setting.AppWorkPath),
|
||||||
|
"CustomConf": util.ShellEscape(setting.CustomConf),
|
||||||
|
"CustomPath": util.ShellEscape(setting.CustomPath),
|
||||||
|
"Key": key,
|
||||||
|
})
|
||||||
|
|
||||||
|
return fmt.Sprintf(tplPublicKey, util.ShellEscape(sb.String()), key.Content)
|
||||||
}
|
}
|
||||||
|
|
||||||
func extractTypeFromBase64Key(key string) (string, error) {
|
func extractTypeFromBase64Key(key string) (string, error) {
|
||||||
|
|
|
@ -20,6 +20,7 @@ import (
|
||||||
"runtime"
|
"runtime"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"text/template"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"code.gitea.io/gitea/modules/generate"
|
"code.gitea.io/gitea/modules/generate"
|
||||||
|
@ -123,48 +124,51 @@ var (
|
||||||
AbsoluteAssetURL string
|
AbsoluteAssetURL string
|
||||||
|
|
||||||
SSH = struct {
|
SSH = struct {
|
||||||
Disabled bool `ini:"DISABLE_SSH"`
|
Disabled bool `ini:"DISABLE_SSH"`
|
||||||
StartBuiltinServer bool `ini:"START_SSH_SERVER"`
|
StartBuiltinServer bool `ini:"START_SSH_SERVER"`
|
||||||
BuiltinServerUser string `ini:"BUILTIN_SSH_SERVER_USER"`
|
BuiltinServerUser string `ini:"BUILTIN_SSH_SERVER_USER"`
|
||||||
Domain string `ini:"SSH_DOMAIN"`
|
Domain string `ini:"SSH_DOMAIN"`
|
||||||
Port int `ini:"SSH_PORT"`
|
Port int `ini:"SSH_PORT"`
|
||||||
ListenHost string `ini:"SSH_LISTEN_HOST"`
|
ListenHost string `ini:"SSH_LISTEN_HOST"`
|
||||||
ListenPort int `ini:"SSH_LISTEN_PORT"`
|
ListenPort int `ini:"SSH_LISTEN_PORT"`
|
||||||
RootPath string `ini:"SSH_ROOT_PATH"`
|
RootPath string `ini:"SSH_ROOT_PATH"`
|
||||||
ServerCiphers []string `ini:"SSH_SERVER_CIPHERS"`
|
ServerCiphers []string `ini:"SSH_SERVER_CIPHERS"`
|
||||||
ServerKeyExchanges []string `ini:"SSH_SERVER_KEY_EXCHANGES"`
|
ServerKeyExchanges []string `ini:"SSH_SERVER_KEY_EXCHANGES"`
|
||||||
ServerMACs []string `ini:"SSH_SERVER_MACS"`
|
ServerMACs []string `ini:"SSH_SERVER_MACS"`
|
||||||
ServerHostKeys []string `ini:"SSH_SERVER_HOST_KEYS"`
|
ServerHostKeys []string `ini:"SSH_SERVER_HOST_KEYS"`
|
||||||
KeyTestPath string `ini:"SSH_KEY_TEST_PATH"`
|
KeyTestPath string `ini:"SSH_KEY_TEST_PATH"`
|
||||||
KeygenPath string `ini:"SSH_KEYGEN_PATH"`
|
KeygenPath string `ini:"SSH_KEYGEN_PATH"`
|
||||||
AuthorizedKeysBackup bool `ini:"SSH_AUTHORIZED_KEYS_BACKUP"`
|
AuthorizedKeysBackup bool `ini:"SSH_AUTHORIZED_KEYS_BACKUP"`
|
||||||
AuthorizedPrincipalsBackup bool `ini:"SSH_AUTHORIZED_PRINCIPALS_BACKUP"`
|
AuthorizedPrincipalsBackup bool `ini:"SSH_AUTHORIZED_PRINCIPALS_BACKUP"`
|
||||||
MinimumKeySizeCheck bool `ini:"-"`
|
AuthorizedKeysCommandTemplate string `ini:"SSH_AUTHORIZED_KEYS_COMMAND_TEMPLATE"`
|
||||||
MinimumKeySizes map[string]int `ini:"-"`
|
AuthorizedKeysCommandTemplateTemplate *template.Template `ini:"-"`
|
||||||
CreateAuthorizedKeysFile bool `ini:"SSH_CREATE_AUTHORIZED_KEYS_FILE"`
|
MinimumKeySizeCheck bool `ini:"-"`
|
||||||
CreateAuthorizedPrincipalsFile bool `ini:"SSH_CREATE_AUTHORIZED_PRINCIPALS_FILE"`
|
MinimumKeySizes map[string]int `ini:"-"`
|
||||||
ExposeAnonymous bool `ini:"SSH_EXPOSE_ANONYMOUS"`
|
CreateAuthorizedKeysFile bool `ini:"SSH_CREATE_AUTHORIZED_KEYS_FILE"`
|
||||||
AuthorizedPrincipalsAllow []string `ini:"SSH_AUTHORIZED_PRINCIPALS_ALLOW"`
|
CreateAuthorizedPrincipalsFile bool `ini:"SSH_CREATE_AUTHORIZED_PRINCIPALS_FILE"`
|
||||||
AuthorizedPrincipalsEnabled bool `ini:"-"`
|
ExposeAnonymous bool `ini:"SSH_EXPOSE_ANONYMOUS"`
|
||||||
TrustedUserCAKeys []string `ini:"SSH_TRUSTED_USER_CA_KEYS"`
|
AuthorizedPrincipalsAllow []string `ini:"SSH_AUTHORIZED_PRINCIPALS_ALLOW"`
|
||||||
TrustedUserCAKeysFile string `ini:"SSH_TRUSTED_USER_CA_KEYS_FILENAME"`
|
AuthorizedPrincipalsEnabled bool `ini:"-"`
|
||||||
TrustedUserCAKeysParsed []gossh.PublicKey `ini:"-"`
|
TrustedUserCAKeys []string `ini:"SSH_TRUSTED_USER_CA_KEYS"`
|
||||||
PerWriteTimeout time.Duration `ini:"SSH_PER_WRITE_TIMEOUT"`
|
TrustedUserCAKeysFile string `ini:"SSH_TRUSTED_USER_CA_KEYS_FILENAME"`
|
||||||
PerWritePerKbTimeout time.Duration `ini:"SSH_PER_WRITE_PER_KB_TIMEOUT"`
|
TrustedUserCAKeysParsed []gossh.PublicKey `ini:"-"`
|
||||||
|
PerWriteTimeout time.Duration `ini:"SSH_PER_WRITE_TIMEOUT"`
|
||||||
|
PerWritePerKbTimeout time.Duration `ini:"SSH_PER_WRITE_PER_KB_TIMEOUT"`
|
||||||
}{
|
}{
|
||||||
Disabled: false,
|
Disabled: false,
|
||||||
StartBuiltinServer: false,
|
StartBuiltinServer: false,
|
||||||
Domain: "",
|
Domain: "",
|
||||||
Port: 22,
|
Port: 22,
|
||||||
ServerCiphers: []string{"aes128-ctr", "aes192-ctr", "aes256-ctr", "aes128-gcm@openssh.com", "arcfour256", "arcfour128"},
|
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"},
|
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"},
|
ServerMACs: []string{"hmac-sha2-256-etm@openssh.com", "hmac-sha2-256", "hmac-sha1", "hmac-sha1-96"},
|
||||||
KeygenPath: "ssh-keygen",
|
KeygenPath: "ssh-keygen",
|
||||||
MinimumKeySizeCheck: true,
|
MinimumKeySizeCheck: true,
|
||||||
MinimumKeySizes: map[string]int{"ed25519": 256, "ed25519-sk": 256, "ecdsa": 256, "ecdsa-sk": 256, "rsa": 2048},
|
MinimumKeySizes: map[string]int{"ed25519": 256, "ed25519-sk": 256, "ecdsa": 256, "ecdsa-sk": 256, "rsa": 2048},
|
||||||
ServerHostKeys: []string{"ssh/gitea.rsa", "ssh/gogs.rsa"},
|
ServerHostKeys: []string{"ssh/gitea.rsa", "ssh/gogs.rsa"},
|
||||||
PerWriteTimeout: PerWriteTimeout,
|
AuthorizedKeysCommandTemplate: "{{.AppPath}} --config={{.CustomConf}} serv key-{{.Key.ID}}",
|
||||||
PerWritePerKbTimeout: PerWritePerKbTimeout,
|
PerWriteTimeout: PerWriteTimeout,
|
||||||
|
PerWritePerKbTimeout: PerWritePerKbTimeout,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Security settings
|
// Security settings
|
||||||
|
@ -785,6 +789,10 @@ func NewContext() {
|
||||||
}
|
}
|
||||||
|
|
||||||
SSH.ExposeAnonymous = sec.Key("SSH_EXPOSE_ANONYMOUS").MustBool(false)
|
SSH.ExposeAnonymous = sec.Key("SSH_EXPOSE_ANONYMOUS").MustBool(false)
|
||||||
|
SSH.AuthorizedKeysCommandTemplate = sec.Key("SSH_AUTHORIZED_KEYS_COMMAND_TEMPLATE").MustString(SSH.AuthorizedKeysCommandTemplate)
|
||||||
|
|
||||||
|
SSH.AuthorizedKeysCommandTemplateTemplate = template.Must(template.New("").Parse(SSH.AuthorizedKeysCommandTemplate))
|
||||||
|
|
||||||
SSH.PerWriteTimeout = sec.Key("SSH_PER_WRITE_TIMEOUT").MustDuration(PerWriteTimeout)
|
SSH.PerWriteTimeout = sec.Key("SSH_PER_WRITE_TIMEOUT").MustDuration(PerWriteTimeout)
|
||||||
SSH.PerWritePerKbTimeout = sec.Key("SSH_PER_WRITE_PER_KB_TIMEOUT").MustDuration(PerWritePerKbTimeout)
|
SSH.PerWritePerKbTimeout = sec.Key("SSH_PER_WRITE_PER_KB_TIMEOUT").MustDuration(PerWritePerKbTimeout)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue