I want to add support to sftp backend on my iOS restic client (see Restic iOS Client App ). When I check the sftp backend, I noticed the sftp actually forked a ssh command and use pipe to communicate with ssh. On iOS there is no ssh command and can not support fork exec. I also noticed there is actually a go ssh package golang.org/x/crypto/ssh can establish ssh connect without depends on native ssh command. I tried a make some modification on internal/backend/sftp/sftp.go to use golang.org/x/crypto/ssh package and actually it works on my initial test, I can initial a new sftp repo, backup, list snapshots, restore. All looks good to me.
I’m curious whether there’s a specific reason to use the native SSH client instead of golang.org/x/crypto/ssh to achieve consistent SSH behavior? Native SSH clients can vary in behavior across versions and platforms.
How would you support the SSH configuration people have on their machines? Even when using e.g. github.com/kevinburke/ssh_config it’s mostly an explicit process to configure golang.org/x/crypto/ssh. There are more configuration items in ssh_config than just host-specific ones.
Good question about ssh_config.
Actually I didn’t think about go that far. I would like to start with simple to support typical usage and we can expand it later. Add option to config ssh authentication manually through env var. Here is my thought for the changes:
Introduce env var RESTIC_SSH_KEY, the value is based64 encoded (to keep as one line) ssh private key.
Introduce env var RESTIC_SSH_CLIENT, the value can be:
“native” (default): fallback the exist ssh implementation
“golang”: use golang.org/x/crypto/ssh to establish ssh connection with key authentication, key came from RESTIC_SSH_KEY. No password authentication is supported. also private key should not protected by a password.