Running command in hook on behalf of another user? #841

Closed
opened 2024-03-13 07:25:41 +00:00 by knedlyk · 7 comments

What I'm trying to do and why

Hi! I use borgmatic for backing up certain apps, which I need to stop on behalf of the www-data user before and start after running the backup.

I've added a couple of hooks:

before_backup:
  - echo "`date` - Starting backup"`
  - apprise -c /etc/apprise.yaml -t "⚙ PREPARING" --tag=test
  - sudo - u www-data php /var/www/mycloud/myapp config:system:set maintenance --value=true

after_backup:
  - echo "`date` - Finished backup"`
  - apprise -c /etc/apprise.yaml -t "✅ DONE" --tag=test
  - sudo -u www-data php /var/www/mycloud/myapp config:system:set maintenance --value=false

When executed borgmatic reports that:

Mar 05 07:22:59 my.local borgmatic[1105519]: CRITICAL sudo: no valid sudoers sources found, quitting
Mar 05 07:22:59 my.local borgmatic[1105519]: CRITICAL sudo: error initializing audit plugin sudoers_audit
Mar 05 07:22:59 my.local borgmatic[1105519]: CRITICAL Command 'sudo -u www-data php /var/www/mycloud/myapp config:system:set maintenance --value=false' returned non-zero exit status 1.

Is it possible to use sudo in hooks somehow or what to use?

UPD:

The only workaround, which I've found is to replace the string variable manually:

before_backup:
    - /usr/local/bin/app-maint-on

where app-maint-on:

#!/bin/bash
# Enable maintenance mode in app
printf "1,$ s/'maintenance' => false/'maintenance' => true/g\nw! /var/www/mycloud/config/config.php\nq!" | ex - /var//www/nextcloud/config/config.php

But that is like a workaround, which doesn't allow me to process the exit code from the execution of the app command.

borgmatic version

1.8.3

borgmatic installation method

deb package

Borg version

1.2.0

Python version

3.10.12

Database version (if applicable)

mysql Ver 15.1 Distrib 10.6.16-MariaDB

Operating system and version

Ubuntu 22.04.4 LTS"

### What I'm trying to do and why Hi! I use borgmatic for backing up certain apps, which I need to stop on behalf of the `www-data` user before and start after running the backup. I've added a couple of hooks: ``` before_backup: - echo "`date` - Starting backup"` - apprise -c /etc/apprise.yaml -t "⚙ PREPARING" --tag=test - sudo - u www-data php /var/www/mycloud/myapp config:system:set maintenance --value=true after_backup: - echo "`date` - Finished backup"` - apprise -c /etc/apprise.yaml -t "✅ DONE" --tag=test - sudo -u www-data php /var/www/mycloud/myapp config:system:set maintenance --value=false ``` When executed borgmatic reports that: ``` Mar 05 07:22:59 my.local borgmatic[1105519]: CRITICAL sudo: no valid sudoers sources found, quitting Mar 05 07:22:59 my.local borgmatic[1105519]: CRITICAL sudo: error initializing audit plugin sudoers_audit Mar 05 07:22:59 my.local borgmatic[1105519]: CRITICAL Command 'sudo -u www-data php /var/www/mycloud/myapp config:system:set maintenance --value=false' returned non-zero exit status 1. ``` Is it possible to use sudo in hooks somehow or what to use? UPD: The only workaround, which I've found is to replace the string variable manually: ``` before_backup: - /usr/local/bin/app-maint-on ``` where app-maint-on: ``` #!/bin/bash # Enable maintenance mode in app printf "1,$ s/'maintenance' => false/'maintenance' => true/g\nw! /var/www/mycloud/config/config.php\nq!" | ex - /var//www/nextcloud/config/config.php ``` But that is like a workaround, which doesn't allow me to process the exit code from the execution of the app command. ### borgmatic version 1.8.3 ### borgmatic installation method deb package ### Borg version 1.2.0 ### Python version 3.10.12 ### Database version (if applicable) mysql Ver 15.1 Distrib 10.6.16-MariaDB ### Operating system and version Ubuntu 22.04.4 LTS"
Owner

Is it possible to use sudo in hooks somehow or what to use?

In theory, yes—if you're running as the root user and sudo-ing to a non-root user. So when you're running borgmatic, what user are you running it as? Does that user have sudo permissions? If you run the full sudo -u www-data ... command as that user at the command-line, does it work? And how are you actually kicking off borgmatic? systemd, cron, manually, etc?

Also, side note: Once you upgrade borgmatic, you might consider switching to borgmatic's native Apprise support so that you don't have to call out to Apprise manually in before/after hooks.

> Is it possible to use sudo in hooks somehow or what to use? In theory, yes—if you're running as the root user and sudo-ing to a non-root user. So when you're running borgmatic, what user are you running it as? Does that user have `sudo` permissions? If you run the full `sudo -u www-data ...` command as that user at the command-line, does it work? And how are you actually kicking off borgmatic? systemd, cron, manually, etc? Also, side note: Once you upgrade borgmatic, you might consider switching to borgmatic's [native Apprise support](https://torsion.org/borgmatic/docs/how-to/monitor-your-backups/#apprise-hook) so that you don't have to call out to Apprise manually in before/after hooks.
Author

Is it possible to use sudo in hooks somehow or what to use?

In theory, yes—if you're running as the root user and sudo-ing to a non-root user. So when you're running borgmatic, what user are you running it as? Does that user have sudo permissions? If you run the full sudo -u www-data ... command as that user at the command-line, does it work? And how are you actually kicking off borgmatic? systemd, cron, manually, etc?

I have created systems service and time units:

# cat borgmatic.service
[Unit]
Description=borgmatic backup
Wants=network-online.target
After=network-online.target
ConditionACPower=true

[Service]
Type=oneshot

LockPersonality=true
MemoryDenyWriteExecute=no
NoNewPrivileges=yes
PrivateDevices=yes
PrivateTmp=yes
ProtectClock=yes
ProtectControlGroups=yes
ProtectHostname=yes
ProtectKernelLogs=yes
ProtectKernelModules=yes
ProtectKernelTunables=yes
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6 AF_NETLINK
RestrictNamespaces=yes
RestrictRealtime=yes
RestrictSUIDSGID=yes
SystemCallArchitectures=native
SystemCallFilter=@system-service
SystemCallErrorNumber=EPERM
ProtectSystem=full

CapabilityBoundingSet=CAP_DAC_READ_SEARCH CAP_NET_RAW

Nice=19
CPUSchedulingPolicy=batch
IOSchedulingClass=best-effort
IOSchedulingPriority=7
IOWeight=100

Restart=no
LogRateLimitIntervalSec=0

ExecStartPre=sleep 1m
ExecStart=systemd-inhibit --who="borgmatic" --why="Prevent interrupting scheduled backup" borgmatic --syslog-verbosity 1
# cat borgmatic.timer
[Unit]
Description=Run borgmatic backup

[Timer]
OnCalendar=*-*-* 2:30:00
Persistent=true

[Install]
WantedBy=timers.target

Also, side note: Once you upgrade borgmatic, you might consider switching to borgmatic's native Apprise support so that you don't have to call out to Apprise manually in before/after hooks.

Well, with native it demands v.1.8.5, though I haven't found the proper deb package for my Ubuntu 22.04 :(
Additionally, in native call I do not understand how to deal with hooks: are they called after apprise or before? How are they interconnected?

> > Is it possible to use sudo in hooks somehow or what to use? > > In theory, yes—if you're running as the root user and sudo-ing to a non-root user. So when you're running borgmatic, what user are you running it as? Does that user have `sudo` permissions? If you run the full `sudo -u www-data ...` command as that user at the command-line, does it work? And how are you actually kicking off borgmatic? systemd, cron, manually, etc? I have created systems service and time units: ``` # cat borgmatic.service [Unit] Description=borgmatic backup Wants=network-online.target After=network-online.target ConditionACPower=true [Service] Type=oneshot LockPersonality=true MemoryDenyWriteExecute=no NoNewPrivileges=yes PrivateDevices=yes PrivateTmp=yes ProtectClock=yes ProtectControlGroups=yes ProtectHostname=yes ProtectKernelLogs=yes ProtectKernelModules=yes ProtectKernelTunables=yes RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6 AF_NETLINK RestrictNamespaces=yes RestrictRealtime=yes RestrictSUIDSGID=yes SystemCallArchitectures=native SystemCallFilter=@system-service SystemCallErrorNumber=EPERM ProtectSystem=full CapabilityBoundingSet=CAP_DAC_READ_SEARCH CAP_NET_RAW Nice=19 CPUSchedulingPolicy=batch IOSchedulingClass=best-effort IOSchedulingPriority=7 IOWeight=100 Restart=no LogRateLimitIntervalSec=0 ExecStartPre=sleep 1m ExecStart=systemd-inhibit --who="borgmatic" --why="Prevent interrupting scheduled backup" borgmatic --syslog-verbosity 1 ``` ``` # cat borgmatic.timer [Unit] Description=Run borgmatic backup [Timer] OnCalendar=*-*-* 2:30:00 Persistent=true [Install] WantedBy=timers.target ``` > > Also, side note: Once you upgrade borgmatic, you might consider switching to borgmatic's [native Apprise support](https://torsion.org/borgmatic/docs/how-to/monitor-your-backups/#apprise-hook) so that you don't have to call out to Apprise manually in before/after hooks. Well, with native it demands v.1.8.5, though I haven't found the proper deb package for my Ubuntu 22.04 :( Additionally, in native call I do not understand how to deal with hooks: are they called after apprise or before? How are they interconnected?
Owner

I have created systems service and time units:

Okay, it looks like that systemd service/timer is running as the root user. That's good. So does your full sudo command work when run from root manually at the command-line or do you get the same error?

It's possible that some of the security options (between Type=oneshot and Nice=19) are interfering with the sudo command. You could try commenting some or all of them out, reloading your systemd service, and seeing if that fixes the issue. If it does, you can add them back by halves until you find the culprit.

Well, with native it demands v.1.8.5, though I haven't found the proper deb package for my Ubuntu 22.04 :(

Yeah, if you're using debs you'll have to wait until a new versions is available. There are several other ways to install though depending on your system and preferences.

Additionally, in native call I do not understand how to deal with hooks: are they called after apprise or before? How are they interconnected?

They're not really interconnected; they're called separately. But just in terms of ordering, the native Apprise hook start is called before before_backup and finish after after_backup.

> I have created systems service and time units: Okay, it looks like that systemd service/timer is running as the root user. That's good. So does your full sudo command work when run from root manually at the command-line or do you get the same error? It's possible that some of the security options (between `Type=oneshot` and `Nice=19`) are interfering with the sudo command. You could try commenting some or all of them out, reloading your systemd service, and seeing if that fixes the issue. If it does, you can add them back by halves until you find the culprit. > Well, with native it demands v.1.8.5, though I haven't found the proper deb package for my Ubuntu 22.04 :( Yeah, if you're using debs you'll have to wait until a new versions is available. There are several [other ways to install](https://torsion.org/borgmatic/docs/how-to/set-up-backups/) though depending on your system and preferences. > Additionally, in native call I do not understand how to deal with hooks: are they called after apprise or before? How are they interconnected? They're not really interconnected; they're called separately. But just in terms of ordering, the native Apprise hook start is called before `before_backup` and finish after `after_backup`.
Author

I have created systems service and time units:

Okay, it looks like that systemd service/timer is running as the root user. That's good. So does your full sudo command work when run from root manually at the command-line or do you get the same error?

It's possible that some of the security options (between Type=oneshot and Nice=19) are interfering with the sudo command. You could try commenting some or all of them out, reloading your systemd service, and seeing if that fixes the issue. If it does, you can add them back by halves until you find the culprit.

NoNewPrivileges=yes
RestrictSUIDSGID=yes

You are right! Probably these two options /^^^ are influencing, from man:

NoNewPrivileges=yes and RestrictSUIDSGID=yes prevent any scripts from taking advantage of password-less sudo configurations or capabilites. Note that when running in user mode or in system mode without User=, setting RestrictSUIDSGID=yes will imply NoNewPrivileges=yes.

Thank you for pointing my attention. Actually, the idea is to protect files from accidental changing by borgmatic itself. 🙄

Well, with native it demands v.1.8.5, though I haven't found the proper deb package for my Ubuntu 22.04 :(

Yeah, if you're using debs you'll have to wait until a new versions is available. There are several other ways to install though depending on your system and preferences.

I see

Additionally, in native call I do not understand how to deal with hooks: are they called after apprise or before? How are they interconnected?

They're not really interconnected; they're called separately. But just in terms of ordering, the native Apprise hook start is called before before_backup and finish after after_backup.

Good to know! Perhaps it is a good idea to add this tip to the documentation?..

> > I have created systems service and time units: > > Okay, it looks like that systemd service/timer is running as the root user. That's good. So does your full sudo command work when run from root manually at the command-line or do you get the same error? > > It's possible that some of the security options (between `Type=oneshot` and `Nice=19`) are interfering with the sudo command. You could try commenting some or all of them out, reloading your systemd service, and seeing if that fixes the issue. If it does, you can add them back by halves until you find the culprit. ``` NoNewPrivileges=yes RestrictSUIDSGID=yes ``` You are right! Probably these two options /^^^ are influencing, from man: `NoNewPrivileges=yes` and `RestrictSUIDSGID=yes `prevent any scripts from taking advantage of password-less sudo configurations or capabilites. Note that when running in user mode or in system mode without `User=`, setting `RestrictSUIDSGID=yes` will imply `NoNewPrivileges=yes`. Thank you for pointing my attention. Actually, the idea is to protect files from accidental changing by borgmatic itself. 🙄 > > > Well, with native it demands v.1.8.5, though I haven't found the proper deb package for my Ubuntu 22.04 :( > > Yeah, if you're using debs you'll have to wait until a new versions is available. There are several [other ways to install](https://torsion.org/borgmatic/docs/how-to/set-up-backups/) though depending on your system and preferences. > I see > > Additionally, in native call I do not understand how to deal with hooks: are they called after apprise or before? How are they interconnected? > > They're not really interconnected; they're called separately. But just in terms of ordering, the native Apprise hook start is called before `before_backup` and finish after `after_backup`. Good to know! Perhaps it is a good idea to add this tip to the documentation?..
Owner

You are right! Probably these two options /^^^ are influencing, from man:

Thank you for pointing my attention. Actually, the idea is to protect files from accidental changing by borgmatic itself. 🙄

Glad to hear that was it! And yeah, security is always a trade-off with convenience. I don't know why you're setting maintenance mode during backups, but if it's because you're worried about getting a consistence/atomic backup snapshot, you may be able to get that through other means. E.g. if your app is database-backed, it should be possible to get a consistent dump even if your application is running during the backup. And if your app is filesystem-backed, you could look into filesystem snapshots to support backups while the application stays online.

Good to know! Perhaps it is a good idea to add this tip to the documentation?..

Good idea!

> You are right! Probably these two options /^^^ are influencing, from man: > Thank you for pointing my attention. Actually, the idea is to protect files from accidental changing by borgmatic itself. 🙄 Glad to hear that was it! And yeah, security is always a trade-off with convenience. I don't know why you're setting maintenance mode during backups, but if it's because you're worried about getting a consistence/atomic backup snapshot, you may be able to get that through other means. E.g. if your app is database-backed, it should be possible to get a consistent dump even if your application is running during the backup. And if your app is filesystem-backed, you could look into filesystem snapshots to support backups while the application stays online. > Good to know! Perhaps it is a good idea to add this tip to the documentation?.. Good idea!
witten added the
question / support
label 2024-03-13 18:44:49 +00:00
Author

You are right! Probably these two options /^^^ are influencing, from man:

Thank you for pointing my attention. Actually, the idea is to protect files from accidental changing by borgmatic itself. 🙄

Glad to hear that was it! And yeah, security is always a trade-off with convenience. I don't know why you're setting maintenance mode during backups, but if it's because you're worried about getting a consistence/atomic backup snapshot, you may be able to get that through other means. E.g. if your app is database-backed, it should be possible to get a consistent dump even if your application is running during the backup. And if your app is filesystem-backed, you could look into filesystem snapshots to support backups while the application stays online.

Backup process consumes a lot of resources, so the app is almost not functional. Plus the artifacts produced by the app are also backed up. I have a mix of filesystem and DB backups. Still thinking what may be the best backup solution, so playing with borgmatic :)

> > You are right! Probably these two options /^^^ are influencing, from man: > > > Thank you for pointing my attention. Actually, the idea is to protect files from accidental changing by borgmatic itself. 🙄 > > Glad to hear that was it! And yeah, security is always a trade-off with convenience. I don't know why you're setting maintenance mode during backups, but if it's because you're worried about getting a consistence/atomic backup snapshot, you may be able to get that through other means. E.g. if your app is database-backed, it should be possible to get a consistent dump even if your application is running during the backup. And if your app is filesystem-backed, you could look into filesystem snapshots to support backups while the application stays online. > Backup process consumes a lot of resources, so the app is almost not functional. Plus the artifacts produced by the app are also backed up. I have a mix of filesystem and DB backups. Still thinking what may be the best backup solution, so playing with borgmatic :)
Owner

Understood. Well I hope it works out for you! Feel free to file tickets for anything else that comes up. I'll close this one for now.

Understood. Well I hope it works out for you! Feel free to file tickets for anything else that comes up. I'll close this one for now.
Sign in to join this conversation.
No Milestone
No Assignees
2 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: borgmatic-collective/borgmatic#841
No description provided.