Make internal SSH server host key path configurable (#14918)

* Make SSH server host key path configurable

* make it possible to have multiple keys

* Make gitea.rsa the default key

* Add some more logging

Signed-off-by: Andrew Thornton <art27@cantab.net>
This commit is contained in:
zeripath 2021-03-08 02:43:59 +00:00 committed by GitHub
parent 78b7529cd4
commit c03f530212
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 62 additions and 40 deletions

View file

@ -48,11 +48,11 @@ type Server struct {
}
// NewServer creates a server on network at provided address
func NewServer(network, address string) *Server {
func NewServer(network, address, name string) *Server {
if GetManager().IsChild() {
log.Info("Restarting new server: %s:%s on PID: %d", network, address, os.Getpid())
log.Info("Restarting new %s server: %s:%s on PID: %d", name, network, address, os.Getpid())
} else {
log.Info("Starting new server: %s:%s on PID: %d", network, address, os.Getpid())
log.Info("Starting new %s server: %s:%s on PID: %d", name, network, address, os.Getpid())
}
srv := &Server{
wg: sync.WaitGroup{},

View file

@ -9,8 +9,8 @@ import (
"net/http"
)
func newHTTPServer(network, address string, handler http.Handler) (*Server, ServeFunction) {
server := NewServer(network, address)
func newHTTPServer(network, address, name string, handler http.Handler) (*Server, ServeFunction) {
server := NewServer(network, address, name)
httpServer := http.Server{
ReadTimeout: DefaultReadTimeOut,
WriteTimeout: DefaultWriteTimeOut,
@ -25,21 +25,21 @@ func newHTTPServer(network, address string, handler http.Handler) (*Server, Serv
// HTTPListenAndServe listens on the provided network address and then calls Serve
// to handle requests on incoming connections.
func HTTPListenAndServe(network, address string, handler http.Handler) error {
server, lHandler := newHTTPServer(network, address, handler)
func HTTPListenAndServe(network, address, name string, handler http.Handler) error {
server, lHandler := newHTTPServer(network, address, name, handler)
return server.ListenAndServe(lHandler)
}
// HTTPListenAndServeTLS listens on the provided network address and then calls Serve
// to handle requests on incoming connections.
func HTTPListenAndServeTLS(network, address, certFile, keyFile string, handler http.Handler) error {
server, lHandler := newHTTPServer(network, address, handler)
func HTTPListenAndServeTLS(network, address, name, certFile, keyFile string, handler http.Handler) error {
server, lHandler := newHTTPServer(network, address, name, handler)
return server.ListenAndServeTLS(certFile, keyFile, lHandler)
}
// HTTPListenAndServeTLSConfig listens on the provided network address and then calls Serve
// to handle requests on incoming connections.
func HTTPListenAndServeTLSConfig(network, address string, tlsConfig *tls.Config, handler http.Handler) error {
server, lHandler := newHTTPServer(network, address, handler)
func HTTPListenAndServeTLSConfig(network, address, name string, tlsConfig *tls.Config, handler http.Handler) error {
server, lHandler := newHTTPServer(network, address, name, handler)
return server.ListenAndServeTLSConfig(tlsConfig, lHandler)
}

View file

@ -132,6 +132,7 @@ var (
ServerCiphers []string `ini:"SSH_SERVER_CIPHERS"`
ServerKeyExchanges []string `ini:"SSH_SERVER_KEY_EXCHANGES"`
ServerMACs []string `ini:"SSH_SERVER_MACS"`
ServerHostKeys []string `ini:"SSH_SERVER_HOST_KEYS"`
KeyTestPath string `ini:"SSH_KEY_TEST_PATH"`
KeygenPath string `ini:"SSH_KEYGEN_PATH"`
AuthorizedKeysBackup bool `ini:"SSH_AUTHORIZED_KEYS_BACKUP"`
@ -157,6 +158,7 @@ var (
KeygenPath: "ssh-keygen",
MinimumKeySizeCheck: true,
MinimumKeySizes: map[string]int{"ed25519": 256, "ed25519-sk": 256, "ecdsa": 256, "ecdsa-sk": 256, "rsa": 2048},
ServerHostKeys: []string{"ssh/gitea.rsa", "ssh/gogs.rsa"},
}
// Security settings
@ -698,6 +700,11 @@ func NewContext() {
if err = Cfg.Section("server").MapTo(&SSH); err != nil {
log.Fatal("Failed to map SSH settings: %v", err)
}
for i, key := range SSH.ServerHostKeys {
if !filepath.IsAbs(key) {
SSH.ServerHostKeys[i] = filepath.Join(AppDataPath, key)
}
}
SSH.KeygenPath = sec.Key("SSH_KEYGEN_PATH").MustString("ssh-keygen")
SSH.Port = sec.Key("SSH_PORT").MustInt(22)

View file

@ -259,28 +259,38 @@ func Listen(host string, port int, ciphers []string, keyExchanges []string, macs
},
}
keyPath := filepath.Join(setting.AppDataPath, "ssh/gogs.rsa")
isExist, err := util.IsExist(keyPath)
if err != nil {
log.Fatal("Unable to check if %s exists. Error: %v", keyPath, err)
keys := make([]string, 0, len(setting.SSH.ServerHostKeys))
for _, key := range setting.SSH.ServerHostKeys {
isExist, err := util.IsExist(key)
if err != nil {
log.Fatal("Unable to check if %s exists. Error: %v", setting.SSH.ServerHostKeys, err)
}
if isExist {
keys = append(keys, key)
}
}
if !isExist {
filePath := filepath.Dir(keyPath)
if len(keys) == 0 {
filePath := filepath.Dir(setting.SSH.ServerHostKeys[0])
if err := os.MkdirAll(filePath, os.ModePerm); err != nil {
log.Error("Failed to create dir %s: %v", filePath, err)
}
err := GenKeyPair(keyPath)
err := GenKeyPair(setting.SSH.ServerHostKeys[0])
if err != nil {
log.Fatal("Failed to generate private key: %v", err)
}
log.Trace("New private key is generated: %s", keyPath)
log.Trace("New private key is generated: %s", setting.SSH.ServerHostKeys[0])
keys = append(keys, setting.SSH.ServerHostKeys[0])
}
err = srv.SetOption(ssh.HostKeyFile(keyPath))
if err != nil {
log.Error("Failed to set Host Key. %s", err)
for _, key := range keys {
log.Info("Adding SSH host key: %s", key)
err := srv.SetOption(ssh.HostKeyFile(key))
if err != nil {
log.Error("Failed to set Host Key. %s", err)
}
}
go listen(&srv)
@ -291,7 +301,7 @@ func Listen(host string, port int, ciphers []string, keyExchanges []string, macs
// Public key is encoded in the format for inclusion in an OpenSSH authorized_keys file.
// Private Key generated is PEM encoded
func GenKeyPair(keyPath string) error {
privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
privateKey, err := rsa.GenerateKey(rand.Reader, 4096)
if err != nil {
return err
}

View file

@ -12,7 +12,7 @@ import (
)
func listen(server *ssh.Server) {
gracefulServer := graceful.NewServer("tcp", server.Addr)
gracefulServer := graceful.NewServer("tcp", server.Addr, "SSH")
err := gracefulServer.ListenAndServe(server.Serve)
if err != nil {