Skip to content →

New WordPress plugin: URL Builder for Analytics

tl;dr: I’ve built a WordPress plugin for creating Google Analytics tracking URLs for your posts, straight in the post editor. Development of the plugin happens on the GitHub repository

Website Analytics in short

When doing website analytics, it can be really helpful to know which channels site visitors come from. If you use Google Analytics this can be specified easily, as a couple of GET parameters in the site URL. The main issue here is that remembering the names of the parameters can be bothersome, and writing them manually is error prone. That’s why Google supplies a URL builder tool, where you just fill out the fields and it’ll give you an URL with the tracking parameters.

URL builder for Analytics

Since I was doing a bunch of tracking URLs for WordPress posts, I decided it would be helpful to just to it all straight from the WordPress interface. I couldn’t find a proper plugin for it, so I decided to build my own, the URL builder for Analytics.

The plugin is pretty simple. It adds a meta box to the edit page of all post types. The meta box has 2 tabs, social sharing, and custom sharing.

Social Sharing

The Social Sharing tab
The Social Sharing tab

Most of my URL sharing happened on various social channels, so to streamline that I made the social sharing tab, heavily inspired by this linktagger tool (thanks to Søren Sprogøe for showing me that). Using the social sharing you just fill out your campaign name, and the plugin will give you links for various social media sites (Facebook, Twitter, Google+ and LinkedIn). The created links will have it’s source set to the social site’s name, and the medium will be “social”, this ensures consistency for all posts shared to social media.

Custom sharing

The Custom Sharing tabs
The Custom Sharing tabs

The other tab allows you to specify your own tracking values for all five of the parameters Google Analytics allows for it’s tracking URLs. The plugin will then give you a full tracking URL ready to cut and paste into your newsletter, or where you’d want to use it.

Development and Next step

The development of the plugin is done on a GitHub repository, which also hosts the current issues and feature requests queue.

The next thing I’d like to add is support. This would include doing OAuth authentication with the service, allowing the use of the URL shortening service, to shorten the URLs and saving them to your account.

The plugin can be downloaded from the WordPress repository, and bug reports and feature requests are very welcome both in the issues queue, or in the comments below.

Leave a Comment

Levemand – om mad, øl og andre gode ting i livet

Jeg har i nogle måneder efterhånden leget med et sideprojekt jeg kalder Levemand. Navnet var egentlig bare en working title så jeg kunne komme i gang, og det var meningen at det skulle skiftes ud når jeg kom på noget bedre, men nu har det ligesom bidt sig fast, så det bliver nok hængende.

Levemandbloggen handler om nydelse og det gode liv. Der bliver fokus på ting jeg godt kan lide, som god mad, men især om det gode øl. Bloggen er en ment som en sted hvor jeg kan samle mine tanker om forskellige emner jeg er interesseret i, men hvor jeg ikke før har haft et ordentligt sted at samle mine mentale noter til sammenhængende tanker. Samtidig er det en tænkt som en legeplads hvor jeg kan lege med forskellige onlinerelaterede teknologier jeg ellers kun har haft mulighed for at læse om. Nogle af de eksperimenter kommer der nok mere om her på bloggen løbende.

Indtil nu har Levemand hovedsageligt handlet om øl. Det består indtil nu af fire hoveddele:

  • Øltyper hvor jeg samler min research og noter til egentlige beskrivelser af nogle af de mange forskellige øltyper der findes.
  • Bryggerier hvor jeg skriver om forskellige bryggerier jeg synes laver nogle spændende ting, og bryggerier jeg mener er værd at holde øje med.
  • Ølanmeldelser der handler om enkelte øl.
  • Arrangementer, som er den nyeste sektion. Her vil det handle om interessante øl, mad og alkoholrelaterede arrangementer såsom festivaler, smagninger og lignende.

Sammen med en kammerat, er jeg begyndt at besøge en række af Københavns interessante smørrebrødsrestauranter, hvilket er blevet til et par anmeldelser af spisesteder. Det er desuden planen at jeg i løbet af det kommende år vil begynde at skrive om nogle af de mange spændende ølbarer. Der findes rigtig mange spændende ølbarer rundt omkring i landet, men mit fokus vil sandsynligvis være på de Københavnske ølbarer, da det er dem jeg selv kommer på, og derfor dem jeg kender bedst.

Leave a Comment

PHP 7 – What’s up, and what’s new?

Update nov. 9 – Looks like the PHP 7 release date has been postponed due to some outstanding bugs and regressions. It should still be right around the corner, though.

PHP 7 overview

The next major version of PHP, PHP 7, should be right around the corner, with a planned release date on November 12th, according to the current release timetable. PHP 7 will include of a lot of performance improvements, and a range of new features. In thi of post I’ll try to go through the major new stuff.

But, what about PHP 6?

You probably know that the current version is PHP 5.6, and if the next version is PHP 7, obviously PHP 6 was skipped. I won’t go into details with this choice since I’d rather just forget about it.

But in short, first politics happened, then bullshit happened, and then finally they had a vote and moved on.


Since PHP 7 is a major version release, backwards compatibility breaks are allowed. BC breaks are never nice, so the dev team is trying to keep them at a minimum, but some BC breaks should be expected.

Deprecation of PHP 4 style constructors

PHP 4 introduced object oriented programming to PHP. Back in those days an object constructor was a method named like the class you wanted to create an object from.

class MyObject {
  protected $param;

  // Object constructor.
  function MyObject($param) {
    $this->param = $param;

In PHP 5 the class name constructor was replaced with the new magic method __construct() as the recommended way to create objects.

class MyObject {
  protected $param;

  // Object constructor.
  function __construct($param) {
    $this->param = $param;

PHP 4 style constructors is still available in PHP 5, unless you’re using namespaces, in which case they are ignored and only the PHP 5 style constructors are available. This inconsistency can cause some confusion, and this is the main reason that the PHP 4 style constructors will be marked as deprecated in PHP 7 and removed in the following PHP 8. This means that in PHP 7 a class with a PHP 4 style constructor, but no PHP 5 style constructor will cause PHP to emit an E_DEPRECATED error.

Removal of SAPIs and extensions

PHP 7 also removes a bunch of SAPIs (Server APIs – PHP interfaces for module developers to extend the webserver) and extensions. I’ll skip on the SAPIs as I doubt that change will affect me.

Two modules have been removed. The ext/ereg regex module which has been deprecated since PHP 5.3, and the ext/mysql extension, which has been deprecated since PHP 5.5. If you are using the ereg functionality, it is recommended that you switch to using pcre, and if you are still using the mysql functions, you should switch over to using either MySQLi or PDO, more info for choosing which of the two to use can be found in the manual.

Removal of other functionality

Besides the removed SAPIs and extensions, a bunch of other functionality will be removed, most notably probably being some mcrypt, iconv and mbstring functionality. For a full list, refer to the rfc.

PHP 7 Performance

Internally the Zend Engine has been completely refactored and rebuilt, a project known as PHPNG (next generation). This rewrite allows for a lot of improvements, most of which go way over my head (I’m a web developer, not a language developer), but you can find a lot of details on the wiki.

Some of the notable improvements includes improved hash tables and improvements to the internal representation of values and objects, which Nikita Popov has written some interesting articles about: part 1 and part 2.

For PHP developers, the most notable improvements will probably be the drastically improved performance, that Rasmus Lerdorf has been talking about.

Engine Exceptions

Until now when something went really wrong in a PHP script, it would cause either an error, or an exception. An error was an internal PHP things that would either kill the script, or at least output an error message, either to the user, but hopefully just to a log file, depending on your setup. An exception was a part of the script, it would stop the execution and bubble up through the call stack until it hit something designed to catch it, or kill the script if nothing would catch it.

An exception would change the script’s execution flow, but could be mitigated in a properly designed application, while errors were a bit harder to handle on runtime.
In PHP 7 the Exception hierarchy has been extended, and the error types that would previously stop the entire script execution, will be catchable, so the developer is able to handle the errors more gracefully.
To keep backwards compatibility all exceptions still extend the Exception class, while the errors will extend a new Error class. To ensure both errors and exceptions can be handled together they will both implement a new Throwable interface, making it possible to make catch-all solutions.
You can learn more about the new engine exceptions in this rfc, and about the new Throwable interface in this rfc.

Scalar type hints

PHP 5 introduced type hinting, the notion of allowing methods to expect it’s parameters to be of a certain type, and throw a recoverable fatal error if the input didn’t match the type hint. This was possible for objects and arrays.
In PHP 7 it is also possible to type hint scalar types, ie. integers, floats, booleans and strings. If an input parameter doesn’t match the hinted type, the default behaviour will be to convert the value to the type hinted type, but it’s possible to turn on strict mode, in this case a TypeError Exception will be thrown if an input parameter has the wrong value. Strict mode will have to be set for each file where it should be activated.
I’m really looking forward to this change, and will probably be writing a lot of strict files. I’ll probably get more into this in a later post.

Return type hints

Another new thing that I think will be really awesome is return type hints. In the same way that methods can define which parameter types it expects as input, it will also be able to make a promise of which data type it will return. Declared return types will be included in PHP 7, but an rfc extending the concept by adding void return types is currently being voted on.
Another cool extensions would be nullable types, the rfc is currently only a draft, but I’m hoping to see this for PHP 7.1.
Return types is another thing I’m really looking forward to, and will probably write more about later.

Null coalesce

Null coalesce is a variant of the ternary operators, aka shorthand ifs. The new ternary operator ?? will also check if a value is null.

$category = $_GET['category'] ?? 'cakes';

In human terms this means, $category should get the value of $_GET[‘category’] if it is set, otherwise, it should be ‘cakes’.
This could, of course, also be done using the existing ternary operator

$category = isset($_GET['category']) ? $_GET['category'] : 'cakes';

This is not a revolutionary addition, but rather some nice syntactic sugar.

Anonymous classes

PHP 5.3 introduced anonymous functions, which is unnamed functions defined during runtime. In PHP 7 the concept is expanded with anonymous classes. I believe their main purpose is for single use objects where stdClass might not be enough, but I’ll have to work with it for real before I’ll figure out their real purpose.

Group use

PHP 5.3 also introduced namespaces, logical separation of classes into groups.
To use classes from other namespaces you can either use their fully qualified name:

namespace Foo;

class Bar
  protected $baz;

  public function __construct()
     $this->baz = new \Xyz\Baz();

or use the required class from it’s namespace

namespace Foo;

use Xyz\Baz;

class Bar
  protected $baz;

  public function __construct()
    $this->baz = new Baz();

PHP 7 introduces grouped use declarations, so it’s possible to include multiple classes from a namespace in a single use statement. This is done by stuffing the class names in curly braces. It’s still possible to name individual includes

use Name\Space\{Foo as Xyz, Bar}

I’ll let you decide whether this is nice syntactical sugar, or another way to build an unreadable mess, since I havn’t fully decided yet.

Uniform variable syntax

The uniform variable syntax tries to make variable syntax more consistent. I don’t have a full overview over all of the changes yet, but the RFC contains a lot of examples. This is a pretty important change to be aware of, since it might actually change the behaviour of, or just break, some of your running code since it changes how a lot of expressions are evaluated.


PHP has always had functionality to generate pseudo-random data, the standard functionality just havn’t been cryptographically secure (aka. random enough). PHP 7 introduces some new functionality for creating data that is even more random.

Further reading about PHP 7

In this post I’ve introduced a bunch of the major changes in PHP 7 that I believe will be the most impactful to m daily life as a developer. There is a lot of more stuff being added and removed, and a full list is available here.

Do you have any change that you look forward to more than the rest of PHP 7? Or do you see anything coming up in one of the following versions that makes everything even cooler? Leave your answer in a comment.

Leave a Comment

Code reviews


I’ve recently taken part in introducing code reviews at my current workplace, so I’d like to spend some time here to tell a bit about why I believe code reviews is a good thing, what I believe code reviews can do for the code and for the development team, how we’re currently doing code reviews and what a I believe a good code reviewer is looking for.

The aim of this post is not to be a checklist of how or what to do at code reviews, but rather to provide a broader perspective on some of the benefits of code reviews, and some broader points about what to look for.

Purpose of the code reviews

At first some people might get the feeling that they are being supervised, or that they aren’t trusted. The point of code reviews isn’t to point out how bad a developer you are, or to point out your flaws, it actually has very little to do with you as a person at all. A code review has two main purposes:

  1. To improve the overall quality of the software
  2. To improve the overall quality of the developers

The first point should be obvious. Better code means less bugs, which means less maintenance. This translates directly into better value for the customer, and more time for us as developers to build new exciting things, instead of maintaining old boring things.

The second point has two sides to it. First, there is a lot to learn from reading other people’s code. They might do stuff in a way that you never thought about, using libraries you didn’t know about. Even on the off chance that you have to do reviews for somebody you could never learn anything from at all, there is still a lot to be learned from condensing your current knowledge into useful actionable feedback.

Before a code review

It is important to prioritise code reviews, as having code reviews lying around waiting for reviews will both be a showstopper for the developer, and hold back the project. At the same time a code review will require you to disturb one of your colleagues, so please respect your colleagues’ time; this means that you should prepare properly as to take as little of your colleague’s time as possible away from his own project.

Be sure to read through your pull request again and make sure it is actually ready for review. Make sure everything is documented as expected, and that any debugging info is removed, so your colleague doesn’t have to waste time rejecting your pull request because of something obvious like that.

Small pull requests are easier to grasp and review, so be sure to only include things that actually needs review in your pull request.

What needs to be reviewed

What needs to be reviewed is up to your organisation and project; the rule at our office is that if you wrote it, it needs to be reviewed. This might seem strict, but it saves everybody the trouble of thinking “is this actually a large enough change to require a code review?” since the answer is always yes. This saves us the trouble of having small bugs go into production because “it was just a minor change”.

Exception: hotfixes

If a critical bug has been found which requires an immediate hotfix, we obviously won’t be able to wait for a code review. In this case the hotfix will be made and deployed to solve the issue, the hotfix will then be code reviewed afterwards and fixed to live up to normal coding standards. This can be done in a more calm and considered fashion since the immediate problem has been fixed.

What doesn’t need to be reviewed

Since the rule is “if you wrote it, it needs a review” it goes that if you didn’t write it, it doesn’t need a review.
We do a lot of sites in Drupal which makes it possible to deploy settings and configurations using a module called features. Features creates a PHP version of your configuration, since this is auto-generated we do not bother code reviewing this.

The same goes for community contributed code, like Composer packages Drupal modules since these are expected to be tested and vetted elsewhere and it is expected that the developer uses his critical sense before including these in a project.

The review

A code review is very similar to any other kind of text review, and should happen on 4 different levels using a top-down approach starting with the architectural thoughts and ending with the actual lines of code.

  • Architectural level: A code review should start at the architectural level, which is the bird’s eye view of the code. Does the structure make sense? Is the code modular? Testable? Performant? Maintainable? Does the chosen design patterns make sense for the problem at hand? Could the code be made more modular or maintainable by using more abstractions? Fewer abstractions? Are the concerns properly separated?
  • Functional level: Jumping down a level we look at the individual functions. Does every function serve one, and only one, clear purpose? Is it obvious what that purpose is from the function name? Is the documentation descriptive? Do functions duplicate functionality from each other, or from built-in functions? Is the function itself readable and understandable?
  • Line level: Does every line have a clear purpose? Are the lines compressed enough to allow you to keep an overview of the methods? Are they compressed to the point of unreadability? Are inline comments included? Are they necessary, or should they be replaced by properly named methods/functions/variables?
  • Word level: At the lowest level we’re looking at the words. Naming is known to be one of the hardest disciplines in computer science, so make sure the names makes sense now, and in 6 months when you come back to maintain the code. Does method names clearly describe what a method does, what it needs and what it’s output should be? Does variables and properties tell you what might be in them?

Post code reviews

After the code review, the pull request is sent back to the developer to fix any issues and it will likely go back and forth a few times with the developer asking questions, fixing issues and questioning feedback.

It’s important to note that the reviewer’s word isn’t set in stone, but should be considered feedback and suggestions. Everything is up for discussion, especially because there is no one right way to structure code. Again, the entire point of code reviews is to improve the quality and maintainability of the software, and learning from each others. Different developers have different strengths and skills, and bringing these together will both improve the software, the people developing it and the team.

Further reading

  • Kevin London Code review best practices – A more in-depth view of the actual code review, and suggestions on what to look for.
  • Smartbear 11 best practices for peer code review – Real life experiences condensed into a set of best practices. Many of them can be directly put into use, like the max size of a code review and how to articulate feedback.
Leave a Comment


What is Composer

Composer is a dependency manager for PHP. It makes it easy to include 3rd party libraries in your PHP project. It’s inspired by npm and aims to bring some of the same ideas to PHP will fixing some of the deficiencies.

But, what about PEAR

It is true. We have had dependency management using PEAR for quite a while. Composer brings some advantages and modernizations to the table:


  • Requires libraries to follow a specific structure.
  • Installs libraries globally, not per project. Requires all libraries to be installed globally on all servers. Causes trouble with different versions of a library on servers running multiple services.


  • De-facto standard (everybody does it).
  • Install per-project, or globally, depending on library and needs.
  • Better version handling when following semver. Automatically handling of allowed versions.
  • Lazy-loading autoloader.
  • Even handles pear packages if required.

Installing Composer

Installing composer is easy, go to for the latest release.
Just download and run the installer:

curl -sS | php

And the move the created composer.phar file to a bin dir, or any directory in your $PATH.

Composer basics

Using composer in your project only requires 2 files: composer.json and composer.lock.
composer.json is a json formatted file which describes your project. It contains stuff like your project’s dependencies, and how to load your own files, and examples:

    "require": {
        "monolog/monolog": "1.12.0"
    "autoload": {
        "psr-4": {
            "app\\": "src/"

This file tells composer 2 things; first is that the project is dependent on the project called monolog/monolog, in the specific version 1.12.0, second that everything in the app namespace should be loaded from the src directory, using a psr-4 autoloader.

To install your dependencies run
composer.phar install
This will make composer look up the package monolog/monolog in it’s default repository, packagist, and try to install the required version. It will then install any requirements the monolog/monolog package might have, as well as any requirements of the required packages etc. it then sets up the required autoloaders making the use of the installed libraries a charm. The last thing it does is to create a composer.lock file, which lists all the installed packages, along with the exact version that has been installed.

Now including your required packages is as easy as including composers autoloader:


require __DIR__ . '/vendor/autoload.php';
// Your project goes here

Composer best practices

JSON builds upon a very strict syntax, and editing it by hand is error prone, and not recommended. That’s where the composer cli tool saves the day.

Instead of installing new packages by adding them to the composer.json manually, it is recommended to install them using:
composer.phar require {vendor/package[:version]}
The version number is optional, if it isn’t specified composer will find the newest version of the library and create a dependency on that version. Unless you require a specific version of a library, omitting the version number is the recommended practice. Ie. to install the newest version of monolog/monolog, run:
composer.phar require monolog/monolog
At the time of writing, the newest version of monolog/monolog is version 1.16.0, so the above will add the require clause:

"require": {
    "monolog/monolog": "~1.16"

When checking versions, ~1.16 is equivalent to “>=1.16,<2.0.0", but more on specifying versions later.

Daily usage

Daily usage of composer mainly consists of 3 commands; composer require as explained above, composer install and composer update.

composer install

Composer install is the most used of the two.
The command first checks if a composer.lock file exists, if it does, it will install all of the exact versions specified in the .lock, if no .lock file exists, it will install the newest versions of the libraries allowed by the package requirements. It will then create it’s required autoloaders. If the composer.lock file did not exist, it is then created, or if new packages has been added that wasn’t in the previous .lock file, it will be updated.

composer update

Composer update basically does the same as composer install, except that it will ignore any existsing composer.lock file, and just install the newest allowed version. It then creates autoloaders and writes a new composer.lock file.

Bulk-updating all of a projects dependencies is bound to cause a world of pain, so it’s recommended to update one dependency at a time, and then running your test suite, to make sure nothing breaks in the update process.

composer update vendor/package

Version control

composer.lock specifies the exact installed versions of all dependencies. This file should be commited to versioning system to make deployment faster and to guarantee that tested versions are installed. The vendor dir is where the actual dependecies are kept. This is a bunch of code that is already hosted on version control systems somewhere else, and should not be included in your version control system.
When deploying your project, running composer install will install the required version the project has been tested with, using the composer.lock file.


Composer allows for a bunch of different ways to specify the allowed versions of each package, by specifying ranges, wildcards etc.

Most of the specifiers are built to support projects using SemVer as a promise of predictability in version numbers, so if you are a library maintainer and not using semver, please do, to make it easier for people to use your library.


>, <, >=, <=, !=, ||, ,, (comma and space, logical AND)


I.e. “2.3.*” == “>=2.3.0 <2.4”


Recommended usage! (For libraries following semver).
Specifies a min. version, and allows updates to next minor/major version, depending on specificity.
I.e. “~3.6” == “>=3.6 <4.0”, “~3.6.0” == “>=3.6.0 <3.7.0”

Advanced usage

So far I’ve went through the basic usage of composer, but it actually does quite a lot. In this last section I’ll do a quick run-through of some nice to know features, but I won’t be going through everything that is possible with the program.

Neat cli options

–verbose – Prints more information when running commands.
–profile – Provides profiling information.
–dry-run – Pretend to do install/update, but don’t actually touch any files. Useful for getting an idea of what has been changed.

Composer repositories

By default composer installs from packagist, but it is possible to install from other sources like github, SitePoint has a nice tutorial on that.

Cli commands

composer.phar show -i – Show all installed libraries and their version.

composer.phar create-project namespace/project
Clones the specified project and runs composer install in the install directory.

If in doubt: composer help

Further study

Some other nice features that I might touch upon in future blog posts includes:

  • Creating your own composer-ready packages
  • Scripts – allows running scripts during various parts of the installation process


Some nice references to know about
The Composer Homepage
Official documentation
Interactive composer cheat-sheet
Composer on

Leave a Comment

2014 and beyond

Efter at have fået opsummeret år 2013 er det tid til at kigge på år 2014 der allerede er godt igang. Inspireret af erfaringerne fra sidste års målsætning har jeg i år valgt at prøve at lave min målsætning på en lidt anden måde. Jeg har sat mig to mål får året, et personligt og et professionelt, indlægget her vil fokusere på det professionelle.

Jeg har længe haft en ambition om at blive selvstændig og kunne leve af egen (egne?) virksomhed(er). Målet for i år er derfor at begynde at tjene penge på egen virksomhed. Målet er ikke at gå selvstændig på fuld tid i år, men bare at bruge en del af min fritid på at bygge et fundament der forhåbentlig gør det muligt over en årrække.

Jeg har et par projekter i støbeskeen som forhåbentlig kan begynde at give en indtjening i løbet af året, plus jeg er stille og roligt begyndt at finde nogle potentielle samarbejdspartnere og kundeemner. Så det handler om at finde en måde at give værdi til disse, så jeg forhåbentlig kan gøre nogle af dem til indkomstkilder.

Målet er ikke nær så skarpt defineret som de målene fra sidste år, men erfaringen siger at det fungerer bedre at sætte de mere konkrete mål indenfor en kortere tidshorisont, da det gør det lettere at tilpasse dem løbende i takt med at virkeligheden ændrer sig.

Leave a Comment

2013, det succesfulde år der gik

2013 er overstået, 2014 er godt i gang, og det er ved at være på tide at få afsluttet det forgangne år så fokus rigtigt kan komme på det igangværende.

Jeg satte mig i starten af året en række mål for 2013. Der var en del mål, og flere af dem vidste jeg på forhånd var ret ambitiøse. Det var heller ikke alle målene jeg nåede, men jeg synes at jeg nåede nogle af de væsentlige, desuden lærte jeg en del, selv af de mål jeg ikke nåede så det må betegnes som en succes.

Jeg vil her nøjes med at opsummere de væsentligste sejre og nederlag. Nederlagene først.

Jeg havde udvalgt 2 projekter jeg gerne ville lancere i løbet af året, og ingen af dem har endnu set dagens lys. Efter at have afsluttet mit speciale valgte jeg at gennemgå alle de projekter jeg havde liggende på sidelinjen. Det viste sig at jeg på det tidspunkt ikke længere mente at de projekter jeg havde udvalgt mig ved årets start gav lige så meget mening som da jeg valgte dem. Projekterne i sig selv blev altså ikke en succes (det ene er dog ikke helt afskrevet endnu), men tankerne jeg gjorde mig om valget af projekter og deres skæbne lærte mig en del om hvordan jeg bedst udvælger projekter med potentiale, samt hvordan jeg bedst arbejder med dem. På trods af projekternes skæbne fik jeg mig altså nogle gode insights som jeg er sikker på jeg får meget glæde af fremover.

Jeg havde også som mål at deltage i en form for startup- eller hacker- weekendarrangement. Dette skete da jeg i starten af året deltog i Nordic game jam. Det var en hård, men spændende weekend hvor jeg mødte nogle spændende mennesker, og prøvede projektarbejde på en måde der var meget anderledes end hvordan jeg normalt arbejder. Dette var altså både lærerigt på flere planer, samt et fuldført mål.

Lidt i samme boldgade havde jeg en plan om at forlade landet min. 2 gange. Et mål jeg også nåede, først med en tur til Barcelona med nogle venner, efterfulgt af en tur med arbejdet til DrupalCon i Prag. Det var to meget forskellige, men utroligt gode ture på hver sin måde, og endnu et mål opnået.

En anden aflægger af weekenden og rejserne er at jeg er blevet bedre til at deltage i arrangementer af både professionel og social karakter i min fritid. Jeg har både deltaget i et par CopenhagenJS og WordPress Meetup arrangementer. Det har været spændende fagligt og har givet en del til mit netværk, så det vil jeg helt sikkert gøre noget mere.

Det vigtigste kortsigtede mål var nok at få afsluttet mit studie. Det lykkedes i Juni da jeg forsvarede mit speciale. Det betyder at jeg nu kan kalde mig Civilingeniør, eller M.Sc in Digital Media Engineering. Dette medførte at jeg i September gik fuld tid på mit daværende studiejob hos webbureauet Dwarf hvor jeg stadig sidder som Drupaludvikler. Endnu en succes for året!

Alt i alt har det været et rigtig godt år, og jeg føler virkelig at jeg har rykket mig fremad på mange områder. Så gælder det bare om at holde dampen oppe og blive ved med at rykke. 2014 kan kun blive godt!

Leave a Comment

Opsummering af Aprils 30-dages udfordring

Jeg erklærede tidligere min 30-dages udfordring for April, så det må være på sin plads med en lille opsamling, selvom April er ved at være længe siden. Udfordringen bestod i at dyrke en eller anden form for motion hver eneste morgen hele April måned, og den korte version er at udfordringen er klaret.

Den lidt længere version indeholder en del armbøjninger, der hurtigt blev den foretrukne motion de fleste morgener. Men der blev da også plads til næsten 50km løb i løbet af måneden ikke overvældende, men det hjalp med at få mig i gang med at løbe igen.

Udover den planlagte motion siger min skridttæller at jeg i gennemsnit har gået 11114 skridt/dag, så alt i alt en fornuftig måned rent motionsmæssigt.

Hovedformålet med ufordringen var at se om motion fra morgenstunden ville have indflydelse på min produktivitet i løbet af dagen, men umiddelbart fandt jeg ingen, eller kun meget lille sammenhæng. Til gengæld har projektet hjulpet mig med at få dyrket mere motion, hvilket betyder at jeg er kommet i bedre form over det sidste stykke tid, så helt spildt har det selvfølgelig ikke være. Desuden har jeg haft bedre fokus og jeg har generelt fået lavet mere, bl.a blev arbejdet med mit speciale en del mere effektivt. Om dette skyldes at jeg er kommet i bedre form, den voksende mængde af solskinstimer eller noget helt andet er så noget jeg må eksperimentere herfra.

Desuden har jeg nu gennemført 2 af de 3 30-dages udfordringer jeg har sat som mål for 2013.

Leave a Comment

WordPress-sikkerhed og brute force angreb

Der er i øjeblikket mange der taler om et botnet der på nuværende tidspunkt skulle være i gang med at brute force sig adgang til WordPress sites overalt. Der skulle efter sigende være tale om et angreb fra op til 90.000 forskellige kilder.

Om et sådan angreb er i gang eller ej skal jeg ikke kunne sige, men det har tilsyneladende fået rigtig mange WordPressbrugere til at genoverveje deres nuværende sikkerhedsniveau, så noget positivt er der da kommet ud af det lige meget hvad.

Jeg ser mange der diskuterer problemet og mulige løsninger, hvilket igen er positivt, men der er mange der ikke har helt styr på hvad der er godt og skidt, og evt. hvorfor, så jeg vil her prøve at give mit bud på nogle overvejelser man bør gøre sig inden man hovedløst kaster sig ud i installation af tilfældige sikkerhedsplugins.

En række supportere på det officielle WordPress support forum har sammen lavet en side på WordPress codex med tips og tricks til at sikre sig mod angrebet, så hvis du vil have den korte version på engelsk kan den findes her. Jeg vil gå lidt mere i dybden og forsøge at forklare det hele på dansk.

Hvad sker der egentlig?

For god ordens skyld vil jeg lige starte med at forklare det egentlige problem, så vi allesammen snakker om de samme ting, og for at give en idé om de overvejelser man bør gøre sig.

Botnets? What?

Det omtalte angreb stammer fra et stort botnet. Et botnet er et antal computere der, for det meste uden at ejeren ved det, bliver brugt af tredjepart til andre formål end hvad ejeren af computeren havde til hensigt.

I dette tilfælde handler det efter sigende om at bagmændende bag botnettet prøver at tiltvinge sig kontrol over flere computere, for på den måde at udvide deres botnet. De gør det ved at “brute force” sig administratoradgang til maskiner der kører websites bygget på WordPressplatformen. Hvis det lykkedes dem at få adgang til et WordPress-site gør de så dette site til en del af deres botnet, og på den måde vil angrebet vokse hver gang det lykkedes dem at overtage et WordPress-site.

Hvad så med det “brute forcing”?

Brute forcing handler om at tiltvinge sig adgang ved “brute force”, altså rå magt. Det foregår ved de simpelthen prøver at logge ind som adminbrugeren, ved at prøve mere eller mere tilfældige passwords, i teorien kan man jo gætte alle passwords hvis man har uendelige forsøg og god tålmodighed. Da der er tale om et automatisk angreb er det ikke noget der koster bagmændende noget tid, og de har derfor rigeligt med tålmodighed.

Men hvad kan jeg gøre ved det?

For det første skal du tage dine normale forholdsregler. Sørg ALTID for at holde WordPress fuldt opdateret. Det samme gælder alle installerede plugins og temaer. Dette er ikke specielt for det nuværende angreb, men alt software er usikkert på den ene eller anden måde. Folkene bag WordPress arbejder hårdt for at lukke alle sikkerhedshuller der bliver fundet så hurtigt så muligt, så sørg for altid at være opdateret. Sørg desuden for at slå alle plugins fra du ikke bruger. Som nævnt er intet software 100% sikkert, så en tommelfingerregel er at jo mindre software du har jo bedre.

Mht. det nuværende angreb er der selvfølgelig nogle ekstra ting du kan gøre.

Tag backup af alt!

En backup sikrer dig selvfølgelig ikke imod angreb udefra. Men hvis du skulle være uheldig enten at blive offer for angrebet, eller at få ødelagt dit site i et forsøg på at sikre det er det altså noget rarere at have end up-to-date backup, end at skulle starte helt forfra. Sørg altså for at tage backup af både selvesitet (via. FTP) og databasen (f.eks. via phpmyadmin), gerne lige nu, inden du forsøger at øge din sikkerhed.

Selve backupprocessen er afhængig af hvor du har dit website liggende, så der kan jeg ikke være så behjælpelig, men der findes som sædvanlig en række forslag på WordPress Codex.

Skift navnet på din adminbruger

Det igangværende angreb udnytter tilsyneladende at WordPress i gamle dage automatisk oprettede en administratorbruger med brugernavnet. Fra version 3.0 og frem har det været muligt selv at bestemme dette brugernavn, men det er ikke alle der har ændret det. En ændring af dette brugernavn vil gøre det sværere at brute force sig adgang til dit site, da angriberne så både skal finde brugernavn og password, i stedet for kun password.

Hvis du har en administratorbruger med brugernavnet admin kan det ændres forholdsvist enkelt med et plugin, eller ved et par manuelle skridt:

  1. Login som din administratorbruger
  2. I adminpanelet gå til “Brugere” -> “Tilføj ny”
  3. Opret en ny bruger, sæt brugerens rolle til administrator (med et ordentlig password!)
  4. Log ud.
  5. Log ind med din nyoprettede administratorbruger.
  6. I adminpanelet gå til “Brugere” -> “Alle brugere”.
  7. Hold musen hen over admin-brugeren, og tryk på det “slet”-link der kommer frem.

Hvis du oplever at du ikke kan slette admin-brugeren så dobbeltcheck lige at du har logget ind med din nyoprettede bruger, og ikke stadig er logget ind som adminbrugere (ja, vi kan alle lave trykfejl :-)).

Brug ordentlige passwords

Dette er vel nok det vigtigste punkt på listen, og desværre nok også det mest besværlige at gøre ordentligt. Sørg altid for at bruge ordentlige passwords der ikke er lige til at gætte. Som sagt foregår det nuværende angreb som et brute force angreb, hvor de prøver sig at gætte sig til dit password, dette vil normalt foregå på en af to måder.

Enten kan man prøve fra en ende af, med “a” som password, derefter “b”, når alle muligheder er opbrugt prøver man så med to bogstaver, “aa”. Dette kan selvsagt tage lang tid, men hvis dit password f.eks. er “asdf” tager det altså ikke lang tid.

En anden metode er at tage udgangspunkt i en ordbog. I stedet for at prøve alle kombinationer af tal og bogstaver nøjes man med ord fra en prædefineret liste af ord. Disse liste vil ofte også indeholde ofte brugte afarter af ord, hvor f.eks bogstaver er udskiftet med tal. Dette betyder at hverken “password” eller “p4ssw0rd” er særlig gode passwords.

Der er skrevet rigtig, rigtig, rigtig, meget om hvordan man gør sine passwords sikre. WordPress Codex nævner også nogle gode forholdsregler man kan forholde sig til. Der henvises desuden til nogle services der kan hjælpe med at generere og huske gode passwords. De væsentligste ting må være:

  • Lad være med at bruge personlige oplysninger, såsom dit navn, din fødselsdag eller lignende offentlige oplysninger.
  • Lad være med at bruge ord fra ordbogen.
  • Længere passwords er generelt bedre passwords.
  • Brug en blanding af store og små bogstaver, tal og tegn

Men husk altid på de ovenstående metoder der bruges til at gætte passwords. 5up3rM4nRul3z43v3r (superman rules forever) er altså ikke nødvendigvis et godt password, da det stadig er en sammensætning af ord der garanteret vil stå i enhver password breaking ordbog.
Gode passwords vil oftest (altid?) være svære at huske. En metode til at gøre det lettere er at bruge en passwordmanager, et program eller en service til at huske dine passwords for dig. Jeg bruger selv LastPass som gør at jeg har et meget stærkt password som jeg skal huske. Dette masterpassword giver så adgang til alle mine passwords til diverse websites. Det betyder at jeg kan bruge services til at generere tilfældige passwords (eller, ihvertfald tilfældige nok), uden selv at skulle huske alle disse passwords, eller nedskrive dem på papirer som jeg kan smide væk.

Bloker adgang til din loginside

Da det igangværende angreb forsøger at få adgang administratorinterfacet på WordPress sites via den normale loginmetode, er en mulighed for øget beskyttelse at begrænse adgangen til adminpanelet. De to mest brugte metoder til dette er:

  • Password-beskyt adminpanelet
  • Bloker adgang til filen på IP-niveau

Fælles for de to metoder er at de kan fungere på et af to niveauer. Det kan enten gøres via. WordPress selv, eller det kan gøres direkte på serverniveau. Om man bruger den ene eller anden metode kan umiddelbart virke ligegyldigt, men jeg vil gerne lige understrege hvorfor det gør en forskel.

WordPress er skrevet i PHP, som bl.a. bruges til at skabe dynamiske hjemmesider. Det betyder at hver gang sikkerheden bliver håndteret i WordPress skal serveren have hele WordPress i gang med at arbejde for først at finde ud af om en bruger skal have adgang til en ressource. Samme sikkerhed kan ofte klares på serverniveau, hvilket betyder meget mindre arbejde for serveren, da en evt. angriber vil blive forment adgang allerede inden WordPress bliver sat i gang.

Password-beskyt adminpanelet

Passwordbeskyttelse kan som nævnt foregå både på server- og på WordPressniveau. Passwordbeskyttelse på WordPressniveau foregår via. WordPress eget loginsystem, det er en beskyttelse vi snakkede om tidligere med ændring af adminbrugernavn, og brug af gode passwords.

Passwordbeskyttelsen kan dog også flyttes ned på serverniveau med HTTP authentication. Dette vil resultere i at når du tilgår din WordPress loginside vil du først møde en popup hvor du skal skrive brugernavn og password, og derefter vil du møde den normale WordPress loginside. Dette er selvfølgelig en afvejning af sikkerhed vs. convenience da det kan virke lidt irriterende at skulle logge ind to gange. Hvis du vælger denne metode skal du selvfølgelig huske ikke at bruge samme brugernavn/passwordkombination til begge lag af beskyttelse. WordPress Codex har selvfølgelig også instruktioner til hvordan du opsætter HTTP authentication, både på Apache og Nginx servere.

Bloker adgangen på IP-niveau

En anden metode er at blokere adgangen til WordPress-loginformen ud fra forespørgerens IP-adresse. Hvis du ved at du har en fast IP-adresse og at du vil have den samme adresse lige så længe som du har din WordPressside kan du selvfølgelig lave en opsætning der kun giver den ene IP-adresse adgang til din loginside, men det er de færreste forundt (og nu er ikke tidspunktet til en IPv6-diskussion).

Et alternativ, som vil være mere relevant for de fleste, er kun at tillade en IP-adresse X antal loginforsøg, før denne blokeres. Dette kan gøres på WordPressniveau vha. et plugin som WordFence (tak til Kasper Bergholt for anbefaling af pluginet, der tilsyneladende også kan mange andre lækre ting), men igen har vi problemet med at hele WordPresspakken skal startes op, før der kan tages stilling til om en bruger skal have adgang eller ej. Dette er dog noget mere besværligt, og nok ikke noget alle og enhver bare bør kaste sig ud i, men en guide til opsætning af af rate-limiting på Apache kan findes her. Hvis man vil opsætte rate limiting i .htaccess, kræver det dog at man kører Apache med mod_security 2.7.3 eller senere.

Et problem med denne tilgang til det igangværende angreb er at angrebet som forklaret udføres af et botnet der arbejder fra mere end 90.000 forskellige IP-adresser (med mulighed for udvidelse, hvis de får succes). Det betyder at de potentielt kan fortsætte angrebet fra en ny IP, hvis en af adresserne bliver spærret. Dog må der altid være en form for ressource cost tilknyttet hvis angrebet skal flyttes til en ny afsender, da der skal holdes styr på hvor langt hver angriber er nået i ordbogen. Så jo flere lag af sikkerhed du kan opsætte, jo sværere bliver det for angriberen.


Så for at opsummere hvad jeg mener du bør gøre for at højne din WordPress-sikkerhed generelt, og imod det måske igangværende angreb er:

  1. Hold WordPress opdateret, inkl.
    • WordPress core
    • Alle installerede plugins
    • Alle installerede temaer
  2. Tag backup. Om ikke andet for at gøre det lettere at komme tilbage på benene hvis uheldet skulle være ude.
  3. Lad være med at have en adminbruger med navnet admin.
  4. Brug ordentlige passwords. Brug evt. en passwordmanager.
  5. Passwordbeskyt din loginside.
  6. Bloker adgangen for IP-adresser der prøver at gætte dit password.

Hvis i har andre gode råd til beskyttelse af WordPress hører jeg selvfølgelig også gerne om det i kommentarfeltet nedenfor, så vi kan få spredt ordet om ordentlig sikkerhed (At lade være med at bruge WordPress godtages ikke som et godt råd, så hvis det er din mission, så spar dig selv besværet og lad være med at skrive det her).

Leave a Comment

Aprils 30-dages udfordring

Nu har jeg efterhånden ikke haft en 30-dages udfordring siden Januar. Det holder jo ikke hvis jeg nogensinde skal kunne nå at gennemføre min. 3 stk i løbet af året. Desuden har jeg nu i ca. 3 måneder arbejdet med forskellige systemer og metoder, til at holde overblik over mine projekter og til at nå mere, så jeg burde have lært noget brugbart efterhånden, og det mener jeg da også at jeg har.
Jeg har flere gange læst om den fantastiske sammenhæng mellem motion og produktivitet. Jeg har ingen konkrete beviser på sammenhængen, men jeg mener selv at jeg har set en sammenhæng i form af øget produktivitet på dage hvor jeg har dyrket en eller anden form for motion.
Min 30-dages udfordring for April bliver derfor at starte hver dag med at dyrke en eller anden form for motion. Omfanget vil svinge meget fra dag til dag, alt efter hvad jeg lige har af tid fra morgenstunden. Nogen dage vil jeg starte stort enten med en WOD eller en løbetur, mens andre dage (især arbejds- og tømmermandsdage) vil være noget mindre prangende, disse kunne f.eks. bestå af 10 armbøjninger eller lignende. Planen er selvfølgelig at dette skal hjælpe mig til at blive mere produktiv, men det skal også hjælpe med at holde mig til ilden i forbindelse med min træning, og ændre mit mindset mht. både produktivitet og træning. Dette er et emne jeg vil komme mere ind på i senere indlæg, hvor jeg også vil komme lidt ind på hvad der kom ud af udfordringen med de 750 ord fra min Januarudfordring.

Leave a Comment