An extremely comprehensive guide to running your own school elections with old software

Nothing drives me more crazy than abandonware.

A modified version of Halalan tweaked for the 2021 PSHS-CVC SSG Elections. It includes a few graphical and functional changes, the most prominent in this screenshot being the notice right before the form box.

Facilitating school elections is no easy feat. Not because it’s hard for students to understand how to vote, but because the software is hilariously painful to deal with. The software currently suggested by PSHS-CVC teachers, and also used by the University of the Philippines, Halalan, is 9 years old as of writing. It relies on older software, and makes life extremely difficult. But no worries, since this “guide” of sorts will help you through everything you need to know.

Do note, however, that you will be severely violating some common security practices for the sake of compatibility. It is suggested that you move on to a different platform for elections, or else you might compromise the elections’ security.

A screenshot of the Halalan GitHub repository, dating its last commit back to September 19, 2012.

Halalan, literally “election” in Filipino, is an open-source voting platform developed by University of the Philippines students in early 2006. It supports both English and Filipino (albeit the language configured on the server side) and the first-past-the-post voting.

Getting started

Prior to literally anything at all, you should probably scout for where you’re going to host the election server. As a small benchmark, we ended up using a single-vCore, 2 GB RAM VPS for the elections. OVH gave this exact configuration and was also available on their Singapore datacenter, which made latencies to the Philippines extremely low. Luckily, this dedicated server allowed us to perform the elections smoothly with peak RAM usage hitting only up to 40%. Granted, we did spread out the election period quite a bit in order to decrease simultaneous traffic, but the server would have been perfectly capable of handling a hundred voters at the same time.

That said, if you’re planning to run this on an existing server that may have its own web server already installed, you might want to use Docker to completely isolate the software versions that you need. Spoiler alert: unless you’re using something as ancient as Ubuntu 12.04, it likely won’t run. Halalan requires PHP 5, which was declared EOL at the start of 2019. Luckily there’s not much restrictions on what MySQL server to use, but we’ll get to that later.

For now, you can get away with installing Apache HTTP Server (httpd) 2.4 together with PHP 5.6. This highly depends on what flavor of Linux you have installed, so I’ll leave this up to you. If you happen to be using Docker, your life will be made easy if you just use the provided PHP 5.6 images. But then there’s a catch! You need gd (with at least PNG and JPEG support so that you won’t lose your mind) and the rewrite module for httpd. So you’ll need to get those installed and enabled as well.

After installing httpd and PHP 5.6, you’ll need to get MySQL up and running. I’d actually advise against using MySQL, and instead use a fork of it, MariaDB, as it contains significant performance improvements which can help make the elections much more smooth. The latest version of MariaDB (currently 10.6.4) works perfect for the job, as it is backwards compatible with the required MySQL version for Halalan.

Now, however, is where I introduce the first dealbreaker for Halalan: you must disable strict mode in your SQL server’s configuration. Merely attempting to open the website without disabling strict mode will show an error immediately on load. That’s definitely something you should not be looking for.

After disabling strict mode, you can now begin installation of Halalan. You can download the latest version as a zip file from GitHub, or just clone the repository on your server. You’ll need to extract the repository onto your document root (probably /var/www/html) to get the files in and then modify the system/application/config/database.php file to set up the database. After entering your configuration, the installation menu should now be accessible. This is located in the /install subdirectory of your web server. Halalan will present you with a few options for setup.

The configuration screen for Halalan.

The configuration here is mostly up to you. For the SSG elections, we went with PINs disabled, candidate details showing, and password lengths at 10 characters. This would make the election process simple and straightforward for students, without compromising security.

Here comes the second dealbreaker for Halalan: passwords are stored as SHA-1 hashes. I don’t have to go in-depth on how insecure SHA-1 is since there’s hundreds of articles about that already. When you’re dealing with elections, you really want to aim for the best security possible. SHA-1 just doesn’t make that any helpful. You can spend some time in the depths of the code trying to replace all the instances of SHA-1 hashing with SHA-256, or better yet Blowfish with password_hash, but this takes time, effort, and technical knowledge of what you’re doing and what you might get wrong. Granted, all passwords are automatically generated by Halalan, so this might not be an issue for you as long as you tightly secure your server.

Once you’ve configured your server and moved the configuration file to its final destination, you will now be able to configure your elections. Congratulations! You can already stop here if you really just wanted to play around. If you want to use this in production though, you need to secure your server quite a bit before you get the elections going.

Locking down

You might be tempted to just start the elections with this setup. If you do that, you’ll be leaving some vital components exposed to the wild by default (at least on Debian or Ubuntu). Your next step would be to open up a firewall to allow access only to ports 80 and 443 (if you’re using SSL, which you should). You might wonder just how the hell are you supposed to control the server if you block off all ports. I present to you the wonders of ZeroTier: a service that’s kind of like Hamachi, but completely free and open source.

ZeroTier opens up a virtual private network between you and the server, and it counts as a completely separate interface, which means your firewall can easily whitelist that interface. You can do things like access the SSH and SQL ports over the private connection without risking exposure to the rest of the internet. There’s separate tutorials for this, so I’ll spare you the details on how exactly this is done.

After getting ZeroTier set up, whitelisting ZeroTier connections in nftables is as easy as two lines:

udp dport 9993 accept  # ZT communication port
iifname zt* accept     # or jump to a different chain

When you’re done with that, you’ve mostly secured yourself against intrusion. It is still best to follow other security practices though, such as only allowing public key authentication with SSH and disallowing root logins for both SSH and SQL.

Next step is to get a domain. A cheap one if possible. The reason why you’d likely want to register a domain is because Let’s Encrypt provides SSL certificates completely for free, and because requesting an SSL certificate IP address is extremely expensive. If you had the money to buy an SSL certificate for your election server’s IP address, you might as well have bought a domain name, heck, even invested in a custom-made election server.

Your focus now is to improve on client-side security, which means adding in an SSL certificate so that the elections can be conducted through HTTPS. Of course, you can skip this option entirely, but you might lose voter trust if they find out that their votes are being transmitted unencrypted through the internet. You can also opt for a self-signed certificate which, although is better than HTTP, will still throw warnings for a browser.

That’s it!

A diagram with the complete infrastructure used by the PSHS-CVC SSG Election server.

If you were able to follow all those steps, then you’re 100% ready for an actual election using Halalan. The only thing left now is to add in the data through the administration panel, and to begin the elections yourself. For the SSG elections, I opted not to use the in-built results panel (since the candidates preferred to keep the actual count of votes hidden) and instead created my own live results dashboard using Grafana. Such a thing is out of the scope of this guide, however it’s not that hard to set up if you know how to deal with SQL and Grafana itself.

If you did happen to stumble upon a few issues, remember that Halalan is nearly 9-year-old software. It is expected to break at this point given changes to the other software and services that it depends on now. In case you do end up giving up and moving on, you can always turn to GitHub for some alternatives that might fit your use case.

The total cost of everything ended up at around US$ 3 and my sanity. Not bad, if I do say so myself.

That’s all for now. Good luck with getting your elections running!