Today is the 10th anniversary of when I started this – way too occasional – WordPress-based blog.
The server hardware is on its third version, software is still courtesy of Larry the Cow… er, that is, Gentoo Linux.
Ten years. Moo…
Today is the 10th anniversary of when I started this – way too occasional – WordPress-based blog.
The server hardware is on its third version, software is still courtesy of Larry the Cow… er, that is, Gentoo Linux.
Ten years. Moo…
Earlier, I used a WordPress plugin to do periodic backups of the sites I’m hosting, but I came to a conclusion that it would be more reliable, flexible and fun to do the backups via a system script instead, sending the resulting backup archives to a remote server. Here’s how I ended up doing it:
First, I wanted to create a separate mariadb/mysql user with only just enough privileges to be able to make a mysqldump (using the “Principle of Least Privilege“; for the same reason the backup script is executed by an user, not by root). I chose the username ‘dumpo’ because… well. he just dumbly dumps stuff:
MariaDB [(none)]> CREATE USER 'dumpo'@'localhost' IDENTIFIED BY '<dumpopasswd>'; MariaDB [(none)]> GRANT SELECT, SHOW VIEW, LOCK TABLES, RELOAD, REPLICATION CLIENT ON *.* TO 'dumpo'@'localhost'; MariaDB [(none)]> FLUSH PRIVILEGES;
Then, the mysqldump user’s credentials must be stored in the ~/.my.cnf
file within the backup-executing user’s home directory. Afterwards, run chmod 600 ~/.my.cnf
to set the correct permissions.
[mysqldump]
user=dumpo
password=<dumpopasswd>
The actual backup script below is executed by an user’s cronjob once a week. I added a lot of comments to the example script to explain how it works.
#!/bin/bash
# The device acting as a fileserver for WP backups is not always powered up,
# so let's use Wake-On-LAN to make sure it is up when it is actually needed.
wol <mac-address-of-fileserver>
# I happen to have the same username on both the webserver and the fileserver,
# that simplifies some settings.
USER=<user-running-the-script>
WPUSER=dumpo
BFILENAME=backupwp-$(date +%d%m%Y)
# I'm mailing the backup messages somewhere.
MAILADR=someone@somewhere.com
# Let's make a temporary working directory on the users home directory.
cd /home/${USER}
mkdir -p backupdb
# I have three Wordpress sites on the server.
# Dump the mariadb databases of those sites to the working directory.
mysqldump -u ${WPUSER} SITE1 > backupdb/SITE1.sql
mysqldump -u ${WPUSER} SITE2 > backupdb/SITE2.sql
mysqldump -u ${WPUSER} SITE3 > backupdb/SITE3.sql
mysqldump -u ${WPUSER} mysql > backupdb/MYSQL.sql
echo -e "Database dump: done"
# Copy the Wordpress installations to the working directory.
cp -a /var/www/site1.com backupdb/
cp -a /var/www/site2.com backupdb/
cp -a /var/www/site3.com backupdb/
echo -e "Website copy: done"
# Make a tar.gz archive of the contents of the working directory.
tar -czf ${BFILENAME}.tar.gz backupdb
echo -e "Archive: done"
# Check whether the fileserver is up and running. I'm checking the port 22
# (ssh) because I'll be using rsync with ssh for upload. The loop waits for
# 5 minutes for the connection, and then gives up and mails an error message.
# Waiting for 5 minutes may actually be useless, because the fileserver usually
# boots up within a minute, and making the backup archive already takes up some
# 3-4 minutes. But just in case...
CHECK=0
until [[ `nmap <fileserver-ip-addr> -p 22 | grep "Host is up"` ]]
do
if [ $CHECK -ge 60 ]; then
echo -e "File server unreachable, aborting!!! $(date '+%d-%m-%Y %T')" | mail -s "Backup" ${MAILADR}
exit 1
fi
sleep 5
let CHECK++
done
# Send the backup archive to the fileserver using rsync with ssh.
rsync -e ssh ${BFILENAME}.tar.gz ${USER}@<fileserver-ip-addr>:/home/${USER}/wpbackup/
# If the upload was succesful, clean up by removing the local archive and
# temporary working directory, and mail a success message; otherwise, leave
# everything as it is and mail a failure message.
if [[ $? == 0 ]]; then
rm ${BFILENAME}.tar.gz
rm -rf backupdb
echo -e "Wordpress and mariadb backup completed successfully at $(date '+%d-%m-%Y %T')" | mail -s "Backup" ${MAILADR}
else
echo -e "Archive upload failure!!! $(date '+%d-%m-%Y %T')" | mail -s "Backup" ${MAILADR}
exit 1
fi
Finally, at the fileserver end, a script – executed by the cron some time after the upload – rotates and cleans up the backups, leaving only the 4 latest backup archives:
#!/bin/bash
cd /home/<user>/wpbackup
echo -e "Rotating Wordpress backups, removing following files:\n"
ls -1t | tail -n +5 | xargs rm -v # That is 'ls dash one t'.
During the still-ongoing Covid-19 epidemic the Zoom video conferencing app/service has been a lifeline for many, many people, including myself; I’m using Zoom several times a week. I AM very grateful to the Zoom team for making a version for Linux, too, and including Arch as an officially supported Linux distribution.
However, there’s one design ‘feature’ in Zoom which makes me grimace: the multi-window/multi-popup user interface. I firmly think that it is a bad UI design principle in all cases, but worse, it makes life very difficult for the tiling window manager users. I use Awesome window manager on the desktop and i3wm on the laptop, so you can guess where this is going…
One way to tame Zoom on these wm’s is to configure most, if not all, Zoom windows as floating, but that still leaves the annoying and unnecessary ‘informative’ popups (“John Doe has started screen sharing” and so like), which steal mouse and keyboard focus while present. I cooked up a special configuration for those popups to kill them instantly, so they never have a chance to disturb the user. (NOTE: these window rules are not perfect: due to Zoom design. they may kill windows which should be left untouched, and as a side-effect, make Zoom a ‘start-in-tray’ app, which may, or may not be desirable.)
Let’s start with Awesome. These rules go to rc.lua
inside the awful.rules.rules = {}
-section.
-- Kill Zoom popups
{ rule = { class = "zoom", instance = "zoom", name = "zoom" },
callback = function (c)
c:kill()
end },
Then, it’s i3 time. The lines below set everything else except the main window floating. They belong to .config/i3/config
for_window [class="^zoom$"] floating enable
for_window [class="zoom" instance="zoom" title="zoom"] kill
for_window [class="^zoom$" title="Zoom Meeting"] floating disable
This site, Dollz’n’Codez and its sister sites, Miranda and Lux Argentea, were down for some time because of an unscheduled server maintenance.
The server got some hardware updates, complete OS reinstall (still Gentoo Linux), and finally, a proper SSL support courtesy of Let’s Encrypt.
As I mentioned in the previous post, I recently set up a network audio server computer using pulseaudio-rtp. Because it would have been a waste of resources to use it only for audio work, I started using it for some other services, too. For security and access control reasons I ended up installing and setting up a firewall there (UFW in my case). Of course, at that point pulseaudio-rtp stopped working…
I do not want to go through all the different setups I tried to make pulseaudio-rtp to work through a firewall, lack of proper documentation made the task quite laborous. Here’s just the working setup:
/etc/pulse/default.pa
, set module-rtp-send port=<portofyourchoice>
/etc/pulse/default.pa
, set module-rtp-recv sap_address=0.0.0.0
/etc/default/ufw
, set DEFAULT_FORWARD_POLICY="ACCEPT"
I found out about the undocumented port 9875 only after debugging the network traffic with tcpdump
and netstat
. I couldn’t find any information about that port anywhere in the pulseaudio-rtp documentation (or if it is there, it’s hidden so well that I didn’t find it).