<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Adam Cooke]]></title><description><![CDATA[Ruby & Rails developer, front-end guru, designer and managing director at aTech Media, Dial 9 & Niftyware.]]></description><link>http://adamcooke.io/</link><generator>Ghost 0.5</generator><lastBuildDate>Mon, 12 Jan 2015 19:43:43 GMT</lastBuildDate><atom:link href="http://adamcooke.io/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Create an IPv6 network with an EdgeRouter]]></title><description><![CDATA[<p>We've been using IPv6 for quite a while now on the <a href="http://atechmedia.com/">aTech</a> and <a href="http://viaduct.io/">Viaduct</a> networks however my home ISP doesn't support IPv6 natively. As you can imagine, this is quite a pain but there is a solution using <a href="http://tunnelbroker.net/]">TunnelBroker.net</a>. </p>

<p>So... I want to ensure that all computers on my home network are able to access anything which uses IPv6. This guide explains how to go about setting up a full IPv6-enabled network using an EdgeRouter with an ISP which does not support native IPv6 and provides dynamic IP addresses.</p>

<h2 id="getanipv6tunnel">Get an IPv6 tunnel</h2>

<p>The first thing you need to do is head over to the <a href="http://tunnelbroker.net/">TunnelBroker.net</a> site and signup for an account and request a new tunnel. </p>

<ol>
<li>Goto the site  </li>
<li>Create an account or login with one if you already have one  </li>
<li>Select <strong>Create Regular Tunnel</strong>  </li>
<li>Enter your current IPv4 IP address in the <strong>IPv4 Endpoint</strong> field and select the location closest to your physical address.  </li>
<li>Once you have created the tunnel, you'll be given a number of IP addresses and network addresses.</li>
</ol>

<p><img src="http://s.adamcooke.io/14/nwigI.png" alt="Addresses"></p>

<h2 id="creatingthetunnel">Creating the tunnel</h2>

<p>Now you need to add this tunnel to your EdgeRouter. Login to your EdgeRouter using SSH and execute the following commands.Login to your EdgeRouter using SSH. </p>

<pre><code>configure  
set interfaces tunnel tun0 description "HE IPv6 Tunnel"  
set interfaces tunnel tun0 encapsulation sit  
set interfaces tunnel tun0 local-ip 0.0.0.0  
set interfaces tunnel tun0 remote-ip [SERVER IPv4 ADDRESS]  
set interfaces tunnel tun0 address [CLIENT IPv6 ADDERSS]  
</code></pre>

<p>Next, you need to configure a default route which will send all IPv6 traffic down over the new tunnel.</p>

<pre><code>set protocols static interface-route6 ::/0 next-hop-interface tun0  
</code></pre>

<p>You can now commit and save this configuration and give it a quick test.</p>

<pre><code>commit  
save  
exit  
ping6 google.com  
&gt; PING google.com(2a00:1450:4009:80a::2000) 56 data bytes
&gt; 64 bytes from 2a00:1450:4009:80a::2000: icmp_seq=1 ttl=58 time=19.3 ms
&gt; 64 bytes from 2a00:1450:4009:80a::2000: icmp_seq=2 ttl=58 time=10.4 ms
</code></pre>

<p>Although this is all working great, HE is sending your traffic to the IP address you entered when you created the tunnel. If this changes (i.e. you disconnect and reconnect to your ISP), your IPv6 tunnel will cease working. To resolve this, HE provides a Dynamic DNS endpoint which will receive your IP each time you connect and updates your tunnel configuration as appropriate.</p>

<p>Let's set that up. To start, you'll need to get some information from the tunnel broker site.</p>

<ul>
<li>Your <strong>Update key</strong>  - this can be found on the advanced tab of your tunnel settings page.</li>
<li>Your <strong>tunnel hostname</strong> - you can find this on the main page in the list of all the tunnels you have configured. It'll look something like this <code>username-1.tunnel.tserv1.lon2.ipv6.he.net</code>.</li>
</ul>

<p>Run the following commands and replace <em>pppoe0</em> with the name of your external interface.</p>

<pre><code>configure  
edit service dns dynamic interface pppoe0  
set service dyndns host-name [TUNNEL HOSTNAME]  
set service dyndns login [TUNNELBROKER.NET USERNAME]  
set service dyndns password [UPDATE KEY]  
set service dyndns server ipv4.tunnelbroker.net  
top  
commit  
save  
exit  
</code></pre>

<p>You can check on the status of this at anytime using:</p>

<pre><code>show dns dynamic status  
&gt; interface    : pppoe0
&gt; ip address   : 146.200.56.42
&gt; host-name    : adamcooke-1.tunnel.tserv1.lon2.ipv6.he.net
&gt; last update  : Sat Jan 10 13:40:25 2015
&gt; update-status: good
</code></pre>

<p>Although the EdgeRouter can now connect to IPv6 hosts, none of the other computers on your network are able to do this yet. </p>

<h2 id="configuringafirewall">Configuring a firewall</h2>

<p>Unless you want all your clients to be available publically (you probably don't), you'll need to configure an IPv6 firewall.</p>

<p>Firstly, you need to create the firewall itself. In this example, we'll drop everything except existing connections.</p>

<pre><code>configure  
edit firewall ipv6-name home-ipv6  
set default-action drop  
set rule 10 action accept  
set rule 10 state established enable  
set rule 10 state related enable  
top  
</code></pre>

<p>Next, we need to associate this new firewall with our interfaces. I'm assuming that <code>eth0</code> is the interface which connects to your local network. </p>

<pre><code>set interfaces ethernet eth0 firewall out ipv6-name home-ipv6  
commit  
save  
</code></pre>

<p>You're now protected. If you need to allow certain hosts, you can do this by adding new rules to the <code>home-ipv6</code> firewall.</p>

<h2 id="connectingclients">Connecting clients</h2>

<p>When we created our tunnel, we were allocated a /64 subnet (the "Routed /64"). This is the subnet which clients on your network will have IP addresses in. For example, my home network is <code>2001:470:1f1d:5::/64</code>.</p>

<p>To begin, we need to allocate an address from this range to our router. Run the command below to add the address. Note that I have added <code>1</code> just before the <code>/64</code>.</p>

<pre><code>set interfaces ethernet eth0 address 2001:470:1f1d:5::1/64  
</code></pre>

<p>In order for your clients to connect they need to have their own IPv6 address. Unlike IPv4, the most common way to connect client machines to an IPv6 network is to allow them to choose their own address based on their MAC address. In order for them to do this, we need to tell them things like the router address and what DNS servers to use. This is known as a router advertisement.</p>

<pre><code>edit interfaces ethernet eth0 ipv6  
set router-advert prefix [YOUR ROUTED /64]  
set router-advert radvd-options "RDNSS [YOUR ROUTER IPV6 ADDRESS] {};"  
top  
commit  
save  
</code></pre>

<h2 id="testing">Testing</h2>

<p>Everything should now be working and the clients on your network should start having IPv6 addresses as well as IPv4 ones.</p>

<p><img src="http://s.adamcooke.io/14/5o3hC.png" alt="OS X Screenshot"></p>

<p>You can do some testing to ensure things are working for you. Here's a few commands which I use to test different aspects of the IPv6 connection.</p>

<h3 id="testingconnectivitywithping">Testing connectivity with ping</h3>

<pre><code>ping6 google.com  
&gt; PING6(56=40+8+8 bytes) 2a00:1450:4009:80b::2000
&gt; 16 bytes from 2a00:1450:4009:80b::2000, icmp_seq=0 hlim=57 time=16.416 ms
&gt; 16 bytes from 2a00:1450:4009:80b::2000, icmp_seq=1 hlim=57 time=15.939 ms
</code></pre>

<h3 id="testingdns">Testing DNS</h3>

<p>This command will return information about <code>google.com</code>. The <code>-6</code> flag means that it will only use IPv6 to perform the lookups.</p>

<pre><code>host -6 google.com  
</code></pre>

<p>Another fun command to try is this.... this will lookup a DNS name and output the full trace of how it was located. You should be able to see that each step of the trace is resolved by an IPv6-enabled nameserver.</p>

<pre><code>dig -6 +trace atechmedia.com  
</code></pre>

<h2 id="nextsteps">Next steps</h2>

<ul>
<li>Ensure that any websites you run have are enabled for IPv6.</li>
<li>Take the <a href="https://ipv6.he.net/certification">HE.net IPv6 certification</a> to help improve your knowledge of IPv6.</li>
<li>Install a plugin in your browser so you can see whether a site is using IPv6 or not.</li>
</ul>]]></description><link>http://adamcooke.io/ipv6-edgerouter-he/</link><guid isPermaLink="false">4ef22e8f-7a90-4b23-8abd-c13dc95056e3</guid><dc:creator><![CDATA[Adam Cooke]]></dc:creator><pubDate>Sun, 11 Jan 2015 21:26:09 GMT</pubDate></item><item><title><![CDATA[Home-made Crunchie Ice Cream]]></title><description><![CDATA[<p>With Christmas fast approaching and with indulgence and over-eating very much part of the holiday, I made one of my favourite desserts - <strong>Crunchie Ice Cream</strong>.</p>

<p>It's a very simple recipe and only takes a few minutes to knock up and the end result is delicious.</p>

<h2 id="ingredients">Ingredients</h2>

<ul>
<li>600ml double cream</li>
<li>~350ml condensed milk (a whole tin)</li>
<li>6 Cadbury Crunchie Bars</li>
<li>2tsp of vanilla extract</li>
</ul>

<h2 id="method">Method</h2>

<ol>
<li>Chop up the Crunchie bars into small pieces. While doing this, keep hold of as much of the "dust" as possible.  </li>
<li>Whip the double cream until it is the thickness of a thickish custard.  </li>
<li>Fold in the condensed milk.  </li>
<li>Add the chopped up crunchie bars.  </li>
<li>Place the contents in a container and place in the freezer until frozen hard.  </li>
<li>Enjoy.</li>
</ol>]]></description><link>http://adamcooke.io/home-made-crunchie-ice-cream/</link><guid isPermaLink="false">511a39b9-165c-4691-b04d-205f37a26ac1</guid><category><![CDATA[recipes]]></category><dc:creator><![CDATA[Adam Cooke]]></dc:creator><pubDate>Mon, 22 Dec 2014 18:23:29 GMT</pubDate></item><item><title><![CDATA[The EU, Tech Companies & VAT]]></title><description><![CDATA[<p>Starting from January 2015, there are going to be some changes to way EU tech companies need to charge VAT to consumers. In the past, you would simply charge EU consumers VAT at your country's VAT rate however from 2015, companies will need to charge VAT the rate in the consumer's country.</p>

<p>This in itself isn't a particularily challenging issue for tech companies to deal with, however reliability determining the VAT rate for a country is slightly tricky. Unfortunately, there's no provided API which contains the VAT rates for countries therefore I have quickly knocked together a quick services which returns the VAT rates for every EU member country.</p>

<p>This can be accessed free of charge at <a href="http://jsonvat.com/"><strong>jsonvat.com</strong></a> and the data which is served can be found in <a href="https://github.com/adamcooke/vat-rates">this GitHub repository</a>.</p>

<p>Here's some lovely example JSON:</p>

<pre><code class="language-javascript">{
  "details":"http://github.com/adamcooke/vat-rates",
  "rates":[
    {
      "name":"Italy",
      "code":"IT",
      "periods":[
        {
          "effective_from":"0000-01-01",
          "rates":{
            "super_reduced":4.0,
            "reduced":10.0,
            "standard":22.0
          }
        }
      ]
    },
    [.... more countries here ....]
    {
      "name":"Greece",
      "code":"EL",
      "periods":[
        {
          "effective_from":"0000-01-01",
          "rates":{
            "reduced1":6.5,
            "reduced2":13.0,
            "standard":23.0
          }
        }
      ]
    }
  ]
}
</code></pre>

<p>While I will try to keep the data in the repository up to date, please do feel free to share this post and encourage others to submit pull requests when new VAT rates are announced. As I'm in the UK, I'll be on top of the UK changes.</p>]]></description><link>http://adamcooke.io/the-eu-tech-companies-vat/</link><guid isPermaLink="false">d781deb1-d4bd-46cf-92a7-df8ab2d8aa06</guid><category><![CDATA[ruby]]></category><category><![CDATA[vat]]></category><category><![CDATA[eu]]></category><category><![CDATA[opensource]]></category><dc:creator><![CDATA[Adam Cooke]]></dc:creator><pubDate>Mon, 13 Oct 2014 12:58:00 GMT</pubDate></item><item><title><![CDATA[Documentation Engine for Rails]]></title><description><![CDATA[<p>A couple of months ago, I wrote a Rails engine which provides applications with complete documentation library functionality by simplying adding a gem.</p>

<p><a href="http://github.com/adamcooke/documentation"><strong>Documentation</strong></a> is a Rails engine which provides a complete system for managing a set of hierarchical documentation. Once installed in an application, you'll have a complete user interface for viewing as well as editing a set of markdown pages.</p>

<p><img src="http://s.adamcooke.io/14/VGaMe.png" alt="Image"></p>

<p>I'm already using this myself in a couple of places including the <a href="http://viaduct.io/docs">Viaduct docs</a> and the <a href="http://sirportly.com/docs/api-specification">new Sirportly docs</a>.</p>

<p>Full documentation about how to get started can be found on <a href="https://github.com/adamcooke/documentation">GitHub</a> and <a href="https://github.com/adamcooke/documentation/tree/master/doc">in the repo</a>.</p>]]></description><link>http://adamcooke.io/documentation-rails-engine/</link><guid isPermaLink="false">c3572b96-a94a-4ae6-b745-b748cbe818a4</guid><category><![CDATA[ruby]]></category><category><![CDATA[rails]]></category><category><![CDATA[documentation]]></category><dc:creator><![CDATA[Adam Cooke]]></dc:creator><pubDate>Sun, 12 Oct 2014 17:52:43 GMT</pubDate></item><item><title><![CDATA[Install Ruby 2.1 on Ubuntu 14.04]]></title><description><![CDATA[<p>It's one of the most common tasks I need to carry out so I thought I'd quickly just document the process for installing Ruby from source on Ubuntu 14.04.</p>

<p>This assumes you're on a clean Ubuntu installation but it should perfectly well on an existing machine too.</p>

<h4 id="installprerequsitesdevelopmentlibraries">Install Prerequsites &amp; Development Libraries</h4>

<pre><code>apt-get update  
apt-get install  openssl libssl-dev libcurl4-openssl-dev \  
  zlib1g zlib1g-dev libsasl2-dev libncurses5-dev \
  libreadline-dev libxml2-dev python python-setuptools \
  libxslt-dev build-essential
</code></pre>

<h4 id="downloadcompileinstallruby">Download, Compile &amp; Install Ruby</h4>

<pre><code>cd /tmp  
wget http://cache.ruby-lang.org/pub/ruby/2.1/ruby-2.1.2.tar.gz  
tar zxvf ruby-2.1.2.tar.gz  
cd ruby-2.1.2  
./configure --disable-install-rdoc
make -j4  
make install  
cd /tmp  
rm -Rf ruby-2.1.2*  
</code></pre>

<h4 id="installbundler">Install Bundler</h4>

<pre><code>gem install bundler --no-ri --no-rdoc  
</code></pre>

<h4 id="useruby">Use Ruby</h4>

<pre><code>$ ruby -v
  ruby 2.1.2p95 (2014-05-08 revision 45877) [x86_64-linux]
</code></pre>]]></description><link>http://adamcooke.io/install-ruby-2-1-on-ubuntu-14-04/</link><guid isPermaLink="false">324c43c7-b136-46d0-bd15-d17abea0f5ea</guid><category><![CDATA[ubuntu]]></category><category><![CDATA[ruby]]></category><category><![CDATA[sysadmin]]></category><dc:creator><![CDATA[Adam Cooke]]></dc:creator><pubDate>Tue, 02 Sep 2014 20:41:00 GMT</pubDate></item><item><title><![CDATA[Gulp & Rails]]></title><description><![CDATA[<p>I've recently started using Gulp rather than the built-in asset pipeline in Rails. Gulp provides a fair amount of additional flexibility and functionality which I am very much enjoying.</p>

<p><img src="http://s.adamcooke.io/14/TE1xO.png" alt="Image"></p>

<p>However, one of the key issues is that it is nessessary to run <code>gulp</code> in the background when working on the application. The OCD part of me makes me feel very dirty and I do often forget to run it which leads to frustration.</p>

<h3 id="introducinggulp_rails">Introducing gulp_rails</h3>

<p>gulp_rails is a tiny gem which sits in your Rails request cycle and runs your gulp commands automatically on each request. This now avoids the need to run any other commands other than your normal <code>rails server</code> when working on a application - neat, huh?</p>

<p><a href="http://github.com/adamcooke/gulp-rails">Check it out on GitHub.</a> Also be sure to read the README as there's a bit of useful information about how to optimise your Gulpfile.js for maximum performance.</p>

<p><img src="http://s.adamcooke.io/14/pWWTs.png" alt="Screenshot"></p>]]></description><link>http://adamcooke.io/gulp-rails/</link><guid isPermaLink="false">b7063661-3aa2-4361-bebb-9886edc3c7ef</guid><category><![CDATA[rails]]></category><category><![CDATA[frontend]]></category><category><![CDATA[gulp]]></category><dc:creator><![CDATA[Adam Cooke]]></dc:creator><pubDate>Mon, 21 Jul 2014 09:49:59 GMT</pubDate></item><item><title><![CDATA[Installing Shoppe into Rails]]></title><description><![CDATA[<p>I've just recorded a quick screencast showing how to install <a href="http://tryshoppe.com/">Shoppe</a> (my open source e-commerce engine) into a new Rails application. </p>

<iframe width="640" height="360" src="http://www.youtube.com/embed/p2Fvw35ezds" frameborder="0" allowfullscreen></iframe>

<p>As you can see, getting started with Shoppe is really easy!</p>]]></description><link>http://adamcooke.io/installing-shoppe-into-rails/</link><guid isPermaLink="false">b7057699-faa1-4601-a3ca-3b74d9668389</guid><category><![CDATA[shoppe]]></category><category><![CDATA[rails]]></category><category><![CDATA[screencast]]></category><dc:creator><![CDATA[Adam Cooke]]></dc:creator><pubDate>Fri, 11 Jul 2014 07:03:38 GMT</pubDate></item><item><title><![CDATA[Apple Push Notifications using HTTP]]></title><description><![CDATA[<p>I've recently been working on developing an iOS application for <a href="http://www.sirportly.com/">Sirportly</a> - a helpdesk product which we run &amp; develop at aTech. As part of this application, it became nessessary for the Sirportly application to be able to send push notifications to users iOS devices. </p>

<h3 id="theapplepushnotificationservice">The Apple Push Notification Service</h3>

<p>The Apple Push Notification Service (or APNS for short) is a service provided by Apple to iOS developers to enable them to send notifications to any iOS device which has installed their application. In order to do this, your service-side application must open a secure connection to the APNS service and send any notifications in binary across this persistent connection. Unfortunately, many developers are unfamiliar with this technology and more happy working with HTTP APIs. There is also the additional overhead of worrying about maintaining persistent connections to Apple to avoid being blacklisted for repeated re-connections. </p>

<h3 id="introducingapnsproxy">Introducing APNS Proxy...</h3>

<p>The <a href="http://github.com/adamcooke/apns-proxy">APNS proxy</a> is an open source Rails application which handles all the connections to the APNS service and allows you to send your notifications to a familiar HTTP endpoint. Other key features include:</p>

<ul>
<li>A nice web-based admin interface for managing your service &amp; monitoring the sending of your notifications</li>
<li>Monitoring of the Apple Feedback channels to ensure that devices which uninstall your application are no longer delivered notifications.</li>
<li>Ability to support multiple applications with multiple environments and authentication keys.</li>
</ul>

<p><img src="http://s.adamcooke.io/14/89p8W.png" alt="Image"></p>

<h3 id="howcaniuseit">How can I use it?</h3>

<p>Full documentation about using the APNS Proxy is provided within the repository's <a href="https://github.com/adamcooke/apns-proxy/blob/master/README.md">README</a>. This includes information about installing the server software and using the API to deliver notifications to it.</p>

<p>It's pretty simple to get started. It only took a few seconds for me to deploy a new instances for my own use to <a href="http://viaduct.io/">Viaduct</a>.</p>

<h4 id="sendingnotificationstoapnsproxyfromruby">Sending notifications to APNS Proxy from Ruby</h4>

<p>I've also made <a href="https://github.com/adamcooke/apns-client">APNS Client</a> which is a Ruby library which can send messages to your APNS Proxy server. Once you've installed this, sending a notification from a Ruby application is as simple as this:</p>

<pre><code>require 'apns'

# Create a client object
client = APNS::Client.new('https://apns.company.com', auth_key)

# Make a notification
notification = APNS::Notification.new  
notification.alert_body = 'Hello World!'

# Send the notification to the device token
client.notify(device_token, notification)  
</code></pre>

<h4 id="convertingyourp12andcerfilestoasuitableformat">Converting your P12 and CER files to a suitable format</h4>

<p>If you follow Apple guidance and create a private key using Keychain Access, you'll be presented with a P12 private key file. You will also have a CER file from Apple once you have uploaded your signing request. The APNS Proxy service needs these keys to be provided in PEM format.</p>

<p>To help with this conversion, I've made a small command line utility called <a href="https://github.com/adamcooke/apns-key-convert">apns-key-convert</a> which takes your two key files and spits out a PEM file which you can just upload into the appropriate APNS Proxy environment.</p>]]></description><link>http://adamcooke.io/apple-push-notifications-over-http/</link><guid isPermaLink="false">874f4e28-57e6-4aac-a7d3-afdc800c7869</guid><category><![CDATA[ios]]></category><category><![CDATA[apns]]></category><category><![CDATA[apple]]></category><category><![CDATA[iphone]]></category><category><![CDATA[ipad]]></category><category><![CDATA[http]]></category><category><![CDATA[p12]]></category><category><![CDATA[cer]]></category><category><![CDATA[ruby]]></category><dc:creator><![CDATA[Adam Cooke]]></dc:creator><pubDate>Mon, 23 Jun 2014 20:00:40 GMT</pubDate></item><item><title><![CDATA[Set the top border colour of a UINavBar]]></title><description><![CDATA[<p>I've recently started developing iOS applications and on my journey of discovery I have discovered a number of useful little gems of information which I wanted to share.</p>

<p>The first of these gems is how to set the top border colour of a <code>UINavBar</code> element. </p>

<p><img src="http://s.adamcooke.io/14/wpQIv.png" alt="Image"></p>

<p>By default, iOS includes a grey bar at the top of the bar itself. This line is actually outside the <code>UINavBar</code> view and not easily configurable using Interface Builder. In order to change this bar, you must create a new layer within the bar and hide the default border.</p>

<p>Firstly, you'll need to connect your <code>UITabBar</code> up to a view controller as an IBAction. In this example, I have called it <code>tabBar</code>. </p>

<script src="https://gist.github.com/adamcooke/a6ce87df015f26488fc1.js"></script>

<p>In order to hide the system border, I have found that it's usually enough to simply set the <code>clipsToBounds</code> property on the tab bar to true.</p>

<pre><code>self.tabBar.clipsToBounds = YES;  
</code></pre>]]></description><link>http://adamcooke.io/set-the-top-border-colour-of-a-uinavbar/</link><guid isPermaLink="false">50d47f35-2be0-48ff-8f0c-c77ec3ffb5c8</guid><category><![CDATA[ios]]></category><category><![CDATA[UITabBar]]></category><category><![CDATA[UIColor]]></category><category><![CDATA[clipsToBounds]]></category><dc:creator><![CDATA[Adam Cooke]]></dc:creator><pubDate>Tue, 10 Jun 2014 21:45:08 GMT</pubDate></item><item><title><![CDATA[Take your phone system on the go]]></title><description><![CDATA[<p>In the last few days, we've been exploring ways to help our customers stay connected with their business when they're on the move and we've got a fantastic solution.</p>

<h3 id="introducingdial9mobile">Introducing Dial 9 Mobile</h3>

<p>Dial 9 Mobile is a SIM card which you can put into any mobile and your phone will work in exactly the same way as the phone on your desk.</p>

<ul>
<li>Make and receive calls.</li>
<li>Make and receive calls from other extensions.</li>
<li>Send &amp; receive text messages.</li>
<li>If your mobile is part of a call group, it will ring just like all the other phones.</li>
<li>Voicemail is available when your phone is out of range or turned off.</li>
<li>Calls can be recorded just like all other extensions.</li>
<li>Route any numbers directly to your mobile.</li>
</ul>

<p><img src="http://files.adamcooke.io/2014/d05tw4s.jpg" alt="Image"></p>

<p>We've still got a bit of work to do our end to establish exactly how much it will cost and how it will be billed. We currently expect to charge a line rental of around £4/month and an additional 2p/minute for all calls made/to from your mobile on top of any existing call charges. </p>]]></description><link>http://adamcooke.io/take-your-phone-system-on-the-go/</link><guid isPermaLink="false">f32b9215-17c3-4dfd-9b79-d0525ab84557</guid><category><![CDATA[dial9]]></category><category><![CDATA[nokia]]></category><category><![CDATA[sim-cards]]></category><dc:creator><![CDATA[Adam Cooke]]></dc:creator><pubDate>Wed, 14 May 2014 13:02:30 GMT</pubDate></item><item><title><![CDATA[It's time for Viaduct]]></title><description><![CDATA[<p>Yesterday, I publically announced a huge new project we'll be launching next year. I just wanted to write a quick post about what this means for me personally.</p>

<p><a href="http://viaduct.io/"><img src="http://s.adamcooke.io/kzzWW.png" alt="Image" title=""></a></p>

<p><a href="http://viaduct.io/">Viaduct</a> is an application hosting platform with a difference and I'm so excited to get it out there! If you haven't already go and <a href="http://viaduct.io/">check out the website</a> and/or <a href="http://blog.viaduct.io/introducing-viaduct/">intro blog post</a> to get an idea of what we're trying to achieve.</p>

<p>This is the biggest new venture I have taken on since I started <a href="http://atechmedia.com/">aTech Media</a> back in 2004. It's all very exciting (and daunting) at the moment and there's loads going on behind the scenes. At the moment, we're busy working on the management and orchestration platform behind it all as well as making some big decisions about hardware. Fortunately, having worked closely with some big players in the cloud hosting world, we've got many years of experience working with virtualisation, application hosting &amp; networks so we have a very firm understanding of the technologies involved and our requirements.</p>

<p><img src="http://viaduct.io/assets/holding/ss-bbfed46976b8444435a0dd62f06871b0.png" alt="Screenshot"></p>

<p><strong>What does this mean for me for 2014?</strong> While my main focus going forward will be Viaduct, I'm not abandoned my other commitments. Fortunately, I have an excellent team at aTech and they will continue to develop &amp; support these other projects as well as contributing heavily to Viaduct. Physically, I'm not going anywhere, so I'll still be in <a href="http://www.pooletourism.com/">Poole</a> and working from our office.</p>

<p><strong>What's your role with Viaduct?</strong> To begin with, I will continue to lead development &amp; design alongside handling all the day-to-day management &amp; marketing responsibilities. As the time progresses, I will be able to shed some development responsibilities to the rest of the team and focus on the business side of things. As usual, <a href="http://twitter.com/catphish">Charlie</a> is on-board too and between us we'll implement our new network &amp; server architecture.</p>

<p>So... with all that said... it's time for me to get back to working on our internal API for the Viaduct orchestration suite!</p>]]></description><link>http://adamcooke.io/its-time-for-viaduct/</link><guid isPermaLink="false">0cabff4d-8ef3-4b82-8db5-964e0ea828e7</guid><dc:creator><![CDATA[Adam Cooke]]></dc:creator><pubDate>Fri, 20 Dec 2013 06:44:37 GMT</pubDate></item><item><title><![CDATA[Setting up an office network]]></title><description><![CDATA[<p>Our office connectivity is relatively simple and pretty standard for most offices, so I thought I would share our configuration and how we've set everything up. I thought a blog post outlining how we have things configured would be useful for others as well as documentation for ourselves.</p>

<p><img src="http://s.adamcooke.io/6yX9v.png" alt="Image"></p>

<p>I recently came by a <a href="http://www.ubnt.com/edgemax#EdgeMAXhardware">EdgeRouter Lite</a> from <a href="http://www.ubnt.com/">Ubiquiti Networks</a> and we use one of these as our main office gateway/router. In the past we have just used a Linux box but the EdgeRouter is less power-hungry and easily fits into our data cabinets.</p>

<p>Before I get into the details of how we have this router configured, the list below outlines our key requirements from our network.</p>

<ul>
<li>Three seperate networks:
<ul><li>Our main office network used by staff workstations, VoIP phones etc...</li>
<li>A public network for guests to use with both wired &amp; wireless access</li>
<li>An "access control" network which is used for our IP-connected access control system. Unfortunately, there's no security on the actual access control devices so a seperate firewalled network is a must.</li></ul></li>
<li>2 PPPoE BT-provided FTTC connections (from Zen Internet). One used for public traffic and the other used just for our VPN.</li>
<li>Ability to join our office network into our VPN - allowing us to connect to other networks (including our core networks in London).</li>
</ul>

<h2 id="equipmentused">Equipment Used</h2>

<ul>
<li>The EdgeRouter Lite itself (here after referred to as the router).</li>
<li>BT provided VDSL modems.</li>
<li>We use two managed switches on the office which allow us to place any port in the office onto any VLAN we desire.</li>
<li>Our wifi uses the Ubiquiti Unifi access points which support multiple SSIDs on different VLANs with a variety of security options. We have two SSIDs one for staff (using WPA2 Enterprise) and one for guests (WPA2-PSK).</li>
</ul>

<h2 id="vsdlmodems">VSDL Modems</h2>

<p>The VSDL modems provided by BT allow you to simple connect to your ISP using PPPoE. Therefore, we placed each modem on its own dedicated VLAN which is only available to the router.</p>

<h2 id="routerinterfaces">Router Interfaces</h2>

<p>In order to configure the router, I am using the CLI interface which I love. The web interface provided by Ubiquiti seems to only include 20% of the actual functionality.</p>

<p>To begin I've set up our router with an interface on each of our networks. At present, it is just plugged into a single <em>trunk</em> port on a switch with the main office network untagged and the other VLANs tagged.</p>

<pre><code>interfaces {  
    ethernet eth0 {
        address 10.0.2.1/24
        description Office
        vif 100 {
            address 10.0.3.1/24
            description Security
            mtu 1500
        }
        vif 101 {
            address 172.16.0.1/24
            description Guests
            mtu 1500
        }
        vif 201 {
            description "PPPoE Linknet #1"
            mtr 1500
        }
        vif 202 {
            description "PPPoE Linknet #2"
            mtu 1500
        }
      }
    loopback lo {
    }
}
</code></pre>

<p>In this configuration, you can see we have set up 5 networks. As there is only one connected physical interface, these virtual interfaces are all within the <code>eth0</code> interface.</p>

<p>Of course, once you have made these changes, you will need to <code>commit</code> them on the router and any IP you were using for management may be removed.</p>

<h2 id="pppoeconfiguration">PPPoE Configuration</h2>

<p>Our PPPoE Configuration is pretty simple. The PPPoE configuration itself is placed on the <code>vif</code> for your PPPoE link network, as follows:</p>

<pre><code>interfaces {  
    ethernet eth0 {
        vif 201 {
            description "PPPoE Linknet #1"
            mtu 1500
            pppoe 0 {
                default-route auto
                   firewall {
                    out {
                        modify pppoe-out
                    }
                }
                mtu 1492
                password *******
                user-id username@isp
            }
        }
    }
}
</code></pre>

<p>You will also notice the interface is set to use the <code>pppoe-out</code> firewall policy. This must also be created:</p>

<pre><code>firewall {  
    modify pppoe-out {
        rule 1 {
            action modify
            modify {
                tcp-mss 1452
            }
            protocol tcp
            tcp {
                flags SYN
            }
        }
    }
}
</code></pre>

<p>This policy is configured to modify the size of TCP packets so they work with PPPoE connections. <a href="http://adsl.cutw.net/mtu.html">Read more about this here</a>.</p>

<p>This is then repeated for <code>vif 202</code> but using <code>pppoe 1</code> rather than <code>0</code> and with different credentials. The other difference is that <code>default-route</code> is set to <code>none</code> as we don't want a default route for this connection.</p>

<p>In order to route our VPN traffic over the other PPPoE connection (pppoe1), we will create a static interface route which ensures the IP for our VPN will always go to that connection.</p>

<pre><code>protocols {  
    static {
        interface-route x.x.x.x/32 {
            next-hop-interface pppoe1
        }
    }
}
</code></pre>

<h2 id="configuratingnat">Configurating NAT</h2>

<p>Next up, you'll need to configure a NAT so that your local subnets have access to the internet over these connections. The following NAT rule will ensure that all traffic destined for pppoe0 will be "natted" as appropriate.</p>

<pre><code>service {  
    nat {
        rule 5000 {
            description pppoe0-nat
            log disable
            outbound-interface pppoe0
            type masquerade
        }
    }
}
</code></pre>

<p>You should repeat these as rule <code>5001</code> for <code>pppoe1</code> for the other connection (if you need it). In our case, we don't actually need to NAT the traffic to our VPN as only our router will be connecting to it.</p>

<h2 id="dhcpserver">DHCP Server</h2>

<p>Assuming you don't want every user to manually configure their own IPs on your network, you'll need to configure the DHCP server. We only need to dynamically allocate addresses for our office &amp; guest networks.</p>

<pre><code>service {  
    dhcp-server {
        shared-network-name office {
            subnet 10.0.2.0/24 {
                default-router 10.0.2.1
                dns-server 8.8.8.8
                dns-server 141.1.1.1
                domain-name poole.atech.io
                start 10.0.2.10 {
                    stop 10.0.2.199
                }
            }
        }
    }
}
</code></pre>

<p>You should repeat the <code>shared-network-name</code> section for your public network and set it up to allocate addresses as appropriate. We just use a couple of public DNS servers as nameservers (Google and C&amp;W in this case).</p>

<h2 id="midwaytesting">Mid-way testing</h2>

<p>You can give all that a test now. Pop a computer onto one of your subnets and using <code>ping</code> and <code>mtr</code> to test you can access the sites you expect and that traffic is routed over the correct paths. </p>

<p>To look at the connected interfaces, just run <code>show interfaces</code> on your router's CLI.</p>

<pre><code>ubnt@gateway:~$ show interfaces  
Codes: S - State, L - Link, u - Up, D - Down, A - Admin Down  
Interface    IP Address                S/L  Description  
---------    ----------                ---  -----------
eth0         10.0.2.1/24               u/u  Office  
eth0.100     10.0.3.1/24               u/u  Security  
eth0.101     172.16.0.1/24             u/u  Guests  
eth0.201     -                         u/u  PPPoE Link #1  
eth0.202     -                         u/u  PPPoE Link #2  
lo           127.0.0.1/8               u/u  
             ::1/128
pppoe0       123.123.123.123           u/u  
pppoe1       123.123.123.234           u/u  
</code></pre>

<p>You can also take a look at your routing table with <code>show ip route</code>.</p>

<pre><code>ubnt@gateway:~$ show ip route  
Codes: K - kernel route, C - connected, S - static, R - RIP, O - OSPF,  
       I - ISIS, B - BGP, &gt; - selected route, * - FIB route

K&gt;* 0.0.0.0/0 is directly connected, pppoe0  
C&gt;* 10.0.3.0/24 is directly connected, eth0.100  
C&gt;* 62.3.84.21/32 is directly connected, pppoe1  
C&gt;* 62.3.84.25/32 is directly connected, pppoe0  
C&gt;* 127.0.0.0/8 is directly connected, lo  
C&gt;* 172.16.0.0/24 is directly connected, eth0.101  
S&gt;* xxx.xxx.xxx.xxx/32 [1/0] is directly connected, pppoe1  
</code></pre>

<p>The final route in the example output is the static route you provided for your VPN connection on <code>pppoe1</code>.</p>

<h2 id="settingupopenvpn">Setting up OpenVPN</h2>

<p>This isn't a blog post about the specifics of OpenVPN but I will explain where to put your configuration files and how to make the router connect to it.</p>

<p>I have placed my OpenVPN configuration files into <code>/config/auth/ovpn*</code> on the router. I have 4 files: </p>

<ul>
<li><code>ovpn.conf</code> - a standard OpenVPN client configuration file</li>
<li><code>ovpn-ca.crt</code> - the OpenVPN CA certificate</li>
<li><code>ovpn-client.crt</code> - the OpenVPN client certificate</li>
<li><code>ovpn-client.key</code> - the OpenVPN client private key</li>
</ul>

<p>Once you have put these in place, you should tell the router you've done that with:</p>

<pre><code>interfaces {  
    openvpn vtun0 {
        config-file /config/auth/ovpn.conf
    }
}
</code></pre>

<p>You can configure OpenVPN itself in the <code>openvpn</code> configuration above but as I already had configuration files, it was quicker to do this for me.</p>

<p>Once you have committed these changes, you should find that your VPN connects and your <code>show interfaces</code> includes a new interface for your VPN connection.</p>

<pre><code>tap0         10.0.5.4/24               u/D  
</code></pre>

<p>If your OpenVPN server also provides you with routes, you will find that <code>show ip route</code> includes these routes along with a "connected" route for your VPN client subnet.</p>

<pre><code>K&gt;* 10.0.0.0/16 via 10.0.5.1, tap0  
C&gt;* 10.0.5.0/24 is directly connected, tap0  
K&gt;* 185.22.208.0/22 via 10.0.5.1, tap0  
</code></pre>

<h2 id="fixingtheguestnetwork">Fixing the Guest Network</h2>

<p>Unfortunately, at this point we have a bit an issue with our Guest network. While it can access most of the internet, it will not have access to anything which is routed over the VPN connection. This is because our core network routers know how to route <code>10.0.2.0/24</code> back to our office over the VPN but has no idea about the <code>172.16.0.0/24</code> network used for the guest network.</p>

<p>We don't want our guests to access to our network over the VPN so we need to use policy based routed to route traffic different based on its source IP. Fortunately, this is pretty simple. Firstly, we need to create a new routing table for the public network which sends everything over <code>pppoe0</code>.</p>

<pre><code>protocols {  
    static {
        table 101 {
            interface-route 0.0.0.0/0 {
                next-hop-interface pppoe0
            }
        }
    }
}
</code></pre>

<p>Next, we need to create a firewall policy to route traffic from <code>172.16.0.0/24</code> to this new routing table.</p>

<pre><code>firewall {  
    modify public-traffic {
        rule 10 {
            modify {
                table 101
            }
            source {
                address 172.16.0.0/24
            }
        }
    }
}
</code></pre>

<p>Finally, we need to set up our public interface on the router <code>eth0 vif 101</code> to use this policy.</p>

<pre><code>interfaces {  
    ethernet eth0 {
        vif 101 {
            in {
                modify public-traffic
            }
        }
    }
}
</code></pre>

<h2 id="securingtheaccesscontrolnetwork">Securing the access control network</h2>

<p>We don't want anyone (except our access control server) accessing the access control network so we need to add a firewall policy for this. </p>

<pre><code>firewall {  
    name security {
        default-action drop
        rule 1 {
            action accept
            description "Allow Management Server"
            destination {
                address 10.0.3.0/24
            }
            log disable
            protocol all
            source {
                address xxx.xxx.xxx.xxx
            }
        }
    }
}
</code></pre>

<p>As above, this policy needs to be applied to the security interface.</p>

<pre><code>interfaces {  
    ethernet eth0 {
        vif 100 {
            out {
                name security
            }
        }
    }
}
</code></pre>

<h2 id="finishingup">Finishing up</h2>

<p>That's pretty much all there is to it. There are a couple of other bits which I haven't documented like IPv6 tunnelling over our VPN and DHCP settings for the Unifi APs. </p>

<p>All in all, the EdgeRouter is a powerful bit of kit and I would recommend them for any office-based situation. The software itself seems to be based on Vyatta who have an excellent reputation for routing. I look forward to having a look at their more professional equipment in the future!</p>]]></description><link>http://adamcooke.io/edgerouter-pppoe-office/</link><guid isPermaLink="false">c3ecd775-90f7-4c49-ae24-f5de03e47e18</guid><dc:creator><![CDATA[Adam Cooke]]></dc:creator><pubDate>Sun, 15 Dec 2013 15:16:52 GMT</pubDate></item><item><title><![CDATA[Reminiscing: Desklamp]]></title><description><![CDATA[<p>Back in 2006 when <a href="http://atechmedia.com/">aTech</a> was just a fledgling web design company, I started work on a CRM-type application to help us manage clients, jobs &amp; quotes.</p>

<p style="text-align:center;"><img src="http://s.adamcooke.io/LtyUP.png" width="140"></p>

<p>At the time, we received quite a lot of interest from other designers &amp; developers and, the SaaS market was tiny compared to today. Frameworks were much less advanced and creating applications was a slow and labourious process. It certainly shows here!</p>

<p>Desklamp was originally written in PHP and later converted to Ruby on Rails. I recently came across the original PHP code and an associated screencast. I thought it would be fun to share both!</p>

<iframe style="margin:auto" width="640" height="480" src="http://www.youtube-nocookie.com/embed/DMIyMOfiw3g?rel=0" frameborder="0" allowfullscreen></iframe>

<p>This screencast shows some of the little UI enhancements which existed - inline editting, confirmation dialogs, validation errors etc... I'm actually very proud of the design &amp; the experience . I wish I could say the same about <a href="https://github.com/adamcooke/desklamp-php">the code</a>! I haven't looked at it in too much detail but if I wrote actual MySQL queries in my views today, I would be <a href="http://en.wikipedia.org/wiki/Hanged,_drawn_and_quartered">hung, drawn and quartered</a>. </p>

<p>Here's a few screenshots from the application and it's associated marketing website:</p>

<p><img src="http://s.adamcooke.io/0z3qG.png" alt="Image"></p>

<p><img src="http://s.adamcooke.io/9d3od.png" alt="Image"></p>

<p><img src="http://s.adamcooke.io/brVGa.png" alt="Image"></p>

<p><img src="http://s.adamcooke.io/S5lqg.png" alt="Image"></p>]]></description><link>http://adamcooke.io/reminiscing-desklamp/</link><guid isPermaLink="false">7b198e10-b9e4-4aff-8d4e-ba979767d852</guid><dc:creator><![CDATA[Adam Cooke]]></dc:creator><pubDate>Thu, 12 Dec 2013 20:09:36 GMT</pubDate></item><item><title><![CDATA[Gandi inter-account transfer woes]]></title><description><![CDATA[<p>I use Gandi for registering .io domains as they tend to be slightly cheaper than doing direct to the registry (and they have a better process).</p>

<p>However, for one reason and other, I have ended up with domains split across two Gandi accounts so I wanted to transfer them into the same account. A simple task, you'd think? </p>

<p><img src="http://s.adamcooke.io/UdyE4.png" alt="Website"></p>

<p>Firstly, I try to do this in the web interface, but it's not possible there. So, I emailed support and asked and was told a crazy and ridciculous procedure:</p>

<ul>
<li><p>Complete <a href="http://wiki.gandi.net/_media/en/contacts/changeowner/en-owner-change.pdf">a form</a> signed by both new &amp; old owners and return to them by fax or post. Despite it being 2013, they cannot accept these by e-mail.</p></li>
<li><p>Topup the receiving account with the full registration amount for the domains. Therefore they are asking me to re-buy domains which I have already paid for. I'm told "this is the charge to move the domain". I wouldn't object to this so much if the domain was renewed at the point of transfer but I have no reason to think it will be.</p></li>
</ul>

<p>All of this, for a simple:</p>

<pre><code>UPDATE domains SET user_id = 'NEWID' WHERE domain = 'mydomain.io';  
</code></pre>

<p>Am I being unresonable in expecting these simple moves to other accounts to be free and a simple process?</p>]]></description><link>http://adamcooke.io/gandis-domain-transfer/</link><guid isPermaLink="false">9ee35ef7-c5af-4b53-b4c5-1a22caceeac7</guid><dc:creator><![CDATA[Adam Cooke]]></dc:creator><pubDate>Wed, 11 Dec 2013 08:53:30 GMT</pubDate></item><item><title><![CDATA[Introducing Shoppe]]></title><description><![CDATA[<p>During October, I started looking for an e-commerce platform we could use to launch our first line shop for <a href="http://www.dial9.co.uk/">Dial 9</a>. We needed to be able to sell products from a number of categories, accept a payment and mark the order as shipped.</p>

<p>I looked at a number of potential solutions, ranging from Spree &amp; Magento to hosted solutions like Shopify but I couldn't really find anythign which met my needs and I was happy with using. </p>

<p>I then decided to quickly build something in Rails and <a href="http://tryshoppe.com/">Shoppe</a> was born. I originally was planning to just build something for the Dial 9 shop but was pursuaded to build it as an engine which can be plugged into any Rails application to expose a wealth of e-commerce functionality.</p>

<p><img src="http://s.adamcooke.io/sG1oP.png" alt="Screenshot"></p>

<p><a href="http://tryshoppe.com/">Shoppe</a> is a full Ruby on Rails engine which provides all the models needed to accept orders through a checkout process, integrate with any payment processor as well as having a beautiful user interface for managing products &amp; orders.</p>

<p>It's a completely open source project released under the MIT licence. It has a lovely little website and some <a href="http://tryshoppe.com/docs/tutorials/getting-started">excellent documentation</a> to help anyone get started.</p>

<p>Check out <a href="http://demo.tryshoppe.com/">the demo</a> to see an example frontend store and access the backend Shoppe interface.</p>

<p><img src="http://s.adamcooke.io/ZgZLp.png" alt="Website Screenshot"></p>

<p>So... if you're looking for some e-commerce platform, why not take a look at Shoppe? </p>]]></description><link>http://adamcooke.io/introducing-shoppe/</link><guid isPermaLink="false">29195d15-0d48-4cc2-bedc-4d400321081d</guid><dc:creator><![CDATA[Adam Cooke]]></dc:creator><pubDate>Sat, 30 Nov 2013 14:00:34 GMT</pubDate></item></channel></rss>