DISCLAIMER
USE THIS GUIDE AT YOUR OWN RISK. I MAKE NO GUARANTEE OF FUNCTIONALITY OR SECURITY. YOU SHOULD BE AWARE THAT YOU ARE EXPOSING PARTS OF YOUR NETWORK TO THE PUBLIC AT LEAST TEMPORARILY. THIS IS ALWAYS A RISK.
ONCE AGAIN - BY FOLLOWING THIS GUIDE, YOU DO SO ENTIRELY AT YOUR OWN RISK AND RESPONSIBILITY.
This tutorial utilizes the the following apps and tools to set up and automatically backup a snap package based nextcloud server with encryption certificates by lets-encrypt on a EndeavourOS system, accessible from your local network or by VPN (VPN instructions not included):
- snap
- apparmor
- cronie
- nextcloud_snap
- dnsmasq
Prerequisites
- A public domain/subdomain pointing to your routerâs public ip address (needed to get officially signed encryption certificates)
- If you donât own a static IP address, youâll need a working DynDNS setup.
- This guide assumes youâre running an EndeavourOS installation, with itâs included tools and utilities.
- PAY ATTENTION to the firewall rules, itâs assumed yourâre using the âpublicâ zone as a default. If not you might have to customize the rules slightly.
Install snap and apparmor
yay -S snapd
sudo systemctl enable --now snapd.socket
yay -S apparmor
sudo systemctl enable apparmor
Reboot!
Open the grub settings and edit the following line to add the needed kernel-parameters, then regenerate the grub config:
Open the config file:
sudo nano /etc/default/grub
Locate and extend the following line by the âapparmorâ and âsecurityâ parameters:
GRUB_CMDLINE_LINUX_DEFAULT="... apparmor=1 security=apparmor ..."
Update grub:
grub-mkconfig -o /boot/grub/grub.cfg
Reboot!
Check if apparmor is up and running:
systemctl status apparmor
Enable the snap apparmor service and add classic snap support by creating a symbolic link:
sudo systemctl enable --now snapd.apparmor.service
sudo ln -s /var/lib/snapd/snap /snap
Add the snap binary installation folder to the PATH:
Create/Open:
sudo nano /etc/sudoers.d/90_snap
Add the following (insert your username):
Defaults:<your-user-name> secure_path="/usr/local/sbin:/usr/local/bin:/usr/bin:/var/lib/snapd/snap/bin"
Reboot!
Test:
sudo snap install hello-world
This command should return âHello World!â:
hello-world
This command should return a âDenied ErrorâŚâ as a sign that apparmor is working:
hello-world.evil
As a preparation for the next steps install and enable cronie:
sudo pacman -S cronie
sudo systemctl enbale --now cronie
Set a static IP to the server
== Set a static IP address to the server using your favorite network configuration tools. ==
== Add Port-Forwardings to your routerâs config. Add 80 tcp, 443 tcp pointing to your static server IP address. ==
If you need further informations, consult your routerâs manual
Afterwards edit your serverâs firewall configuration to accept inbound traffic at 80/tcp, 443/tcp and 53/tcp+udp from your local network only.
ATTENTION! You have to change the networkâs IP address to fit your own network.
sudo firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" port port="53" protocol="udp" accep
t' --permanent
sudo firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" port port="53" protocol="tcp" accep
t' --permanent
sudo firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" port port="80" protocol="tcp" accep
t' --permanent
sudo firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" port port="443" protocol="tcp" accep
t' --permanent
Install the Nextcloud Server and generate letâs encrypt certificates
Install nextcloud_snap
sudo snap install nextcloud
Goto http://localhost using your browser and follow the steps shown there!
Create lets-encrypt encryption certificates
First temporary open your server to the public by adding port openings to the âRuntimeâ configuration of your firewall:
sudo firewall-cmd --zone=public --add-port=443/tcp
sudo firewall-cmd --zone=public --add-port=80/tcp
Configure nextcloud-snap to use new official certificates by âletâs encryptâ:
sudo -i
nextcloud.enable-https lets-encrypt
exit
When everything worked well, remove public access to your server by reloading the firewall. This will remove temporary âRuntimeâ rules and limit access to local network only again:
sudo firewall-cmd --reload
Fine-tune nextcloud_snap (Insert your domain instead of sub.domain.tld):
sudo snap connect nextcloud:removable-media
sudo snap connect nextcloud:network-observe
sudo snap set nextcloud php.memory-limit=512M
sudo snap set nextcloud nextcloud.cron-interval=5m
sudo snap set nextcloud http.compression=true
sudo nextcloud.occ config:system:set trusted_domains 1 --value="sub.domain.tld"
Setup a local DNS service
Next we set up dnsmasq, which enables us to use our domain name inside the network while utilizing the lets-encrypt certificate.
Edit â/etc/dnsmasq.confâ add/uncomment/customize:
## exclude libvirt virtual network this is optional
except-interface=virbr0
## insert the IP address of your server/local DNS i.e. 192.168.1.20
bind-dynamic
listen-address=::1,127.0.0.1,<your local dns server ip>
no-resolv
domain-needed
bogus-priv
## Insert the desired public DNS servers 8.8.8.8 / 8.8.4.4 (Google) for example.
## You can use any other public DNS Servers. Pretty sure you don't want to have
## Google.
server=<replace with public dns-server1>
server=<replace with public dns-server2>
cache-size=1000
Edit your DNS serverâs hosts file (/etc/hosts) by adding your server IP and the domain name you want to associate to it:
<replace with your server ip> sub.domain.tld
Enable dnsmasq via systemd:
sudo systemctl enable dnsmasq
Reboot!
== Configure your router to provide your custom local DNS server IP to dhcp clients ==
If further informations are needed, consult your routerâs manual
Configure an automatic backup script executed by cron
Create 3 new files and add the following lines.
Edit the TARGET path and RETENTION days variables inside the snapsnapshot.sh file as needed:
cd
mkdir bin
sudo nano bin/snapsnapshot.sh
sudo nano bin/fw_open.sh
sudo nano bin/fw_close.sh
snapsnapshot.sh - slightly extended version of scubamucâs origianl work.
#!/bin/bash
##############################################################
#
# ATTENTION! ATTENTION! ATTENTION! ATTENTION! ATTENTION!
#
# This is a slighty extended version, adding two support scripts.
# The original version of the script can be found here:
#
# Script description -scubamuc- https://scubamuc.github.io/
# Nextcloud-snap backup with Snap snapshot
#
# Thanks to -scubamuc- for his original work!
#
# ATTENTION! ATTENTION! ATTENTION! ATTENTION! ATTENTION!
#
##############################################################
## create target directory "sudo mkdir /mnt/Backup"
## snapshot rotation 14 days
## create crontab as root for automation
## 0 3 * * * /home/$USER/bin/snapsnapshot.sh
##############################################################
# VARIABLES #
##############################################################
SNAPNAME="nextcloud"
TARGET="/mnt/Backup" ## target directory
LOG="$TARGET/snapbackup-nc.log" ## logfile
SOURCE="/var/lib/snapd/snapshots" ## source directory
RETENTION="13" ## retention in days
##############################################################
# FUNCTIONS #
##############################################################
## Timestamp for Log ##
timestamp()
{
date +"%Y-%m-%d %T"
}
##############################################################
# SCRIPT #
##############################################################
## must be root, enter sudo password for manual snapshot
## sudo pwd
## start log
echo "********************************************************" >> "$LOG" ; ## log seperator
echo "$(timestamp) -- Snapbackup "$SNAPNAME" Start" >> "$LOG" ; ## start log
## optional stop snap for snapshot
sudo snap stop "$SNAPNAME" ;
## create snap snapshot
sudo snap save --abs-time "$SNAPNAME" ;
## open firewall for certbot/letsencrypt
sudo ./fw_open.sh ;
## optional if stopped restart snap after snapshot (it will issue certificate renewal also)
sudo snap start "$SNAPNAME" ;
## wait 45 seconds for certbot to finish and close firewall again
sudo sleep 45 ;
sudo ./fw_close.sh ;
## find snapshot file in $SOURCE and move to $TARGET
sudo find "$SOURCE"/ -maxdepth 1 -name "*.zip" -exec mv {} "$TARGET"/ \; # find and move
## find old snapshots and delete snapshots older than $RETENTION days
sudo find "$TARGET"/ -name "*.zip" -mtime +"$RETENTION" -exec rm -f {} \; # find and delete
## end log
echo "$(timestamp) -- Snapbackup "$SNAPNAME" End " >> "$LOG" ; ## end log
echo "" >> "$LOG" ; ## log linefeed
exit
fw_open.sh
#!/bin/bash
## Add port openings to the "Runtime" config to temporary open them for certbot
sudo firewall-cmd --zone=public --add-port=443/tcp ;
sudo firewall-cmd --zone=public --add-port=80/tcp ;
exit
fw_close.sh
#!/bin/bash
## remove temporary port openings by reloading the firewall (remove Runtime rules)
sudo firewall-cmd --reload ;
exit
Change ownership and permissions of the script files:
cd
sudo chown root:root bin/snapsnapshot.sh
sudo chown root:root bin/fw_open.sh
sudo chown root:root bin/fw_close.sh
sudo chmod 700 bin/snapsnapshot.sh
sudo chmod 700 bin/fw_open.sh
sudo chmod 700 bin/fw_close.sh
Edit the crontab of the root account
Edit the root crontab:
sudo crontab -e
Add the following line (change $USER to your username):
0 3 * * * /home/$USER/bin/snapsnapshot.sh
This example will create a daily snapshot at 03:00 AM, temporary expose port 80/443 tcp to the public for a 45 second time-window and try to renew certificates with âletâs encryptâ, afterwards close the ports to the public again and finally move the backup to your backup directory.
The chosen command order in âsnapsnapshot.shâ relies on the fact, that certbot will try to renew certificates with âletâs encrpytâ automatically, right after the services get started again, which where stopped for the backup creation.
Enjoy your personal Cloud!
I recommend you take a look at this:
https://github.com/nextcloud-snap/nextcloud-snap/wiki
Other Useful commands and tips
Check if the certificate renewal with lets-encrypt is working correctly
To see if cerbot/lets-encrypt renewal worked out you can have a look at the log-file, usually certbot will continuously try to renew the certificates starting 30 days before they expire, before that it wonât even try to:
sudo journalctl -u snap.nextcloud.renew-certs.service