<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Seb Maynard</title>
	<atom:link href="http://5eb.me/feed/" rel="self" type="application/rss+xml" />
	<link>http://5eb.me</link>
	<description>software and web developer</description>
	<lastBuildDate>Thu, 26 Apr 2012 13:32:37 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>How to import your ReadItLater items into Delicious (python converter)</title>
		<link>http://5eb.me/readitlater-to-delicious-export-converter/</link>
		<comments>http://5eb.me/readitlater-to-delicious-export-converter/#comments</comments>
		<pubDate>Thu, 26 Apr 2012 13:29:24 +0000</pubDate>
		<dc:creator>Seb</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[The Internet]]></category>

		<guid isPermaLink="false">http://5eb.me/?p=348</guid>
		<description><![CDATA[I like readitlater; but recently I found myself wanting to share some of my tagged items with other people and couldn&#8217;t find a way to do it. I used Delicious years ago and that&#8217;s always been a much more social app, so fired that up, and looked for way to import items. Unfortunately the export [...]]]></description>
			<content:encoded><![CDATA[<p>I like readitlater; but recently I found myself wanting to share some of my tagged items with other people and couldn&#8217;t find a way to do it. I used Delicious years ago and that&#8217;s always been a much more social app, so fired that up, and looked for way to import items.</p>
<p>Unfortunately the export format of readitlater isn&#8217;t compatible with the import format required by Delicious; so here&#8217;s a quick python script to convert a ReadItLater exported html file to a file that Delicious&#8217;s import will accept.</p>
<p><span id="more-348"></span></p>
<h4>Get the export</h4>
<p>First, visit <a title="ReadItLater export" href="http://readitlaterlist.com/export" target="_blank">readitlaterlist.com/export</a> and download that file somewhere; it should create <code class="prettyprint">ril_export.html</code></p>
<h4>Convert to Delicious format</h4>
<p>Copy the script below to <code class="prettyprint">ril2del.py</code> (or whatever you feel like) then run:</p>
<pre class="prettyprint">./ril2del.py ril_export.html converted_for_delicious.html</pre>
<h4>Import to Delicious</h4>
<p>Then visit the Delicious import page at <a href="http://export.delicious.com/settings/bookmarks/import" target="_blank">export.delicious.com/settings/bookmarks/import</a> and point it at your generated file (<code class="prettyprint">converted_for_delicious.html</code>) and hey presto, you&#8217;ve got all your readitlater bookmarks in Delicious complete with tags. Read items from RiL will have an extra tag &#8220;read&#8221; and unread items have an &#8220;unread&#8221; tag.</p>
<h4>The script</h4>
<p>(requires python2 and BeautifulSoup4 to be installed; you can install BeautifulSoup4 with pip)</p>
<pre class="prettyprint">#!/usr/bin/env python

from bs4 import BeautifulSoup
import sys
import os

def usage():
    print "r2d &lt;inputfile&gt; &lt;outputfile&gt;"
    return 1

def first_child(list):
    for item in list:
        return item

def process(ul, extraTag, output):
    for li in ul.find_all("li"):
        a = li.a
        replacements = dict()
        replacements[":tags"] = a["tags"] + "," + extraTag
        replacements[":time_added"] = a["time_added"]
        replacements[":href"] = a["href"]
        replacements[":content"] = first_child(a)
        outputString = """&lt;DT&gt;&lt;A HREF=":href" ADD_DATE=":time_added" PRIVATE="1" TAGS=":tags"&gt;:content&lt;/A&gt;\n"""
        for key in replacements:
            outputString = outputString.replace(key, replacements[key])
        output.write(outputString.encode("UTF-8"))

def main():
    args = sys.argv[1:]
    if len(args) != 2:
        return usage()
    infile = args[0]
    outfile = args[1]
    if not os.path.isfile(infile):
        print "Cannot read input file:", infile
    soup = BeautifulSoup(file(infile).read())

    output = file(outfile, "w")
    output.write("""&lt;!DOCTYPE NETSCAPE-Bookmark-file-1&gt;
&lt;META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8"&gt;
&lt;TITLE&gt;Bookmarks&lt;/TITLE&gt;
&lt;H1&gt;Bookmarks&lt;/H1&gt;
&lt;DL&gt;&lt;p&gt;
""")

    uls = soup.find_all("ul")
    unread = uls[0]
    read = uls[1]
    process(ul=unread, extraTag="unread", output=output)
    process(ul=read, extraTag="read", output=output)

    output.write("&lt;/DL&gt;&lt;p&gt;")

if __name__ == "__main__":
    sys.exit(main())</pre>
]]></content:encoded>
			<wfw:commentRss>http://5eb.me/readitlater-to-delicious-export-converter/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Google Chrome Extension build script</title>
		<link>http://5eb.me/google-chrome-extension-build-script/</link>
		<comments>http://5eb.me/google-chrome-extension-build-script/#comments</comments>
		<pubDate>Fri, 09 Mar 2012 10:15:48 +0000</pubDate>
		<dc:creator>Seb</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[The Internet]]></category>

		<guid isPermaLink="false">http://5eb.me/?p=317</guid>
		<description><![CDATA[If you build Chrome extensions, you probably understand it&#8217;s a bit of a pain in the bum having to move all the files into the right place (especially if you have shared assets elsewhere), keep track of versions of your package, update your update.xml, and packaging it all up into a .crx and a .zip [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignright size-full wp-image-329" title="buildchrome" src="http://5eb.me/wp/wp-content/uploads/2012/03/buildchrome.png" alt="" width="124" height="129" />If you build Chrome extensions, you probably understand it&#8217;s a bit of a pain in the bum having to move all the files into the right place (especially if you have shared assets elsewhere), keep track of versions of your package, update your update.xml, and packaging it all up into a .crx and a .zip for publishing on the Chrome webstore. I found a it a pain in the bum anyway, so I wrote a bash script to simplify the build process a bit.</p>
<p>It pumps out a .crx (signed with your .pem, ready for hosting on your site) and a .zip (ready for uploading to the Chrome Store).</p>
<p><span id="more-317"></span></p>
<p>Here it is &#8211; it should work under linux and cygwin, let me know if you have any issues in the comments <img src='http://5eb.me/wp/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  &#8211; instructions at the top of the file.</p>
<p>Click <a title="Right-click and save" href="http://5eb.me/other/chromebuild/crx_build.sh" target="_blank">here</a> to download a copy of it.</p>
<p>There&#8217;s an example of how to use it at the end of this post.</p>
<h4>crx_build.sh Chrome extension build script</h4>
<pre class="prettyprint">#!/bin/bash
# Author Seb Maynard, 2012
# http://5eb.me
#
# Script to generate and package CRX chrome extensions and zip files ready for upload
# requires updates.xml, manifest.json in current folder - these shouldn't reference a version number,
# but instead have xxxxxxx where the version number will be replaced in.
#
# This should work on cygwin and *nix
#
# required variables are
# $version (appended to the built filenames - like 0.0.1)
# $files (should be an array of files to include - like (updates.xml somefile.txt ../someotherfile.txt) )
# $modulename
#
# when this script has finished running, 2 variables will be availabe for use:
#   $filename_crx
#   $filename_zip
# which can then be used (for example) to automatically update your server with the new files

# dependency checks
if [ "$version" == "" ] ; then
	echo "Need a version variable (version=...)"
	exit
fi

if [ "$files" == "" ] ; then
	echo "Need a list of files (files=...)"
	exit
fi

if [ "$modulename" == "" ] ; then
	echo "Need a modulename (modulename=...)"
	exit
fi

# Copy in the files we need
rm -r dist_tmp
mkdir dist_tmp
for i in "${files[@]}"
do
	cp "$i" dist_tmp/
done

# Sort out the version numbers
echo Building dist_tmp folder
cd dist_tmp
sed -i "s/xxxxxxx/$version/g" updates.xml
sed -i "s/xxxxxxx/$version/g" manifest.json
cd ..

# build the Chrome crx for distribution
echo Building Chrome crx
chrome_run=`which google-chrome 2&gt;/dev/null`
cygwin=
if [ ! -f "$chrome_run" ] ; then
	cygwin=yes
	chrome_run=`cygpath -u "$APPDATA/../Local/Google/Chrome/Application/chrome.exe"`
fi
if [ -f "$chrome_run" ] ; then
	path_dist_tmp=`pwd`/dist_tmp
	path_key=`pwd`/$modulename.pem
	if [ "$cygwin" == "yes" ] ; then
		path_dist_tmp=`cygpath -w $path_dist_tmp`
		path_key=`cygpath -w $path_key`
	fi
	echo Building dist_tmp.crx in $path_dist_tmp
	$chrome_run --no-message-box --pack-extension=$path_dist_tmp --pack-extension-key=$path_key
	filename_crx=$modulename-$version.crx
	if [ -f "$filename_crx" ] ; then
		echo $filename_crx already exists\! Skipping rename
	else
		mv dist_tmp.crx $filename_crx
		echo Built $filename_crx
	fi
else
	echo "Couldn't find Chrome!"
fi

# Build the zip for uploading
cd dist_tmp
filename_zip=$modulename-$version.zip
if [ -f "../$filename_zip" ] ; then
	echo $filename_zip already exists\! Skipping zip
else
	echo Removing update site line from packaged zip
	sed -i "s/\"update_url\"\:.*$//g" manifest.json
	zip -r ../$filename_zip *
fi
cd ../</pre>
<h4>Example usage</h4>
<p>This is my <code class="prettyprint">build.sh</code> for the <a title="A raytracer for Google Chrome Native Client" href="http://5eb.me/a-raytracer/">raytracer</a>:</p>
<pre class="prettyprint">#!/bin/bash

# version
version=0.0.3

# file list
files=(
	updates.xml
	manifest.json
	sebtracer-16.png
	sebtracer-48.png
	sebtracer-128.png
	../sebtracer2.html
	../sebtracer2.nmf
	../sebtracer2_x86_32.nexe
	../sebtracer2_x86_64.nexe
	)

modulename=SebTracer

source /s/git/Code/chromeextensions/crx_build.sh</pre>
]]></content:encoded>
			<wfw:commentRss>http://5eb.me/google-chrome-extension-build-script/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Download Google Music tracks with wget from Chrome</title>
		<link>http://5eb.me/download-google-music-tracks-with-wget-from-chrome/</link>
		<comments>http://5eb.me/download-google-music-tracks-with-wget-from-chrome/#comments</comments>
		<pubDate>Thu, 08 Mar 2012 21:19:52 +0000</pubDate>
		<dc:creator>Seb</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[The Internet]]></category>

		<guid isPermaLink="false">http://5eb.me/?p=319</guid>
		<description><![CDATA[Google Music (or Google Play Music now!) is brilliant. It lets you upload 20,000 tracks to Google&#8217;s servers, available to play anywhere with a web browser, and streamable from your phone too. However, sometimes it&#8217;s good to be able to listen to your music when you haven&#8217;t got an internet connection &#8211; the Android Music [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignright size-full wp-image-333" title="downloader-128" src="http://5eb.me/wp/wp-content/uploads/2012/03/downloader-128.png" alt="" width="128" height="128" />Google Music (or Google Play Music now!) is brilliant. It lets you upload 20,000 tracks to Google&#8217;s servers, available to play anywhere with a web browser, and streamable from your phone too.</p>
<p>However, sometimes it&#8217;s good to be able to listen to your music when you haven&#8217;t got an internet connection &#8211; the Android Music client supports &#8220;make available offline&#8221; for tracks, but the webpage doesn&#8217;t yet &#8211; so I wrote a small Chrome extension that generates a list of wget commands (and mv commands) to automate the process of downloading specific tracks from Google Music, ready for play offline.</p>
<p><span id="more-319"></span></p>
<p>The extension adds a button to the Google Music webpage&#8217;s interface that when clicked will (hopefully!) copy a series of shell commands (linux or cygwin) to your clipboard. You can also click a link to view the commands it generates &#8211; these commands will download each track, then rename them in the form &lt;track-number&gt; &#8211; &lt;track name&gt;.mp3</p>
<p>For example:</p>
<pre class="prettyprint">wget 'http://t.doc-0-0-sj.sj.googleusercontent.com/stream/001?id=aaaaaaaaaaaaaaaa&amp;itag=25&amp;source=skyjam&amp;o=aaaaaaaaaaaaaaaaaaaa&amp;ip=0.0.0.0&amp;ipbits=0&amp;expire=0000000000&amp;sparams=id,itag,source,o,ip,ipbits,expire&amp;signature=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&amp;key=sj2' -O track1.mp3; mv track1.mp3 '01 - My track name.mp3' ;</pre>
<p>If you run that in a shell, you&#8217;ll end up with your MP3.</p>
<p>The tracks don&#8217;t have any ID3 info embedded but for those times when you just need 1 or 2 albums (which is what this should be used for!) that doesn&#8217;t matter too much. This is *not* intended to batch-dump your entire Google Music library.</p>
<p>Obviously, this shouldn&#8217;t be used for evil &#8211; please use responsibly <img src='http://5eb.me/wp/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<h4>Download</h4>
<p>You can download the latest version <a title="GoogleMusicWgetter" href="http://5eb.me/other/GoogleMusicWgetter/?C=N;O=D" target="_blank">here</a>.</p>
<h4>Changelog</h4>
<p>2012-03-08 v0.0.1<br />
First build</p>
<p>2012-03-08 v0.0.2-4<br />
Slightly more user-friendly interface, support for copying directly to the OS clipboard</p>
<p>2012-03-08 v0.0.5<br />
Supports downloading tracks from playlists now too</p>
]]></content:encoded>
			<wfw:commentRss>http://5eb.me/download-google-music-tracks-with-wget-from-chrome/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A raytracer for Google Chrome Native Client</title>
		<link>http://5eb.me/a-raytracer/</link>
		<comments>http://5eb.me/a-raytracer/#comments</comments>
		<pubDate>Thu, 08 Mar 2012 17:19:33 +0000</pubDate>
		<dc:creator>Seb</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[The Internet]]></category>

		<guid isPermaLink="false">http://5eb.me/wp/?p=164</guid>
		<description><![CDATA[A couple of months ago, I applied for a job. I&#8217;d been working for the previous 6 years in Java, and the job was a C++ post so I needed to learn C++ quickly &#8211; as a good project to get me going, I wrote a raytracer. I got the job, and I&#8217;m about 5 [...]]]></description>
			<content:encoded><![CDATA[<p><a href="https://chrome.google.com/webstore/detail/keikppoeceeaceabgdiommjljipfjmng" target="_blank"><img class="alignright size-full wp-image-322" title="sebtracer-0.0.2" src="http://5eb.me/wp/wp-content/uploads/2012/02/sebtracer-0.0.2.png" alt="" width="200" height="127" /></a>A couple of months ago, I applied for a job. I&#8217;d been working for the previous 6 years in Java, and the job was a C++ post so I needed to learn C++ quickly &#8211; as a good project to get me going, I wrote a raytracer. I got the job, and I&#8217;m about 5 months in &#8211; looking back at the code I&#8217;d written for this starter project, it&#8217;s not great &#8211; I&#8217;ve already learnt a lot in that time, so I&#8217;ve rewritten it &#8211; and this time I targeted only standard, portable C++ so it compiled nicely (at least the core of the raytracer does) under GCC 4 with no libraries on any platform I fancied.</p>
<p>Then I found out about <a title="Google's Native Client" href="http://www.gonacl.com/" target="_blank">NaCl</a> - Native Client &#8211; Google&#8217;s system for building extensions for Chrome using native code &#8211; and noticed the requirements for building things in it are that it compiles in GCC 4. Sounded like a good test-case&#8230;</p>
<p><span id="more-164"></span></p>
<p>I&#8217;ve built a NaCl version of the simple raytracer &#8211; it&#8217;s not fast (it&#8217;s only single threaded) and because it&#8217;s compiled for NaCl, that&#8217;s got a small performance hit too, but it works.</p>
<p>It&#8217;s pretty slow at the moment, single threaded, no acceleration structures (kd-trees et al), no ray averaging, etc but now it has triangles (!) so next step is .obj loading or at least simple scene graph editing in the page it&#8217;s loaded into&#8230; Once I&#8217;ve figured out pthreads in Pepper and made them work in NaCl, that should speed it up a bit on multicore processors anyway.</p>
<p>It&#8217;s about 4mb for the NaCl .nexe (unfortunately, most of that is 0&#8242;s added as padding by the modified gcc) so takes a little while to download but if you&#8217;d like to try it, you need a recent(ish) version of Chrome and you can find it in the Chrome store (with a rather daft name too):</p>
<p><a title="SebTracer in the Chrome Store" href="https://chrome.google.com/webstore/detail/keikppoeceeaceabgdiommjljipfjmng" target="_blank">https://chrome.google.com/webstore/detail/keikppoeceeaceabgdiommjljipfjmng</a></p>
<p>Depending on the speed of your PC, it may be unuseably slow, but on my work I7 it&#8217;s responsive enough&#8230; (drag the bits around x and y; hold ctrl to drag around x and z).</p>
<p>For reference, <a title="Windows binary" href="http://5eb.me/other/sebtracer/SebTracer2.exe" target="_blank">here&#8217;s a native (Windows) version</a> compiled using VC++ (I said it was portable C++!) &#8211; on my PC, it runs considerably faster &#8211; I&#8217;m not 100% convinced where the major slowdowns are, but that&#8217;s something to look into.</p>
<h4>Future</h4>
<p>Eventually (when I get time &#8211; something I don&#8217;t seem to have much of at the moment) I&#8217;ll expand on it, and add some features to it.</p>
<ul>
<li>add some kind of scene description support</li>
<li>acceleration structure for the scene description (kd-tree, octree perhaps)</li>
<li>multi-threading</li>
</ul>
<h4>Changelog</h4>
<p>2012/03/08 &#8211; v 0.0.2<br />
first build in NaCl, first build of Chrome extension, and upload to Chrome store. Woo!</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://5eb.me/a-raytracer/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Iptables firewall and SSH brute-force blocking with fail2ban on Ubuntu server</title>
		<link>http://5eb.me/iptables-firewall-and-ssh-brute-force-blocking-with-fail2ban-on-ubuntu-server/</link>
		<comments>http://5eb.me/iptables-firewall-and-ssh-brute-force-blocking-with-fail2ban-on-ubuntu-server/#comments</comments>
		<pubDate>Wed, 29 Feb 2012 12:58:25 +0000</pubDate>
		<dc:creator>Seb</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[The Internet]]></category>

		<guid isPermaLink="false">http://5eb.me/?p=300</guid>
		<description><![CDATA[This is a quick howto to get an iptables firewall setup on Ubuntu server, with fail2ban enabled to block brute-force&#8217;d attempts at breaking in over SSH. I&#8217;m running this on Ubuntu 10.04 LTS, but it should work similarly on other versions. Warning! If you get your iptables config wrong, you can end up blocking yourself [...]]]></description>
			<content:encoded><![CDATA[<p>This is a quick howto to get an iptables firewall setup on Ubuntu server, with fail2ban enabled to block brute-force&#8217;d attempts at breaking in over SSH. I&#8217;m running this on Ubuntu 10.04 LTS, but it should work similarly on other versions.</p>
<p><i><b>Warning!</b> If you get your iptables config wrong, you can end up blocking yourself  out of your server, so be careful! Always best to have serial console access to the box just in case&#8230;</i></p>
<p><span id="more-300"></span></p>
<p>IPTables rules can be configured one-by-one; you can list the current iptables with:</p>
<p><code class="prettyprint">sudo iptables -L</code></p>
<p>This should print something like:</p>
<pre class="prettyprint">
Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Chain fail2ban-ssh (0 references)
target     prot opt source               destination
</pre>
<p>This basically means accept everything, from everyone. Incidentally, if you need to flush (get rid of) all your iptables rules:</p>
<p><code class="prettyprint">iptables -F</code></p>
<p>Running an iptables command like this:</p>
<p><code class="prettyprint">-A INPUT -i lo -j ACCEPT</code></p>
<p>will allow (<code class="prettyprint">-j ACCEPT</code>) all incoming connections  (<code class="prettyprint">-A INPUT</code>) on the localhost interface (<code class="prettyprint">-i lo</code>). On the other hand, this:</p>
<p><code class="prettyprint">iptables -A INPUT -j DROP</code></p>
<p>will <b>drop</b> (i.e. reject) everything incoming. What we&#8217;d like to end up with is a firewal which allows everything on localhost, allows certain incoming ports on tcp and udp, a host which is always allowed no matter what, and block everything else (whilst also allowing existing connections) &#8211; for an iptables rule set which does that for these ports and this host: </p>
<p><b>Ports to allow</b><br />
<b>22</b> &#8211; SSH (tcp)<br />
<b>80</b>  &#8211; HTTP (tcp)<br />
<b>443</b> &#8211; HTTPS (tcp)<br />
<b>110</b> &#8211; POP3 (tcp)<br />
<b>995</b> &#8211; POP3S (tcp)<br />
<b>1194</b> &#8211; OpenVPN (tcp and udp)</b></p>
<p><b>Host to allow:</b><br />
123.123.123.123</p>
<p>The iptables commands to generate that list are:</p>
<pre class="prettyprint">sudo iptables -A INPUT -i lo -j ACCEPT
sudo iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
sudo iptables -A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
sudo iptables -A INPUT -p tcp -m tcp --dport 443 -j ACCEPT
sudo iptables -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
sudo iptables -A INPUT -p tcp -m tcp --dport 110 -j ACCEPT
sudo iptables -A INPUT -p tcp -m tcp --dport 995 -j ACCEPT
sudo iptables -A INPUT -p tcp -m tcp --dport 1194 -j ACCEPT
sudo iptables -A INPUT -p udp -m udp --dport 1194 -j ACCEPT
sudo iptables -A INPUT -s 123.123.123.123 -j ACCEPT
sudo iptables -A INPUT -j DROP</pre>
<p>If you run all of these, then run <code>iptables -L</code> again, you should get something like:</p>
<pre class="prettyprint">Chain INPUT (policy ACCEPT)
target     prot opt source               destination
ACCEPT     all  --  anywhere             anywhere
ACCEPT     all  --  anywhere             anywhere            state RELATED,ESTABLISHED
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:ssh
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:https
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:www
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:pop3
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:pop3s
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:openvpn
ACCEPT     udp  --  anywhere             anywhere            udp dpt:openvpn
ACCEPT     all  --  123.123.123.123          anywhere
DROP       all  --  anywhere             anywhere

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination
</pre>
<p>If you&#8217;re still connected, then everything&#8217;s working ok so far!</p>
<p>Next up, we&#8217;d like to get these rules automagically loaded on startup, so we&#8217;ll create a save-state for iptables:</p>
<p><code class="prettyprint">sudo iptables-save &gt; /etc/iptables.rules</code></p>
<p>Now flush your rules, (<code class="prettyprint">iptables -F</code>) so we can then restore our rules with:</p>
<p><code class="prettyprint">sudo iptables-restore &lt; /etc/iptables.rules</code></p>
<p>Running <code class="prettyprint">iptables -L</code> again after that should give you the same rules active you had before. HOORAY!</p>
<p>To get this to happen automatically on startup, create a file in <code class="prettyprint">/etc/network/if-pre-up.d</code> &#8211; everything in this folder gets run automatically on startup just before the network interface is brought online.</p>
<pre class="prettyprint">#!/bin/sh
# this file is /etc/network/if-pre-up.d/iptables-restore
iptables-restore < /etc/iptables.rules
exit 0
</pre>
<p>then <b>make sure it's executable!</b> Otherwise, it won't do anything:</p>
<p><code class="prettyprint">sudo chmod a+x /etc/network/if-pre-up.d/iptables-restore</code></p>
<p>If you reboot now, your box should come back eventually, you should still be able to login, and running <code>iptables -L</code> should give you your list of configured iptables rules.</p>
<h4>fail2ban</h4>
<p>Fail2ban will help block some ips if they appear to be hammering your server trying to login. It's quite easy to get going on ubuntu:</p>
<p><code class="prettyprint">sudo apt-get install fail2ban</code></p>
<p>That's pretty much it... just make sure that the <code>/etc/fail2ban/jail.conf</code> file includes the [ssh] section, and that it's enabled. Then, restart the fail2ban daemon:</p>
<p><code class="prettyprint">sudo /etc/init.d/fail2ban restart</code></p>
<p>then you should now have some extra iptables rules:</p>
<pre class="prettyprint">Chain INPUT (policy ACCEPT)
target     prot opt source               destination
fail2ban-ssh  tcp  --  anywhere             anywhere            multiport dports ssh
...</pre>
<p>And that's that. Your server is now just a little bit more secure <img src='http://5eb.me/wp/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  good luck!</p>
]]></content:encoded>
			<wfw:commentRss>http://5eb.me/iptables-firewall-and-ssh-brute-force-blocking-with-fail2ban-on-ubuntu-server/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>50gb of &#8220;cloud&#8221; space with Box, automatically sync&#8217;d on XUbuntu with webdav and unison [update:Working!]</title>
		<link>http://5eb.me/50gb-of-cloud-space-with-box-automatically-syncd-on-linux-with-webdav/</link>
		<comments>http://5eb.me/50gb-of-cloud-space-with-box-automatically-syncd-on-linux-with-webdav/#comments</comments>
		<pubDate>Fri, 24 Feb 2012 09:53:54 +0000</pubDate>
		<dc:creator>Seb</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">http://5eb.me/?p=249</guid>
		<description><![CDATA[Update 2012/02/29: All seems to be working fine again &#8211; not sure why it all stopped yesterday! Box (used to be box.net) is an online storage service that&#8217;s been around for a while &#8211; it&#8217;s quite popular and gives you more storage space than Dropbox usually does. And, if you&#8217;ve got an Android or iPhone, [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignright size-full wp-image-276" title="boxubuntusync" src="http://5eb.me/wp/wp-content/uploads/2012/02/boxubuntusync.png" alt="" width="129" height="122" /><i>Update 2012/02/29: All seems to be working fine again &#8211; not sure why it all stopped yesterday!</i></p>
<p>Box (used to be box.net) is an online storage service that&#8217;s been around for a while &#8211; it&#8217;s quite popular and gives you more storage space than Dropbox usually does. And, if you&#8217;ve got an Android or iPhone, getting the mobile Box app (for Box.com) unlocks 50gb of storage immediately, for free. 50GB of storage. Unfortunately, it doesn&#8217;t have a linux syncing client yet &#8211; wouldn&#8217;t it be nice if you could create your own?</p>
<p><span id="more-249"></span></p>
<hr />
<h4>Contents</h4>
<ul>
<li><a href="#box_intro">Intro</a></li>
<li><a href="#box_signup">Signup for Box!</a></li>
<li><a href="#box_mountwebdav">Mount the Box folder locally using webdav</a></li>
<li><a href="#box_unison">Setup Unison to keep a local folder and your Box folder in sync</a></li>
<li><a href="#box_cronjob">Create a cron job to run unison automagically</a></li>
</ul>
<p><a name="box_intro"></a><br />
Box supports webdav; webdav is an extension to HTTP that allows handling of remote filesystems &#8211; thankfully, there are a number of packages in linux available to let you mount these webdav folders locally and have them behave as local folders. However, performance on these usually is a bit slow (each read/write involves a few round-trips to the web server) so what we&#8217;ll get here is:</p>
<ul>
<li>a locally mounted webdav folder that will have the &#8220;live&#8221; contents of what Box has, but quite slow</li>
<li>a local copy of the contents of the webdav folder that gets kept in sync with the online Box copy every, or automatically when you change a file &#8211; but because it&#8217;s a local copy, it&#8217;s no different to normal files</li>
</ul>
<p>(Anywhere I&#8217;ve used <code class="prettyprint">vim</code>, feel free to use your editor of choice &#8211; just replace it with something like <code class="prettyprint">gedit</code> if you&#8217;d rather a gui)</p>
<hr />
<p><a name="box_signup"></a></p>
<h3>Sign up for Box!</h3>
<p>So, first up, you&#8217;ll need a Box account.</p>
<p>Just visit <a href="http://www.box.com/" target="_blank">box.com</a> to create one, or signup from your mobile (then you get 50gb space from the getgo!). Once you&#8217;ve got your account all set up and confirmed, continue!</p>
<hr />
<p><a name="box_mountwebdav"></a></p>
<h3>Mount the Box folder locally using webdav</h3>
<p>Next we need to mount the Box web folder as a webdav folder &#8211; the <code class="prettyprint">davfs2</code> package will do the job:</p>
<p><code class="prettyprint">sudo apt-get install davfs2</code></p>
<p>Now create somewhere for the webdav folder to mount:</p>
<p><code class="prettyprint">sudo mkdir /media/box.net</code></p>
<p>Then we&#8217;ll add an entry in fstab (the file that Ubuntu reads to work out what&#8217;s mountable)</p>
<p><code class="prettyprint">sudo vim /etc/fstab</code></p>
<p>and put this in it at the end:</p>
<p><code class="prettyprint">https://www.box.net/dav /media/box.net davfs defaults,rw,user,noauto 0 0</code></p>
<p>Now we&#8217;ll change the davfs config so that users in the <code class="prettyprint">users</code> group can mount the webdav share whenever they need, and also to disable the use of file locks &#8211; they don&#8217;t seem to work properly with the Box.com webdav service</p>
<p><code class="prettyprint">sudo vim /etc/davfs2/davfs2.conf</code></p>
<p>and put this in it (there might already be something similar to this somewhere in the file &#8211; just replace it with this):</p>
<pre class="prettyprint">dav_group users
use_locks 0</pre>
<div class="subnote">(Thanks to <a href="http://johnreid.it/2009/09/26/mount-a-webdav-folder-in-ubuntu-linux/" target="_blank">johnreid.it</a> for the pointers about use_locks)</div>
<p>Next, we need to add our user to the users group &#8211; (my user&#8217;s called <code class="prettyprint">seb</code>, replace seb with you obviously!)</p>
<p><code class="prettyprint">sudo addgroup seb users</code></p>
<p>Now we need to store our Box.com username and password so that it doesn&#8217;t prompt every time we try and use it:</p>
<p><code class="prettyprint">sudo vim /etc/davfs2/secrets</code></p>
<p>and put this at the end:</p>
<p><code class="prettyprint">https://www.box.net/dav &lt;your_user&gt; &lt;your_password&gt;</code></p>
<p>At this point, everything should be ready to test the webdav setup; run this to mount it:</p>
<p><code class="prettyprint">mount /media/box.net</code></p>
<div class="subnote">(it might say something strange about <code class="prettyprint">system option in user configuration file</code> &#8211; I don&#8217;t really know why that is, but it doesn&#8217;t appear to break anything)</div>
<div class="subnote">(it might also say <code class="prettyprint">program is not setuid root</code> &#8211; you can fix this by running <code class="prettyprint">sudo chmod u+s /sbin/mount.davfs</code> then running the mount command again)</div>
<p>If that worked, then you should be able to open a filemanager (like nautilus or thunar) and visit /media/box.net and view the contents of your Box account! However, you might notice that it&#8217;s really not very responsive &#8211; and sometimes freezes up the file manager&#8230; which is what the next section will fix.</p>
<hr />
<p><a name="box_unison"></a></p>
<h3>Setup Unison to keep a local folder and your Box folder in sync</h3>
<p>Unison is a 2-way synchronization tool that can do all sorts of powerful things; here though we&#8217;re just going to use it to keep 2 folders in sync with each other &#8211; I&#8217;m going to put my local Box folder in <code class="prettyprint">/home/seb/box.net</code> and keep it in sync with the existing <code class="prettyprint">/media/box.net</code>. So first make sure you&#8217;ve got the <code class="prettyprint">box.net</code> folder:</p>
<pre class="prettyprint">cd ~
mkdir box.net</pre>
<p>Now you need to install unison (if you&#8217;ve not got it already) then run unison once to create the .unison config folder:</p>
<pre class="prettyprint">sudo apt-get install unison
unison # if you've already used unison before to create a profile, this might run it! So be careful...</pre>
<p>You should now have a .unison folder in your home directory. We&#8217;re going to create a new unison profile to keep our folders in sync:</p>
<p><code class="prettyprint">vim .unison/box.prf</code></p>
<p>and put this in it (obviously again replacing seb with your username!):</p>
<pre class="prettyprint">root = /home/seb/box.net
root = /media/box.net

ignore = Name *~
ignore = Name .*~

auto = true

retry = 2

logfile = /tmp/unisonlog

batch = true</pre>
<p>That profile ignores any files with filenames ending in ~ (like vim and emacs&#8217; backup files), sets automatic and batchmode to true (so it&#8217;ll try and do everything automatically, without asking for confirmation all the time) and write out a log of what happened to /tmp/unisonlog.</p>
<p>So let&#8217;s try it:</p>
<p><code class="prettyprint">unison box</code></p>
<p>This should print out a load of stuff about what it&#8217;s doing, what it&#8217;s copying, conflicts etc, then write something (hopefully!) like:</p>
<pre class="prettyprint">UNISON 2.32.52 finished propagating changes at 08:30:46 on 24 Feb 2012
Saving synchronizer state
Synchronization complete at 08:30:46</pre>
<p>If it did, then the contents if your box.net account should be in the box.net folder in your home directory. Brilliant.</p>
<p>So, now you can edit files, move them around, change, rename, whatever files in the /home//box.net foder, run <code class="prettyprint">unison box</code>, then your box account will update itself. Likewise, you can put files in your box account on your phone, upload files through the website, email files in, run <code class="prettyprint">unison box</code> again and your box.net folder in your home dir should update itself. AMAZING!</p>
<p>It&#8217;s a bit of a pain in the bum having to manually run unison everytime we want updates though&#8230;</p>
<hr />
<p><a name="box_cronjob"></a></p>
<h3>Create a cron job to run unison automagically</h3>
<p>Cron lets your system run commands automatically in the background on timed intervals, without you having to do anything. So we&#8217;ll create a cron job to automatically run our <code class="prettyprint">unison box</code> command every hour. You can fiddle with that number to suit, but bear in mind that if you need some files sync&#8217;d immediately, just run <code class="prettyprint">unison box</code> again.</p>
<p>Edit your crontab (your user&#8217;s list of scheduled cron jobs):</p>
<p><code class="prettyprint">crontab -e</code></p>
<p>and put this at the bottom of it:<br />
<code class="prettyprint">0 * * * * unison box</code></p>
<p>Cron&#8217;s format is a bit odd &#8211; it&#8217;s:</p>
<pre class="prettyprint">m    h    dom    mon    dow    command</pre>
<p>So the crontab line we put in will run <code class="prettyprint">unison box</code> on the 0th minute of * hours (every hour), * days of the month, * months, * days of the week &#8211; which is exactly what we want.</p>
<p>And with that, you should be done! Feel free to drop me a line if you have any problems&#8230;</p>
<div class="subnote" style="margin: 20px 0;">
<p>It is possible to get unison to run automatically every time you change a file in your local copy of the folder using dnotify or famd. Basically, you get dnotify or famd to &#8220;watch&#8221; the folder, then run unison for you everytime something changes. However, I&#8217;m not sure whether using this is a good idea as if you change a lot of files in short succession, it&#8217;ll create a lot of instances of unison running on top of each other and they might collide, creating havoc in your box! It&#8217;ll also mean that everytime a file changes, it creates a load of https requests to Box.com (which they may or may not be too happy about if it happens a lot!)I haven&#8217;t tried this myself so won&#8217;t provide details, but if you&#8217;re feeling adventurous and would like to give it a whirl, apparently the following dnotify command will do roughly what you want (again, untested!):</p>
<pre class="prettyprint">	dnotify -CDMr --background /home/seb/sync -e "unison box"</pre>
<p>I didn&#8217;t have dnotify on my box, and searching for it in the apt-cache suggested <code class="prettyprint">fam</code> &#8211; I didn&#8217;t have time to try configuring and setting this up, but if you do, let me know how you get on!</p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://5eb.me/50gb-of-cloud-space-with-box-automatically-syncd-on-linux-with-webdav/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>VNC from boot on XUbuntu 11.10 without logging in, using LightDM (or GDM) and x11vnc (update: includes LUbuntu with lxdm)</title>
		<link>http://5eb.me/vnc-from-boot-on-xubuntu-11-10-without-logging-in/</link>
		<comments>http://5eb.me/vnc-from-boot-on-xubuntu-11-10-without-logging-in/#comments</comments>
		<pubDate>Thu, 23 Feb 2012 11:21:20 +0000</pubDate>
		<dc:creator>Seb</dc:creator>
				<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">http://5eb.me/?p=225</guid>
		<description><![CDATA[In XUbuntu (and Ubuntu) there are a number of fairly decent VNC servers, broadly split into 2 groups &#8211; 1 lot that let you view the existing desktop (i.e. remote control your existing session) and the other lot that create seperate X sessions that only exist under the VNC server. I&#8217;m interested in the first [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://5eb.me/wp/wp-content/uploads/2012/02/vnclogin.jpg"><img class="alignright size-medium wp-image-245" title="vnclogin" src="http://5eb.me/wp/wp-content/uploads/2012/02/vnclogin-300x192.jpg" alt="" width="300" height="192" /></a>In XUbuntu (and Ubuntu) there are a number of fairly decent VNC servers, broadly split into 2 groups &#8211; 1 lot that let you view the existing desktop (i.e. remote control your existing session) and the other lot that create seperate X sessions that only exist under the VNC server. I&#8217;m interested in the first lot, and I&#8217;d like to be able to login to my X session over VNC before I&#8217;ve logged in on the box itself.</p>
<p><span id="more-225"></span></p>
<p>A standard package in Ubuntu is the Vino VNC server &#8211; it&#8217;s the one that&#8217;s used when you select &#8220;allow users to remotely control my pc&#8221; which is quite handy. However, it only lets you log in once your user has logged into Gnome or XFCE (i.e. after you&#8217;ve got past the login promt in GDM or LightDM) &#8211; so if your PC reboots whilst you&#8217;re away, it&#8217;s a bit of a pain as you can&#8217;t VNC into it.</p>
<p>In XUbuntu 11.10, the team removed GDM (Gnome Display Manager) and replaced it with LightDM (Light Display Manager) so these instructions are specific to that, although they may work on other setups.</p>
<h4>Instructions</h4>
<p>LightDM apparently supports a VNC server out of the box; however, it&#8217;s designed to work with tightvncserver (or similar) which create separate X sessions (the 2nd lot of VNC servers I mentioned above) so not quite what we&#8217;re after<sup><a href="#builtinvnc">1</a></sup>.</p>
<p>Ubuntu derivatives use Upstart (<a href="http://upstart.ubuntu.com/" target="_blank">upstart.ubuntu.com</a>) to manage startup processes - LightDM (and GDM!) creates a <code>login-session-start</code> event when the display manager is up (i.e. when X is all loaded, but before you&#8217;ve logged in) so we&#8217;ll create an upstart job that listens for that, and starts a VNC server on the existing X session, allowing connections before login.</p>
<p><strong>Step 1</strong> &#8211; we want the VNC server to have a password, just in case &#8211; the VNC port shouldn&#8217;t really be exposed to the outside world &#8211; it&#8217;s easy to wrap it in an SSH connection to encrypt everything for you (see <a href="http://www.cl.cam.ac.uk/research/dtg/attarchive/vnc/sshvnc.html" target="_blank">here</a> for a good explanation of how to set that up).</p>
<p><code class="prettyprint">sudo x11vnc -storepasswd /etc/x11vnc.pass</code></p>
<p>This will prompt you for a password to (lightly) secure your VNC server.</p>
<p><strong>Step 2a (for LightDM &#8211; XUbuntu)</strong> &#8211; create the upstart job. Put this in <code class="prettyprint lang-sh">/etc/init/x11vnc.conf</code> :</p>
<pre class="prettyprint">start on login-session-start
script
/usr/bin/x11vnc -xkb -auth /var/run/lightdm/root/:0 -noxrecord -noxfixes -noxdamage -rfbauth /etc/x11vnc.pass -forever -bg -rfbport 5900 -o /var/log/x11vnc.log
end script</pre>
<div class="subnote">Note: if you&#8217;d like this to work with GDM instead, you&#8217;ll need to find where GDM puts its MIT-MAGIC-COOKIE &#8211; I believe it&#8217;s <code class="prettyprint">/var/run/gdm/auth...</code> or something similar, although I haven&#8217;t got a box to test it on</div>
<p><strong>Step 2b (for lxdm &#8211; LUbuntu)</strong> &#8211; LXDM doesn&#8217;t seem to emit the right event, but instead is has /etc/lxdm/LoginReady which lets you specify pre-login events. However, we need to first get the xauth setup properly. Edit <code class="prettyprint">/etc/lxdm/lxdm.conf</code> and uncomment the line:</p>
<pre class="prettyprint">xauth_path=/tmp</pre>
<p>This specifies that we&#8217;re going to use a different xauth path; we also need to update the /etc/lxdm/LoginReady file with our x11 command, using the updated xauth path. </p>
<p>Put this in <code class="prettyprint">/etc/lxdm/LoginReady</code>:</p>
<pre class="prettyprint">/usr/bin/x11vnc -xkb -auth /tmp/.Xauth1000 -noxrecord -noxfixes -noxdamage -rfbauth /etc/x11vnc.pass -forever -bg -rfbport 5900 -o /var/log/x11vnc.log</pre>
<p><strong>Step 3 &#8211; Done!</strong></p>
<p>Reboot! That&#8217;s all there is to it &#8211; hopefully, you&#8217;ll now have a shared VNC server which connects to your main desktop X session, running on port 5900 using the password you gave, all started automatically as soon as LightDM asks you to login. Hooray!</p>
<div class="subnote" style="margin: 20px 0;">
<p><a name="builtinvnc"></a>1. If you&#8217;d like to have a separated VNC server running too you can &#8211; make sure you have tightvncserver installed (or similar) and then put</p>
<pre class="prettyprint lang-bash">[VNCServer]
enabled=true
port=5901 # I've used port 5901 so it doesn't interfere with the setup from above</pre>
<p>in your <code class="prettyprint lang-sh">/etc/lightdm/lightdm.conf</code>  then reboot &#8211; should have a separate X session available for VNC&#8217;ing into.</p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://5eb.me/vnc-from-boot-on-xubuntu-11-10-without-logging-in/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Steam and Oblivion under Linux (Ubuntu 11.10, Oneiric Ocelot) with Wine 1.4</title>
		<link>http://5eb.me/steam-and-oblivion-under-linux-ubuntu-11-10-oneiric-ocelot-with-wine/</link>
		<comments>http://5eb.me/steam-and-oblivion-under-linux-ubuntu-11-10-oneiric-ocelot-with-wine/#comments</comments>
		<pubDate>Thu, 23 Feb 2012 10:22:36 +0000</pubDate>
		<dc:creator>Seb</dc:creator>
				<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">http://5eb.me/?p=208</guid>
		<description><![CDATA[I&#8217;ve been playing quite a lot of Oblivion (Elder Scrolls IV) recently through Steam (I got the Game of the Year Edition, Deluxe on a Steam deal!). Usually I reboot into Windows for gaming but recently decided to give the latest versions of Wine a try to see how it runs under Linux. I&#8217;m running [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://5eb.me/wp/wp-content/uploads/2012/02/steam_wine_oblivion.jpg" target="_blank"><img class="alignright size-medium wp-image-214" title="steam_wine_oblivion" src="http://5eb.me/wp/wp-content/uploads/2012/02/steam_wine_oblivion-300x187.jpg" alt="" width="300" height="187" /></a>I&#8217;ve been playing quite a lot of Oblivion (Elder Scrolls IV) recently through Steam (I got the Game of the Year Edition, Deluxe on a Steam deal!). Usually I reboot into Windows for gaming but recently decided to give the latest versions of Wine a try to see how it runs under Linux. I&#8217;m running a fresh install of XUbuntu 11.10 (Ubuntu + XFCE) and this post is a brief guide on how to get Oblivion running smoothly with minimal hickups without having to reboot.</p>
<p><span id="more-208"></span></p>
<p>Ubuntu&#8217;s normal repositories have Wine 1.3 which apparently works ok, but the latest builds (1.4RC4+) have a few stability fixes and performance tweaks so I decided to try and run that. This may not be the quickest way to install these things, but it was the way I did it and it all works <img src='http://5eb.me/wp/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<h4>Instructions</h4>
<p>Install Winetricks &#8211; a helper tool which downloads and installs things automatically for Wine.</p>
<p>From a terminal:</p>
<p><code class="prettyprint lang-sh">sudo apt-get install winetricks</code></p>
<p>Next up, we&#8217;ll install the official version of Steam &#8211; the <code class="prettyprint lang-sh">--no-isolate</code> parameter makes sure that Steam is installed in the shared wine environment.</p>
<p><code class="prettyprint lang-sh">winetricks --no-isolate steam</code></p>
<p>That will download and install Steam and a few other libraries &#8211; follow through the installer then let it run and log in. Easy peasy! After you&#8217;re sure Steam itself is working (don&#8217;t try and run any games yet), exit Steam.</p>
<p>As I mentioned, the latest versions of Wine have a lot of compatibility fixes for games &#8211; I noticed an increase in framerate and less crashes after I installed the latest Wine (although this could be the placebo effect&#8230;!)</p>
<p>Add the official development Ubuntu Wine repository (again, from a terminal):</p>
<p><code class="prettyprint lang-sh">sudo add-apt-repository ppa:ubuntu-wine/ppa</code></p>
<p>and press enter &#8211; that adds the Ubuntu Wine repository to your apt sources list, and gets the GPG key for it too.<br />
(this comes from here: <a title="Ubuntu Wine PPA" href="https://launchpad.net/~ubuntu-wine/+archive/ppa" target="_blank">https://launchpad.net/~ubuntu-wine/+archive/ppa</a>)</p>
<p>Once that&#8217;s done, install the latest versions of Wine using our new repository:</p>
<pre class="prettyprint lang-sh">sudo apt-get update
sudo apt-get install wine1.3 wine1.3-gecko</pre>
<p>and that&#8217;s it! Now you should have the latest version of Wine that will be automatically kept up to date, and a Steam icon on your desktop (if you chose to put one there) &#8211; run it and install all your favourite games <img src='http://5eb.me/wp/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>This works brilliantly on my laptop to play Oblivion &#8211; it&#8217;s a tiny bit slower than when run natively under Windows, but I just turned down a couple of the graphics settings and it&#8217;s all great. If you have any issues with sound (sometimes it cuts out) then setting Audio -&gt; Direct Sound to &#8220;emulation&#8221; apparently fixes it.</p>
]]></content:encoded>
			<wfw:commentRss>http://5eb.me/steam-and-oblivion-under-linux-ubuntu-11-10-oneiric-ocelot-with-wine/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Free cross-platform dynamic DNS with wildcards</title>
		<link>http://5eb.me/free-cross-platform-dynamic-dns-with-wildcards/</link>
		<comments>http://5eb.me/free-cross-platform-dynamic-dns-with-wildcards/#comments</comments>
		<pubDate>Tue, 11 Oct 2011 19:32:00 +0000</pubDate>
		<dc:creator>Seb</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[The Internet]]></category>

		<guid isPermaLink="false">http://5eb.me/wp/?p=156</guid>
		<description><![CDATA[This will roughly explain how to get wildcard DNS working for free (any-words-here.yoursubdomain.yourdomain.com) on a connection which gets assigned dynamic IPs. I&#8217;d like to make sure subdomain.example.com is always up to date with my home IP, and be able to request subdomains (like someword.subdomain.example.com) that resolve to the same IP. These are useful if you [...]]]></description>
			<content:encoded><![CDATA[<p>This will roughly explain how to get wildcard DNS working for free (<em>any-words-here.yoursubdomain.yourdomain.com</em>) on a connection which gets assigned dynamic IPs. I&#8217;d like to make sure <em>subdomain.example.com</em> is always up to date with my home IP, and be able to request subdomains (like <em>someword.subdomain.example.com</em>) that resolve to the same IP. These are useful if you want to use multiple virtual hosts in apache hosted from a machine on your home network, accessible to the outside world using a fixed hostname.</p>
<p><span id="more-156"></span></p>
<h4>Requirements</h4>
<p>Your own domain (<em>example.com</em>)<br />
Your have a server on the outside world, running PHP (for this example anyway)<br />
A way of requesting a remote web page automatically</p>
<h4>Introduction</h4>
<p>Our previous internet provider gave me a static IP (2 actually!) on a standard ADSL broadband connection. I also own a domain (for this, I&#8217;ll say <em>example.com</em>) &#8211; so I setup a zone specifically for my house (<em>subdomain.example.com</em>) &#8211; this was nice and easy using any DNS provider as it never changed. I also created NS records pointing <em>subdomain.example.com</em> at my home IP, so that I could create requests for <em>blah.subdomain.example.com</em></p>
<p>We&#8217;ve recently moved house. We&#8217;re now with Virgin, and they don&#8217;t provide static IPs &#8211; so I thought I could use something like <em>dyndns.com</em> or <em>no-ip.com</em> (which runs a small daemon which updates your IP to point to something like <em>yourname.no-ip.com</em>). However, these don&#8217;t support recursive wildcard DNS requests without paying for a subscription (i.e. <em>something.yourname.no-ip.com</em>) so I&#8217;d only be able to have a single domain name for my home, which makes using Virtual Hosts in apache not really possible&#8230;</p>
<h4>Solution!</h4>
<p>Find a free DNS host which support an API, and supports wildcard DNS records for a fixed zone. I&#8217;ve done the hard work for you, and found <a title="Zerigo DNS" href="http://www.zerigo.com/">Zerigo</a></p>
<p>Setup a free account on Zerigo and creat a new zone for <em>subdomain.example.com</em> &#8211; my primary DNS is hosted elsewhere for <em>example.com</em>, so I just created an NS record for <em>subdomain.example.com</em> on my main DNS to point at <em>a.ns.zerigo.com. </em>You could probably host both on Zerigo if you wanted.</p>
<p>Then, create 2 hosts on this new zone &#8211; &#8220;&#8221; (empty hostname) and &#8220;*&#8221; (the wildcard host) &#8211; give these any old IP; they&#8217;ll be updated in a minute!</p>
<p>So, now if you do something like (from your machine):</p>
<p><em>nslookup banana.subdomain.example.com a.ns.zerigo.com</em></p>
<p>you should get the IP you&#8217;ve given both these hosts. If you do, everything&#8217;s working fine.</p>
<p>Now, the best bit about Zerigo is that it has a rather nifty REST api for updating DNS zones and hosts, and they provide a PHP client library along with some fairly simple examples. So I created a small PHP script (using their provided API &#8211; thank you!) which just updates your zone to point to the client IP requesting the script, provided it&#8217;s not the same as it used to be (with very simple authentication):</p>
<h4>The PHP script to do it for you</h4>
<pre class="prettyprint lang-php">&lt;?php
$WILDCARD_ZONE="subdomain.example.com"

// rather nasty "authentication" - does the job though... (and it's fine provided the logs on your server are private!)
// just check the MD5 of a GET param is the same as one we're expecting
if (isset($_GET["key"]) &amp;&amp; "abc123abc123abc123abc123abc123ab"===md5($_GET["key"])) {
        // get the last IP we updated it to - if it's not the same, write the new one into the file
        // for use next time.
        $oldIP=file_get_contents("oldIP");
        $remoteIP=$_SERVER['REMOTE_ADDR'];
        if ($oldIP != $remoteIP) {
                file_put_contents("oldIP", $remoteIP);
        }
        else {
                // IP hasn't changed, so nothing to do - save superfluous calls to the Zerigo API
                die("No change: $oldIP, $remoteIP");
        }
        // include the zerigo API
        require_once("zerigo-dns_api_php/zerigo_ns.php");

        ZerigoAPI::$api_user = 'you@zerigouser.com';
        ZerigoAPI::$api_key  = 'abc123abc123abc123abc123abc123ab';

        // get all zones on your account (up to 50 of them anyway)
        $zones = NSZone::find_all(array('per_page'=&gt;50, 'page'=&gt;1));

        // Now get the zone we're trying to update
        $homeZone = null;
        foreach ($zones as $zone) {
                if ($zone-&gt;domain == $WILDCARD_ZONE) {
                        $homeZone = $zone;
                }
        }
        // found the zone we want?
        if ($homeZone) {
                // update all the hosts that match what we're fudging (i.e. the empty host and the wildcard)
                foreach ($homeZone-&gt;hosts as $host) {
                        if ($host-&gt;hostname == "" || $host-&gt;hostname == "*") {
                                // bit of debug to go in my cron logs
                                echo "Updating " . $host-&gt;hostname . "." . $homeZone-&gt;domain;
                                echo " from " . $host-&gt;data . " to " . $remoteIP . "&lt;br/&gt;\n";
                                $host-&gt;data = $remoteIP;
                                // call the Zerigo API to update the remote IP for this host
                                if ($host-&gt;save()) {
                                        echo "Updated.&lt;br/&gt;\n&lt;br/&gt;\n";
                                }
                                else echo "Failed.&lt;br/&gt;\n&lt;br/&gt;\n";
                        }
                }
        }

        exit();
}
header("Status: 404 Not Found");</pre>
<p>(You&#8217;ll also need the Zerigo PHP api stuff too, which can be found here: <a title="Zerigo PHP Libs" href="http://www.zerigo.com/docs/managed-dns/api_code_php" target="_blank">Zerigo PHP Libs</a>)</p>
<h4>Getting it to automatically update</h4>
<p>I just set a box on my home network to fetch this every now and again &#8211; at the moment, I&#8217;ve just got a cron job that does it hourly and it keeps my remote IP up to date  (with a low (1 hour) TTL) on Zerigo&#8217;s DNS servers. I presume there&#8217;s a way in Windows to create a scheduled job that does it too, so this method is pretty cross-platform (and because PHP can run on pretty much anything, it works on all client/server setups).</p>
<p>Hooray!</p>
]]></content:encoded>
			<wfw:commentRss>http://5eb.me/free-cross-platform-dynamic-dns-with-wildcards/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>VIM quick fix (for arrow keys in insert mode)</title>
		<link>http://5eb.me/vim-quick-fix-for-arrow-keys-in-insert-mode/</link>
		<comments>http://5eb.me/vim-quick-fix-for-arrow-keys-in-insert-mode/#comments</comments>
		<pubDate>Thu, 28 Jul 2011 13:27:40 +0000</pubDate>
		<dc:creator>Seb</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">http://5eb.me/wp/?p=3</guid>
		<description><![CDATA[When using VIM in insert mode, when I try and move around with the arrow keys, it inserts A, B, C and D instead. Not completely sure why, but typing: :set nocompatible seems to fix the problem. You can make this permanent by sticking set nocompatible in .vimrc in your home directory. Anyone know why?!]]></description>
			<content:encoded><![CDATA[<p>When using VIM in insert mode, when I try and move around with the arrow keys, it inserts A, B, C and D instead. Not completely sure why, but typing:</p>
<p><code class="prettyprint lang-sh">:set nocompatible</code></p>
<p>seems to fix the problem. You can make this permanent by sticking</p>
<p><code class="prettyprint lang-sh">set nocompatible</code></p>
<p>in .vimrc in your home directory. Anyone know why?!</p>
]]></content:encoded>
			<wfw:commentRss>http://5eb.me/vim-quick-fix-for-arrow-keys-in-insert-mode/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

