Server Administration

Mandrill support for vBulletin

Update February 2016: Mandrill has announced changes that if I understand them correctly would mean for my sending volume I’d go from paying $65 in the past two years to $30/month in the future. Needless to say, I’ll be moving away from them a.s.a.p. and do not recommend them anymore to anyone! Of course I am not the only one who is not happy about that. While I have yet to properly evaluate alternatives, Mailgun looks promising. I’ll update my plugins when I’ve moved to another service.

If you have a server that needs to send mail, I highly recommend using a specialized service such as SendGrid or my personal favorite Mandrill (up to 12k sends per month are free). While integrating Mandrill in certain web software is easy (like their wpMandrill plugin for WordPress), vBulletin is a bit more tricky.

While it is easy to configure vBulletin to send mail through Mandrill (just create an API key and configure mail in the vBulletin settings) a problem is that the vBulletin Contact Us form uses the user’s email address in the “From:” field and that pollutes your Mandrill account very quickly.

As solution I’ve written a little plugin that rewrites the “From:” field into a “Reply-To:” field and then adds your webmaster email address as “From:” field, which solves this issue.

Now on to one of the neat things you can do with Mandrill: automated handling of bounced mail. Mandrill supports webhooks where you can have certain events be reported to automatically, such as “hard-bounce” or “reject” email events. Such a webhook can then take action on this information.

I’ve written a Mandrill webhook for vBulletin that will automatically move a user to the “Users Awaiting Email Confirmation” usergroup if such an event occurs, so that no more mail is sent to them (until they update and reconfirm their email address), which will improve your email delivery score.

The plugin and webhook plus further info can be found here: https://bitbucket.org/ghdpro/vbulletin-mandrill

Tip: for greater security, limit your Mandrill API key access (in Mandrill settings) to your server’s IP address and for vBulletin (or any service that only uses SMTP access) you only need to allow the “send-raw” API call, nothing else.

Keep WordPress & phpMyAdmin up-to-date with a single command II

A few years ago I wrote about keeping WordPress & phpMyAdmin up-to-date with a single command. While those methods still work it is time to make a few changes (and revive this blog while I’m at it, it has been too long).

First off, using Subversion to track stable versions might keep WordPress itself up-to-date (unless something breaks due to subtle changes in the repository as I found out with WordPress 4.1), it won’t do anything for your themes or plugins.

If you like to keep everything in WordPress up-to-date through the command line (instead of FTP, which I don’t even have installed) there now fortunately is a tool called wp-cli. Updating all plugins for example is as simple as:

wp plugin --all update

There is loads more it can do, see the wp-cli site for documentation of all commands and features.

Second, while the method of using git to update phpMyAdmin in my previous article wasn’t inaccurate, it was highly inefficient. The commands would first download the whole phpMyAdmin repository (including all branches and commit history) and then switch to tracking the stable branch. This was slow and wasted a lot of space.

So here are the updated commands:

git clone --depth=1 -b STABLE https://github.com/phpmyadmin/phpmyadmin.git
git pull -q origin STABLE
composer update --no-dev

With this we tell git that we want only the latest commit (depth flag) in the stable branch (b flag). This executes must faster and occupies only about 70 MB of space instead of nearly 500 MB. I recommend calling the git pull command from a cron job every day, so that your phpMyAdmin is always up-to-date.

Mac OS X Time Machine backup on a Debian server

December 2015: I just wanted to note that the solution below stopped working for me after a while. However I recently purchased a Synology NAS and configuring as a Time Machine backup destination is fairly easy.

I just got a MacBook Air and had already read about how you can setup your own network based Time Machine backup on a Linux server. The problem is that there is some outdated information floating around, which caused me some headaches getting it to work with errors such as “The network backup disk does not support the required AFP features” and “backup failed with error 45” (in Console).

First: you need version 2.2.x of the “netatalk” package. Debian 6.0 (Squeeze) comes with 2.1 by default, which won’t work (with Mac OS X 10.8 “Mountain Lion” at least). Second, lots of how-to information includes instructions on creating a /etc/avahi/services/afpd.service file. With netatalk 2.2, this file is redundant: you do not need to create it.

Back to netatalk. Really old information will talk about needing to compile it from source to have it support the required authentication protocol. That is no longer relevant with the most recent version. If you are still running Debian 6.0 (still the stable version at time of writing) you can get netatalk 2.2 from Debian 7.0 (Wheezy) by doing the following (all as root): first add the following line to /etc/apt/sources.list

deb-src http://http.debian.net/debian wheezy main contrib non-free

Then run the following commands:

aptitude update
apt-get build-dep netatalk
apt-get -b source netatalk
dpkg -i netatalk_2.2.2-1_amd64.deb

Change the filename accordingly if the version number has slightly changed. With netatalk 2.2 installed, follow other guides on the net (such as this one or this one) to configure a Time Machine AFP share on your Debian server.

Hiding MySQL/PostgreSQL password from the “ps” command

If you want to run a database tool for MySQL from the command line it would seem you cannot avoid including the password using a –password argument. The problem is that the whole command line while the command is being run will be visible to any other user of the same server using the “ps” command.

The solution is to specify the password in a “option” file (as MySQL calls it). This is a file named .my.cnf (note the dot at the beginning) in your account’s root folder (ie: /home/myname/ or /root/ for the root user) with the following contents:

[client]
password=password

Of course replace the “password” with your real password. You should als make this file only readable by yourself with the following command:

chmod 600 .my.cnf

That ensures that nobody else can open the file (well except root if you are not an admin, but the root user would have access to everything anyway).

Now whenever you run a MySQL tool (mysql, mysqldump, etc) the password from the option file will be automatically used. If your username matches the MySQL username you also don’t need to specify a username. This can be very useful especially as root, when you need to do daily backups using mysqldump for example.

This tricks works in a similar way for PostgreSQL: put a file named .pgpass with the following contents:

hostname:port:database:username:password

You can use an asterisk (*) to match “any” value (wildcard), for example for port or database.

Arrays in Linux shell scripting

For a script I want to build for maintaining WordPress themes & plugins a bit easier I wanted to basically loop through a list of locations of WordPress installations on a single server. This basically means I need to be able to create an “array”.

I knew that you could use arrays in a shell script as I was using it in another script to automatically make a backup of all databases in a MySQL or PostgreSQL database, however that script gets the list from the output of an application: how do you define them yourself?

First thing to know is that array support differs by which shell you use. I prefer simply “/bin/sh”, but that only has extremely basic array support. Bash (and others) have better support. Fortunately the array support in “/bin/sh” is sufficient in my case.

Anyway, on to the solution. In “/bin/sh” you define an array as a list of strings separated by spaces (as such, I’m not sure if you can include strings with spaces) and use a very simple “for” loop to iterate through them:

#!/bin/sh

ARRAY="Hello World"

for WORD in $ARRAY
do
  echo $WORD
done

This script will display each word from the array on a different line. Note that there is no way to refer to a specific member of the array (you can’t use an index).

In Bash you can use arrays in a more advanced way:

#!/bin/bash

ARRAY=("Hello" "World")
ARRAY[2]="In Bash"
LENGTH=${#ARRAY[@]}

for ((i = 0; i < $LENGTH; i++))
do
  echo ${ARRAY[i]}
done

Now as you can see you can easily define a list of strings (with spaces if you want), refer to specific members of the array using an index and get the length of the array.

Go to Top