Tempus fugit

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…

Posted in Linux | Tagged , , , , | Comments Off on Tempus fugit

WordPress backups to a remote server

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.

  1. [mysqldump]
  2. user=dumpo
  3. 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.

  1. #!/bin/bash
  2.  
  3. # The device acting as a fileserver for WP backups is not always powered up,
  4. # so let's use Wake-On-LAN to make sure it is up when it is actually needed.
  5. wol <mac-address-of-fileserver>
  6.  
  7. # I happen to have the same username on both the webserver and the fileserver,
  8. # that simplifies some settings.
  9. USER=<user-running-the-script>
  10. WPUSER=dumpo
  11. BFILENAME=backupwp-$(date +%d%m%Y)
  12. # I'm mailing the backup messages somewhere.
  13. MAILADR=someone@somewhere.com
  14.  
  15. # Let's make a temporary working directory on the users home directory.
  16. cd /home/${USER}
  17. mkdir -p backupdb
  18.  
  19. # I have three Wordpress sites on the server.
  20. # Dump the mariadb databases of those sites to the working directory.
  21. mysqldump -u ${WPUSER} SITE1 > backupdb/SITE1.sql
  22. mysqldump -u ${WPUSER} SITE2 > backupdb/SITE2.sql
  23. mysqldump -u ${WPUSER} SITE3 > backupdb/SITE3.sql
  24. mysqldump -u ${WPUSER} mysql > backupdb/MYSQL.sql
  25. echo -e "Database dump: done"
  26.  
  27. # Copy the Wordpress installations to the working directory.
  28. cp -a /var/www/site1.com backupdb/
  29. cp -a /var/www/site2.com backupdb/
  30. cp -a /var/www/site3.com backupdb/
  31. echo -e "Website copy: done"
  32.  
  33. # Make a tar.gz archive of the contents of the working directory.
  34. tar -czf ${BFILENAME}.tar.gz backupdb
  35. echo -e "Archive: done"
  36.  
  37. # Check whether the fileserver is up and running. I'm checking the port 22
  38. # (ssh) because I'll be using rsync with ssh for upload. The loop waits for
  39. # 5 minutes for the connection, and then gives up and mails an error message.
  40. # Waiting for 5 minutes may actually be useless, because the fileserver usually
  41. # boots up within a minute, and making the backup archive already takes up some
  42. # 3-4 minutes. But just in case...
  43. CHECK=0
  44. until [[ `nmap <fileserver-ip-addr> -p 22 | grep "Host is up"` ]]
  45. do
  46.     if [ $CHECK -ge 60 ]; then
  47.         echo -e "File server unreachable, aborting!!! $(date '+%d-%m-%Y %T')" | mail -s "Backup" ${MAILADR}
  48.         exit 1
  49.     fi
  50.     sleep 5
  51.     let CHECK++
  52. done
  53.  
  54. # Send the backup archive to the fileserver using rsync with ssh.
  55. rsync -e ssh ${BFILENAME}.tar.gz ${USER}@<fileserver-ip-addr>:/home/${USER}/wpbackup/
  56.  
  57. # If the upload was succesful, clean up by removing the local archive and
  58. # temporary  working directory, and mail a success message; otherwise, leave
  59. # everything as it is and mail a failure message.
  60. if [[ $? == 0 ]]; then
  61.     rm ${BFILENAME}.tar.gz
  62.     rm -rf backupdb
  63.     echo -e "Wordpress and mariadb backup completed successfully at $(date '+%d-%m-%Y %T')" | mail -s "Backup" ${MAILADR}
  64. else
  65.     echo -e "Archive upload failure!!! $(date '+%d-%m-%Y %T')" | mail -s "Backup" ${MAILADR}
  66.     exit 1
  67. 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:

  1. #!/bin/bash
  2.  
  3. cd /home/<user>/wpbackup
  4. echo -e "Rotating Wordpress backups, removing following files:\n"
  5. ls -1t | tail -n +5 | xargs rm -v # That is 'ls dash one t'.
Posted in Linux | Tagged , , , , | Comments Off on WordPress backups to a remote server

Killing Zoom popup windows, Awesome/i3-style

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.

  1. -- Kill Zoom popups
  2.      { rule = { class = "zoom", instance = "zoom", name = "zoom" },
  3.        callback = function (c) 
  4.          c:kill()
  5.      end },

Then, it’s i3 time. The lines below set everything else except the main window floating. They belong to .config/i3/config

  1. for_window [class="^zoom$"] floating enable
  2. for_window [class="zoom" instance="zoom" title="zoom"] kill
  3. for_window [class="^zoom$" title="Zoom Meeting"] floating disable
Posted in Linux | Tagged , , , , , , | Comments Off on Killing Zoom popup windows, Awesome/i3-style

Server updates

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.

Posted in Linux | Tagged , , , | Comments Off on Server updates

Punching Pulseaudio-RTP through a firewall

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:

  1. On the client (i.e. the desktop), in the /etc/pulse/default.pa, set module-rtp-send port=<portofyourchoice>
  2. On the server, in the /etc/pulse/default.pa, set module-rtp-recv sap_address=0.0.0.0
  3. In the /etc/default/ufw, set DEFAULT_FORWARD_POLICY="ACCEPT"
  4. In the firewall setup, open the <port>/udp you set up in step 1, and port 9875/udp

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).

Posted in Linux | Tagged , , , | Comments Off on Punching Pulseaudio-RTP through a firewall