<?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>Confessions of a Guru &#187; Uncategorized</title>
	<atom:link href="http://www.guru.net.nz/blog/category/uncategorized/feed" rel="self" type="application/rss+xml" />
	<link>http://www.guru.net.nz/blog</link>
	<description>Random stuff from a Dunedin (NZ) based web developer, beer drinker and dad</description>
	<lastBuildDate>Wed, 14 Dec 2011 09:18:51 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Setting up an Ubuntu 10.10 laptop for LAMP development</title>
		<link>http://www.guru.net.nz/blog/2011/12/setting-up-an-ubuntu-10-10-laptop-for-lamp-development.html</link>
		<comments>http://www.guru.net.nz/blog/2011/12/setting-up-an-ubuntu-10-10-laptop-for-lamp-development.html#comments</comments>
		<pubDate>Mon, 12 Dec 2011 08:42:04 +0000</pubDate>
		<dc:creator>GuruBob</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.guru.net.nz/blog/?p=449</guid>
		<description><![CDATA[I&#8217;m blogging this mostly for my reference as I occasionally reinstall my laptop and always forget the steps to get back to a good state. Aim: Ubuntu Linux 10.10 desktop Apache 2.2 MySQL 5.1 PHP 5.2 Firstly, install Ubuntu 10.10. Make sure you opt to encrypt your home directory. While this means it&#8217;s difficult to [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m blogging this mostly for my reference as I occasionally reinstall my laptop and always forget the steps to get back to a good state.</p>
<p>Aim:</p>
<ul>
<li>Ubuntu Linux 10.10 desktop</li>
<li>Apache 2.2</li>
<li>MySQL 5.1</li>
<li>PHP 5.2</li>
</ul>
<p>Firstly, install Ubuntu 10.10. Make sure you opt to encrypt your home directory. While this means it&#8217;s difficult to recover contents of your home directory in the event of an OS crash, it&#8217;s also means you can sleep at night knowing that if you lose your laptop you haven&#8217;t lost your intellectual property. The system overhead for doing this is not really noticable. The down side of this is that you cannot access the files unless you&#8217;re logged on (see the bit later about the projects directory and Apache).</p>
<p>Now, let&#8217;s install Apache, MySQL and PHP. Note that I&#8217;m installing some extra packages that I need for my development purposes.</p>
<pre>bob@bob-laptop:~$ sudo apt-get install libapache2-mod-php5 mysql-server php5-mysql
bob@bob-laptop:~$ sudo apt-get install php5-curl php-pear  # some extras I use
bob@bob-laptop:~$ sudo apt-get install openssh-server subversion bzr  # some extras I use</pre>
<p>During the installation of those packages you&#8217;ll be asked for a password for the MySQL root user. I always use &#8220;root&#8221; for my convenience. You can use whatever you like. This user does not have root access to the system, but will have full access to the MySQL databases. By default MySQL only listens on the localhost interface so an insecure password like &#8220;root&#8221; is acceptable for my purposes. You&#8217;ll see later that we can shift certain databases to reside on the encrypted home directory if that&#8217;s important to you.</p>
<p><strong>Set up the projects directory</strong></p>
<p>I like to keep all my web stuff in a subdirectory of my home directory called projects. The full path to that will be /home/bob/projects. In order to be able to browse these projects with Apache I&#8217;ll put a symlink in /var/www (Apache&#8217;s default web root directory) to it.</p>
<p>Here&#8217;s a terminal session where I create the projects directory.</p>
<pre>bob@bob-laptop:~$ mkdir ~/projects
bob@bob-laptop:~$ sudo ln -s ~/projects /var/www/projects
bob@bob-laptop:~$ ls -l /var/www
total 4
-rw-r--r-- 1 root root 177 2011-12-11 15:30 index.html
lrwxrwxrwx 1 root root  18 2011-12-12 21:25 projects -&gt; /home/bob/projects</pre>
<p>Great. But now if you try to access <a href="http://localhost/projects">http://localhost/projects</a> you&#8217;ll get a 403 Forbidden page. This is because Apache isn&#8217;t able to see your home directory. A small tweak will fix that.</p>
<pre>bob@bob-laptop:~$ chmod o+x ~</pre>
<p>Note that this command will allow any other user (of which Apache&#8217;s www-data is one) on your system to see the files in your home directory. For me this isn&#8217;t an issue as I&#8217;m the only user on my system.</p>
<p>Now if you revisit <a href="http://localhost/projects">http://localhost/projects</a> you&#8217;ll get a directory index instead of a 403 Forbidden page. You can now create files in /home/bob/projects (or whatever your user name is) and Apache will be able to serve them up to your web browser.</p>
<p>Note that because we opted to encrypt the home directory, the /home/bob directory is only mounted when bob logs in. This means that if you boot your system and try to access it over the network without being logged in, you&#8217;ll likely get a 403 Forbidden or 404 Page Not Found error for any URL in /projects. Other files can be placed in /var/www/whateveryoulike and will be accessible regardless.</p>
<p>Example:</p>
<pre>bob@bob-laptop:~/projects$ cat &gt; phpinfo.php
&lt;?php phpinfo(); ?&gt;</pre>
<p>(press Ctrl-D after typing the phpinfo() line to save the file)</p>
<p>Now if you browse to <a href="http://localhost/projects/phpinfo.php">http://localhost/projects/phpinfo.php</a> you will get the standard PHP Information page.</p>
<p><strong>Using an encrypted database</strong></p>
<p>We&#8217;re not so much using an encrypted database as we are moving it onto an encrypted file system. We use the same trick that we used for Apache but we&#8217;re doing this for MySQL. Note that while it is possible to have all databases encrypted, you will need to make sure you log on first before you start MySQL. Here I will just encrypt one database:</p>
<pre>-- Create a mysql directory in my home dir.
bob@bob-laptop:~$ mkdir ~/mysql

-- Create a sample mysql database called 'secure'
bob@bob-laptop:~$ mysqladmin -uroot -proot create secure

-- Stop the mysql service
bob@bob-laptop:~$ sudo stop mysql
mysql stop/waiting

-- Move the newly created 'secure' database to my home dir
bob@bob-laptop:~$ sudo mv /var/lib/mysql/secure ~/mysql

-- Create a symbolic link for mysql to use
bob@bob-laptop:~$ sudo ln -s ~/mysql/secure /var/lib/mysql/secure

-- Start mysql again
bob@bob-laptop:~$ sudo start mysql
mysql start/running, process 2778

-- Now access the database in the new place
bob@bob-laptop:~$ mysql -uroot -proot
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 34
Server version: 5.1.49-1ubuntu8.1 (Ubuntu)

Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
This software comes with ABSOLUTELY NO WARRANTY. This is free software,
and you are welcome to modify and redistribute it under the GPL v2 license

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql&gt; use secure;
Database changed</pre>
<p>No errors &#8211; the connection was successful. Again the same thing applies in that you can only access this database while you are logged on.</p>
<p><strong>.htaccess files</strong> (optional, but recommended)<br />
Out of the box, Apache won&#8217;t read .htaccess files. To enable these permanently for all directories under your /var/www directory (including the project directory), edit the /etc/apache2/sites-enabled/000-default file (as root) and change line 11 to say &#8220;AllowOverride All&#8221; (instead of None).</p>
<p><strong>mod_rewrite</strong> (optional, but recommended)</p>
<p>Also, you may want to enable mod_rewrite as many web applications use this to generate nice looking URL&#8217;s.</p>
<pre>bob@bob-laptop:~$ sudo a2enmod rewrite
bob@bob-laptop:~$ sudo apache2ctl restart</pre>
<p><strong>xdebug plugin for PHP</strong></p>
<p>The xdebug plugin gives you nice stack traces and formatted var_dump()s which makes it easier to develop. It also comes with breakpoints, remote debugging and a range of other things. Check out the whole shebang at <a href="http://xdebug.org/">http://xdebug.org/</a>.</p>
<p>Installation is simple:</p>
<pre>
bob@bob-laptop:~$ sudo apt-get install php5-xdebug
</pre>
<p>Restart Apache for the change to take effect (sudo apache2ctl restart).</p>
<p><strong>Enabling display of errors in your browser</strong></p>
<p>By default PHP ships with display_errors = Off. This is a requirement for a production system but it will drive you nuts on a development box. When off, any errors are logged to Apache&#8217;s error_log file in /var/log/apache.</p>
<p>To turn it on, edit the file /etc/php5/apache2/php.ini and look for the lines like this:</p>
<pre>
display_errors = Off
display_startup_errors = Off
html_errors = Off
</pre>
<p>And change them all to &#8220;On&#8221;. Again, restart Apache for the change to take effect (sudo apache2ctl restart).</p>
<p>Happy developing!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.guru.net.nz/blog/2011/12/setting-up-an-ubuntu-10-10-laptop-for-lamp-development.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Consistency</title>
		<link>http://www.guru.net.nz/blog/2011/12/consitency.html</link>
		<comments>http://www.guru.net.nz/blog/2011/12/consitency.html#comments</comments>
		<pubDate>Sat, 10 Dec 2011 10:57:37 +0000</pubDate>
		<dc:creator>GuruBob</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.guru.net.nz/blog/?p=433</guid>
		<description><![CDATA[Warning: this may be the most valuable blog post you ever read. I&#8217;ve been developing for a long time &#8211; the first programs that I first wrote that other people were using was back in 1992. At the time, I was the only one working on the code and there was no reason for others [...]]]></description>
			<content:encoded><![CDATA[<p>Warning: this may be the most valuable blog post you ever read.</p>
<p>I&#8217;ve been developing for a long time &#8211; the first programs that I first wrote that other people were using was back in 1992. At the time, I was the only one working on the code and there was no reason for others to get involved. In fact back then it seemed that we were driven by one-upmanship and sharing code was almost unheard of, unless you had to get an assignment in the next day and you had some stupid reason for not being able to complete it, then someone might take pity on your ass and bail you out. Back then, consistency wasn&#8217;t important &#8211; what mattered was whether the code ran or not. Even better if it ran and you got paid.</p>
<p>If there&#8217;s one thing I could share with you about my experiences over the last twenty years, I would have to say that it&#8217;s this. Be consistent.</p>
<p>Consider the following code:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
  <span style="color: #000088;">$query</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'select * from customer where id = 123'</span><span style="color: #339933;">;</span>
  <span style="color: #000088;">$result</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_query</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$query</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000088;">$row</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_fetch_assoc</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$result</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000088;">$identifier</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$row</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'id'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
  <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$identifier</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<p>We&#8217;re fetching a row from a table and echoing out the id field. The code above doesn&#8217;t really matter, but what does matter is the inconsistency. Can you spot it?</p>
<p>The inconsistency is that the field in the database is called &#8220;id&#8221; and we put it into a variable called $identifier. This does not break the code, but it does mean that you have just introduced an inconsistency that will bite you.</p>
<p>That&#8217;s a pretty simple example, but imagine those kind of differences across an entire application, a database schema or even your whole organisation. It happens, and all too frequently.</p>
<p>The consistency issue isn&#8217;t a coding style issue &#8211; let me be very clear on that &#8211; it&#8217;s more a culture issue. You need to work hard to spot these inconsistencies in your organisation and nip them in the bud really early. And they may not appear in code either. You can find them anywhere from code, to documentation, to common usage in discussions in the workplace.</p>
<p>If you let these inconsistencies propagate you&#8217;re going to have to deal with them time and time again. Here&#8217;s a real world example: I am dealing with a system at the moment where products are identified by their SKU number (Stock Keeping Unit). This number has been referred to as the following in various places (code, documentation, wiki pages, emails etc):</p>
<ul>
<li>ItemCode</li>
<li>ItemId</li>
<li>Item_Id</li>
<li>ItemID (yes, case makes a difference!)</li>
<li>ItemSKU</li>
<li>Identifier</li>
<li>Identifer (yes, misspelling of Identifier)</li>
<li>ProductId</li>
<li>ProductSku</li>
<li>SKU</li>
</ul>
<p>The boat has sailed on that one &#8211; there is no way that this situation could be wrestled under control, you&#8217;ll have to do what you can if you come across this. But if you have the luxury of a fresh project then it&#8217;s time to gather your troops and spell it out on the board &#8211; CONSISTENCY. Drum it into your processes and procedures, your code reviews and commit messages. There&#8217;s no excuse for any inconsistency at all &#8211; especially when it will cost you in time chasing bugs because the value isn&#8217;t turning up like it should or the record isn&#8217;t saving.</p>
<p>If you haven&#8217;t already I highly recommend putting together some coding standards for your company &#8211; or even for yourself. And follow them to the letter. It doesn&#8217;t really matter what style of indenting you use (K&amp;R, Allman, BSD KNF, Whitesmiths etc) &#8211; what matters is that you&#8217;re &#8230; you know what I&#8217;m going to say don&#8217;t you.</p>
<p>Feel free to borrow from the <a title="Turboweb Coding Standards" href="http://dev.turboweb.co.nz/turboweb-coding-standards/" target="_blank">Turboweb Coding Standards</a> (which in turn were based on the Drupal Coding Standards). Make sure that your new starts read your coding standards and understand them. And take time to teach them well.</p>
<p>Addendum: Ironically I managed to misspell the title of this blog post, I&#8217;ve now corrected it but as the link is out and about on various social media sites I can&#8217;t change that, therefore if you&#8217;re viewing this post by itself you&#8217;ll see that the URL says &#8220;consitency&#8221; <img src='http://www.guru.net.nz/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.guru.net.nz/blog/2011/12/consitency.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Using the Grid plugin in Compiz</title>
		<link>http://www.guru.net.nz/blog/2010/08/using-the-grid-plugin-in-compiz.html</link>
		<comments>http://www.guru.net.nz/blog/2010/08/using-the-grid-plugin-in-compiz.html#comments</comments>
		<pubDate>Tue, 31 Aug 2010 09:09:51 +0000</pubDate>
		<dc:creator>GuruBob</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[ubuntu compiz]]></category>

		<guid isPermaLink="false">http://www.guru.net.nz/blog/?p=345</guid>
		<description><![CDATA[Recently I&#8217;ve been introduced to the Grid plugin in Compiz &#8211; this is a fantastic little plugin that snaps your windows to predefined positions on the screen. After using it for the last couple of weeks I can&#8217;t imagine going back to not using it. To get access to it you will need to install [...]]]></description>
			<content:encoded><![CDATA[<p>Recently I&#8217;ve been introduced to the Grid plugin in Compiz &#8211; this is a fantastic little plugin that snaps your windows to predefined positions on the screen.  After using it for the last couple of weeks I can&#8217;t imagine going back to not using it.</p>
<p>To get access to it you will need to install the compiz settings manager, and load Compiz&#8217;s &#8220;Fusion Plugins Extra&#8221;:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">apt-get</span> <span style="color: #c20cb9; font-weight: bold;">install</span> \
    compizconfig-settings-manager \
    compiz-fusion-plugins-extra</pre></div></div>

<p>Once you&#8217;ve done this simply enable it:</p>
<ol>
<li>System, Preferences, CompizConfig Settings Manager</li>
<li>In the Filter box in the top left, type in &#8220;grid&#8221;</li>
<li>Tick the box to enable it and click &#8220;Close&#8221; (bottom left)</li>
</ol>
<p>Now try using Ctrl-Alt and numbers on your keypad.  CA-9 will snap a window into the top right corner (press it a few more times to get different sizes) and CA-8 will make it snap to the top half of the screen (the number is the position on the screen, you&#8217;ll get the gist of it).</p>
<p>Check out this demo video:</p>
<p><object width="480" height="385"><param name="movie" value="http://www.youtube.com/v/Z9hZb7blbVg?fs=1&amp;hl=en_US&amp;color1=0x2b405b&amp;color2=0x6b8ab6"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/Z9hZb7blbVg?fs=1&amp;hl=en_US&amp;color1=0x2b405b&amp;color2=0x6b8ab6" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="480" height="385"></embed></object></p>
<p>Happy Ubuntuing!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.guru.net.nz/blog/2010/08/using-the-grid-plugin-in-compiz.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Mosgiel Centenary Celebrations &#8211; 1985.</title>
		<link>http://www.guru.net.nz/blog/2010/06/mosgiel-centenary-celebrations-1985.html</link>
		<comments>http://www.guru.net.nz/blog/2010/06/mosgiel-centenary-celebrations-1985.html#comments</comments>
		<pubDate>Sat, 12 Jun 2010 11:45:43 +0000</pubDate>
		<dc:creator>GuruBob</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.guru.net.nz/blog/2010/06/mosgiel-centenary-celebrations-1985.html</guid>
		<description><![CDATA[I recalled an event I participated in back in 1985 which was the Mosgiel 100 year centenary parade. As a pupil of one of the local primary schools (Reid Park Primary) we were primed with dress of the era and a song that was nowhere near as bad as some radio jingles. We got to [...]]]></description>
			<content:encoded><![CDATA[<p>I recalled an event I participated in back in 1985 which was the Mosgiel 100 year centenary parade.  As a pupil of one of the local primary schools (Reid Park Primary) we were primed with dress of the era and a song that was nowhere near as bad as some radio jingles.  We got to ride on a float down the main street, oh what joy!</p>
<p>&#8220;I&#8217;m a hundred year old kid &#8211; don&#8217;t you see,<br />
I&#8217;m proud to see the end of our first century.<br />
From 1885 through &#8217;til 1985,<br />
We&#8217;ll still be century children at our next centenary.&#8221;</p>
<p>Author unknown, can you help?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.guru.net.nz/blog/2010/06/mosgiel-centenary-celebrations-1985.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Walk To Work Day</title>
		<link>http://www.guru.net.nz/blog/2010/03/walk-to-work-day.html</link>
		<comments>http://www.guru.net.nz/blog/2010/03/walk-to-work-day.html#comments</comments>
		<pubDate>Wed, 10 Mar 2010 10:20:16 +0000</pubDate>
		<dc:creator>GuruBob</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.guru.net.nz/blog/?p=324</guid>
		<description><![CDATA[View Larger Map Today was Walk To Work Day in Dunedin, an initiative spearheaded by Living Streets Aotearoa with the support of Sport Otago and the DCC. I decided to make the trip as the amount of excercise I get thanks to the extreme convenience of my scotter is minimal. I left home at 7:20 [...]]]></description>
			<content:encoded><![CDATA[<div style="padding-left: 15px; width: 330px; float: right; margin-left: auto; margin-right: 0px;">
<iframe width="320" height="200" frameborder="0" scrolling="no" marginheight="0" marginwidth="0" src="http://maps.google.com/maps?f=d&amp;source=s_d&amp;saddr=The+Octagon,+Dunedin&amp;daddr=35+Statham+St,+Dunedin,+Otago+9011,+New+Zealand&amp;hl=en&amp;geocode=%3BCfEaD0KJs7J8FV8WRP0dlfcoCimTrhhQyKsuqDED_3vCFBfVXg&amp;mra=ls&amp;dirflg=w&amp;sll=-45.870977,170.457773&amp;sspn=0.014881,0.038581&amp;g=35+Statham+St,+Brockville,+Otago+9011,+New+Zealand&amp;ie=UTF8&amp;ll=-45.869692,170.480347&amp;spn=0.023905,0.05991&amp;z=13&amp;output=embed"></iframe><br /><small><a href="http://maps.google.com/maps?f=d&amp;source=embed&amp;saddr=The+Octagon,+Dunedin&amp;daddr=35+Statham+St,+Dunedin,+Otago+9011,+New+Zealand&amp;hl=en&amp;geocode=%3BCfEaD0KJs7J8FV8WRP0dlfcoCimTrhhQyKsuqDED_3vCFBfVXg&amp;mra=ls&amp;dirflg=w&amp;sll=-45.870977,170.457773&amp;sspn=0.014881,0.038581&amp;g=35+Statham+St,+Brockville,+Otago+9011,+New+Zealand&amp;ie=UTF8&amp;ll=-45.869692,170.480347&amp;spn=0.023905,0.05991&amp;z=13" style="color:#0000FF;text-align:left">View Larger Map</a></small>
</div>
<p>Today was Walk To Work Day in Dunedin, an initiative spearheaded by <a href="http://www.livingstreets.org.nz">Living Streets Aotearoa</a> with the support of Sport Otago and the DCC.  I decided to make the trip as the amount of excercise I get thanks to the extreme convenience of my scotter is minimal.  I left home at 7:20 this morning and arrived in the Octagon at about 8:30 where a few stands were laid out for registration.  The registration process was rewarded with a $7 voucher redeemable at Barakah, MASH, The Ra Bar, Alibi or The Craic.  I chose MASH and a nice looking breakfast bap which was delicious, but unfortunately my order was forgotten in the rush of breakfast time cafe operations.  After a reminder it turned up with an apology.</p>
<p>They say New Zealand is a small place and indeed it is &#8211; I ran into community advocates Frank Buddingh and Nina Arron from <a href="http://www.lawrence.co.nz/">Lawrence</a> who were on the registration stands.  A familiar face was very much a welcome sight.  I first ran into Frank and Nina some time ago when Frank was looking for an alternative provider for the <a href="http://www.buddingtree.com">Buddingtree Consultancy</a> website.</p>
<p>For me the nicest thing (other than the fantastic weather!) about walking into town was it was a chance for me to &#8220;sit down&#8221; and listen to some podcasts.  Listening to Leo Laporte, Jono Bacon and Randal Schwartz interview Jamie Cameron about Webmin on the <a href="http://twit.tv/FLOSS">FLOSS weekly podcast</a> was a delight, especially as in my dark days I had a fair use for Webmin, so much so that I bought Jamie&#8217;s &#8220;Using Webmin&#8221; book.</p>
<p>Now that I have my walking method sussed all I need to do is load up my iPod and get an early night and a good sleep beforehand &#8211; unfortunately the early night and good sleep was thwarted last night by some jQuery and AJAX goodness and also by Zoe night-babbling, then Linus who woke up crying because &#8220;Ada ate my pie in a dream!&#8221; and then some more Zoe babbling.  Things had quietened down by about 4am anyway.</p>
<p>Check out the local Channel Nine TV coverage at <a href="http://www.ch9.co.nz/node/14223">http://www.ch9.co.nz/node/14223</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.guru.net.nz/blog/2010/03/walk-to-work-day.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Installing MagentoCommerce &#8211; problems</title>
		<link>http://www.guru.net.nz/blog/2009/07/installing-magentocommerce-problems.html</link>
		<comments>http://www.guru.net.nz/blog/2009/07/installing-magentocommerce-problems.html#comments</comments>
		<pubDate>Tue, 21 Jul 2009 12:39:04 +0000</pubDate>
		<dc:creator>GuruBob</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.guru.net.nz/blog/?p=279</guid>
		<description><![CDATA[MagentoCommerce is an open-source enterprise level ecommerce system suitable for high end ecommerce websites. We&#8217;re in the throes of developing a large solution for a local company, and the developers involved in provisioning the site are installing local copies of Magento on their Apache servers to test with. Here&#8217;s a list of issues that I&#8217;ve [...]]]></description>
			<content:encoded><![CDATA[<div class="mceTemp">
<dl id="attachment_280" class="wp-caption alignright" style="width: 328px;">
<dt class="wp-caption-dt"><a href="http://www.guru.net.nz/blog/wp-content/uploads/2009/07/media_logo1.png"><img class="size-full wp-image-280" title="MagentoCommerce" src="http://www.guru.net.nz/blog/wp-content/uploads/2009/07/media_logo1.png" alt="MagentoCommerce" width="318" height="100" /></a></dt>
</dl>
</div>
<p>MagentoCommerce is an open-source enterprise level ecommerce system suitable for high end ecommerce websites.  <a href="http://www.turboweb.co.nz/">We&#8217;re</a> in the throes of developing a large solution for a local company, and the developers involved in provisioning the site are installing local copies of Magento on their Apache servers to test with.</p>
<p>Here&#8217;s a list of issues that I&#8217;ve come across with installing Magento, and how I&#8217;ve solved them.  For the record I&#8217;m using Magento 1.3.2.2 (released 19.07.2009)</p>
<p>1. Can&#8217;t get past the second install step</p>
<p>This is the step that asks you for your database password.  If the database you&#8217;re specifying doesn&#8217;t exist then you can&#8217;t proceed.  I&#8217;m sure there&#8217;s a bug here because it&#8217;s like an error message isn&#8217;t displayed.  Would love to dig into this but our project is on a tight time frame.  MAKE SURE YOU CREATE THE DATABASE YOURSELF FIRST (no tables required).</p>
<p>2. Can&#8217;t log in after installation</p>
<p>If after logging in you go to the /admin directory and you can&#8217;t log in, it&#8217;s probably because of the URL that you used to install it.  I tried installing it to http://localhost/, http://127.0.0.1/ and http://192.168.2.10/ (my IP) all with the same result.  After googling it seemed to be something to do with Magento refusing to set a cookie for a top-level domain (or somesuch).  Workarounds are to use a host name that has a dot in it, e.g. http://localhost.localdomain/ (or in my case, http://bob-desktop.local).  Add this to your hosts file, you may have to restart your browser for it to pick it up.</p>
<p>3. Firefox keeps asking you to download a PHTML file.</p>
<p>After doing a completely fresh install of Apache2, PHP5, mysql, Magento etc on a fresh machine (Ubuntu 9.04, Firefox 3.0.11) Firefox kept asking me what I wanted to do with the PHTML file when accessing the freshly untarred Magento directory.  It took me ages to find an answer to this, but it was as simple as clearing your cache in Firefox.  I dicked around with the Apache configuration, permissions, .htaccess files etc and finally found a comment about the Firefox cache.</p>
<p>4. AllowOverride All</p>
<p>Magento uses a .htaccess file in the root directory.  I noticed that the default for /var/www is AllowOverride None which prevents Apache from looking at the content of .htaccess files.  While this didn&#8217;t cause me trouble, I did set it to &#8220;AllowOverride All&#8221; while trying to solve #3.  The file is /etc/apache2/sites-enabled/000-default, line 11.  Note there may be security implications of doing this if you&#8217;re the administrator of a shared hosting environment and as such you should read about the AllowOverride directive.</p>
<p>Installation requirements:</p>
<p>From a stock Ubuntu 9.04 machine I had to install the following packages to support Magento:</p>
<ul>
<li>libapache2-mod-php5</li>
<li>php5-curl</li>
<li>php5-mcrypt</li>
<li>php5-mysql</li>
<li>php5-gd</li>
<li>mysql-server</li>
</ul>
<p>Also, I have this command on standby to reset the Magento environment back to scratch (deletes the magento directory, drops the database, untars the source file and creates the empty database again)</p>
<pre>cd /var/www ; rm -Rf magento ; tar xvfz /home/bob/magento-1.3.2.2.tar.gz ;
   chmod -R a+rw magento ; mysqladmin -uroot -proot -f drop magento ;
   mysqladmin -uroot -proot create magento</pre>
<p>That&#8217;s all for now.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.guru.net.nz/blog/2009/07/installing-magentocommerce-problems.html/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Screen scraping with jQuery</title>
		<link>http://www.guru.net.nz/blog/2009/06/screen-scraping-with-jquery.html</link>
		<comments>http://www.guru.net.nz/blog/2009/06/screen-scraping-with-jquery.html#comments</comments>
		<pubDate>Mon, 01 Jun 2009 11:04:50 +0000</pubDate>
		<dc:creator>GuruBob</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.guru.net.nz/blog/?p=268</guid>
		<description><![CDATA[During the course of my job I often find myself faced with the task of migrating information from an existing website to our own content management system.  In the past my approach to this task has been to assess the source code of the existing site and see whether it&#8217;s feasible to use a combination [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignright size-full wp-image-273" title="jquery-logo" src="http://www.guru.net.nz/blog/wp-content/uploads/2009/06/jquery-logo.png" style="padding: 10px;" alt="jQuery logo" width="236" height="85" />During the course of my job I often find myself faced with the task of migrating information from an existing website to our own content management system.  In the past my approach to this task has been to assess the source code of the existing site and see whether it&#8217;s feasible to use a combination of curl, regular expressions and string manipulation.  Sometimes this is straightforward but increasingly this method is becoming less and less viable as it&#8217;s too intensive.</p>
<p>I&#8217;ve been using jQuery a lot recently and it occurred to me that I could use jQuery&#8217;s <a href="http://docs.jquery.com/Selectors">selectors</a> to target the information that I&#8217;m interested in a web page, and then using Ajax POST it to my own script that would be ready waiting to then do something useful with the data, e.g. validate it and save it in a database.  For educational purposes I was keen to keep this completely client-side if possible (except for a script to receive the information).  See later on for a server-side solution.</p>
<p>The situation I was up against was a page that had a heap of data in a table (about 90 items), but the table was interspersed with random images to split it up and make it more pleasing to the eye.  Fortunately for me, all of the data that I wanted was neatly wrapped in &lt;div class=&#8221;information&#8221;&gt;&lt;/div&gt; tags.  Selecting these div tags with jQuery is really easy by using $(&#8216;div.information&#8217;).</p>
<p>My first problem was that in order to use jQuery, the web page you&#8217;re looking at has to be using it.  Fortunately there&#8217;s a quick <a href="http://en.wikipedia.org/wiki/Bookmarklet">bookmarklet</a> called <a href="http://www.learningjquery.com/2009/04/better-stronger-safer-jquerify-bookmarklet/">jQuerify</a> that allows you to load jQuery onto any web page.  Once you&#8217;ve got that then you can write further bookmarklets of your own to do stuff.</p>
<p>So, my evil evil plan was to combine a jQuery selector, jQuery&#8217;s each() construct, and jQuery&#8217;s ajax support to post the content of each div to a &#8220;scraper&#8221; script, like so:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'div.information'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">each</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
  $.<span style="color: #660066;">post</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'http://localhost/scraper.php'</span><span style="color: #339933;">,</span><span style="color: #009900;">&#123;</span>
    data<span style="color: #339933;">:</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">innerHTML</span>
  <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>I loaded my source page, clicked the jQuerify bookmarklet and then pasted the code above into the Firebug console (what, oh you&#8217;ll need that&#8230;) and it was flawless &#8230; except that the browser security model stepped in and prevented the ajax call because the XHTTPRequest object is not allowed to post information from one domain to another.  I was stuck &#8211; I googled around for a while looking for workarounds, and investigated the use of JSONP but the transport method seemed more weighted at retrieving information rather than posting it.</p>
<p>So, I was stuck with a simple question: &#8220;How can I get information from one site to another by using the browser?&#8221; &#8211; the simplest answer to this question is of course to have a form on the source website, that when submitted posts to the target.  Thanks to the power of JavaScript, modifying the DOM of a loaded web page is a doddle.  Therefore it should be simple to create a form on the page after it has loaded (client side, remember), create and populate some form fields with data and then submit the form to my scraper script.</p>
<p>Suddenly my intentions had outgrown a bookmarklet, but I would still need one for jQuerify and one for my &#8220;Scraper Utils&#8221;.  My new bookmarket simply asked jQuery to load a local JavaScript file in exactly the same was that jQuery was loaded in the first place:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">javascript<span style="color: #339933;">:</span>$.<span style="color: #660066;">getScript</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'http://localhost/scraper.js'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Now I had the freedom of writing chunk loads of stuff in my local scraper.js file.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">Scraper <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
Scraper.<span style="color: #660066;">createForm</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
  <span style="color: #003366; font-weight: bold;">var</span> form <span style="color: #339933;">=</span> document.<span style="color: #660066;">createElement</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'form'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  form.<span style="color: #660066;">setAttribute</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'method'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'POST'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  form.<span style="color: #660066;">setAttribute</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'action'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'http://localhost/scraper.php'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  document.<span style="color: #660066;">getElementsByTagName</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'body'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span>.<span style="color: #660066;">appendChild</span><span style="color: #009900;">&#40;</span>form<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000066; font-weight: bold;">return</span> form<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
Scraper.<span style="color: #660066;">createSubmitButton</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
  <span style="color: #003366; font-weight: bold;">var</span> button <span style="color: #339933;">=</span> document.<span style="color: #660066;">createElement</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'input'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  button.<span style="color: #660066;">setAttribute</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'type'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'submit'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000066; font-weight: bold;">return</span> button<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
Scraper.<span style="color: #660066;">createFormField</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #000066;">name</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
  <span style="color: #003366; font-weight: bold;">var</span> field <span style="color: #339933;">=</span> document.<span style="color: #660066;">createElement</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'textarea'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  field.<span style="color: #660066;">setAttribute</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'name'</span><span style="color: #339933;">,</span> <span style="color: #000066;">name</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  field.<span style="color: #660066;">setAttribute</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'rows'</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">10</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  field.<span style="color: #660066;">setAttribute</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'cols'</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">50</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000066; font-weight: bold;">return</span> field<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>		
&nbsp;
<span style="color: #003366; font-weight: bold;">var</span> ScraperForm <span style="color: #339933;">=</span> Scraper.<span style="color: #660066;">createForm</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'div.information'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">each</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
  <span style="color: #003366; font-weight: bold;">var</span> field <span style="color: #339933;">=</span> ScraperForm.<span style="color: #660066;">appendChild</span><span style="color: #009900;">&#40;</span>Scraper.<span style="color: #660066;">createFormField</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'data[]'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  field.<span style="color: #660066;">value</span> <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">innerHTML</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #006600; font-style: italic;">// Create a field that we can post with:</span>
ScraperForm.<span style="color: #660066;">appendChild</span><span style="color: #009900;">&#40;</span>Scraper.<span style="color: #660066;">createSubmitButton</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>You can see here that I&#8217;ve set up a few functions, createForm(), createFormField(), createSubmitButton() and then at the bottom I wrap them all together with the $(&#8216;div.information&#8217;).each(&#8230;) construct.  The end result of this is that when I click my bookmarklet that includes the scraper.js script, a form is created at the bottom of the page and a textarea for each div.information is created that holds the innerHTML from that div.</p>
<p>Then, by clicking the Submit button, the browser posts all of that information across to http://localhost/scraper.php where I then collect the information from $_POST['data'] and poke it into a database.</p>
<p>It&#8217;s pretty rough and ready but could easily be extended to do other things like allow you to specify the selector and target URL for the post when you click the Scraper bookmarket.</p>
<h3>Server Side Solution</h3>
<p>On my travels I also came across the &#8220;PHP Simple HTML DOM Parser&#8221; which claims a similar ability like so:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// Create DOM from URL or file</span>
<span style="color: #000088;">$html</span> <span style="color: #339933;">=</span> file_get_html<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'http://www.google.com/'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Find all images</span>
<span style="color: #b1b100;">foreach</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$html</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">find</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'img'</span><span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$element</span><span style="color: #009900;">&#41;</span>
       <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$element</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">src</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'&lt;br/&gt;'</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Find all links</span>
<span style="color: #b1b100;">foreach</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$html</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">find</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'a'</span><span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$element</span><span style="color: #009900;">&#41;</span>
       <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$element</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">href</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'&lt;br/&gt;'</span><span style="color: #339933;">;</span></pre></div></div>

<p>You can get a hold of this from <a href="http://simplehtmldom.sourceforge.net/">Sourceforge at the PHP Simple HTML DOM Parser website</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.guru.net.nz/blog/2009/06/screen-scraping-with-jquery.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>More on fail2ban</title>
		<link>http://www.guru.net.nz/blog/2009/01/more-on-fail2ban.html</link>
		<comments>http://www.guru.net.nz/blog/2009/01/more-on-fail2ban.html#comments</comments>
		<pubDate>Thu, 15 Jan 2009 09:42:56 +0000</pubDate>
		<dc:creator>GuruBob</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.guru.net.nz/blog/?p=257</guid>
		<description><![CDATA[A while ago I blogged about a SSH attack &#8211; this had been going on unnoticed for some time.  Taking my typical fire-and-forget (gently forced by a busy family life) I simply installed fail2ban and did nothing else.  Finally I was in a position where I had to research fail2ban a little more to figure [...]]]></description>
			<content:encoded><![CDATA[<p>A while ago I blogged about a SSH attack &#8211; this had been going on unnoticed for some time.  Taking my typical fire-and-forget (gently forced by a busy family life) I simply installed fail2ban and did nothing else.  Finally I was in a position where I had to research fail2ban a little more to figure out how to make it work.</p>
<p><strong>What is fail2ban?</strong></p>
<p>It&#8217;s a python script (that runs as a <a href="http://en.wikipedia.org/wiki/Daemon_(computer_software)">daemon</a>) which monitors log files in your /var/log file.  It monitors them for specific entries, for example &#8220;Failed password&#8221;, and then updates iptables rules to deny network access for the offending IP for a configured amount of time.</p>
<p>A good example of this is that if you try to ssh into my system three times unsuccessfully, you won&#8217;t be able to try again for 10 minutes.  This is sufficient to make automated brute force attacks useless.</p>
<p><strong>Do you need it?</strong></p>
<p>If<strong> </strong>you have a public-facing server with the ability to log into it (including web applications even) then you need this.  If you&#8217;re curious to see if you&#8217;ve been targeted for attacks, try running these commands as root on your server:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">cat</span> <span style="color: #000000; font-weight: bold;">/</span>var<span style="color: #000000; font-weight: bold;">/</span>log<span style="color: #000000; font-weight: bold;">/</span>auth.log <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">grep</span> <span style="color: #ff0000;">'Failed password'</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">grep</span> sshd <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">awk</span> <span style="color: #ff0000;">'{print $1,$2}'</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">sort</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">uniq</span> <span style="color: #660033;">-c</span>
<span style="color: #c20cb9; font-weight: bold;">zcat</span> <span style="color: #000000; font-weight: bold;">/</span>var<span style="color: #000000; font-weight: bold;">/</span>log<span style="color: #000000; font-weight: bold;">/</span>auth.log<span style="color: #000000; font-weight: bold;">*</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">grep</span> <span style="color: #ff0000;">'Failed password'</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">grep</span> sshd <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">awk</span> <span style="color: #ff0000;">'{print $1,$2}'</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">sort</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">uniq</span> <span style="color: #660033;">-c</span></pre></div></div>

<p>The first command examines your current auth.log file and the second examines your historical auth.log.[0-9] files.  In my recent history (prior to configuring fail2ban properly) I had over 6,000 failed SSH login attempts on a single day just after Christmas.</p>
<p><strong>What next?</strong><br />
The steps are:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">bob<span style="color: #000000; font-weight: bold;">@</span>server:~$ <span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">apt-get</span> <span style="color: #c20cb9; font-weight: bold;">install</span> iptables fail2ban
bob<span style="color: #000000; font-weight: bold;">@</span>server:~$ <span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>init.d<span style="color: #000000; font-weight: bold;">/</span>fail2ban start</pre></div></div>

<p>Now, you can check to see if it&#8217;s working by &#8220;pinging&#8221; the service:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">bob<span style="color: #000000; font-weight: bold;">@</span>server:~$ <span style="color: #c20cb9; font-weight: bold;">sudo</span> fail2ban-client <span style="color: #c20cb9; font-weight: bold;">ping</span>
Server replied: pong</pre></div></div>

<p>And you can get information on what&#8217;s currently been banned by examining the ssh &#8220;jail&#8221; &#8211; the jail is term used to describe the configuration and current black list for access from remote hosts:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">bob<span style="color: #000000; font-weight: bold;">@</span>server:~$ <span style="color: #c20cb9; font-weight: bold;">sudo</span> fail2ban-client status
Status
<span style="color: #000000; font-weight: bold;">|</span>- Number of jail:	<span style="color: #000000;">1</span>
<span style="color: #000000; font-weight: bold;">`</span>- Jail list:		<span style="color: #c20cb9; font-weight: bold;">ssh</span>
bob<span style="color: #000000; font-weight: bold;">@</span>server:~$ <span style="color: #c20cb9; font-weight: bold;">sudo</span> fail2ban-client status <span style="color: #c20cb9; font-weight: bold;">ssh</span>
Status <span style="color: #000000; font-weight: bold;">for</span> the jail: <span style="color: #c20cb9; font-weight: bold;">ssh</span>
<span style="color: #000000; font-weight: bold;">|</span>- filter
<span style="color: #000000; font-weight: bold;">|</span>  <span style="color: #000000; font-weight: bold;">|</span>- File list:	<span style="color: #000000; font-weight: bold;">/</span>var<span style="color: #000000; font-weight: bold;">/</span>log<span style="color: #000000; font-weight: bold;">/</span>auth.log
<span style="color: #000000; font-weight: bold;">|</span>  <span style="color: #000000; font-weight: bold;">|</span>- Currently failed:	<span style="color: #000000;">0</span>
<span style="color: #000000; font-weight: bold;">|</span>  <span style="color: #000000; font-weight: bold;">`</span>- Total failed:	<span style="color: #000000;">52</span>
<span style="color: #000000; font-weight: bold;">`</span>- action
   <span style="color: #000000; font-weight: bold;">|</span>- Currently banned:	<span style="color: #000000;">0</span>
   <span style="color: #000000; font-weight: bold;">|</span>  <span style="color: #000000; font-weight: bold;">`</span>- IP list:
   <span style="color: #000000; font-weight: bold;">`</span>- Total banned:	<span style="color: #000000;">7</span></pre></div></div>

<p>To test everything is working, simply try to log into your system incorrectly three times.  When you&#8217;ve done this and you look at the results of &#8220;fail2ban-client status ssh&#8221; you will see your remote IP in the list.  To unblock your IP, simply restart the fail2ban daemon (i.e. sudo /etc/init.d/fail2ban restart)</p>
<p>These pages were very useful when reading about fail2ban:</p>
<ul>
<li><a href="http://www.the-art-of-web.com/system/fail2ban/">The Art of Web ~ System: fail2ban and iptables</a></li>
<li><a href="http://www.fail2ban.org/wiki/index.php/MANUAL_0_8">The manual for fail2ban 0.8</a> (very readable)</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.guru.net.nz/blog/2009/01/more-on-fail2ban.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Random Images</title>
		<link>http://www.guru.net.nz/blog/2009/01/random-images.html</link>
		<comments>http://www.guru.net.nz/blog/2009/01/random-images.html#comments</comments>
		<pubDate>Thu, 15 Jan 2009 08:52:37 +0000</pubDate>
		<dc:creator>GuruBob</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.guru.net.nz/blog/?p=250</guid>
		<description><![CDATA[Found these today on facebook, too good not to share&#8230;. #1: A Stein-smashingly good time! #2: I have days like these &#8230; #3: Just too true #4: Fandom #5: White-belly-making-cereal]]></description>
			<content:encoded><![CDATA[<p>Found these today on facebook, too good not to share&#8230;.</p>
<p>#1: A Stein-smashingly good time!</p>
<p><a href="http://www.guru.net.nz/blog/wp-content/uploads/2009/01/n561728605_817061_2312.jpg"><img class="alignnone size-full wp-image-251" title="n561728605_817061_2312" src="http://www.guru.net.nz/blog/wp-content/uploads/2009/01/n561728605_817061_2312.jpg" alt="" width="500" height="375" /></a></p>
<p>#2: I have days like these &#8230;</p>
<p><a href="http://www.guru.net.nz/blog/wp-content/uploads/2009/01/n561728605_817077_8346.jpg"><img class="alignnone size-full wp-image-252" title="n561728605_817077_8346" src="http://www.guru.net.nz/blog/wp-content/uploads/2009/01/n561728605_817077_8346.jpg" alt="" width="292" height="266" /></a></p>
<p>#3: Just too true</p>
<p><a href="http://www.guru.net.nz/blog/wp-content/uploads/2009/01/n561728605_817112_4036.jpg"><img class="alignnone size-full wp-image-253" title="n561728605_817112_4036" src="http://www.guru.net.nz/blog/wp-content/uploads/2009/01/n561728605_817112_4036.jpg" alt="" width="604" height="191" /></a></p>
<p>#4: Fandom</p>
<p><a href="http://www.guru.net.nz/blog/wp-content/uploads/2009/01/n561728605_817115_4751.jpg"><img class="alignnone size-full wp-image-254" title="n561728605_817115_4751" src="http://www.guru.net.nz/blog/wp-content/uploads/2009/01/n561728605_817115_4751.jpg" alt="" width="420" height="427" /></a></p>
<p>#5: White-belly-making-cereal</p>
<p><a href="http://www.guru.net.nz/blog/wp-content/uploads/2009/01/n561728605_817162_5313.jpg"><img class="alignnone size-full wp-image-255" title="n561728605_817162_5313" src="http://www.guru.net.nz/blog/wp-content/uploads/2009/01/n561728605_817162_5313.jpg" alt="" width="266" height="400" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.guru.net.nz/blog/2009/01/random-images.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Letter to Parliament re Section 92</title>
		<link>http://www.guru.net.nz/blog/2008/12/letter-to-parliament-re-section-92.html</link>
		<comments>http://www.guru.net.nz/blog/2008/12/letter-to-parliament-re-section-92.html#comments</comments>
		<pubDate>Thu, 18 Dec 2008 00:09:03 +0000</pubDate>
		<dc:creator>GuruBob</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.guru.net.nz/blog/?p=244</guid>
		<description><![CDATA[In response to the proposed Section 92 of the Copyright Amendment Act &#8230; feel free to write one of these yourself, it&#8217;s free!  Also, check out the NZ Creative Freedom Foundation. Rt. Hon Steven Joyce Minister for Communications and Information Technology Care of Distribution Services Parliament Buildings Wellington 6160 Dear Steven, I am writing to [...]]]></description>
			<content:encoded><![CDATA[<p>In response to the proposed Section 92 of the Copyright Amendment Act &#8230; feel free to write one of these yourself, it&#8217;s free!  Also, check out the <a href="http://creativefreedom.org.nz/">NZ Creative Freedom Foundation</a>.</p>
<p style="padding-left: 30px;">Rt. Hon Steven Joyce<br />
Minister for Communications and Information Technology<br />
Care of Distribution Services<br />
Parliament Buildings<br />
Wellington 6160</p>
<p style="padding-left: 30px;">Dear Steven,</p>
<p style="padding-left: 30px;">I am writing to you in urgency regarding the proposed Section 92 of the Copyright Amendment Act that assumes guilt upon accusation, forcing the termination of internet connections and websites without evidence, a fair trial, or punishment for false acusations of copyright infringement.</p>
<p style="padding-left: 30px;">I work for a web development company and cannot let this “roll over” into law without voicing my protest. To know that any one of our clients, or indeed ourselves could be falsely accused without proof required and have our internet access terminated would have dire ramifications as our livelihoods and futures rely on providing these services.</p>
<p style="padding-left: 30px;">I urge you to carefully consider the ramifications of the proposed Section 92 and speak out on behalf of myself and others who have contacted you regarding this.</p>
<p style="padding-left: 30px;">I am available for further comment if required.</p>
<p style="padding-left: 30px;">Yours Sincerely</p>
<p style="padding-left: 30px;">Bob Brown<br />
Web Developer<br />
(my address)<br />
Dunedin</p>
]]></content:encoded>
			<wfw:commentRss>http://www.guru.net.nz/blog/2008/12/letter-to-parliament-re-section-92.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

