Author Archives: dan

Creating a home DNS and DHCP server

A few weeks ago I was trying to shell into my new microserver and from there access a media server to start some downloads.

What I realised was this… unless you know the IP address things get very tedious very quickly:

An attempt to find my media server on the local network

So thinking about my options, and the fact that I’ve just set up my first “real” home network (and by that I mean bothered to configure everything properly like QoS/routing/port forwarding, wired up the house etc). I recently bought my first dedicated server – previously this role was being fulfilled by something that was a warhorse 4 years ago, but now looks more like a panting, furry, very non-green home PC.

So, on with the setup…

I decided upon firing up a Windows Server 2008 instance on my ESXi server to handle both DHCP duties and DNS. I’d read that it was possible to configure the DHCP server to automatically create records with the local DNS server whenever a new client connected. The aim was something like this:

The DHCP server should:

  • Send the gateway IP address to all clients
  • Send the appropriate search domain (in this case home.danielbyrne.net)
  • Send the IP address of the yet-to-be-configured DNS server
  • Notify the DNS server of a newly connected client so A records can be created

The DNS server should

  • Answer any requests for its configured zone (*.home.danielbyrne.net)
  • Accept updates from a linked DHCP server
  • Forward any DNS queries that it can’t answer (basically the rest of the world) to the Google DNS service on 8.8.8.8

DHCP setup

First connect over terminal services to my Windows 2008 server instance. Once in add both ‘DHCP Server’ and ‘DNS Server’ roles to your installation

Adding DNS and DHCP roles to Server Manager in Server2008 R2

Adding DNS and DHCP roles to Server Manager in Server 2008 R2

DHCP Configuration



Video showing DHCP server configuration
  • Create a new scope and give it a name
  • Configure the pool (range) of IP addresses you want to make available. I chose 192.168.1.100 -> 192.168.1.200
  • Choose any excluded IP addresses if any
  • Configure the lease duration. I left a default of 8 days as clients on my network will be relatively static
  • Add your default gateway (Usually your router or ISP provided modem, in my case 192.168.1.1)
  • Specify your parent domain and DNS servers. Your parent domain could be something like mynetwork.local, in my case it’s mapped to home.danielbyrne.net. Important it must be a FQDN. mynetwork.local would work, mynetwork wont as it will cause issues with keeping the DNS records updated. Your DNS server will be the IP address of the machine with the DNS service on it and then any alternate DNS servers like Googles service at 8.8.8.8, or your own ISPs servers
  • Configure WINS (if you like, I didn’t)
  • Activate the new scope by selecting that option

Configure DHCP server to update DNS entries

Here’s a screenshot:

Configure DHCP server to update DNS entries.

To be continued in part 2…

Installing and using the AMQP PECL extension

After spending two fairly painful days refactoring some code away from PHPAMQPLib (some custom PHP classes that allow for a connection with RabbitMQ) and moving to the official PECL extension I thought I’d document. Let me know if this has helped you!

First of all you need to get a compatible version of the rabbitMQ C library, as the version shipped with Ubuntu 11.10 and 12.04 are not compatible with the PECL extension.

sudo su
 
apt-get install mercurial
hg clone http://hg.rabbitmq.com/rabbitmq-c
cd rabbitmq-c
hg clone http://hg.rabbitmq.com/rabbitmq-codegen codegen
 
autoreconf -i 
./configure
make
make install

and then it should just be a case of installing the PECL extension as-per-the-usual-way:

pecl install amqp

I’m hoping to follow this up with some AMQP examples, as the manual is pretty much “function declaration only” at this point and there are very few examples out there. Stay tuned.

A quick and easy way to deploy from git with post-receive hooks

I’ve recently moved over to a custom framework for my main website and wanted deployments into the repositories release branch to be seamless. I could use Jenkins but that would probably be overkill.

To accomplish this, I wrote a quick post-commit post-receive script that will be called by git each time a commit is pushed into my repository. If the branch name matches ‘release’ the commit is extracted into a release folder under the webroot. The webroot directory (in reality a symbolic link) is then updated to point to this new release.

Using symbolic links has the advantage of not leaving your website in an inconsistant state as files are deleted and then re-extracted, it should be an atomic operation.

Here’s the script, put this in your git repository under the hooks subdirectory in a file named ‘post-commit’.
The old revision, new revision and branch name are handily passed into this script :)

Edit: One thing to keep an eye out for is that if you are running PHP5-FPM, when the symbolic link is switched to the new location the fpm seems to be still serving your scripts from the old location. I would love to figure out why this is but a workaround is to call /etc/init.d/php5-fpm restart as the final step in the post-receive script (not ideal!!)

#!/bin/bash
#
# A post commit hook that takes any updates pushed to the 'release' branch
# and creates a release directory for the new version under the webroot.
# Live site is then symlinked to this new release directory.
 
oldrev=$1
newrev=$2
branch=$3
 
# this is the root of the website (a symlink to a release directory)
webroot=/var/www/danielbyrne.net/www
 
if [ "$branch" == "release" ]
then
 
    # create a release directory to extract files into
    target=/var/www/danielbyrne.net/releases/$2/
    mkdir $target
 
    echo "Making target directory: $target"
 
    # create an archive in the webroot of danielbyrne.net
    /usr/bin/git archive master --format zip --output $target/deploy.zip
 
    echo "unzipping archive..."
 
    # extract the archive
    unzip -o -q $target/deploy.zip -d $target
 
    echo "removing deployment archive"
 
    # remove the archive file
    rm $target/deploy.zip
 
    echo "switching symbolic link to $target"
 
    # now switch the live site to point to the new release
    ln -nsf $target $webroot
 
    echo "done";
fi

MySQL import / export fun

Exporting Data

If you run the command:

SELECT * FROM TestTable INTO OUTFILE 'outfile.txt

and receive the rather cryptic error message ‘PERMISSION DENIED’..

Keep in mind, you need to specify an explicit path to export the data to, e.g. ‘/tmp/outfile.txt’

SELECT INTO OUTFILE also requires the permission ‘OUTFILE’ to be granted to the currently executing user.

Importing Data
Similarly, when importing data using LOAD DATA INFILE (even with an explicit path) you get the error message

‘ERROR 29 (HY000): File ‘/tmp/infile.txt’ not found (Errcode: 13)

MySQL server may be denied access to most of the filesystem depending on your OS setup (including /tmp), so try using

LOAD DATA LOCAL INFILE '/tmp/infile.txt' ...

which pipes the result through to the MySQL client which has all the permissions that the executing user has.

#mysqlfun

Migrated to nginx, php-fpm and APM.

My VPS is a little underpowered, and checking the amount of free memory I was, shall we say, a little surprised at just how much Apache thought it needed for the amount of visitors this domain brings in.

The combination of nginx and php-fpm is astoundingly lightweight on memory usage… with nginx and a seperate process manager for PHP (php-fpm) instead of mod_php I now have a few hundred MB to play with. Not just that but the requests per second my server can now handle is through the roof.

Using phpinfo as a test, I’m now managing to serve 3,000 requests per second at a maximum of 3ms per page.
Even the beastly wordpress is coming in at 1,628 requests per second with a helping hand from APC byte-code cache. Breezy.

Adding a custom resource type to the Zend Framework autoloader

I’m working on a new project using the latest Zend Framework. I’ve got a modular application and decided that I wanted to hold my module-specific logic classes in their own ‘logic’ subdirectory.

Setting up class to folder mappings is done inside ‘Zend/Application/Module/Autoloader.php’ in the function ‘initDefaultResourceTypes’. In here you’ve got your standard mappings like ‘Form’ => ‘forms’, ‘Model’ => ‘models’ etc.

You’ve either got the choice of overriding this class with your own implementation, or you add your own resource types by putting the following code in your application or module bootstrap:

class MyApp_Bootstrap extends Zend_Application_Module_Bootstrap
{
 
    /**
     * Add some custom resource types to the resource loader
     *
     * @return void
     */
    protected function _initLoaderResource()
    {
        $this->getResourceLoader()->addResourceTypes(array(
            'logic' => array(
                'namespace' => 'Logic',
                'path'      => 'logic'
            )
        ));
    }
 
}

This will make the autoloader look inside the logic subdirectory for any classes with the namespace ‘MyApp_Logic’

Arduino rover – almost there

Here’s the first build of my Arduino powered rover. (edit: content is now lost, removed the image!)

I’m going to write an instructable on how this was built but for now here’s the parts  list.

Arduino Uno – Programmable Microcontroller
ProtoX – prototyping shield for Arduino
L293NE – Quadruple Half-H Driver
1x Remote Control car, stripped down to the chassis and 2x 3v motors
1x battery holder with 4x3v batteries

Zend Framework Tool – project already exists here

When using the Zend Framework tool to create directory structures and some basic classes, you might come across the message “An error has occurred. A project already exists here”. A quick Google search found a couple of other people reporting this issue but no solution.

The problem occurs because by default the project provider searches all parent directories for a .zfproject.xml project configuration file. In my case I’d created a testing project further up the directory tree and neglected to delete it – this was fooling the tool into thinking a project already existed.

…which makes sense – you wouldn’t normally have a project inside a project (although you can’t rule out that somebody wants to do this)

Two solutions:

either look for a ZF project file in your parent directories:

find /path/to/htdocs -name '.zfproject.xml'

or, modify the code to search only the current directory if you have a directory structure that the tool doesn’t like

diff --git a/Zend/Tool/Project/Provider/Project.php b/Zend/Tool/Project/Provider/Project.php
index c24af5e..d3d75ea 100644
--- a/Zend/Tool/Project/Provider/Project.php
+++ b/Zend/Tool/Project/Provider/Project.php
@@ -61,7 +61,7 @@ class Zend_Tool_Project_Provider_Project
             $path = str_replace('\\', '/', realpath($path));
         }
 
-        $profile = $this->_loadProfile(self::NO_PROFILE_RETURN_FALSE, $path);
+        $profile = $this->_loadProfile(self::NO_PROFILE_RETURN_FALSE, $path, false);
 
         if ($profile !== false) {
             require_once 'Zend/Tool/Framework/Client/Exception.php';

ZF create project diff

The simplest way to apply this patch in Linux is to use the command:

patch Zend/Tool/Project/Provider/Project.php < createprojectfix.txt

Note: your mileage may vary – this was the cause of my particular issue, but it’s possible this happens for other reasons.

Italy 2010

Just got back this weekend from Tuscany Italy. We stayed in a villa two miles from San Gimignano and visited Sienna a  Monteriggioni, and spent a lot of time drinking wine by our pool

There’s millions of photos (and even more from other trips) that I really should get sorted. Thinking about getting a Flikr or Photobucket account although I’d prefer to host them on my own webserver I’ve yet to find any decent Gallery software.