How WordPress Scheduled Posts Work

There’s a bit of a misnomer in the WordPress community about scheduled posts that I hope to help clarify.

To start, let’s do a quick overview of the WordPress cron system. It’s a psuedo-cron, meaning that it doesn’t rely on a true linux crontab or the Windows version of scheduled task running. It depends on user activity on the site. If a user visits a page, it triggers a check of the scheduled tasks, and if it finds one that is in the past, it invokes the task callback. If WP_DISABLE_CRON is set to true, then the implicit behavior-based system is disabled and awaits for an explicit call to wp-cron.php. This is really the better option of the two as you can run a curl on the wp-cron.php URL from a true crontab and invoke the scheduler on a cyclical basis from the os task runner.

Domain Hosting Hijacking

I’ve heard of Domain Hijacking where hackers will attempt and sometimes succeed in stealing ownership of a domain name. However, I can’t find much posted about Domain Hosting Hijacking. That’s precisely what happened to me.

I have an old domain that I don’t use anymore and I had cancelled my hosting plan for that domain. Unfortunately, I forgot to update the nameservers in the registrar and just left it pointed to the hosting company.

A couple of years later, I was curious about the domain and decided to check up on it. I saw the nameservers were pointed to a specific hosting company and thinking I still might host it, I typed in my domain name. Sure enough, my old website came up! But, something was off. Some of the links were dead and hovering over other links, it looked like they might be malicious.

It quickly became clear that someone had figured out I was no longer hosting the site, but saw the nameservers pointed to a specific host and registered their own hosting for my domain. It appears they used the WayBack Machine to scrape an old snapshot of the site and updated it with their malicious links. They also had full DNS control over email as well so they had hijacked all of the email that went to that account. I have no idea if any of my internet accounts I used for that email were compromised. There’s no way to tell since it’s been years since that email was active.

I quickly changed the nameservers to the parking lot of my registrar and cut off their capabilities to use that domain name. I also contacted the hosting company and asked them to remove that user account. They have their process of domain ownership verification that I have gone through, but it was still a bit of a pain and ate up some of my free time.

So, how did these guys figure this out? This happened because people are scraping public WHOIS data, storing it in local data stores, querying that data internally, and running reconnoissance on millions of domains. They can see the IP of the host, send a GET request to see if they get a 200 OK. If not, they can then check if the nameservers are pointed somewhere. If so, they have free access to register that website on the specific host. This is a perfect plan to slip under the radar and take over hosting, email, and do all sorts of mischief while you hold the bag of domain ownership.

What I’ve learned from this:

  1. Never outsource your DNS to your hosting provider. Use a long-term, trusted DNS provider.
  2. Instead of farming out your entire DNS zone to the host, point your A records to the box IP your host gives you, or better yet, use a CDN.
  3. Take inventory of your domains every few months to make sure no one is using a mistake you made to bring harm to the internet
  4. Always point unused domains to a secure parking nameserver from your registrar or remove appropriate records in your DNS.

In this situation, I opened the door, and some malicious actor from Lithuania walked through it. Hopefully this helps save someone some grief.

Someone is always, always watching your WHOIS data.

AWS-CLI – IAM Role Fails – “Unable to locate credentials”

If you run a bootstrap script that uses AWS CLI, you’ve probably run into an intermittent fatal error that says, “Unable to locate credentials”. IAM Roles should just work on the instance, but the credentials are not reliable in my experience on Linux systems. Before I attempt to run any bootstrap script, I use the following code to ensure the IAM credentials are where they should be.

config_exists=$(aws configure list | grep access_key | grep iam-role);
until [ ! -z "$config_exists" ]; do echo 'Amazon is playing games here. Trying to get IAM creds that should already be here ...'; sleep 2; config_exists=$(aws configure list | grep access_key | grep iam-role); done;

Get Latest Project Build from CodeBuild on Single EC2 Instance

If you are bootstrapping a new instance into your cluster, you probably don’t want to kick off an entire deployment pipeline to get the latest build onto just that one instance. I grab the latest build from CodeBuild S3 artifact storage and untar it right into the pertinent path. It’s a much quicker bootstrap and doesn’t take any other instance out of commission for a deployment. Note: This requires the jq package for parsing the response JSON.

LOCATION=$(aws codebuild batch-get-builds --ids $(aws codebuild list-builds-for-project --project-name $PROJECT | jq -r '.ids[0]') | jq -r '.builds[].artifacts.location' | sed 's/arn\:aws\:s3\:\:\:/s3:\/\//g')
tar -xvf $LOCATION

Why does RDS MySQL use so much storage?

We recently migrated 23GB of data from an EC2 MySQL database server to RDS. During the migration, we noticed that the free storage on the 100GB instance was being eaten up quickly. It took some digging to find out that AWS does some configuration trickery here to make more money from unsuspecting customers, in my opinion. They set innodb_file_per_table to true by default.This creates a file per table in the database instead of one global tablespace. There’s really no benefit that I’ve found for performance by doing this. It’s a clever way for users who have file access to migrate tables individually instead of entire databases. The key here is that there is no SSH access for RDS, so, why do we need a file per table? It doesn’t make sense if we can’t even use the feature for its original purpose.

Horizontally scalable on AWS ELB ALB (with HTTPS)

Setting up a horizontally scalable stack to work with AWS ELB can be extremely frustrating as there are several moving parts. There’s also a lot of outdated documentation about AWS ELB that doesn’t include the new Application Load Balancer setup. Here’s a simple setup for getting started with using behind an ELB using HTTPS.

WordPress Data Migration with MySQL

WP-CLI is a great tool for migrating data within WordPress from the command line, however it’s not always the appropriate or most efficient way to move data around. My rule of thumb is if I am working with unserialized data, I try to use MySQL queries first.

A simple migration script with WP-CLI could take up a lot of I/O and could take minutes or hours to complete depending on the data set. The same query in MySQL can take mere seconds. For example, if you wanted to take meta values from a specific post type, and move them to a new key, the WP-CLI script might look something like this:


Installing WordPress and HHVM on Heroku For Beginners

For someone not familiar with Heroku, it can be a bit daunting to get WordPress and HHVM running on a Heroku web dyno after working on a traditional LAMP stack. That’s why I titled this for beginners because I are one and it took me a while to wrap my head around it. Let me also say that I am not a Heroku master and this tutorial most certainly will be agnostic of some of the more technical aspects of Heroku.

This tutorial is also just a means to get WordPress running on a single dyno (server) using the free tier and has not been tested on an enterprise installation. As a point-of-reference, though technically savvy, I do not use because the template they use has actual distribution code committed to the repo which relies on a human to continually update. At this reading, some of the plugins are out-of-date, and I prefer to pull distributions from the source using Composer.


Redirect www to non-www via DNS

Apps rise and fall on single characters. One misplaced character can tank ten thousand lines of code. The same is true with URL redirection. Most DNS providers have a GUI for redirecting URLs. I’ve learned the hard way that the forward slash character is of utmost importance when using these features. For example, if I want to forward all www traffic to (sans slash), all of my traffic for www will end up only on my homepage which is no good for SEO, analytics, user experience, etc…. If I want the DNS provider to forward the entire request, I have to have a trailing slash (