Remote maintenance script for use with Veeam

Support intro

Sorry to hear you’re facing problems :slightly_frowning_face:

help.nextcloud.com is for home/non-enterprise users. If you’re running a business, paid support can be accessed via portal.nextcloud.com where we can ensure your business keeps running smoothly.

In order to help you as quickly as possible, before clicking Create Topic please provide as much of the below as you can. Feel free to use a pastebin service for logs, otherwise either indent short log examples with four spaces:

example

Or for longer, use three backticks above and below the code snippet:

longer
example
here

Some or all of the below information will be requested if it isn’t supplied; for fastest response please provide as much as you can :heart:

Nextcloud version (eg, 20.0.5): 21.0.1
Operating system and version (eg, Ubuntu 20.04): Ubuntu 20.04
Apache or nginx version (eg, Apache 2.4.25): current Apache
PHP version (eg, 7.4): PHP 7.4

The issue you are facing:
I use Veeam Backup & Replication (Community Edition) for backups on my homeserver. The VMs are running on a Windows Hyper-V 2019 environment, mostly because I’m familiar with it, it’s Veeam compatible, and I got the license for free (through an education program).

Given that Veeam sadly doesn’t support application aware processing for mySQL/MariaDB on the regular jobs, I tried to come up with an alternate route to having a consistent backup of the entire VM including the database.
Some googling said that it’s probably best to put the nextcloud VM into maintenance mode before backup. Since Veeam does support pre- and post-backup Scripts, easy enough. I’ll just write a script to SSH into the nextcloud VM and enable maintenance mode.

The initial script (powershell, if it isn’t obvious, since it needs to run on the Veeam server and it’s what I’m most familiar with):

#Credentials erstellen für die SSH-Verbindung zur nextcloud-vm
$username = “root”
$password = “yeahnopenotmakingthatpublic”
$secstr = New-Object -TypeName System.Security.SecureString
$password.ToCharArray() | ForEach-Object {$secstr.AppendChar($_)}
$cred = new-object -typename System.Management.Automation.PSCredential -argumentlist $username, $secstr

#Die Wartung per SSH aktivieren
New-SSHTrustedHost -SSHHost 192.168.12.198 -FingerPrint 3b:9b:5f:f7:notpubliceither
New-SSHSession -ComputerName 192.168.12.198 -Port 22 -Credential $cred
Invoke-SSHCommand -SessionId 0 -Command “sudo -u www-data php /var/www/nextcloud/occ maintenance:mode --on”
Remove-SSHSession -Index 0

That worked very well at the start and then I dug into some more tutorials about tightening security given that I want to expose my nextcloud instance to the wider web.

This is one of the tutorials I used: Nextcloud - Complete Setup Guide - LearnLinux.tv Wiki

This is the relevant step that ‘broke’ my maintenance mode script for me:

Correct permissions of config.php

sudo chmod 660 /var/www/nc.learnlinux.tv/config/config.php
sudo chown root:www-data /var/www/nc.learnlinux.tv/config/config.php

It no longer turns on maintenance mode, output:

Output : {Console has to be executed with the user that owns the file config/config.php, Current user id: 33, Owner id of config.php: 0, Try adding
‘sudo -u #0’ to the beginning of the command (without the single quotes)…}

Story short, blindly following that suggestion and putting #0 in the middle didn’t help a bit.
Some troubleshooting later I came up with the bright idea to cut down the credentials to this line of code since I’m SSHing in as root anyway:

Invoke-SSHCommand -SessionId 0 -Command “php /var/www/nextcloud/occ maintenance:mode --on”

That’ll turn maintenance mode on, but also break the write permissions on the config.php file, meaning that the nextcloud instance is borked.

The permissions after doing that:

root@RIGNextcloud:~# ls -l /var/www/nextcloud/config/
-rw-r----- 1 root www-data 1049 Mai 18 14:43 config.php
-rwxrwxr-x 1 www-data www-data 59161 Apr 8 15:31 config.sample.php

what they need to look like to work:

root@RIGNextcloud:~# ls -l /var/www/nextcloud/config/
-rw-r----- 1 root www-data 1049 Mai 18 14:43 config.php
-rwxrwxr-x 1 www-data www-data 59161 Apr 8 15:31 config.sample.php

So yeah, easy enough fix for my script. Just add a line to fix the permissions.

#Credentials erstellen für die SSH-Verbindung zur nextcloud-vm
$username = “root”
$password = “”
$secstr = New-Object -TypeName System.Security.SecureString
$password.ToCharArray() | ForEach-Object {$secstr.AppendChar($_)}
$cred = new-object -typename System.Management.Automation.PSCredential -argumentlist $username, $secstr

#Die Wartung per SSH aktivieren
New-SSHTrustedHost -SSHHost 192.168.12.198 -FingerPrint 3b:9b:5f:f7:
New-SSHSession -ComputerName 192.168.12.198 -Port 22 -Credential $cred
Invoke-SSHCommand -SessionId 0 -Command “php /var/www/nextcloud/occ maintenance:mode --on”
Invoke-SSHCommand -SessionId 0 -Command “chmod 660 /var/www/nextcloud/config/config.php”
Remove-SSHSession -Index 0

Except - who am I kidding? That’s a heaping pile of dung of a workaround.
Unfortunately, I’m also completely missing the ‘right’ way of doing it. It’s probably blatantly obvious, but I’m not getting anywhere. Halp?

Also, if you have any other suggestions for improving the code, I’d be happy to use them. Maybe stop the mySQL service entirely? Or is the entire ‘put into maintenance’ completely unnecessary?

(Please no mySQL vs mariaDB discussion. I installed with mySQL and I’d switch to mariaDB if I could manage it without borking my nextcloud. Good thing I have snapshots and backups. But that’s a topic for a different day.)

Thanks in advance :slight_smile:

Had to reinstall Nextcloud due to implementing the nginx reverse-proxy and also changing domains. That had me running into the problem that I kept getting a redicrect to the old domain and in the end it was just faster to reinstall since my nextcloud instance was still in the testing phase.

After that, the previous invoke-ssh command has been working again.
As such, my maintenance script is now

#Credentials erstellen für die SSH-Verbindung zur nextcloud-vm
$username = “root”
$password = “rootpw”
$secstr = New-Object -TypeName System.Security.SecureString
$password.ToCharArray() | ForEach-Object {$secstr.AppendChar($_)}
$cred = new-object -typename System.Management.Automation.PSCredential -argumentlist $username, $secstr

#Die Wartung per SSH aktivieren
New-SSHTrustedHost -SSHHost 192.168.12.198 -FingerPrint b:22:e6:b6:bc:63:somemore
New-SSHSession -ComputerName 192.168.12.198 -Port 22 -Credential $cred
Invoke-SSHCommand -SessionId 0 -Command “sudo -u www-data php /var/www/nextcloud/occ maintenance:mode --on”
Remove-SSHSession -Index 0

just in case anyone wants to use it.