Skip to content

Instantly share code, notes, and snippets.

@bganne
Created August 21, 2021 10:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bganne/fd9e07badde7cf6917208a104b004b18 to your computer and use it in GitHub Desktop.
Save bganne/fd9e07badde7cf6917208a104b004b18 to your computer and use it in GitHub Desktop.
yunohost script
Vagrant.configure("2") do |config|
config.vm.box = "debian/buster64"
end
#!/bin/sh
set -eu
#
# CONFIGURATION
#
readonly DOMAIN=yunohost.example.com
readonly LAN=eth0
readonly LAN_IP4="10.0.2.15"
readonly LAN_GW4="10.0.2.2"
readonly LAN_PREFIX="24"
readonly LAN_NET4="10.0.2.0/$LAN_PREFIX"
readonly HOST_NAME=host
readonly HOST_FQDN="$HOST_NAME.$DOMAIN"
readonly DATA_DIR="/data"
readonly DATA_HOME="$DATA_DIR/home"
readonly DATA_MAIL="$DATA_DIR/mail"
readonly DATA_BACKUP="$DATA_DIR/backup"
readonly DATA_BACKUP_REMOTE="login@rsync.example.com:$HOST_NAME"
readonly DMZ=dmz0
readonly DMZ_NAME=dmz
readonly DMZ_FQDN="$DMZ_NAME.$DOMAIN"
readonly DMZ_GW4="192.168.100.1"
readonly DMZ_GW4_PTR="1.100.168.192"
readonly DMZ_IP4="192.168.100.2"
readonly DMZ_ROOTFS="/var/lib/lxc/$DMZ_NAME/rootfs"
readonly YN_USER=test
readonly YN_USER_FIRST='Test-first'
readonly YN_USER_LAST='Test-last'
readonly MAIL_POSTMASTER="postmaster@$DOMAIN"
readonly MAIL_RELAY_USER="$MAIL_POSTMASTER"
readonly MAIL_RELAY_HOST='[mail.example.com]:465'
readonly MAIL_IMAP_HOST='mail.example.com'
readonly MAIL_RELAY_PORT='465'
readonly TIMEZONE='Europe/Paris'
# disable interactive prompts for package config/install
export DEBIAN_FRONTEND=noninteractive
# helper to get password
getpass()
{
local p1 p2
while true; do
p1=$(systemd-ask-password "$* :")
p2=$(systemd-ask-password "$* (confirmation):")
if [ "x$p1" = "x$p2" ]; then
echo "$p1"
break
fi
echo "!!! Password mismatch, try again !!!" >&2
done
}
#
# FIREWALL
#
firewall()
{
# flush previous rules, delete chains and reset counters
for t in filter nat raw; do
iptables -t $t -F
iptables -t $t -X
iptables -t $t -Z
done
# enable loopback traffic
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
# enable statefull rules (after that, only need to allow NEW conections)
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
# drop packets with no known connections
iptables -A INPUT -m conntrack --ctstate INVALID -j DROP
iptables -A OUTPUT -m conntrack --ctstate INVALID -j DROP
iptables -A FORWARD -m conntrack --ctstate INVALID -j DROP
## INPUT
# accept local connections from LAN
iptables -A INPUT -i "$LAN" \
-j ACCEPT
# accept local connections to SSH and DNS/TCP from DMZ
iptables -A INPUT -i "$DMZ" \
-p tcp -m multiport --dports 22,53 \
-j ACCEPT
# accept local connections to DNS/UDP from DMZ
iptables -A INPUT -i "$DMZ" \
-p udp --dport 53 \
-j ACCEPT
# accept icmp
iptables -A INPUT -p icmp \
-j ACCEPT
## OUTPUT
# accept all
iptables -A OUTPUT -j ACCEPT
## FORWARD
# accept all to WAN (DMZ is not allowed to initiate to LAN)
iptables -A FORWARD -i "$DMZ" -o "$LAN" \
! -d "$LAN_NET4" \
-j ACCEPT
# accept ssh, smtp, http, https, submission, imaps to DMZ
iptables -A FORWARD -o "$DMZ" \
-p tcp -m multiport --dports 22,25,80,443,587,993 \
-j ACCEPT
# accept icmp
iptables -A FORWARD -p icmp \
-j ACCEPT
## NAT
# new connections to smtp, http, https, submission, imaps are redirected to DMZ
iptables -t nat -A PREROUTING -i "$LAN" \
-m conntrack --ctstate NEW \
-p tcp -m multiport --dports 25,80,443,587,993 \
-j DNAT --to-destination "$DMZ_IP4"
# tcp port 2222 is redirected to DMZ ssh
iptables -t nat -A PREROUTING -i "$LAN" \
-m conntrack --ctstate NEW \
-p tcp --dport 2222 \
-j DNAT --to-destination "$DMZ_IP4:22"
# DMZ is source-nated
iptables -t nat -A POSTROUTING -o "$LAN" \
-j SNAT --to-source "$LAN_IP4"
## LOGGING
iptables -A INPUT -j LOG --log-level warning --log-prefix '[FW INPUT]:'
iptables -A OUTPUT -j LOG --log-level warning --log-prefix '[FW OUTPUT]:'
iptables -A FORWARD -j LOG --log-level warning --log-prefix '[FW FORWARD ]:'
## Default policies: DROP
iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -P FORWARD DROP
} # end of firewall
# helper to run command in container
dmzexec()
{
lxc-attach -n "$DMZ_NAME" --clear-env --keep-var DEBIAN_FRONTEND -- /bin/sh -c "$*"
}
# helper to run occ commands in the container
nextcloud()
{
dmzexec "cd /var/www/nextcloud && sudo -u nextcloud php7.3 --define apc.enable_cli=1 occ $*"
}
#
# STOP
# stop dmz container
#
stop()
{
lxc-stop -n "$DMZ_NAME" || true
ip link del dev "$DMZ" || true
# disable routing
sysctl -w net.ipv4.conf.all.forwarding=0
} # end of stop
#
# START
# enable firewall and start dmz container
#
start()
{
stop
# create guest ifaces, needed for fw rules
ip link add dev "$DMZ" type veth peer guest
firewall
# enable routing
sysctl -w net.ipv4.conf.all.forwarding=1
# container interface setup
ip addr add "$DMZ_GW4/32" dev "$DMZ" peer "$DMZ_IP4/32"
ip link set dev "$DMZ" up
lxc-start -n "$DMZ_NAME"
lxc-wait -n "$DMZ_NAME" -s RUNNING
## move veth peer to container
# get netns pid
local nspid
nspid=$(lxc-info -n "$DMZ_NAME" -p|awk '/PID:/{print $2}')
[ -z "$nspid" ] && exit 1
# make netns avail. to iproute2...
mkdir -p /var/run/netns
rm -f "/var/run/netns/$nspid"
ln -s "/proc/$nspid/ns/net" "/var/run/netns/$nspid"
# move iface to container under eth0 name
ip link set guest name eth0 netns "$nspid"
# remove netns so iproute2 ignores it again
rm -f "/var/run/netns/$nspid"
# wait for the system to be fully up, to avoid issue with systemctl, dbus etc not ready
# it's a mess
while sleep 1; do
case "x$(dmzexec systemctl is-system-running --wait)" in
xrunning)
break
;;
xdegraded)
break
;;
esac
done
# enable eth0 in container
dmzexec ifup --force eth0
} # end of start()
#
# PROVISION
# setup host - must be run once
#
# update resolv.conf helper
dmz_resolvconf() {
rm -f "$DMZ_ROOTFS/etc/resolv.conf"
cat > "$DMZ_ROOTFS/etc/resolv.conf" << EOF
domain $DOMAIN
search $DOMAIN
nameserver $DMZ_GW4
EOF
chown 100000:100000 "$DMZ_ROOTFS/etc/resolv.conf"
}
idempotent_append() {
local guard='# yunohost provisioning - do not remove'
local file="$1"
grep -q -F "$guard" "$1" && file="/dev/null"
echo "$guard" >> "$file"
cat >> "$file"
}
provision() {
# get passwords
readonly YN_ADMIN_PASS="$(getpass "Yunohost admin password")"
readonly YN_USER_PASS="$(getpass "Yunohost user '$YN_USER' password")"
readonly MAIL_RELAY_PASS="$(getpass "Mail relay user '$MAIL_RELAY_USER' password")"
readonly BORG_PASSPHRASE="$(getpass "Borg backup passphrase")"
export BORG_PASSPHRASE
### Setup host
## sysctl network settings for the host
idempotent_append /etc/sysctl.conf << EOF
# disable ipv6 - I know, I know...
net.ipv6.conf.all.disable_ipv6=1
# harden ipv4 stack
# rpf makes sure dmz cannot spoof its address
net.ipv4.conf.all.rp_filter=1
net.ipv4.conf.all.accept_source_route=0
net.ipv4.conf.all.accept_redirects=0
net.ipv4.icmp_echo_ignore_broadcasts=1
net.ipv4.icmp_ignore_bogus_error_responses=1
net.ipv4.conf.all.log_martians=1
# optimized network settings
net.core.default_qdisc=fq_codel
net.ipv4.tcp_ecn=1
net.ipv4.tcp_sack=1
net.ipv4.tcp_dsack=1
# enable TCP fastopen
net.ipv4.tcp_fastopen=1027
EOF
sysctl -p /etc/sysctl.conf
apt-get -y update
apt-get -y dist-upgrade
apt-get -y install chrony \
dnsmasq \
lxc \
vim \
net-tools \
msmtp-mta \
bsd-mailx \
unattended-upgrades \
apt-listchanges \
borgbackup \
logwatch \
smartmontools
## setup Chrony
timedatectl set-timezone "$TIMEZONE"
[ -f /etc/chrony/chrony.conf.pkg ] || mv /etc/chrony/chrony.conf /etc/chrony/chrony.conf.pkg
cat > /etc/chrony/chrony.conf << EOF
pool 2.debian.pool.ntp.org iburst
keyfile /etc/chrony/chrony.keys
driftfile /var/lib/chrony/chrony.drift
logdir /var/log/chrony
maxupdateskew 100.0
rtcsync
makestep 1 3
allow $LAN_NET4
EOF
## configure dnsmasq
[ -f /etc/dnsmasq.conf.pkg ] || mv /etc/dnsmasq.conf /etc/dnsmasq.conf.pkg
cat > /etc/dnsmasq.conf << EOF
bogus-priv
resolv-file=/etc/resolv.dnsmasq
local=/$DOMAIN/
# need at least 1 except or will not answer
except-interface=enp0s4
no-dhcp-interface=$LAN
no-dhcp-interface=$DMZ
expand-hosts
domain=$DOMAIN
mx-host=$DOMAIN,$DOMAIN,10
ptr-record=$DMZ_GW4_PTR.in-addr.arpa,$HOST_FQDN
address=/use-application-dns.net/
EOF
# configure DNS
cat > /etc/resolv.dnsmasq << EOF
# default virtualbox dns address
# nameserver 10.0.2.2
# Cloudflare
nameserver 1.1.1.1
nameserver 1.0.0.1
# Google
nameserver 8.8.8.8
EOF
echo "$HOST_FQDN" > /etc/hostname
# hosts file: this will be served by dnsmasq
cat > /etc/hosts << EOF
127.0.0.1 localhost localhost.localdomain localhost.$DOMAIN
$LAN_IP4 $HOST_FQDN $HOST_NAME
$DMZ_IP4 $DMZ_FQDN $DMZ_NAME $DOMAIN
EOF
cat > /etc/resolv.conf << EOF
nameserver 127.0.0.1
EOF
## setup network
ifdown $LAN || true
cat > /etc/network/interfaces << EOF
auto lo
iface lo inet loopback
# LAN
auto $LAN
iface $LAN inet static
address $LAN_IP4/$LAN_PREFIX
gateway $LAN_GW4
EOF
# reload network config
hostname -F /etc/hostname
ifup $LAN || true
systemctl restart dnsmasq
systemctl restart chrony
## setup msmtp on host
# do not use /etc/aliases as it is touched by packages
echo "default: root@$DOMAIN" > /etc/aliases.msmtp
cat > /etc/msmtprc << EOF
account default
host $DOMAIN
domain $HOST_FQDN
source_ip $LAN_IP4
auto_from on
maildomain $HOST_FQDN
aliases /etc/aliases.msmtp
EOF
# fix apparmor profile
echo "/etc/aliases.msmtp r," > /etc/apparmor.d/local/usr.bin.msmtp
apparmor_parser -r /etc/apparmor.d/usr.bin.msmtp
## unattended upgrade
# make sure we get mails
echo 'Unattended-Upgrade::Mail "root";' | idempotent_append /etc/apt/apt.conf.d/50unattended-upgrades
# enable it
echo unattended-upgrades unattended-upgrades/enable_auto_updates boolean true | debconf-set-selections
dpkg-reconfigure -f noninteractive unattended-upgrades
## setup borg
# use encryption for remote backups though
borg info "$DATA_BACKUP" || borg init --make-parent-dirs --encryption=repokey-blake2 "$DATA_BACKUP"
borg key export "$DATA_BACKUP" /root/borg.key
echo "$BORG_PASSPHRASE" > /root/borg.pass
chmod 400 /root/borg.key /root/borg.pass
## setup daily backups
cat > /etc/cron.daily/backup << EOF
#!/bin/sh
"$(readlink -f "$0")" backup
EOF
chmod 755 /etc/cron.daily/backup
## setup logwatch
cat > /etc/logwatch/conf/logwatch.conf << EOF
Detail = Low
MailFrom = root@$HOST_FQDN
EOF
## setup smartmontools
cat > /etc/smartd.conf << EOF
# test email on startup
/dev/sda -m root -M test
# Monitor all attributes, enable automatic online data collection,
# automatic Attribute autosave, and start a short self-test every
# day between 2-3am, and a long self test Saturdays between 3-4am.
# Send alert emails to root
/dev/sda -a -o on -S on -s (S/../.././01|L/../../5/03) -m root
EOF
cat > /etc/default/smartmontools << EOF
start_smartd=yes
EOF
systemctl restart smartmontools
### Setup DMZ container
## Setup system for unprivileged containers
lxc-checkconfig
# allocate subuids/subgigs for container
usermod --add-subuids 100000-999999 "$USER"
usermod --add-subgids 100000-999999 "$USER"
# setup default config for containers
cat > /etc/lxc/default.conf << EOF
lxc.net.0.type = empty
lxc.apparmor.profile = generated
lxc.apparmor.allow_nesting = 1
lxc.idmap = u 0 100000 899999
lxc.idmap = g 0 100000 899999
EOF
## create container
lxc-info -n "$DMZ_NAME" ||
lxc-create -n "$DMZ_NAME" -t download -- -d debian -r buster -a amd64 --keyserver keyserver.ubuntu.com
# add bind mount for /home and /var/mail
mkdir -p "$DATA_HOME" "$DATA_MAIL"
chmod '=0755' "$DATA_DIR"
chmod '=0755' "$DATA_HOME"
chmod '=3775' "$DATA_MAIL"
chown 100000:100000 "$DATA_HOME"
chown 100000:100008 "$DATA_MAIL"
idempotent_append "$DMZ_ROOTFS/../config" << EOF
# bind mount /home and /var/mail
lxc.mount.entry=$DATA_HOME home none bind 0 0
lxc.mount.entry=$DATA_MAIL var/mail none bind 0 0
EOF
# setup container network
echo "$DMZ_NAME" > "$DMZ_ROOTFS/etc/hostname"
chown 100000:100000 "$DMZ_ROOTFS/etc/hostname"
cat > "$DMZ_ROOTFS/etc/hosts" << EOF
127.0.0.1 localhost localhost.localdomain localhost.$DOMAIN
$LAN_IP4 $HOST_FQDN $HOST_NAME
$DMZ_IP4 $DMZ_FQDN $DMZ_NAME $DOMAIN
EOF
chown 100000:100000 "$DMZ_ROOTFS/etc/hosts"
cat > "$DMZ_ROOTFS/etc/network/interfaces" << EOF
auto lo
iface lo inet loopback
iface eth0 inet static
address $DMZ_IP4/32
pointopoint $DMZ_GW4
gateway $DMZ_GW4
EOF
chown 100000:100000 "$DMZ_ROOTFS/etc/network/interfaces"
# update resolv.conf
dmz_resolvconf
## sysctl network settings for the container
idempotent_append "$DMZ_ROOTFS/etc/sysctl.conf" << EOF
# disable ipv6 - I know, I know...
net.ipv6.conf.all.disable_ipv6=1
# harden ipv4 stack
# rpf will drop incoming packets blackholed by fail2ban
net.ipv4.conf.all.rp_filter=1
net.ipv4.conf.all.accept_source_route=0
net.ipv4.conf.all.accept_redirects=0
net.ipv4.icmp_echo_ignore_broadcasts=1
net.ipv4.icmp_ignore_bogus_error_responses=1
# do not log blackholed packets (too noisy)
net.ipv4.conf.all.log_martians=0
# optimized network settings
net.ipv4.tcp_ecn=1
net.ipv4.tcp_sack=1
net.ipv4.tcp_dsack=1
# enable TCP fastopen
net.ipv4.tcp_fastopen=1027
EOF
# workaround fail2ban: make sure auth.log exists
touch "$DMZ_ROOTFS/var/log/auth.log"
chmod 600 "$DMZ_ROOTFS/var/log/auth.log"
chown 100000:100000 "$DMZ_ROOTFS/var/log/auth.log"
# start container
start
dmzexec timedatectl set-timezone "$TIMEZONE"
## install Yunohost with default user
dmzexec apt-get -y install wget fetchmail logwatch
dmzexec "[ -x /usr/bin/yunohost ] || wget -O- 'https://install.yunohost.org' | bash -s -- -a"
dmzexec "yunohost tools --help 2>&1 >/dev/null || yunohost tools postinstall --domain '$DOMAIN' --password '$YN_ADMIN_PASS' --ignore-dyndns"
dmzexec apt-get -y autoremove
# add default user & allow ssh
dmzexec "yunohost user info '$YN_USER' 2>&1 >/dev/null || yunohost user create '$YN_USER' --firstname '$YN_USER_FIRST' --lastname '$YN_USER_LAST' --domain '$DOMAIN' -p '$YN_USER_PASS'"
dmzexec "yunohost user permission add ssh '$YN_USER'"
# disable unused services
dmzexec systemctl stop avahi-daemon dnsmasq metronome yunohost-firewall yunohost-api
dmzexec systemctl stop ntp
dmzexec systemctl stop systemd-resolved
dmzexec systemctl mask avahi-daemon dnsmasq metronome yunohost-firewall yunohost-api
dmzexec systemctl mask ntp
dmzexec systemctl mask systemd-resolved
# update resolv.conf again: avoid brain damage by resolvconf
dmz_resolvconf
# make sure nginx use default resolver
sed -i'.bak' '/resolver/d' "$DMZ_ROOTFS"/etc/nginx/conf.d/*.conf
# fixup postfix to relay through gandi mail
dmzexec "yunohost settings set smtp.relay.host -v '$MAIL_RELAY_HOST'"
dmzexec "yunohost settings set smtp.relay.user -v '$MAIL_RELAY_USER'"
dmzexec "yunohost settings set smtp.relay.password -v '$MAIL_RELAY_PASS'"
dmzexec "yunohost settings set smtp.relay.port -v '$MAIL_RELAY_PORT'"
# setup fail2ban to use iproute2 instead of iptables
# as rpf is enabled (see sysctl above) incoming packets will be dropped too
# the metric magic is to distinguished between multiple jails
cat > "$DMZ_ROOTFS/etc/fail2ban/jail.local" << EOF
[DEFAULT]
banaction = route
banaction_allports = route
EOF
cat > "$DMZ_ROOTFS/etc/fail2ban/action.d/route.local" << EOF
[Definition]
actionban = ip route add <blocktype> <ip> metric $(echo -n '<name>'|cksum|cut -f 1 -d ' ')
actionunban = ip route del <blocktype> <ip> metric $(echo -n '<name>'|cksum|cut -f 1 -d ' ')
[Init]
blocktype = blackhole
EOF
chmod --reference="$DMZ_ROOTFS/etc/fail2ban/jail.conf" "$DMZ_ROOTFS/etc/fail2ban/jail.local"
chmod --reference="$DMZ_ROOTFS/etc/fail2ban/action.d/route.local" "$DMZ_ROOTFS/etc/fail2ban/action.d/route.local"
dmzexec systemctl restart fail2ban
# install nextcloud into domain.tld/cloud with mail and calendar apps
dmzexec "yunohost app install nextcloud -a 'domain=$DOMAIN&path=/cloud&admin=$YN_USER&user_home=yes'"
# fixup nextcloud db to use 4-byte support
# https://docs.nextcloud.com/server/stable/admin_manual/configuration_database/mysql_4byte_support.html
nextcloud "maintenance:mode --on"
dmzexec "mysql nextcloud" << EOF
ALTER DATABASE nextcloud CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
EOF
nextcloud "config:system:set mysql.utf8mb4 --type boolean --value=true"
nextcloud "maintenance:repair"
nextcloud "maintenance:mode --off"
# install calendar, contacts and mail apps
nextcloud "app:install calendar"
nextcloud "app:install contacts"
nextcloud "app:install mail"
# fixup some nextcloud configs...
nextcloud "config:import" << EOF
{
"system": {
"mail_smtpmode": "sendmail",
"mail_sendmailmode": "smtp",
"mail_from_address": "$MAIL_POSTMASTER",
"mail_domain": "$DOMAIN",
"app.mail.verify-tls-peer": false,
"app.mail.accounts.default": {
"email": "%EMAIL%",
"imapHost": "localhost",
"imapPort": 143,
"imapSslMode": "none",
"smtpHost": "localhost",
"smtpPort": 587,
"smtpSslMode": "tls"
}
}
}
EOF
## setup fetchmail
cat > "$DMZ_ROOTFS/etc/fetchmailrc" << EOF
defaults ssl fetchall nokeep mda "/usr/lib/dovecot/deliver -d %T"
set postmaster "$MAIL_POSTMASTER"
set bouncemail
set no spambounce
set daemon 300
poll $MAIL_RELAY_HOST with proto imap port 993 and timeout 120
user '$YN_USER@$DOMAIN' with pass "$YN_USER_PASS" is '$YN_USER' here
user '$MAIL_RELAY_USER' with pass "$MAIL_RELAY_PASS" is '$YN_USER' here
EOF
chown --reference="$DMZ_ROOTFS/var/mail" "$DMZ_ROOTFS/etc/fetchmailrc"
chmod 600 "$DMZ_ROOTFS/etc/fetchmailrc"
cat > "$DMZ_ROOTFS/etc/default/fetchmail" << EOF
export LC_ALL=C
USER=vmail
START_DAEMON=yes
EOF
# FIXME: enable fetchmail if needed
#systemctl restart fetchmail
#systemctl enable fetchmail
# unattended upgrade: make sure we get mails
echo 'Unattended-Upgrade::Mail "root";' | idempotent_append "$DMZ_ROOTFS/etc/apt/apt.conf.d/50unattended-upgrades"
# enable it
echo unattended-upgrades unattended-upgrades/enable_auto_updates boolean true | dmzexec debconf-set-selections
dmzexec dpkg-reconfigure -f noninteractive unattended-upgrades
# logwatch in dmz
cat > "$DMZ_ROOTFS/etc/logwatch/conf/logwatch.conf" << EOF
Detail = Low
MailFrom = root@$DMZ_FQDN
EOF
chown 100000:100000 "$DMZ_ROOTFS/etc/logwatch/conf/logwatch.conf"
chmod 644 "$DMZ_ROOTFS/etc/logwatch/conf/logwatch.conf"
# disable annoying warnings
dmzexec yunohost diagnosis run
dmzexec yunohost diagnosis ignore --add-filter ip test=dnsresolv || true
dmzexec yunohost diagnosis ignore --add-filter ip test=ipv6 || true
dmzexec yunohost diagnosis ignore --add-filter dnsrecords category=mail domain=$DOMAIN || true
dmzexec yunohost diagnosis ignore --add-filter dnsrecords category=xmpp domain=$DOMAIN || true
dmzexec yunohost diagnosis ignore --add-filter dnsrecords category=extra domain=$DOMAIN || true
dmzexec yunohost diagnosis ignore --add-filter ports category=xmpp service=metronome || true
dmzexec yunohost diagnosis ignore --add-filter ports port=5222 || true
dmzexec yunohost diagnosis ignore --add-filter ports port=5269 || true
dmzexec yunohost diagnosis ignore --add-filter web test=hairpinning || true
dmzexec yunohost diagnosis ignore --add-filter mail test=mail_fcrdns || true
dmzexec yunohost diagnosis ignore --add-filter services service=avahi-daemon || true
dmzexec yunohost diagnosis ignore --add-filter services service=dnsmasq || true
dmzexec yunohost diagnosis ignore --add-filter services service=metronome || true
dmzexec yunohost diagnosis ignore --add-filter services service=yunohost-firewall || true
dmzexec yunohost diagnosis ignore --add-filter services service=yunohost-api || true
dmzexec yunohost diagnosis ignore --add-filter regenconf file=/etc/ssh/sshd_config || true
dmzexec yunohost diagnosis ignore --add-filter regenconf file=/etc/postfix/main.cf || true
dmzexec yunohost diagnosis ignore --add-filter mail test=mail_blacklist || true
dmzexec yunohost diagnosis ignore --add-filter mail test=mail_queue || true
### Finalization
## start DMZ at boot
cat > /etc/rc.local << EOF
#!/bin/sh
"$(readlink -f "$0")" start
exit 0
EOF
chmod 755 /etc/rc.local
# run the 1st backup & logwatch (also act as smoke test)
/etc/cron.daily/backup
/etc/cron.daily/00logwatch
} # end of provision
#
# BACKUP
#
yh_backup() {
local name="$1"; shift
dmzexec "yunohost backup delete '$name'" || true
dmzexec "BACKUP_CORE_ONLY=1 yunohost backup create -n '$name' $*"
}
borg_backup() {
local repo="$1"; shift
# borg on host will backup home and mail
# yunohost backups are put in home and will be backuped by borg
BORG_PASSPHRASE="$(cat /root/borg.pass)"
export BORG_PASSPHRASE
borg create "$@" \
--verbose \
--filter AME \
--list \
--stats \
--show-rc \
--exclude "$DATA_HOME/yunohost.multimedia/share/Music/" \
--exclude "$DATA_HOME/yunohost.multimedia/share/Video/" \
--compression zstd \
"$repo::{hostname}-{now}" \
$DATA_HOME \
$DATA_MAIL
borg prune --list \
--prefix '{hostname}-' \
--show-rc \
--keep-daily 7 \
--keep-weekly 4 \
--keep-monthly 6 \
"$repo"
}
backup() {
# backup system, excluding mails and home
local hooks
hooks="$(dmzexec "yunohost hook list backup" | awk '"-"==$1 && "data_mail" != $2 && "data_home" != $2{printf " %s", $2}')" && yh_backup system "--system $hooks" || true
# backup apps (excluding 'big' data (in home))
yh_backup apps --apps || true
# borg on host will backup home and mail
# yunohost backups are put in home and will be backuped by borg
borg_backup "$DATA_BACKUP" || true
# FIXME: enable remote backup
#borg_backup "$DATA_BACKUP_REMOTE" --remote-path=borg1
} # end of backup
#
# UPGRADE
#
upgrade() {
# update host
apt-get -y update
apt-get -y dist-upgrade
apt-get -y autoremove
# update yunohost
dmzexec yunohost tools upgrade system
dmzexec yunohost tools upgrade apps
# update nextcloud apps
nextcloud 'app:update --all'
# yunohost system update does not update everything
dmzexec apt-get -y update
dmzexec apt-get -y dist-upgrade
dmzexec apt-get -y autoremove
} # end of upgrade
#
# MAIN
#
{
{
case "${1:-none}" in
"start")
start
;;
"stop")
stop
;;
"restart")
start
;;
"provision")
provision
;;
"backup")
backup
;;
"firewall")
firewall
;;
"upgrade")
upgrade
;;
*)
echo "Usage: $0 <start|stop|restart|provision|backup|firewall|upgrade>" >&2
exit 1
esac
# redirect stdout to syslog local0.debug
} | logger -s -t "$0 $*" -p local0.debug 2>&1
# redirect stderr to syslog local0.warning (we need to swap stderr and stdout)
} 3>&2 2>&1 1>&3 | logger -s -t "$0 $*" -p local0.warning -s -p local0.warning
echo "success" | logger -t "$0 $*" -p local0.info
exit 0
@bganne
Copy link
Author

bganne commented Aug 21, 2021

This my management script for yunohost. You can give it a try inside a Vagrant VM:

~ # vagrant up
~# vagrant ssh
vagrant@vm~# sudo /vagrant/yunohost.sh provision

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment