<?xml version="1.0"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>matthew manning</title>
    <link>http://mwmanning.com/</link>
    <atom:link href="http://mwmanning.com/rss.xml" rel="self" type="application/rss+xml" />
    <description>matthew manning</description>
    <language>en-us</language>
    <pubDate>Mon, 01 Apr 2013 02:59:31 +0000</pubDate>
    <lastBuildDate>Mon, 01 Apr 2013 02:59:31 +0000</lastBuildDate>

    
    <item>
      <title>Sun Jar Prototyping</title>
      <link>http://mwmanning.com/2013/03/31/Sun-Jar-Prototyping.html</link>
      <pubDate>Sun, 31 Mar 2013 00:00:00 +0000</pubDate>
      <author>matt.manning@gmail.com (Matt Manning)</author>
      <guid>http://mwmanning.com/2013/03/31/Sun-Jar-Prototyping</guid>
      <description>&lt;p&gt;&lt;img alt='Sun Jar' src='https://lh3.googleusercontent.com/-H4iETK4HtSY/UVjajKXCLfI/AAAAAAAATFc/GYoIxbpEUX4/s545/solar-sun-jar.jpg' /&gt;&lt;/p&gt;

&lt;p&gt;Sun jars are solar-powered LED night lights. You can find them for sale all over the web and even at some brick-and-mortar retail stores. Making one looked like a fun project, so I started Googling and checking the normal places like &lt;a href='http://www.instructables.com/index'&gt;Instructables&lt;/a&gt; for project ideas. Surprisingly, all the DIY sun jar guides I could find centered around hacking up a pre-built solar garden light and stuffing the guts into a jar.&lt;/p&gt;

&lt;p&gt;That didn&amp;#8217;t sound like any fun to me. This had to be a really simple circuit. Why not build it from scratch and learn something along the way? I decided that would be my project.&lt;/p&gt;

&lt;h2 id='designing_the_circuit'&gt;Designing the circuit&lt;/h2&gt;

&lt;p&gt;My first step was reading about battery-charging circuits. I wanted this to be a simple project, and I knew I&amp;#8217;d be working with a low current from a solar panel, so &lt;a href='http://en.wikipedia.org/wiki/Battery_charging#Trickle'&gt;trickle-charging&lt;/a&gt; seemed like the best option. After Googling around for a bit, I settled on this circuit configuration:&lt;/p&gt;

&lt;p&gt;&lt;a href='https://www.circuitlab.com/circuit/wn826n/sun-jar/'&gt;&lt;img alt='circuit' src='/images/sunjar_circuit.png' /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click on the circuit image above to visit the CircuitLab page and read a full explanation of how it works.&lt;/p&gt;

&lt;h2 id='building_the_circuit'&gt;Building the circuit&lt;/h2&gt;

&lt;p&gt;The next step was to start spec&amp;#8217;ing out the parts. Most LEDs have a forward voltage — also called a &lt;a href='http://en.wikipedia.org/wiki/LED_circuit'&gt;voltage drop&lt;/a&gt; — of around 2V, with some blues &lt;a href='http://www.oksolar.com/led/led_color_chart.htm'&gt;dropping as much as 3.8V&lt;/a&gt;. This meant I needed a battery of 3V or more. A normal AA or AAA cell is about 1.2V, and I had some rechargeables around, so I strung 3 AAAs in series and made myself a 3.6V battery pack.&lt;/p&gt;

&lt;p&gt;To trickle charge a 3.6V battery I needed a solar panel that could produce a higher voltage than that and also would fit in the lid of a jar. After a lot of searching I found these inexpensive &lt;a href='http://www.adafruit.com/products/700'&gt;5V solar &amp;#8220;badges&amp;#8221;&lt;/a&gt; from Adafruit.&lt;/p&gt;

&lt;p&gt;&lt;a href='http://www.adafruit.com/products/700'&gt;&lt;img alt='solar badge front' src='/images/solar_badge_front.jpeg' /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, I built the circuit on a breadboard to test it out. Here&amp;#8217;s a video of me demonstrating the light turning on when the solar panel gets dark:&lt;/p&gt;
&lt;object height='360' width='640'&gt;&lt;param name='movie' value='http://www.youtube.com/v/ASY-5kZcReo?hl=en_US&amp;amp;version=3&amp;amp;rel=0' /&gt;&lt;param name='allowFullScreen' value='true' /&gt;&lt;param name='allowscriptaccess' value='always' /&gt;&lt;embed allowfullscreen='true' allowscriptaccess='always' height='360' src='http://www.youtube.com/v/ASY-5kZcReo?hl=en_US&amp;amp;version=3&amp;amp;rel=0' type='application/x-shockwave-flash' width='640' /&gt;&lt;/object&gt;
&lt;p&gt;I could tell right away that the battery would light the LED and voltage from the solar panel would control the transistor, but it took some time to test charging the battery. I observed with a multimeter that the battery voltage was higher after several hours in the sun, but I also left the breadboard in a sunny window for a couple of weeks as a real test, and the LED kept lighting up every night.&lt;/p&gt;

&lt;h2 id='fitting_it_in_a_jar'&gt;Fitting it in a jar&lt;/h2&gt;

&lt;p&gt;Now that I&amp;#8217;d demonstrated that the circuit worked, the next step was to build a prototype. The 3AAA battery pack was too big to fit in a jar, so I went searching for a better battery. I found these cool 3.6V &lt;a href='https://www.sparkfun.com/products/10319'&gt;rechargeable lithium ion coin cells&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;img alt='rechargable coin cell' src='https://lh4.googleusercontent.com/-fxoSB3m2i_A/UVjcnCcdBoI/AAAAAAAATFs/V8HB8NtdCTg/s545/10319-00a.jpg' /&gt;&lt;/p&gt;

&lt;p&gt;at Sparkfun which ended up being perfect, so I ordered several of them along with some matching &lt;a href='https://www.sparkfun.com/products/8863'&gt;holders&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img alt='holder' src='https://lh5.googleusercontent.com/-R_lP45tDXJY/UVjcnJ6GtfI/AAAAAAAATFw/Ffi2GZ7eG7E/s545/08863-03-L.jpg' /&gt;&lt;/p&gt;

&lt;p&gt;Here&amp;#8217;s where ordering stuff online can bite you. I didn&amp;#8217;t realize until they arrived that the holders are only the positive contact for the battery. They&amp;#8217;re intended for use on a PCB where a solder pad on the board provides the negative contact. Bummer! So I had to wait a few more days for some &lt;a href='https://www.sparkfun.com/products/10495'&gt;breakout boards&lt;/a&gt; to arrive.&lt;/p&gt;

&lt;p&gt;&lt;img alt='breakout board' src='https://lh5.googleusercontent.com/-z2Wej6BZA8g/UVjcnDNqfjI/AAAAAAAATF0/805fKg0V1hY/s545/10495-01.jpg' /&gt;&lt;/p&gt;

&lt;p&gt;Once I received the breakout boards, I soldered one up and used it to replace the 3AAA battery pack in my window circuit. I let that run for several more weeks as a battery test.&lt;/p&gt;

&lt;p&gt;Lithium ion batteries are really sensitive to overcharging, and you can easily ruin them that way. Most LI-charging circuits employ circuitry to cut off the charger once the battery has reached a certain float voltage. I didn&amp;#8217;t think too much overcharging would happen in my circuit, so I decided to gamble $3 and find out what would happen. So far everything seems to work fine. The LED lights up brightly after sunny days and runs for several hours. On overcast days it&amp;#8217;s somewhat dimmer and doesn&amp;#8217;t last as long. I haven&amp;#8217;t measured a battery voltage above the 3.6V rating, so I don&amp;#8217;t think it&amp;#8217;s overcharging. I guess it could be different in areas that get more intense direct sunlight for longer periods of time.&lt;/p&gt;

&lt;h2 id='making_the_first_real_prototype'&gt;Making the first real prototype&lt;/h2&gt;

&lt;p&gt;With a working circuit and a smaller battery I next built the actual prototype sun jar. Most commercial sun jars put the solar panel underneath a hinged glass lid. Since I had weatherproof solar panels that could go on the outside of a jar, I decided to go for a slightly different look, and I ordered these &lt;a href='http://www.amazon.com/gp/product/B008586UJY/ref=oh_details_o04_s00_i00?ie=UTF8&amp;amp;psc=1'&gt;8-ounce Ball Jars&lt;/a&gt; from Amazon.&lt;/p&gt;

&lt;p&gt;&lt;img alt='jar' src='https://lh6.googleusercontent.com/-vBlMKgWrqxI/UVjdu70DGHI/AAAAAAAATGE/-DhXuIj5DFk/s500/url.jpeg' /&gt;&lt;/p&gt;

&lt;p&gt;I also picked up some &lt;a href='http://www.amazon.com/gp/product/B0009XCKBA/ref=oh_details_o03_s00_i00?ie=UTF8&amp;amp;psc=1'&gt;frosted glass spray&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img alt='frosted glass spray' src='https://lh5.googleusercontent.com/-X6D4e6A4xsQ/UVjdvN9ByiI/AAAAAAAATGM/xJXylRtFUFY/s544/71-BZrK03tL._SL1500_.jpg' /&gt;&lt;/p&gt;

&lt;p&gt;I soldered a couple of wires to the solder pads on the back of the solar panel and drilled a hole in the jar lid. I routed the wires through the hole and then adhered the panel to the lid with some &lt;a href='http://www.amazon.com/gp/product/B0002UEPVI/ref=oh_details_o09_s00_i00?ie=UTF8&amp;amp;psc=1'&gt;RTV Silicone&lt;/a&gt; sealant.&lt;/p&gt;

&lt;p&gt;&lt;img alt='rtv' src='https://lh6.googleusercontent.com/-8DmflriP_C4/UVjduznTTRI/AAAAAAAATGI/6IVmMYqaB3k/s500/51qCJy1QWTL.jpg' /&gt;&lt;/p&gt;

&lt;p&gt;This stuff takes patience because you have to clamp it overnight, but it makes a good weatherproof seal, so the finished jar can be left outside.&lt;/p&gt;

&lt;p&gt;&lt;img alt='clamped lids' src='https://lh5.googleusercontent.com/-ouuDbEpzcLk/UVjUGWGjR5I/AAAAAAAATEo/BMN18G1s4GU/s730/940BF1B5-BE37-47FB-A732-C026EC78311A.JPG' /&gt;&lt;/p&gt;

&lt;p&gt;I took the other circuit components off the breadboard and soldered them down to a little piece of &lt;a href='http://www.amazon.com/gp/product/B008CG62DI/ref=oh_details_o00_s01_i00?ie=UTF8&amp;amp;psc=1'&gt;protobard&lt;/a&gt;. Once the silicone had cured on the lid I wired the solar panel to the rest of the board.&lt;/p&gt;

&lt;p&gt;&lt;img alt='completed board' src='https://lh4.googleusercontent.com/-1Xtv22QMMng/UVjTyfhashI/AAAAAAAATEc/Qrp0360izFQ/s730/7BDDAF8D-E158-4A7F-AC00-D77D46873F66.JPG' /&gt;&lt;/p&gt;

&lt;p&gt;Adhering the board to the underside of the jar lid proved pretty tricky. I couldn&amp;#8217;t get silicone to hold, so I went to hot glue. It seemed to work at first, but then popped apart a couple of hours later. These jars are made for food, and it turns out the non-stick stuff they coat the underside of the lid with is pretty damn non-stick. The third time was the charm, though. &lt;a href='http://www.amazon.com/Gorilla-Glue-50004-Adhesive-4-Ounces/dp/B0001GAYRC/ref=sr_1_1?ie=UTF8&amp;amp;qid=1364768335&amp;amp;sr=8-1&amp;amp;keywords=gorilla+glue'&gt;Gorilla glue&lt;/a&gt; held really well.&lt;/p&gt;

&lt;p&gt;The jars actually look pretty nice after being frosted with the spray. Here&amp;#8217;s one complete jar and a couple I&amp;#8217;m still working on.&lt;/p&gt;

&lt;p&gt;&lt;img alt='frosted jars' src='https://lh3.googleusercontent.com/-mpbF5m9LLkU/UVjXSKtyvAI/AAAAAAAATE0/9TCkA9CqbM0/s730/98E1C46D-9F6F-4DCA-A0D1-20C9ECE52450.JPG' /&gt;&lt;/p&gt;

&lt;p&gt;Here&amp;#8217;s how the first completed jar looks in the dark. Pretty good if I do say so myself.&lt;/p&gt;

&lt;p&gt;&lt;img alt='lit jar' src='https://lh6.googleusercontent.com/-KTQSJQDCUvk/UVjXSGFdNfI/AAAAAAAATE4/Dbla8NtCHlo/s730/316CC0CC-F068-41C0-BDC5-331349D7BA0C.JPG' /&gt;&lt;/p&gt;

&lt;h2 id='designing_a_custom_pcb'&gt;Designing a custom PCB&lt;/h2&gt;

&lt;p&gt;Building the sun jar was really fun, and I want to make a lot more with different size jars and different color LEDs, so it would be really nice to get this circuit on a PCB. That way I could just drop in the parts and solder, rather than buying more battery breakout boards and cobbling everything together on protobard.&lt;/p&gt;

&lt;p&gt;First I downloaded &lt;a href='http://www.cadsoftusa.com/download-eagle/?language=en'&gt;Eagle&lt;/a&gt;. It seemed to be the DIY community standard and Sparkfun has &lt;a href='https://github.com/sparkfun/SparkFun-Eagle-Libraries'&gt;open source Eagle libraries&lt;/a&gt; that include the battery holder wanted to use.&lt;/p&gt;

&lt;p&gt;I used these two really great tutorials, also by Sparkfun, to first create the circuit schematic and then the PCB layout.&lt;/p&gt;

&lt;p&gt;&lt;a href='https://www.sparkfun.com/tutorials/108'&gt;Eagle: Schematics&lt;/a&gt; &lt;img alt='screenshot of my schematic' src='https://lh4.googleusercontent.com/-boGZ6TuJkRw/UVjr1t3Wi_I/AAAAAAAATGU/7S-abtDulaE/s785/Screen%2520Shot%25202013-03-31%2520at%252010.04.18%2520PM.png' /&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href='https://www.sparkfun.com/tutorials/109'&gt;Eagle: PCB Layout&lt;/a&gt; &lt;img alt='screenshot of my board layout' src='https://lh5.googleusercontent.com/-dk-xBSGJ6Hk/UVjr2PLp8tI/AAAAAAAATGc/Z2R7y9SpmoI/s783/Screen%2520Shot%25202013-03-31%2520at%252010.05.06%2520PM.png' /&gt;&lt;/p&gt;

&lt;p&gt;If you&amp;#8217;d like to play with this design, you can &lt;a href='https://github.com/mattmanning/sunjar'&gt;fork it on Github&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The tutorials were really great and comprehensive. I didn&amp;#8217;t have to do much Googling outside of them to figure things out. The only real issues were that the Windows-oriented keyboard shortcuts didn&amp;#8217;t work for me on OS X, so I had to dig through the menus for a couple of things, but it wasn&amp;#8217;t too bad.&lt;/p&gt;

&lt;h2 id='fabricating_the_pcb'&gt;Fabricating the PCB&lt;/h2&gt;

&lt;p&gt;With the layouts done and &lt;a href='http://en.wikipedia.org/wiki/Gerber_format'&gt;Gerber files&lt;/a&gt; generated, I needed a place to get the PCB printed. Adafruit has some good reviews and recommendations for board houses, but even the cheapest of those charge a $35 setup fee and it looked like I might have to spend time on the phone to get the order done.&lt;/p&gt;

&lt;p&gt;Just when I started to feel discouraged, Sparkfun came to the rescue again with their brilliant &lt;a href='https://batchpcb.com/faq'&gt;BatchPCB&lt;/a&gt; service. You simply upload a zip of your Gerber files and it does some quick checks to verify the files. Once they clear, your board shows up on the Marketplace view where you can order it. The set up fee is only $10, so I&amp;#8217;ve ordered a prototype of &lt;a href='https://www.batchpcb.com/pcbs/112559'&gt;my board&lt;/a&gt; for under $20 including shipping.&lt;/p&gt;

&lt;p&gt;&lt;img alt='image of board from BatchPCB marketplace' src='https://lh6.googleusercontent.com/-RsTLMC2PiHI/UVjXxE2RPmI/AAAAAAAATFA/S2ZNB8S02jI/s700/BatchPCB+%23112559.png' /&gt;&lt;/p&gt;

&lt;p&gt;It&amp;#8217;ll take a few weeks for the first board to get to me, but if it works, I&amp;#8217;ll post an update here in case anyone wants to buy one. I think this might also make a fun &amp;#8220;learn to solder&amp;#8221; kit since it only has a few parts and they&amp;#8217;re all of the through-hole type. If you&amp;#8217;d be interested in buying a kit of these parts including a PCB, please leave a comment here or let me know at matt.manning@gmail.com.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Geospoofing with the Raspberry Pi</title>
      <link>http://mwmanning.com/2013/02/11/Geospoofing-with-the-Raspberry-Pi.html</link>
      <pubDate>Mon, 11 Feb 2013 00:00:00 +0000</pubDate>
      <author>matt.manning@gmail.com (Matt Manning)</author>
      <guid>http://mwmanning.com/2013/02/11/Geospoofing-with-the-Raspberry-Pi</guid>
      <description>&lt;p&gt;Many online services alter their content availability based on your geographic location, which they detect using your IP address. For example, some movie streaming services offer different movies to users outside of the United States, and live sports streaming services enforce regional blackouts to protect TV contracts. These types of practices violate the spirit of the free and open Internet.&lt;/p&gt;

&lt;p&gt;The good news is that you can circumvent these unfair practices using a &lt;a href='http://en.wikipedia.org/wiki/Vpn'&gt;virtual private network&lt;/a&gt; (VPN). VPN technology is used heavily in the corporate world to provide secure remote access to a local networks. A side effect of VPN usage is that outbound requests appear to originate from the VPN&amp;#8217;s IP address, rather than your own, and you can use this to your advantage to &amp;#8220;geospoof&amp;#8221; your physical location.&lt;/p&gt;

&lt;p&gt;This works great if you&amp;#8217;re spoofing on a general-purpose computing device like a laptop. You can just fire up your VPN client and go to town. But what if you want to connect a closed device, like an AppleTV, a game console, or a network-connected TV to a VPN? These devices won&amp;#8217;t let you install arbitrary software like a VPN client or let you have too much control over networking.&lt;/p&gt;

&lt;p&gt;What you need is a router on your local network that can forward traffic from these devices through a VPN. You could do this by installing open source firmware like &lt;a href='http://tomatousb.org/'&gt;TomatoUSB&lt;/a&gt; or &lt;a href='http://www.dd-wrt.com/site/index'&gt;ddwrt&lt;/a&gt; onto a hardware router, but that process can be tedious, and good hardware routers tend to be a bit pricey. I wanted something easy and inexpensive. Enter the Raspberry Pi.&lt;/p&gt;

&lt;p&gt;&lt;img alt='Raspberry Pi' src='/images/RaspberryPi.jpeg' /&gt;&lt;/p&gt;

&lt;p&gt;The &lt;a href='http://www.raspberrypi.org/faqs'&gt;Raspberry Pi&lt;/a&gt; is a credit-card sized, low power computer on a single board that costs about $35. It was originally designed to be a cheap computer for education, but it&amp;#8217;s seen a boom in the maker market, too. My friend, &lt;a href='http://www.youtube.com/watch?v=Kh2AWswAMvw'&gt;Mike&lt;/a&gt;, gave me one for Christmas, and it&amp;#8217;s been really fun to tinker with.&lt;/p&gt;

&lt;p&gt;The Raspberry Pi Foundation releases a special version of Debian Linux called &lt;a href='http://www.raspbian.org/'&gt;Raspbian&lt;/a&gt; which is optimized for the Raspberry Pi. A $35 Linux computer is hard to beat, and it can be turned into a geospoofing VPN gateway on your local network pretty easily. Here&amp;#8217;s a step-by-step guide.&lt;/p&gt;

&lt;h2 id='setting_up_the_raspberry_pi'&gt;Setting up the Raspberry Pi&lt;/h2&gt;

&lt;p&gt;First you need to start with a fresh install of Raspian. You can download it &lt;a href='http://www.raspberrypi.org/downloads'&gt;here&lt;/a&gt; and find a guide for writing the image to an SD card &lt;a href='http://elinux.org/RPi_Easy_SD_Card_Setup'&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The first time you boot the computer, you&amp;#8217;ll be taken to the configuration tool, &lt;code&gt;raspi-config&lt;/code&gt;. It looks something like this:&lt;/p&gt;

&lt;p&gt;&lt;img alt='raspi-config menu screen' src='/images/raspi-config.png' /&gt;&lt;/p&gt;

&lt;p&gt;Since you&amp;#8217;ll be using this computer as a networking device, you should change the default password for security reasons. Turning on the SSH server is also necessary unless you intend to keep the Pi hooked up to a monitor, keyboard, and mouse.&lt;/p&gt;

&lt;p&gt;Next, &lt;a href='http://www.raspberrypi-tutorials.co.uk/raspberry-pi-static-ip-address/'&gt;give your Raspberry Pi a static IP address&lt;/a&gt; outside your router&amp;#8217;s DHCP range. You&amp;#8217;ll use this address as the router or gateway when you configure the other devices on your local network.&lt;/p&gt;

&lt;p&gt;It&amp;#8217;s a good idea to upgrade all the software on your Pi using the commands:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo apt-get update
sudo apt-get upgrade&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The upgrade command will take quite a while to complete, so you might want to kick it off at night before you go to bed or before you go to work in the morning.&lt;/p&gt;

&lt;h2 id='installing_and_configuring_openvpn'&gt;Installing and configuring OpenVPN&lt;/h2&gt;

&lt;p&gt;The next step is to install a VPN client. You can install OpenVPN with the following command:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo apt-get install openvpn&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now you&amp;#8217;ll want to get access to a VPN server in a geographically beneficial area. I&amp;#8217;ve had good results with &lt;a href='https://www.privatetunnel.com'&gt;PrivateTunnel&lt;/a&gt;. The service is inexpensive, and they have servers in San Jose, Chicago, London, Zurich, and Montreal. Once you choose a server location you can download its related configuration file. Save this file on the Raspberry Pi as &lt;code&gt;/etc/openvpn/server.conf&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It&amp;#8217;s necessary to make a couple of edits to this file. So open it with &lt;code&gt;nano&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo nano /etc/openvpn/server.conf&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Right before the first certificate add the line:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;redirect-gateway&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;and further down in the file, change the line:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;dev tun&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;to:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;dev tun0&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id='configuring_iptables'&gt;Configuring iptables&lt;/h2&gt;

&lt;p&gt;Now that you have VPN software set up, the next step is to turn the Pi into a router. You can do this using the Linux utility, &lt;a href='http://wiki.debian.org/iptables'&gt;&lt;code&gt;iptables&lt;/code&gt;&lt;/a&gt;. Download &lt;a href='/share/iptables.test.rules'&gt;this file&lt;/a&gt; and save it on your Raspberry Pi as &lt;code&gt;/etc/iptables.test.rules&lt;/code&gt;. Load its rules using the command:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo iptables-restore &amp;lt; /etc/iptables.test.rules&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Normally you would now test the functionality of your iptables rules. We know that these work, so go ahead and save them into your permanent config file with the command:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo iptables-save &amp;gt; /etc/iptables.up.rules&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You want these rules to be loaded every time the Pi boots, so create a new file:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo nano /etc/network/if-pre-up.d/iptables&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;and add these lines to it:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#!/bin/bash
/sbin/iptables-restore &amp;lt; /etc/iptables.up.rules&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Make it executable:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo chmod +x /etc/network/if-pre-up.d/iptables&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id='enabling_ip_forwarding'&gt;Enabling IP forwarding&lt;/h2&gt;

&lt;p&gt;Finally, we need to enable IP forwarding by editing one more config file. Open up the file:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo nano /etc/sysctl.conf&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;and uncomment the line:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;net.ipv4.ip_forward = 1&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now reboot your Raspberry Pi with the command:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo reboot&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id='testing'&gt;Testing&lt;/h2&gt;

&lt;p&gt;If everything was done correctly, you should now be able to use the Raspberry Pi as a VPN gateway. On a computer connected to the same local network as the Pi, visit &lt;a href='http://whatismyipaddress.com/'&gt;WhatIsMyIPAddress.com&lt;/a&gt;. Note your current IP address and physical location on the map.&lt;/p&gt;

&lt;p&gt;Now, change your computer&amp;#8217;s router to the Raspberry Pi&amp;#8217;s IP address. If you don&amp;#8217;t know its address, you can find it by running the command:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ifconfig&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;on the Pi. I&amp;#8217;m on a Mac and my Pi&amp;#8217;s IP address is 10.0.1.202, so my network config looks like this:&lt;/p&gt;

&lt;p&gt;&lt;img alt='Network Preferences' src='/images/network-config.png' /&gt;&lt;/p&gt;

&lt;p&gt;If you&amp;#8217;re on Windows I think &amp;#8220;Router&amp;#8221; is called &amp;#8220;Default Gateway&amp;#8221;. Now, reload WhatIsMyIPAddress, and you should see the IP address of your VPN and its location reflected on the map. Congratulations! You&amp;#8217;re geospoofing!&lt;/p&gt;

&lt;p&gt;Now all you have to do is set the router (or gateway) on your closed devices like AppleTV and Xbox 360 to the Raspberry Pi&amp;#8217;s IP address and you can access content available only in your VPN&amp;#8217;s location.&lt;/p&gt;

&lt;p&gt;This is what my AppleTV config looked like after setting it to use the Pi as a router:&lt;/p&gt;

&lt;p&gt;&lt;img alt='Apple TV Network Config' src='/images/apple-tv.png' /&gt;&lt;/p&gt;

&lt;h2 id='using_the_gateway_selectively'&gt;Using the gateway selectively&lt;/h2&gt;

&lt;p&gt;PrivateTunnel is reasonably priced, but if you&amp;#8217;re streaming video, it&amp;#8217;s easy to use up your data transfer allotment very quickly. Luckily, many services use only a single authentication request to determine your location. If you find this to be the case with your service, you can configure OpenVPN to send requests through the VPN only to certain IP addresses.&lt;/p&gt;

&lt;p&gt;To do that, open up the config file:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo nano /etc/openvpn/server.conf&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Comment out the line:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#redirect-gateway&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;and right below it add these lines:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# Ignore routes given to us by OpenVPN Server:
route-nopull
# Route authentication IP through VPN:
route 184.72.247.194 255.255.255.255&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now restart OpenVPN:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo /etc/init.d/openvpn restart&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In this example, I&amp;#8217;ve used the IP address of another IP address checking site, &lt;a href='http://myipaddress.com'&gt;myipaddress.com&lt;/a&gt;. If you&amp;#8217;ve set everything up correctly, you should be able to reload WhatIsMyIPAddress.com and see your actual IP address, but load myipaddress.com and see the VPN&amp;#8217;s IP address. Once you get this working, you can use the route command to send requests to any IP addresses you want through the VPN!&lt;/p&gt;

&lt;h2 id='credits'&gt;Credits&lt;/h2&gt;

&lt;p&gt;I learned all the stuff to write this post from:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href='http://www.raspberrypi.org/phpBB3/viewtopic.php?f=36&amp;amp;t=19350'&gt;RPI as VPN gateway&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://wiki.debian.org/iptables'&gt;iptables - Debian Wiki&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;Bugging smart guy &lt;a href='https://github.com/bgentry'&gt;Blake Gentry&lt;/a&gt; via email&lt;/li&gt;
&lt;/ul&gt;</description>
    </item>
    
    <item>
      <title>Cloud Goodness With the DNSimple ALIAS Record</title>
      <link>http://mwmanning.com/2012/01/18/Cloud-Goodness-with-DNSimple-ALIAS-Record.html</link>
      <pubDate>Wed, 18 Jan 2012 00:00:00 +0000</pubDate>
      <author>matt.manning@gmail.com (Matt Manning)</author>
      <guid>http://mwmanning.com/2012/01/18/Cloud-Goodness-with-DNSimple-ALIAS-Record</guid>
      <description>&lt;p&gt;This is the third in a &lt;a href='/2011/11/29/Run-Your-Jekyll-Site-On-Heroku.html'&gt;series&lt;/a&gt; of &lt;a href='/2011/12/04/Jekyll-on-Heroku-Part-2.html'&gt;posts&lt;/a&gt; about setting up this Jekyll-backed blog on Heroku.&lt;/p&gt;

&lt;p&gt;Cloud computing and second-level domains a.k.a. root domains (example.com) don&amp;#8217;t play nicely together. This is because of &lt;a href='http://www.ietf.org/rfc/rfc1034.txt'&gt;RFC 1034&lt;/a&gt; section 3.6.2: &amp;#8220;If a CNAME RR is present at a node, no other data should be present; this ensures that the data for a canonical name and its aliases cannot be different.&amp;#8221; Since root domains tend to have several types of records &amp;#8211; &amp;#8220;other data&amp;#8221; &amp;#8211; like NS or MX records, you can&amp;#8217;t use a CNAME for them. That means you&amp;#8217;re left with A records, which must specify IP addresses. Hence the rub with cloud computing, which tries to abstract away servers and IP addresses.&lt;/p&gt;

&lt;p&gt;Heroku deals with root domains by providing &lt;a href='http://devcenter.heroku.com/articles/custom-domains#dns_setup'&gt;3 public IP addresses&lt;/a&gt; for routing web requests. For SSL, the extremely cloud-unfriendly &lt;a href='http://addons.heroku.com/ssl'&gt;IP-based SSL add-on&lt;/a&gt; is used, which provisions a dedicated server instance to serve your certificate. While these solutions work, they&amp;#8217;re not really optimal. For example, if Heroku ever changes those IP addresses, as would be necessary in the case of a large-scale DDoS attack, or a datacenter failure, your root domain would no longer resolve. The IP-based SSL add-on has these same downsides, plus it&amp;#8217;s a scaling bottleneck and costs $100/mo. Bummer.&lt;/p&gt;

&lt;p&gt;DNSimple has introduced a really clever mechanism for dealing with this problem, the &lt;a href='http://blog.dnsimple.com/introducing-the-alias-record/'&gt;ALIAS record&lt;/a&gt;. An ALIAS record is set up much like a CNAME, but it resolves the name it points to and returns its IP addresses as if you had set up A records for them. This provides the flexibility of a CNAME without violating the RFC. You can see it working for this site using the &lt;code&gt;host&lt;/code&gt; command:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;[~/code/blog] host mwmanning.com
mwmanning.com has address 107.20.209.232
mwmanning.com has address 107.22.180.220
mwmanning.com has address 107.20.154.48
mwmanning.com has address 107.22.181.229
mwmanning.com has address 107.22.173.156
mwmanning.com has address 50.17.208.142
mwmanning.com has address 107.22.180.255
mwmanning.com has address 107.22.178.183&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Besides the routing flexibility afforded by using an ALIAS record, you can take advantage of &lt;a href='http://devcenter.heroku.com/articles/http-routing#the_herokuappcom_http_stack'&gt;Heroku&amp;#8217;s new HTTP stack&lt;/a&gt;, which is only available at [appname].herokuapp.com, and not at the 3 IPs mentioned previously. You can also use an ALIAS record to provide SSL at your root domain without using the IP-SSL add-on. &lt;strike&gt;If you use the Endpoint SSL add-on (available in the Beta program), you can actually have SSL at your root domain for free!&lt;/strike&gt; SSL Endpoint was free in early beta, but is now priced at $20/mo. More info &lt;a href='https://devcenter.heroku.com/articles/ssl-endpoint-beta'&gt;here&lt;/a&gt;.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Jekyll on Heroku Part 2: Rack 'Em</title>
      <link>http://mwmanning.com/2011/12/04/Jekyll-on-Heroku-Part-2.html</link>
      <pubDate>Sun, 04 Dec 2011 00:00:00 +0000</pubDate>
      <author>matt.manning@gmail.com (Matt Manning)</author>
      <guid>http://mwmanning.com/2011/12/04/Jekyll-on-Heroku-Part-2</guid>
      <description>&lt;p&gt;This is a follow up to my previous post, &lt;a href='/2011/11/29/Run-Your-Jekyll-Site-On-Heroku.html'&gt;Run Your Jekyll Site On Heroku&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id='ditching_rackjekyll'&gt;Ditching rack-jekyll&lt;/h2&gt;

&lt;p&gt;The previous post we got going as a Rack app using rack-jekyll. While rack-jekyll is a good project, it does some checking that isn&amp;#8217;t really necessary since we&amp;#8217;re precompiling the site and don&amp;#8217;t need to build anything at runtime.&lt;/p&gt;

&lt;p&gt;I first tried replacing rack-jekyll with Rack::Static, but it only works with explicit filenames. For example, with rack static the URL &lt;a href=''&gt;http://mwmanning.com/index.html&lt;/a&gt; would work fine, but &lt;a href=''&gt;http://mwmanning.com&lt;/a&gt; would return a 404. Luckily I found &lt;a href='http://chriscontinanza.com/2011/06/15/Jekyll-to-heroku.html'&gt;this blog post by Chris Continanza&lt;/a&gt; which clued me in to Rack::TryStatic, which is part of &lt;a href='https://github.com/rack/rack-contrib'&gt;rack-contrib&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Making this switch is pretty easy. Just remove the rack-jekyll gem and add the rack-contrib gem, so your Gemfile looks like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;source :rubygems

gem &amp;#39;jekyll&amp;#39;
gem &amp;#39;rack-contrib&amp;#39;
gem &amp;#39;RedCloth&amp;#39;
gem &amp;#39;thin&amp;#39;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Then change your config.ru file to use Rack::TryStatic. The result should look something like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;require &amp;#39;rack/contrib/try_static&amp;#39;

use Rack::TryStatic,
    :root =&amp;gt; &amp;quot;_site&amp;quot;,
    :urls =&amp;gt; %w[/],
    :try =&amp;gt; [&amp;#39;.html&amp;#39;, &amp;#39;index.html&amp;#39;, &amp;#39;/index.html&amp;#39;]

run lambda { [404, {&amp;#39;Content-Type&amp;#39; =&amp;gt; &amp;#39;text/html&amp;#39;}, [&amp;#39;Not Found&amp;#39;]]}&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id='rewriting_urls'&gt;Rewriting URLs&lt;/h2&gt;

&lt;p&gt;One of the reasons I really wanted Rack was for rewriting URLs. That&amp;#8217;s something the Jekyll server can&amp;#8217;t do. My old blog was a Wordpress site hosted by A Small Orange, and its URL scheme was slightly different. I had a few links and some Google results pointing to my old URLs, and I didn&amp;#8217;t want to throw all of that away, so I turned to &lt;a href='https://github.com/jtrupiano/rack-rewrite'&gt;Rack::Rewrite&lt;/a&gt;. With Rack:Rewrite you get a little DSL that lets you specify routes that are either rewritten or issue redirects. Regular expressions are available for route matching, which suited my needs perfectly for supporting the old blog URL scheme.&lt;/p&gt;

&lt;p&gt;Since I don&amp;#8217;t plan to go back to the old scheme from the Wordpress blog, I dedided to use 301 - Moved Permanently redirects.&lt;/p&gt;

&lt;p&gt;I added the gem to my Gemfile:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;source :rubygems

gem &amp;#39;jekyll&amp;#39;
gem &amp;#39;rack-contrib&amp;#39;
gem &amp;#39;rack-rewrite&amp;#39;
gem &amp;#39;RedCloth&amp;#39;
gem &amp;#39;thin&amp;#39;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;and set up the appropriate redirects in my config.ru:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;require &amp;#39;rack/contrib/try_static&amp;#39;
require &amp;#39;rack/rewrite&amp;#39;

# Support links to old Wordpress site
use Rack::Rewrite do
  r301 &amp;#39;/2010/11/29/ec2-micro-instance-as-a-remote-bittorrent-client/&amp;#39;, &amp;#39;/2010/11/29/EC2-Micro-Instance-as-a-Remote-Bittorrent-Client.html&amp;#39;
  r301 &amp;#39;/2009/01/13/timemachine-ubuntu-nas/&amp;#39;, &amp;#39;/2009/01/13/TimeMachine-Ubuntu-NAS.html&amp;#39;
  r301 &amp;#39;/projects/jack-o-led/&amp;#39;, &amp;#39;/projects/jack-o-LED.html&amp;#39;
  r301 %r{/projects/(\S+)/}, &amp;#39;/projects/$1.html&amp;#39;
end

use Rack::TryStatic,
    :root =&amp;gt; &amp;quot;_site&amp;quot;,
    :urls =&amp;gt; %w[/],
    :try =&amp;gt; [&amp;#39;.html&amp;#39;, &amp;#39;index.html&amp;#39;, &amp;#39;/index.html&amp;#39;]

run lambda { [404, {&amp;#39;Content-Type&amp;#39; =&amp;gt; &amp;#39;text/html&amp;#39;}, [&amp;#39;Not Found&amp;#39;]]}&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id='caching'&gt;Caching&lt;/h2&gt;

&lt;p&gt;The final piece I wanted for my Rack app was caching. Older Heroku stacks (Aspen and Bamboo, which only support Ruby apps) use &lt;a href='https://www.varnish-cache.org/'&gt;Varnish&lt;/a&gt; and &lt;a href='http://nginx.org/'&gt;nginx&lt;/a&gt; in front of the app server and can be blazing fast. The Cedar stack does not, because they &lt;a href='http://devcenter.heroku.com/articles/http-routing#the_herokuappcom_http_stack'&gt;conflict with some advanced HTTP features it supports&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Luckily, Heroku offers a &lt;a href='http://addons.heroku.com/memcache'&gt;hosted memcache add-on&lt;/a&gt; which can be used with the Rack::Cache middleware. The free version of the add-on gives you 5MB of memory, which is pretty good for my purposes since my whole app (gems included) is only a little over 7MB. To get this working I first added the add-on with this command:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;heroku addons:add memcache:5mb&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Next, I needed a couple of gems, dalli and rack-cache. With those installed my Gemfile looked like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;source :rubygems

gem &amp;#39;dalli&amp;#39;
gem &amp;#39;jekyll&amp;#39;
gem &amp;#39;rack-cache&amp;#39;
gem &amp;#39;rack-contrib&amp;#39;
gem &amp;#39;rack-rewrite&amp;#39;
gem &amp;#39;RedCloth&amp;#39;
gem &amp;#39;thin&amp;#39;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The last bit was to set up Rack::Cache in the config.ru file.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;require &amp;#39;dalli&amp;#39;
require &amp;#39;rack/cache&amp;#39;
require &amp;#39;rack/contrib/try_static&amp;#39;
require &amp;#39;rack/rewrite&amp;#39;

$cache = Dalli::Client.new
use Rack::Cache,
  :verbose =&amp;gt; true,
  :metastore =&amp;gt; $cache,
  :entitystore =&amp;gt; $cache

# Support links to old Wordpress site
use Rack::Rewrite do
  r301 &amp;#39;/2010/11/29/ec2-micro-instance-as-a-remote-bittorrent-client/&amp;#39;, &amp;#39;/2010/11/29/EC2-Micro-Instance-as-a-Remote-Bittorrent-Client.html&amp;#39;
  r301 &amp;#39;/2009/01/13/timemachine-ubuntu-nas/&amp;#39;, &amp;#39;/2009/01/13/TimeMachine-Ubuntu-NAS.html&amp;#39;
  r301 &amp;#39;/projects/jack-o-led/&amp;#39;, &amp;#39;/projects/jack-o-LED.html&amp;#39;
  r301 %r{/projects/(\S+)/}, &amp;#39;/projects/$1.html&amp;#39;
end

use Rack::TryStatic,
    :root =&amp;gt; &amp;quot;_site&amp;quot;,
    :urls =&amp;gt; %w[/],
    :try =&amp;gt; [&amp;#39;.html&amp;#39;, &amp;#39;index.html&amp;#39;, &amp;#39;/index.html&amp;#39;]

run lambda { [404, {&amp;#39;Content-Type&amp;#39; =&amp;gt; &amp;#39;text/html&amp;#39;}, [&amp;#39;Not Found&amp;#39;]]}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I set this up without really thinking too much about it. Caching Is Good™, right? Well I decided to do a quick test with ApacheBench to see what kind of average response times I got. (If you&amp;#8217;re having trouble with ApacheBench on OS X Lion, &lt;a href='https://gist.github.com/1430691'&gt;here&amp;#8217;s how to fix it&lt;/a&gt;). First I wanted to get a baseline number without caching, so I removed that part from config.ru and ran this test on one dyno.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;[~/code/blog] ab -n 1000 -c 5 http://www.mwmanning.com/2010/11/29/EC2-Micro-Instance-as-a-Remote-Bittorrent-Client.html
This is ApacheBench, Version 2.3 &amp;lt;$Revision: 1178079 $&amp;gt;
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking www.mwmanning.com (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Completed 1000 requests
Finished 1000 requests


Server Software:        thin
Server Hostname:        www.mwmanning.com
Server Port:            80

Document Path:          /2010/11/29/EC2-Micro-Instance-as-a-Remote-Bittorrent-Client.html
Document Length:        11274 bytes

Concurrency Level:      5
Time taken for tests:   42.249 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Total transferred:      11451000 bytes
HTML transferred:       11274000 bytes
Requests per second:    23.67 [#/sec] (mean)
Time per request:       211.247 [ms] (mean)
Time per request:       42.249 [ms] (mean, across all concurrent requests)
Transfer rate:          264.68 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:       29   43  12.6     39     117
Processing:    75  168 127.0    140    1870
Waiting:       32   59  27.4     53     422
Total:        109  211 127.5    184    1913

Percentage of the requests served within a certain time (ms)
  50%    184
  66%    199
  75%    209
  80%    218
  90%    255
  95%    310
  98%    582
  99%    853
 100%   1913 (longest request)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Not bad. The average response time was about 211ms, with 2/3 of requests taking less than 200ms. Next I turned caching back on and ran the same test.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;[~/code/blog] ab -n 1000 -c 5 http://www.mwmanning.com/2010/11/29/EC2-Micro-Instance-as-a-Remote-Bittorrent-Client.html
This is ApacheBench, Version 2.3 &amp;lt;$Revision: 1178079 $&amp;gt;
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking www.mwmanning.com (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Completed 1000 requests
Finished 1000 requests


Server Software:        thin
Server Hostname:        www.mwmanning.com
Server Port:            80

Document Path:          /2010/11/29/EC2-Micro-Instance-as-a-Remote-Bittorrent-Client.html
Document Length:        11274 bytes

Concurrency Level:      5
Time taken for tests:   49.630 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Total transferred:      11593000 bytes
HTML transferred:       11274000 bytes
Requests per second:    20.15 [#/sec] (mean)
Time per request:       248.152 [ms] (mean)
Time per request:       49.630 [ms] (mean, across all concurrent requests)
Transfer rate:          228.11 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:       28   43  60.9     35    1142
Processing:    76  205 262.7    142    3830
Waiting:       41   77 140.4     59    2418
Total:        110  248 285.4    183    3932

Percentage of the requests served within a certain time (ms)
  50%    183
  66%    199
  75%    214
  80%    228
  90%    392
  95%    548
  98%    970
  99%   1279
 100%   3932 (longest request)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;What&amp;#8217;s this? Not only were the caching results not any better, the averages were slightly &lt;em&gt;worse&lt;/em&gt;. This was a bit of a facepalm moment. The main purpose of caching is to prevent calculations or database transactions being made by the web app backend, but in this case the web app backend is doing very little other than serving static files off of disk. Plus the Memcached instance being used here is network-attached, so there&amp;#8217;s some unavoidable latency in that connection. In this case serving files off of disk is faster than serving out of memory over a network connection, so I disabled caching. Hooray for the scientific method!&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Run Your Jekyll Site On Heroku</title>
      <link>http://mwmanning.com/2011/11/29/Run-Your-Jekyll-Site-On-Heroku.html</link>
      <pubDate>Tue, 29 Nov 2011 00:00:00 +0000</pubDate>
      <author>matt.manning@gmail.com (Matt Manning)</author>
      <guid>http://mwmanning.com/2011/11/29/Run-Your-Jekyll-Site-On-Heroku</guid>
      <description>&lt;p&gt;A few months back I decided I wanted to &lt;a href='http://tom.preston-werner.com/2008/11/17/blogging-like-a-hacker.html'&gt;blog like a hacker&lt;/a&gt;, so I started revamping my old Wordpress blog into a more minimal site generated by &lt;a href='http://github.com/mojombo/jekyll'&gt;Jekyll&lt;/a&gt;. You&amp;#8217;re reading the result of that work right now.&lt;/p&gt;

&lt;p&gt;I was happy with how easy Jekyll was to set up and use, and it&amp;#8217;s a relief to have my post archives as markdown files under Git version control instead of in a proprietary blog engine format in some database.&lt;/p&gt;

&lt;p&gt;One of the cool things about a Jekyll site is that you can push it to Github, and Github will serve it. Not just the source, but the actual site itself. You can see it working with this site. &lt;a href='https://github.com/mattmanning/mattmanning.github.com'&gt;Here is the source&lt;/a&gt;, and &lt;a href='http://mattmanning.github.com/'&gt;here it is running&lt;/a&gt;. While this is pretty cool, Github isn&amp;#8217;t really an app platform. I wanted to run my site on &lt;a href='http://www.heroku.com'&gt;Heroku&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Through some searching and tinkering I figured out a couple of different ways of getting my site running on Heroku. I&amp;#8217;ll share both of them here. The first method is great for its simplicity but is short on configurability and efficiency. The second method is more complicated but is performant and endlessly tweakable.&lt;/p&gt;

&lt;h2 id='method_1_running_the_jekyll_server_on_heroku'&gt;Method 1: Running the Jekyll Server on Heroku&lt;/h2&gt;

&lt;p&gt;Heroku&amp;#8217;s latest application stack, Cedar, provides an amazing amount of flexibility with some very simple configuration techniques. It makes running your Jekyll site on Heroku as simple as running it on your own computer &amp;#8211; you install some gems and run the server.&lt;/p&gt;

&lt;p&gt;I used this &lt;a href='https://github.com/markpundsack/jekyll-heroku'&gt;example app created by Mark Pundsack&lt;/a&gt; as a guide. Its REAME explains the setup process very well. Here is a simple series of steps to get up and running for free on Heroku, assuming you already have a working Jekyll site.&lt;/p&gt;

&lt;h3 id='create_a_heroku_app_on_the_cedar_stack'&gt;Create a Heroku app on the Cedar stack&lt;/h3&gt;

&lt;p&gt;From the top level of your Jekyll site&amp;#8217;s repo, create the Heroku site. This will provision the Heroku site and add a git remote named &amp;#8220;heroku&amp;#8221;.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;heroku create -s cedar&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id='install_the_gems'&gt;Install the gems&lt;/h3&gt;

&lt;p&gt;Create a Gemfile that looks like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;source :rubygems

gem &amp;#39;jekyll&amp;#39;
gem &amp;#39;RedCloth&amp;#39;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Then run:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;bundle install&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;to install the gems and create a Gemfile.lock file.&lt;/p&gt;

&lt;h3 id='configure_the_jekyll_server'&gt;Configure the Jekyll server&lt;/h3&gt;

&lt;p&gt;Apps on the Cedar stack define their process types via a &lt;a href='http://devcenter.heroku.com/articles/procfile'&gt;Procfile&lt;/a&gt;. Your Procfile needs one line defining the Jekyll server like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;web: bundle exec jekyll --server -p $PORT&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id='deploy_to_heroku'&gt;Deploy to Heroku&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;git push heroku master&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That&amp;#8217;s it! Now your Jekyll site is running on Heroku.&lt;/p&gt;

&lt;h2 id='method_2_running_your_site_as_a_rack_app'&gt;Method 2: Running Your Site As a Rack App&lt;/h2&gt;

&lt;p&gt;While the method above is simple and straightforward, it&amp;#8217;s not the ideal way to run the site. The Jekyll server isn&amp;#8217;t meant for production as it generates pages on the fly for every request. I wanted to take advantage of the real power of Jekyll, its ability to generate a static site that can be served efficiently.&lt;/p&gt;

&lt;p&gt;Instead of using the Jekyll server, I really wanted to serve my site as a Rack app. That way I could choose my own app server and have a great deal more control over things like caching using Rack middleware.&lt;/p&gt;

&lt;h3 id='setting_up_rackjekyll'&gt;Setting Up rack-jekyll&lt;/h3&gt;

&lt;p&gt;Luckily this can be done quite easily using the &lt;a href='https://github.com/adaoraul/rack-jekyll'&gt;rack-jekyll&lt;/a&gt; project. Here&amp;#8217;s how to set it up.&lt;/p&gt;

&lt;p&gt;First add the gem to your Gemfile. I also added the &lt;a href='http://code.macournoyer.com/thin/'&gt;Thin&lt;/a&gt; gem, so I could use it as my server. Now your Gemfile should look something like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;source :rubygems

gem &amp;#39;jekyll&amp;#39;
gem &amp;#39;rack-jekyll&amp;#39;
gem &amp;#39;RedCloth&amp;#39;
gem &amp;#39;thin&amp;#39;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Next set up a config.ru file that looks like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;require &amp;#39;rack/jekyll&amp;#39;

run Rack::Jekyll.new&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Finally, modify your Procfile to run your new Rack app. With Thin, mine looks like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;web: bundle exec thin start -p $PORT -e $RACK_ENV&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id='building_your_site_the_right_way'&gt;Building Your Site the Right Way&lt;/h3&gt;

&lt;p&gt;The documentation for rack-jekyll suggests building the files and then committing the _site directory to your repo before deploying to Heroku. While that will work, it&amp;#8217;s a bit messy. I really didn&amp;#8217;t want builds to be checked into version control.&lt;/p&gt;

&lt;p&gt;An alternative would have been letting Jekyll build the site on the first request to each dyno, but that&amp;#8217;s no good either, because it &lt;a href='http://www.12factor.net/build-release-run'&gt;mixes the build and run phases&lt;/a&gt;. Plus, depending on writes across multiple requests is not the intended use of Heroku&amp;#8217;s &lt;a href='http://devcenter.heroku.com/articles/dyno-isolation#ephemeral_filesystem'&gt;ephemeral writable filesystem&lt;/a&gt; and could lead to bugs.&lt;/p&gt;

&lt;p&gt;What I really needed was to build the site during Heroku&amp;#8217;s build phase. This can actually be done by leveraging a new experimental feature known as a &amp;#8220;custom buildpack.&amp;#8221; Buildpacks are the key to Heroku&amp;#8217;s polyglot platform. Each language or framework supported on Heroku such as &lt;a href='https://github.com/heroku/heroku-buildpack-ruby'&gt;Ruby&lt;/a&gt;, &lt;a href='https://github.com/heroku/heroku-buildpack-nodejs'&gt;Node.js&lt;/a&gt;, or &lt;a href='https://github.com/heroku/heroku-buildpack-clojure'&gt;Clojure&lt;/a&gt; has it&amp;#8217;s own buildpack containing the tools necessary to build an app.&lt;/p&gt;

&lt;p&gt;In a normal deployment Heroku automatically detects what buildpack to apply, but you can actually tell Heroku to use a specific buildpack. Either pass an option for it when you create the app:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;heroku create -s cedar --buildpack [URL]&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;or provide the URL for the buildpack repo using the BUILDPACK_URL config variable.&lt;/p&gt;

&lt;p&gt;Since it already had all the tools for Rack apps, I &lt;a href='https://github.com/mattmanning/heroku-buildpack-ruby-jekyll'&gt;forked the Ruby buildpack&lt;/a&gt; and added &lt;a href='https://github.com/mattmanning/heroku-buildpack-ruby-jekyll/commit/e86ac4f4e7c839b6f977ed6de22e1ecb6c94b723'&gt;a few lines&lt;/a&gt; so that my Jekyll site will be built by Heroku during slug compilation. Finally I set my BUILDPACK_URL with the following command:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;heroku config:add BUILDPACK_URL=http://github.com/mattmanning/heroku-buildpack-ruby-jekyll.git&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now when I deploy I see an extra &amp;#8220;Building jekyll site&amp;#8221; line in the output,&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;[~/code/blog] git push heroku master
Counting objects: 12, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (8/8), done.
Writing objects: 100% (8/8), 1.10 KiB, done.
Total 8 (delta 4), reused 0 (delta 0)

-----&amp;gt; Heroku receiving push
-----&amp;gt; Fetching custom build pack... done
-----&amp;gt; Ruby/Rack app detected
-----&amp;gt; Installing dependencies using Bundler version 1.1.rc
       Running: bundle install --without development:test --path vendor/bundle --binstubs bin/ --deployment
       Fetching gem metadata from http://rubygems.org/.......
       Using RedCloth (4.2.8)
       Using posix-spawn (0.3.6)
       Using albino (1.3.3)
       Using fast-stemmer (1.0.0)
       Using classifier (1.3.3)
       Using daemons (1.1.4)
       Using directory_watcher (1.4.1)
       Using eventmachine (0.12.10)
       Using kramdown (0.13.3)
       Using liquid (2.3.0)
       Using syntax (1.0.0)
       Using maruku (0.6.0)
       Using jekyll (0.11.0)
       Using rack (1.3.5)
       Using thin (1.3.1)
       Using bundler (1.1.rc)
       Your bundle is complete! It was installed into ./vendor/bundle
       Cleaning up the bundler cache.
       Building jekyll site
-----&amp;gt; Discovering process types
       Procfile declares types     -&amp;gt; web
       Default types for Ruby/Rack -&amp;gt; console, rake
-----&amp;gt; Compiled slug size is 7.2MB
-----&amp;gt; Launching... done, v47
-----&amp;gt; Deploy hooks scheduled, check output in your logs
       http://www.mwmanning.com deployed to Heroku

To git@heroku.com:mattmanning.git
   8f84bc4..9350a12  master -&amp;gt; master&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;and my site runs as a Rack app without polluting the repo with build files!&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>EC2 Micro Instance as a Remote Bittorrent Client</title>
      <link>http://mwmanning.com/2010/11/29/EC2-Micro-Instance-as-a-Remote-Bittorrent-Client.html</link>
      <pubDate>Mon, 29 Nov 2010 00:00:00 +0000</pubDate>
      <author>matt.manning@gmail.com (Matt Manning)</author>
      <guid>http://mwmanning.com/2010/11/29/EC2-Micro-Instance-as-a-Remote-Bittorrent-Client</guid>
      <description>&lt;p&gt;Bittorrent is an efficient, fault-tolerant way to distribute files across the Internet. When a file is popular, it can get shared really quickly as lots of users swarm to download and upload the file simultaneously. When a file is less popular, however, it can take hours or even days to download because of a diminished number of seeders. If you use a desktop computer that runs 24/7 and is always connected to a reliable Internet connection this is no problem, but if your primary machine is a laptop and especially if you use it on the go, slow torrents can turn into a problem.&lt;/p&gt;

&lt;p&gt;Wouldn’t it be nice if you had a remote Bittorrent client running on a reliable server somewhere? You could start a download any time from any computer, then pull down the file over a fast, reliable connection when it’s finished. You could even be nice and seed the file for a few days, all the while using (or more importantly NOT using) your laptop as normal.&lt;/p&gt;

&lt;p&gt;Amazon’s new, cheap — or in limited cases free — &amp;#8220;micro&amp;#8221; EC2 instances make this a possibility. Below you’ll find a step-by-step guide to set up your own remote bittorrent client using the Transmission application on an EC2 micro instance running Ubuntu.&lt;/p&gt;

&lt;h2 id='amazon_web_services'&gt;Amazon Web Services&lt;/h2&gt;

&lt;p&gt;First you’ll need to create an Amazon Web Services (AWS) account. If you already have an AWS account you can skip ahead to the server creation. If not head on over to &lt;a href='http://aws.amazon.com/free/'&gt;http://aws.amazon.com/free&lt;/a&gt; and sign up for an account and get your free Linux-based micro instance (this is what we’ll be using to run our client).&lt;/p&gt;

&lt;h2 id='creating_and_booting_an_instance'&gt;Creating and Booting an Instance&lt;/h2&gt;

&lt;p&gt;Now that you’re all signed up, we need to create and boot an EC2 micro instance to run our client. EC2 instances are based on Amazon Machine Image (AMI) files. For this guide, we’ll be using one of the official Ubuntu 10.4 LTS AMIs found here. You should chose a 32-bit, EBS-based AMI from a region geographically close to you. I chose ami-480df921.&lt;/p&gt;

&lt;p&gt;Once you have the ID of the AMI you want to use, create a new instance based on it. Log into the AWS management console and click on the &amp;#8220;Instances&amp;#8221; link in the left navbar, then click the &amp;#8220;Launch Instance&amp;#8221; button.&lt;/p&gt;

&lt;p&gt;&lt;a href='/images/remotebt-launch.png'&gt;&lt;img height='216' src='/images/remotebt-launch.png' width='384' /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click the &amp;#8220;Community Instances&amp;#8221; tab in the wizard that pops up and paste your AMI ID into the search field. Click the &amp;#8220;Select&amp;#8221; button next the the search result for your image.&lt;/p&gt;

&lt;p&gt;&lt;a href='/images/remotebt-ami.png'&gt;&lt;img height='198' src='/images/remotebt-ami.png' width='692' /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Change the &amp;#8220;Instance Type&amp;#8221; to &amp;#8220;Micro (t1.micro, 613 MB) and click &amp;#8220;Continue.&amp;#8221;&lt;/p&gt;

&lt;p&gt;&lt;a href='/images/remotebt-micro.png'&gt;&lt;img height='468' src='/images/remotebt-micro.png' width='698' /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click &amp;#8220;Continue&amp;#8221; on the next screen to use the default Kernel ID and RAM Disk ID.&lt;/p&gt;

&lt;p&gt;&lt;a href='/images/remotebt-kernel.png'&gt;&lt;img height='468' src='/images/remotebt-kernel.png' width='694' /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On the next screen, give your instance a name. I called mine &amp;#8220;Remote Bittorrent.&amp;#8221; Click &amp;#8220;Continue.&amp;#8221;&lt;/p&gt;

&lt;p&gt;&lt;a href='/images/remotebt-name.png'&gt;&lt;img height='468' src='/images/remotebt-name.png' width='694' /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you don’t already have a key pair set up, click the &amp;#8220;Create New Key Pair&amp;#8221; radio button and follow the directions to create a new key pair.&lt;/p&gt;

&lt;p&gt;&lt;a href='/images/remotebt-keypair.png'&gt;&lt;img height='342' src='/images/remotebt-keypair.png' width='686' /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On the next screen, click the &amp;#8220;Create a New Security Group&amp;#8221; radio button. Here we will open port 22 so we can SSH into the server for administration. Add an entry for SSH by choosing it from the select in the &amp;#8220;Application&amp;#8221; column and clicking the &amp;#8220;Add Rule&amp;#8221; button. Click &amp;#8220;Continue.&amp;#8221;&lt;/p&gt;

&lt;p&gt;&lt;a href='/images/remotebt-ssh.png'&gt;&lt;img height='468' src='/images/remotebt-ssh.png' width='694' /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally click the &amp;#8220;Launch&amp;#8221; button to start your instance. It may take a few minutes to launch your instance for the first time.&lt;/p&gt;

&lt;p&gt;&lt;a href='/images/remotebt-launch2.png'&gt;&lt;img height='468' src='/images/remotebt-launch2.png' width='688' /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Return to the management console and click &amp;#8220;Security Groups&amp;#8221; in the left navbar. Click the name of the security group we just created; we need to a few more rules to it.&lt;/p&gt;

&lt;p&gt;First we’ll open port 9091, which is the port used by the Transmission web client. To do this choose &amp;#8220;Custom&amp;#8221; from the &amp;#8220;Connection Method&amp;#8221; select box. Chose TCP as the Protocol, From Port and To Port should be 9091, and the source IP should be 0.0.0.0/0. Click the &amp;#8220;Add Rule&amp;#8221; button. If you don’t see the new rule in the list right away, click the &amp;#8220;Refresh&amp;#8221; button near the top of the page.&lt;/p&gt;

&lt;p&gt;Next we’ll open a range of ports for the actual bittorrent application to use. Again chose &amp;#8220;Custom&amp;#8221; as the Connection Method, TCP as the Protocol, 49152 as the From Port, 65535 as the To Port, and 0.0.0.0/0 as the Source IP. Click &amp;#8220;Add Rule.&amp;#8221;&lt;/p&gt;

&lt;p&gt;&lt;a href='/images/remotebt-security.png'&gt;&lt;img height='252' src='/images/remotebt-security.png' width='774' /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2 id='updateinstallation'&gt;Update/Installation&lt;/h2&gt;

&lt;p&gt;Now we’ll connect to our new server and configure all of the software we’ll be using. Click &amp;#8220;Instances&amp;#8221; in the left navbar. Select your instance and select &amp;#8220;Connect&amp;#8221; under the &amp;#8220;Instance Actions&amp;#8221; select box. Follow the directions to SSH into your server, but use the user &amp;#8220;ubuntu&amp;#8221; instead of &amp;#8220;root&amp;#8221;.&lt;/p&gt;

&lt;p&gt;&lt;a href='/images/remotebt-connect.png'&gt;&lt;img height='396' src='/images/remotebt-connect.png' width='234' /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ssh -i bittorrent.pem ubuntu@ec2-184-72-148-12.compute-1.amazonaws.com&lt;/p&gt;

&lt;p&gt;Now we’ll upgrade all of the installed packages. Issue the following commands:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ubuntu@ip-10-203-65-125:~$ sudo aptitude update
ubuntu@ip-10-203-65-125:~$ sudo aptitude upgrade&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Next, install the Transmission packages&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ubuntu@ip-10-203-65-125:~$ sudo aptitude install transmission-cli transmission-daemon&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id='configuration'&gt;Configuration&lt;/h2&gt;

&lt;p&gt;Now we want to stop transmission-daemon so we can edit its config.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ubuntu@ip-10-203-65-125:~$ sudo /etc/init.d/transmission-daemon stop&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Open the settings.json config file with your favorite editor.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ubuntu@ip-10-203-65-125:~$ sudo nano /etc/transmission-daemon/settings.json&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Save downloaded files in a more convenient place: &amp;#8220;download-dir&amp;#8221;: &amp;#8220;/home/ubuntu/Downloads&amp;#8221;&lt;/p&gt;

&lt;p&gt;Come up with a password to protect your server: &amp;#8220;rpc-password&amp;#8221;: &amp;#8220;mysecretpassword&amp;#8221;. (Don’t worry. This password will be obscured to a hash once we restart the transmission-daemon.) Turn off the rpc-whitelist so we can access this client from any IP: &amp;#8220;rpc-whitelist-enabled&amp;#8221;: false,&lt;/p&gt;

&lt;p&gt;Now start transmission-daemon back up:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ubuntu@ip-10-203-65-125:~$ sudo /etc/init.d/transmission-daemon start&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Finally, we need to create the /home/ubuntu/Downloads directory and give transmission-daemon the ability to write to it.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ubuntu@ip-10-203-65-125:~$ mkdir /home/ubuntu/Downloads/
ubuntu@ip-10-203-65-125:~$ chown ubuntu:debian-transmission /home/ubuntu/Downloads/
ubuntu@ip-10-203-65-125:~$ sudo chmod g+w /home/ubuntu/Downloads/&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And we’re done!&lt;/p&gt;

&lt;p&gt;Now point your browser at your instance on port 9091. You can find the URL by clicking on your instance in the AWS management console and checking the value of the &amp;#8220;Public DNS&amp;#8221; field. For my instance, the URL is http://ec2-184-72-148-12.compute-1.amazonaws.com:9091. You will be prompted to log in. The username is &amp;#8220;transmission&amp;#8221; (unless you changed it in settings.json) and the password is whatever password you chose in settings.json.&lt;/p&gt;

&lt;p&gt;&lt;a href='/images/remotebt-login.png'&gt;&lt;img height='198' src='/images/remotebt-login.png' width='398' /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now you have a client that you can browse to at any time on any computer. You can upload torrent files directly, or you can simply enter the URL of the torrent file and have the client do the rest.&lt;/p&gt;

&lt;p&gt;&lt;a href='/images/remotebt-dl.png'&gt;&lt;img height='216' src='/images/remotebt-dl.png' width='436' /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Amazon gets pretty decent download speeds too :)&lt;/p&gt;

&lt;p&gt;&lt;a href='/images/remotebt-speed.png'&gt;&lt;img height='162' src='/images/remotebt-speed.png' width='785' /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;script type='text/javascript'&gt;
  disqus_url = 'http://mwmanning.com/2010/11/29/ec2-micro-instance-as-a-remote-bittorrent-client/';
&lt;/script&gt;</description>
    </item>
    
    <item>
      <title>TimeMachine + Ubuntu NAS</title>
      <link>http://mwmanning.com/2009/01/13/TimeMachine-Ubuntu-NAS.html</link>
      <pubDate>Tue, 13 Jan 2009 00:00:00 +0000</pubDate>
      <author>matt.manning@gmail.com (Matt Manning)</author>
      <guid>http://mwmanning.com/2009/01/13/TimeMachine-Ubuntu-NAS</guid>
      <description>&lt;p&gt;So after a few months of hem-hawing around, I finally implemented a respectable backup solution for my Mac. It&amp;#8217;s getting old enough (almost 4 years) that I&amp;#8217;m starting to worry about random hardware failures, so having a reliable backup is very important.&lt;/p&gt;

&lt;p&gt;At home, I have a computer running Ubuntu Linux that I use as a file/media/print server. It has four 250 GB drives in a RAID5 configuration. Since RAID5 can be rebuilt if a drive dies, I feel like this is a pretty safe place to store backups, although eventually I hope to have an offsite backup (ex: Amazon S3) as well.&lt;/p&gt;

&lt;p&gt;A while back a little command that would let TimeMachine use network drive started floating around the Internet:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;defaults write com.apple.systempreferences TMShowUnsupportedNetworkVolumes 1&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I already had SAMBA set up, but I had some problems, so I ended up following this tutorial — which I highly recommend — and setting up netatalk so I could share the volume over AFP. Looking back, I don&amp;#8217;t think SAMBA was the problem, I think the issue was with creating the initial backup disk image. I had to make the image locally and copy it over, as is explained in the troubleshooting section, but after that everything worked perfectly.&lt;/p&gt;</description>
    </item>
    

  </channel> 
</rss>