Compare commits

..

1 commit

6 changed files with 31 additions and 12 deletions

View file

@ -334,7 +334,7 @@ The following configuration set `Content-Type: application/vnd.android.package-a
- `SSH_USER`: **%(BUILTIN_SSH_SERVER_USER)s**: SSH username displayed in clone URLs. This is only for people who configure the SSH server themselves; in most cases, you want to leave this blank and modify the `BUILTIN_SSH_SERVER_USER`. - `SSH_USER`: **%(BUILTIN_SSH_SERVER_USER)s**: SSH username displayed in clone URLs. This is only for people who configure the SSH server themselves; in most cases, you want to leave this blank and modify the `BUILTIN_SSH_SERVER_USER`.
- `SSH_DOMAIN`: **%(DOMAIN)s**: Domain name of this server, used for displayed clone URL. - `SSH_DOMAIN`: **%(DOMAIN)s**: Domain name of this server, used for displayed clone URL.
- `SSH_PORT`: **22**: SSH port displayed in clone URL. - `SSH_PORT`: **22**: SSH port displayed in clone URL.
- `SSH_LISTEN_HOST`: **0.0.0.0**: Listen address for the built-in SSH server. - `SSH_LISTEN_HOST`: **0.0.0.0**: Listen address(es) for the built-in SSH server; multiple addresses can be separated by comma, addresses can include a port statement to override SSH_LISTEN_PORT.
- `SSH_LISTEN_PORT`: **%(SSH\_PORT)s**: Port for the built-in SSH server. - `SSH_LISTEN_PORT`: **%(SSH\_PORT)s**: Port for the built-in SSH server.
- `SSH_ROOT_PATH`: **~/.ssh**: Root path of SSH directory. - `SSH_ROOT_PATH`: **~/.ssh**: Root path of SSH directory.
- `SSH_CREATE_AUTHORIZED_KEYS_FILE`: **true**: Gitea will create a authorized_keys file by default when it is not using the internal ssh server. If you intend to use the AuthorizedKeysCommand functionality then you should turn this off. - `SSH_CREATE_AUTHORIZED_KEYS_FILE`: **true**: Gitea will create a authorized_keys file by default when it is not using the internal ssh server. If you intend to use the AuthorizedKeysCommand functionality then you should turn this off.

View file

@ -239,6 +239,12 @@ func (g *Manager) InformCleanup() {
g.createServerCond.Signal() g.createServerCond.Signal()
} }
// Should we need to create multile listener for one type (e.g. SSH built-in server),
// the number of expected routines needs to be increased accordingly.
func (g *Manager) IncreaseListenerCountBy(extraNumberOfServersToCreate int) {
g.createServerWaitGroup.Add(extraNumberOfServersToCreate)
}
// Done allows the manager to be viewed as a context.Context, it returns a channel that is closed when the server is finished terminating // Done allows the manager to be viewed as a context.Context, it returns a channel that is closed when the server is finished terminating
func (g *Manager) Done() <-chan struct{} { func (g *Manager) Done() <-chan struct{} {
return g.managerCtx.Done() return g.managerCtx.Done()

View file

@ -25,7 +25,7 @@ var SSH = struct {
Domain string `ini:"SSH_DOMAIN"` Domain string `ini:"SSH_DOMAIN"`
Port int `ini:"SSH_PORT"` Port int `ini:"SSH_PORT"`
User string `ini:"SSH_USER"` User string `ini:"SSH_USER"`
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"`
@ -54,6 +54,7 @@ var SSH = struct {
Disabled: false, Disabled: false,
StartBuiltinServer: false, StartBuiltinServer: false,
Domain: "", Domain: "",
ListenHost: []string{"0.0.0.0"},
Port: 22, Port: 22,
ServerCiphers: []string{"chacha20-poly1305@openssh.com", "aes128-ctr", "aes192-ctr", "aes256-ctr", "aes128-gcm@openssh.com", "aes256-gcm@openssh.com"}, ServerCiphers: []string{"chacha20-poly1305@openssh.com", "aes128-ctr", "aes192-ctr", "aes256-ctr", "aes128-gcm@openssh.com", "aes256-gcm@openssh.com"},
ServerKeyExchanges: []string{"curve25519-sha256", "ecdh-sha2-nistp256", "ecdh-sha2-nistp384", "ecdh-sha2-nistp521", "diffie-hellman-group14-sha256", "diffie-hellman-group14-sha1"}, ServerKeyExchanges: []string{"curve25519-sha256", "ecdh-sha2-nistp256", "ecdh-sha2-nistp384", "ecdh-sha2-nistp521", "diffie-hellman-group14-sha256", "diffie-hellman-group14-sha1"},

View file

@ -11,6 +11,7 @@ import (
"strconv" "strconv"
"strings" "strings"
"code.gitea.io/gitea/modules/graceful"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
) )
@ -22,12 +23,23 @@ func Init() error {
} }
if setting.SSH.StartBuiltinServer { if setting.SSH.StartBuiltinServer {
Listen(setting.SSH.ListenHost, setting.SSH.ListenPort, setting.SSH.ServerCiphers, setting.SSH.ServerKeyExchanges, setting.SSH.ServerMACs) if len(setting.SSH.ListenHost) > 1 {
graceful.GetManager().IncreaseListenerCountBy(len(setting.SSH.ListenHost) - 1)
}
for _, listenHost := range setting.SSH.ListenHost {
var addr string
if _, _, err := net.SplitHostPort(listenHost); err == nil {
addr = listenHost
} else {
addr = net.JoinHostPort(listenHost, strconv.Itoa(setting.SSH.ListenPort))
}
Listen(addr, 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)", 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)), addr, setting.SSH.ServerCiphers, setting.SSH.ServerKeyExchanges, setting.SSH.ServerMACs,
setting.SSH.ServerCiphers, setting.SSH.ServerKeyExchanges, setting.SSH.ServerMACs,
) )
}
return nil return nil
} }
builtinUnused() builtinUnused()

View file

@ -17,7 +17,7 @@ import (
"os" "os"
"os/exec" "os/exec"
"path/filepath" "path/filepath"
"strconv" "reflect"
"strings" "strings"
"sync" "sync"
"syscall" "syscall"
@ -280,10 +280,10 @@ func sshConnectionFailed(conn net.Conn, err error) {
log.Warn("Failed authentication attempt from %s", conn.RemoteAddr()) log.Warn("Failed authentication attempt from %s", conn.RemoteAddr())
} }
// Listen starts a SSH server listens on given port. // Listen starts a SSH server listens on given addr (host, port combination).
func Listen(host string, port int, ciphers, keyExchanges, macs []string) { func Listen(addr string, ciphers, keyExchanges, macs []string) {
srv := ssh.Server{ srv := ssh.Server{
Addr: net.JoinHostPort(host, strconv.Itoa(port)), Addr: addr,
PublicKeyHandler: publicKeyHandler, PublicKeyHandler: publicKeyHandler,
Handler: sessionHandler, Handler: sessionHandler,
ServerConfigCallback: func(ctx ssh.Context) *gossh.ServerConfig { ServerConfigCallback: func(ctx ssh.Context) *gossh.ServerConfig {

View file

@ -52,7 +52,7 @@ func createSSHUrl(gitPath string, u *url.URL) *url.URL {
u2 := *u u2 := *u
u2.Scheme = "ssh" u2.Scheme = "ssh"
u2.User = url.User("git") u2.User = url.User("git")
u2.Host = net.JoinHostPort(setting.SSH.ListenHost, strconv.Itoa(setting.SSH.ListenPort)) u2.Host = net.JoinHostPort(setting.SSH.ListenHost[0], strconv.Itoa(setting.SSH.ListenPort))
u2.Path = gitPath u2.Path = gitPath
return &u2 return &u2
} }