<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Linux on bramp.net</title>
    <link>https://blog.bramp.net/</link>
    <description>Recent content in Linux on bramp.net</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-GB</language>
    <lastBuildDate>Sun, 12 Sep 2021 13:09:07 -0700</lastBuildDate>
    <atom:link href="https://blog.bramp.net/tags/linux/" rel="self" type="application/rss+xml" />
    
    <item>
      <title>Recovering a RAID-5 Intel Storage Matrix on Linux (without the hardware)</title>
      <link>https://blog.bramp.net/post/2021/09/12/recovering-a-raid-5-intel-storage-matrix-on-linux-without-the-hardware/</link>
      <pubDate>Sun, 12 Sep 2021 13:09:07 -0700</pubDate>
      
      <guid>https://blog.bramp.net/post/2021/09/12/recovering-a-raid-5-intel-storage-matrix-on-linux-without-the-hardware/</guid>
      <description><p>I recently found hard drives from an old RAID array I stopped using over a decade ago. I wanted to <a href="https://raid.wiki.kernel.org/index.php/RAID_Recovery">recover the data</a> from these disks, and that turned out to be more challenging than expected. This post outlines the steps, and hopefully helps someone else in future.</p>
<p>This was a four 750GB disk RAID-5 array using Intel Storage Matrix &ldquo;fake-raid&rdquo; (now called <a href="https://en.wikipedia.org/wiki/Intel_Rapid_Storage_Technology">Intel Rapid Storage Technology</a>). This is a RAID solution that uses a mix of software and hardware. I no longer have this Intel hardware, and in fact I no longer have a machine that would accept four drives. Luckily <code>mdadm</code> seems to have a pure software implementation of Intel Storage Matrix, so I hatched a plan. I would:</p>
<ol>
<li>Create disk images for each of the four drives,</li>
<li>Mount the images locally as block devices,</li>
<li>Use <code>mdadm</code> to construct an array,</li>
<li>Copy the data into my backups.</li>
</ol>
<h1 id="1-create-disk-images">1. Create disk images</h1>
<p>I have a <a href="https://www.google.com/search?q=usb+sata+adapter">USB SATA adapter</a>, and connected one drive at a time to my PC. This computer has a single local 12 TB drive, which I would store the disk images to. I start to create the disk images using:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">$ sudo dd <span class="k">if</span><span class="o">=</span>/dev/sdc <span class="nv">of</span><span class="o">=</span>1.raw
</span></span></code></pre></div><p>This worked great for the first disk, but the 2nd disk fail around the 600GB point. It seems this drive has developed bad blocks, but I kept my fingers crossed that this was still recoverable since this was RAID-5 after all. I switched up to using <a href="https://www.gnu.org/software/ddrescue/"><code>ddrescue</code></a>.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">$ sudo ddrescue /dev/sdc 2.raw 2.log --try-again --force --verbose
</span></span></code></pre></div><p>This worked great, and was able to create a full 750GB image, slowly retiring the failed blocks, recovering as much as possible. After about a week of copying I had four disk images, <code>1.raw</code>, <code>2.raw</code>, <code>3.raw</code>, <code>4.raw</code>, with only the 2nd disk having problems.</p>
<p>I now, <code>chmod -w *.raw</code> to remove write permissions to the images, helping to prevent a future step accidently altered the images.</p>
<h1 id="2-mounting-the-images">2. Mounting the images</h1>
<p>To mount the images I use <code>losetup</code> (roughly following instructions <a href="https://askubuntu.com/questions/663027/create-raid-array-of-image-files">here</a>), specifically:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">$ sudo losetup -r /dev/loop31 1.raw
</span></span><span class="line"><span class="cl">$ sudo losetup -r /dev/loop32 2.raw
</span></span><span class="line"><span class="cl">$ sudo losetup -r /dev/loop33 3.raw
</span></span><span class="line"><span class="cl">$ sudo losetup -r /dev/loop34 4.raw
</span></span></code></pre></div><p>Later I would use <code>sudo losetup -d /dev/loop3[1234]</code> to unmount these images. I then decided to inspect these drives, to see what partitions were on them:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">$ sudo fdisk -l /dev/loop31
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Disk /dev/loop31: 698.65 GiB, <span class="m">750156374016</span> bytes, <span class="m">1465149168</span> sectors
</span></span><span class="line"><span class="cl">Units: sectors of <span class="m">1</span> * <span class="nv">512</span> <span class="o">=</span> <span class="m">512</span> bytes
</span></span><span class="line"><span class="cl">Sector size <span class="o">(</span>logical/physical<span class="o">)</span>: <span class="m">512</span> bytes / <span class="m">512</span> bytes
</span></span><span class="line"><span class="cl">I/O size <span class="o">(</span>minimum/optimal<span class="o">)</span>: <span class="m">512</span> bytes / <span class="m">512</span> bytes
</span></span><span class="line"><span class="cl">Disklabel type: dos
</span></span><span class="line"><span class="cl">Disk identifier: 0xd204616a
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Device        Boot Start        End    Sectors Size Id Type
</span></span><span class="line"><span class="cl">/dev/loop31p1          <span class="m">1</span> <span class="m">4294967295</span> <span class="m">4294967295</span>   2T ee GPT
</span></span></code></pre></div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">$ sudo fdisk -l /dev/loop32
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Disk /dev/loop32: 698.65 GiB, <span class="m">750156374016</span> bytes, <span class="m">1465149168</span> sectors
</span></span><span class="line"><span class="cl">Units: sectors of <span class="m">1</span> * <span class="nv">512</span> <span class="o">=</span> <span class="m">512</span> bytes
</span></span><span class="line"><span class="cl">Sector size <span class="o">(</span>logical/physical<span class="o">)</span>: <span class="m">512</span> bytes / <span class="m">512</span> bytes
</span></span><span class="line"><span class="cl">I/O size <span class="o">(</span>minimum/optimal<span class="o">)</span>: <span class="m">512</span> bytes / <span class="m">512</span> bytes
</span></span></code></pre></div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">$ sudo fdisk -l /dev/loop33
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Disk /dev/loop33: 698.65 GiB, <span class="m">750156374016</span> bytes, <span class="m">1465149168</span> sectors
</span></span><span class="line"><span class="cl">Units: sectors of <span class="m">1</span> * <span class="nv">512</span> <span class="o">=</span> <span class="m">512</span> bytes
</span></span><span class="line"><span class="cl">Sector size <span class="o">(</span>logical/physical<span class="o">)</span>: <span class="m">512</span> bytes / <span class="m">512</span> bytes
</span></span><span class="line"><span class="cl">I/O size <span class="o">(</span>minimum/optimal<span class="o">)</span>: <span class="m">512</span> bytes / <span class="m">512</span> bytes
</span></span><span class="line"><span class="cl">Disklabel type: dos
</span></span><span class="line"><span class="cl">Disk identifier: 0x899c1289
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Device        Boot      Start        End    Sectors   Size Id Type
</span></span><span class="line"><span class="cl">/dev/loop33p1        <span class="m">33488921</span> <span class="m">4294836216</span> <span class="m">4261347296</span>     2T ee GPT
</span></span><span class="line"><span class="cl">/dev/loop33p2        <span class="m">35651584</span>   <span class="m">35651584</span>          <span class="m">0</span>     0B  <span class="m">0</span> Empty
</span></span><span class="line"><span class="cl">/dev/loop33p3               <span class="m">0</span>    <span class="m">1377535</span>    <span class="m">1377536</span> 672.6M <span class="m">12</span> Compaq diagnostics
</span></span><span class="line"><span class="cl">/dev/loop33p4      <span class="m">3071040408</span> <span class="m">3104693987</span>   <span class="m">33653580</span>    16G <span class="m">64</span> Novell Netware <span class="m">286</span>
</span></span></code></pre></div><p>Disk 1 had a single partition, disk 2 and 4 had no partitions, and the 3rd disk had four! Those partitions looked a little weird, and I wondered for a minute if I mixed up my drives, or reformatted them at some point. I tried to mount them to no success, so I just assumed the RAID added something that looked like a real partition table. So I moved onto the next step.</p>
<h1 id="3-use-mdadm-to-construct-an-array">3. Use <code>mdadm</code> to construct an array.</h1>
<p>This is where it got difficult, due to limitations of mounting local disks, and the Intel Storage Matrix support.</p>
<p>I started by asking <code>mdadm</code> to examine the images (telling it to use <code>imsm</code>):</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">$ sudo mdadm --examine -e imsm /dev/loop31
</span></span><span class="line"><span class="cl">mdadm: /dev/loop31 is not attached to Intel<span class="o">(</span>R<span class="o">)</span> RAID controller.
</span></span><span class="line"><span class="cl">mdadm: Failed to retrieve serial <span class="k">for</span> /dev/loop31
</span></span><span class="line"><span class="cl">mdadm: Failed to load all information sections on /dev/loop31
</span></span></code></pre></div><p>Well that’s not a great start. If I understand the error <code>/dev/loop31 is not attached to Intel(R) RAID controller</code> it implies I need to connect my drive (or in this case loopback disk image) via a real RAID controller. Well that defeats my whole plan. After some googling, I found this <a href="https://askubuntu.com/questions/1239082/reassemble-intel-rst-raid-on-another-mainboard">stackoverflow post</a> pointing out there is a <code>IMSM_NO_PLATFORM=1</code> environment various I could set. The messaging <code>is not attached to Intel(R) RAID controller</code> was really a warning, and had no actual bearing on the problem.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">$ sudo <span class="nv">IMSM_NO_PLATFORM</span><span class="o">=</span><span class="m">1</span> mdadm --examine -e imsm <span class="se">\
</span></span></span><span class="line"><span class="cl">  /dev/loop31 /dev/loop32 /dev/loop33 /dev/loop34
</span></span><span class="line"><span class="cl">mdadm: no recogniseable superblock on /dev/loop34
</span></span><span class="line"><span class="cl">mdadm: Cannot assemble mbr metadata on /dev/loop33
</span></span><span class="line"><span class="cl">mdadm: no recogniseable superblock on /dev/loop32
</span></span><span class="line"><span class="cl">mdadm: Cannot assemble mbr metadata on /dev/loop31
</span></span></code></pre></div><p>A new set of errors, but they did not look promising. More head scratching, and I hit a bit of a dead end. I now wondered if the drives were corrupt, making the superblocks unreadable. I decided to start to read the source code for <code>mdadm</code> to try and understand the superblock format, and see what was wrong.</p>
<p>It indicated the <a href="https://github.com/neilbrown/mdadm/blob/5f4184557a98bb641a7889e280265109c73e2f43/super-intel.c#L242">superblock</a> (the data structure containing information about the array) was two sectors from the end of the disk, starting with the string <code>Intel Raid ISM Cfg Sig. </code>.</p>
<p>Guessing that a sector is 512 bytes long, I did the following:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">$ tail -c <span class="m">1024</span> 3.raw  <span class="p">|</span> hd
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="m">00000000</span>  <span class="m">49</span> 6e <span class="m">74</span> <span class="m">65</span> 6c <span class="m">20</span> <span class="m">52</span> <span class="m">61</span>  <span class="m">69</span> <span class="m">64</span> <span class="m">20</span> <span class="m">49</span> <span class="m">53</span> 4d <span class="m">20</span> <span class="m">43</span>  <span class="p">|</span>Intel Raid ISM C<span class="p">|</span>
</span></span><span class="line"><span class="cl"><span class="m">00000010</span>  <span class="m">66</span> <span class="m">67</span> <span class="m">20</span> <span class="m">53</span> <span class="m">69</span> <span class="m">67</span> 2e <span class="m">20</span>  <span class="m">31</span> 2e <span class="m">33</span> 2e <span class="m">30</span> <span class="m">30</span> <span class="m">00</span> <span class="m">00</span>  <span class="p">|</span><span class="nb">fg</span> Sig. 1.3.00..<span class="p">|</span>
</span></span><span class="line"><span class="cl"><span class="m">00000020</span>  cc c0 3d de <span class="m">48</span> <span class="m">02</span> <span class="m">00</span> <span class="m">00</span>  <span class="m">40</span> d5 <span class="m">11</span> d4 <span class="m">09</span> ae <span class="m">19</span> <span class="m">00</span>  <span class="p">|</span>..<span class="o">=</span>.H...@.......<span class="p">|</span>
</span></span><span class="line"><span class="cl"><span class="m">00000030</span>  f8 <span class="m">11</span> <span class="m">00</span> <span class="m">00</span> <span class="m">10</span> <span class="m">00</span> <span class="m">00</span> a0  <span class="m">04</span> <span class="m">01</span> <span class="m">02</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span>  <span class="p">|</span>................<span class="p">|</span>
</span></span><span class="line"><span class="cl"><span class="m">00000040</span>  <span class="m">40</span> d5 <span class="m">11</span> d4 <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span>  <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span>  <span class="p">|</span>@...............<span class="p">|</span>
</span></span><span class="line"><span class="cl"><span class="m">00000050</span>  <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span>  <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span>  <span class="p">|</span>................<span class="p">|</span>
</span></span><span class="line"><span class="cl">*
</span></span><span class="line"><span class="cl">000000d0  <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span>  <span class="m">53</span> <span class="m">31</span> <span class="m">33</span> <span class="m">55</span> 4a <span class="m">31</span> 4b <span class="m">51</span>  <span class="p">|</span>........S13UJ1KQ<span class="p">|</span>
</span></span><span class="line"><span class="cl">000000e0  <span class="m">34</span> <span class="m">30</span> <span class="m">33</span> <span class="m">33</span> <span class="m">33</span> <span class="m">37</span> <span class="m">00</span> <span class="m">00</span>  f0 <span class="m">66</span> <span class="m">54</span> <span class="m">57</span> <span class="m">00</span> <span class="m">00</span> <span class="m">01</span> <span class="m">00</span>  <span class="p">|</span>403337...fTW....<span class="p">|</span>
</span></span><span class="line"><span class="cl">000000f0  3a <span class="m">01</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span>  <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span>  <span class="p">|</span>:...............<span class="p">|</span>
</span></span><span class="line"><span class="cl"><span class="m">00000100</span>  <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span>  <span class="m">53</span> <span class="m">31</span> <span class="m">33</span> <span class="m">55</span> 4a <span class="m">44</span> <span class="m">57</span> <span class="m">51</span>  <span class="p">|</span>........S13UJDWQ<span class="p">|</span>
</span></span><span class="line"><span class="cl"><span class="m">00000110</span>  <span class="m">33</span> <span class="m">34</span> <span class="m">36</span> <span class="m">34</span> <span class="m">35</span> <span class="m">37</span> <span class="m">00</span> <span class="m">00</span>  f0 <span class="m">66</span> <span class="m">54</span> <span class="m">57</span> <span class="m">00</span> <span class="m">00</span> <span class="m">02</span> <span class="m">00</span>  <span class="p">|</span>346457...fTW....<span class="p">|</span>
</span></span><span class="line"><span class="cl"><span class="m">00000120</span>  3a <span class="m">01</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span>  <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span>  <span class="p">|</span>:...............<span class="p">|</span>
</span></span><span class="line"><span class="cl"><span class="m">00000130</span>  <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span>  <span class="m">53</span> <span class="m">31</span> <span class="m">33</span> <span class="m">55</span> 4a <span class="m">44</span> <span class="m">57</span> <span class="m">51</span>  <span class="p">|</span>........S13UJDWQ<span class="p">|</span>
</span></span><span class="line"><span class="cl"><span class="m">00000140</span>  <span class="m">33</span> <span class="m">34</span> <span class="m">36</span> <span class="m">36</span> <span class="m">36</span> <span class="m">38</span> <span class="m">00</span> <span class="m">00</span>  f0 <span class="m">66</span> <span class="m">54</span> <span class="m">57</span> <span class="m">00</span> <span class="m">00</span> <span class="m">03</span> <span class="m">00</span>  <span class="p">|</span>346668...fTW....<span class="p">|</span>
</span></span><span class="line"><span class="cl"><span class="m">00000150</span>  3a <span class="m">01</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span>  <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span>  <span class="p">|</span>:...............<span class="p">|</span>
</span></span><span class="line"><span class="cl"><span class="m">00000160</span>  <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span>  <span class="m">53</span> <span class="m">31</span> <span class="m">33</span> <span class="m">55</span> 4a <span class="m">31</span> 4b <span class="m">51</span>  <span class="p">|</span>........S13UJ1KQ<span class="p">|</span>
</span></span><span class="line"><span class="cl"><span class="m">00000170</span>  <span class="m">34</span> <span class="m">30</span> <span class="m">33</span> <span class="m">33</span> <span class="m">32</span> <span class="m">34</span> 3a <span class="m">30</span>  <span class="m">00</span> <span class="m">66</span> <span class="m">54</span> <span class="m">57</span> ff ff ff ff  <span class="p">|</span>403324:0.fTW....<span class="p">|</span>
</span></span><span class="line"><span class="cl"><span class="m">00000180</span>  <span class="m">02</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span>  <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span>  <span class="p">|</span>................<span class="p">|</span>
</span></span><span class="line"><span class="cl"><span class="m">00000190</span>  <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span>  <span class="m">52</span> <span class="m">41</span> <span class="m">49</span> <span class="m">44</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span>  <span class="p">|</span>........RAID....<span class="p">|</span>
</span></span><span class="line"><span class="cl">000001a0  <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span>  <span class="m">00</span> f8 <span class="nb">fc</span> <span class="m">05</span> <span class="m">01</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span>  <span class="p">|</span>................<span class="p">|</span>
</span></span><span class="line"><span class="cl">000001b0  8c <span class="m">10</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span>  <span class="m">00</span> <span class="m">00</span> <span class="m">01</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span>  <span class="p">|</span>................<span class="p">|</span>
</span></span><span class="line"><span class="cl">000001c0  <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span>  <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span>  <span class="p">|</span>................<span class="p">|</span>
</span></span><span class="line"><span class="cl">*
</span></span><span class="line"><span class="cl">000001e0  <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span>  a6 a8 ae <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span>  <span class="p">|</span>................<span class="p">|</span>
</span></span><span class="line"><span class="cl">000001f0  <span class="m">00</span> <span class="m">02</span> <span class="m">00</span> ff <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span>  <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span>  <span class="p">|</span>................<span class="p">|</span>
</span></span><span class="line"><span class="cl"><span class="m">00000200</span>  <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span>  <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span>  <span class="p">|</span>................<span class="p">|</span>
</span></span><span class="line"><span class="cl">*
</span></span><span class="line"><span class="cl"><span class="m">00000400</span>
</span></span></code></pre></div><p>Boom, the super block was there, started with a valid header, and even had other fields that looked correct (e.g S13UJ1KQ being a serial number of the drive).</p>
<p>Ok, so now I’m confused about what is wrong, and I wondered if this was a bug in <code>mdadm</code>. Going back I remember the first error I got contained <code>Failed to retrieve serial</code>, and I noticed the serial numbers were in the super block (e.g S13UJ1KQ). It then occurred to me, that once I imaged the hard drives, the images don’t contain the serial numbers!</p>
<p>Inspecting the code some more, it would fail with that error if it was unable to read the drive’s serial number. The loopback device doesn’t support serial numbers, so this started to make sense. I did however found a undocumented environment variable <code>IMSM_DEVNAME_AS_SERIAL</code>, which would instead of reading the serial number from the hardware, just use the name of the device as the serial (e.g <code>/dev/loop31</code>). This feature seems explicitly designed to help testing the <code>mdadm</code> codebase.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">$ sudo <span class="nv">IMSM_DEVNAME_AS_SERIAL</span><span class="o">=</span><span class="m">1</span> <span class="nv">IMSM_NO_PLATFORM</span><span class="o">=</span><span class="m">1</span> mdadm --examine -e imsm /dev/loop31 /dev/loop32 /dev/loop33 /dev/loop34
</span></span><span class="line"><span class="cl">…
</span></span><span class="line"><span class="cl">/dev/loop31:
</span></span><span class="line"><span class="cl">          Magic : Intel Raid ISM Cfg Sig.
</span></span><span class="line"><span class="cl">        Version : 1.3.00
</span></span><span class="line"><span class="cl">    Orig Family : d411d540
</span></span><span class="line"><span class="cl">         Family : d411d540
</span></span><span class="line"><span class="cl">     Generation : 0019ae09
</span></span><span class="line"><span class="cl">     Attributes : All supported
</span></span><span class="line"><span class="cl">           UUID : ff44bc31:56060902:afb34379:b0faf183
</span></span><span class="line"><span class="cl">       Checksum : de3dc0cc correct
</span></span><span class="line"><span class="cl">    MPB Sectors : <span class="m">2</span>
</span></span><span class="line"><span class="cl">          Disks : <span class="m">4</span>
</span></span><span class="line"><span class="cl">   RAID Devices : <span class="m">1</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="o">[</span>RAID<span class="o">]</span>:
</span></span><span class="line"><span class="cl">           UUID : 676c222f:760eaf46:97bd30b8:989d2470
</span></span><span class="line"><span class="cl">     RAID Level : <span class="m">5</span>
</span></span><span class="line"><span class="cl">        Members : <span class="m">4</span>
</span></span><span class="line"><span class="cl">          Slots : <span class="o">[</span>UUU_<span class="o">]</span>
</span></span><span class="line"><span class="cl">    Failed disk : <span class="m">3</span>
</span></span><span class="line"><span class="cl">      This Slot : ?
</span></span><span class="line"><span class="cl">    Sector Size : <span class="m">512</span>
</span></span><span class="line"><span class="cl">     Array Size : <span class="m">4395431936</span> <span class="o">(</span>2095.91 GiB 2250.46 GB<span class="o">)</span>
</span></span><span class="line"><span class="cl">   Per Dev Size : <span class="m">1465144328</span> <span class="o">(</span>698.64 GiB 750.15 GB<span class="o">)</span>
</span></span><span class="line"><span class="cl">  Sector Offset : <span class="m">0</span>
</span></span><span class="line"><span class="cl">    Num Stripes : <span class="m">11446438</span>
</span></span><span class="line"><span class="cl">     Chunk Size : <span class="m">64</span> KiB
</span></span><span class="line"><span class="cl">       Reserved : <span class="m">0</span>
</span></span><span class="line"><span class="cl">  Migrate State : idle
</span></span><span class="line"><span class="cl">      Map State : degraded
</span></span><span class="line"><span class="cl">    Dirty State : clean
</span></span><span class="line"><span class="cl">     RWH Policy : off
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  Disk00 Serial : S13UJ1KQ403337
</span></span><span class="line"><span class="cl">          State : active
</span></span><span class="line"><span class="cl">             Id : <span class="m">00010000</span>
</span></span><span class="line"><span class="cl">    Usable Size : <span class="m">1465138766</span> <span class="o">(</span>698.63 GiB 750.15 GB<span class="o">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  Disk01 Serial : S13UJDWQ346457
</span></span><span class="line"><span class="cl">          State : active
</span></span><span class="line"><span class="cl">             Id : <span class="m">00020000</span>
</span></span><span class="line"><span class="cl">    Usable Size : <span class="m">1465138766</span> <span class="o">(</span>698.63 GiB 750.15 GB<span class="o">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  Disk02 Serial : S13UJDWQ346668
</span></span><span class="line"><span class="cl">          State : active
</span></span><span class="line"><span class="cl">             Id : <span class="m">00030000</span>
</span></span><span class="line"><span class="cl">    Usable Size : <span class="m">1465138766</span> <span class="o">(</span>698.63 GiB 750.15 GB<span class="o">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  Disk03 Serial : S13UJ1KQ403324:0
</span></span><span class="line"><span class="cl">          State : active
</span></span><span class="line"><span class="cl">             Id : ffffffff
</span></span><span class="line"><span class="cl">    Usable Size : <span class="m">1465138526</span> <span class="o">(</span>698.63 GiB 750.15 GB<span class="o">)</span>
</span></span></code></pre></div><p>Ok, slowly making progress! Now it lists all the superblock information, and I was happy to see <code>Checksum : de3dc0cc correct</code>, etc. However, it listed <code>Failed disk : 3</code>, and <code>This Slot : ?</code>. It made me think without the valid serial numbers, it didn’t know which drive was which, and thus couldn’t assemble the array.</p>
<blockquote>
<p>This made me ponder that if I was ever going to create a RAID array implementation, I would not make it depend on information from the hardware. How do folks re-image disks? What is wrong with some GUID in the superblock to identify the disk? Ok digression aside.</p>
</blockquote>
<p>To move forward, I needed to trick <code>mdadm</code> to think that serial <code>/dev/loop31</code> was actually the real hardware. I went back to my drives, and visibility inspected them to check the serial numbers.</p>
<pre tabindex="0"><code>  Disk00 Serial : S13UJ1KQ403337   1.raw
  Disk01 Serial : S13UJDWQ346457   2.raw
  Disk02 Serial : S13UJDWQ346668   4.raw
  Disk03 Serial : S13UJ1KQ403324   3.raw
</code></pre><p>At this point, I realised I had accidentally swapped drives 3 and 4. Quickly renaming them got them into the correct order.</p>
<p>Since I had already looked over the mdadm source code, it seemed a simple clean codebase, so I decided to change it to accept serial numbers. After a little while I did the hackiest thing possible:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-diff" data-lang="diff"><span class="line"><span class="cl"><span class="gh">diff --git a/super-intel.c b/super-intel.c
</span></span></span><span class="line"><span class="cl"><span class="gh">index da376251..d466d911 100644
</span></span></span><span class="line"><span class="cl"><span class="gd">--- a/super-intel.c
</span></span></span><span class="line"><span class="cl"><span class="gi">+++ b/super-intel.c
</span></span></span><span class="line"><span class="cl"><span class="gu">@@ -3994,6 +3994,20 @@ static int nvme_get_serial(int fd, void *buf, size_t buf_len)
</span></span></span><span class="line"><span class="cl">        if (!name)
</span></span><span class="line"><span class="cl">                return 1;
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="gi">+       if (strcmp(name, &#34;loop31&#34;) == 0) {
</span></span></span><span class="line"><span class="cl"><span class="gi">+               strcpy((char *)buf, &#34;S13UJ1KQ403337&#34;);
</span></span></span><span class="line"><span class="cl"><span class="gi">+               return 0;
</span></span></span><span class="line"><span class="cl"><span class="gi">+       } else if (strcmp(name, &#34;loop32&#34;) == 0) {
</span></span></span><span class="line"><span class="cl"><span class="gi">+               strcpy((char *)buf, &#34;S13UJDWQ346457&#34;);
</span></span></span><span class="line"><span class="cl"><span class="gi">+               return 0;
</span></span></span><span class="line"><span class="cl"><span class="gi">+       } else if (strcmp(name, &#34;loop33&#34;) == 0) {
</span></span></span><span class="line"><span class="cl"><span class="gi">+               strcpy((char *)buf, &#34;S13UJDWQ346668&#34;);
</span></span></span><span class="line"><span class="cl"><span class="gi">+               return 0;
</span></span></span><span class="line"><span class="cl"><span class="gi">+       } else if (strcmp(name, &#34;loop34&#34;) == 0) {
</span></span></span><span class="line"><span class="cl"><span class="gi">+               strcpy((char *)buf, &#34;S13UJ1KQ403324&#34;);
</span></span></span><span class="line"><span class="cl"><span class="gi">+               return 0;
</span></span></span><span class="line"><span class="cl"><span class="gi">+       }
</span></span></span><span class="line"><span class="cl"><span class="gi">+
</span></span></span><span class="line"><span class="cl">        if (strncmp(name, &#34;nvme&#34;, 4) != 0)
</span></span><span class="line"><span class="cl">                return 1;
</span></span></code></pre></div><p>The <code>nvme_get_serial</code> function now had hard coded serial numbers when reading loop3[1234]. This obviously isn’t a generalised solution, but worked for me. Go open source!.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">$ make mdadm
</span></span><span class="line"><span class="cl">…
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">$ sudo <span class="nv">IMSM_NO_PLATFORM</span><span class="o">=</span><span class="m">1</span> ./mdadm --examine -e imsm /dev/loop31 /dev/loop32 /dev/loop33 /dev/loop34
</span></span></code></pre></div><p>Examine looked good, so the moment of truth, let’s assemble.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">$ sudo <span class="nv">IMSM_NO_PLATFORM</span><span class="o">=</span><span class="m">1</span> ./mdadm --assemble --readonly -e imsm /dev/md0 /dev/loop31 /dev/loop32 /dev/loop33 /dev/loop34
</span></span><span class="line"><span class="cl">mdadm: Container /dev/md0 has been assembled with <span class="m">3</span> drives
</span></span></code></pre></div><p>Ok mixed success, it says 3 drives, but I would expect 4… But let’s keep going</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">$ sudo ./mdadm --assemble --scan
</span></span><span class="line"><span class="cl">mdadm: Started /dev/md/RAID_0 with <span class="m">3</span> devices
</span></span></code></pre></div><p>W00t! It Started without errors!</p>
<p>I now have a <code>/dev/md0</code>, <code>/dev/md127</code> and <code>/dev/md127p1</code> devices.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">$ sudo mount -o ro /dev/md127p1 /mnt/raid5
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">$ ls /mnt/raid5
</span></span><span class="line"><span class="cl">… lots of old files...
</span></span></code></pre></div><p>YAY. Finished!</p>
<p>Ok, I’m not sure why it says three drives not four.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">$ sudo ./mdadm --detail /dev/md127
</span></span><span class="line"><span class="cl">/dev/md127:
</span></span><span class="line"><span class="cl">         Container : /dev/md0, member <span class="m">0</span>
</span></span><span class="line"><span class="cl">        Raid Level : raid5
</span></span><span class="line"><span class="cl">        Array Size : <span class="m">2197715968</span> <span class="o">(</span>2.05 TiB 2.25 TB<span class="o">)</span>
</span></span><span class="line"><span class="cl">     Used Dev Size : <span class="m">732572032</span> <span class="o">(</span>698.64 GiB 750.15 GB<span class="o">)</span>
</span></span><span class="line"><span class="cl">      Raid Devices : <span class="m">4</span>
</span></span><span class="line"><span class="cl">     Total Devices : <span class="m">3</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">             State : clean, degraded
</span></span><span class="line"><span class="cl">    Active Devices : <span class="m">3</span>
</span></span><span class="line"><span class="cl">   Working Devices : <span class="m">3</span>
</span></span><span class="line"><span class="cl">    Failed Devices : <span class="m">0</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">            Layout : left-asymmetric
</span></span><span class="line"><span class="cl">        Chunk Size : 64K
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Consistency Policy : resync
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">              UUID : 676c222f:760eaf46:97bd30b8:989d2470
</span></span><span class="line"><span class="cl">    Number   Major   Minor   RaidDevice State
</span></span><span class="line"><span class="cl">       <span class="m">2</span>       <span class="m">7</span>       <span class="m">31</span>        <span class="m">0</span>      active sync   /dev/loop31
</span></span><span class="line"><span class="cl">       <span class="m">1</span>       <span class="m">7</span>       <span class="m">32</span>        <span class="m">1</span>      active sync   /dev/loop32
</span></span><span class="line"><span class="cl">       <span class="m">0</span>       <span class="m">7</span>       <span class="m">33</span>        <span class="m">2</span>      active sync   /dev/loop33
</span></span><span class="line"><span class="cl">       -       <span class="m">0</span>        <span class="m">0</span>        <span class="m">3</span>      removed
</span></span></code></pre></div><p>This does seem to imply a drive is missing. Maybe it doesn’t matter, as it mounted successfully, and I can copy all my data off the array.</p>
<h1 id="conclusion">Conclusion</h1>
<p>This did not seem the easiest task, and there were a few road bumps along the way. Hopefully the hacks in here will help someone else out in a similar situation.</p>
<p>To finally clean up, you can run this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">$ sudo umount /mnt/raid5
</span></span><span class="line"><span class="cl">$ sudo mdadm --stop /dev/md127
</span></span><span class="line"><span class="cl">$ sudo mdadm --stop /dev/md0
</span></span><span class="line"><span class="cl">$ sudo losetup -d /dev/loop3<span class="o">[</span>1234<span class="o">]</span>
</span></span></code></pre></div></description>
    </item>
    
    <item>
      <title>Certbot: Unexpected Error</title>
      <link>https://blog.bramp.net/post/2018/05/26/certbot-unexpected-error/</link>
      <pubDate>Sat, 26 May 2018 11:28:44 -0700</pubDate>
      
      <guid>https://blog.bramp.net/post/2018/05/26/certbot-unexpected-error/</guid>
      <description><p>I got a <a href="https://letsencrypt.org/docs/expiration-emails/">nice warning email</a> from <a href="https://letsencrypt.org/">Let&rsquo;s Encrypt</a> that my cert was going to expire soon, and hadn&rsquo;t been renewed. I found in  <code>/var/log/letsencrypt/letsencrypt.log</code> the following error:</p>
<pre tabindex="0"><code>Renewal configuration file /etc/letsencrypt/renewal/mydomain.bramp.net.conf (cert: mydomain.bramp.net) produced an unexpected error: &#39;Namespace&#39; object has no attribute &#39;dns_cloudflare_credentials&#39;. Skipping.
</code></pre><p>I manually ran certbot in dry-run mode and it worked fine:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">$ sudo certbot renew --dry-run
</span></span></code></pre></div><p>So this error only occurs when certbot is running as a cron job. Looking at <code>/etc/cron.d/certbot</code> I see the user runs as root, so I tried the <code>certbot renew --dry-run</code> again, but this time as the root user:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">$ sudo su
</span></span><span class="line"><span class="cl">root@:~$ sudo certbot renew --dry-run
</span></span></code></pre></div><p>and bam, the same error. This error somehow related to the <a href="https://certbot-dns-cloudflare.readthedocs.io/en/latest/">certbot-dns-cloudflare plugin</a>, which proves the ownership of the domain with a <a href="https://acme-python.readthedocs.io/en/latest/api/challenges.html#acme.challenges.DNS01">DNS01 challenge</a> via Cloudflare&rsquo;s DNS. I use this form of challenge, because the domain in question is internal and not available on the Internet.</p>
<p>I had forgotten how I installed the plugin, but searching Google, it seems to be via <code>pip3</code>. Clearly something was different between my root and normal user w/ sudo environments. So I did the following</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">$ sudo pip3 list <span class="p">|</span> grep certbot
</span></span><span class="line"><span class="cl">certbot <span class="o">(</span>0.23.0<span class="o">)</span>
</span></span><span class="line"><span class="cl">certbot-apache <span class="o">(</span>0.23.0<span class="o">)</span>
</span></span><span class="line"><span class="cl">certbot-dns-cloudflare <span class="o">(</span>0.24.0<span class="o">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">$ sudo su
</span></span><span class="line"><span class="cl">root@:~$ pip3 list <span class="p">|</span> grep certbot
</span></span><span class="line"><span class="cl">certbot <span class="o">(</span>0.23.0<span class="o">)</span>
</span></span><span class="line"><span class="cl">certbot-apache <span class="o">(</span>0.23.0<span class="o">)</span>
</span></span></code></pre></div><p>Aha, no certbot-dns-cloudflare when running as root. Clearly I hadn&rsquo;t installed this correctly. Running <code>pip3 install certbot-dns-cloudflare</code> as root fixed the problem, and voila, certbot correctly fetches new certs via a regular cron.</p>
</description>
    </item>
    
    <item>
      <title>pt-kill CentOS init.d script</title>
      <link>https://blog.bramp.net/post/2012/09/30/pt-kill-centos-init.d-script/</link>
      <pubDate>Sun, 30 Sep 2012 00:00:00 +0000</pubDate>
      
      <guid>https://blog.bramp.net/post/2012/09/30/pt-kill-centos-init.d-script/</guid>
      <description><p><a href="http://www.percona.com/doc/percona-toolkit/2.1/pt-kill.html">pt-kill</a> is a neat little application that can stop long running MySQL queries. It was formally know as <a href="http://www.maatkit.org/doc/mk-kill.html">mk-kill</a> before <a href="http://www.Percona.com">Percona</a> took over the project. Here is the init.d script I use (as one doesn’t seem provided by the project):</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="cp">#!/bin/sh
</span></span></span><span class="line"><span class="cl"><span class="c1">#</span>
</span></span><span class="line"><span class="cl"><span class="c1"># pt-kill	This shell script takes care of starting and stopping</span>
</span></span><span class="line"><span class="cl"><span class="c1">#               the pt-kill services.</span>
</span></span><span class="line"><span class="cl"><span class="c1">#</span>
</span></span><span class="line"><span class="cl"><span class="c1"># chkconfig: - 60 20</span>
</span></span><span class="line"><span class="cl"><span class="c1"># description: pt-kill stops long running MySQL queries</span>
</span></span><span class="line"><span class="cl"><span class="c1">#</span>
</span></span><span class="line"><span class="cl"><span class="c1"># probe: true</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Source function library.</span>
</span></span><span class="line"><span class="cl">. /etc/rc.d/init.d/functions
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nv">RETVAL</span><span class="o">=</span><span class="m">0</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># See how we were called.</span>
</span></span><span class="line"><span class="cl"><span class="k">case</span> <span class="s2">&#34;</span><span class="nv">$1</span><span class="s2">&#34;</span> in
</span></span><span class="line"><span class="cl">  start<span class="o">)</span>
</span></span><span class="line"><span class="cl">    <span class="nb">echo</span> -n <span class="s2">$&#34;Starting pt-kill: &#34;</span>
</span></span><span class="line"><span class="cl"> 
</span></span><span class="line"><span class="cl">    pt-kill <span class="se">\
</span></span></span><span class="line"><span class="cl">      --pid /var/run/pt-kill.pid <span class="se">\
</span></span></span><span class="line"><span class="cl">      --daemonize <span class="se">\
</span></span></span><span class="line"><span class="cl">      --interval <span class="m">5</span> <span class="se">\
</span></span></span><span class="line"><span class="cl">      --busy-time <span class="m">60</span> <span class="se">\
</span></span></span><span class="line"><span class="cl">      --wait-after-kill <span class="m">15</span>  <span class="se">\
</span></span></span><span class="line"><span class="cl">      --ignore-info <span class="s1">&#39;(?i-smx:^insert|^update|^delete|^load)&#39;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl">      --match-info <span class="s1">&#39;(?i-xsm:select)&#39;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl">      --ignore-user <span class="s1">&#39;(?i-xsm:root)&#39;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl">      --log /var/log/mysql-kill.log <span class="se">\
</span></span></span><span class="line"><span class="cl">      --print <span class="se">\
</span></span></span><span class="line"><span class="cl">      --execute-command <span class="s1">&#39;(echo &#34;Subject: pt-kill query found on `hostname`&#34;; tail -1 /var/log/mysql-kill.log)|/usr/sbin/sendmail -t you@example.com&#39;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl">      --kill-query
</span></span><span class="line"><span class="cl"> 
</span></span><span class="line"><span class="cl">    <span class="nv">RETVAL</span><span class="o">=</span><span class="nv">$?</span>
</span></span><span class="line"><span class="cl">    <span class="nb">echo</span>
</span></span><span class="line"><span class="cl">    <span class="o">[</span> <span class="nv">$RETVAL</span> -ne <span class="m">0</span> <span class="o">]</span> <span class="p">&amp;</span><span class="c1">#038;&amp;#038; exit $RETVAL</span>
</span></span><span class="line"><span class="cl"> 
</span></span><span class="line"><span class="cl">  <span class="p">;;</span>
</span></span><span class="line"><span class="cl">  stop<span class="o">)</span>
</span></span><span class="line"><span class="cl">        <span class="c1"># Stop daemons.</span>
</span></span><span class="line"><span class="cl">       	<span class="nb">echo</span> -n <span class="s2">$&#34;Shutting down pt-kill: &#34;</span>
</span></span><span class="line"><span class="cl">        killproc pt-kill
</span></span><span class="line"><span class="cl">        <span class="nb">echo</span>
</span></span><span class="line"><span class="cl">	<span class="p">;;</span>
</span></span><span class="line"><span class="cl">  restart<span class="o">)</span>
</span></span><span class="line"><span class="cl">	<span class="nv">$0</span> stop
</span></span><span class="line"><span class="cl">        <span class="nv">$0</span> start
</span></span><span class="line"><span class="cl">        <span class="p">;;</span>
</span></span><span class="line"><span class="cl">  *<span class="o">)</span>
</span></span><span class="line"><span class="cl">    	<span class="nb">echo</span> <span class="s2">$&#34;Usage: pt-kill {start|stop}&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="nv">RETVAL</span><span class="o">=</span><span class="m">3</span>
</span></span><span class="line"><span class="cl">        <span class="p">;;</span>
</span></span><span class="line"><span class="cl"><span class="k">esac</span>
</span></span><span class="line"><span class="cl"> 
</span></span><span class="line"><span class="cl"><span class="nb">exit</span> <span class="nv">$RETVAL</span>
</span></span></code></pre></div><p><strong>Usage:</strong></p>
<p>Create the script as /etc/init.d/pt-kill, and change the pt-kill command in the middle of the script to suit your needs. Then run ‘chkconfig –level 345 pt-kill on’ to ensure this script starts up at boot. Alternatively test the script with ‘/etc/init.d/pt-kill start’ or ‘/etc/init.d/pt-kill stop’.</p>
<p>Thanks to <a href="http://www.mysqldiary.com/you-must-have-a-killer-in-your-system/">MySQL Diary</a> as they provided their default pt-kill command line. Perhaps in future someone could create a more generic startup script.</p></description>
    </item>
    
    <item>
      <title>Hacking Linksys E4200v2 firmware</title>
      <link>https://blog.bramp.net/post/2012/01/24/hacking-linksys-e4200v2-firmware/</link>
      <pubDate>Tue, 24 Jan 2012 00:00:00 +0000</pubDate>
      
      <guid>https://blog.bramp.net/post/2012/01/24/hacking-linksys-e4200v2-firmware/</guid>
      <description><p>In a previous post I <a href="/post/2012/01/22/obtaining-the-firmware-for-linksys-e4200v2/">obtained the Linksys E4200v2 firmware</a>, now I plan to break it apart and see what I can find.</p>
<p>I start off by simplying using “file” on the firmware:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">$ file FW_E4200_2.0.36.126507.SSA 
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">FW_E4200_2.0.36.126507.SSA: u-boot legacy uImage, Linux-2.6.35.8, Linux/ARM, OS Kernel Image <span class="o">(</span>Not compressed<span class="o">)</span>, <span class="m">2677476</span> bytes, Thu Dec <span class="m">22</span> 19:40:21 2011, Load Address: 0x00008000, Entry Point: 0x00008000, Header CRC: 0x6ADD9801, Data CRC: 0xB010442D
</span></span></code></pre></div><p>Well this is a great start. We know we are dealing with Linux, and that this is a normal uImage. I then move on to use a neat little tool called <a href="https://github.com/devttys0/binwalk">binwalk</a>. By using libmagic, binwalk tries to find interesting sections of the file.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">$ /usr/local/bin/binwalk FW_E4200_2.0.36.126507.SSA 
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">DECIMAL   	HEX       	DESCRIPTION
</span></span><span class="line"><span class="cl">-------------------------------------------------------------------------------------------------------
</span></span><span class="line"><span class="cl"><span class="m">0</span>         	0x0       	uImage header, header size: <span class="m">64</span> bytes, header CRC: 0x6ADD9801, created: Thu Dec <span class="m">22</span> 19:40:21 2011, image size: <span class="m">2677476</span> bytes, Data Address: 0x8000, Entry Point: 0x8000, data CRC: 0xB010442D, OS: Linux, CPU: ARM, image type: OS Kernel Image, compression type: none, image name: Linux-2.6.35.8
</span></span><span class="line"><span class="cl"><span class="m">1124</span>      	0x464     	LZMA compressed data, properties: 0x87, dictionary size: <span class="m">250216448</span> bytes, uncompressed size: <span class="m">14786800</span> bytes
</span></span><span class="line"><span class="cl"><span class="m">16636</span>     	0x40FC    	gzip compressed data, from Unix, last modified: Thu Dec <span class="m">22</span> 19:40:18 2011, max compression
</span></span><span class="line"><span class="cl"><span class="m">2752512</span>   	0x2A0000  	JFFS2 filesystem data little endian, JFFS node length: <span class="m">49</span>
</span></span><span class="line"><span class="cl">..A whole lot of JFFS2 sections..
</span></span><span class="line"><span class="cl"><span class="m">20974612</span>  	0x1400C14 	JFFS2 filesystem data little endian, JFFS node length: <span class="m">51</span>
</span></span><span class="line"><span class="cl"><span class="m">20974664</span>  	0x1400C48 	JFFS2 filesystem data little endian, JFFS node length: <span class="m">193</span>
</span></span></code></pre></div><p>We find a small LZMA section, and large gzip section, and lots of JFFS2 sections. JFFS2 is a popular embedded file system, so we can guess the bulk of the file system is here. Next we can extract each section using dd:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">dd <span class="nv">bs</span><span class="o">=</span><span class="m">1</span> <span class="nv">skip</span><span class="o">=</span><span class="m">1124</span>  <span class="nv">count</span><span class="o">=</span><span class="m">15512</span>   <span class="k">if</span><span class="o">=</span>FW_E4200_2.0.36.126507.SSA <span class="nv">of</span><span class="o">=</span>image-1.lzma
</span></span><span class="line"><span class="cl">dd <span class="nv">bs</span><span class="o">=</span><span class="m">1</span> <span class="nv">skip</span><span class="o">=</span><span class="m">16636</span> <span class="nv">count</span><span class="o">=</span><span class="m">2735876</span> <span class="k">if</span><span class="o">=</span>FW_E4200_2.0.36.126507.SSA <span class="nv">of</span><span class="o">=</span>image-2.gz
</span></span><span class="line"><span class="cl">dd <span class="nv">bs</span><span class="o">=</span><span class="m">1</span> <span class="nv">skip</span><span class="o">=</span><span class="m">2752512</span> <span class="k">if</span><span class="o">=</span>FW_E4200_2.0.36.126507.SSA <span class="nv">of</span><span class="o">=</span>image-3.jffs2
</span></span></code></pre></div><p>Notice we are using a block size of 1 (so we can count in bytes), and we skip the offset into the file. Then we manually work out the sizes for the lzma and gzip sections. They can be no larger than their start until the next section. If they don’t fill that full space, then not to worry as these tools will normally ignore trailing data.</p>
<p>As I’m interested to see what’s in the JFFS filesystem, we should mount it. You can’t mount JFFS like a normal loopback device, you have to create a fake flash device. The following set of command can solve that:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo modprobe mtdram <span class="nv">total_size</span><span class="o">=</span><span class="m">32768</span> <span class="nv">erase_size</span><span class="o">=</span><span class="m">256</span>
</span></span><span class="line"><span class="cl">sudo modprobe mtdblock
</span></span><span class="line"><span class="cl">sudo modprobe mtdchar
</span></span><span class="line"><span class="cl"><span class="c1"># sudo mknod /dev/mtdblock0 b 31 0</span>
</span></span><span class="line"><span class="cl">dd <span class="k">if</span><span class="o">=</span>image-3.jffs2 <span class="nv">of</span><span class="o">=</span>/dev/mtdblock0
</span></span><span class="line"><span class="cl">mount -t jffs2 /dev/mtdblock0 /mnt/disk
</span></span></code></pre></div><p>The mknod line is only needed if you don’t already have a /dev/mtdblock0. Also a /mnt/disk needs to be created ahead of time so the mounting works. Anyway once that was done, I cd /mnt/disk and found that it does appear to contain most of the file system. There are all the HTML pages, and binaries (for example busybox).</p>
<p>Now we should go back to image-1.lzma and image-2.gz. Well straight away trying to decompress image-1</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">$ lzma -dc image-1.lzma &gt; image-1
</span></span><span class="line"><span class="cl">lzma: Decoder error
</span></span></code></pre></div><p>results in a error. So we can assume that was a incorrectly detected by binwalk. Lets now try and decompress image-2.gz:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">$ gzip -dc image-2.gz &gt; image-2
</span></span><span class="line"><span class="cl">gzip: image-2.gz: decompression OK, trailing garbage ignored
</span></span></code></pre></div><p>So that does indeed produce a large image-2 file, so we can ignore the trailing garbage warning. A quick “file” on image-2 doesn’t reveal anything useful, so I run binwalk on it. This turns up a set of false positives. So I take a different approach. I run:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">$ strings image-2
</span></span></code></pre></div><p>This produces a whole host of valid looking strings. From the contents of the strings it makes me think it’s the actual kernel. A line like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">Linux version 2.6.35.8 (root@ubuntu) (gcc version 4.2.0 20070413 (prerelease) (CodeSourcery Sourcery G++ Lite 2007q1-21)) #1 Thu Dec 22 16:40:10 PST 2011
</span></span></code></pre></div><p>helps me come to that conclusion.</p>
<p>I haven’t finished poking around image-2.gz, but I suspect the interesting parts are mostly in the JFFS2 filesystem. Hopefully this will lead to me getting ssh access to the router, and eventually being able to customise the firmware.</p>
</description>
    </item>
    
    <item>
      <title>Obtaining the firmware for Linksys E4200v2</title>
      <link>https://blog.bramp.net/post/2012/01/22/obtaining-the-firmware-for-linksys-e4200v2/</link>
      <pubDate>Sun, 22 Jan 2012 00:00:00 +0000</pubDate>
      
      <guid>https://blog.bramp.net/post/2012/01/22/obtaining-the-firmware-for-linksys-e4200v2/</guid>
      <description><p>I recently got a Linksys E4200v2 wireless router. It’s pretty cool, supports IPv6, 2.4Ghz and 5Ghz wifi networks, VPN, etc. The one downside is that the firmware for the router is not available from <a href="http://homesupport.cisco.com/en-us/wireless/linksys/E4200">Linksys’s website</a>, and the <a href="http://homesupport.cisco.com/en-us/gplcodecenter">GPL code</a> has not been made available, yet… However, the router has been able to pull updates itself from the Internet.</p>
<p>So I wanted to acquire the firmware to see if I could do something fun with the router. I set about to figure out how the router does this. My plan was to set my laptop up between Internet interface on the router, and the cable modem. Since my laptop doesn’t have two network cards, I plugged into a switch and used <a href="http://ettercap.sourceforge.net/">Ethercap</a> to ARP poison to redirect traffic via the laptop.</p>
<p>Then using <a href="http://www.wireshark.org/">Wireshark</a> I could see the traffic coming out of the router. All I needed to do now was to hit the “check for updates button”.</p>
<p>Firstly I saw two DNS requests, one for the AAAA (IPv6) record for update.linksys.com, then a A request for update.linksys.com. Clearly the updates are coming from there. Secondly I saw a HTTPS connection form to that domain. That makes this a little more complex, as I am unable to see the encrypted traffic, and thus see what is being transferred.</p>
<p>So, I grabbed a <a href="http://code.activestate.com/recipes/491264-mini-fake-dns-server/">simple DNS server</a>, and set up a simple SSL server following <a href="http://wirewatcher.wordpress.com/2010/07/20/decrypting-ssl-traffic-with-wireshark-and-ways-to-prevent-it/">these instructions</a>.</p>
<p>Now with DNS spoofing, and a fake SSL server, I could intercept encrypted traffic from the router, as long as it does not validate the SSL certificate. Luckily it didn’t check the validity, and thus I was able to capture the request: (BTW Not checking the cert completely defeats the point of using SSL… bad Linksys!).</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-http" data-lang="http"><span class="line"><span class="cl"><span class="nf">POST</span> <span class="nn">/cds/update</span> <span class="kr">HTTP</span><span class="o">/</span><span class="m">1.1</span>
</span></span><span class="line"><span class="cl"><span class="n">Host</span><span class="o">:</span> <span class="l">update.linksys.com</span>
</span></span><span class="line"><span class="cl"><span class="n">Accept</span><span class="o">:</span> <span class="l">*/*</span>
</span></span><span class="line"><span class="cl"><span class="n">Content-Type</span><span class="o">:</span> <span class="l">text/xml</span>
</span></span><span class="line"><span class="cl"><span class="n">Content-Length</span><span class="o">:</span> <span class="l">573</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="ni">&amp;lt;</span>SOAP-ENV:Envelope xmlns:SOAP-ENV=&#34;http://schemas.xmlsoap.org/soap/envelope/&#34;<span class="ni">&amp;gt;</span>
</span></span><span class="line"><span class="cl">  <span class="ni">&amp;lt;</span>SOAP-ENV:Header/<span class="ni">&amp;gt;</span>
</span></span><span class="line"><span class="cl">  <span class="ni">&amp;lt;</span>SOAP-ENV:Body<span class="ni">&amp;gt;</span>
</span></span><span class="line"><span class="cl">    <span class="ni">&amp;lt;</span>ns:GetFirmwareFromDeviceRequest xmlns:ns=&#34;http://cisco.com/schemas&#34;<span class="ni">&amp;gt;</span>
</span></span><span class="line"><span class="cl">      <span class="ni">&amp;lt;</span>ns:LanguageCode<span class="ni">&amp;gt;</span>en<span class="ni">&amp;lt;</span>/ns:LanguageCode<span class="ni">&amp;gt;</span>
</span></span><span class="line"><span class="cl">      <span class="ni">&amp;lt;</span>ns:CountryCode<span class="ni">&amp;gt;</span>us<span class="ni">&amp;lt;</span>/ns:CountryCode<span class="ni">&amp;gt;</span>
</span></span><span class="line"><span class="cl">      <span class="ni">&amp;lt;</span>ns:MacAddress<span class="ni">&amp;gt;</span>12:34:56:78:90:ab<span class="ni">&amp;lt;</span>/ns:MacAddress<span class="ni">&amp;gt;</span>
</span></span><span class="line"><span class="cl">      <span class="ni">&amp;lt;</span>ns:ModelNo<span class="ni">&amp;gt;</span>E4200<span class="ni">&amp;lt;</span>/ns:ModelNo<span class="ni">&amp;gt;</span>
</span></span><span class="line"><span class="cl">      <span class="ni">&amp;lt;</span>ns:HardwareVersion<span class="ni">&amp;gt;</span>2<span class="ni">&amp;lt;</span>/ns:HardwareVersion<span class="ni">&amp;gt;</span>
</span></span><span class="line"><span class="cl">      <span class="ni">&amp;lt;</span>ns:CurrentFirmwareVersion<span class="ni">&amp;gt;</span>2.0.36.126507<span class="ni">&amp;lt;</span>/ns:CurrentFirmwareVersion<span class="ni">&amp;gt;</span>
</span></span><span class="line"><span class="cl">    <span class="ni">&amp;lt;</span>/ns:GetFirmwareFromDeviceRequest<span class="ni">&amp;gt;</span>
</span></span><span class="line"><span class="cl">  <span class="ni">&amp;lt;</span>/SOAP-ENV:Body<span class="ni">&amp;gt;</span>
</span></span><span class="line"><span class="cl"><span class="ni">&amp;lt;</span>/SOAP-ENV:Envelope<span class="ni">&amp;gt;</span>
</span></span></code></pre></div><p>and the response:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-http" data-lang="http"><span class="line"><span class="cl"><span class="kr">HTTP</span><span class="o">/</span><span class="m">1.1</span> <span class="m">200</span> <span class="ne">OK</span>
</span></span><span class="line"><span class="cl"><span class="n">Content-Language</span><span class="o">:</span> <span class="l">en-US</span>
</span></span><span class="line"><span class="cl"><span class="n">Content-Type</span><span class="o">:</span> <span class="l">text/xml</span>
</span></span><span class="line"><span class="cl"><span class="n">SOAPAction</span><span class="o">:</span> <span class="l">&#34;&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="ni">&amp;lt;</span>soapenv:Envelope
</span></span><span class="line"><span class="cl"> xmlns:soapenv=&#34;http://schemas.xmlsoap.org/soap/envelope/&#34;
</span></span><span class="line"><span class="cl"> xmlns:soapenc=&#34;http://schemas.xmlsoap.org/soap/encoding/&#34;
</span></span><span class="line"><span class="cl"> xmlns:xsd=&#34;http://www.w3.org/2001/XMLSchema&#34;
</span></span><span class="line"><span class="cl"> xmlns:xsi=&#34;http://www.w3.org/2001/XMLSchema-instance&#34;<span class="ni">&amp;gt;</span>
</span></span><span class="line"><span class="cl">  <span class="ni">&amp;lt;</span>soapenv:Header/<span class="ni">&amp;gt;</span>
</span></span><span class="line"><span class="cl">  <span class="ni">&amp;lt;</span>soapenv:Body<span class="ni">&amp;gt;</span>
</span></span><span class="line"><span class="cl">    <span class="ni">&amp;lt;</span>ns:GetFirmwareFromDeviceResponse xmlns:ns=&#34;http://cisco.com/schemas&#34;<span class="ni">&amp;gt;</span>
</span></span><span class="line"><span class="cl">      <span class="ni">&amp;lt;</span>ns:FirmwareList xmlns:ns=&#34;http://cisco.com/schemas&#34;<span class="ni">&amp;gt;</span>
</span></span><span class="line"><span class="cl">        <span class="ni">&amp;lt;</span>ns:Firmware xmlns:ns=&#34;http://cisco.com/schemas&#34;<span class="ni">&amp;gt;</span>
</span></span><span class="line"><span class="cl">          <span class="ni">&amp;lt;</span>ns:Version xmlns:ns=&#34;http://cisco.com/schemas&#34;<span class="ni">&amp;gt;</span>2.0.36.126507<span class="ni">&amp;lt;</span>/ns:Version<span class="ni">&amp;gt;</span>
</span></span><span class="line"><span class="cl">          <span class="ni">&amp;lt;</span>ns:Revision xmlns:ns=&#34;http://cisco.com/schemas&#34;<span class="ni">&amp;gt;</span>D<span class="ni">&amp;lt;</span>/ns:Revision<span class="ni">&amp;gt;</span>
</span></span><span class="line"><span class="cl">          <span class="ni">&amp;lt;</span>ns:ReleaseDate xmlns:ns=&#34;http://cisco.com/schemas&#34;<span class="ni">&amp;gt;</span>2012-01-06T16:48:08Z<span class="ni">&amp;lt;</span>/ns:ReleaseDate<span class="ni">&amp;gt;</span>
</span></span><span class="line"><span class="cl">          <span class="ni">&amp;lt;</span>ns:DownloadURI xmlns:ns=&#34;http://cisco.com/schemas&#34;<span class="ni">&amp;gt;</span>http://download.linksys.com/updates/to0037258865.pdx/FW_E4200_2.0.36.126507.SSA<span class="ni">&amp;lt;</span>/ns:DownloadURI<span class="ni">&amp;gt;</span>
</span></span><span class="line"><span class="cl">          <span class="ni">&amp;lt;</span>ns:DateFormat xmlns:ns=&#34;http://cisco.com/schemas&#34;<span class="ni">&amp;gt;</span>yyyy-MM-dd&#39;;T&#39;;HH:mm:ss&#39;;Z&#39;;<span class="ni">&amp;lt;</span>/ns:DateFormat<span class="ni">&amp;gt;</span>
</span></span><span class="line"><span class="cl">          <span class="ni">&amp;lt;</span>ns:Checksum xmlns:ns=&#34;http://cisco.com/schemas&#34;<span class="ni">&amp;gt;</span>1958710861<span class="ni">&amp;lt;</span>/ns:Checksum<span class="ni">&amp;gt;</span>
</span></span><span class="line"><span class="cl">        <span class="ni">&amp;lt;</span>/ns:Firmware<span class="ni">&amp;gt;</span>
</span></span><span class="line"><span class="cl">      <span class="ni">&amp;lt;</span>/ns:FirmwareList<span class="ni">&amp;gt;</span>
</span></span><span class="line"><span class="cl">    <span class="ni">&amp;lt;</span>/ns:GetFirmwareFromDeviceResponse<span class="ni">&amp;gt;</span>
</span></span><span class="line"><span class="cl">  <span class="ni">&amp;lt;</span>/soapenv:Body<span class="ni">&amp;gt;</span>
</span></span><span class="line"><span class="cl"><span class="ni">&amp;lt;</span>/soapenv:Envelope<span class="ni">&amp;gt;</span>
</span></span></code></pre></div><p>(I slightly modified portions of the request and response to hide the identify of my router.).</p>
<p>I might write a script to make fake requests, but until then you can easily create a request with curl:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">curl -d @request.raw https://update.linksys.com/cds/update
</span></span></code></pre></div><p>Then you just extract the DownloadURI and</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">curl http://download.linksys.com/updates/to0037258865.pdx/FW_E4200_2.0.36.126507.SSA
</span></span></code></pre></div><p>Voila I now have the firmware. Now I need to figure out what to do with it.</p>
<p><strong>Update</strong>: As requested I fetched the more recent version of the file:<br>
2.0.37.131047 – <a href="http://download.linksys.com/updates/to0040829450.pdx/FW">http://download.linksys.com/updates/to0040829450.pdx/FW</a>_E4200_2.0.37.131047.SSA</p>
</description>
    </item>
    
    <item>
      <title>Building PHP’s Debian package nightmare</title>
      <link>https://blog.bramp.net/post/2011/11/22/building-phps-debian-package-nightmare/</link>
      <pubDate>Tue, 22 Nov 2011 00:00:00 +0000</pubDate>
      
      <guid>https://blog.bramp.net/post/2011/11/22/building-phps-debian-package-nightmare/</guid>
      <description><p>I just tried to compile the Debian PHP packages, so I could make some <a href="http://www.howtoforge.com/recompiling-php5-with-bundled-support-for-gd-on-ubuntu">minor tweaks</a> to the source, to fix a bug I’m hopefully going to document shortly. This turned out to be very problematic, mainly due to the testing phase!</p>
<p>To build the Debian packages you typically do the following:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">mkdir php
</span></span><span class="line"><span class="cl"><span class="nb">cd</span> php
</span></span><span class="line"><span class="cl">apt-get <span class="nb">source</span> php5
</span></span><span class="line"><span class="cl"><span class="nb">cd</span> php5-*
</span></span><span class="line"><span class="cl">debuild -us -uc -j4
</span></span></code></pre></div><p>While testing, the debian/setup_mysql.sh script is called, to create a temporary MySQL database. This however failed to execute correctly because I had some custom options in my <a href="http://dev.mysql.com/doc/refman/5.1/en/option-files.html">~/.my.cnf</a>. Thus it failed like so:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># start our own mysql server for the tests</span>
</span></span><span class="line"><span class="cl">/bin/sh debian/setup-mysql.sh <span class="m">1029</span> /home/bramp/vendor/php/php5-5.3.8.0/mysql_db
</span></span><span class="line"><span class="cl">mysqladmin: connect to server at <span class="s1">&#39;localhost&#39;</span> failed
</span></span><span class="line"><span class="cl">error: <span class="s1">&#39;Access denied for user &#39;</span>root<span class="s1">&#39;@&#39;</span>localhost<span class="s1">&#39; (using password: YES)&#39;</span>
</span></span><span class="line"><span class="cl">make: *** <span class="o">[</span>test-results.txt<span class="o">]</span> Error <span class="m">1</span>
</span></span><span class="line"><span class="cl">dpkg-buildpackage: error: debian/rules build gave error <span class="nb">exit</span> status <span class="m">2</span>
</span></span><span class="line"><span class="cl">debuild: fatal error at line 1348:
</span></span><span class="line"><span class="cl">dpkg-buildpackage -rfakeroot -D -us -uc -j8 failed
</span></span></code></pre></div><p>After removing the my.cnf things were ok. The below patch fixes it in a more general way:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-diff" data-lang="diff"><span class="line"><span class="cl"><span class="gd">-- debian/setup-mysql.sh.org	2011-11-21 21:57:07.244481175 -0500
</span></span></span><span class="line"><span class="cl"><span class="gi">+++ debian/setup-mysql.sh	2011-11-21 21:40:39.384455880 -0500
</span></span></span><span class="line"><span class="cl"><span class="gu">@@ -16,7 +16,7 @@
</span></span></span><span class="line"><span class="cl"> 
</span></span><span class="line"><span class="cl"> socket=$datadir/mysql.sock
</span></span><span class="line"><span class="cl"> # Commands:
</span></span><span class="line"><span class="cl"><span class="gd">-mysqladmin=&#34;mysqladmin -u root -P $port -h localhost --socket=$socket&#34;
</span></span></span><span class="line"><span class="cl"><span class="gi">+mysqladmin=&#34;mysqladmin --no-defaults -u root -P $port -h localhost --socket=$socket&#34;
</span></span></span><span class="line"><span class="cl"> mysqld=&#34;/usr/sbin/mysqld --no-defaults --bind-address=localhost --port=$port --socket=$socket --datadir=$datadir&#34;
</span></span><span class="line"><span class="cl"> 
</span></span><span class="line"><span class="cl"> # Main code #
</span></span></code></pre></div><p>The next problem I encountered is that all the automated PHP unit tests were failing, and they would eventually get stuck and use all my RAM and swap space (at least 16GiB of it) :( I’m not sure what made the machine run out of RAM, but the tests were failing because the version of PHP that was running the tests was incorrectly loading extensions from my system. The quick fix for this was to disable any extensions I had installed to my system. I just</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo mv /etc/php5/conf.d /etc/php5/conf.d.tmp
</span></span></code></pre></div><p>to do that.</p>
<p>This made me think that in future I should perhaps find a cleaner environment to build these packages. In fact, it makes me wonder if the builds are just broken if my environment clearly impacts the successful run of tests.</p>
<p>One trick I found while building again and again, is that you can pass “-nc” to debuild so that it does not clean, and thus reuses the existing build materials for a faster build. Either way, I now have my own version of PHP built and installed! Next time I might just ignore the .deb files and build direct from source.</p>
</description>
    </item>
    
    <item>
      <title>Default to curses interface for mtr</title>
      <link>https://blog.bramp.net/post/2011/08/07/default-to-curses-interface-for-mtr/</link>
      <pubDate>Sun, 07 Aug 2011 00:00:00 +0000</pubDate>
      
      <guid>https://blog.bramp.net/post/2011/08/07/default-to-curses-interface-for-mtr/</guid>
      <description><p>I really like <a href="http://www.bitwizard.nl/mtr/">mtr</a> (the traceroute tool), however, it always bugged me that it launches a GUI app instead of using the <a href="http://en.wikipedia.org/wiki/Curses_(programming_library)">curses</a> interface. You can easily pass the “-t” or “–curses” flag to default to the curses interface, but I always forget.</p>
<p>So today I set about writing a patch for mtr to read a environment varable to force the curses interface. While I was reading the source I noticed there was already a simple undocumented way!</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="nb">export</span> <span class="nv">MTR_OPTIONS</span><span class="o">=</span>-t
</span></span></code></pre></div><p>Voila the curses interface is now used by default. This is certainly going into my ~/.bashrc</p>
</description>
    </item>
    
    <item>
      <title>Linux 64bit Flash glibc memcpy bug</title>
      <link>https://blog.bramp.net/post/2011/06/19/linux-64bit-flash-glibc-memcpy-bug/</link>
      <pubDate>Sun, 19 Jun 2011 00:00:00 +0000</pubDate>
      
      <guid>https://blog.bramp.net/post/2011/06/19/linux-64bit-flash-glibc-memcpy-bug/</guid>
      <description><p>Does your Linux 64bit version of Flash now make anonying beeping/distortion noises while playing videos? Well it turns out a recent “<a href="http://lwn.net/Articles/414467/">improvement</a>” to glibc has caused some programs to now crash or do weird things. This is to do with an improvement of <a href="http://linux.die.net/man/3/memcpy">memcpy</a>, which makes its use more strict, causing those applications that incorrectly used it to now crash.</p>
<p>On Debian, there is a simple a fix that allows you to use the original memcpy. You can load the application using an additional .so file:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="nv">LD_PRELOAD</span><span class="o">=</span>/usr/lib/libc/memcpy-preload.so /path/to/your/program
</span></span></code></pre></div><p>As I use Google Chrome when using Flash I had to do the following:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="nv">LD_PRELOAD</span><span class="o">=</span>/usr/lib/libc/memcpy-preload.so /usr/bin/google-chrome
</span></span></code></pre></div><p>but if you want to fix chrome on a system level, you can edit the Chrome Wrapper used to launch it.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo nano /opt/google/chrome/google-chrome
</span></span></code></pre></div><p>add the following line</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="nb">export</span> <span class="nv">LD_PRELOAD</span><span class="o">=</span><span class="s2">&#34;/usr/lib/libc/memcpy-preload.so&#34;</span>
</span></span></code></pre></div><p>for example</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="nb">export</span> LD_LIBRARY_PATH
</span></span><span class="line"><span class="cl"><span class="nb">export</span> <span class="nv">LD_PRELOAD</span><span class="o">=</span><span class="s2">&#34;/usr/lib/libc/memcpy-preload.so&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">export</span> <span class="nv">CHROME_VERSION_EXTRA</span><span class="o">=</span><span class="s2">&#34;beta&#34;</span>
</span></span></code></pre></div></description>
    </item>
    
    <item>
      <title>Intel ucode firmware version parser</title>
      <link>https://blog.bramp.net/post/2011/01/24/intel-ucode-firmware-version-parser/</link>
      <pubDate>Mon, 24 Jan 2011 00:00:00 +0000</pubDate>
      
      <guid>https://blog.bramp.net/post/2011/01/24/intel-ucode-firmware-version-parser/</guid>
      <description><p>Out of fun I wrote a simple Python script to pull the version number out of Intel’s ucode firmware, for example, the firmware used by my wifi driver. I needed this so I could see what version I was running versus a new version I had downloaded from <a href="http://intellinuxwireless.org/?n=Downloads">Intel’s Linux Wireless site</a>.</p>
<p>So here is the code if anyone finds it interesting:</p>
<p>and example of using it is:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">$ ./ucode.py /lib/firmware/*.ucode
</span></span><span class="line"><span class="cl">iwlwifi-1000-3.ucode    : ver 128.50.3.1
</span></span><span class="line"><span class="cl">iwlwifi-3945-1.ucode    : ver 15.28.1.6
</span></span><span class="line"><span class="cl">iwlwifi-3945-2.ucode    : ver 15.32.2.9
</span></span><span class="line"><span class="cl">iwlwifi-4965-1.ucode    : ver 228.57.1.21
</span></span><span class="line"><span class="cl">iwlwifi-4965-2.ucode    : ver 228.61.2.24
</span></span><span class="line"><span class="cl">iwlwifi-5000-1.ucode    : ver 5.4.1.16
</span></span><span class="line"><span class="cl">iwlwifi-5000-2.ucode    : ver 8.24.2.12
</span></span><span class="line"><span class="cl">iwlwifi-5150-2.ucode    : ver 8.24.2.2
</span></span><span class="line"><span class="cl">iwlwifi-6000-4.ucode    : ver 9.221.4.1
</span></span><span class="line"><span class="cl">iwlwifi-6000g2a-5.ucode : ver 17.168.5.1 <span class="o">(</span>6000g2a fw v17.168.5.1 build 33993<span class="o">)</span>
</span></span><span class="line"><span class="cl">iwlwifi-6000g2b-5.ucode : ver 17.168.5.1 <span class="o">(</span>6000g2b fw v17.168.5.1 build 33993<span class="o">)</span>
</span></span><span class="line"><span class="cl">iwlwifi-6050-4.ucode    : ver 9.201.4.1
</span></span><span class="line"><span class="cl">iwlwifi-6050-5.ucode    : ver 41.28.5.1 <span class="o">(</span><span class="m">6050</span> fw v41.28.5.1 build 33926<span class="o">)</span>
</span></span></code></pre></div></description>
    </item>
    
    <item>
      <title>ifconfig stats gotcha</title>
      <link>https://blog.bramp.net/post/2010/09/06/ifconfig-stats-gotcha/</link>
      <pubDate>Mon, 06 Sep 2010 00:00:00 +0000</pubDate>
      
      <guid>https://blog.bramp.net/post/2010/09/06/ifconfig-stats-gotcha/</guid>
      <description><p>I’ve recently been running network benchmarks and I wanted to highlight a quick gotcha that caught me out. My benchmark script would run ifconfig before and after the experiment and record the number of packets sent and received. The same would be recorded on another machine which was generating the packets.</p>
<p>I started to notice a problem that more packets were being received than being sent. It was only a small number, but nevertheless an seemingly impossible situation to have occurred. I tracked the problem down to the fact that the network card driver did not always report accurate and up to date stats. In fact, after checking the source, the e1000, ixgb, ixgbe and most likely the other Intel drivers all refresh their stats every 2 seconds. The other NIC I was using, an embedded smsc9500, always updated its stats in realtime.</p>
<p>Delaying the update of stats is obviously a performance optimisation, which no doubt avoids costly locking, or problems such as cache line bouncing. I did some searching and other people have noticed similar delays in other networking devices, in some cases as much as 30 seconds on <a href="http://fixunix.com/snmp/443079-how-handle-interface-counter-update-delay.html">cisco routers</a>.</p>
<p>From now on I will always pause my scripts for a few seconds to allow the ifconfig stats to catch up before I record my data. An alternative would be to hack the drivers to either stay up to date, or offer a API that forces a update.</p>
</description>
    </item>
    
    <item>
      <title>Persec python script</title>
      <link>https://blog.bramp.net/post/2010/08/31/persec-python-script/</link>
      <pubDate>Tue, 31 Aug 2010 00:00:00 +0000</pubDate>
      
      <guid>https://blog.bramp.net/post/2010/08/31/persec-python-script/</guid>
      <description><p>A while ago I wrote a python script that does a similar job to GNU’s <a href="http://linux.die.net/man/1/watch">watch</a> command. You use it like so:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">./persec.py <span class="o">[</span>--interval<span class="o">=</span><span class="p">&amp;</span>lt<span class="p">;</span>n<span class="p">&amp;</span>gt<span class="p">;</span><span class="o">]</span> <span class="p">&amp;</span>lt<span class="p">;</span>command<span class="p">&amp;</span>gt<span class="p">;</span>
</span></span></code></pre></div><p>so for example</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">./persec.py ifconfig
</span></span></code></pre></div><p>Now in a similar way to watch, it executes the command every second, and highlights the differences between each execution. However, in addition to this it finds any numbers that have changed and works out the rate at which they are changing. So for example, ifconfig would typically output this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">usb0      Link encap:Ethernet  HWaddr 02:04:4b:00:d3:cf
</span></span><span class="line"><span class="cl">          inet addr:10.0.0.2  Bcast:10.0.0.255  Mask:255.255.255.0
</span></span><span class="line"><span class="cl">          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
</span></span><span class="line"><span class="cl">          RX packets:1017422291 errors:0 dropped:0 overruns:0 frame:0
</span></span><span class="line"><span class="cl">          TX packets:549382406 errors:0 dropped:0 overruns:0 carrier:0
</span></span><span class="line"><span class="cl">          collisions:0 txqueuelen:1000
</span></span><span class="line"><span class="cl">          RX bytes:1910704266 (1.9 GB)  TX bytes:1834667124 (1.8 GB)
</span></span></code></pre></div><p>but now outputs something like:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">usb0      Link encap:Ethernet  HWaddr 02:04:4b:00:d3:cf
</span></span><span class="line"><span class="cl">          inet addr:10.0.0.2  Bcast:10.0.0.255  Mask:255.255.255.0
</span></span><span class="line"><span class="cl">          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
</span></span><span class="line"><span class="cl">          RX packets:&lt;b&gt;2001/s&lt;/b&gt; errors:0 dropped:0 overruns:0 frame:0
</span></span><span class="line"><span class="cl">          TX packets:&lt;b&gt;2002/s&lt;/b&gt; errors:0 dropped:0 overruns:0 carrier:0
</span></span><span class="line"><span class="cl">          collisions:0 txqueuelen:1000
</span></span><span class="line"><span class="cl">          RX bytes:&lt;b&gt;168120/s&lt;/b&gt; (1.9 GB)  TX bytes:&lt;b&gt;217144/s&lt;/b&gt; (1.8 GB)
</span></span></code></pre></div><p>Notice the per second (/s) values for RX/TX packets and RX/TX bytes. I have found this quite useful many times in the past, on commands such as:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">./persec.py cat /proc/interrupts
</span></span><span class="line"><span class="cl">./persec.py df
</span></span><span class="line"><span class="cl">./persec.py ls -l somefile
</span></span></code></pre></div><p><a href="https://raw.githubusercontent.com/bramp/handy-tools/master/persec.py">Download version 1.1</a> or <a href="https://github.com/bramp/handy-tools/blob/master/persec.py">View on Github</a></p>
</description>
    </item>
    
    <item>
      <title>Humble Indie Bundle md5sums</title>
      <link>https://blog.bramp.net/post/2010/05/07/humble-indie-bundle-md5sums/</link>
      <pubDate>Fri, 07 May 2010 00:00:00 +0000</pubDate>
      
      <guid>https://blog.bramp.net/post/2010/05/07/humble-indie-bundle-md5sums/</guid>
      <description><p>I just purchased the <a href="http://www.wolfire.com/humble">Humble Indie Bundle</a>, 5 games which run on Windows, Linux and Mac. They kindly offered md5 hashes, however they weren’t in a convenient format, so I created a md5sums file.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">187287db6226ef6a306a4cd0cfa8dd45 *Aquaria111.2008.12.12.exe
</span></span><span class="line"><span class="cl">8b24ddeeb553e028bbd501102f891cc2 *aquaria-lnx-humble-bundle.mojo.run
</span></span><span class="line"><span class="cl">336d89eb431e0b00535a2b50146c579d *WorldOfGooSetup.1.30.exe
</span></span><span class="line"><span class="cl">f5afa40893d0fbcc37885191404f6d8c *WorldOfGooSetup.1.41.tar.gz
</span></span><span class="line"><span class="cl">b373132f6e78665f1076752b038a8218 *gish153-1.tar.gz
</span></span><span class="line"><span class="cl">94e82d53e2104914f19ec97f7cf5da42 *gish1531.zip
</span></span><span class="line"><span class="cl">41ea2e41fe42c40b5ad017ae1afb45c7 *lugaru-full-linux-x86-1.0c.bin
</span></span><span class="line"><span class="cl">d40d4076ed3ffa2a9bc9913202c55a06 *lugaru-windows.zip
</span></span><span class="line"><span class="cl">56060bb550e0cd7e90bc7bc60d7c4c23 *penumbra_overture_1.1.exe
</span></span><span class="line"><span class="cl">539567b590cf53e65a8e8f1b2bc728b3 *penumbra_overture_1.1.sh
</span></span></code></pre></div><p>and for those that prefer sha1:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">ec8fd66bb44c6f67eab40f73e57838dcb5e2f4dd *Aquaria111.2008.12.12.exe
</span></span><span class="line"><span class="cl">48267967b3a57fb406fa6545261f8b758edb8fb5 *aquaria-lnx-humble-bundle.mojo.run
</span></span><span class="line"><span class="cl">70fad514746d6fc482fc3d681a7e9d498374bdad *WorldOfGooSetup.1.30.exe
</span></span><span class="line"><span class="cl">4f7202a4ac17dd1665a1ab7f90153e5b813e16f1 *WorldOfGooSetup.1.41.tar.gz
</span></span><span class="line"><span class="cl">27b862939b6a01c29b1b146ed1307c0027217855 *gish153-1.tar.gz
</span></span><span class="line"><span class="cl">7a1341822d4d4e0010cc1e8cce68da6bb02ea904 *gish1531.zip
</span></span><span class="line"><span class="cl">2349bdea3d595c3aaedca0810229d12f96323874 *lugaru-full-linux-x86-1.0c.bin
</span></span><span class="line"><span class="cl">73f09414e0cabd371802eea1b9c75c76522c5934 *lugaru-windows.zip
</span></span><span class="line"><span class="cl">557c6988eda16c6269d09a35031fd1754e042c02 *penumbra_overture_1.1.exe
</span></span><span class="line"><span class="cl">e115f7cfcf9710d7aa5b2a5a9186b3736bb55cf2 *penumbra_overture_1.1.sh
</span></span></code></pre></div><p>Note, these were correct and validated on the 8th of May, however, if any of the files have been updated the hashes might no longer much. Feel free to <a href="/about-me/">contact me</a> to tell me if this happens.</p>
</description>
    </item>
    
    <item>
      <title>VMWare breaks shift key</title>
      <link>https://blog.bramp.net/post/2010/03/19/vmware-breaks-shift-key/</link>
      <pubDate>Fri, 19 Mar 2010 00:00:00 +0000</pubDate>
      
      <guid>https://blog.bramp.net/post/2010/03/19/vmware-breaks-shift-key/</guid>
      <description><p>I came into my office today to find that my keyboard would no longer type capital letters. The shift, caps lock, and even num lock keys seemed to be broken. After a quick WTF <a href="http://www.evolution-systems.co.uk/blogs/matt/view_post&amp;id=37/">it was pointed out to me</a> that VMWare occasionally does this to Linux machines. Thanks to <a href="http://twitter.com/bigkebabman">Matt</a> who showed me a quick solution. In a terminal just type:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">setxkbmap
</span></span></code></pre></div><p>And everything should be back to normal. After using VMWare on Linux for a couple of years I’ve never encountered this problem!</p>
</description>
    </item>
    
    <item>
      <title>Redirect local traffic to a web cache with iptables</title>
      <link>https://blog.bramp.net/post/2010/01/26/redirect-local-traffic-to-a-web-cache-with-iptables/</link>
      <pubDate>Tue, 26 Jan 2010 00:00:00 +0000</pubDate>
      
      <guid>https://blog.bramp.net/post/2010/01/26/redirect-local-traffic-to-a-web-cache-with-iptables/</guid>
      <description><p>Very occasionally I come across a Linux application that does not respect the http_proxy variable. This stops the application from working while I’m at university as they forbid traffic on port 80 unless it goes via their webcache. So today I came up with a hack of a solution that involves iptables:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># IP address and port number of the webcache</span>
</span></span><span class="line"><span class="cl"><span class="nv">WEBCACHE</span><span class="o">=</span>194.80.32.10:8080
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Flush any previous rules</span>
</span></span><span class="line"><span class="cl">iptables -t nat --flush
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Delete and recreate the chain</span>
</span></span><span class="line"><span class="cl">iptables -t nat -X HTTPFORCE
</span></span><span class="line"><span class="cl">iptables -t nat -N HTTPFORCE
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Don&#39;t touch local traffic (localhost and internal network)</span>
</span></span><span class="line"><span class="cl">iptables -t nat -A HTTPFORCE -o lo -j RETURN
</span></span><span class="line"><span class="cl">iptables -t nat -A HTTPFORCE --dst 127.0.0.1/8 -j RETURN
</span></span><span class="line"><span class="cl">iptables -t nat -A HTTPFORCE --dst 10.0.0.0/8 -j RETURN
</span></span><span class="line"><span class="cl"><span class="c1"># Add any other local networks here.</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Now we have two options. Please uncomment out one of them</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 1) Redirect packets on port 80 to the webcache</span>
</span></span><span class="line"><span class="cl"><span class="c1">#    This may not work unless the webcache is generous with its input</span>
</span></span><span class="line"><span class="cl"><span class="c1">#iptables -t nat -A HTTPFORCE -p tcp --dport 80 -j DNAT --to $WEBCACHE</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 2) Redirect packets on port 80 to localhost port 1234</span>
</span></span><span class="line"><span class="cl"><span class="c1">#    On port 1234 you need to run a local web proxy, which forwards </span>
</span></span><span class="line"><span class="cl"><span class="c1">#    requests to the real webcache</span>
</span></span><span class="line"><span class="cl"><span class="c1">#iptables -t nat -A HTTPFORCE -p tcp --dport 80 -j REDIRECT --to-port 1234</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Capture all outgoing TCP syns</span>
</span></span><span class="line"><span class="cl">iptables -t nat -A OUTPUT -p tcp --syn -j HTTPFORCE
</span></span></code></pre></div><p>All outgoing TCP packets on port 80 which are not destined for a local network are captured and changed in one of two ways. The first option just manipulates the IP/TCP header, and the second redirects the traffic to a proxy running on localhost. The reason for the two options was that my university’s webcache seemed unable to deal with HTTP requests without the full URL in the GET line, even though the request contains a valid Host header. I think this is a misconfiguration of their squid proxy, so instead you can redirect to a local proxy which forwards the request on to the webcache.</p>
<p>This all seems a hassle but sometimes it is needed when a application does not respect the http_proxy environment. On a good note all libcurl applications should respect it by default.</p>
</description>
    </item>
    
    <item>
      <title>Installing packages into your user directory</title>
      <link>https://blog.bramp.net/post/2010/01/14/installing-packages-into-your-user-directory/</link>
      <pubDate>Thu, 14 Jan 2010 00:00:00 +0000</pubDate>
      
      <guid>https://blog.bramp.net/post/2010/01/14/installing-packages-into-your-user-directory/</guid>
      <description><p>Today I had the need to install some <a href="http://www.freebsd.org/">FreeBSD</a> and <a href="http://www.ubuntu.com/">Ubuntu</a> packages inside my home directory because I did not have root permissions to install them.</p>
<p>It was quite simple to install the packages on FreeBSD</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">pkg_add -rRP /home/bramp nano
</span></span></code></pre></div><p>Where nano is the name of the package I wanted.</p>
<p>I should point out you don’t need to be root to do this!, but the installed packages only work for you, and in future could cause you hassle if the base OS is updated.</p>
<p>On Ubuntu I however failed :( I tried the “–root” option and did some <a href="http://ubuntuforums.org/archive/index.php/t-513933.html">Googleing</a> but I didn’t find a solution. Unitl then I’ll just install from source.</p>
</description>
    </item>
    
  </channel>
</rss>
