<?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>kdmurray.blog &#187; best practices</title>
	<atom:link href="http://kdmurray.net/tag/best-practices/feed/" rel="self" type="application/rss+xml" />
	<link>http://kdmurray.net</link>
	<description>The crossroads of life and tech</description>
	<lastBuildDate>Tue, 07 Feb 2012 20:34:17 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Aftermath of a Hack</title>
		<link>http://kdmurray.net/2011/09/30/aftermath-of-a-hack/</link>
		<comments>http://kdmurray.net/2011/09/30/aftermath-of-a-hack/#comments</comments>
		<pubDate>Sat, 01 Oct 2011 04:52:17 +0000</pubDate>
		<dc:creator>kdmurray</dc:creator>
				<category><![CDATA[Announcements]]></category>
		<category><![CDATA[Soapbox]]></category>
		<category><![CDATA[Tech Tips]]></category>
		<category><![CDATA[authorization]]></category>
		<category><![CDATA[backup]]></category>
		<category><![CDATA[best practices]]></category>
		<category><![CDATA[hack]]></category>
		<category><![CDATA[hosting]]></category>
		<category><![CDATA[maintenance]]></category>
		<category><![CDATA[PKI]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[updates]]></category>

		<guid isPermaLink="false">http://kdmurray.net/?p=933</guid>
		<description><![CDATA[This site was hacked. While it’s still unclear exactly how it happened, or precisely when, sometime in the past 6 weeks my blog, at least 2 other websites and possibly my DreamHost shell account were all hacked. I’m generally a pretty security conscious person, but even I get lazy from time to time. It wasn’t [...]]]></description>
			<content:encoded><![CDATA[<p>This site was hacked. While it’s still unclear exactly how it happened, or precisely when, sometime in the past 6 weeks my blog, at least 2 other websites and possibly my <a href="http://www.dreamhost.com/r.cgi?105113">DreamHost</a> shell account were all hacked. I’m generally a pretty security conscious person, but even I get lazy from time to time. It wasn’t clear to me just how dangerous that laziness could be until this week. I’m going to outline a bit below some of the issues which may have led to my problems, and talk about the steps that have now been taken to help prevent them from occurring again in the future.</p>
<h2>The Problem</h2>
<p><a title="Problem Alert by Krypto, on Flickr" href="http://www.flickr.com/photos/krypto/509911344/"><img class="alignleft" style="margin: 8px;" src="http://farm1.static.flickr.com/196/509911344_a9e7d94b9d_m.jpg" alt="Problem Alert" width="180" height="135" /></a>In retrospect I can see five things I did wrong, and all of them can be traced back to laziness or perhaps, to be less forbidding, they can be traced back to actions taken (or not taken) for the sake of convenience.</p>
<h3>Error #1 &#8211; Out-of-date Software</h3>
<p>Many of us take the time to make sure our operating systems and browsers are up-to-date and fully patched; but do we take the necessary time to make sure that all of our software is patched? Particularly things which don’t reside on our home computers? If you run your own blog, forum or other website and are responsible for your own updates can you say unequivocally that you are currently running the latest and greatest version? Software that is out of date by as little as one revision may have critical vulnerabilities which could allow for disruption of your site, or even execution of commands on your web server.</p>
<p>([<em><strong>aside</strong></em>: If you don't use <a href="http://secunia.com/vulnerability_scanning/personal/" target="_blank">Secunia's PSI product</a> on your home PC at least once a month, you should.])</p>
<h3>Error #2 &#8211; Abandoned Web Properties</h3>
<p>This goes hand-in-hand with the out-of-date software but is, in some ways, a bit trickier to prevent. It is far easier to remember to update software on sites which you update and monitor on a regular basis. It’s far more difficult to monitor sites which have been, for lack of a better term, abandoned. In my case there were three separate sites on my account which were running versions of their software which were more than 12 months out-of-date. The reason was that I was no longer maintaining these sites and had, in essence, forgotten they were still there. I had hidden a couple of them by renaming the homepage which made it look (to the casual observer) like the sites weren’t there but of course all of the other pages were still in their normal locations and were full of holes.</p>
<h3>Error #3 &#8211; Shared User Accounts</h3>
<p>Sharing is good, right? Not in this case&#8230; I have a several different domains hosted under a single hosting account. DreamHost is really generous allowing customers to register any number of domains and attach them to the account. I host sites for myself, for family and for a couple of organizations I’m affiliated with. This in and of itself does not cause a problem. The security hole in my plan was that most of these domains were hosted on a single user account. This means that if that shared user account gets compromised, all of the domains which are run on that user account are potentially at risk.</p>
<h3>Error #4 &#8211; Lack of Backups</h3>
<p>The websites had no viable backups. Because no regular backups were being run of the account, it was virtually impossible to trace when the hack initially occurred. If there had been regular full or differential backups being made of the various websites it may have been possible to determine when the initial attack took place and roll all of the sites back to the way they were before they were compromised. In addition, if there had been any data loss (there does not appear to have been) the lack of backups could have meant the loss of many hours of work.</p>
<h3>Error #5 &#8211; Reused Credentials</h3>
<p>We hear it all the time – do not reuse usernames and passwords on your various accounts, particularly accounts you care about or are important. Account reuse increases the chances that a hack on one site can do more wide-spread damage than the initial compromised password should really allow. My main SSH credentials were a username and password that I had used on over 100 different sites and services. I know for sure that one of the web properties I use had these particular credentials released into the wild. Why didn&#8217;t I change the password? I don&#8217;t know. If that was the entry vector, it is quite possible that a number of other accounts of mine have also been compromised.</p>
<h2>Overall Impact</h2>
<p><a title="&quot;Fire in the Hole&quot; by jurvetson, on Flickr" href="http://www.flickr.com/photos/jurvetson/2899529924/"><img class="alignright" style="margin: 8px;" src="http://farm4.static.flickr.com/3204/2899529924_f4bdcdf6e7_m.jpg" alt="&quot;Fire in the Hole&quot;" width="83" height="120" /></a>The impact was (thankfully) minimal. Only two sites of value were compromised, and it appears that all of the data for those sites is undamaged. A number of other obsolete sites were compromised as well but as they are no longer actively used they are of no great loss.<br />
It also appears that some sort of mass-mailing script was being run from the account as well. My server-side user account had received over 27K “Message Undeliverable” replies from various web servers. I hate to think how many it was able to send successfully.</p>
<h2>The Cleanup</h2>
<p><a title="Pug WIth Mop and Mop Bucket by zoomar, on Flickr" href="http://www.flickr.com/photos/zoomar/132638187/"><img class="alignleft" style="margin: 8px;" src="http://farm1.static.flickr.com/45/132638187_071e853af4_m.jpg" alt="Pug WIth Mop and Mop Bucket" width="240" height="197" /></a>The cleanup had to be done in phases, addressing each of the five defects individually. Some of them were very easy to change, others required quite a bit more effort to implement and verify. However before any of the remediation could begin, the site needed to be cleansed.</p>
<p>The very first step was to ensure that my local machine had not been infected or compromised. I was pretty sure that it was clean as scans are run every night, but it would be like trying to wash a car with mud. No amount of scrubbing with the muddy sponge would get it clean. The machine checked out.</p>
<p>The second step was to change the passwords for all of the users on my hosting account, and change the main password for the account itself.</p>
<p>Next, data from the websites that needed to be saved was exported. None of the code for the software running those sites was saved, only the data. There was no way to tell if the software was clean or compromised so I decided to take no chances. The application software is not that difficult to install, and I was willing to take the hit on setting up modules, components and themes anew.</p>
<p>Once the data was backed up I wiped out all of the data on the user accounts which were being preserved. This meant a full wipe from the file-system from the operating-system shell on the server. All files and directories including “hidden” and “special” folders were wiped out. Some of these operations required the assistance of a DreamHost technician.</p>
<h3>Step #1 &#8211; Remove all unused or obsolete websites</h3>
<p>This was taken care of as part of the cleanup activities mentioned above. Simply removing the affected websites greatly decreased the attack surface of the account and reduced the number of attack vectors which could be used to attack the websites and/or the account.</p>
<h3>Step #2 – Remove all un-needed user accounts</h3>
<p>In the case of any obsolete sites, test accounts or test databases, these were removed directly from the hosting provider’s control panel as they would no longer be needed. Much like response #1, there is no sense in keeping any old files or data hanging around where they might later become a liability.</p>
<h3>Step #3 &#8211; Change the passwords again</h3>
<p>Once all of the files, scripts, data, databases, directories, logs and anything else I could think of were removed from the sites, the passwords were rotated again. This was done in the off-chance that there were cached credentials or some other form of persistent authentication lurking somewhere in the ether.</p>
<h3>Step #4 &#8211; Create new per-domain user accounts</h3>
<p>For each of the domains that would be remaining active, a new user account was created specifically for that user. These accounts would be used to connect to and install the necessary software on the websites, as well as to run backup and maintenance scripts. Passwords for these accounts were set to extremely long strings of random characters as they would not be required for day-to-day access and maintenance.</p>
<h3>Step #5 &#8211; Set up public key authentication</h3>
<p>For regular access to these sites, I decided to go with public key authentication. By requiring a private key (stored in an encrypted volume on my main desktop) and a lengthy but easy-to-remember passphrase I could fairly safely rely on the same public/private key pair to secure access to all of the websites. I found out during this step that both PuTTY’s puttygen application and my hosting provider’s implementation of OpenSSH have an upper-limit on the length of the passphrase. It is still a very long upper limit, but I was surprised to find it. If you share access to a website keys can be installed for each trusted user using the same method.</p>
<h3>Step #6 – Change passwords again (optional)</h3>
<p>Once the public-key authentication is in place the account passwords can be changed at will without affecting the state of the affected keys. This means that I have effectively made the public keys the only viable way of accessing the site over SSH short of having access to the main hosting provider account to do a password reset. Admittedly this step is for the very security conscious (read: paranoid) as I was quite certain at this point that the passwords on the system at this time had not been compromised. This however is to be the first step in a regularly scheduled series of password rotations that the system will handle on my behalf as a part of standard system maintenance.</p>
<h3>Step #7 &#8211; Reinstall all server-side software</h3>
<p>Once all of the base security measures was in place and tested, I set up the application software I wanted to run on the web server. The key here is to do the set up using copies of the software obtained only from trusted sources. What a trusted source is will vary from software package to software package, but typically the main project site for an open-source project (not a mirror) or the vendor website are good places to start. In this case downloading the latest stable WordPress release from the main website &lt;link&gt;.<br />
I made sure not to rely on previously downloaded installation packages, getting the newest most up-to-date version I could lay my hands on.</p>
<h3>Step #8 &#8211; Configure server-side software</h3>
<p>Each software package is different, but going through all the configuration steps for your software package is important: don’t try to short-cut the process. In the case of WordPress we have to set up a MySQL database, set a number of hey/hash values which are used for authorization and cookies and finally set up the user accounts. I wanted to make sure that any passwords, keys or salt values were set using long randomly-generated strings. In my case I used the password generation function in LastPass. Other options would include tools like 1Password, RoboForm or Perfect Paper Passwords &lt;Links&gt;. The longer and more random the string is, the more difficult it will be to crack. I have been using values from 24 to 64 characters in length depending on the purpose.<br />
If you have a system that assigns default passwords for new user accounts, be sure to change those default system-generated passwords and replace them with your own strong credentials at this stage.</p>
<h3>Step #9 &#8211; Set up extensions and themes for server-side software</h3>
<p>Once I got the base configuration is in place it was time to add in the additional features I required for these sites. In my case it was a collection of WordPress plugins and themes. It is easy to forget that each extension, plugin or theme that you add to your website’s software package is in fact additional software that will be executed when the website is used. Just as with the base software package it is important to trust the source of your plugins and themes. If you are suspicious as to the origins of the software, choose something else.<br />
I also added the plugins and themes one at a time confirming after each step that there were no immediately visible defects.</p>
<h3>Step 10 – Automated backup</h3>
<p>The next step was to add a backup script for both the website and the associated database. By building this as a shell script it was possible to schedule full backups of the various sites and have them run on a set schedule. For now the script is very simple:</p>
<ol>
<li>Extract the contents of the database</li>
<li>Zip the website and extracted database into a single archive</li>
<li>Send that file over SFTP to a location off-site from the server</li>
</ol>
<p>There are other ideas for automation as well, but this post is long enough as it is. I will save those for later.</p>
<h2>Lessons Learned</h2>
<p>This could have been much worse. In many ways I count myself very lucky. I could have had all of my data wiped out, I could potentially have seen malware/scripts injected into my websites to capture login credentials or other sensitive information. This attack served as a warning and though I have had to spend a number of hours rethinking the way my websites are set up and managed, at the end of the day I will have better control over the sites I manage, better practices in place for dealing with security, and with any luck, better personal habits for dealing with information security.</p>
<p>Last, but certainly not least, a big thank you to the folks at DreamHost for confirming my initial diagnosis, helping to find the  possible entry vectors, providing guidance on cleanup and purging, and just generally doing that great customer service thing that they do.</p>
<div style="float: right; margin-left: 10px;"><a href="http://twitter.com/share?url=http://kdmurray.net/2011/09/30/aftermath-of-a-hack/&via=kdmurray&text=Aftermath of a Hack&related=:&lang=en&count=horizontal" class="twitter-share-button">Tweet</a><script type="text/javascript" src="http://platform.twitter.com/widgets.js"></script></div>]]></content:encoded>
			<wfw:commentRss>http://kdmurray.net/2011/09/30/aftermath-of-a-hack/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Regaining my Chops</title>
		<link>http://kdmurray.net/2009/06/30/regaining-my-chops/</link>
		<comments>http://kdmurray.net/2009/06/30/regaining-my-chops/#comments</comments>
		<pubDate>Tue, 30 Jun 2009 07:10:15 +0000</pubDate>
		<dc:creator>kdmurray</dc:creator>
				<category><![CDATA[Soapbox]]></category>
		<category><![CDATA[best practices]]></category>
		<category><![CDATA[commenting]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[documentation]]></category>
		<category><![CDATA[process]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[refactoring]]></category>
		<category><![CDATA[software]]></category>

		<guid isPermaLink="false">http://kdmurray.net/?p=713</guid>
		<description><![CDATA[It&#8217;s been a good long while since I&#8217;ve written much in the way of production code. I&#8217;ve tinkered here and there with some small side projects, but rarely have I given much thought into how those pieces of code were written so long as they got the job done; after all I didn&#8217;t expect that [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s been a good long while since I&#8217;ve written much in the way of production code.  I&#8217;ve tinkered here and there with some small side projects, but rarely have I given much thought into how those pieces of code were written so long as they got the job done; after all I didn&#8217;t expect that the code would ever leave my own desk.</p>
<p>During a recent vacation I had the opportunity to help my brother-in-law with a project.  It took a few iterations but we managed to get some code written which fulfilled the need in just a few nights&#8217; work.  Though the complexity was about the same as my own small personal projects, this project was different.   It was for a client &#8212; albeit a client who I wasn&#8217;t charging money for the work.   Someone else was going to read and maintain this code so I knew that I had to take some measures that I hadn&#8217;t been used to taking recently.</p>
<p><span style="text-decoration: underline;"><strong>The first was <a title="Posts tagged 'Refactoring' on Stack Overflow" href="http://stackoverflow.com/questions/tagged/refactoring" target="_blank">refactoring</a></strong></span>.  I refactored the crap out of this application &#8212; and for the most part things worked out nicely.  I was able to turn all my poorly named and one-character variable names into elements and objects with meaningful monikers.</p>
<p><span style="text-decoration: underline;"><strong><a title="Posts tagged 'Comments' on Stack Overflow" href="http://stackoverflow.com/questions/tagged/comments" target="_blank">Commenting</a> was the next step</strong></span>.  After the refactoring was completed I could move on to the next step of the application which was to put in some descriptive comments in the applications.  These comments describe not the what, but the why.   This is the approach I&#8217;ve tried to take relying on good naming within the application to describe the what, and comments to provide rationale.</p>
<p>The final thing I did was take my brother-in-law through the code.  He has a background in software but has never done much in the way of OO (he writes Cobol) and hasn&#8217;t ever worked with the .NET languages.  In doing the walkthrough we came across a few minor issues and a couple of small enhancements for the application.</p>
<p>All told I spent about 25 hours working on this project, and in that short amount of time, I really did begin to regain my programming chops.  I&#8217;ve got a ways to go yet before I get to a level that I&#8217;d be comfortable with, but it&#8217;s a start.</p>
<div style="float: right; margin-left: 10px;"><a href="http://twitter.com/share?url=http://kdmurray.net/2009/06/30/regaining-my-chops/&via=kdmurray&text=Regaining my Chops&related=:&lang=en&count=horizontal" class="twitter-share-button">Tweet</a><script type="text/javascript" src="http://platform.twitter.com/widgets.js"></script></div>]]></content:encoded>
			<wfw:commentRss>http://kdmurray.net/2009/06/30/regaining-my-chops/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>AnkhSVN and Visual Studio 2008</title>
		<link>http://kdmurray.net/2009/05/13/ankhsvn-and-visual-studio-2008/</link>
		<comments>http://kdmurray.net/2009/05/13/ankhsvn-and-visual-studio-2008/#comments</comments>
		<pubDate>Thu, 14 May 2009 06:08:42 +0000</pubDate>
		<dc:creator>kdmurray</dc:creator>
				<category><![CDATA[Reviews]]></category>
		<category><![CDATA[Tech Tips]]></category>
		<category><![CDATA[ankhsvn]]></category>
		<category><![CDATA[best practices]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[source control]]></category>
		<category><![CDATA[subversion]]></category>
		<category><![CDATA[svn]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[version control]]></category>
		<category><![CDATA[visual studio]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://kdmurray.net/?p=655</guid>
		<description><![CDATA[Source control is one of those things that developers get really polarized about.  Most agree that having source control on projects is a necessity, but that&#8217;s typically were the similarities end.  Some folks are of the mind that every line of code, however insignificant, should be under source control.  This provides records of what was [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://kdmurray.net/wp-content/uploads/2009/05/ankhsvn11.gif"><img class="alignleft size-full wp-image-656" style="border: 0pt none; margin: 4px;" title="ankhsvn" src="http://kdmurray.net/wp-content/uploads/2009/05/ankhsvn11.gif" alt="ankhsvn" width="67" height="65" /></a>Source control is one of those things that developers get really polarized about.  Most agree that having source control on projects is a necessity, but that&#8217;s typically were the similarities end.  Some folks are of the mind that every line of code, however insignificant, <a href="http://stackoverflow.com/questions/132520/good-excuses-not-to-use-version-control" target="_blank">should be under source control</a>.  This provides records of what was written, and a reference for things that were done in the past.  Others believe that source control should be reserved for &#8220;real&#8221; projects, things that are deliverables for customers, or products to be released to real-world environments.  I really don&#8217;t want to get into this debate tonight, so I&#8217;m going to stick to the technology.</p>
<p>I was wanting to get some source control in place for a few of my personal projects.  I chose to go with Subversion for my source control server for a few reasons, not the least of which was that my hosting company supports auto-configuration of SVN repositories, so I was able to get that set up in just a couple of minutes.  That left me some time to contemplate how I would access the repository from the client.</p>
<p><a href="http://kdmurray.net/wp-content/uploads/2009/05/newproject_svn11.png"><img class="alignright size-medium wp-image-657" style="border: 0pt none; margin: 4px;" title="newproject_svn" src="http://kdmurray.net/wp-content/uploads/2009/05/newproject_svn1-300x218.png" alt="newproject_svn" width="300" height="218" /></a>I&#8217;m running Visual Studio 2008 on my development machine and this gives me the ability to use plugins for the IDE, a feature that is sadly <a href="http://blogs.msdn.com/danielfe/archive/2007/05/31/visual-studio-express-and-testdriven-net.aspx" target="_blank">missing from the express editions</a>.  There were a couple of good options available for SVN plugins, <a href="http://www.visualsvn.com/" target="_blank">VisualSVN</a> which is the 800lb gorilla in this space, and the open-source option <a href="http://ankhsvn.open.collab.net/" target="_blank">CollabNet&#8217;s AnkhSVN</a>.  Given the fact that this was for personal exploration of the toolset, the open source (free) option was the obvious choice.</p>
<p>The setup for AnkhSVN was quick and painless, and when the IDE opened up it put options for source control right in the menus where they were nice and easy to find.  I created a project, and selected the &#8220;add to Subversion&#8221; checkbox, entered the necessary credentials and created the project in my SVN repository.</p>
<p><a href="http://kdmurray.net/wp-content/uploads/2009/05/anhksvn11.png"><img class="alignleft size-medium wp-image-658" style="border: 0pt none; margin: 4px;" title="anhksvn" src="http://kdmurray.net/wp-content/uploads/2009/05/anhksvn1-300x106.png" alt="anhksvn" width="300" height="106" /></a>When in Visual Studio, the AnkhSVN controls are located on a tab at the bottom of the IDE, alongside other solution-wide functionality like the To-do list, output window etc.  This pane tracks all of the changes (adds, deletes and updates) that you&#8217;ve made to the solution files.  This is extra handy as a review when you&#8217;re ready to make your commits back to the repository.  By quickly scanning the list of changes you&#8217;re able to write solid commit comments to provide some decent documentation for you, or those who come after you.</p>
<p>I&#8217;m still relatively new to Subversion and AnkhSVN, but I&#8217;m looking forward to exploring them in more detail &#8212; maybe I&#8217;ll even do a podcast episode about it!</p>
<div style="float: right; margin-left: 10px;"><a href="http://twitter.com/share?url=http://kdmurray.net/2009/05/13/ankhsvn-and-visual-studio-2008/&via=kdmurray&text=AnkhSVN and Visual Studio 2008&related=:&lang=en&count=horizontal" class="twitter-share-button">Tweet</a><script type="text/javascript" src="http://platform.twitter.com/widgets.js"></script></div>]]></content:encoded>
			<wfw:commentRss>http://kdmurray.net/2009/05/13/ankhsvn-and-visual-studio-2008/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using disk: basic
Page Caching using disk: enhanced
Object Caching 704/758 objects using disk: basic

Served from: kdmurray.net @ 2012-02-09 01:48:52 -->
