-
-
Notifications
You must be signed in to change notification settings - Fork 753
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
document pull-like operation #900
Comments
A pull setup that does not involve ssh is to just mount the source filesystems on the machine that runs borg. |
For the usecase where the normal push way is problematic because of firewalls etc. From axion on irc (slightly edited and simplified, so all errors are likely mine):
This way tunnels a ssh connection through an ssh connections so it does have some additional overhead. Another way would be to use BORG_RSH and a pair of socat instances to avoid one layer of ssh encryption. |
@textshell I don't think that BORG_UNKNOWN_UNENCRYPTED_REPO_ACCESS_IS_OK=yes should be in there permanently, right? Also, the repo=...{REPO_PATH}/${host} can be done that way, but is unrelated to pull-mode. Also, REPO_PATH there is rather the path that has the repos as subdirs, not the path of the repository itself. |
@UNKNOWN_UNENCRYPTED it depends if PULL_PORT is always the same. If that can be arranged that yes, it should not be in there. @repo yes that can be simplified. I only did limited editing from axion’s pastebin, but i didn’t want this to get lost again. I think the BORG_RSH + socat way would be nicer anyway (no ssh in ssh, not dependency on sshd running on the backups server, etc), but a little more complex bash script. |
While having documentation for this workaround is great, wouldn't it be better to add this functionality to borg itself? This kind of syntax would be awesome:
|
I agree with @sudoman; it would be useful to know, are there architectural reasons this would be difficult? It feels like this would dramatically increase the number of scenarios for which Borg is a recommendable solution. |
We first need to agree on a plan. For example i don‘t like overloading the directory argument on borg create with additional magic. I personally tend to a new sub command. (Note: server is where the repo is, client is the remote system where the to be backuped data is) Also as this is not the main use case for borg i think the design should minimize the changes needed. Thus i think the stdin, stdout and stderr of the ssh session should be used for the ui of the borg client on the remote system not for data transfer so that all interaction still works as expected. Thus the repository communication would need to be tunneled with an additional unix socket forward. I’m not sure what to do about borg serve’s stderr. Maybe it‘s ok to just (implicitly) splice that in on the server side. One way to implement borg pull would be to create unix socket and listen to it, ssh to the to be backuped system to run borg with special options to create that tell it the needed unix socket to connect. The server would then wait for an connection on the unix socket, dup2 these to stdin, stdout and invoke the RepositoryServer. Still open is how key management is even supposed to work in this scenario. Maybe mandate a keyfile on the client in the default location? This would need minimal changes to the main borg code:
Of course this still requires a borg executable on the client. So it doesn‘t need any architectural changes but is a lot fiddling with external ssh process interaction and the os module. So in the end i think it‘s a task that is doable for anyone with sufficient motivation and decent python skills. |
It's pretty much what I do over at borgcube. I don't mean that as advertisement (wouldn't make any sense for a project that doesn't really work yet, does it?), rather, if someone wants to implement it in their system they can draw inspiration from there - the basics (pulling an archive from a client) work rather well. You can also gauge how many changes it would likely need to do this; if it is even more tightly integrated into Borg itself it would probably mean much more changes than those presented in borgcube. Which is the reason why I choose to put that into a separate project; however if someone wants to work toward integrating it into Borg itself I won't interfere of course, since I'm obviously inherently biased here. |
I'm reading the ~solution posted by @textshell again, and I'm realizing... this has reintroduces to the pull model one of the issues (well, issue depending on your setup) that I was hoping to avoid from the push model. In the scenario being described, it sounds like both machines will have to have access to each other. |
@cwebber The client only has access to the borg repository not the whole backup server in the scenario i posted (but that is comparable to the access it would have in push mode with a correctly setup forced command and assuming sshd is not buggy). At least if RepositoryServer is started with restrictions to only allow access to the right borg repository and only via the socket that borg pull creates. (So no direct network or ssh access is needed) |
FWIW, I have made a small hack which works with socat, thus saving the SSH-in-SSH overhead and obliterating the need for the remote machine to have an account on the local machine. Using First, we create #!/bin/bash
exec socat STDIO TCP-CONNECT:localhost:12345 Locally, we run socat to offer the borg service: socat TCP-LISTEN:12345,fork \
"EXEC:borg serve --append-only --restrict-to-path $PATH_TO_REPOSITORIES --umask 077" (omit the Now we invoke borg on the remote using ssh, forwarding the port: ssh -R 12345:localhost:12345 sourcehost \
BORG_RSH="/home/horazont/socat-wrap.sh" \
borg init -e none ssh://foo/$PATH_TO_REPOSITORIES/some_repository
Of course, it’s also possible to do the same with UNIX sockets, providing more isolation.
#!/bin/bash
exec socat STDIO UNIX-CONNECT:/home/horazont/borg-remote.sock socat UNIX-LISTEN:/home/horazont/borg-local.sock,fork \
"EXEC:borg serve --append-only --restrict-to-path $PATH_TO_REPOSITORIES --umask 077" ssh -R /home/horazont/borg-local.sock:/home/horazont/borg-remote.sock sourcehost \
BORG_RSH="/home/horazont/socat-wrap.sh" \
borg init -e none ssh://foo/$PATH_TO_REPOSITORIES/some_repository
|
@horazont looks good. did you compare performance ssh vs. socat? Is the socat-wrap.sh needed or could the socat command be used directly in BORG_RSH? |
@ThomasWaldmann socat doesn’t like the additional arguments borg is attempting to add. Not sure how to circumvent that. re performance, I haven’t checked. My main motivation for finding this solution was that I didn’t want to setup an account for the remote to SSH into (even though it should be pretty safe authorized_keys command restrictions). The appeal is that it works out-of-the-box, no configuration on either side needed (the socat-wrapper.sh can be scp’d on demand). |
ah, of course. yeah, then such a script is easiest way. if you have that setup working ok, could you add a section to our docs about it and do a PR against 1.0-maint? |
i set up the socat-based solution from @horazont mentioned above, running nightly backups from various locations. i noticed that with larger backup targets, after a couple of days, i reproducably get this error:
after this happens once, the lockfile not having been deleted properly prohibits further backups... i guess it has to do with one of the connections being closed prematurely? edit: this error is reported on the server that "pulls" the backup from the client (i can only tell by of the /opt/lib/... location - this setup is pretty confusing to debug). |
Maybe socat times out?
Not sure if that's on by default. |
hm, i just realized i used thanks for the timeout hint, i now enabled socat logging with -lf and -d -d. if it happens again, we'll know for sure if there was a timeout! |
it happened again :( no timeout though. here is the borg output:
and here's the socat log for that run:
all looks normal.. but all the days before, when stuff was working fine, there was an additional few lines in the log:
note the i'm at a loss.. what's going on here? |
You revoke the key when not issuing a backup command.
… On Feb 12, 2019, at 11:43 AM, Stefan Schlott ***@***.***> wrote:
@marcpope you can issue a "borg purge" on the compromised host; or is there a way to limit the borg operation via authorized_keys file?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub, or mute the thread.
|
Unless I'm blind, I don't think anyone spoke about the fact a complete pull system with sshfs started before Borg is doable, without a root login (specific sudo right on the remote target is required).
Adjust sftp_server arg to the sshd_config subsystems entry. To have this working, you'll need :
Now try to connect to the target server with ssh, and retry with sshfs. You'll see all files can be accessed, due to sftp-server running as root. Only limitation for now is the fact the backup will have inside the full path of the mount point. And this will also need to be set as a prefix on all paths to backup and exclude. |
Thanks! I used this reverse unix socket forwarding to backup a remote server. I didn't want to use static reverse port and I could not figure out how to catch dynamic port, also using unix sockets offers better isolation as default mask is 01777 and thus other uses can't try to access it. People who would like to use it just check |
A new round of fun with pull-like operation. I wrapped the pulling side in systemd units:
[Unit]
Description=Socket for accessing a specific path as borg repositories
[Socket]
ListenStream=/data/test/borg.sock
Accept=yes
[Unit]
Description=Borg serve
[Service]
Type=simple
ExecStart=/usr/bin/borg serve --append-only --restrict-to-path /data/test/repos/ --umask 077
StandardInput=socket
StandardOutput=socket
StandardError=journal
User=remote-backups
Group=remote-backups
ProtectSystem=strict
PrivateTmp=yes
PrivateNetwork=yes
PrivateDevices=yes
ProtectKernelTunables=yes
RestrictAddressFamilies=
ReadWritePaths=/data/test/repos/ This makes the
To execute a backup, one can use for example:
The (Of course, you’d normally not use root but instead a user with sudo privileges for exactly the required borg create commands.) |
@fantasya-pbem did you see this ticket / bounty? |
Yeah, I find it quite difficult to go through all these comments and get the essence of what could be called a general recipe to to it. And I don't have experience with pull-like operations. I'll follow this issue and maybe one day find time to write some docs from it. |
@fantasya-pbem ok, thanks. guess one needs to actually try it and in parallel write complete / consistent docs. |
Was this ever implemented? |
I managed to get a pull setup running, turns out it looks extremely similar to @horazont's approach ;-) I also use socat to redirect from/to a unix domain socket. I baked all in two shell scripts (one on the pull-side, one on the machine to be backupped) - no systemd, "borg serve" is only spun up during the actual backup process. A first step to streamline this approach would be a modification of borg to get rid of the socat workaround, i.e. redirecting stdin/stdout to a unix domain socket (sounds similar to #4749). This clould look like the following:
@ThomasWaldmann would you be interested in code changes implementing this? Or are you aiming for a more comfortabe "all-in-one solution" which would seamlessly integrate the push like in the comment above by @binaryplease? |
@Skyr I'ld like to see a solution that does not need major modifications or additions to the RPC code (remote.py). That code is fragile, performance critical and not easy to debug. |
Is this resolved? Seems like all @horazont needs to do is open a PR. |
BTW latest OpenSSH added support for remote/local unix socket forwarding tokens, see https://bugzilla.mindrot.org/show_bug.cgi?id=3014 |
I'm creating a daemon to automate backups for me (need to learn go, and this fits it). Eventually, I'd like to be able to run the daemon on a server, that will tell my client to start a backup if one hasn't been done recently. Does anyone see any issues doing this? Anyone interested in a similar thing? |
closing due to #5230. |
docs: describe socat pull mode, fixes #900 also: fix sphinx deprecation warning borg/docs/conf.py:114: RemovedInSphinx40Warning: The app.add_stylesheet() is deprecated. Please use app.add_css_file() instead.
@BenediktSeidl solved this, but wants to give the bounty to the borg project thanks! So, I will claim it and transfer the funds back to borgbackup org, so they can be used for future bounties. |
Now claimed USD 50 bounty and transferred back to borgbackup org, https://www.bountysource.com/orders/119860?receipt=1 |
This method requires only passwordless access from borg-server to borg-client. Not ssh-in-ssh. Do this once on borg-server:
Execute pull operation on borg-server:
|
@tombyman commenting on a closed issue / merged PR might be not the best way to push this. So, maybe better open a new issue. Describe what the issue is and if you have a solution, make a PR that fixes the issue? |
Backport from master borgbackup#5150: Document the socat pull mode described in borgbackup#900.
this is a FAQ (by people who have firewalls or want it for other reasons) and some people are evaluating setups with
ssh -R
(see some posts in #36).this issue is to collect such setups and if evaluated successfully, add it to the documentation.
note: the debian/ubuntu package description says borg only supports push, maybe that can be removed after this ticket is closed.
so, if you successfully run a pull-like setup, the best thing you can do is to make a pull request that closes this ticket.
💰 there is a bounty for this
Note: to collect the bounty you need to run a reliable pull-like setup, do a pull request for our documentation, documenting the pull-related parts of the setup.
The text was updated successfully, but these errors were encountered: