Updating to include systemd timers

Better Makefile layout
Improving pytest
This commit is contained in:
DarkFeather 2023-07-15 22:34:00 -05:00
parent 49f9f6d315
commit 3b49a6c49e
Signed by: DarkFeather
GPG Key ID: 1CC1E3F4ED06F296
12 changed files with 123 additions and 87 deletions

1
.gitignore vendored
View File

@ -5,3 +5,4 @@ nodeslist
*.tar.xz *.tar.xz
pkg/ pkg/
src/ src/
**/__pycache__

View File

@ -1,76 +1,25 @@
SHELL := /bin/bash SHELL := /bin/bash
BACKUPDIR := /usr/local/backup BACKUPDIR := /usr/local/backup
client: user aether.bash
cp aether.bash /home/aether/aether.bash
/home/aether/aether.bash
sudo -u aether crontab -l > /tmp/cronie
grep aether.bash /tmp/cronie || echo '0 1 * * * /home/aether/aether.bash &>> /var/log/aether.log' >> /tmp/cronie
sudo -u aether crontab /tmp/cronie
rm /tmp/cronie
touch /var/log/aether.log
chown aether:aether /var/log/aether.log
make checkperm
compile: compile:
@echo Nothing to do @echo Nothing to do
install: compile install: compile
@echo You must specify client or server in a call to make. mkdir -p ${pkgdir}/usr/local/sbin
mkdir -p ${pkgdir}/usr/local/etc
server: keys scripts user ./aether-gen.bash ./aether.pub ./server-backup install -m 0750 -o aether aether.bash ${pkgdir}/usr/local/sbin
bash ./aether-gen.bash install -m 0750 -o root -g root aether-gen.bash ${pkgdir}/usr/local/sbin
cp ./aether.pub /home/aether/.ssh/authorized_keys install -m 0750 -o root -g root remote-backup ${pkgdir}/usr/local/sbin
cp ./aether-gen.bash /root/bin/aether-gen.bash install -m 0750 -o aether -d ${pkgdir}/usr/local/etc/Aether
mkdir -p /usr/local/etc/Aether/backup-entries install -m 0750 -o aether -d ${pkgdir}/usr/local/etc/Aether/backup-entries
touch /usr/local/etc/Aether/nodeslist mkdir -p ${pkgdir}/usr/lib/systemd/system
mkdir -p ${BACKUPDIR}; for i in *.service *.timer; do install -m 0640 -o root -g root "$$i" ${pkgdir}/usr/lib/systemd/system; done
make checkperm
@echo You have the files. Add aether-gen.bash and server-backup to root\'s crontab.
@echo Mark services to be backed up by adding a file from examples/ to /usr/local/etc/Aether/backup-entries
@echo Track client nodes in /usr/local/etc/Aether/nodeslist
user: aether make-user.bash
/bin/bash ./make-user.bash
node-command:
@echo USE THE FOLLOWING COMMANDS TO SET UP A NODE.
@echo -ne 'git clone https://aninix.net/foundation/Aether;'
@echo
@echo -ne 'cd Aether; cat > aether # Paste the private key'
@echo
@echo -ne 'make client'
@echo
@echo MAKE SURE TO ADD THE NODE TO /usr/local/etc/Aether/nodes.list
keys:
if [ ! -f ./aether ]; then ssh-keygen -t rsa -P "" -f aether; fi
scripts: ./server-backup ./remote-backup
cp ./server-backup /root/bin
cp ./remote-backup /root/bin
make checkperm
reverse:
if [ -f /root/bin/server-backup ]; then cp /root/bin/server-backup .; fi
if [ -f /root/bin/remote-backup ]; then cp /root/bin/remote-backup .; fi
if [ -f /root/bin/aether-gen.bash ]; then cp /root/bin/aether-gen.bash .; fi
if [ -f /home/aether/aether.bash ]; then cp /home/aether/aether.bash .; fi
diff:
if [ -f /root/bin/server-backup ]; then diff ./server-backup /root/bin/server-backup; fi
if [ -f /root/bin/remote-backup ]; then diff ./remote-backup /root/bin/remote-backup; fi
if [ -f /root/bin/aether-gen.bash ]; then diff ./aether-gen.bash /root/bin/aether-gen.bash; fi
if [ -f /home/aether/aether.bash ]; then diff ./aether.bash /home/aether/aether.bash; fi
checkperm: checkperm:
id aether; for i in ${pkgdir}/usr/local/sbin/aether.bash ${pkgdir}/usr/local/sbin/aether-gen.bash ${pkgdir}/usr/local/sbin/remote-backup ${pkgdir}/usr/local/etc/Aether; do chmod 0750 "$$i"; done
if [ -d /home/aether ]; then chmod 0600 /home/aether/.ssh/authorized_keys; chmod 0700 /home/aether/.ssh /home/aether; chown -R aether:aether /home/aether; fi for i in ${pkgdir}/usr/local/sbin/aether.bash ${pkgdir}/usr/local/sbin/aether-gen.bash ${pkgdir}/usr/local/sbin/remote-backup ${pkgdir}/usr/local/etc/Aether; do chown root: "$$i"; done
if [ -f /root/bin/remote-backup ]; then chmod 0700 /root/bin/remote-backup; chown root:root /root/bin/remote-backup; fi chown aether: ${pkgdir}/usr/local/sbin/aether.bash
if [ -f /root/bin/server-backup ]; then chmod 0700 /root/bin/server-backup; chown root:root /root/bin/server-backup; fi for i in *.service *.timer; do chown root: ${pkgdir}/usr/lib/systemd/system; chmod 0640 ${pkgdir}/usr/lib/systemd/system; done
if [ -d /usr/local/etc/Aether ]; then chmod -R 0700 /usr/local/etc/Aether; chown -R aether:aether /usr/local/etc/Aether; fi
if [ -d ${BACKUPDIR} ]; then chmod 0770 ${BACKUPDIR}; chown postgres:root ${BACKUPDIR}; fi
if [ -f /var/log/aether.log ]; then chown aether:aether /var/log/aether.log; chmod 0750 /var/log/aether.log; fi
clean: clean:
@bash -c 'printf "This will irreversibly destroy all backups. Confirm? [YES/no] " ; read answer; [ "$$answer" == "YES" ] && exit 0; exit 1' @bash -c 'printf "This will irreversibly destroy all backups. Confirm? [YES/no] " ; read answer; [ "$$answer" == "YES" ] && exit 0; exit 1'

View File

@ -19,7 +19,7 @@ conflicts=()
replaces=("${pkgname,,}", "aninix-${pkgname,,}") replaces=("${pkgname,,}", "aninix-${pkgname,,}")
backup=() backup=()
options=() options=()
install= install=installscript
changelog= changelog=
source=() source=()
noextract=() noextract=()

View File

@ -10,20 +10,27 @@ You have two options to install this project:
* Arch Linux and related distros: Run `makepkg -sri` * Arch Linux and related distros: Run `makepkg -sri`
* Other operating systems: Run `make install` * Other operating systems: Run `make install`
# Initial setup ## Initial setup
To create the aether and aether.pub files, run "make keys". This should not be repeated. To create the aether and aether.pub files, run "make keys". This should not be repeated.
# Adding backup configurations ## Adding backup configurations
Individual projects wanting to be backed up by the Aether system should add a file to their package into `/usr/local/etc/Aether/backups/`. Individual projects wanting to be backed up by the Aether system should add a file to their package into `/usr/local/etc/Aether/backups/`.
## Tracking Nodes
A SIEM filter should be set up to search for successful logins of the `aether` user.
# Relevant Files and Software # Relevant Files and Software
Aether installs a script for rsync-based remote backups. We implement this policy through the two 4TB hard-drives, at least one of which is always off-site, that can be plugged into the [Maat](/Wiki/Hosts/Maat.md) hotswap bay along with a virtual machine that mounts the ArchLinux iso and the drive in the bay. Aether installs a script for rsync-based remote backups. We implement this policy through the two 8TB hard-drives, at least one of which is always off-site, that can be plugged into a hotswap bay of a hypervisor along with a virtual machine that mounts the ArchLinux iso and the drive. Admins use the included ssh daemon in the iso to present the drive as a backup target,
An additional backup is the generated `/home/aether/aether.enc` file. This is a more targeted backup of databases and file indexes.
Keep in mind that all of [AniNIX/Foundation](https://foundation.aninix.net) is naturally a backup solution -- so long as anyone has a clone of the repo, the data survives.
# Available Clients # Available Clients
The only client is direct server access on one of the client nodes. The only client is direct server access on one of the client nodes.
# Equivalents or Competition # Equivalents or Competition
Equivalent services are DropBox, Google Drive, or Barracuda. Equivalent services are DropBox, Google Drive, iCloud, or OneDrive.
# Notes # Notes
Those deploying Aether should maintain a nodeslist file that only root can read. Those deploying Aether should maintain a nodeslist file that only root can read.

View File

@ -1,31 +1,29 @@
#!/bin/bash #!/bin/bash
export LOGFILE="/var/log/aether-gen.log" # File: aether-gen.bash
#
# Description: This file generates the backup in an encrypted format.
#
# Package: AniNIX/HelloWorld
# Copyright: WTFPL
#
# Author: DarkFeather <ircs://aninix.net:6697/DarkFeather>
export BACKUPDIR="/usr/local/backup" export BACKUPDIR="/usr/local/backup"
export BACKUPCMD="rsync -avzl --delete-after"; export BACKUPCMD="rsync -avzl --delete-after";
date >> "$LOGFILE"
chown root:root "$BACKUPDIR" chown root:root "$BACKUPDIR"
chmod 0770 "$BACKUPDIR" chmod 0770 "$BACKUPDIR"
for i in `find /usr/local/etc/Aether/backup-entries/ -type f`; do for i in `find /usr/local/etc/Aether/backup-entries/ -type f`; do
bash "${i}" &>> "$LOGFILE" bash "${i}"
done done
date > "$BACKUPDIR"/lastbackup.date date > "$BACKUPDIR"/lastbackup.date
cd /home/aether cd /home/aether
echo Creating and compressing archive... echo Creating and encrypting archive...
tar cvf aether.tar /usr/local/backup tar cvzf - /usr/local/backup | openssl enc -aes256 -pass file:/usr/local/etc/Aether/pass.txt -in aether.tar.gz -out aether.enc
gzip -f aether.tar
echo Encrypting archive
openssl enc -aes256 -pass file:/usr/local/etc/Aether/pass.txt -in aether.tar.gz -out aether.enc
rm aether.tar.gz
echo Created aether archive. echo Created aether archive.
date >> "$LOGFILE"
echo >> "$LOGFILE"

11
aether-gen.service Normal file
View File

@ -0,0 +1,11 @@
[Unit]
Description=AniNIX/Aether | Generation
[Service]
Nice=19
IOSchedulingClass=best-effort
IOSchedulingPriority=7
Type=simple
ExecStart=/usr/local/sbin/aether-gen.bash
#EOF

11
aether-gen.timer Normal file
View File

@ -0,0 +1,11 @@
[Unit]
Description=AniNIX/Aether | Generation
[Timer]
OnCalendar=01:00
Persistent=false
[Install]
WantedBy=timers.target
#EOF

12
aether.service Normal file
View File

@ -0,0 +1,12 @@
[Unit]
Description=AniNIX/Aether | Pull-back
[Service]
Nice=19
IOSchedulingClass=best-effort
IOSchedulingPriority=7
Type=simple
ExecStart=/usr/local/sbin/aether
User=aether
#EOF

11
aether.timer Normal file
View File

@ -0,0 +1,11 @@
[Unit]
Description=AniNIX/Aether | Pull-back
[Timer]
OnCalendar=05:00
Persistent=false
[Install]
WantedBy=timers.target
#EOF

9
installscript Normal file
View File

@ -0,0 +1,9 @@
pre_install() {
groupadd aether &>/dev/null
useradd -g aether -d /srv/aether -s /bin/false aether &> /dev/null
chown -R aether:aether /srv/aether &> /dev/null
}
pre_remove() {
getent passwd aether &>/dev/null && userdel aether &> /dev/null
}

View File

@ -1,17 +1,44 @@
#!/bin/bash #!/bin/bash
# File: HelloWorld.bash
#
# Description: This file exemplifies printing 'Hello world!' in bash.
#
# Package: AniNIX/HelloWorld
# Copyright: WTFPL
#
# Author: DarkFeather <ircs://aninix.net:6697/DarkFeather>
# Should only be done as root.
if [ "$(whoami)" != "root" ]; then if [ "$(whoami)" != "root" ]; then
echo Needs to be run as root. echo Needs to be run as root.
exit 1; exit 1;
fi fi
if (ping -c 4 "$1" | grep -c ' 0% packet loss,'); then # Default the host to the Aether host in whatever domain this host lives in.
printf "Are you sure you want to back everything up to %s?\nIs the root password set and all storage mounted?\nDo you have time for this backup to complete?\nEnter YES in all capitals to continue..." "$1" host="$1"
if [ -z "$host" ]; then
host=Aether
fi
# Default the path to /
path="$2"
if [ -z "$path" ]; then
path='/'
fi
# Try to contract the host
if (nmap --open -p 22 "$host" | grep -E '22/tcp\s+open' &>/dev/null); then
# Confirm with the user
printf "Are you sure you want to back everything up to %s?\n* Is the root password set and backup volume mounted on '/mnt'?\n* Do you have time for this backup to complete?\n* Does \`ssh-keyscan -D localhost\` on the server match this? `ssh-keyscan -D "$host" 2>/dev/null | grep 4\ 2`\nEnter YES in all capitals to continue..." "$host"
read answer read answer
if [ "$answer" != "YES" ]; then if [ "$answer" != "YES" ]; then
echo User did not confirm. echo User did not confirm.
exit 1; exit 1;
else else
rsync -aAXv --delete --exclude={"/dev/*","/proc/*","/sys/*","/tmp/*","/run/*","/mnt/*","/media/*","/lost+found"} / root@"$1":/mnt/ rsync -aAXv --delete --exclude={"/dev/*","/proc/*","/sys/*","/tmp/*","/run/*","/mnt/*","/media/*","/lost+found"} "$path" root@"$host":/mnt"$path"
status="$?" status="$?"
echo rsync exited with status $status echo rsync exited with status $status
exit $status exit $status

View File

@ -5,7 +5,7 @@ import subprocess
# TODO Still need to devise a testing strategy (https://foundation.aninix.net/AniNIX/Aether/issues/1) # TODO Still need to devise a testing strategy (https://foundation.aninix.net/AniNIX/Aether/issues/1)
def test_aether(): def test_aether():
print(os.getcwd()) print(os.getcwd())
fh = os.popen("echo bye | sftp -o IdentityFile=./aether aether@aninix.net", mode='r', buffering=-1) fh = os.popen("echo bye | timeout 3 sftp -o IdentityFile=./aether aether@aninix.net", mode='r', buffering=-1)
output = fh.read() output = fh.read()
retcode = fh.close() retcode = fh.close()
assert retcode == None and CheckOutput(output) assert retcode == None