Repository: borgbackup/borg
Pull request: Add ssh-agent pull backup method to doc
[DOCS] Add ssh-agent pull mode
Closes #5287 .

Problem statement:
Document how to use ssh-agent pull mode
When trying to implement borg in our infrastructure I found out that there is no documentation for using borg in pull mode with ssh-agent for forwarding of the authentication information from server to client. From my point of view this method is more convenient than using socat because it have less prerequirements and overhead.

More detalied explanation in PR.

## Have you checked borgbackup docs, FAQ, and open Github issues?

Yes

## Is this a BUG / ISSUE report or a QUESTION?

ISSUE

Hints from issue discussion:

Commit message: Add ssh-agent pull backup method to doc

Patch to review:
diff --git a/docs/deployment/pull-backup.rst b/docs/deployment/pull-backup.rst
index f4c67f8ea0..48cee60c32 100644
--- a/docs/deployment/pull-backup.rst
+++ b/docs/deployment/pull-backup.rst
@@ -301,3 +301,66 @@ a backup may be the following command::
 
 This command also automatically removes the socket file after the ``borg
 create`` command is done.
+
+ssh-agent
+=========
+
+In this scenario *borg-server* initiate SSH connection to *borg-client* with forwarding of the authentication agent connection.
+Afterwards scenario is similar to the push mode: *borg-client* initiate another SSH connection
+back to *borg-server* using forwarded agent connection for authenticate itself,
+starts ``borg serve`` and communicate with them.
+
+Using of this method requires ssh access from *borgs* to *borgc@borg-client* and
+from *borgs* to *borgs@borg-server* itself. Where:
+
+* *borgs* is the user on the server side with read/write access to local borg repository.
+* *borgc* is the user on the client side with read access to files meant to be backed up.
+
+Apply of this method in case of automated backup operations
+-----------------------------------------------------------
+
+Do this once on *borg-server* for allowing *borgs* to connect itself on *borg-server*::
+
+  borgs@borg-server$ cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
+  borgs@borg-server$ chmod go-w ~/.ssh/authorized_keys
+
+Execute pull operation (init repo in this example) on *borg-server*::
+
+  borgs@borg-server$ (
+    eval $(ssh-agent) > /dev/null
+    ssh-add -q
+    ssh -A borgc@borg-client "borg init -e none --rsh 'ssh -o StrictHostKeyChecking=no' borgs@borg-server:repo"
+    kill "${SSH_AGENT_PID}"
+  )
+
+Parentheses around commands are needed to exclude interferention with possibly already running ssh-agent.
+Parentheses not needed in case of using dedicated bash process.
+
+*eval $(ssh-agent) > /dev/null*
+
+  Run SSH agent in background and export related environment variables to current bash session.
+
+*ssh-add -q*
+
+  Load SSH private key(s) to SSH agent from default locations:
+  ~/.ssh/id_rsa, ~/.ssh/id_dsa, ~/.ssh/id_ecdsa and ~/.ssh/id_ed25519.
+  Look at ``man 1 ssh-add`` for more detailed explanation.
+
+  Care needs to be taken when loading keys to SSH agent. Users on the *borg-client* having read/write permissions to
+  agent's UNIX-domain socket (at least borgc and root in our case) can access the agent on *borg-server* through the
+  forwarded connection and use loaded keys for authenticate using the identities loaded into the agent
+  (look at ``man 1 ssh`` for more detailed explanation). Therefore there are some security considerations:
+
+  * *borgs*'s private key loaded to agent must not be used to access anywhere else.
+  * The keys meant to be loaded to agent must be specified explicitly, not from default locations.
+  * The *borgs*'s public key record at *borgs@borg-server:~/.ssh/authorized_keys* must be as restrictive as possible.
+
+*ssh -A borgc@borg-client "borg init -e none --rsh 'ssh -o StrictHostKeyChecking=no' borgs@borg-server:repo"*
+
+  Issue *borg init -e none borgs@borg-server:repo* command to be executed at *borg-client*.
+  *StrictHostKeyChecking=no* used for automatically adding host key of
+  *borg-server* to *borgc@borg-client:~/.ssh/known_hosts* without user intervention.
+
+*kill "${SSH_AGENT_PID}"*
+
+  Kill ssh-agent with loaded keys as it not needed anymore.


Code review comments:
diff_hunk: @@ -301,3 +301,66 @@ a backup may be the following command::
 
 This command also automatically removes the socket file after the ``borg
 create`` command is done.
+
+ssh-agent
+=========
+
+In this scenario *borg-server* initiate SSH connection to *borg-client* with forwarding of the authentication agent connection.
+Afterwards scenario is similar to the push mode: *borg-client* initiate another SSH connection
+back to *borg-server* using forwarded agent connection for authenticate itself,
+starts ``borg serve`` and communicate with them.
+
+Using of this method requires ssh access from *borgs* to *borgc@borg-client* and
+from *borgs* to *borgs@borg-server* itself. Where:
+
+* *borgs* is the user on the server side with read/write access to local borg repository.
+* *borgc* is the user on the client side with read access to files meant to be backed up.
+
+Apply of this method in case of automated backup operations
+-----------------------------------------------------------
+
+Do this once on *borg-server* for allowing *borgs* to connect itself on *borg-server*::
+
+  borgs@borg-server$ cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
+  borgs@borg-server$ chmod go-w ~/.ssh/authorized_keys
+
+Execute pull operation (init repo in this example) on *borg-server*::
+
+  borgs@borg-server$ (
+    eval $(ssh-agent) > /dev/null
+    ssh-add -q
+    ssh -A borgc@borg-client "borg init -e none --rsh 'ssh -o StrictHostKeyChecking=no' borgs@borg-server:repo"
path: docs/deployment/pull-backup.rst
text: @user2:
maybe rather use the `ssh://borgs@user1-server/./path/to/repo` (check how parts are named at other places in the docs) syntax, so people can give :port if needed (this is not supported by the syntax you used).

@user2:
also, we should not have unsafe examples (like `-e none`) in the docs, so I suggest setting BORG_PASSPHRASE env var and remove `-e none` so it uses the safe default (encrypted repo).

@author:
Fixed

diff_hunk: @@ -301,3 +301,66 @@ a backup may be the following command::
 
 This command also automatically removes the socket file after the ``borg
 create`` command is done.
+
+ssh-agent
+=========
+
+In this scenario *borg-server* initiate SSH connection to *borg-client* with forwarding of the authentication agent connection.
+Afterwards scenario is similar to the push mode: *borg-client* initiate another SSH connection
+back to *borg-server* using forwarded agent connection for authenticate itself,
+starts ``borg serve`` and communicate with them.
+
+Using of this method requires ssh access from *borgs* to *borgc@borg-client* and
+from *borgs* to *borgs@borg-server* itself. Where:
+
+* *borgs* is the user on the server side with read/write access to local borg repository.
+* *borgc* is the user on the client side with read access to files meant to be backed up.
+
+Apply of this method in case of automated backup operations
+-----------------------------------------------------------
+
+Do this once on *borg-server* for allowing *borgs* to connect itself on *borg-server*::
+
+  borgs@borg-server$ cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
+  borgs@borg-server$ chmod go-w ~/.ssh/authorized_keys
path: docs/deployment/pull-backup.rst
text: @user1:
if there is not already a ssh key present for this user, it needs `ssh-keygen -t rsa` first.

@user1:
also, guess we should show how to use the forced command in authorized_keys here, so this key can *only* invoke borg

@author:
Fixed