mirror of
https://github.com/rclone/rclone
synced 2024-12-22 13:03:02 +01:00
sftp: allow cert based auth via optional pubkey
Discussion at https://forum.rclone.org/t/ssh-certificate-based-authentication-does-not-work/19222 Basically we allow the user to specify their own public key cert rather than letting the SSH client extract the pubkey from the private key. This allows certificate based authentication to work.
This commit is contained in:
parent
57261c7e97
commit
17acae2b00
@ -82,6 +82,11 @@ func init() {
|
||||
Only PEM encrypted key files (old OpenSSH format) are supported. Encrypted keys
|
||||
in the new OpenSSH format can't be used.`,
|
||||
IsPassword: true,
|
||||
}, {
|
||||
Name: "pubkey_file",
|
||||
Help: `Optional path to public key file.
|
||||
|
||||
Set this if you have a signed certificate you want to use for authentication.` + env.ShellExpandHelp,
|
||||
}, {
|
||||
Name: "key_use_agent",
|
||||
Help: `When set forces the usage of the ssh-agent.
|
||||
@ -190,6 +195,7 @@ type Options struct {
|
||||
KeyPem string `config:"key_pem"`
|
||||
KeyFile string `config:"key_file"`
|
||||
KeyFilePass string `config:"key_file_pass"`
|
||||
PubKeyFile string `config:"pubkey_file"`
|
||||
KeyUseAgent bool `config:"key_use_agent"`
|
||||
UseInsecureCipher bool `config:"use_insecure_cipher"`
|
||||
DisableHashCheck bool `config:"disable_hashcheck"`
|
||||
@ -438,6 +444,7 @@ func NewFs(name, root string, m configmap.Mapper) (fs.Fs, error) {
|
||||
}
|
||||
|
||||
keyFile := env.ShellExpand(opt.KeyFile)
|
||||
pubkeyFile := env.ShellExpand(opt.PubKeyFile)
|
||||
//keyPem := env.ShellExpand(opt.KeyPem)
|
||||
// Add ssh agent-auth if no password or file or key PEM specified
|
||||
if (opt.Pass == "" && keyFile == "" && !opt.AskPassword && opt.KeyPem == "") || opt.KeyUseAgent {
|
||||
@ -507,7 +514,38 @@ func NewFs(name, root string, m configmap.Mapper) (fs.Fs, error) {
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to parse private key file")
|
||||
}
|
||||
sshConfig.Auth = append(sshConfig.Auth, ssh.PublicKeys(signer))
|
||||
|
||||
// If a public key has been specified then use that
|
||||
if pubkeyFile != "" {
|
||||
certfile, err := ioutil.ReadFile(pubkeyFile)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "unable to read cert file")
|
||||
}
|
||||
|
||||
pk, _, _, _, err := ssh.ParseAuthorizedKey(certfile)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "unable to parse cert file")
|
||||
}
|
||||
|
||||
// And the signer for this, which includes the private key signer
|
||||
// This is what we'll pass to the ssh client.
|
||||
// Normally the ssh client will use the public key built
|
||||
// into the private key, but we need to tell it to use the user
|
||||
// specified public key cert. This signer is specific to the
|
||||
// cert and will include the private key signer. Now ssh
|
||||
// knows everything it needs.
|
||||
cert, ok := pk.(*ssh.Certificate)
|
||||
if !ok {
|
||||
return nil, errors.New("public key file is not a certificate file: " + pubkeyFile)
|
||||
}
|
||||
pubsigner, err := ssh.NewCertSigner(cert, signer)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "error generating cert signer")
|
||||
}
|
||||
sshConfig.Auth = append(sshConfig.Auth, ssh.PublicKeys(pubsigner))
|
||||
} else {
|
||||
sshConfig.Auth = append(sshConfig.Auth, ssh.PublicKeys(signer))
|
||||
}
|
||||
}
|
||||
|
||||
// Auth from password if specified
|
||||
|
@ -102,7 +102,7 @@ excess files in the directory.
|
||||
The SFTP remote supports three authentication methods:
|
||||
|
||||
* Password
|
||||
* Key file
|
||||
* Key file, including certificate signed keys
|
||||
* ssh-agent
|
||||
|
||||
Key files should be PEM-encoded private key files. For instance `/home/$USER/.ssh/id_rsa`.
|
||||
@ -128,6 +128,26 @@ Using an ssh-agent is the only way to load encrypted OpenSSH keys at the moment.
|
||||
If you set the `--sftp-ask-password` option, rclone will prompt for a
|
||||
password when needed and no password has been configured.
|
||||
|
||||
If you have a certificate then you can provide the path to the public key that contains the certificate. For example:
|
||||
|
||||
```
|
||||
[remote]
|
||||
type = sftp
|
||||
host = example.com
|
||||
user = sftpuser
|
||||
key_file = ~/id_rsa
|
||||
pubkey_file = ~/id_rsa-cert.pub
|
||||
````
|
||||
|
||||
If you concatenate a cert with a private key then you can specify the
|
||||
merged file in both places.
|
||||
|
||||
Note: the cert must come first in the file. e.g.
|
||||
|
||||
```
|
||||
cat id_rsa-cert.pub id_rsa > merged_key
|
||||
```
|
||||
|
||||
### ssh-agent on macOS ###
|
||||
|
||||
Note that there seem to be various problems with using an ssh-agent on
|
||||
@ -234,6 +254,18 @@ in the new OpenSSH format can't be used.
|
||||
- Type: string
|
||||
- Default: ""
|
||||
|
||||
#### --sftp-pubkey-file
|
||||
|
||||
Optional path to public key file; set this if you have a signed certificate you want to use for authentication.
|
||||
|
||||
Leading `~` will be expanded in the file name as will environment variables such as `${RCLONE_CONFIG_DIR}`.
|
||||
|
||||
|
||||
- Config: pubkey_file
|
||||
- Env Var: RCLONE_SFTP_PUBKEY_FILE
|
||||
- Type: string
|
||||
- Default: ""
|
||||
|
||||
#### --sftp-key-use-agent
|
||||
|
||||
When set forces the usage of the ssh-agent.
|
||||
|
Loading…
Reference in New Issue
Block a user