Wrong home dir when mounting via borgfs using /etc/fstab
When I mount a borg repository as non-root user through the following /etc/fstab entry:
/path/to/repo /mnt/repo fuse.borgfs defaults,noauto,user 0 0
as described in the documentation, I get the following permission error.
$ mount /mnt/repo
Enter passphrase for key /path/to/repo:
Local Exception
Traceback (most recent call last):
File "/usr/local/lib/python3.6/dist-packages/borg/archiver.py", line 4157, in main
exit_code = archiver.run(args)
File "/usr/local/lib/python3.6/dist-packages/borg/archiver.py", line 4089, in run
return set_ec(func(args))
File "/usr/local/lib/python3.6/dist-packages/borg/archiver.py", line 1324, in do_mount
return self._do_mount(args)
File "/usr/local/lib/python3.6/dist-packages/borg/archiver.py", line 138, in wrapper
kwargs['manifest'], kwargs['key'] = Manifest.load(repository, compatibility)
File "/usr/local/lib/python3.6/dist-packages/borg/helpers.py", line 334, in load
key = key_factory(repository, cdata)
File "/usr/local/lib/python3.6/dist-packages/borg/crypto/key.py", line 131, in key_factory
return identify_key(manifest_data).detect(repository, manifest_data)
File "/usr/local/lib/python3.6/dist-packages/borg/crypto/key.py", line 572, in detect
if key.load(target, passphrase):
File "/usr/local/lib/python3.6/dist-packages/borg/crypto/key.py", line 763, in load
success = self._load(key_data, passphrase)
File "/usr/local/lib/python3.6/dist-packages/borg/crypto/key.py", line 603, in _load
self.tam_required = key.get('tam_required', tam_required(self.repository))
File "/usr/local/lib/python3.6/dist-packages/borg/crypto/key.py", line 140, in tam_required
file = tam_required_file(repository)
File "/usr/local/lib/python3.6/dist-packages/borg/crypto/key.py", line 135, in tam_required_file
security_dir = get_security_dir(bin_to_hex(repository.id))
File "/usr/local/lib/python3.6/dist-packages/borg/helpers.py", line 494, in get_security_dir
security_dir = os.environ.get('BORG_SECURITY_DIR', os.path.join(get_config_dir(), 'security'))
File "/usr/local/lib/python3.6/dist-packages/borg/helpers.py", line 525, in get_config_dir
os.makedirs(config_dir)
File "/usr/lib/python3.6/os.py", line 210, in makedirs
makedirs(head, mode, exist_ok)
File "/usr/lib/python3.6/os.py", line 220, in makedirs
mkdir(name, mode)
PermissionError: [Errno 13] Permission denied: '/root/.config'
Platform: Linux hostname 4.13.0-1-marvell #1 Debian 4.13.4-2 (2017-10-15) armv5tel
Linux: debian buster/sid
Borg: 1.1.3 Python: CPython 3.6.3
PID: 10713 CWD: /home/user/bin
sys.argv: ['/usr/local/bin/borgfs', '/path/to/repo', '/mnt/repo', '-o', 'rw,noexec,nosuid,nodev']
SSH_ORIGINAL_COMMAND: None
From the backtrace it looks like the security dir is not set, resulting in borg trying to write to /root/.config, but I don't know the proper way to tell borg where to look for the security directory in the /etc/fstab scenario.
This problem does not occur when I mount the repo manually (borg mount /path/to/repo /mnt/repo).
Is this a problem with my configuration, or is the documentation incomplete on how mount a borg repo through /etc/fstab?
ok, which permission to /root/.config have you? read?
but I don't know the proper way to tell borg where to look for the security directory in the
put the info to /root/.profile, /root/.bashrc or /etc/profile?
Thanks for your help! Without sudo I don't have any permissions for anything in /root/. Since the documentation says:
To allow a regular user to use fstab entries, add the user option:
/path/to/repo /mnt/point fuse.borgfs defaults,noauto,user 0 0
I was under the impression that borg would use the .config directory of the user doing the mount. That doesn't seem to be the case.
put the info to /root/.profile,/root/.bashrc or /etc/profile?
I can do that for one user, but then only that user can mount borg repositories through /etc/fstab, right?
Without sudo I don't have any permissions for anything in
/root
ok, you try it as normal user.
To allow a regular user to use fstab entries, add the user option: /path/to/repo /mnt/point fuse.borgfs defaults,noauto,user 0 0
I was under the impression that borg would use the .config directory of the user doing the mount. That doesn't seem to be the case.
ok, that's a fstab setting.
- nouser only root can mount
- users all users can mount and unmount
- user all users can mount and only the mount user can unmount
I can do that for one user, but then only that user can mount borg repositories through /etc/fstab, right?
I think it would be the best, you are explaning what you try to do. :)
I have a server where I store backups from various computers. I would like to be able to locally mount each of these repositories through /etc/fstab on that server to access the backups if I need to.
Ok, I think you will mount the repository with any user on the local computer? Or at booting phase? The simplest solution would be to use the root user to mount/umount. Keep it simple :) Or creating an user 'borg' and use the /home/borg/ to store all information. Or ... :)
also look to chapter Environment Variables https://borgbackup.readthedocs.io/en/stable/usage/general.html
I am aware of the environment variables borg uses, but I don't think they can be passed to borgfs when it is called through /etc/fstab.
When I mount as root, the mount directory is only readable by root, that's not what I want.
Perhaps the borgfs can be extended to support the uid mount option, so that it uses the $HOME of that user to look for the .config. If not I think it would be better to remove the part about using the user mount option in /etc/fstab from the documentation in http://borgbackup.readthedocs.io/en/stable/usage/mount.html.
Perhaps the borgfs can be extended to support the uid mount option
Yeah, I look to the code and that is an issue.
I don't think they can be passed to borgfs when it is called through /etc/fstab
How you would be mounting the fstab entry?
Have you tried to customize the mount command at /etc/profile by using an alias (and passing the variables you wish to borg?).
How you would be mounting the fstab entry?
Maybe I misunderstand, but the idea would be by: mount /mnt/repo
Have you tried to customize the mount command at /etc/profile by using an alias (and passing the variables you wish to borg?).
In that case I might as well use an alias to borg mount /path/to/repo /mnt/repo in my own .profile. That kind of proves my point that user mounting a borg repo through /etc/fstab is currently not a feasible option.
Using one borg repo by different uids is asking for trouble (this is a rather general issue, not limited to borg).
See also: https://github.com/borgbackup/borg/issues/3403#issuecomment-348510592
If you can reproduce your other issues after fixing this fundamental "permissions mixup" issue, please re-open a new ticket for them.
Using one borg repo by different uids is asking for trouble (this is a rather general issue, not limited to borg).
Fair enough. But then I'm left with the question how user mounting through /etc/fstab is supposed to work in the first place. If I issue mount /mnt/repo as a normal user (which is allowed with the user option in /etc/fstab), I will need write permissions for /root, and that's not supposed to be the case.
Well, maybe one way is to create/update the repo with the same user that is expected to be able to work with it later (like mount it).
Alternatively, you can also try the borguser@localhost trick maybe, which de-couples the repo-files-accessing user from the input-files-reading user.
Well, maybe one way is to create/update the repo with the same user that is expected to be able to work with it later (like mount it).
That's what I'm doing. The user doing the mount is also the owner of the repo, but the permission error seems to originate from the fact that borgfs does not use the .config of that user (presumably because when mounting from /etc/fstab, the $HOME variable visible to borgfs is set to /root).
If I understand right, currently only the root user can use fstab fsborg feature so you say the sentence "To allow a regular user to use fstab entries [implicitly with fsborg feature], add the user option:" in the borg documentation is not correct.
only the root user can use fstab fsborg feature so the sentence "To allow a regular user to use fstab entries, add the user option:" in the borg documentation is not relevant.
Exactly, so I'm fine if this issue stays closed, but then the documentation should not propose the use of the user option in /etc/fstab, and preferably it should mention that mounting only works for root, and that the mounted repo will only be readable by root.
I reproduced the issue. I interpreted the OP badly (sorry!), it seems to be a valid issue.
Added a fstab entry like in the docs (including "user" option).
As a user (not root):
- made a repo and a mountpoint (corresponding to the fstab line, in users' home)
- tried to mount the repo using "mount mountpoint"
- BAM, it complains about /root/.config.
So, something is wrong here, just not sure what. Maybe how it determines home dir (for config and cache locations).
When it crashes (when borgfs is invoked by mount):
sys.argv: ['/usr/local/bin/borgfs', '/home/tw/w/borg/repo', '/home/tw/w/borg/mnt', '-o', 'rw,noexec,nosuid,nodev']
This is the borgfs process environment then:
env LOGNAME=tw
env _=/bin/mount
env USER=tw
env HOME=/root
# ... lots of uninteresting stuff removed ...
def get_home_dir():
"""Get user's home directory while preferring a possibly set HOME
environment variable
"""
# os.path.expanduser() behaves differently for '~' and '~someuser' as
# parameters: when called with an explicit username, the possibly set
# environment variable HOME is no longer respected. So we have to check if
# it is set and only expand the user's home directory if HOME is unset.
if os.environ.get('HOME', ''):
return os.environ.get('HOME')
else:
return os.path.expanduser('~%s' % os.environ.get('USER', ''))
So, as HOME is set to /root, this results in borg trying to access /root/.config.
But obviously borgfs is not root at that time, therefore it crashes with PermissionError.
So, borgfs is the user, but HOME is for root... (on Ubuntu and, see OP, also on Debian).
I must admit that it's unclear to me how to fix get_home_dir() so it works under all imaginable circumstances.
Obviously, we can't rely on $HOME (== this issue).
But the get_home_dir() code seems to tell that HOME should have precendence over ~$USER, when HOME is available.
Shall we reverse the logic, so check $USER first and if set, use ~$USER and only if not set look at $HOME?
Yes, it's very strange. I thought it might have to do with the fact that mount is suid root, so it runs with root permissions, but that does not seem to explain why HOME is set to /root. The following script:
#!/usr/bin/env python
import os
print(os.environ['HOME'])
with its permissions set like /bin/mount:
-rwsr-xr-x 1 root root 58 dec 1 21:59 print_home.py*
-rwsr-xr-x 1 root root 93K nov 23 2016 /bin/mount*
does output output /home/user and not /root
From the docs:
On Unix, an initial ~ is replaced by the environment variable HOME if it is set; otherwise the current user’s home directory is looked up in the password directory through the built-in module pwd. An initial ~user is looked up directly in the password directory.
That looks like the right thing to do in this case, but yes, it violates the sensible maxim that an explicitly set HOME variable should take precedence.
It would be good if we could find out why HOME is not set to the user's home dir in this case...
@mgrachten suid is ignored for scripts.
SUID - Sudden Unexpected Infant Death
That explains why young borg die.
suid is ignored for scripts.
That's good to know, but a suid root executable of the following example does not produce /root either:
#include<stdio.h>
#include<stdlib.h>
main()
{
printf(getenv("HOME"));
}
Ah, but if I invoke the same executable with an fstab line like this:
/dev/xxx /mnt/yyy fuse.printhomefs defaults,user,owner,noauto 0 0
then it returns /root!
I was confused about the suid root thing, because obviously the problem manifests itself not in the suid root executable (mount), but in the process it spawns (borgfs), which is not suid root.
@enkore any idea what has to be done to fix and not to break anything?
If I understand correctly from discussions elswhere that operating on a repo using different users is discouraged (is this true even if only one user performs write actions and the others only read actions?) then the whole notion of a borg repo as an fstab entry (with the users option) seems misguided to me, since it suggests that the repo may be mounted by any user. If in fact the mounting of a repo should be the sole privilege of the user owning that repo, then I think that repo should not appear in a system wide configuration file like /etc/fstab.
That does not solve the problem of the incorrect $HOME value, but would dissolve it ;-)
@mgrachten that is not borg specific, but a general multi-user system administration problem. If one adjusts permissions accordingly so everybody who should use the repo can r/w all the files/dirs in there and newly created files/dirs will also have such permissions, borg will be fine with that. Not very much different from having a file share for multiple users. setgid dirs and ACLs can help achieving that.
Or just always use same user, easier.
Note: there might be a workaround for this for borg >= 1.1.4 using BORG_BASE_DIR env var, try it.
Yes, this works for me, great!
I need to use fusermount -u /mnt/repo to unmount however, umount /mnt/repo gives me a permission denied error. Is this expected behavior?