backend/sftp: Add sftp.args option

Allow setting custom arguments for the `sftp` backend, by using the
`sftp.args` option. This is similar to the approach already implemented
in the `rclone` backend, to support new arguments without requiring
future code changes for each different SSH argument.

Closes #4241
This commit is contained in:
Michael Manganiello 2023-10-17 22:21:06 -03:00 committed by Michael Eischer
parent 17f2301cc2
commit 41f70f1f4f
5 changed files with 45 additions and 8 deletions

View file

@ -0,0 +1,16 @@
Enhancement: Add config option to set SFTP command arguments
The `sftp.args` option can be passed to restic (using `-o`) to specify
custom arguments to be used by the SSH command executed by the SFTP
backend.
Before this change, a common scenario where a custom identity file was
needed for the SSH connection, required the full command to be
specified:
`-o sftp.command='ssh user@host:port -i /ssh/my_private_key -s sftp'`
With this new configuration option:
`-o sftp.args='-i /ssh/my_private_key'`
https://github.com/restic/restic/pull/4519
https://github.com/restic/restic/issues/4241

View file

@ -119,10 +119,10 @@ user's home directory.
Also, if the SFTP server is enforcing domain-confined users, you can
specify the user this way: ``user@domain@host``.
.. note:: Please be aware that sftp servers do not expand the tilde character
.. note:: Please be aware that SFTP servers do not expand the tilde character
(``~``) normally used as an alias for a user's home directory. If you
want to specify a path relative to the user's home directory, pass a
relative path to the sftp backend.
relative path to the SFTP backend.
If you need to specify a port number or IPv6 address, you'll need to use
URL syntax. E.g., the repository ``/srv/restic-repo`` on ``[::1]`` (localhost)
@ -174,7 +174,11 @@ Last, if you'd like to use an entirely different program to create the
SFTP connection, you can specify the command to be run with the option
``-o sftp.command="foobar"``.
.. note:: Please be aware that sftp servers close connections when no data is
The SFTP backend has the following additional option:
* ``-o sftp.args`` allows setting the arguments passed to the default SSH command (ignored when ``sftp.command`` is set)
.. note:: Please be aware that SFTP servers close connections when no data is
received by the client. This can happen when restic is processing huge
amounts of unchanged data. To avoid this issue add the following lines
to the client's .ssh/config file:

View file

@ -13,8 +13,9 @@ import (
type Config struct {
User, Host, Port, Path string
Layout string `option:"layout" help:"use this backend directory layout (default: auto-detect)"`
Layout string `option:"layout" help:"use this backend directory layout (default: auto-detect)"`
Command string `option:"command" help:"specify command to create sftp connection"`
Args string `option:"args" help:"specify arguments for ssh"`
Connections uint `option:"connections" help:"set a limit for the number of concurrent connections (default: 5)"`
}

View file

@ -213,6 +213,9 @@ func buildSSHCommand(cfg Config) (cmd string, args []string, err error) {
if err != nil {
return "", nil, err
}
if cfg.Args != "" {
return "", nil, errors.New("cannot specify both sftp.command and sftp.args options")
}
return args[0], args[1:], nil
}
@ -226,11 +229,19 @@ func buildSSHCommand(cfg Config) (cmd string, args []string, err error) {
args = append(args, "-p", port)
}
if cfg.User != "" {
args = append(args, "-l")
args = append(args, cfg.User)
args = append(args, "-l", cfg.User)
}
args = append(args, "-s")
args = append(args, "sftp")
if cfg.Args != "" {
a, err := backend.SplitShellStrings(cfg.Args)
if err != nil {
return "", nil, err
}
args = append(args, a...)
}
args = append(args, "-s", "sftp")
return cmd, args, nil
}

View file

@ -30,6 +30,11 @@ var sshcmdTests = []struct {
"ssh",
[]string{"host", "-p", "10022", "-l", "user", "-s", "sftp"},
},
{
Config{User: "user", Host: "host", Port: "10022", Path: "/dir/subdir", Args: "-i /path/to/id_rsa"},
"ssh",
[]string{"host", "-p", "10022", "-l", "user", "-i", "/path/to/id_rsa", "-s", "sftp"},
},
{
// IPv6 address.
Config{User: "user", Host: "::1", Path: "dir"},