serve sftp: add support for multiple host keys by repeating --key flag

This commit is contained in:
Maxime Suret 2020-05-09 15:43:17 +02:00 committed by GitHub
parent c80b6d96dd
commit 79d29bb41e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 31 additions and 29 deletions

View file

@ -206,34 +206,36 @@ func (s *server) serve() (err error) {
} }
// Load the private key, from the cache if not explicitly configured // Load the private key, from the cache if not explicitly configured
keyPath := s.opt.Key keyPaths := s.opt.HostKeys
cachePath := filepath.Join(config.CacheDir, "serve-sftp") cachePath := filepath.Join(config.CacheDir, "serve-sftp")
if keyPath == "" { if len(keyPaths) == 0 {
keyPath = filepath.Join(cachePath, "id_rsa") keyPaths = []string{filepath.Join(cachePath, "id_rsa")}
} }
private, err := loadPrivateKey(keyPath) for _, keyPath := range keyPaths {
if err != nil && s.opt.Key == "" { private, err := loadPrivateKey(keyPath)
fs.Debugf(nil, "Failed to load %q: %v", keyPath, err) if err != nil && len(s.opt.HostKeys) == 0 {
// If loading a cached key failed, make the keys and retry fs.Debugf(nil, "Failed to load %q: %v", keyPath, err)
err = os.MkdirAll(cachePath, 0700) // If loading a cached key failed, make the keys and retry
if err != nil { err = os.MkdirAll(cachePath, 0700)
return errors.Wrap(err, "failed to create cache path") if err != nil {
return errors.Wrap(err, "failed to create cache path")
}
const bits = 2048
fs.Logf(nil, "Generating %d bit key pair at %q", bits, keyPath)
err = makeSSHKeyPair(bits, keyPath+".pub", keyPath)
if err != nil {
return errors.Wrap(err, "failed to create SSH key pair")
}
// reload the new keys
private, err = loadPrivateKey(keyPath)
} }
const bits = 2048
fs.Logf(nil, "Generating %d bit key pair at %q", bits, keyPath)
err = makeSSHKeyPair(bits, keyPath+".pub", keyPath)
if err != nil { if err != nil {
return errors.Wrap(err, "failed to create SSH key pair") return err
} }
// reload the new keys fs.Debugf(nil, "Loaded private key from %q", keyPath)
private, err = loadPrivateKey(keyPath)
}
if err != nil {
return err
}
fs.Debugf(nil, "Loaded private key from %q", keyPath)
s.config.AddHostKey(private) s.config.AddHostKey(private)
}
// Once a ServerConfig has been configured, connections can be // Once a ServerConfig has been configured, connections can be
// accepted. // accepted.

View file

@ -19,12 +19,12 @@ import (
// Options contains options for the http Server // Options contains options for the http Server
type Options struct { type Options struct {
ListenAddr string // Port to listen on ListenAddr string // Port to listen on
Key string // Path to private host key HostKeys []string // Paths to private host keys
AuthorizedKeys string // Path to authorized keys file AuthorizedKeys string // Path to authorized keys file
User string // single username User string // single username
Pass string // password for user Pass string // password for user
NoAuth bool // allow no authentication on connections NoAuth bool // allow no authentication on connections
} }
// DefaultOpt is the default values used for Options // DefaultOpt is the default values used for Options
@ -40,7 +40,7 @@ var Opt = DefaultOpt
func AddFlags(flagSet *pflag.FlagSet, Opt *Options) { func AddFlags(flagSet *pflag.FlagSet, Opt *Options) {
rc.AddOption("sftp", &Opt) rc.AddOption("sftp", &Opt)
flags.StringVarP(flagSet, &Opt.ListenAddr, "addr", "", Opt.ListenAddr, "IPaddress:Port or :Port to bind server to.") flags.StringVarP(flagSet, &Opt.ListenAddr, "addr", "", Opt.ListenAddr, "IPaddress:Port or :Port to bind server to.")
flags.StringVarP(flagSet, &Opt.Key, "key", "", Opt.Key, "SSH private host key file (leave blank to auto generate)") flags.StringArrayVarP(flagSet, &Opt.HostKeys, "key", "", Opt.HostKeys, "SSH private host key file (Can be multi-valued, leave blank to auto generate)")
flags.StringVarP(flagSet, &Opt.AuthorizedKeys, "authorized-keys", "", Opt.AuthorizedKeys, "Authorized keys file") flags.StringVarP(flagSet, &Opt.AuthorizedKeys, "authorized-keys", "", Opt.AuthorizedKeys, "Authorized keys file")
flags.StringVarP(flagSet, &Opt.User, "user", "", Opt.User, "User name for authentication.") flags.StringVarP(flagSet, &Opt.User, "user", "", Opt.User, "User name for authentication.")
flags.StringVarP(flagSet, &Opt.Pass, "pass", "", Opt.Pass, "Password for authentication.") flags.StringVarP(flagSet, &Opt.Pass, "pass", "", Opt.Pass, "Password for authentication.")