Basically a place that Chris can post solutions to problems so he can easily find them later

SimpleSAMLphp + Nginx


Ugh, this was weeks in the making. I want to use SimpleSAMLphp but I prefer Nginx over Apache. As of right now I can’t find any official documentation for installing on Nginx but they say it should work and shouldn’t be too hard. There’s a couple of threads out there but they were all old configs (two plus years) and none of them worked for me. Finally, after many hours (including giving up for a couple of weeks and just firing up a dedicated Apache server before coming back) I finally found one that works for me.

First, don’t clone from git but download the most recent version as a zipped resources. This is important because the paths in git (I think) aren’t all setup completely and are expected to be resolved via some dependency resolver.

Second, extract the zip file somewhere, in my case /var/www/simplesamlphp.

Third, use this for your location block:

    location ^~ /simplesaml {
        alias /var/www/simplesamlphp/www;
        location ~ ^(?/simplesaml)(?.+?\.php)(?/.*)?$ {
          include fastcgi_params;
          fastcgi_pass unix:/var/run/php5-fpm.sock;
          fastcgi_param SCRIPT_FILENAME $document_root$phpfile;
          fastcgi_param PATH_INFO       $pathinfo if_not_empty;

If you want to use a different URL endpoint you can change simplesaml above in the location lines to match your value in config/config.php for the baseurlpath value.

Written by Chris Haas

December 1st, 2014 at 9:58 pm

Posted in nginx,simplesamlphp

curl with base64 encoded data

leave a comment

I just spent the last hour trying to figure out how to send base64 encoded data that lives in a file using curl. Everyone says to just use --data-binary but that assumes you know what the binary format should actually be! Every combination I tried of --data-ascii and --crlf kept failing with server-side errors.

The trick for me was making sure that the file itself was manually URL encoded. So all newlines were replaced with %0a and all plus signs were replaced with %2b. Then just put everything on one line. So my file (which was a SAML payload for testing) looked like:

                                                                 +                     \n

This can just be sent using the normal --data parameter as a file:

curl -XPOST --data @saml.txt http://www.example.net/

Written by Chris Haas

November 26th, 2014 at 2:17 pm

Posted in Uncategorized

Using web page test with a custom IP address

leave a comment

I recently had a need to speed test a site that was almost launched. Since the site required an SSL cert we’d been doing our final tests with local host files. However, we wanted to get an external network’s view of our site and for that we always use the wonderful http://www.webpagetest.org/. The obvious problem that we ran into was that they wouldn’t have access to our local copies of DNS.

Luckily the answer was simple, they have a great scripting interface along with very comprehensive documentation.

All we had to do was enter this into the Script tab:

setDns www.example.com 456.456.456.456
navigate https://www.example.com

Written by Chris Haas

November 20th, 2014 at 3:52 pm

Posted in Uncategorized

WP 4.1 – Something to watch

leave a comment

First, a very old bug/feature:

Currently, if you have WP Category for fruits called “Apple” and a WP Tag for pies called “Apple” and a custom taxonomy such as “Computer Manufacturers” with an item called “Apple”, that “Apple” term is shared between everything. This isn’t much of a problem until you decide to rename the computer manufacturer to “Apple Computers”, at which point you’ve also renamed the fruit and pie. For the past seven years the only solution to this has been to create a new term instead and manually re-tag everything.

Last year one of the core developers, Andrew Nacin, outlined a roadmap for fixing this, with the expected final change to land in 4.x somewhere in 2015

One part of this roadmap that was to land in 4.1 was when a shared term was detected by the system during an edit, the system would automatically break the share and create unique unrelated terms. So if you edit the Apple computer term in any way (or just hit save on it), WP would detect that it is used in multiple contexts and break that computer one away into a dedicated context of its own.

Sounds like a good plan except it turns out a lot of people having been storing/caching the underlying ID of the shared term instead of the term itself. So developers have been storing “term 48” instead of just “apple” since developers like numbers.

This is a pretty big potentially breaking change but was luckily rolled backed a couple of days ago:

This was re-introduced and in theory fixed four days ago however I can still think of many edge cases that can break:

Written by Chris Haas

November 18th, 2014 at 1:33 pm

Posted in WordPress

Fun links of the day

leave a comment

Written by Chris Haas

November 17th, 2014 at 10:19 am

Fun links of the day

leave a comment

I love the Hot Network Questions on the StackExchange network. Here’s some from this morning.

Written by Chris Haas

November 13th, 2014 at 9:11 am

Finding abandoned/no longer maintained plugins

leave a comment

After Matt’s State of the Word 2014 presentation I was talking to my host (QTH) about how Matt would like to encourage/pressure hosts into upgrading their PHP installs. My host told me that he’s tried this but it often results in broken sites because users don’t have their plugins updated in the first place and many are using plugins that are no longer maintained by anyone.

WordPress does a pretty good job of alerting you that a plugin is no longer maintained if you actually visit the WordPress plugin website but once you’re in the backend you (shudder) have to actually read! And worse, once you have a plugin installed you have no idea when it was last updated by the plugin author unless you (double shudder) click and then read on each individual plugin. Who has the time?

Seriously, I actually do click and read, but most people don’t.

This lead me to build a quick plugin to query the WordPress API servers for each plugin and ask them when each plugin was last updated. You can download the Vendi Abandoned Plugin Check here. Version 1 will query the servers daily and update your plugin listing screen with the number of days since the last SVN check-in.

Unfortunately it needs WordPress 3.4 or greater because of improvements made to the built-in HTTP request methods. I spent a while trying to get it working in 3.3 but eventually had to give up.

If I get a chance, version 2 will add support for alerting on the plugin install screen itself for abandoned plugins. Version 3 will add a management screen where you can actually configure a couple of settings like “how old is abandoned (currently 365 days, half of WordPress’s 2 year)” and possibly excluding plugins from the check.

Written by Chris Haas

October 30th, 2014 at 12:08 pm

Posted in Plugins,WordPress

WordPress VIP Scanner – Undefined index: slug

leave a comment

We just started playing with WordPress’s VIP scanning plugin but ran into an issue when trying to scan with the WordPress coding standards.

PHP Notice:  Undefined index: slug in /var/www/wp-content/plugins/vip-scanner-master/vip-scanner/checks/WordPressCodingStandardsCheck.php on line 173

After a little bit of digging we found that there’s a problem with the way that the scanning tool parses the results of PHP_CodeSniffer (or there’s a problem with how PHP_CodeSniffer writes results or there’s a problem with WordPress’s implementation of PHP_CodeSniffer rulesets, I guess this is a matter of perspective). Since no one is mentioning this I’m guessing that the problem might be related to my install but I decided to document it here just in case.

Anyway, results are supposed to look like:

Line is indented with space not tab (WordPress.WhiteSpace.PhpIndent.Incorrect)
No space after opening parenthesis of function definition prohibited (WordPress.Functions.FunctionCallSignature)
No space before closing parenthesis of function definition prohibited (WordPress.Functions.FunctionCallSignature)

Or more generically:


The regex that handles this in on line 41 of /vip-scanner/checks/WordPressCodingStandardsCheck.php:

private $sniffer_slug_regex = '/\((?P<slug>(\w+\.)+\w+)\)/';

For whatever reason, some rules are coming through ending in a period (or missing the last word, perspective again) and looking like this:

Detected access of super global var $_POST, probably need manual inspection. (WordPress.VIP.SuperGlobalInputUsage.)

Note the period inside of the parentheses.

In the regex above, the (\w+\.)+ means “find one or more words that each end in a period“. This is then followed up by \w+ which means “plus one more word”. Combined this means “find a bunch of words separated by periods but doesn’t end in a period” which is what is breaking the rule above.

The solution is to just switch to a simpler capture that uses a character class of [\w\.]+ which means “find a bunch of things that are words or periods”. Technically this matches A..B and .A.B as well as our desired A.B. but at least it doesn’t break anymore.

So the final solution is to change line 41 to:

private $sniffer_slug_regex = '/\((?P[\w\.]+)\)/';

Written by Chris Haas

October 3rd, 2014 at 2:17 pm

Posted in VIP,WordPress

Varnish as a frontend for a remote WordPress install – Part 2

leave a comment

Part of this setup Nginx, MySql, PHP and WordPress. This part is for configuring Varnish 4.0 on Ubuntu 14.04

On varnish.chris.example.com

Install Varnish 4.0

  1. Add Varnish’s GPG key
    curl https://repo.varnish-cache.org/ubuntu/GPG-key.txt | sudo apt-key add -
  2. Add the source location
    echo "deb https://repo.varnish-cache.org/ubuntu/ trusty varnish-4.0" | sudo tee /etc/apt/sources.list.d/varnish-cache.list
  3. Update local cache
    sudo apt-get update
  4. Perform a version check to make sure that Varnish 4.0 is listed:
    sudo apt-get install -s varnish
  5. Install
    sudo apt-get install varnish

Configure Varnish

  1. Edit the main config file for Varnish
    sudo vi /etc/default/varnish
  2. Change the 6081 to 80 in this block.

    DAEMON_OPTS="-a :6081 \
                 -T localhost:6082 \
                 -f /etc/varnish/default.vcl \
                 -S /etc/varnish/secret \
                 -s malloc,256m"


    DAEMON_OPTS="-a :80 \
                 -T localhost:6082 \
                 -f /etc/varnish/default.vcl \
                 -S /etc/varnish/secret \
                 -s malloc,256m"
  3. Restart Varnish
    sudo service varnish restart

Written by Chris Haas

September 27th, 2014 at 12:25 pm

Varnish as a frontend for a remote WordPress install – Part 1

one comment

This tutorial assumes two sites, varnish.chris.example.com and web.chris.example.com. Both of my test sites will be created on DigitalOcean but on separate instances. Both will be running basic Ubuntu 14.04.

On web.chris.example.com

Install Nginx

  1. Add the dev repo so that we can get to 1.7.x:
    sudo apt-add-repository ppa:nginx/development
    sudo apt-get update
  2. Verify that we’ll get 1.7.x (check the version number returned, currently 1.7.5 as of this posting. If you see 1.4.6 you probably didn’t run apt-get update above)
    sudo apt-get -s install nginx
  3. Install Nginx
    sudo apt-get install nginx
  4. Verify that it was installed
    nginx -v

Install and configure PHP-FPM

  1. Install PHP-FPM
    sudo apt-get install php5-fpm
  2. Tweak PHP-FMP for security:
    sudo vi /etc/php5/fpm/php.ini
  3. Look for ;cgi.fix_pathinfo=1 and change it to cgi.fix_pathinfo=0
  4. Restart PHP-FPM
    sudo service php5-fpm restart
  5. Create a directory for our web files:
    sudo mkdir /var/www

Configure Nginx

  1. Edit the default site for Nginx (or whatever site you want to work on)
    sudo vi /etc/nginx/sites-available/default
  2. Erase and change to
    server {
        listen 80 default_server;
        root /var/www;
        index index.php;
        location / {
            try_files $uri $uri/ =404;
        location ~ \.php$ {
            try_files $uri =404;
            fastcgi_split_path_info ^(.+\.php)(/.+)$;
            fastcgi_pass unix:/var/run/php5-fpm.sock;
            fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
            fastcgi_index index.php;
            include fastcgi_params;
  3. Test Nginx:
    sudo nginx -t
  4. Restart Nginx
    sudo service nginx restart
  5. Create a quick test file
    echo "<?php phpinfo();" | sudo tee /var/www/index.php
  6. Use a web browser to confirm that PHP is running
  7. Remove the test file
    sudo rm /var/www/index.php

Install and configure mysql

  1. Install
    sudo apt-get install mysql-server php5-mysql
  2. Configure
    sudo mysql_install_db
    sudo mysql_secure_installation

Install exim for email (optional)

  1. sudo apt-get install exim4
    sudo dpkg-reconfigure exim4-config

Install WP-CLI

    1. Install PHP CLI
      sudo apt-get install php5-cli
    2. Download
      cd ~
      curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
  • Test
    php wp-cli.phar --info
  • Make it executable
    chmod +x wp-cli.phar
  • Make it available everywhere as just the command wp
    sudo mv wp-cli.phar /usr/local/bin/wp
    Confirm it works
    wp --info

Install WordPress via WP-CLI (optional, you can do it any way you want)

  1. Download WordPress
    cd /var/www
    wp core download
  2. Create a MySql database and user, replace the testXYZ parts as needed
    mysql -uroot -p -e “CREATE DATABASE testdb; GRANT ALL PRIVILEGES ON testdb.* TO testuser@localhost IDENTIFIED BY ‘testpassword'; FLUSH PRIVILEGES;”
  3. Create a config file (replace variable below obviously)
    wp core config --dbname=testdb --dbuser=testuser --dbpass=testpassword

Generate some sample content

  1.  wp post generate –count=10000



  1. Nginx runs as user and group www-data by default. For most of my installs I usually add my non-root account to the www-data group and also make that my default group
    sudo usermod -a -G www-data myaccounthere
    sudo usermod -g www-data myaccounthere

Written by Chris Haas

September 27th, 2014 at 11:51 am

Posted in nginx,WordPress,WP-CLI