<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><title>NicJ.net</title> <link>http://nicj.net</link> <description>Home to Nic Jansma</description> <lastBuildDate>Wed, 16 May 2012 12:58:33 +0000</lastBuildDate> <language>en</language> <sy:updatePeriod>hourly</sy:updatePeriod> <sy:updateFrequency>1</sy:updateFrequency> <generator>http://wordpress.org/?v=3.3.1</generator> <feedburner:info uri="nicj" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><geo:lat>47.67903</geo:lat><geo:long>-122.193409</geo:long><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://www.nicj.net/rss.xml" /><feedburner:feedFlare href="http://add.my.yahoo.com/rss?url=http%3A%2F%2Fwww.nicj.net%2Frss.xml" src="http://us.i1.yimg.com/us.yimg.com/i/us/my/addtomyyahoo4.gif">Subscribe with My Yahoo!</feedburner:feedFlare><feedburner:feedFlare href="http://www.newsgator.com/ngs/subscriber/subext.aspx?url=http%3A%2F%2Fwww.nicj.net%2Frss.xml" src="http://www.newsgator.com/images/ngsub1.gif">Subscribe with NewsGator</feedburner:feedFlare><feedburner:feedFlare href="http://feeds.my.aol.com/add.jsp?url=http%3A%2F%2Fwww.nicj.net%2Frss.xml" src="http://o.aolcdn.com/favorites.my.aol.com/webmaster/ffclient/webroot/locale/en-US/images/myAOLButtonSmall.gif">Subscribe with My AOL</feedburner:feedFlare><feedburner:feedFlare href="http://www.bloglines.com/sub/http://www.nicj.net/rss.xml" src="http://www.bloglines.com/images/sub_modern11.gif">Subscribe with Bloglines</feedburner:feedFlare><feedburner:feedFlare href="http://www.netvibes.com/subscribe.php?url=http%3A%2F%2Fwww.nicj.net%2Frss.xml" src="http://www.netvibes.com/img/add2netvibes.gif">Subscribe with Netvibes</feedburner:feedFlare><feedburner:feedFlare href="http://fusion.google.com/add?feedurl=http%3A%2F%2Fwww.nicj.net%2Frss.xml" src="http://buttons.googlesyndication.com/fusion/add.gif">Subscribe with Google</feedburner:feedFlare><feedburner:feedFlare href="http://www.pageflakes.com/subscribe.aspx?url=http%3A%2F%2Fwww.nicj.net%2Frss.xml" src="http://www.pageflakes.com/ImageFile.ashx?instanceId=Static_4&amp;fileName=ATP_blu_91x17.gif">Subscribe with Pageflakes</feedburner:feedFlare><item><title>PngOutBatch: Optimize your PNGs by running PngOut multiple times</title><link>http://feedproxy.google.com/~r/NicJ/~3/HltpbYBORCI/pngoutbatch-optimize-your-pngs-by-running-pngout-multiple-times</link> <comments>http://nicj.net/2012/05/15/pngoutbatch-optimize-your-pngs-by-running-pngout-multiple-times#comments</comments> <pubDate>Wed, 16 May 2012 02:23:42 +0000</pubDate> <dc:creator>Nic</dc:creator> <category><![CDATA[Life]]></category><guid isPermaLink="false">http://nicj.net/?p=1254</guid> <description><![CDATA[PngOut is a command-line tool that can losslessly reduce the file size of your PNGs. In many cases, it can reduce the size of a PNG by 10-15%. I&#8217;ve even seen some cases where it was able to reduce the file size by over 50%. There are several other PNG compression utilties out there, such [...]]]></description> <content:encoded><![CDATA[<p><a
href="http://advsys.net/ken/utils.htm">PngOut</a> is a command-line tool that can losslessly reduce the file size of your PNGs. In many cases, it can reduce the size of a PNG by 10-15%. I&#8217;ve even seen some cases where it was able to reduce the file size by over 50%.</p><p>There are several other PNG compression utilties out there, such as <a
href="http://pmt.sourceforge.net/pngcrush/">pngcrush</a> and <a
href="http://advancemame.sourceforge.net/comp-readme.html">AdvanceCOMP</a>, but I&#8217;ve found PngOut to be the best optimizer <em>most of the time</em>.</p><p>There&#8217;s an excellent tutorial on <a
title="PngOut" href="http://advsys.net/ken/util/pngout.htm">PngOut</a> for first-timers.  Running PngOut is pretty easy, simply run it once agaist your PNG:</p><pre style="padding-left: 30px;">PngOut.exe [image.png]</pre><p>However, to get the best optimization of your images, you can run PngOut multiple times with different block sizes (eg, <code>/b1024</code>) and randomized initial tables (<code>/r</code>).</p><p>There&#8217;s a commercial program, <a
href="http://www.ardfry.com/pngoutwin/">PngOutWin</a> that can run through all of the block sizes using multiple CPU cores, but I wanted something free that I could run from the command line.</p><p>To aid in this, I created a simple DOS batch script that runs PngOut through 9 different block sizes (from 0 to 8192), with each block size run multiple times with random initial tables.</p><p>While the first iteration of PngOut does all of the heavy lifting, I&#8217;ve sometimes found that using the different block sizes can eek out a few extra bytes (sometimes 100-bytes or more than the initial pass).  You may not care about optimizing your PNG to the absolute last byte possible, but I try to run any new PNGs ready for production in my websites and mobile apps through this batch script before they&#8217;re committed to the wild.</p><p>Running PngOutBatch is as easy as running PngOut:</p><pre style="padding-left: 30px;">PngOutBatch.cmd [image.png] [number of iterations per block size - defaults to 5]</pre><p>PngOutBatch will show progress as it reduces the file size.  Here&#8217;s a sample compressing the PNG logo from <a
href="http://www.libpng.org/pub/png/">libpng.org</a>:</p><pre style="padding-left: 30px;">Blocksize: 0
Iteration #1: Saved 2529 bytes
Iteration #2: No savings
Iteration #3: No savings
Iteration #4: No savings
Iteration #5: No savings
Blocksize: 128
Iteration #1: Saved 606 bytes
Iteration #2: Saved 10 bytes
Iteration #3: No savings
Iteration #4: Saved 2 bytes
Iteration #5: No savings
Blocksize: 192
Iteration #1: No savings
Iteration #2: No savings
Iteration #3: No savings
Iteration #4: No savings
Iteration #5: No savings
Blocksize: 256
Iteration #1: Saved 1 bytes
Iteration #2: No savings
Iteration #3: Saved 5 bytes
Iteration #4: Saved 11 bytes
Iteration #5: No savings
Blocksize: 512
Iteration #1: No savings
Iteration #2: No savings
Iteration #3: No savings
Iteration #4: No savings
Iteration #5: No savings
Blocksize: 1024
Iteration #1: No savings
Iteration #2: No savings
Iteration #3: No savings
Iteration #4: No savings
Iteration #5: No savings
Blocksize: 2048
Iteration #1: No savings
Iteration #2: No savings
Iteration #3: No savings
Iteration #4: No savings
Iteration #5: No savings
Blocksize: 4096
Iteration #1: No savings
Iteration #2: No savings
Iteration #3: No savings
Iteration #4: No savings
Iteration #5: No savings
Blocksize: 8192
Iteration #1: No savings
Iteration #2: No savings
Iteration #3: No savings
Iteration #4: No savings
Iteration #5: No savings
D:\temp\test.png: SUCCESS: 17260 bytes originally, 14096 bytes final: 3164 bytes saved</pre><p>The first block size (0) reduced the file by 2529 bytes, then the 128-byte block size further reduced it by 606, 10 then 2 bytes. The 192-byte block size didn&#8217;t help, but a 256-byte block size reduced the file size by 1, 5 then 11 more bytes.  Larger block sizes didn&#8217;t help, but at the end of the day we reduced the PNG by 3164 bytes (18%), and 635 bytes (25% more) than if we had only run it once.</p><p>The PngOutBatch.cmd script is hosted at <a
href="https://gist.github.com/2706660">Gist.Github</a> if you want to use it or contribute changes.</p><div
class="mr_social_sharing_wrapper"><span
class="mr_social_sharing_top"><iframe
src="https://www.facebook.com/plugins/like.php?locale=en_US&amp;href=http%3A%2F%2Fnicj.net%2F2012%2F05%2F15%2Fpngoutbatch-optimize-your-pngs-by-running-pngout-multiple-times&amp;layout=standard&amp;show_faces=false&amp;width=51px&amp;height=24px" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:51px; height:24px;" allowTransparency="true"></iframe></span><span
class="mr_social_sharing_top"><a
href="http://twitter.com/share?url=http%3A%2F%2Fnicj.net%2F2012%2F05%2F15%2Fpngoutbatch-optimize-your-pngs-by-running-pngout-multiple-times&amp;text=PngOutBatch%3A+Optimize+your+PNGs+by+running+PngOut+multiple+times&amp;via=nicj" target="_blank" class="mr_social_sharing_popup_link"><img
src="http://nicj.net/wp-content/plugins/social-sharing-toolkit/images/buttons/twitter.png" alt="Share on Twitter" title="Share on Twitter"/></a></span><span
class="mr_social_sharing_top"><g:plusone size="medium" count="false" href="http://nicj.net/2012/05/15/pngoutbatch-optimize-your-pngs-by-running-pngout-multiple-times"></g:plusone></span></div><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/NicJ?a=HltpbYBORCI:5-88BNwFmm8:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/NicJ?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/NicJ?a=HltpbYBORCI:5-88BNwFmm8:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/NicJ?i=HltpbYBORCI:5-88BNwFmm8:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/NicJ?a=HltpbYBORCI:5-88BNwFmm8:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/NicJ?i=HltpbYBORCI:5-88BNwFmm8:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/NicJ?a=HltpbYBORCI:5-88BNwFmm8:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/NicJ?i=HltpbYBORCI:5-88BNwFmm8:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/NicJ?a=HltpbYBORCI:5-88BNwFmm8:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/NicJ?d=qj6IDK7rITs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/NicJ/~4/HltpbYBORCI" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://nicj.net/2012/05/15/pngoutbatch-optimize-your-pngs-by-running-pngout-multiple-times/feed</wfw:commentRss> <slash:comments>0</slash:comments> <feedburner:origLink>http://nicj.net/2012/05/15/pngoutbatch-optimize-your-pngs-by-running-pngout-multiple-times</feedburner:origLink></item> <item><title>DIY Cloud Backup using Amazon EC2 and EBS</title><link>http://feedproxy.google.com/~r/NicJ/~3/pVcOQrL3WBc/diy-cloud-backup-using-amazon-ec2-and-ebs</link> <comments>http://nicj.net/2012/02/20/diy-cloud-backup-using-amazon-ec2-and-ebs#comments</comments> <pubDate>Mon, 20 Feb 2012 20:18:44 +0000</pubDate> <dc:creator>Nic</dc:creator> <category><![CDATA[Life]]></category><guid isPermaLink="false">http://nicj.net/?p=1183</guid> <description><![CDATA[I&#8217;ve created a small set of scripts that allows you to use Amazon Web Services to backup files to your own personal &#8220;cloud&#8221;. It&#8217;s available at GitHub for you to download or fork. Features Uses rsync over ssh to securely backup your Windows machines to Amazon&#8217;s EC2 (Elastic Compute Cloud) cloud, with persistent storage provided [...]]]></description> <content:encoded><![CDATA[<p>I&#8217;ve created a small set of scripts that allows you to use Amazon Web Services to backup files to your own personal &#8220;cloud&#8221;. It&#8217;s available at <a
href="https://github.com/nicjansma/amazon-cloud-backup">GitHub</a> for you to download or fork.</p><h2>Features</h2><ul><li>Uses rsync over ssh to securely backup your Windows machines to Amazon&#8217;s EC2 (Elastic Compute Cloud) cloud, with persistent storage provided by Amazon EBS (Elastic Block Store)</li><li>Rsync efficiently mirrors your data to the cloud by only transmitting changed deltas, not entire files</li><li>An Amazon EC2 instance is used as a temporary server inside Amazon&#8217;s data center to backup your files, and it is only running while you are actively performing the rsync</li><li>An Amazon EBS volume holds your backup and is only attached during the rsync, though you could attach it to any other EC2 instance later for data retrieval, or snapshot it to S3 for point-in-time backup</li></ul><h2>Introduction</h2><p>There are several online backup services available, from <a
href="http://mozy.com/">Mozy</a> to <a
href="http://www.carbonite.com/en/">Carbonite</a> to <a
href="http://dropbox.com">Dropbox</a>.  They all provide various levels of backup services for little or no cost.  They usually require you to run one of their apps on your machine, which backs up your files periodically to their &#8220;cloud&#8221; of storage.</p><p>While these services may suffice for the majority of people, you may wish to take a little more control of your backup process. For example, you are trusting their client app to do the right thing, and for your files to be stored securely in their data centers. They may also put limits on the rate they upload your backups, change their cost, or even go out of business.</p><p>On the other hand, one of the simplest tools to backup files is a program called <a
href="http://en.wikipedia.org/wiki/Rsync">rsync</a>, which has been around for a long time. It efficiently transfers files over a network, and can be used to only transfer the parts of a file that have changed since the last sync.  Rsync can be run on Linux or Windows machines through <a
href="http://www.cygwin.com">Cygwin</a>.  It can be run over SSH, so backups are performed with encryption. The problem is you need a Linux rsync server somewhere as the remote backup destination.</p><p>Instead of relying on one of the commercial backup services, I wanted to create a DIY backup &#8220;cloud&#8221; that I had complete control of.  This script uses Amazon Web Services, a service from Amazon that offers on-demand compute instances (EC2) and storage volumes (EBS).  It uses the amazingly simple, reliable and efficient rsync protocol to back up your documents quickly to Amazon&#8217;s data centers, only using an EC2 instance for the duration of the rsync.  Your backups are stored on EBS volumes in Amazon&#8217;s data center, and you have complete control over them.  By using this DIY method of backup, you get complete control of your backup experience.  No upload rate-limiting, no client program constantly running on your computer.  You can even do things like encrypt the volume you&#8217;re backing up to.</p><p>The only service you&#8217;re paying for is Amazon EC2 and EBS, which is pretty cheap, and not likely to disappear any time soon. For example, my monthly EC2 costs for perfoming a weekly backup are less than a dollar, and EBS costs at this time are as cheap as $0.10/GB/mo.</p><p>These scripts are provided to give you a simple way to backup your files via rsync to Amazon&#8217;s infrastructure, and can be easily adapted to your needs.</p><h2>How It Works</h2><p>This script is a simple DOS batch script that can be run to launch an EC2 instance, perform the rsync, stop the instance, and check on the status of your instances.</p><p>After you&#8217;ve created your personal backup &#8220;cloud&#8221; (see <em>Amazon Cloud Setup</em>), and have the <em>Required Tools</em>, you simply run the <code>amazon-cloud-backup.cmd -start</code> to startup a new EC2 instance.  Internally, this uses the Amazon API Developer Tools to start the instance via <code>ec2-run-instances</code>.  There&#8217;s  a custom bootscript for the instance, <code>amazon-cloud-backup.bootscript.sh</code> that works well with the Amazon Linux AMIs to enable <code>root</code> access to the machine over SSH (they initially only offer the user <code>ec2-user</code> SSH access).  We need root access to perform the mount of the volume.</p><p>After the instance is started, the script attaches your personal EBS volume to the device.  Its remote address is queried via<code>ec2-describe-instances</code> and SSH is used to mount the EBS volume to a backup point (eg, <code>/backup</code>).  Once this is completed, your remote EC2 instance and EBS volume are ready for you to rsync.</p><p>To start the rsync, you simply need to run <code>amazon-cloud-backup.cmd -rsync [options]</code>.  Rsync is started over SSH, and your files are backed up to the remote volume.</p><p>Once the backup is complete, you can stop the EC2 instance at any time by running <code>amazon-cloud-backup.cmd -stop</code>, or get the status of the instance by running <code>amazon-cloud-backup.cmd -status</code>.  You can also check on the free space on the volume by running <code>amazon-cloud-backup.cmd -volumestatus</code>.</p><p>There are a couple things you will need to configure to set this all up.  First you need to sign up for Amazon Web Services and generate the appropriate keys and certificates. Then you need a few helper programs on your machine, for example <code>rsync.exe</code> and <code>ssh.exe</code>.  Finally, you need to set a few settings in <code>amazon-cloud-backup.cmd</code> so the backup is tailored to your keys and requirements.</p><h2>Amazon &#8220;Cloud&#8221; Setup</h2><p>To use this script, you need to have an Amazon Web Services account.  You can sign up for one at <a
href="https://aws.amazon.com/">https://aws.amazon.com/</a>.  Once you have an Amazon Web Services account, you will also need to sign up for Amazon EC2.</p><p>Once you have access to EC2, you will need to do the following.</p><ol><li>Create a X.509 Certificate so we can enable API access to the Amazon Web Service API.  You can get this in your <a
href="https://aws-portal.amazon.com/gp/aws/securityCredentials">Security Credentials</a> page.  Click on the <em>X.509 Certificates</em> tab, then <em>Create a new Certificate</em>.  Download both the X.509 Private Key and Certificate files (pk-xyz.pem and cert-xyz.pem).<a
href="https://aws-portal.amazon.com/gp/aws/securityCredentials"><img
class="alignnone size-full wp-image-1216" title="access-credentials" src="http://o.nicj.net/wp-content/uploads/2012/02/access-credentials.png" alt="" width="600" height="439" style="margin-left: 20px; margin-top: 10px" /></a></li><li>Determine which Amazon Region you want to work out of.  See their <a
href="http://docs.amazonwebservices.com/general/latest/gr/rande.html">Reference</a> page for details. For example, I&#8217;m in the Pacific Northwest so I chose us-west-2 (Oregon) as the Region.<a
href="http://o.nicj.net/wp-content/uploads/2012/02/ec2-regions.png"><img
class="alignnone size-full wp-image-1220" title="ec2-regions" src="http://o.nicj.net/wp-content/uploads/2012/02/ec2-regions.png" alt="" width="502" height="256" style="margin-left: 20px; margin-top: 10px" /></a></li><li>Create an EC2 Key Pair so you can log into your EC2 instance via SSH.  You can do this in the <a
href="https://console.aws.amazon.com/ec2/">AWS Management Console</a>.  Click on <em>Create a Key Pair</em>, name it (for example, &#8220;amazon-cloud-backup-rsync&#8221;) and download the .pem file.<a
href="http://o.nicj.net/wp-content/uploads/2012/02/create-key-pair.png"><img
class="alignnone size-full wp-image-1217" title="create-key-pair" src="http://o.nicj.net/wp-content/uploads/2012/02/create-key-pair.png" alt="" width="600" height="475" style="margin-left: 20px; margin-top: 10px" /></a></li><li>Create an EBS Volume in the <a
href="https://console.aws.amazon.com/ec2/">AWS Management Console</a>.  Click on <em>Volumes</em> and then <em>Create Volume</em>.  You can create whatever size volume you want, though you should note that you will pay monthly charges for the volume size, not the size of your backed up files.<a
href="http://o.nicj.net/wp-content/uploads/2012/02/create-volume.png"><img
class="alignnone size-full wp-image-1219" title="create-volume" src="http://o.nicj.net/wp-content/uploads/2012/02/create-volume.png" alt="" width="600" height="478" style="margin-left: 20px; margin-top: 10px" /></a></li><li>Determine which EC2 AMI (Amazon Machine Image) you want to use.  I&#8217;m using the <a
href="http://aws.amazon.com/amis/4157">Amazon Linux AMI: EBS Backed 32-bit</a> image.  This is a Linux image provided and maintained by Amazon.  You&#8217;ll need to pick the appropriate AMI ID for your region.  If you  do not use one of the Amazon-provided AMIs, you may need to modify <code>amazon-cloud-backup.bootscript.sh</code> for the backup to work.</li><li>Create a new EC2 Security Group that allows SSH access.  In the <a
href="https://console.aws.amazon.com/ec2/">AWS Management Console</a>, under EC2, open the <em>Security Groups</em> pane.  Select <em>Create Security Group</em> and name it &#8220;ssh&#8221; or something similar.  Once added, edit its <em>Inbound</em> rules to allow port 22 from all sources &#8220;0.0.0.0/0&#8243;.  If you know what your remote IP address is ahead of time, you could limit the source to that IP.<a
href="http://o.nicj.net/wp-content/uploads/2012/02/create-security-group.png"><img
class="alignnone size-full wp-image-1218" title="create-security-group" src="http://o.nicj.net/wp-content/uploads/2012/02/create-security-group.png" alt="" width="600" height="477" style="margin-left: 20px; margin-top: 10px" /></a></li><li>Launch an EC2 instance with the &#8220;ssh&#8221; Security Group.  After you launch the instance, you can use the <em>Attach Volume</em> button in the<em>Volumes</em> pane to attach your new volume as <code>/dev/sdb</code>.<a
href="http://o.nicj.net/wp-content/uploads/2012/02/launch.png"><img
class="alignnone size-full wp-image-1221" title="launch" src="http://o.nicj.net/wp-content/uploads/2012/02/launch.png" alt="" width="600" height="388" style="margin-left: 20px; margin-top: 10px" /></a></li><li>Log-in to your EC2 instance using ssh (see <em>Required Tools</em>below) and fdisk the volume and create a filesystem. For example:<pre>ssh -i my-rsync-key.pem ec2-user@ec2-1-2-3-4.us-west-1.compute.amazonaws.com
[ec2-user] sudo fdisk /dev/sdb
...
[ec2-user] sudo mkfs.ext4 /dev/sdb1</pre></li><li>Your Amazon personal &#8220;Cloud&#8221; is now setup.</li></ol><p>Many of the choices you&#8217;ve made in this section will need to be set as configuration options in the <code>amazon-cloud-backup.cmd</code> script.</p><h2>Required Tools</h2><p>You will need a couple tools on your Windows machine to perform the rsync backup and query the Amazon Web Services API.</p><ol><li>First, you&#8217;ll need a few binaries (<code>rsync.exe</code>, <code>ssh.exe</code>) on your system to facilitate the ssh/rsync transfer. <a
href="http://www.cygwin.com/">Cygwin</a> can be used to accomplish this.  You can easily install Cygwin from <a
href="http://www.cygwin.com/">http://www.cygwin.com/</a>. After installing, pluck a couple files from the <code>bin/</code>folder and put them into this directory. The binaries you need are:<pre>rsync.exe
ssh.exe
sleep.exe</pre><p>You may also need a couple libraries to ensure those binaries run:</p><pre>cygcrypto-0.9.8.dll
cyggcc_s-1.dll
cygiconv-2.dll
cygintl-8.dll
cygpopt-0.dll
cygspp-0.dll
cygwin1.dll
cygz.dll</pre></li><li>You will need the Amazon API Developer Tools, downloaded from <a
href="http://aws.amazon.com/developertools/">http://aws.amazon.com/developertools/</a>. Place them in a sub-directory called <code>amazon-tools\</code></li></ol><h2>Script Configuration</h2><p>Now you simply have to configure <code>amazon-cloud-backup.cmd</code>.</p><p>Most of the settings can be left at their defaults, but you will likely need to change the locations and name of your X.509 Certificate and EC2 Key Pair.</p><h2>Usage</h2><p>Once you&#8217;ve done the steps in <em>Amazon &#8220;Cloud&#8221; Setup</em>, <em>Required Tools</em> and <em>Script Configuration</em>, you just need to run the <code>amazon-cloud-backup.cmd</code> script.</p><p>These simple steps will launch your EC2 instance, perform the rsync, and then stop the instance.</p><pre>amazon-cloud-backup.cmd -launch
amazon-cloud-backup.cmd -rsync
amazon-cloud-backup.cmd -stop</pre><p>After <code>-stop</code>, your EC2 instance will stop and the EBS volume will be un-attached.</p><h2>Source</h2><p>The source code is available at <a
href="https://github.com/nicjansma/amazon-cloud-backup">GitHub</a>. Feel free to send pull requests for improvements!</p><div
class="mr_social_sharing_wrapper"><span
class="mr_social_sharing_top"><iframe
src="https://www.facebook.com/plugins/like.php?locale=en_US&amp;href=http%3A%2F%2Fnicj.net%2F2012%2F02%2F20%2Fdiy-cloud-backup-using-amazon-ec2-and-ebs&amp;layout=standard&amp;show_faces=false&amp;width=51px&amp;height=24px" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:51px; height:24px;" allowTransparency="true"></iframe></span><span
class="mr_social_sharing_top"><a
href="http://twitter.com/share?url=http%3A%2F%2Fnicj.net%2F2012%2F02%2F20%2Fdiy-cloud-backup-using-amazon-ec2-and-ebs&amp;text=DIY+Cloud+Backup+using+Amazon+EC2+and+EBS&amp;via=nicj" target="_blank" class="mr_social_sharing_popup_link"><img
src="http://nicj.net/wp-content/plugins/social-sharing-toolkit/images/buttons/twitter.png" alt="Share on Twitter" title="Share on Twitter"/></a></span><span
class="mr_social_sharing_top"><g:plusone size="medium" count="false" href="http://nicj.net/2012/02/20/diy-cloud-backup-using-amazon-ec2-and-ebs"></g:plusone></span></div><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/NicJ?a=pVcOQrL3WBc:pGzwRNMVx_M:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/NicJ?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/NicJ?a=pVcOQrL3WBc:pGzwRNMVx_M:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/NicJ?i=pVcOQrL3WBc:pGzwRNMVx_M:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/NicJ?a=pVcOQrL3WBc:pGzwRNMVx_M:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/NicJ?i=pVcOQrL3WBc:pGzwRNMVx_M:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/NicJ?a=pVcOQrL3WBc:pGzwRNMVx_M:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/NicJ?i=pVcOQrL3WBc:pGzwRNMVx_M:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/NicJ?a=pVcOQrL3WBc:pGzwRNMVx_M:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/NicJ?d=qj6IDK7rITs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/NicJ/~4/pVcOQrL3WBc" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://nicj.net/2012/02/20/diy-cloud-backup-using-amazon-ec2-and-ebs/feed</wfw:commentRss> <slash:comments>0</slash:comments> <feedburner:origLink>http://nicj.net/2012/02/20/diy-cloud-backup-using-amazon-ec2-and-ebs</feedburner:origLink></item> <item><title>Windows command-line regular expression renaming tool: RenameRegex</title><link>http://feedproxy.google.com/~r/NicJ/~3/khAkgAT_FWw/windows-command-line-regular-expression-renaming-tool-renameregex</link> <comments>http://nicj.net/2012/01/30/windows-command-line-regular-expression-renaming-tool-renameregex#comments</comments> <pubDate>Mon, 30 Jan 2012 23:26:23 +0000</pubDate> <dc:creator>Nic</dc:creator> <category><![CDATA[Life]]></category><guid isPermaLink="false">http://nicj.net/?p=1175</guid> <description><![CDATA[Every once in a while, I need to rename a bunch of files.  Instead of hand-typing all of the new names, sometimes a nice regular expression would get the job done a lot faster.  While there are a couple Windows GUI regular expression file renamers, I enjoy doing as much as I can from the [...]]]></description> <content:encoded><![CDATA[<p>Every once in a while, I need to rename a bunch of files.  Instead of hand-typing all of the new names, sometimes a nice regular expression would get the job done a lot faster.  While there are a couple <a
href="http://geekswithblogs.net/cicorias/archive/2006/07/10/84601.aspx">Windows GUI</a> <a
href="http://www.bennadel.com/blog/460-Flex-Renamer-Most-Awesome-Bulk-File-Folder-Regular-Expression-Renamer-Ever.htm">regular expression</a> <a
href="http://www.publicspace.net/windows/BetterFileRename/">file</a> <a
href="http://cybernetnews.com/regex-bulk-file-renaming/">renamers</a>, I enjoy doing as much as I can from the command-line.</p><p>Since .NET exposes an easy to use library for regular expressions, I created a small C# command-line app that can rename files via any regular expression.</p><p><strong>Usage:</strong></p><pre style="padding-left: 30px;">RR.exe file-match search replace [/p]
  /p: pretend (show what will be renamed)</pre><p>You can use .NET regular expressions for the search and replacement strings, including substitutions (for example, &#8220;$1&#8243; is the 1st capture group in the search term).</p><p><strong>Examples:</strong></p><p>Simple rename without a regular expression:</p><pre style="padding-left: 30px;">RR.exe * .ext1 .ext2</pre><p>Renaming with a replacement of all &#8220;-&#8221; characters to &#8220;_&#8221;:</p><pre style="padding-left: 30px;">RR.exe * "-" "_"</pre><p>Remove all numbers from the file names:</p><pre style="padding-left: 30px;">RR.exe * "[0-9]+" ""</pre><p>Rename files in the pattern of &#8220;123_xyz.txt&#8221; to &#8220;xyz_123.txt&#8221;:</p><pre style="padding-left: 30px;">RR.exe *.txt "([0-9]+)_([a-z]+)" "$2_$1"</pre><p><strong>Download</strong></p><p>You can download RenameRegex (RR.exe) from <a
href="https://github.com/nicjansma/rename-regex/downloads">here</a>.  The full source of RenameRegex is also available at <a
href="https://github.com/nicjansma/rename-regex">GitHub</a> if you want to fork or modify it. If you make changes, let me know!</p><div
class="mr_social_sharing_wrapper"><span
class="mr_social_sharing_top"><iframe
src="https://www.facebook.com/plugins/like.php?locale=en_US&amp;href=http%3A%2F%2Fnicj.net%2F2012%2F01%2F30%2Fwindows-command-line-regular-expression-renaming-tool-renameregex&amp;layout=standard&amp;show_faces=false&amp;width=51px&amp;height=24px" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:51px; height:24px;" allowTransparency="true"></iframe></span><span
class="mr_social_sharing_top"><a
href="http://twitter.com/share?url=http%3A%2F%2Fnicj.net%2F2012%2F01%2F30%2Fwindows-command-line-regular-expression-renaming-tool-renameregex&amp;text=Windows+command-line+regular+expression+renaming+tool%3A+RenameRegex&amp;via=nicj" target="_blank" class="mr_social_sharing_popup_link"><img
src="http://nicj.net/wp-content/plugins/social-sharing-toolkit/images/buttons/twitter.png" alt="Share on Twitter" title="Share on Twitter"/></a></span><span
class="mr_social_sharing_top"><g:plusone size="medium" count="false" href="http://nicj.net/2012/01/30/windows-command-line-regular-expression-renaming-tool-renameregex"></g:plusone></span></div><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/NicJ?a=khAkgAT_FWw:Sw-V6B4wIQ4:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/NicJ?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/NicJ?a=khAkgAT_FWw:Sw-V6B4wIQ4:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/NicJ?i=khAkgAT_FWw:Sw-V6B4wIQ4:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/NicJ?a=khAkgAT_FWw:Sw-V6B4wIQ4:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/NicJ?i=khAkgAT_FWw:Sw-V6B4wIQ4:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/NicJ?a=khAkgAT_FWw:Sw-V6B4wIQ4:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/NicJ?i=khAkgAT_FWw:Sw-V6B4wIQ4:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/NicJ?a=khAkgAT_FWw:Sw-V6B4wIQ4:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/NicJ?d=qj6IDK7rITs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/NicJ/~4/khAkgAT_FWw" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://nicj.net/2012/01/30/windows-command-line-regular-expression-renaming-tool-renameregex/feed</wfw:commentRss> <slash:comments>4</slash:comments> <feedburner:origLink>http://nicj.net/2012/01/30/windows-command-line-regular-expression-renaming-tool-renameregex</feedburner:origLink></item> <item><title>Auto-ban website spammers via the Apache access_log</title><link>http://feedproxy.google.com/~r/NicJ/~3/afHULm1mi1Q/auto-ban-website-spammers-via-the-apache-access_log</link> <comments>http://nicj.net/2012/01/24/auto-ban-website-spammers-via-the-apache-access_log#comments</comments> <pubDate>Wed, 25 Jan 2012 04:43:48 +0000</pubDate> <dc:creator>Nic</dc:creator> <category><![CDATA[Tech]]></category><guid isPermaLink="false">http://nicj.net/?p=1143</guid> <description><![CDATA[During the past few months, several of my websites have been the target of some sort of SPAM attack.  After my getting alerted that my servers were under high load (from Cacti), I found that a small number of IP addresses were loading and re-loading or POSTing to the same pages over and over again.  [...]]]></description> <content:encoded><![CDATA[<p>During the past few months, several of my websites have been the target of some sort of SPAM attack.  After my getting alerted that my servers were under high load (from <a
href="http://www.cacti.net/">Cacti</a>), I found that a small number of IP addresses were loading and re-loading or POSTing to the same pages over and over again.  In one of the attacks, they were simply reloading a page several times a second from multiple IP addresses.  In another attack, they were POSTing several megabytes of data to a form (which spent time validating the input), several times a second.  I&#8217;m not sure of their motives &#8211; my guess is that they&#8217;re either trying to game search rankings (the POSTings) or someone with an improperly configured robot.</p><p>Since I didn&#8217;t have anything in-place to automatically drop requests from these rogue SPAMmers, the servers were coming under increasing load and causing real visitor&#8217;s page loads to slow down.</p><p>After looking at the server&#8217;s Apache&#8217;s access_log, I was able to narrow down the IPs causing the issue.  With their IP, I simply created a few <a
href="http://www.netfilter.org/">iptables</a> rules to drop all packets from their IP addresses.  Within a few seconds, the load on the server returned to normal.</p><p>I didn&#8217;t want to play catch-up the next time this happened, so I created a small script to automatically parse my server&#8217;s access_logs and auto-ban any IP address that appears to be doing inappropriate things.</p><p>The script is pretty simple.  It uses <code>tail</code> to look at the last <code>$LINESTOSEARCH</code> lines of the <code>access_log</code>, grabs all of the IPs via <code>awk</code>, <code>sorts</code> and counts them via <code>uniq</code>, then looks to see if any of these IPs had loaded more than <code>$THRESHOLD</code> pages.  If so, it does a quick query of <code>iptables</code> to see if the IP is already banned.  If not, it adds a single <code>INPUT</code> rule to <code>DROP</code> packets from that IP.</p><p>Here&#8217;s the code:</p><pre name="code" class="bash">
#!/bin/bash

#
# Config
#

# if more than the threshold, the IP will be banned
THRESHOLD=100

# search this many recent lines of the access log
LINESTOSEARCH=50000

# term to search for
SEARCHTERM=POST

# logfile to search
LOGFILE=/var/log/httpd/access_log

# email to alert upon banning
ALERTEMAIL=foo@foo.com

#
# Get the last n lines of the access_log, and search for the term.  Sort and count by IP, outputting the IP if it's
# larger than the threshold.
#
for ip in `tail -n $LINESTOSEARCH $LOGFILE | grep "$SEARCHTERM" | awk "{print \\$1}" | sort | uniq -c | sort -rn | head -20 | awk "{if (\\$1 &gt; $THRESHOLD) print \\$2}"`
do
    # Look in iptables to see if this IP is already banned
    if ! iptables -L INPUT -n | grep -q $ip
    then
        # Ban the IP
        iptables -A INPUT -s $ip -j DROP

        # Notify the alert email
        iptables -L -n | mail -s "Apache access_log banned '$SEARCHTERM': $ip" $ALERTEMAIL
    fi
done
</pre><p>You can put this in your crontab, so it runs every X minutes.  The script will probably need root access to use <code>iptables</code>.</p><p>I have the script in <code>/etc/cron.10minutes</code> and a crontab entry to run all files in that directory every 10 minutes: <code>/etc/crontab</code>:<br
/> <code>0,10,20,30,40,50 * * * * root run-parts /etc/cron.10minutes</code></p><p><strong>Warning:</strong> Ensure that the <code>$SEARCHTERM</code> you use will not match a wide set of pages that at web crawler (for example, Google) would see.  In my case, I set <code>SEARCHTERM=POST</code>, because I know that Google will not be posting to my website as all of the forms are excluded from crawling via <a
href="http://www.robotstxt.org/">robots.txt</a>.</p><p>The full code is also available at <a
href="https://gist.github.com/1674688">Gist.GitHub</a> if you want to fork or modify it.  It&#8217;s a rather simplistic, brute-force approach to banning rogue IPs, but it has worked for my needs.  You could easily update the script to be a bit smarter.  If you do, let me know!</p><div
class="mr_social_sharing_wrapper"><span
class="mr_social_sharing_top"><iframe
src="https://www.facebook.com/plugins/like.php?locale=en_US&amp;href=http%3A%2F%2Fnicj.net%2F2012%2F01%2F24%2Fauto-ban-website-spammers-via-the-apache-access_log&amp;layout=standard&amp;show_faces=false&amp;width=51px&amp;height=24px" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:51px; height:24px;" allowTransparency="true"></iframe></span><span
class="mr_social_sharing_top"><a
href="http://twitter.com/share?url=http%3A%2F%2Fnicj.net%2F2012%2F01%2F24%2Fauto-ban-website-spammers-via-the-apache-access_log&amp;text=Auto-ban+website+spammers+via+the+Apache+access_log&amp;via=nicj" target="_blank" class="mr_social_sharing_popup_link"><img
src="http://nicj.net/wp-content/plugins/social-sharing-toolkit/images/buttons/twitter.png" alt="Share on Twitter" title="Share on Twitter"/></a></span><span
class="mr_social_sharing_top"><g:plusone size="medium" count="false" href="http://nicj.net/2012/01/24/auto-ban-website-spammers-via-the-apache-access_log"></g:plusone></span></div><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/NicJ?a=afHULm1mi1Q:JKhO4I2yLrc:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/NicJ?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/NicJ?a=afHULm1mi1Q:JKhO4I2yLrc:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/NicJ?i=afHULm1mi1Q:JKhO4I2yLrc:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/NicJ?a=afHULm1mi1Q:JKhO4I2yLrc:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/NicJ?i=afHULm1mi1Q:JKhO4I2yLrc:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/NicJ?a=afHULm1mi1Q:JKhO4I2yLrc:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/NicJ?i=afHULm1mi1Q:JKhO4I2yLrc:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/NicJ?a=afHULm1mi1Q:JKhO4I2yLrc:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/NicJ?d=qj6IDK7rITs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/NicJ/~4/afHULm1mi1Q" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://nicj.net/2012/01/24/auto-ban-website-spammers-via-the-apache-access_log/feed</wfw:commentRss> <slash:comments>0</slash:comments> <feedburner:origLink>http://nicj.net/2012/01/24/auto-ban-website-spammers-via-the-apache-access_log</feedburner:origLink></item> <item><title>Mounting VHDs in Windows 7 from a command-line script</title><link>http://feedproxy.google.com/~r/NicJ/~3/3l__Hrm8jUU/mounting-vhds-in-windows-7-from-a-command-line-script</link> <comments>http://nicj.net/2012/01/04/mounting-vhds-in-windows-7-from-a-command-line-script#comments</comments> <pubDate>Thu, 05 Jan 2012 02:41:47 +0000</pubDate> <dc:creator>Nic</dc:creator> <category><![CDATA[Tech]]></category><guid isPermaLink="false">http://nicj.net/?p=1135</guid> <description><![CDATA[Windows 7 has native support for VHDs (virtual hard disks) built into the OS. VHDs are great for virtual machines, native VHD booting into recent Windows OSs, or even moving whole file systems around. While you can mount VHDs from the Windows 7 diskmgmt.msc GUI, or via vhdmount, if you need support for mounting or unmounting [...]]]></description> <content:encoded><![CDATA[<p>Windows 7 has native support for <a
href="http://www.google.com/url?sa=t&amp;rct=j&amp;q=&amp;esrc=s&amp;frm=1&amp;source=web&amp;cd=4&amp;ved=0CEQQFjAD&amp;url=http%3A%2F%2Fen.wikipedia.org%2Fwiki%2FVHD_(file_format)&amp;ei=Mg0FT9agGOSniQKy84SvDg&amp;usg=AFQjCNHRI-1mPPZ82eAr8W56lWkU_vYHhA&amp;sig2=_up9pv9zNqPv_hn2NsNYSw">VHDs</a> (virtual hard disks) built into the OS. VHDs are great for virtual machines, <a
href="http://www.google.com/url?sa=t&amp;rct=j&amp;q=&amp;esrc=s&amp;frm=1&amp;source=web&amp;cd=3&amp;ved=0CDYQFjAC&amp;url=http%3A%2F%2Fblogs.msdn.com%2Fb%2Fknom%2Farchive%2F2009%2F04%2F07%2Fwindows-7-vhd-boot-setup-guideline.aspx&amp;ei=RQ0FT5vzA6OSiQK4num3Dg&amp;usg=AFQjCNH0QWg7oNTepj_pAQL9CkRL1doVWQ&amp;sig2=JONe0gvBfOQIgj5SJk-jwA">native VHD booting into recent Windows OSs</a>, or even moving whole file systems around.</p><p>While you can mount VHDs from the Windows 7 <a
href="http://www.sevenforums.com/tutorials/566-virtual-hard-disk-create-attach-vhd.html">diskmgmt.msc GUI</a>, or via <a
href="http://technet.microsoft.com/en-us/library/cc708295(WS.10).aspx">vhdmount</a>, if you need support for mounting or unmounting VHDs from the command-line on a vanilla Windows 7 / Server 2008 install, you have to use diskpart.</p><p>diskpart&#8217;s mount commands are pretty simple:</p><pre style="padding-left: 30px;">C:\&gt; diskpart
DISKPART&gt; sel vdisk file="[location of vhd]"
DISKPART&gt; attach vdisk</pre><p>Unmounting is just as simple:</p><pre style="padding-left: 30px;">C:\&gt; diskpart
DISKPART&gt; sel vdisk file="[location of vhd]"
DISKPART&gt; detach vdisk</pre><p>These commands work fine on an ad-hoc basis, but I had the need to automate loading a VHD from a script.  Luckily, diskpart takes a single parameter, /s, which specifies a diskpart &#8220;script&#8221;.  The script is simply the command you would have typed in above:</p><pre style="padding-left: 30px;">C:\&gt; diskpart /s [diskpart script file]</pre><p>I&#8217;ve created two simple scripts, MountVHD.cmd and UnmountVHD.cmd that create a &#8220;diskpart script&#8221;, run it, then remove the temporary file.  This way, you can simply run MountVHD.cmd and point it to your VHD:</p><pre style="padding-left: 30px;">C:\&gt; MountVHD.cmd [location of vhd] [drive letter - optional]</pre><p>Or unmount the same VHD:</p><pre style="padding-left: 30px;">C:\&gt; UnMountVHD.cmd [location of vhd]</pre><p>These files are hosted at <a
href="https://gist.github.com/9b82f28a77f306b0cfc0">Gist.Github</a> if you want to use them or contribute changes.</p><div
class="mr_social_sharing_wrapper"><span
class="mr_social_sharing_top"><iframe
src="https://www.facebook.com/plugins/like.php?locale=en_US&amp;href=http%3A%2F%2Fnicj.net%2F2012%2F01%2F04%2Fmounting-vhds-in-windows-7-from-a-command-line-script&amp;layout=standard&amp;show_faces=false&amp;width=51px&amp;height=24px" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:51px; height:24px;" allowTransparency="true"></iframe></span><span
class="mr_social_sharing_top"><a
href="http://twitter.com/share?url=http%3A%2F%2Fnicj.net%2F2012%2F01%2F04%2Fmounting-vhds-in-windows-7-from-a-command-line-script&amp;text=Mounting+VHDs+in+Windows+7+from+a+command-line+script&amp;via=nicj" target="_blank" class="mr_social_sharing_popup_link"><img
src="http://nicj.net/wp-content/plugins/social-sharing-toolkit/images/buttons/twitter.png" alt="Share on Twitter" title="Share on Twitter"/></a></span><span
class="mr_social_sharing_top"><g:plusone size="medium" count="false" href="http://nicj.net/2012/01/04/mounting-vhds-in-windows-7-from-a-command-line-script"></g:plusone></span></div><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/NicJ?a=3l__Hrm8jUU:By9kzxRz4rQ:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/NicJ?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/NicJ?a=3l__Hrm8jUU:By9kzxRz4rQ:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/NicJ?i=3l__Hrm8jUU:By9kzxRz4rQ:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/NicJ?a=3l__Hrm8jUU:By9kzxRz4rQ:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/NicJ?i=3l__Hrm8jUU:By9kzxRz4rQ:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/NicJ?a=3l__Hrm8jUU:By9kzxRz4rQ:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/NicJ?i=3l__Hrm8jUU:By9kzxRz4rQ:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/NicJ?a=3l__Hrm8jUU:By9kzxRz4rQ:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/NicJ?d=qj6IDK7rITs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/NicJ/~4/3l__Hrm8jUU" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://nicj.net/2012/01/04/mounting-vhds-in-windows-7-from-a-command-line-script/feed</wfw:commentRss> <slash:comments>0</slash:comments> <feedburner:origLink>http://nicj.net/2012/01/04/mounting-vhds-in-windows-7-from-a-command-line-script</feedburner:origLink></item> <item><title>Backing up Windows computers to a Synology NAS via SSH and rsync</title><link>http://feedproxy.google.com/~r/NicJ/~3/SOr_sg48Ik8/backing-up-windows-computers-to-a-synology-nas-via-ssh-and-rsync</link> <comments>http://nicj.net/2012/01/04/backing-up-windows-computers-to-a-synology-nas-via-ssh-and-rsync#comments</comments> <pubDate>Wed, 04 Jan 2012 20:29:55 +0000</pubDate> <dc:creator>Nic</dc:creator> <category><![CDATA[Tech]]></category><guid isPermaLink="false">http://nicj.net/?p=1090</guid> <description><![CDATA[I recently purchased a Synology DS1511+ to act as a NAS (network attached storage) for my home network. The 5-drive, Linux powered device is beautiful &#8211; small, sleek and quiet. What sold me was the amazing web-based configuration interface they provide, and the ability to access the device remotely via the web or from mobile [...]]]></description> <content:encoded><![CDATA[<p><a
href="http://www.amazon.com/gp/product/B004GKLT4G/ref=as_li_ss_il?ie=UTF8&amp;tag=minifigcollector-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=B004GKLT4G"><img
style="float: right;" src="http://ws.assoc-amazon.com/widgets/q?_encoding=UTF8&amp;Format=_SL160_&amp;ASIN=B004GKLT4G&amp;MarketPlace=US&amp;ID=AsinImage&amp;WS=1&amp;tag=minifigcollector-20&amp;ServiceVersion=20070822" alt="" border="0" /></a><img
style="border: none !important; margin: 0px !important;" src="http://www.assoc-amazon.com/e/ir?t=minifigcollector-20&amp;l=as2&amp;o=1&amp;a=B004GKLT4G" alt="" width="1" height="1" border="0" />I recently purchased a <a
href="http://www.amazon.com/gp/product/B004GKLT4G/ref=as_li_ss_tl?ie=UTF8&amp;tag=minifigcollector-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=B004GKLT4G">Synology DS1511+</a><img
style="border: none !important; margin: 0px !important; float: right;" src="http://www.assoc-amazon.com/e/ir?t=minifigcollector-20&amp;l=as2&amp;o=1&amp;a=B004GKLT4G" alt="" width="1" height="1" border="0" /> to act as a NAS (network attached storage) for my home network. The 5-drive, Linux powered device is beautiful &#8211; small, sleek and quiet. What sold me was the amazing <a
href="http://www.synology.com/dsm/index.php?lang=us">web-based configuration interface</a> they provide, and the ability to access the device remotely via the web or from mobile apps Synology provides in the iTunes App Store and Android Market.</p><p>After setting it up with a couple 2TB and 3TB drives, I wanted to use the device to backup documents from several Windows computers I manage (my own, my wife&#8217;s netbook and my parents&#8217; computers thousands of miles away). Local network backup is pretty easy &#8211; you can use the <a
href="http://www.synology.com/us/products/features/backup_desktop.php">Synology Data Replicator</a> to backup Windows hosts to your Synology on your local network. However, it seemed pretty slow to me, and doesn&#8217;t use the highly-optimized rsync protocol for backing up files. Since I was previously using rsync over SSH to a Linux server I run at home, I figured since the Synology was Linux-based, it should be able to do the same.</p><p>All it takes is a few updates to the Synology server, and a few scripts on the Windows computers you want to backup to make this work for both computers on your home network as well as any external computers you want to backup, as long as they know the address of the remote server. You can use a dynamic-IP service such as <a
href="http://TZO.com">TZO.com</a> or <a
href="http://DynDNS.org">DynDNS.org</a> so your remote Windows clients know how to contact your home Synology.</p><p>Once I got it all working, I figured the process and scripts I created could be used by others with a Synology NAS (or any server or NAS running Linux). I&#8217;ve created a <a
href="http://github.com">GitHub</a> repository with the scripts and instructions so you can setup your own secure backup for local and remote Windows computers:</p><p
style="padding-left: 30px;"><a
href="https://github.com/nicjansma/synology-windows-ssh-rsync-backup">https://github.com/nicjansma/synology-windows-ssh-rsync-backup</a></p><h2>Features</h2><ul><li>Uses rsync over ssh to securely backup your Windows hosts to a Synology NAS.</li><li>Each Windows host gets a unique SSH private/public key that can be revoked at any time on the server.</li><li>The server limits the SSH private/public keys so they can only run rsync, and can&#8217;t be used to log into the server.</li><li>The server also limits the SSH private/public keys to a valid path prefix, so rsync can&#8217;t destroy other parts of the file system.</li><li>Windows hosts can backup to the Synology NAS if they&#8217;re on the local network or on a remote network, as long as the outside IP/port are known.</li></ul><p>NOTE: The backups are performed via the Synology root user&#8217;s credentials, to simplify permissions. The SSH keys are only valid for rsync, and are limited to the path prefix you specify. You could change the scripts to backup as another user if you want (config.csv).</p><h2>Synology NAS Setup</h2><ol><li>Enable SSH on your Synology NAS if you haven&#8217;t already. Go to Control Panel &#8211; Terminal, and check &#8220;Enable SSH service&#8221;.</li><li>Log into your Synology via SSH.</li><li>Create a /root/.ssh directory if it doesn&#8217;t already exist<pre>mkdir /root/.ssh
chmod 700 /root/.ssh</pre></li><li>Upload server/validate-rsync.sh to your /root/.ssh/validate-rsync.sh. Then chmod it so it can be run:<pre>chmod 755 /root/.ssh/validate-rsync.sh</pre></li><li>Create an authorized_keys file for later use:<pre>touch /root/.ssh/authorized_keys
chmod 600 /root/.ssh/authorized_keys</pre></li><li>Ensure private/public key logins are enabled in /etc/ssh/sshd_config.<pre>vi /etc/ssh/sshd_config</pre><p>You want to ensure the following lines are uncommented:</p><pre>PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys</pre></li><li>You should reboot your Synology to ensure the settings are applied:<pre>reboot</pre></li><li>Setup a share on your Synology NAS for backups (eg, &#8216;backup&#8217;).</li></ol><h2>Client Package Preparation</h2><p>Before you backup any clients, you will need to make a couple changes to the files in the client/ directory.</p><ol><li>First, you&#8217;ll need a few binaries (rsync, ssh, chmod, ssh-keygen) on your system to facilitate the ssh/rsync transfer. <a
href="http://www.cygwin.com/">Cygwin</a> can be used to accomplish this. You can easily install Cygwin from <a
href="http://www.cygwin.com/">http://www.cygwin.com/</a>. After installing, pluck a couple files from the bin/ folder and put them into the client/ directory. The binaries you need are:<pre>chmod.exe
rsync.exe
ssh.exe
ssh-keygen.exe</pre><p>You may also need a couple libraries to ensure those binaries run:</p><pre>cygcrypto-0.9.8.dll
cyggcc_s-1.dll
cygiconv-2.dll
cygintl-8.dll
cygpopt-0.dll
cygspp-0.dll
cygwin1.dll
cygz.dll</pre></li><li>Next, you should update config.csv for your needs:<pre>rsyncServerRemote - The address clients can connect to when remote (eg, a dynamic IP host)
rsyncPortRemote - The port clients connect to when remote (eg, 22)
rsyncServerHome - The address clients can connect to when on the local network (for example, 192.168.0.2)
rsyncPortHome - The port clients connect to when on the local network (eg, 22)
rsyncUser - The Synology user to backup as (eg, root)
rsyncRootPath - The root path to back up to (eg, /volume1/backup)
vcsUpdateCmd - If set, the version control system command to use prior to backup up (eg, svn up)</pre></li><li>The version control update command (%vcsUpdateCmd%) can be set to run a version control update on your files prior to backing up. This can be useful if you have a VCS repository that clients can connect to. It allows you to make remote changes to the backup scripts, and have the clients get the updated scripts without you having to log into them. The scripts are updated each time start-backup.cmd is run. For example, you could use this command to update from a svn repository:<pre>vcsUpdateCmd,svn up</pre><p>If you are using a VCS system, you should ensure you have the proper command-line .exes and .dlls in the client/ directory. I&#8217;ve used Collab.net&#8217;s svn.exe and lib*.dll files from their distribution (<a
href="http://www.collab.net/downloads/subversion/">http://www.collab.net/downloads/subversion/</a>).</p><p>During client setup, you simply need to log into the machine, checkout the repository, and setup a scheduled task to do the backups (see below). Each time a backup is run, the client will update its backup scripts first.</li></ol><p>The client package is now setup! If you&#8217;re using %vcsUpdateCmd%, you can check the client/ directory into your remote repository.</p><h2>Client Setup</h2><p>For each client you want to backup, you will need to do the following:</p><ol><li>Generate a private/public key pair for the computer. You can do this by running ssh-keygen.exe, or have generate-client-keys.cmd do it for you:<pre>generate-client-keys.cmd</pre><p>or</p><pre>generate-client-keys.cmd [computername]</pre><p>If you run ssh-keygen.exe on your own, you should name the files rsync-keys-[computername]:</p><pre>ssh-keygen.exe -t dsa -f rsync-keys-[computername]</pre><p>If you run ssh-keygen.exe on your own, do not specify a password, or clients will need to enter it every time they backup.</li><li>Grab the public key out of rsync-keys-[computername].pub, and put it into your Synology backup user&#8217;s .ssh/authorized_keys:<pre>vi ~/.ssh/authorized_keys</pre><p>You will want to prefix the authorized key with your validation command. It should look something like this</p><pre>command="[validate-rsync.sh location] [backup volume root]" [contents of rsync-keys-x.pub]</pre><p>For example:</p><pre>command="/root/.ssh/validate-rsync.sh /volume1/backup/MYCOMPUTER" ssh-dss AAAdsadasds...</pre><p>This ensures that the public/private key is only used for rsync (and can&#8217;t be used as a shell login), and that the rsync starts at the specified root path and no higher (so it can&#8217;t destroy the rest of the filesystem).</li><li>Copy backup-TEMPLATE.cmd to backup-[computername].cmd</li><li>Edit the backup-[computername].cmd file to ensure %rsyncPath% is correct. The following DOS environment variable is available to you, which is set in config.csv:<pre>%rsyncRootPath% - Remote root rsync path</pre><p>You should set rsyncPath to the root remote rsync path you want to use. For example:</p><pre>set rsyncPath=%rsyncRootPath%/%COMPUTERNAME%</pre><p>or</p><pre>set rsyncPath=%rsyncRootPath%/bob/%COMPUTERNAME%</pre><p>%rsyncRootPath% is set in config.csv to your Synology backup volume (eg, /volume1/backup), so %rsyncPath% would evaluate to this if your current computer&#8217;s name is MYCOMPUTER:</p><pre>/volume1/backup/MYCOMPUTER</pre><p>You can see this is the same path that you put in the authorized_keys file.</li><li>Edit the backup-[computername].cmd file to run the appropriate rsync commands. The following DOS environment variables are available to you, which are set in start-backup.cmd:<pre>%rsyncStandardOpts% - Standard rsync command-line options
%rsyncConnectionString% - Rsync connection string</pre><p>For example:</p><pre>set cmdArgs=rsync %rsyncStandardOpts% "/cygdrive/c/users/bob/documents/" %rsyncConnectionString%:%rsyncPath%/documents
echo Starting %cmdArgs%
call %cmdArgs%</pre></li><li>Copy the client/ directories to the target computer, say C:\backup. If you are using %vcsUpdateCmd%, you can checkout the client directory so you can push remote updates (see above).</li><li>Setup a scheduled task (via Windows Task Scheduler) to run start-backup.cmd as often as you wish.</li><li>Create the computer&#8217;s backup directory on your Synology NAS:<pre>mkdir /volume1/backup/MYCOMPUTER</pre></li></ol><p>The client is now setup!</p><h2>Source</h2><p>As noted above, the source for these scripts is available on Github:</p><p
style="padding-left: 30px;"><a
href="https://github.com/nicjansma/synology-windows-ssh-rsync-backup">https://github.com/nicjansma/synology-windows-ssh-rsync-backup</a></p><p>If you have any suggestions, find a bug or want to make contributions, please head over to GitHub!</p><div
class="mr_social_sharing_wrapper"><span
class="mr_social_sharing_top"><iframe
src="https://www.facebook.com/plugins/like.php?locale=en_US&amp;href=http%3A%2F%2Fnicj.net%2F2012%2F01%2F04%2Fbacking-up-windows-computers-to-a-synology-nas-via-ssh-and-rsync&amp;layout=standard&amp;show_faces=false&amp;width=51px&amp;height=24px" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:51px; height:24px;" allowTransparency="true"></iframe></span><span
class="mr_social_sharing_top"><a
href="http://twitter.com/share?url=http%3A%2F%2Fnicj.net%2F2012%2F01%2F04%2Fbacking-up-windows-computers-to-a-synology-nas-via-ssh-and-rsync&amp;text=Backing+up+Windows+computers+to+a+Synology+NAS+via+SSH+and+rsync&amp;via=nicj" target="_blank" class="mr_social_sharing_popup_link"><img
src="http://nicj.net/wp-content/plugins/social-sharing-toolkit/images/buttons/twitter.png" alt="Share on Twitter" title="Share on Twitter"/></a></span><span
class="mr_social_sharing_top"><g:plusone size="medium" count="false" href="http://nicj.net/2012/01/04/backing-up-windows-computers-to-a-synology-nas-via-ssh-and-rsync"></g:plusone></span></div><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/NicJ?a=SOr_sg48Ik8:AZ0rUHkL3TY:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/NicJ?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/NicJ?a=SOr_sg48Ik8:AZ0rUHkL3TY:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/NicJ?i=SOr_sg48Ik8:AZ0rUHkL3TY:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/NicJ?a=SOr_sg48Ik8:AZ0rUHkL3TY:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/NicJ?i=SOr_sg48Ik8:AZ0rUHkL3TY:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/NicJ?a=SOr_sg48Ik8:AZ0rUHkL3TY:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/NicJ?i=SOr_sg48Ik8:AZ0rUHkL3TY:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/NicJ?a=SOr_sg48Ik8:AZ0rUHkL3TY:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/NicJ?d=qj6IDK7rITs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/NicJ/~4/SOr_sg48Ik8" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://nicj.net/2012/01/04/backing-up-windows-computers-to-a-synology-nas-via-ssh-and-rsync/feed</wfw:commentRss> <slash:comments>4</slash:comments> <feedburner:origLink>http://nicj.net/2012/01/04/backing-up-windows-computers-to-a-synology-nas-via-ssh-and-rsync</feedburner:origLink></item> <item><title>Unofficial LEGO Minifigure Catalog App now available in Apple AppStore</title><link>http://feedproxy.google.com/~r/NicJ/~3/f3sNaz2PeFs/unofficial-lego-minifigure-catalog-app-now-available-in-apple-appstore</link> <comments>http://nicj.net/2011/12/16/unofficial-lego-minifigure-catalog-app-now-available-in-apple-appstore#comments</comments> <pubDate>Sat, 17 Dec 2011 00:37:11 +0000</pubDate> <dc:creator>Nic</dc:creator> <category><![CDATA[Tech]]></category><guid isPermaLink="false">http://nicj.net/?p=1075</guid> <description><![CDATA[Our Unofficial LEGO Minifigure Catalog App was just approved by Apple and is now available in the AppStore!]]></description> <content:encoded><![CDATA[<p>Our Unofficial LEGO Minifigure Catalog App was just approved by Apple and is now available in the <a
href="http://itunes.apple.com/us/app/the-unofficial-lego-minifigure/id486578707">AppStore!</a></p><p><a
href="http://itunes.apple.com/us/app/the-unofficial-lego-minifigure/id486578707"><img
class="size-full wp-image-1077 alignnone" style="border: 1px solid gray; float: left;" title="mzl_qyquledo_320x480-75" src="http://o.nicj.net/wp-content/uploads/2011/12/mzl_qyquledo_320x480-75.jpg" alt="" width="240" height="360" /></a><a
href="http://itunes.apple.com/us/app/the-unofficial-lego-minifigure/id486578707"><img
class="size-full wp-image-1076 alignnone" style="border: 1px solid gray; float: left; margin-left: 10px;" title="mzl_glprtcre_320x480-75" src="http://o.nicj.net/wp-content/uploads/2011/12/mzl_glprtcre_320x480-75.jpg" alt="" width="240" height="360" /></a></p><div
class="mr_social_sharing_wrapper"><span
class="mr_social_sharing_top"><iframe
src="https://www.facebook.com/plugins/like.php?locale=en_US&amp;href=http%3A%2F%2Fnicj.net%2F2011%2F12%2F16%2Funofficial-lego-minifigure-catalog-app-now-available-in-apple-appstore&amp;layout=standard&amp;show_faces=false&amp;width=51px&amp;height=24px" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:51px; height:24px;" allowTransparency="true"></iframe></span><span
class="mr_social_sharing_top"><a
href="http://twitter.com/share?url=http%3A%2F%2Fnicj.net%2F2011%2F12%2F16%2Funofficial-lego-minifigure-catalog-app-now-available-in-apple-appstore&amp;text=Unofficial+LEGO+Minifigure+Catalog+App+now+available+in+Apple+AppStore&amp;via=nicj" target="_blank" class="mr_social_sharing_popup_link"><img
src="http://nicj.net/wp-content/plugins/social-sharing-toolkit/images/buttons/twitter.png" alt="Share on Twitter" title="Share on Twitter"/></a></span><span
class="mr_social_sharing_top"><g:plusone size="medium" count="false" href="http://nicj.net/2011/12/16/unofficial-lego-minifigure-catalog-app-now-available-in-apple-appstore"></g:plusone></span></div><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/NicJ?a=f3sNaz2PeFs:SS9WOk7X1lE:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/NicJ?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/NicJ?a=f3sNaz2PeFs:SS9WOk7X1lE:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/NicJ?i=f3sNaz2PeFs:SS9WOk7X1lE:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/NicJ?a=f3sNaz2PeFs:SS9WOk7X1lE:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/NicJ?i=f3sNaz2PeFs:SS9WOk7X1lE:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/NicJ?a=f3sNaz2PeFs:SS9WOk7X1lE:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/NicJ?i=f3sNaz2PeFs:SS9WOk7X1lE:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/NicJ?a=f3sNaz2PeFs:SS9WOk7X1lE:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/NicJ?d=qj6IDK7rITs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/NicJ/~4/f3sNaz2PeFs" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://nicj.net/2011/12/16/unofficial-lego-minifigure-catalog-app-now-available-in-apple-appstore/feed</wfw:commentRss> <slash:comments>0</slash:comments> <feedburner:origLink>http://nicj.net/2011/12/16/unofficial-lego-minifigure-catalog-app-now-available-in-apple-appstore</feedburner:origLink></item> <item><title>The Unofficial LEGO Minifigure Catalog App</title><link>http://feedproxy.google.com/~r/NicJ/~3/i5x-Ynrp470/the-unofficial-lego-minifigure-catalog-app</link> <comments>http://nicj.net/2011/12/12/the-unofficial-lego-minifigure-catalog-app#comments</comments> <pubDate>Mon, 12 Dec 2011 18:59:53 +0000</pubDate> <dc:creator>Nic</dc:creator> <category><![CDATA[Tech]]></category><guid isPermaLink="false">http://nicj.net/?p=1037</guid> <description><![CDATA[I&#8217;m happy to announce the release of a new project I&#8217;ve been working on, The Unofficial LEGO Minifigure Catalog App.  Earlier this year, Dr. Christoph Bartneck released a new book titled The Unofficial LEGO Minifigure Catalog.  The book contains high quality photographs of all 3,600 minifigures released between the 1970s and 2010.  Dr. Barneck also [...]]]></description> <content:encoded><![CDATA[<p><a
title="The Unofficial LEGO Minifigure Catalog" href="http://www.minifigure.org/"><img
class="alignright size-full wp-image-1040" title="book" src="http://o.nicj.net/wp-content/uploads/2011/12/book.png" alt="" width="200" height="239" /></a>I&#8217;m happy to announce the release of a new project I&#8217;ve been working on, <a
title="App" href="http://www.minifigure.org/application/">The Unofficial LEGO Minifigure Catalog App</a>.  Earlier this year, Dr. Christoph Bartneck released a new book titled <em><a
href="http://www.minifigure.org/">The Unofficial LEGO Minifigure Catalog</a></em>.  The book contains high quality photographs of all 3,600 minifigures released between the 1970s and 2010.  Dr. Barneck also introduces a new nomenclature for identifying and categorizing minifigures.  It&#8217;s a great book for LEGO fans, and is available from <a
href="http://www.amazon.com/gp/product/1463518978/ref=as_li_ss_tl?ie=UTF8&amp;tag=virtualglo-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=1463518978">Amazon</a><img
style="margin: 0px !important; border: currentColor !important;" src="http://www.assoc-amazon.com/e/ir?t=virtualglo-20&amp;l=as2&amp;o=1&amp;a=1463518978" alt="" width="1" height="1" border="0" />.</p><p>Since its release, I have been working with Dr. Bartneck on a mobile application that highlights all of the great content in the book.  Today, the app is available in the Android Market, and the iOS version has been submitted for review.  We think the app is a great companion for the book.</p><p><strong>Features</strong></p><ul><li>More than 3650 Minifigures and 650 Heads listed</li><li>High-resolution photographs of every Minifigure</li><li>Thousands of LEGO sets listed</li><li>Browse by theme or year</li><li>Search by name</li><li>Manage favorite Minifigures</li><li>Mark the Minifigures you own</li><li>Import and export with <a
href="http://brickset.com">Brickset.com</a> account</li><li>Advanced downloading and caching technology</li><li>Regular updates</li><div
style="clear: both;">&nbsp;</div><p><strong>Screen Shots</strong></p><p>Here are screenshots from an Android device:</p><p><a
href="http://o.nicj.net/wp-content/uploads/2011/12/device-2011-12-12-094151.png"><img
class="size-full wp-image-1042 alignleft" style="border: 1px solid black;" title="device-2011-12-12-094151" src="http://o.nicj.net/wp-content/uploads/2011/12/device-2011-12-12-094151.png" alt="" width="240" height="400" /></a><a
href="http://o.nicj.net/wp-content/uploads/2011/12/device-2011-12-12-094455.png"><img
class="alignleft size-full wp-image-1043" style="border: 1px solid black;" title="device-2011-12-12-094455" src="http://o.nicj.net/wp-content/uploads/2011/12/device-2011-12-12-094455.png" alt="" width="240" height="400" /></a></p><div
style="clear: both;">&nbsp;</div><p><a
href="http://o.nicj.net/wp-content/uploads/2011/12/device-2011-12-12-094312.png"><img
class="alignleft size-full wp-image-1047" style="border: 1px solid black;" title="device-2011-12-12-094312" src="http://o.nicj.net/wp-content/uploads/2011/12/device-2011-12-12-094312.png" alt="" width="240" height="400" /></a><a
href="http://o.nicj.net/wp-content/uploads/2011/12/device-2011-12-12-094349.png"><img
class="alignleft size-full wp-image-1048" style="border: 1px solid black;" title="device-2011-12-12-094349" src="http://o.nicj.net/wp-content/uploads/2011/12/device-2011-12-12-094349.png" alt="" width="240" height="400" /></a></p><div
style="clear: both;">&nbsp;</div><p><strong>Availability</strong></p><p>The app is available today in the <a
href="https://market.android.com/details?id=org.minifigure.theUnofficialLEGOminifigureCatalog">Android Market</a>:</p><p><a
title="Available in the Android Market" href="https://market.android.com/details?id=org.minifigure.theUnofficialLEGOminifigureCatalog"><img
title="45_avail_market_logo2" src="http://o.nicj.net/wp-content/uploads/2011/12/45_avail_market_logo2.png" alt="" width="192" height="45" /></a></p><p><a
title="Android Market QR code" href="https://market.android.com/details?id=org.minifigure.theUnofficialLEGOminifigureCatalog"><img
class="alignleft size-thumbnail wp-image-1056" title="img" src="http://o.nicj.net/wp-content/uploads/2011/12/img-150x150.png" alt="" width="150" height="150" /></a></p><div
style="clear: both;">&nbsp;</div><p>The iOS version (iPod, iPhone, iPad) will be available as soon as Apple approves it.</p><p>Please let us know what you think!</p><div
class="mr_social_sharing_wrapper"><span
class="mr_social_sharing_top"><iframe
src="https://www.facebook.com/plugins/like.php?locale=en_US&amp;href=http%3A%2F%2Fnicj.net%2F2011%2F12%2F12%2Fthe-unofficial-lego-minifigure-catalog-app&amp;layout=standard&amp;show_faces=false&amp;width=51px&amp;height=24px" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:51px; height:24px;" allowTransparency="true"></iframe></span><span
class="mr_social_sharing_top"><a
href="http://twitter.com/share?url=http%3A%2F%2Fnicj.net%2F2011%2F12%2F12%2Fthe-unofficial-lego-minifigure-catalog-app&amp;text=The+Unofficial+LEGO+Minifigure+Catalog+App&amp;via=nicj" target="_blank" class="mr_social_sharing_popup_link"><img
src="http://nicj.net/wp-content/plugins/social-sharing-toolkit/images/buttons/twitter.png" alt="Share on Twitter" title="Share on Twitter"/></a></span><span
class="mr_social_sharing_top"><g:plusone size="medium" count="false" href="http://nicj.net/2011/12/12/the-unofficial-lego-minifigure-catalog-app"></g:plusone></span></div><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/NicJ?a=i5x-Ynrp470:IUgUSBDZhP8:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/NicJ?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/NicJ?a=i5x-Ynrp470:IUgUSBDZhP8:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/NicJ?i=i5x-Ynrp470:IUgUSBDZhP8:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/NicJ?a=i5x-Ynrp470:IUgUSBDZhP8:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/NicJ?i=i5x-Ynrp470:IUgUSBDZhP8:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/NicJ?a=i5x-Ynrp470:IUgUSBDZhP8:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/NicJ?i=i5x-Ynrp470:IUgUSBDZhP8:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/NicJ?a=i5x-Ynrp470:IUgUSBDZhP8:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/NicJ?d=qj6IDK7rITs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/NicJ/~4/i5x-Ynrp470" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://nicj.net/2011/12/12/the-unofficial-lego-minifigure-catalog-app/feed</wfw:commentRss> <slash:comments>0</slash:comments> <feedburner:origLink>http://nicj.net/2011/12/12/the-unofficial-lego-minifigure-catalog-app</feedburner:origLink></item> <item><title>Amazon S3/CloudFront 304s stripping Cache-Control headers</title><link>http://feedproxy.google.com/~r/NicJ/~3/pUWb7uJT7DU/amazon-s3cloudfront-304s-stripping-cache-control-headers</link> <comments>http://nicj.net/2011/10/07/amazon-s3cloudfront-304s-stripping-cache-control-headers#comments</comments> <pubDate>Sat, 08 Oct 2011 06:25:51 +0000</pubDate> <dc:creator>Nic</dc:creator> <category><![CDATA[Tech]]></category><guid isPermaLink="false">http://nicj.net/?p=1023</guid> <description><![CDATA[TL;DR: Beware of relying on Cache-Control: max-age and Expires HTTP header fallback behavior on Amazon CloudFront. The Cache-Control header may get stripped on CloudFront 304s, and browsers will then have to fall back to whatever is in the Expires header. If that Expires date has passed, or if you never specified it, all subsequent requests [...]]]></description> <content:encoded><![CDATA[<p><a
href="http://en.wikipedia.org/wiki/Wikipedia:Too_long;_didn%27t_read">TL;DR</a>: Beware of relying on <code>Cache-Control: max-age</code> and <code>Expires</code> HTTP header <a
href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.2.4">fallback behavior</a> on Amazon CloudFront. The <code>Cache-Control</code> header may get stripped on CloudFront 304s, and browsers will then have to fall back to whatever is in the <code>Expires</code> header. If that <code>Expires</code> date has passed, or if you never specified it, all subsequent requests for the resource will be conditionally validated by the browser.</p><p><strong>The Problem</strong></p><p>I was looking at my web server&#8217;s health metrics recently (via Cacti), and noticed a spike in outbound traffic and HTTP requests. Analytics logs didn&#8217;t show a large increase in visitors or page loads, and it looked like the additional traffic was simply an increase in requests for static images.</p><p><strong>The Investigation</strong></p><p>The static images in question have <a
href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html">HTTP Cache headers</a> set for 1 year into the future, so they can be easily cached by browsers and proxies per performance best-practices. The <a
href="http://stackoverflow.com/questions/4566275/http-headers-is-cache-control-enough-or-do-i-still-need-expires">suggested way to set a far expiry date</a> is by setting both the <code>Cache-Control</code> header (eg, <code>Cache-Control: public, max-age=31536000</code>), as well as an <code>Expires</code> header with a static date set for the same time in the future. The <code>Expires</code> header is a HTTP/1.0 header that sets a specific date, say Jan 1 2011, whereas <code>Cache-Control</code> is relative, in seconds. Theoretically, if both <code>Cache-Control</code> <em>and </em><code>Expires</code> headers are sent, the <code>Cache-Control</code> header <a
href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.2.4">should take precedence</a>, so it&#8217;s safe to additionally set <code>Expires</code> for fall-back cases.</p><p>This combination of caching header behavior works good if you are using Amazon&#8217;s <a
href="http://aws.amazon.com/cloudfront/">CloudFront </a>CDN, backed by static files on Amazon <a
href="http://aws.amazon.com/s3/">S3</a>, which is what I use for several sites. The files are uploaded once to S3, and their HTTP headers are set at upload time.  For the static images, I am uploading them with a 1-year max-age expiry and an <code>Expires</code> header 1 year from when they&#8217;re uploaded. For example, I uploaded an image to S3 on Oct 5 2010 with these headers:</p><pre style="padding-left: 30px;">Cache-Control: public, max-age=31536000
Expires: Thu, 05 Oct 2011 22:45:05 GMT</pre><p>Theoretically, HTTP/1.1 clients (current web browsers) and even ancient HTTP/1.0 proxies should both be able to understand these headers. Even though the <code>Expires</code> header was for Oct 5 2011 (a couple days ago), <code>Cache-Control</code> should take precedence and the content should still be fresh for all current web browsers that recently downloaded the file. HTTP/1.0 proxies will only understand the <code>Expires</code> header, and they may want to conditionally validate the content if the date is past Oct 5 2011, but they should be a small part of HTTP accesses.</p><p>So my first thought was that the additional load on the server was from HTTP/1.0 proxies re-validating the already-expired content since I had set the content to expire in 1 year and that date had just passed. I should have set a much-further expiry in the first place &#8212; these images never change. To fix this, I could easily just re-upload the content with a much longer <code>Expires </code>(30 years from now should be sufficient).</p><p>However, as I was investigating the issue, I noticed via the F12 Developer Tools that IE9 was conditionally validating some of the already-expired images, even though the <code>Cache-Control</code> header should be taking precedence. Multiple images were being conditionally re-validated (incurring a HTTP request and 304 response), for every IE session. All of these images had <code>Expires</code> header date that recently passed.</p><p>After I cleared my IE browser cache, the problem no longer repro&#8217;d. It was only after I happened to F5 the page (refresh) that the past-<code>Expires</code> images were being conditionally requested again on subsequent navigations.</p><p><strong>The Repro</strong></p><p>Take, for example, this request of a static file on my webserver that expired back on Jan 1, 2010:</p><pre style="padding-left: 30px; color: #339966;">GET /test/test-public.txt HTTP/1.1
Accept: text/html, application/xhtml+xml, */*
Accept-Language: en-US
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)
Accept-Encoding: gzip, deflate
Connection: Keep-Alive
Host: cf.nicj.net</pre><pre style="padding-left: 30px; color: #3366ff;">HTTP/1.0 200 OK Date: Sat, 08 Oct 2011 02:28:03 GMT
<strong>Cache-Control: public, max-age=946707779</strong>
<strong>Expires: Fri, 01 Jan 2010 00:00:00 GMT </strong>
Last-Modified: Sat, 08 Oct 2011 02:25:58 GMT
ETag: "098f6bcd4621d373cade4e832627b4f6"
Accept-Ranges: bytes
Content-Type: text/plain
Content-Length: 4
Server: AmazonS3</pre><p>IE and other modern browsers will download this content today, and treat it as fresh for 30 years (946,707,779 seconds), due to the <code>Cache-Control</code> header taking precedence over the Jan 1, 2010 <code>Expires</code> header.</p><p>The problem comes when, for whatever reason, a browser conditionally re-validates the content (via <code>If-Modified-Since</code>). Here are IE&#8217;s request headers and Amazon&#8217;s CloudFront response headers:</p><pre style="padding-left: 30px; color: #396;">GET /test/test-public.txt HTTP/1.1
Accept: text/html, application/xhtml+xml, */*
Accept-Language: en-US
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)
Accept-Encoding: gzip, deflate
Connection: Keep-Alive
Host: cf.nicj.net
<strong>If-Modified-Since: Sat, 08 Oct 2011 02:28:03 GMT</strong></pre><pre style="padding-left: 30px; color: #36f;"><strong>HTTP/1.0 304 Not Modified</strong>
Date: Sat, 08 Oct 2011 02:31:54 GMT
Content-Type: text/plain
<strong>Expires: Fri, 01 Jan 2010 00:00:00 GMT</strong>
Last-Modified: Sat, 08 Oct 2011 02:25:58 GMT
ETag: "098f6bcd4621d373cade4e832627b4f6"
Age: 232</pre><p>We see the additional <code>If-Modifed-Since</code> in the request, and the same <code>Expires</code> date in the response. Unfortunately, there&#8217;s an important missing header in this response: the <code>Cache-Control</code> header. It appears, at least from my testing, that CloudFront strips the <code>Cache-Control</code> headers from 304 responses.</p><p>After this happens it appears that IE forgets the original <code>Cache-Control</code> header so <strong>all </strong>subsequent navigations to the page will trigger conditional GETs for those resources.  Since the 304 is missing the <code>Cache-Control</code> header, it just sees the <code>Expires</code> tag, and thinks it needs to always re-validate the content from now on<em>.</em></p><p><strong>Why This Would Happen</strong></p><p>But what&#8217;s causing the re-validation (<code>If-Modifed-Since)</code> and subsequent 304 in the first place?</p><p>User agents shouldn&#8217;t normally re-validate these resources, since the original <code>Cache-Control</code> header should keep it fresh for quite a while.  Except, when you either force a refresh (F5) of the page, <em>or </em>if the content has passed its natural freshness.</p><p>On F5 refresh, <em>all </em>resources on the page are conditionally re-validated via <code>If-Modified-Since</code>. And, as we&#8217;ve seen, the resources on CloudFront are sent back missing the original <code>Cache-Control</code> header, and IE updates its cache with just the <code>Expires</code> tag, instead of keeping the resource still fresh for a year.<em> </em> For some reason, this doesn&#8217;t occur with Chrome or Firefox on F5.</p><p>In addition, the problem will appear in all browsers when they need to send a <code>If-Modified-Since</code> header for re-validation of content they think might have expired, such as with max-age headers that have expired (shorter-expiring content).</p><p>Take, for example, a resource that you set to expire 1 day from now, and either set the <code>Expires</code> header to 1 day from now (per best practices) or simply don&#8217;t specify the <code>Expires</code> header:</p><pre style="padding-left: 30px;">Cache-Control: public, max-age=86400</pre><p>For the first 24 hours after your visitor loads the resource, modern browsers won&#8217;t re-validate the resource. At hour 24 and 1 second, the browser will send a conditional request. Unfortunately, with CloudFront, the 304 response will be missing the <code>Cache-Control</code> header.  The browser then doesn&#8217;t realize that the resource should be fresh for another 24 hours. So even if the content wasn&#8217;t actually updated after those 24 hours, <em>all </em>subsequent navigations with the resource will trigger a conditional validate of that resource, since the original <code>Cache-Control</code> headers were lost with the 304. Ugh.</p><p><strong>How to Avoid the Issue</strong></p><p>Note this doesn&#8217;t appear to affect Chrome 14 and FireFox 6 in the F5 scenario. Both browsers send conditional <code>If-Modified-Since</code> headers on F5 and get back the same CloudFront response (sans <code>Cache-Control</code> headers), but they don&#8217;t appear to be affected by the missing <code>Cache-Control</code> header. Subsequent navigations in Chrome and FF after a F5 do <em>not </em>conditionally re-validate the CloudFront content. They <em>do </em>appear to be affected by the missing <code>Cache-Control</code> header for naturally stale content on <code>If-Modified-Since</code> requests.</p><p>I haven&#8217;t investigated the F5 problem on pre-IE9 versions, but I would assume the problem exists there as well. As far as I can tell, this isn&#8217;t fixed in IE10 beta.</p><p>I&#8217;ve only found this problem on CloudFront&#8217;s CDN servers. I couldn&#8217;t find a way to get Apache to naturally skip the <code>Cache-Control</code> header for 304s if the header was in the original HTTP 200 response (for example, when using <a
href="http://httpd.apache.org/docs/2.0/mod/mod_expires.html">mod_expires</a> on static content).</p><p>The bottom line is that requests that send an <code>If-Modified-Since</code> to CloudFront and get a 304 back will essentially lose the <code>Cache-Control</code> hints. If your <code>Expires</code> header is missing, or in the past, the resource will be conditionally validated on every page navigation until it gets evicted from the cache. That can cause a lot of unnecessary requests and will slow down your visitor&#8217;s page loads.</p><p>The simple solution is to use a much-further expiry time.  30 years should suffice. Then, if the original <code>Cache-Control</code> header is lost from CloudFront 304s, the 30-year-from-now <code>Expires</code> header will keep the resource from having to be validated.</p><p>I&#8217;m not sure why Amazon CloudFront strips the <code>Cache-Control</code> header from 304 responses. I&#8217;ll follow up with them.</p><p><strong>Back to my original problem</strong>: I think it&#8217;s actually Amazon&#8217;s CloudFront servers noting that the <code>Expires</code> for a lot of my static images are past-due.  They&#8217;re checking the origin server to see if any new content is available.  The above issue isn&#8217;t likely causing a ton of additional load, but it was interesting to find none-the-less!</p><p><strong>Update 2011-10-12:</strong> I&#8217;ve opened a thread on the Amazon CloudFront forums <a
href="https://forums.aws.amazon.com/thread.jspa? threadID=77954&amp;tstart=0">here</a>.  The team has responded saying they&#8217;re looking into the issue.</p><p><strong>Update 2011-12-18:</strong> The Amazon CloudFront team has <a
href="https://forums.aws.amazon.com/thread.jspa?threadID=77954&amp;tstart=0">fixed the issue</a>!</p><div
class="mr_social_sharing_wrapper"><span
class="mr_social_sharing_top"><iframe
src="https://www.facebook.com/plugins/like.php?locale=en_US&amp;href=http%3A%2F%2Fnicj.net%2F2011%2F10%2F07%2Famazon-s3cloudfront-304s-stripping-cache-control-headers&amp;layout=standard&amp;show_faces=false&amp;width=51px&amp;height=24px" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:51px; height:24px;" allowTransparency="true"></iframe></span><span
class="mr_social_sharing_top"><a
href="http://twitter.com/share?url=http%3A%2F%2Fnicj.net%2F2011%2F10%2F07%2Famazon-s3cloudfront-304s-stripping-cache-control-headers&amp;text=Amazon+S3%2FCloudFront+304s+stripping+Cache-Control+headers&amp;via=nicj" target="_blank" class="mr_social_sharing_popup_link"><img
src="http://nicj.net/wp-content/plugins/social-sharing-toolkit/images/buttons/twitter.png" alt="Share on Twitter" title="Share on Twitter"/></a></span><span
class="mr_social_sharing_top"><g:plusone size="medium" count="false" href="http://nicj.net/2011/10/07/amazon-s3cloudfront-304s-stripping-cache-control-headers"></g:plusone></span></div><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/NicJ?a=pUWb7uJT7DU:y2c-YYgDgF8:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/NicJ?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/NicJ?a=pUWb7uJT7DU:y2c-YYgDgF8:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/NicJ?i=pUWb7uJT7DU:y2c-YYgDgF8:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/NicJ?a=pUWb7uJT7DU:y2c-YYgDgF8:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/NicJ?i=pUWb7uJT7DU:y2c-YYgDgF8:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/NicJ?a=pUWb7uJT7DU:y2c-YYgDgF8:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/NicJ?i=pUWb7uJT7DU:y2c-YYgDgF8:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/NicJ?a=pUWb7uJT7DU:y2c-YYgDgF8:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/NicJ?d=qj6IDK7rITs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/NicJ/~4/pUWb7uJT7DU" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://nicj.net/2011/10/07/amazon-s3cloudfront-304s-stripping-cache-control-headers/feed</wfw:commentRss> <slash:comments>0</slash:comments> <feedburner:origLink>http://nicj.net/2011/10/07/amazon-s3cloudfront-304s-stripping-cache-control-headers</feedburner:origLink></item> <item><title>New Adventures: Why I’m Leaving Microsoft and What’s Next</title><link>http://feedproxy.google.com/~r/NicJ/~3/TCU3rdRlzW0/new-adventures-why-im-leaving-microsoft-and-whats-next</link> <comments>http://nicj.net/2011/09/14/new-adventures-why-im-leaving-microsoft-and-whats-next#comments</comments> <pubDate>Wed, 14 Sep 2011 18:00:04 +0000</pubDate> <dc:creator>Nic</dc:creator> <category><![CDATA[Life]]></category><guid isPermaLink="false">http://nicj.net/?p=1010</guid> <description><![CDATA[Six years ago, fresh out of college, I packed up my life into a couple of moving boxes and headed out to the Pacific Northwest to take a job at Microsoft.  Since then, I&#8217;ve been lucky enough to work on some amazing projects &#8211; a large scale performance validation infrastructure for Windows 7, a world-class [...]]]></description> <content:encoded><![CDATA[<p>Six years ago, fresh out of college, I packed up my life into a couple of moving boxes and headed out to the Pacific Northwest to take a job at Microsoft.  Since then, I&#8217;ve been lucky enough to work on some amazing projects &#8211; a large scale performance validation infrastructure for Windows 7, a <a
href="http://ie.microsoft.com/testdrive/">world-class browser</a>, and have helped shape the future of the web by collaborating in the W3C <a
href="http://www.w3.org/2010/webperf/">webperf</a> working group.  It&#8217;s been a great place to work &#8211; I&#8217;ve made some amazing friends, learned more than I ever would have imagined, and have been often humbled by how amazing my coworkers are.</p><p>This Friday will be my last day at Microsoft.  It was a tough decision to leave, and there are many things I will miss about the company, my work, and my coworkers.  Microsoft is a great company, the benefits are amazing, and you get to work with a ton of awesome people.  I&#8217;ve grown in so many ways by just being able to interact with and learn from my coworkers.  I&#8217;ll miss those interactions.</p><p>On the other hand, for the past fifteen years, I have been building software, websites, and now mobile apps in my spare time.  I&#8217;ve always used these side projects to satisfy a need to be creative, to learn and explore new technologies, and to have fun.  Some of these projects have grown beyond what I would have ever expected them to be.  It&#8217;s been tough finding time to work on them &#8211; after a long day of mind-bending work, staring at a monitor for another couple hours isn&#8217;t always at the top of my list of things to do.  But I get a lot of pleasure out of being creative, so I&#8217;ll often stay up late working on this or that.</p><p>And so, I&#8217;ve always wondered what I could accomplish if those projects were my <em>only</em> job?</p><p>Starting Monday, I am taking the big, scary step of becoming my own boss.  I&#8217;m still not 100% sure what that means, and I&#8217;ll let you know a year from now how it has worked out.  I&#8217;m excited to build, to be creative, to learn, and to share.  It&#8217;s time for me to get serious about some of the projects I&#8217;ve already put hundreds of hours into and to take them to the next level.</p><p>In addition to those projects, one of my passions is performance, on both the desktop and the web.  My focus at Microsoft was on perf features and analysis, where I developed a massive performance regression  testing system for Windows 7.  I built performance features for Internet Explorer 9, and collaborated in the W3C webperf working group.  I hope to continue learning, exploring and even teaching others about performance in the future, through research and experimentation with my own projects.</p><p>There are a ton of things I want to accomplish, and I know I&#8217;ll have to work hard to provide for my family.  It&#8217;s not easy walking away from a comfy salary and great benefits, with the knowledge that you have to make up for all of it on your own.  Thankfully I have a head start with some successful websites and apps, but I know I&#8217;m going to have to put a lot of hard work into taking them to the next level.</p><p>Wish me luck.</p><div
class="mr_social_sharing_wrapper"><span
class="mr_social_sharing_top"><iframe
src="https://www.facebook.com/plugins/like.php?locale=en_US&amp;href=http%3A%2F%2Fnicj.net%2F2011%2F09%2F14%2Fnew-adventures-why-im-leaving-microsoft-and-whats-next&amp;layout=standard&amp;show_faces=false&amp;width=51px&amp;height=24px" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:51px; height:24px;" allowTransparency="true"></iframe></span><span
class="mr_social_sharing_top"><a
href="http://twitter.com/share?url=http%3A%2F%2Fnicj.net%2F2011%2F09%2F14%2Fnew-adventures-why-im-leaving-microsoft-and-whats-next&amp;text=New+Adventures%3A+Why+I%E2%80%99m+Leaving+Microsoft+and+What%E2%80%99s+Next&amp;via=nicj" target="_blank" class="mr_social_sharing_popup_link"><img
src="http://nicj.net/wp-content/plugins/social-sharing-toolkit/images/buttons/twitter.png" alt="Share on Twitter" title="Share on Twitter"/></a></span><span
class="mr_social_sharing_top"><g:plusone size="medium" count="false" href="http://nicj.net/2011/09/14/new-adventures-why-im-leaving-microsoft-and-whats-next"></g:plusone></span></div><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/NicJ?a=TCU3rdRlzW0:T4rD-bM57b0:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/NicJ?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/NicJ?a=TCU3rdRlzW0:T4rD-bM57b0:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/NicJ?i=TCU3rdRlzW0:T4rD-bM57b0:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/NicJ?a=TCU3rdRlzW0:T4rD-bM57b0:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/NicJ?i=TCU3rdRlzW0:T4rD-bM57b0:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/NicJ?a=TCU3rdRlzW0:T4rD-bM57b0:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/NicJ?i=TCU3rdRlzW0:T4rD-bM57b0:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/NicJ?a=TCU3rdRlzW0:T4rD-bM57b0:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/NicJ?d=qj6IDK7rITs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/NicJ/~4/TCU3rdRlzW0" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://nicj.net/2011/09/14/new-adventures-why-im-leaving-microsoft-and-whats-next/feed</wfw:commentRss> <slash:comments>9</slash:comments> <feedburner:origLink>http://nicj.net/2011/09/14/new-adventures-why-im-leaving-microsoft-and-whats-next</feedburner:origLink></item> </channel> </rss><!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using memcached
Page Caching using memcached
Content Delivery Network via Amazon Web Services: CloudFront: o.nicj.net

Served from: nicj.net @ 2012-05-16 05:27:37 -->

