<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>Dobrica Pavlinušić&apos;s Weblog / Blog</title>
    <link rel="alternate" type="text/html" href="http://blog.rot13.org/" />
    <link rel="self" type="application/atom+xml" href="http://blog.rot13.org/atom.xml" />
    <id>tag:blog.rot13.org,2011-03-03://1</id>
    <updated>2012-05-08T19:32:45Z</updated>
    <subtitle>Personal weblog about technology, Open Source, perl, GNU etc...</subtitle>
    <generator uri="http://www.sixapart.com/movabletype/">Movable Type 5.04</generator>

<entry>
    <title>rpcbind is new portmap or how to make nfs secure</title>
    <link rel="alternate" type="text/html" href="http://blog.rot13.org/2012/05/rpcbind-is-new-portmap-or-how-to-make-nfs-secure.html" />
    <id>tag:blog.rot13.org,2012://1.751</id>

    <published>2012-05-08T19:32:42Z</published>
    <updated>2012-05-08T19:32:45Z</updated>

    <summary> I was installing NFS server on otherwise public host recently, and noticed that conventional wisdom about securing NFS server is somewhat dated. My goal was to expose NFS on two internal interfaces without exposing it to whole wide Internet (assumptions about network security changed a lot since NFS was designed, sadly). For a start, you are probably running rpcbind instead of portmap on recent Debian installations. So you will need to modify flags which are passed to portmap on startup: root@rsync1:~# cat /etc/default/rpcbind OPTIONS=&quot;-w -l -h 172.16.10.2 -h 192.168.0.219&quot; You will also need to add following line: root@rsync1:~# grep rpcbind /etc/hosts.deny rpcbind: ALL Now you will notice that rpcinfo -p still works OK on localhost. That&apos;s because rpcbind will always add loopback address, so we have to test it from another machine: root@rsync1-dev:~# rpcinfo -p 192.168.0.219 rpcinfo: can&apos;t contact portmapper: RPC: Authentication error; why = Client credential too weak That&apos;s more like it! If we take a look in log... root@rsync1:~# tail -1 /var/log/auth.log May 8 20:31:51 rsync1 rpcbind: connect from 192.168.0.21 to dump(): request from unauthorized host ...we don&apos;t even have to guess local system IP adress. We&apos;ll allow this host to connect with... root@rsync1:~# grep rpcbind /etc/hosts.allow rpcbind: 192.168.0.21 We can also check our tcp wrappers configuration with: root@rsync1:~# tcpdmatch rpcbind 192.168.0.21 client: address 192.168.0.21 server: process rpcbind access: granted...</summary>
    <author>
        <name>Dobrica Pavlinušić</name>
        <uri>http://www.rot13.org/~dpavlin/</uri>
    </author>
    
        <category term="howto" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="sysadminnfs" label="sysadmin nfs" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://blog.rot13.org/">
        <![CDATA[<p>
I was installing NFS server on otherwise public host recently, and noticed that <a href="http://tldp.org/HOWTO/NFS-HOWTO/security.html">conventional wisdom about securing NFS server</a> is somewhat dated. My goal was to expose NFS on two internal interfaces without exposing it to whole wide Internet (assumptions about network security changed a lot since NFS was designed, sadly).
</p>
<p>
For a start, you are probably running <tt>rpcbind</tt> instead of portmap on recent Debian installations. So you will need to modify flags which are passed to portmap on startup:
<pre>
root@rsync1:~# cat /etc/default/rpcbind 
OPTIONS="-w -l -h 172.16.10.2 -h 192.168.0.219"
</pre>
You will also need to add following line:
<pre>
root@rsync1:~# grep rpcbind /etc/hosts.deny 
rpcbind: ALL
</pre>
Now you will notice that <tt>rpcinfo -p</tt> still works OK on localhost. That's because rpcbind will always add loopback address, so we have to test it from another machine:
<pre>
root@rsync1-dev:~# rpcinfo -p 192.168.0.219
rpcinfo: can't contact portmapper: RPC: Authentication error; why = Client credential too weak
</pre>
That's more like it! If we take a look in log...
<pre>
root@rsync1:~# tail -1 /var/log/auth.log
May  8 20:31:51 rsync1 rpcbind: connect from 192.168.0.21 to dump(): request from unauthorized host
</pre>
...we don't even have to guess local system IP adress. We'll allow this host to connect with...
<pre>
root@rsync1:~# grep rpcbind /etc/hosts.allow 
rpcbind: 192.168.0.21
</pre>
We can also check our tcp wrappers configuration with:
<pre>
root@rsync1:~# tcpdmatch rpcbind 192.168.0.21
client:   address  192.168.0.21
server:   process  rpcbind
access:   granted
</pre>
]]>
        
    </content>
</entry>

<entry>
    <title>munin migration and upgrade to v2</title>
    <link rel="alternate" type="text/html" href="http://blog.rot13.org/2012/05/munin-migration-and-upgrade-to-v2.html" />
    <id>tag:blog.rot13.org,2012://1.750</id>

    <published>2012-05-02T18:15:50Z</published>
    <updated>2012-05-02T18:15:20Z</updated>

    <summary> I always loved graphs. For my monitoring needs I&apos;m using munin so in last few days I was migrating one installation from machine behind DSL line to co-location (virtual) server. Using old munin server, I would occasionally get e-mail alerts about unavailable services, mostly because n2n (which we use to connect to nodes) forgot about node or dropped packets because of busy DSL line. In the process, I decided to jump ahead and install version 2.0-rc5 from Debian unstable. This blog post will try to describe my journey... I started simply by installing new munin instance in new (virtual) machine. I decided that historic data is important, so I decided to move configuration and graphs over to new instance. Simply coping rrd files over didn&apos;t went all that well and resulted in dreaded This RRD was created on another architecture error. This was unfortunate but rrd files where so large, that transfer won&apos;t fit into 5 minute munin poll interval anyway, so I had to take different approach. To keep all historical data and not loose any munin polls while I transfer them I decided to first configure new munin node to poll all clients (so new updates will be preserved) and while this is running copy over rrd files from old server. This involved editing all nodes (9 of them!) and Cluster SSH came as perfect solution to add additional allow ^192\.168\.0\.10$ lines in /etc/munin/munin-node.conf on all nodes. Coping rrd files had to be done using rrdtool dump/restore and it had to be done over compressed ssh link due to slow DSL line. For that, small shell script came very handy: #!/bin/sh -x dir=/var/lib/munin/maxxo via_ssh=&quot;ssh -o ControlPath=/tmp/ssh_sock -o ControlMaster=auto -o Compression=yes root@10.1.3.10&quot; if [ ! -e /tmp/ssh_sock ] ; then $via_ssh read fi ls $dir/*.rrd | while read file do echo $file rrdtool dump $file | $via_ssh rrdtool restore - $file --force-overwrite done You need to start it twice. First invocation will ask for password and open master ssh socket which next invocation will use for transfers of rrd files using compressed ssh link, without connection overhead for each file. We are talking about 4560 rrd files with total of over 250Mb, after all... Even with all this, it took hour and a half to transfer all that over, so setting up update of existing files was really required. You might think that it&apos;s all, but unfortunately, it&apos;s not. Looking in /var/log/munin/munin-update.log I could see [FATAL] Socket read timed out to node. Terminating process.. Some of nodes required more time than default value provided by munin (30 sec) to respond with all data. It seems that ipmi plugins are notoriously snow to respond for example. To change server-side timeout, you have to pass --timeout 90 to munin-update utility. Unfortunately, in Debian you can&apos;t do that by modifying munin-cron invocation in /etc/cron.d/munin because it passes all parameters to munin-limit which doesn&apos;t have timeout option and dies on you (moral of the story: check cron e-mail while configuring cron jobs). In the end, I edited /usr/bin/munin-cron directly, changing one line: /usr/share/munin/munin-update --timeout 90 $@ || exit 1 This will probably break with next update, but this blog post will remind me to change it again :-) There where also a few tweaks on munin-node plugins to make them work inside kvm. iostat_ios plugin from munin-plugins-extra didn&apos;t like virtio devices which have major number 254, same as LVM2 devices which it ignores. Following patch solved this problem: diff --git a/cs-munin/etc/munin/plugins/iostat_ios b/cs-munin/etc/munin/plugins/iostat_ios index 1380eb1..823df63 100755 --- a/cs-munin/etc/munin/plugins/iostat_ios +++ b/cs-munin/etc/munin/plugins/iostat_ios @@ -101,7 +101,7 @@ sub filter { return 0 if ($major == 1); # RAM devices return 0 if ($major == 9); # MD devices return 0 if ($major == 58); # LVM devices - return 0 if ($major == 254); # LVM2 devices + return 1 if ($major == 254); # LVM2 devices and KVM virtio } if(defined($tmpnam)) { return 0 if ($tmpnam =~ /part\d+$/); I also decided to use ksm which is enabled by following line in /etc/rc.local: echo 1 &gt; /sys/kernel/mm/ksm/run And of course, now I had to graph it with simple shell ksm munin plugin. Dropping sharing line on this graph makes me think that it wasn&apos;t really needed, but we&apos;ll see in few more days. To track other kvm parameters, I used munin-libvirt-plugins which comes with it&apos;s own helper script munin-libvirt-plugins-detect which you have to run to enable plugin and generate configuration. For a web server, I opted to use apache2 and libapache2-mod-fastcgi together with graph_strategy cgi and html_strategy cgi in /etc/munin/munin.conf mostly to save some performance on polling machine. To make it work, I had to copy /etc/munin/apache.conf into /etc/apache2/conf.d/munin and uncomment relevant fast-cgi lines inside. After that, dynamically generated html is available at http://munin.example.com/munin-cgi/ and if you ever run munin-html before, you will still get old (obsolete) html pages if you visit page directly. Next step would probably be to get rrdcached up and running......</summary>
    <author>
        <name>Dobrica Pavlinušić</name>
        <uri>http://www.rot13.org/~dpavlin/</uri>
    </author>
    
        <category term="howto" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="en" xml:base="http://blog.rot13.org/">
        <![CDATA[<p>
I always loved graphs. For my monitoring needs I'm using <a href="http://munin-monitoring.org/">munin</a> so in last few days I was migrating one installation from machine behind DSL line to co-location (virtual) server. Using old munin server, I would occasionally get e-mail alerts about unavailable services, mostly because <a href="http://www.ntop.org/products/n2n/">n2n</a> (which we use to connect to nodes) forgot about node or dropped packets because of busy DSL line. In the process, I decided to jump ahead and install version 2.0-rc5 from Debian unstable. This blog post will try to describe my journey...
</p>
<p>
I started simply by installing new munin instance in new (virtual) machine. I decided that historic data is important, so I decided to move configuration and graphs over to new instance. Simply coping rrd files over didn't went all that well and resulted in dreaded <tt>This RRD was created on another architecture</tt> error. This was unfortunate but rrd files where so large, that transfer won't fit into 5 minute munin poll interval anyway, so I had to take different approach.
</p>
<p>
To keep all historical data and not loose any munin polls while I transfer them I decided to first configure new munin node to poll all clients (so new updates will be preserved) and while this is running copy over rrd files from old server. This involved editing all nodes (9 of them!) and <a href="http://sourceforge.net/projects/clusterssh/">Cluster SSH</a> came as perfect solution to add additional <tt>allow ^192\.168\.0\.10$</tt> lines in <tt>/etc/munin/munin-node.conf</tt> on all nodes.
</p>
<p>
Coping rrd files had to be done using <tt>rrdtool dump/restore</tt> and it had to be done over compressed ssh link due to slow DSL line. For that, small shell script came very handy:
<pre>
#!/bin/sh -x

dir=/var/lib/munin/maxxo


via_ssh="ssh -o ControlPath=/tmp/ssh_sock -o ControlMaster=auto -o Compression=yes root@10.1.3.10"

if [ ! -e /tmp/ssh_sock ] ; then
        $via_ssh read
fi

ls $dir/*.rrd | while read file
do
        echo $file
        rrdtool dump $file | $via_ssh rrdtool restore - $file --force-overwrite
done
</pre>
You need to start it <em>twice</em>. First invocation will ask for password and open master ssh socket which next invocation will use for transfers of rrd files using compressed ssh link, without connection overhead for each file. We are talking about <b>4560</b> rrd files with total of over 250Mb, after all... Even with all this, it took hour and a half to transfer all that over, so setting up update of existing files was really required.
</p>
<p>
You might think that it's all, but unfortunately, it's not. Looking in <tt>/var/log/munin/munin-update.log</tt> I could see <tt> [FATAL] Socket read timed out to node.  Terminating process.</tt>. Some of nodes required more time than default value provided by munin (30 sec) to respond with all data. It seems that ipmi plugins are notoriously snow to respond for example. To change server-side timeout, you have to pass <tt>--timeout 90</tt> to <tt>munin-update</tt> utility. Unfortunately, in Debian you can't do that by modifying <tt>munin-cron</tt> invocation in <tt>/etc/cron.d/munin</tt> because it passes all parameters to <tt>munin-limit</tt> which doesn't have timeout option and dies on you (moral of the story: check cron e-mail while configuring cron jobs). In the end, I edited <tt>/usr/bin/munin-cron</tt> directly, changing one line:
<pre>
/usr/share/munin/munin-update <b>--timeout 90</b> $@ || exit 1
</pre>
This will probably break with next update, but this blog post will remind me to change it again :-)
</p>
<p>
There where also a few tweaks on munin-node plugins to make them work inside kvm. <tt>iostat_ios</tt> plugin from <tt>munin-plugins-extra</tt> didn't like virtio devices which have major number 254, same as LVM2 devices which it ignores. Following patch solved this problem:
<pre>
diff --git a/cs-munin/etc/munin/plugins/iostat_ios b/cs-munin/etc/munin/plugins/iostat_ios
index 1380eb1..823df63 100755
--- a/cs-munin/etc/munin/plugins/iostat_ios
+++ b/cs-munin/etc/munin/plugins/iostat_ios
@@ -101,7 +101,7 @@ sub filter {
         return 0 if ($major ==   1); # RAM devices
         return 0 if ($major ==   9); # MD devices
         return 0 if ($major ==  58); # LVM devices
-        return 0 if ($major == 254); # LVM2 devices
+        return 1 if ($major == 254); # LVM2 devices and KVM virtio
     }
     if(defined($tmpnam)) {
         return 0 if ($tmpnam =~ /part\d+$/);
</pre>
</p>
<a href="http://blog.rot13.org/assets_c/2012/05/ksm-day-119.html" onclick="window.open('http://blog.rot13.org/assets_c/2012/05/ksm-day-119.html','popup','width=497,height=316,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://blog.rot13.org/assets_c/2012/05/ksm-day-thumb-320x203-119.png" width="320" height="203" alt="ksm-day.png" class="mt-image-right" style="float: right; margin: 0 0 20px 20px;" /></a>
<p>
I also decided to use <a href="http://lwn.net/Articles/326364/">ksm</a> which is enabled by following line in <tt>/etc/rc.local</tt>:
<pre>
echo 1 > /sys/kernel/mm/ksm/run
</pre>
And of course, now I had to graph it with <a href="https://github.com/HeMan/ksm-plugin">simple shell ksm munin plugin</a>. Dropping sharing line on this graph makes me think that it wasn't really needed, but we'll see in few more days.
</p>
<p>
To track other kvm parameters, I used <tt>munin-libvirt-plugins</tt> which comes with it's own helper script <tt>munin-libvirt-plugins-detect</tt> which you have to run to enable plugin and generate configuration.
</p>
<p>
For a web server, I opted to use <tt>apache2</tt> and <tt>libapache2-mod-fastcgi</tt>  together with <tt>graph_strategy cgi</tt> and <tt>html_strategy cgi</tt> in <tt>/etc/munin/munin.conf</tt> mostly to save some performance on polling machine. To make it work, I had to copy <tt>/etc/munin/apache.conf</tt> into <tt>/etc/apache2/conf.d/munin</tt> and uncomment relevant fast-cgi lines inside. After that, dynamically generated html is available at <code>http://munin.example.com/munin-cgi/</code> and if you ever run <tt>munin-html</tt> before, you will still get old (obsolete) html pages if you visit page directly.
</p>
<p>
Next step would probably be to get <a href="http://munin-monitoring.org/wiki/rrdcached">rrdcached</a> up and running...
</p>
]]>
        
    </content>
</entry>

<entry>
    <title>Read two-column pdf files on Kindle</title>
    <link rel="alternate" type="text/html" href="http://blog.rot13.org/2012/03/read-two-column-pdf-files-on-kindle.html" />
    <id>tag:blog.rot13.org,2012://1.749</id>

    <published>2012-03-01T22:48:49Z</published>
    <updated>2012-03-01T23:13:35Z</updated>

    <summary> I really like Kindle because it allows me to run my own selection of software on it. However, when I try to persuade other Kindle owners in all the benefits of running custom software, I usually get response like: but it already does everything I need. That might be true, but that&apos;s only because you never tried to read two column article on Kindle... Fortunately, we have alternative pdf reader for Kindle based on muPDF library which is mostly written in lua. This is especially nice since it allowed me to add support for reading two-column pdf layouts which you can see in following video: Basically, you press F to switch to new layout and then use fiveway buttons to move down the column, or right to move to top of next column, with page change if needed. If you move to left, you will be positioned to bottom of previous column which is useful if you want to read again last thing. If you like this feature, liberate your kindle and download latest version of pdf reader, drop it in /mnt/us/customupdates and press Shift Shift I to install it from louchpad. Then press Shift P D to start it. Wiki pages of project describe all available shortcuts and there is active thread on mobileread forum....</summary>
    <author>
        <name>Dobrica Pavlinušić</name>
        <uri>http://www.rot13.org/~dpavlin/</uri>
    </author>
    
        <category term="Kindle" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="pdf" label="pdf" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://blog.rot13.org/">
        <![CDATA[<p>
I really like Kindle because it allows me to run <a href="http://blog.rot13.org/2011/12/liberate-your-kindle-3-and-get-full-screen-terminal.html">my own selection of software</a> on it. However, when I try to persuade other Kindle owners in all the benefits of running custom software, I usually get response like: <em>but it already does everything I need</em>. That might be true, but that's only because you never tried to read two column article on Kindle...
</p>
<p>
Fortunately, we have <a href="https://github.com/hwhw/kindlepdfviewer">alternative pdf reader for Kindle</a> based on <a href="http://www.mupdf.com/">muPDF</a> library which is mostly written in lua. This is especially nice since it allowed me to <a href="https://github.com/hwhw/kindlepdfviewer/pull/21">add support for reading two-column pdf layouts</a> which you can see in <a href="http://youtu.be/moiRFi6Ttp4">following video</a>:
</p>

<p>
<iframe width="420" height="315" src="http://www.youtube.com/embed/moiRFi6Ttp4?rel=0" frameborder="0" allowfullscreen></iframe>
</p>

<p>
Basically, you press <tt>F</tt> to switch to new layout and then use <tt>fiveway</tt> buttons to move down the column, or right to move to top of next column, with page change if needed. If you move to left, you will be positioned to bottom of previous column which is useful if you want to read again last thing.
</p>
<p>
If you like this feature, <a href="https://github.com/dpavlin/k3libre/blob/master/liberate-kindle.txt">liberate your kindle</a> and <a href="https://github.com/dpavlin/kindlepdfviewer/downloads">download latest version of pdf reader</a>, drop it in <tt>/mnt/us/customupdates</tt> and press <tt>Shift Shift I</tt> to install it from louchpad. Then press <tt>Shift P D</tt> to start it. <a href="https://github.com/hwhw/kindlepdfviewer/wiki">Wiki pages</a> of project describe all available shortcuts and there is <a href="http://www.mobileread.com/forums/showthread.php?t=157047">active thread on mobileread forum</a>.
</p>]]>
        
    </content>
</entry>

<entry>
    <title>Printing from Koha to Zebra printers on local Windows machine</title>
    <link rel="alternate" type="text/html" href="http://blog.rot13.org/2012/02/printing-from-koha-to-zebra-printers-on-local-windows-machine.html" />
    <id>tag:blog.rot13.org,2012://1.748</id>

    <published>2012-02-10T11:20:56Z</published>
    <updated>2012-02-10T11:19:38Z</updated>

    <summary> As you know by now, I&apos;m somewhat biased towards pixel-exact printing on strange printers. This time around, I was tasked with requirement to make Koha print bar-code labels from web interface on Zebra S4M printers which are locally connected to Windows clients over USB. At first sight, this seems like an easy task. Zebra printers are supported under CUPS on Linux and OSX, so there shouldn&apos;t be any problems, right? For a start I found out that CUPS driver doesn&apos;t work well, mostly because it&apos;s older that Windows version of driver, and doesn&apos;t seem to send all ZPL codes required to print label. To make thing even worse, since printer is connected locally to Windows machine, it presents itself as Windows GDI printer which doesn&apos;t want to print ZPL (printer protocol) directly without wrapping ZPL in magic quotes and enabling it in Windows. On the other side, Koha tries to print labels using normal print dialog in Windows. This won&apos;t work well, because we (again) need pixel exact label as opposed to web page randomly scaled to printer label. To make this worse, client Windows machines are behind firewall, so I can&apos;t send label to IP address of client because all I can see in request is IP address of our firewall. To solve all this problem I decided to deploy following setup: Label design is done in Inkscape. To rasterize it to bitmap I decided to use rsvg-convert which has nice option to create exact bitmap size from SVG file in which I replace placeholders with variable values (bar-code and call number) Printers are installed in Windows using Generic/Text driver which is only one which will just pass data directly to printer To share printer to Linux, I decided to install lpd server so I don&apos;t have to open local Windows accounts to access printer (and they are behind firewall, so It&apos;s safe) To get local IP address of client (so I can send ZPL to internal IP address on which lpd is listening) I decided to redirect client to internal web server (behind firewall, same as clients) which knows client IP address, and knows where to send label. From user&apos;s perspective, Koha redirects clients to internal CGI script, which in turn rasterize label from request parameters, sends it to printer and redirect browser back to Koha page (with additional parameter of IP address of client/printer). This page shows label which was just printerd by pointing directly to internal server&apos;s PNG rendering of label. It also inserts data about printed label (including printer IP) in database for audit log. Since I couldn&apos;t use CUPS to produce ZPL for printer, I wrote Printer-Zebra which can convert pbm and pnm formats (easily created from png label using pgntopnm). Even better, it also includes script which can render ZPL printer output back to pbm bitmap which is the only good way to verify that your solution doesn&apos;t anti-alias bar-codes or does something similar to reduce print quality on back and white printers. Rasterizer was also very useful when tracking differences between Windows driver output (gathered by printing to File on Windows) and CUPS one....</summary>
    <author>
        <name>Dobrica Pavlinušić</name>
        <uri>http://www.rot13.org/~dpavlin/</uri>
    </author>
    
        <category term="projects" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="en" xml:base="http://blog.rot13.org/">
        <![CDATA[<p>
<a href="http://blog.rot13.org/assets_c/2012/02/zebra%20S4m-115.html" onclick="window.open('http://blog.rot13.org/assets_c/2012/02/zebra%20S4m-115.html','popup','width=1500,height=1500,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://blog.rot13.org/assets_c/2012/02/zebra%20S4m-thumb-320x320-115.jpg" width="320" height="320" alt="zebra S4m.jpg" class="mt-image-right" style="float: right; margin: 0 0 20px 20px;" /></a>

As you know by now, I'm somewhat biased towards <a href="http://blog.rot13.org/2010/08/evolis-dualys-pixel-exact-printing-without-cups.html">pixel-exact printing on strange printers</a>. This time around, I was tasked with requirement to make Koha print bar-code labels from web interface on <a href="http://www.zebra.com/id/zebra/na/en/index/products/printers/industrial_commercial/s4m.html">Zebra S4M printers</a> which are locally connected to Windows clients over USB.
</p>
<p>
At first sight, this seems like an easy task. Zebra printers are supported under CUPS on Linux and OSX, so there shouldn't be any problems, right? For a start I found out that CUPS driver doesn't work well, mostly because it's older that Windows version of driver, and doesn't seem to send all ZPL codes required to print label.
<br>
To make thing even worse, since printer is connected locally to Windows machine, it presents itself as Windows GDI printer which doesn't want to print ZPL (printer protocol) directly without wrapping ZPL in magic quotes and enabling it in Windows.
</p>
<p>
On the other side, Koha tries to print labels using normal print dialog in Windows. This won't work well, because we (again) need pixel exact label as opposed to web page randomly scaled to printer label. To make this worse, client Windows machines are behind firewall, so I can't send label to IP address of client because all I can see in request is IP address of our firewall.
</p>
<p>
To solve all this problem I decided to deploy following setup:
<ul>
<li>Label design is done in Inkscape. To rasterize it to bitmap I decided to use <a href="http://librsvg.sourceforge.net/">rsvg-convert</a> which has nice option to create exact bitmap size from SVG file in which I replace placeholders with variable values (bar-code and call number)
<li>Printers are installed in Windows using Generic/Text driver which is only one which will just pass data directly to printer
<li>To share printer to Linux, I decided to install <tt>lpd</tt> server so I don't have to open local Windows accounts to access printer (and they are behind firewall, so It's safe)
<li>To get local IP address of client (so I can send ZPL to internal IP address on which lpd is listening) I decided to redirect client to internal web server (behind firewall, same as clients) which knows client IP address, and knows where to send label.
<li>From user's perspective, Koha redirects clients to internal CGI script, which in turn rasterize label from request parameters, sends it to printer and redirect browser back to Koha page (with additional parameter of IP address of client/printer). This page shows label which was just printerd by pointing directly to internal server's PNG rendering of label. It also inserts data about printed label (including printer IP) in database for audit log.
</ul>
</p>
<p>
Since I couldn't use CUPS to produce ZPL for printer, I wrote <a href="https://github.com/dpavlin/Printer-Zebra">Printer-Zebra</a> which can convert <tt>pbm</tt> and <tt>pnm</tt> formats (easily created from png label using <tt>pgntopnm</tt>). Even better, it also includes script which can render ZPL printer output back to <tt>pbm</tt> bitmap which is the only good way to verify that your solution doesn't anti-alias bar-codes or does something similar to reduce print quality on back and white printers.
Rasterizer was also very useful when tracking differences between Windows driver output (gathered by printing to File on Windows) and CUPS one. 
</p>

]]>
        
    </content>
</entry>

<entry>
    <title>Nook Color as Android tablet</title>
    <link rel="alternate" type="text/html" href="http://blog.rot13.org/2012/01/nook-color-as-android-tablet.html" />
    <id>tag:blog.rot13.org,2012://1.747</id>

    <published>2012-01-21T11:30:42Z</published>
    <updated>2012-02-07T19:18:20Z</updated>

    <summary><![CDATA[ For a last month or so I used Barnes & Noble Nook Color as Android tablet. This post will try to explain what is wrong with Android tablets and now to fix this. For a start, original Android distribution on Nook doesn't make it really Android tablet (no market). But there is easy solution since this device is supported by CynanogenMod 7 for Nook Color to get proper Android distribution. So, let's get started with hints for easier life with your new tablet... adb doesn't see Nook Color For a start, you won't see Nook in adb devices listing. This is easily fixed with proper device id in ~/.android/adb_usb.ini like this: dpavlin@t61p:~/.android$ echo 0x2080 &gt; ~/.android/adb_usb.ini && adb kill-server && adb devices * daemon not running. starting it now on port 5037 * * daemon started successfully * List of devices attached 2011120012345678 device Nook Color specific application There are lot of application which will look quite broken on your Nook when running Android 2.3. Some of them require audio input, GPS or camera and they generally won't work. There is also problem with application which just don't know about wired 1024*600 screen size and produce strange small screen centered on big display. However, this is just a list of few extremely useful apps which you should install on Nook with CM7: Nook Color Tweaks - change speed of CPU, turn USB host more and more Nook Screen Recalibrate - having problems with screen sensitivity? Nook Key Editor allows you to map back and menu keys which are very useful on Android 2.3 to volume up/down which makes tablet much more useful. Once you install all of this, you will be painfully aware that Android 2.3 just isn't OS which works well on tables. So, let's try to see what Google has in source for tablets... Ice Cream Sandwich To get most out of Android on tablet, you have to hop over to CM9/ICS Nightly Builds and install unstable builds on ICS on Nook Color. After initial install reboot into recovery, flash Google Applications from gapps-ics-4.0.3-sam-noinit.zip, turn off signature verification and install fix-bootanimation.zip and telephony-permission-fix.zip. Unfortunately browser application doesn't work for me well, and usually segfaults with: F/libc ( 2878): Fatal signal 11 (SIGSEGV) at 0x0000001f (code=1) I/DEBUG ( 1072): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** I/DEBUG ( 1072): Build fingerprint: 'bn/bn_encore/encore:2.3.4/IML74K/228551:user/release-keys' I/DEBUG ( 1072): pid: 2878, tid: 2895 >>> com.android.browser ICS on Nook currently doesn't have hardware acceleration (but older Androids also doesn't have it) and it freezes from time to time (so you will get quite used to holding power button for 8 seconds or more to turn it off), but ICS is really so much better experience on tablet that I would really recommend it. Finally a note about hardware performance: Nook Color has 512Mb of RAM and Ti OMAP 3621 @ 800 MHz which makes it probably a bit slow for ICS. As o consequence I wouldn't really recommend any Android laptops which are slower than this for ICS. Update 2012-02-07: There is also CyanogenMod Kang build with OpenGL enabled which works very well. In fact, so well that it fixes problem in Hacker's keyboard :-)...]]></summary>
    <author>
        <name>Dobrica Pavlinušić</name>
        <uri>http://www.rot13.org/~dpavlin/</uri>
    </author>
    
        <category term="howto" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="android" label="Android" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="nook" label="Nook" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://blog.rot13.org/">
        <![CDATA[<p>
<a href="http://blog.rot13.org/assets_c/2012/01/nook-ics-112.html" onclick="window.open('http://blog.rot13.org/assets_c/2012/01/nook-ics-112.html','popup','width=540,height=720,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://blog.rot13.org/assets_c/2012/01/nook-ics-thumb-320x426-112.jpg" width="320" height="426" alt="nook-ics.jpg" class="mt-image-right" style="float: right; margin: 0 0 20px 20px;" /></a>

For a last month or so I used <a href="http://www.barnesandnoble.com/p/nook-color-barnes-noble/1100437663">Barnes & Noble Nook Color</a> as Android tablet. This post will try to explain what is wrong with Android tablets and now to fix this.
</p>
<p>
For a start, original Android distribution on Nook doesn't make it really Android tablet (no market). But there is easy solution since this device is supported by <a href="http://www.cyanogenmod.com/devices/nook-color">CynanogenMod 7 for Nook Color</a> to get proper Android distribution. So, let's get started with hints for easier life with your new tablet...
</p>

<h2>adb doesn't see Nook Color</h2>

<p>
For a start, you won't see Nook in <tt>adb devices</tt> listing. This is easily fixed with proper device id in <tt>~/.android/adb_usb.ini</tt> like this:

<pre>
dpavlin@t61p:~/.android$ echo 0x2080 &gt; ~/.android/adb_usb.ini && adb kill-server && adb devices
* daemon not running. starting it now on port 5037 *
* daemon started successfully *
List of devices attached 
2011120012345678        device
</pre>

</p>

<h2>Nook Color specific application</h2>

<p>
There are lot of application which will look quite broken on your Nook when running Android 2.3. Some of them require audio input, GPS or camera and they generally won't work. There is also problem with application which just don't know about wired 1024*600 screen size and produce strange small screen centered on big display.
</p>
<p>
However, this is just a list of few extremely useful apps which you should install on Nook with CM7:

<ul>
<li><a href="https://market.android.com/details?id=com.dalingrin.nookcolortweaks">Nook Color Tweaks</a> - change speed of CPU, turn USB host more and more
<li><a href="https://market.android.com/details?id=com.assid.android.nookrecalibrate">Nook Screen Recalibrate</a> - having problems with screen sensitivity?
<li><a href="http://forum.xda-developers.com/showthread.php?t=965023">Nook Key Editor</a> allows you to map back and menu keys which are very useful on Android 2.3 to volume up/down which makes tablet much more useful.
</ul>

Once you install all of this, you will be painfully aware that Android 2.3 just isn't OS which works well on tables. So, let's try to see what Google has in source for tablets...
</p>

<h2>Ice Cream Sandwich</h2>

<p>
To get most out of Android on tablet, you have to hop over to <a href="http://forum.xda-developers.com/showthread.php?t=1444943">CM9/ICS Nightly Builds</a> and install unstable builds on ICS on Nook Color.
After initial install reboot into recovery, flash Google Applications from <tt>gapps-ics-4.0.3-sam-noinit.zip</tt>, turn off signature verification and install <tt>fix-bootanimation.zip</tt> and <tt>telephony-permission-fix.zip</tt>. Unfortunately browser application doesn't work for me well, and usually segfaults with:
<pre>
F/libc    ( 2878): Fatal signal 11 (SIGSEGV) at 0x0000001f (code=1)
I/DEBUG   ( 1072): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
I/DEBUG   ( 1072): Build fingerprint: 'bn/bn_encore/encore:2.3.4/IML74K/228551:user/release-keys'
I/DEBUG   ( 1072): pid: 2878, tid: 2895  >>> com.android.browser <<<
</pre>
</p>
<p>
ICS on Nook currently doesn't have hardware acceleration (<a href="https://plus.google.com/105051985738280261832/posts/2FXDCz8x93s">but older Androids also doesn't have it</a>) and it freezes from time to time (so you will get quite used to holding power button for 8 seconds or more to turn it off), but ICS is really so much better experience on tablet that I would really recommend it.
</p>
<p>
Finally a note about hardware performance: Nook Color has 512Mb of RAM and Ti OMAP 3621 @ 800 MHz which makes it probably a bit slow for ICS. As o consequence I wouldn't really recommend any Android laptops which are slower than this for ICS.
</p>
<p>
<em>Update 2012-02-07</em>: There is also <a href="http://techerrata.com/browse/nightly_kangs/encore">CyanogenMod Kang build with OpenGL</a> enabled which works very well. In fact, so well that it fixes <a href="http://code.google.com/p/hackerskeyboard/issues/detail?id=169">problem in Hacker's keyboard</a> :-)
</p>
]]>
        
    </content>
</entry>

<entry>
    <title>28C3: recommended watching</title>
    <link rel="alternate" type="text/html" href="http://blog.rot13.org/2011/12/28c3-recommended-watching.html" />
    <id>tag:blog.rot13.org,2011://1.746</id>

    <published>2011-12-31T13:13:49Z</published>
    <updated>2012-01-25T12:11:37Z</updated>

    <summary> Each year, we get a treat right before end of the year in form of 28C3. This year, I can recommend following lectures as a must-see: r0ket++ video Very nice ARM Cortex M3 embedded device with Nokia LCD, battery, RF interface and extension headers. 802.11 Packets in Packets video Drop wifi packet on unsuspecting listeners without access to network segment! Defending mobile phones video Visit GSMmap.org to see if your GSM networks are protecting you or contribute data! Reverse Engineering USB Devices video Very similar to my approach to USB examinations. How governments have tried to block Tor video It&apos;s arms race all over again, this time on Internet. Reverse-engineering a Qualcomm baseband video I can&apos;t wait to see release of this tools on code.google.com Available at http://code.google.com/p/qcombbdbg/ KinectFusion video I would love to see something similar in open source code. Cellular protocol stacks for Internet video Very good overview of cellular stack as it is today Implementation of MITM Attack on HDCP-Secured Links video NeTv is very interesting ARM/FPGA/Linux device which overlays webkit content over HDMI signal on your TV using chroma key. Introducing Osmo-GMR video Osmocom got some support for satellite phones bup: Git for backups video Nice backup system with de-duplication implemented on top of git&apos;s pack file...</summary>
    <author>
        <name>Dobrica Pavlinušić</name>
        <uri>http://www.rot13.org/~dpavlin/</uri>
    </author>
    
        <category term="conferences" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="en" xml:base="http://blog.rot13.org/">
        <![CDATA[<img alt="28c3.png" src="http://blog.rot13.org/2011/12/31/28c3.png" width="145" height="141" class="mt-image-right" style="float: right; margin: 0 0 20px 20px;" />
<p>
Each year, we get a treat right before end of the year in form of <a href="http://events.ccc.de/congress/2011/wiki/Welcome">28C3</a>. This year, I can recommend following lectures as a must-see:
<ul>

<li>
<a href="http://events.ccc.de/congress/2011/Fahrplan/events/4777.en.html">r0ket++</a>
<a href="http://ftp.ccc.de/congress/28C3/mp4-h264-HQ/28c3-4777-en-r0ket_h264.mp4">video</a>
<br>Very nice ARM Cortex M3 embedded device with Nokia LCD, battery, RF interface and extension headers.

<li>
<a href="http://events.ccc.de/congress/2011/Fahrplan/events/4766.en.html">802.11 Packets in Packets</a> 
<a href="http://ftp.ccc.de/congress/28C3/mp4-h264-HQ/28c3-4766-en-802_11_packets_in_packets_h264.mp4">video</a>
<br>Drop wifi packet on unsuspecting listeners without access to network segment!

<li>
<a href="http://events.ccc.de/congress/2011/Fahrplan/events/4736.en.html">Defending mobile phones</a>
<a href="http://ftp.ccc.de/congress/28C3/mp4-h264-HQ/28c3-4736-en-defending_mobile_phones_h264.mp4">video</a>
<br>Visit <a href="http://gsmmap.org">GSMmap.org</a> to see if your GSM networks are protecting you or <a href="http://srlabs.de/gsm-map-tutorial/">contribute data</a>!

<li>
<a href="http://events.ccc.de/congress/2011/Fahrplan/events/4847.en.html">Reverse Engineering USB Devices</a>
<a href="http://ftp.ccc.de/congress/28C3/mp4-h264-HQ/28c3-4847-en-reverse_engineering_usb_devices_h264.mp4">video</a>
<br>Very similar to my approach to USB examinations.

<li>
<a href="http://events.ccc.de/congress/2011/Fahrplan/events/4800.en.html">How governments have tried to block Tor</a>
<a href="http://ftp.ccc.de/congress/28C3/mp4-h264-HQ/28c3-4800-en-how_governments_have_tried_to_block_tor_h264.mp4">video</a>
<br>It's arms race all over again, this time on Internet.

<li>
<a href="http://events.ccc.de/congress/2011/Fahrplan/events/4735.en.html">Reverse-engineering a Qualcomm baseband</a>
<a href="http://ftp.ccc.de/congress/28C3/mp4-h264-HQ/28c3-4735-en-reverse_engineering_a_qualcomm_baseband_h264.mp4">video</a>
<br><del>
I can't wait to see release of this tools on <a href="http://code.google.com/u/112978292662734058287/">code.google.com</a></del>
Available at <a href="http://code.google.com/p/qcombbdbg/">http://code.google.com/p/qcombbdbg/</a>

<li>
<a href="http://events.ccc.de/congress/2011/Fahrplan/events/4928.en.html">KinectFusion</a>
<a href="http://ftp.ccc.de/congress/28C3/mp4-h264-HQ/28c3-4928-en-kinectfusion_h264.mp4">video</a>
<br>I would love to see something similar in open source code.

<li>
<a href="http://events.ccc.de/congress/2011/Fahrplan/events/4663.en.html">Cellular protocol stacks for Internet</a>
<a href="http://ftp.ccc.de/congress/28C3/mp4-h264-HQ/28c3-4663-en-cellular_protocol_stacks_for_internet_h264.mp4">video</a>
<br>Very good overview of cellular stack as it is today

<li>
<a href="http://events.ccc.de/congress/2011/Fahrplan/events/4686.en.html">Implementation of MITM Attack on HDCP-Secured Links</a>
<a href="http://ftp.ccc.de/congress/28C3/mp4-h264-HQ/28c3-4686-en-implementation_of_mitm_attack_on_hdcp_secured_links_h264.mp4">video</a>
<br>NeTv is very interesting ARM/FPGA/Linux device which overlays webkit content over HDMI signal on your TV using chroma key.

<li>
<a href="http://events.ccc.de/congress/2011/Fahrplan/events/4688.en.html">Introducing Osmo-GMR</a>
<a href="http://ftp.ccc.de/congress/28C3/mp4-h264-HQ/28c3-4688-en-introducing_osmo_gmr_h264.mp4">video</a>
<br>Osmocom got some support for satellite phones

<li>
<a href="http://events.ccc.de/congress/2011/Fahrplan/events/4587.en.html">bup: Git for backups</a>
<a href="http://ftp.ccc.de/congress/28C3/mp4-h264-HQ/28c3-4587-en-bup_git_for_backups_h264.mp4">video</a>
<br>Nice backup system with de-duplication implemented on top of git's pack file

</ul>

</p>
]]>
        
    </content>
</entry>

<entry>
    <title>batman-adv layer 2 mesh ad-hoc network at NSND Moravice 2011</title>
    <link rel="alternate" type="text/html" href="http://blog.rot13.org/2011/12/batman-adv-layer-2-mesh-ad-hoc-network-at-nsnd-moravice-2011.html" />
    <id>tag:blog.rot13.org,2011://1.745</id>

    <published>2011-12-21T21:35:13Z</published>
    <updated>2011-12-21T21:35:34Z</updated>

    <summary> We had another gathering called Nothing will happen in Moravice, and this time we wanted to be prepared for it. So we got 2 WRT and 2 TP-Link devices with good faith that we will have stable Internet there. However, our telecom provider decided to screw up our order to increase bandwidth from 4Mbit/s to 10Mbit/s for event and instead decided to downgrade our access to 512Kbit/s. So we opted to create following simple network architecture which involved multiple hops to alternative 4Mbit/s upstream and batman-adv mesh setup. batman-adv is quite cool layer-2 mash network which operates in ad-hoc mode and allows adaptive routing over mash and multiple upstream providers (at DHCP request or renew time, so we made our DHCP lease time down to 5 minutes). Joining network is quite simple: iwconfig wlan0 mode ad-hoc essid nsnd-batman ifconfig wlan0 mtu 1528 modprobe batman_adv batctl if add wlan0 ifconfig wlan0 up ifconfig bat0 up dhclient bat0 This will bring any laptop with ad-hoc support (and not all of them have it), and relatively recent kernel (2.6.32 from Debian stable is a bit too old - batman-adv got included in 2.6.33 kernel) up and running on mash network. My own experience with this experiment is very positive, mostly because we had around 5 clients in mash at any time, compared with overloaded WRTs which handled rest of 40 wifi enabled devices. But, I hope that during next event more people will upgrade to 2.6.33 or newer kernels, so we can have even better mash connectivity....</summary>
    <author>
        <name>Dobrica Pavlinušić</name>
        <uri>http://www.rot13.org/~dpavlin/</uri>
    </author>
    
        <category term="hack-of-the-week" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="en" xml:base="http://blog.rot13.org/">
        <![CDATA[<a href="http://blog.rot13.org/assets_c/2011/12/NSND2011Moravicewifi-106.html" onclick="window.open('http://blog.rot13.org/assets_c/2011/12/NSND2011Moravicewifi-106.html','popup','width=960,height=720,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://blog.rot13.org/assets_c/2011/12/NSND2011Moravicewifi-thumb-320x240-106.png" width="320" height="240" alt="NSND2011Moravicewifi.png" class="mt-image-right" style="float: right; margin: 0 0 20px 20px;" /></a>
<p>
We had another gathering called Nothing will happen in Moravice, and this time we wanted to be prepared for it. So we got 2 WRT and 2 TP-Link devices with good faith that we will have stable Internet there. However, our telecom provider decided to screw up our order to increase bandwidth from 4Mbit/s to 10Mbit/s for event and instead decided to downgrade our access to 512Kbit/s. So we opted to create following simple network architecture which involved multiple hops to alternative 4Mbit/s upstream and batman-adv mesh setup.
</p>
<p>
<a href="http://www.open-mesh.org/wiki/batman-adv">batman-adv</a> is quite cool layer-2 mash network which operates in ad-hoc mode and allows adaptive routing over mash and multiple upstream providers (at DHCP request or renew time, so we made our DHCP lease time down to 5 minutes). Joining network is quite simple:
<pre>
iwconfig wlan0 mode ad-hoc essid nsnd-batman
ifconfig wlan0 mtu 1528
modprobe batman_adv
batctl if add wlan0

ifconfig wlan0 up
ifconfig bat0 up
dhclient bat0
</pre>
This will bring any laptop with ad-hoc support (and not all of them have it), and relatively recent kernel (2.6.32 from Debian stable is a bit too old - batman-adv got included in <a href="http://kernelnewbies.org/Linux_2_6_33">2.6.33</a> kernel) up and running on mash network.
</p>
<p>
My own experience with this experiment is very positive, mostly because we had around 5 clients in mash at any time, compared with overloaded WRTs which handled rest of 40 wifi enabled devices. But, I hope that during next event more people will upgrade to 2.6.33 or newer kernels, so we can have even better mash connectivity.
</p>
]]>
        
    </content>
</entry>

<entry>
    <title>Liberate your Kindle 3 and get full-screen terminal!</title>
    <link rel="alternate" type="text/html" href="http://blog.rot13.org/2011/12/liberate-your-kindle-3-and-get-full-screen-terminal.html" />
    <id>tag:blog.rot13.org,2011://1.744</id>

    <published>2011-12-03T17:10:09Z</published>
    <updated>2011-12-03T17:10:45Z</updated>

    <summary><![CDATA[ As you might know by now, I'm very happy user of Kindle 3 (keyboard) and Kindle DX graphite. One of reasons why I choose those devices was community around Kindle Developer's Corner at mobileread forum. With new generation of Amazon's Kindle device on the way, let me stress that for me older Kindle 3 devices are more interesting since we still don't have the way to run home-brew software on newer Kindle 4. One of the good things about next generation of Kindles is that older models get sold second-hand at reasonable price, and let me re-iterate: for around 100&euro; older Kindle 3 with keyboard are great devices. But what would you do with one when you get your hands on? Start a k3libre project to develop and document free libre command-line tools for Kindle development. It's very much work in progress, with useful example scripts which describe framebuffer format, but also a handy step-by-step instruction on how to liberate your Kindle by installing jailbreak and usbnetwork to get root ssh access over usb cable. Next step is launchpad which listens on /dev/input/input? and allows you to bind execution of programs on key-presses. We are doing all this to install to nice full-screen Kindle terminal. You can do most of this work in under an hour, so there is no excuse not to read man pages on your Kindle! So now that you can run your own software on Kindle, with which would you like to start? I would suggest kindlepdfviewer - a PDF viewer made for e-ink framebuffer devices, using muPDF. It's implemented in lua, so adding new features are rather easy, and latest development include serialization of state into SQLite database and drawing characters on screen! OK, it's in early stage of developments, but already useful on real Kindle, and if you don't like something you can always just edit lua code a bit :-)...]]></summary>
    <author>
        <name>Dobrica Pavlinušić</name>
        <uri>http://www.rot13.org/~dpavlin/</uri>
    </author>
    
        <category term="Kindle" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="en" xml:base="http://blog.rot13.org/">
        <![CDATA[<a href="http://blog.rot13.org/assets_c/2011/12/kindle-k3g-myts-6-103.html" onclick="window.open('http://blog.rot13.org/assets_c/2011/12/kindle-k3g-myts-6-103.html','popup','width=600,height=800,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://blog.rot13.org/assets_c/2011/12/kindle-k3g-myts-6-thumb-320x426-103.jpg" width="320" height="426" alt="kindle-k3g-myts-6.jpg" class="mt-image-right" style="float: right; margin: 0 0 20px 20px;" /></a>
<p>
As you might know by now, I'm very happy user of Kindle 3 (keyboard) and Kindle DX graphite. One of reasons why I choose those devices was community around <a href="http://www.mobileread.com/forums/forumdisplay.php?f=150">Kindle Developer's Corner at mobileread forum</a>. With new generation of Amazon's Kindle device on the way, let me stress that for me older Kindle 3 devices are more interesting since we <a href="http://www.mobileread.com/forums/showthread.php?t=151537">still don't have the way to run home-brew software on newer Kindle 4</a>.</p>
<p>
One of the good things about next generation of Kindles is that older models get sold second-hand at reasonable price, and let me re-iterate: for around 100&euro; older Kindle 3 with keyboard are great devices. But what would you do with one when you get your hands on? Start a <a href="https://github.com/dpavlin/k3libre">k3libre project to develop and document free libre command-line tools for Kindle development</a>. It's very much work in progress, with useful example scripts which describe framebuffer format, but also a handy step-by-step instruction on how to <a href="https://github.com/dpavlin/k3libre/blob/master/liberate-kindle.txt">liberate your Kindle</a> by installing <a href="http://www.mobileread.com/forums/showthread.php?t=88004">jailbreak and usbnetwork</a> to get root ssh access over usb cable. Next step is <a href="http://www.mobileread.com/forums/showthread.php?t=97636">launchpad</a> which listens on <tt>/dev/input/input?</tt> and allows you to bind execution of programs on key-presses. We are doing all this to <a href="http://www.mobileread.com/forums/showthread.php?t=154500">install to nice full-screen Kindle terminal</a>. You can do most of this work in under an hour, so there is no excuse not to read man pages on your Kindle!
</p>
<p>
So now that you can run your own software on Kindle, with which would you like to start? I would suggest <a href="https://github.com/hwhw/kindlepdfviewer">kindlepdfviewer</a> - a PDF viewer made for e-ink framebuffer devices, using muPDF. It's implemented in lua, so adding new features are rather easy, and latest development include serialization of state into SQLite database and drawing characters on screen! OK, it's in early stage of developments, but already useful on real Kindle, and if you don't like something you can always just edit lua code a bit :-)
</p>
]]>
        
    </content>
</entry>

<entry>
    <title>n2n: connect your networks using P2P VPN</title>
    <link rel="alternate" type="text/html" href="http://blog.rot13.org/2011/10/n2n-connect-your-networks-using-p2p-vpn.html" />
    <id>tag:blog.rot13.org,2011://1.743</id>

    <published>2011-10-08T11:47:42Z</published>
    <updated>2011-10-09T17:23:36Z</updated>

    <summary> Sometimes, you need to connect two networks in some way. My usual motivation is ability to access machines behind multiple NATs for easy system administration. So far, I used combination of OpenVPN and DynamicForward in ssh with clever use of ProxyCommand and nc with a sprinkle of proxy.pac for Firefox to make everything seemingly work. However, I never successfully managed to tunnel various JavaWebStart based remote consoles which want to connect directly from your machine to remote IP using sockets (for which you have to disable all proxy settings using jcontrol and selecting direct connection). So this got me thinking. I could configure another OpenVPN for this, but it has many steps and I was lazy. Wouldn&apos;t it be great if there is some kind of P2P network like Skype or Hamachi for Linux? Something like this: n2n: a Layer Two Peer-to-Peer VPN is exactly what I was looking for. It allows you to construct IP network over nodes behind NAT. But is it really easier to configure for specific example of accessing private network on another LAN behind NAT? Let&apos;s find out. Steps are simple: Install n2n (you will have to do this on supernode and two nodes) all$ sudo apt-get install n2n Start super node on public address with DNS name super.example.com internet$ supernode -l 1234 Start first client local# edge -c community -d community -k secret \ -l super.example.com:1234 -a 10.1.2.1 Start remote end-point somewhere within LAN remote# edge -c community -d community -k secret \ -l super.example.com:1234 -a 10.1.2.2 -r Note changed IP address and -r flag which will allow us to route over this node. remote# sysctl -w net.ipv4.ip_forward=1 remote# iptables -t nat -A POSTROUTING -s 10.1.2.1 -o tun0 -j MASQUERADE This will turn forwarding and NAT for our packets coming from community tap interface and going out through tun0 to LAN. We also need to setup route on local side for remote LAN network: local# ip route add 172.18.0.0/16 via 10.1.2.2 And we are done. In just 6 commands we routed remote LAN 172.18.0.0/16 over our 10.1.2.0/24 n2n interface to our local machine. And you don&apos;t have to stop at that. By installing additional edge in some other local network, you can get instant connectivity to your internal administrative network. This is very useful if you want to access your private repositories on local machine or need to open arbitrary sockets between machines....</summary>
    <author>
        <name>Dobrica Pavlinušić</name>
        <uri>http://www.rot13.org/~dpavlin/</uri>
    </author>
    
        <category term="hack-of-the-week" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="en" xml:base="http://blog.rot13.org/">
        <![CDATA[<p>
Sometimes, you need to connect two networks in some way. My usual motivation is ability to access machines behind multiple NATs for easy system administration. So far, I used combination of OpenVPN and DynamicForward in ssh with clever use of ProxyCommand and nc with a sprinkle of proxy.pac for Firefox to make everything seemingly work. However, I never successfully managed to tunnel various JavaWebStart based remote consoles which want to connect directly from your machine to remote IP using sockets (for which you have to disable all proxy settings using jcontrol and selecting direct connection).
</p>
<p>
So this got me thinking. I could configure another OpenVPN for this, but it has many steps and I was lazy. Wouldn't it be great if there is some kind of P2P network like Skype or Hamachi for Linux? Something like this:
</p>
<a href="http://www.ntop.org/products/n2n/">
<img alt="n2n_network.png" src="http://blog.rot13.org/2011/10/06/n2n_network.png" width="442" height="295" class="mt-image-center" style="text-align: center; display: block; margin: 0 auto 20px;" />
</a>
<p>
<a href="http://www.ntop.org/products/n2n/">n2n: a Layer Two Peer-to-Peer VPN</a> is exactly what I was looking for. It allows you to construct IP network over nodes behind NAT. But is it really easier to configure for specific example of accessing private network on another LAN behind NAT? Let's find out.
</p>
<p>
Steps are simple:
<ul>
<li>Install n2n (you will have to do this on supernode and two nodes)
<pre>
all$ sudo apt-get install n2n
</pre>
<li>Start super node on public address with DNS name super.example.com
<pre>
internet$ supernode -l 1234
</pre>
<li>Start first client
<pre>
local# edge -c community -d community  -k secret \
  -l super.example.com:1234 -a 10.1.2.1
</pre>
<li>Start remote end-point somewhere within LAN
<pre>
remote# edge -c community -d community  -k secret \
  -l super.example.com:1234 -a <b>10.1.2.2 -r</b>
</pre>
Note changed IP address and <tt>-r</tt> flag which will allow us to route over this node.
<pre>
remote# sysctl -w net.ipv4.ip_forward=1
remote# iptables -t nat -A POSTROUTING -s 10.1.2.1 -o tun0 -j MASQUERADE
</pre>
This will turn forwarding and NAT for our packets coming from community tap interface and going out through tun0 to LAN. We also need to setup route on local side for remote LAN network:
<pre>
local# ip route add 172.18.0.0/16 via 10.1.2.2
</pre>
</ul>
And we are done. <strong>In just 6 commands we routed remote LAN</strong> 172.18.0.0/16 over our 10.1.2.0/24 n2n interface to our local machine. And you don't have to stop at that. By installing additional edge in some other local network, you can get instant connectivity to your internal administrative network. This is very useful if you want to access your private repositories on local machine or need to open arbitrary sockets between machines.
</p>
]]>
        
    </content>
</entry>

<entry>
    <title>Collecting disk SMART informations from large disk pool</title>
    <link rel="alternate" type="text/html" href="http://blog.rot13.org/2011/09/collecting-disk-smart-information-from-large-disk-pool.html" />
    <id>tag:blog.rot13.org,2011://1.742</id>

    <published>2011-09-30T12:38:42Z</published>
    <updated>2011-09-30T20:58:36Z</updated>

    <summary> Last few weeks, I was configuring huge ZFS pool of 50 disks over three machines. Aside from benchmarking, I wanted to setup monitoring of this disk pool. smartctl comes as natural candidate for getting smart data, but where should I keep it? I recently learned of git log -p output format which shows nicely changes in your source files, so natural question was can I use git to track smart disk statistics? As it turns out, getting overview of disk layout is really easy under Linux if you know where to look. /proc/partitions first comes to mind, but it lacks one really important peace of information: disk serial number. It&apos;s only peace of information which won&apos;t change between reboots when you have to spin up 30+ disks, so you really want to use it as identification for disks, instead of device name for example (which I tried on first try and learned that disks move around). Good naming of dump files is as important as always. In the end, I opted to use smart.id where id part is from /dev/disk/by-id/scsi-something. Paths in /dev/disk/by-id/ are essential useful when creating storage pools because they also don&apos;t change between reboots. Now that we know where to look for disk identification and serial number, we are ready to start collecting smart data. However, this data is much more useful if coupled with info from controllers, so final version of smart-dump.sh script also supports dumping of controller status for LSI Logic / Symbios Logic and 3ware controllers. Have in mind that collecting smart info from disks does interrupt data transfers, so if you have huge pool you might want to spread those requests (or even issue them in parallel if you want one huge interruption as opposed to several smaller ones). So was all this worth an effort? In fact, it was! In our sample of 50 3T disks, one disk reported errors after just 192 hours of lifetime. It would probably report it earlier, but this was second time that I run smartctl -t long on it. On the other side, it passed long check on first test which was 8 hours of LifeTime. Even if you read Failure Trends in a Large Disk Drive Population paper from Google, and concluded that smart is lying to you and you could ignore it, please monitor your drives!...</summary>
    <author>
        <name>Dobrica Pavlinušić</name>
        <uri>http://www.rot13.org/~dpavlin/</uri>
    </author>
    
        <category term="hack-of-the-week" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="en" xml:base="http://blog.rot13.org/">
        <![CDATA[<p>
Last few weeks, I was configuring huge ZFS pool of 50 disks over three machines. Aside from benchmarking, I wanted to setup monitoring of this disk pool. <a href="http://smartmontools.sourceforge.net">smartctl</a> comes as natural candidate for getting smart data, but where should I keep it? I recently learned of <tt>git log -p</tt> output format which shows nicely changes in your source files, so natural question was can I use git to track smart disk statistics?
</p>
<p>
As it turns out, getting overview of disk layout is really easy under Linux if you know where to look. <tt>/proc/partitions</tt> <a href="http://sysadmin-cookbook.rot13.org/#dump_sh">first comes to mind</a>, but it lacks one really important peace of information: <em>disk serial number</em>. It's only peace of information which won't change between reboots when you have to spin up 30+ disks, so you really want to use it as identification for disks, instead of device name for example (which I tried on first try and learned that disks move around).
</p>
<p>
Good naming of dump files is as important as always. In the end, I opted to use <tt>smart.id</tt> where <tt>id</tt> part is from <tt>/dev/disk/by-id/scsi-something</tt>. Paths in <tt>/dev/disk/by-id/</tt> are <em>essential useful when creating storage pools</em> because they also don't change between reboots.
</p>
<p>
Now that we know where to look for disk identification and serial number, we are ready to start collecting smart data. However, this data is much more useful if coupled with info from controllers, so final version of <a href="http://sysadmin-cookbook.rot13.org/#dump_smart_sh">smart-dump.sh</a> script also supports dumping of controller status for LSI Logic / Symbios Logic and 3ware controllers. Have in mind that collecting smart info from disks does interrupt data transfers, so if you have huge pool you might want to spread those requests (or even issue them in parallel if you want one huge interruption as opposed to several smaller ones).
</p>
<p>
So was all this worth an effort? In fact, it was! In our sample of 50 3T disks, one disk reported errors after just 192 hours of lifetime. It would probably report it earlier, but this was second time that I run <tt>smartctl -t long</tt> on it. On the other side, it passed long check on first test which was 8 hours of LifeTime.

Even if you read <a href="http://labs.google.com/papers/disk_failures.pdf">Failure Trends in a Large Disk Drive Population</a> paper from Google, and concluded that smart is lying to you and you could ignore it, please monitor your drives!
</p>
]]>
        
    </content>
</entry>

<entry>
    <title>ZFS on Linux and pool replication</title>
    <link rel="alternate" type="text/html" href="http://blog.rot13.org/2011/09/zfs-on-linux-and-pool-replication.html" />
    <id>tag:blog.rot13.org,2011://1.741</id>

    <published>2011-09-07T11:34:31Z</published>
    <updated>2011-09-07T12:01:37Z</updated>

    <summary> I have been using ZFS on Linux for some time to provide backup appliance using zfs-fuse. Since then, we got native ZFS implementation on Linux, so I decided to move by backup pool from zfs-fuse to in-kernel ZFS. Additional reason to move pool over to new machine was to change pool&apos;s RAID level. In current ZFS implementation(s) you can&apos;t change mirror to RAIDZ1 without re-creating pool and then transfering data over using zfs send and zfs receive. However, when you are creating snapshots for years, and expiring them using script you will have hundreds of snapshots which you need to transfer. This is where zfs-pool-replicate.pl script comes handy. It uses Net::OpenSSH to connect to two machines (source and destination), list all snapshots on source and transfer them to destination. If you have filesystem without snapshots it will create one @send snapshot which will be transferred. It will also optionally use compression for transfer of snapshot over the network. I am using LZO which is fast compression which nicely transfers 150Mb/s or more over normal 1Gbit/s network without much CPU overheard (and we all have multi-core machines anyway, right?). Current implementation allows you to re-run replication script to transfer only new snapshots creating handy disaster recovery solution. Current implementation is designed to run from third (management) machine, so I can envision central storage administration tool which will also allow you to transfer LVM snapshots into ZFS snapshots. For now, I&apos;m using shell script for that, but rewriting it in perl would improve error recovery and reporting....</summary>
    <author>
        <name>Dobrica Pavlinušić</name>
        <uri>http://www.rot13.org/~dpavlin/</uri>
    </author>
    
        <category term="hack-of-the-week" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="perl" label="perl" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="replication" label="replication" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="zfs" label="zfs" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://blog.rot13.org/">
        <![CDATA[<p>
I have been using ZFS on Linux for some time to provide <a href="http://blog.rot13.org/2009/06/storage-appliance-with-containers-using-linux-and-zfs.html">backup appliance</a> using <a href="http://zfs-fuse.net/">zfs-fuse</a>. Since then, we got <a href="http://zfsonlinux.org/">native ZFS implementation on Linux</a>, so I decided to move by backup pool from zfs-fuse to in-kernel ZFS.
</p>
<p>
Additional reason to move pool over to new machine was to change pool's RAID level. In current ZFS implementation(s) you can't change mirror to RAIDZ1 without re-creating pool and then transfering data over using <tt>zfs send</tt> and <tt>zfs receive</tt>. However, when you are creating snapshots for years, and <a href="http://sysadmin-cookbook.rot13.org/#zfs_expire_snapshot_pl">expiring them using script</a> you will have hundreds of snapshots which you need to transfer.
</p>
<p>
This is where <a href="http://sysadmin-cookbook.rot13.org/#zfs_replicate_pool_pl">zfs-pool-replicate.pl</a> script comes handy. It uses <a href="http://search.cpan.org/dist/Net-OpenSSH/">Net::OpenSSH</a> to connect to two machines (source and destination), list all snapshots on source and transfer them to destination. If you have filesystem without snapshots it will create one <tt>@send</tt> snapshot which will be transferred. It will also optionally use compression for transfer of snapshot over the network. I am using LZO which is fast compression which nicely transfers 150Mb/s or more over normal 1Gbit/s network without much CPU overheard (and we all have multi-core machines anyway, right?). Current implementation allows you to re-run replication script to transfer only new snapshots creating handy disaster recovery solution.
</p>
<p>
Current implementation is designed to run from third (management) machine, so I can envision central storage administration tool which will also allow you to transfer LVM snapshots into ZFS snapshots. For now, I'm using shell script for that, but rewriting it in perl would improve error recovery and reporting.
</p>
]]>
        
    </content>
</entry>

<entry>
    <title>MySQL innodb_file_per_table upgrade</title>
    <link rel="alternate" type="text/html" href="http://blog.rot13.org/2011/06/mysql-innodb-file-per-table-upgrade.html" />
    <id>tag:blog.rot13.org,2011://1.740</id>

    <published>2011-06-20T10:40:42Z</published>
    <updated>2011-06-20T10:40:39Z</updated>

    <summary><![CDATA[ By default, MySQL installation on Debian comes without innodb_file_per_table option which spread tables in individual InnoDB files. Based on your usage patterns or backup strategies this might be better filesystem organization than one big /var/lib/mysql/ibdata1 file. I first heard about it in OurSQL Episode 36: It's Not Our (De)fault!. It's great podcast, but to be honest with each new episode I wish to have only PostgreSQL servers to maintain... To enable this option you will need to create configuration file and restart MySQL server: koha:/etc/mysql/conf.d# cat &gt; file-per-table.cnf [mysqld] innodb_file_per_table CTRL+D koha:/etc/mysql/conf.d# /etc/init.d/mysql restart This won't change anything, because only new tables will be created in separate files. But, we can use ALTER TABLE table ENGINE=InnoDB on each table to force InnoDB to re-read tables and create separate files: mysqlshow koha --status | grep InnoDB | cut -d'|' -f2 | sed -e 's/^/alter table/' -e 's/$/ engine=InnoDB;/' | mysql -v koha If you replace grep InnoDB with grep MyISAM you might use same snippet to convert MyISAM tables into InnoDB (if you still have them or don't use fulltext search). I think that system administration is like gardening. I don't know anything about gardening, but it seems to involve a lot of care here and there, seemingly without much pattern. In that sense, it's similar to wiki editing, you start somewhere and you really don't know where it lead you to....]]></summary>
    <author>
        <name>Dobrica Pavlinušić</name>
        <uri>http://www.rot13.org/~dpavlin/</uri>
    </author>
    
        <category term="hack-of-the-week" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="mysql" label="mysql" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://blog.rot13.org/">
        <![CDATA[<p>
By default, MySQL installation on Debian comes without <a href="http://dev.mysql.com/doc/refman/5.1/en/innodb-multiple-tablespaces.html">innodb_file_per_table</a> option which spread tables in individual InnoDB files. Based on your usage patterns or backup strategies this might be better filesystem organization than one big <tt>/var/lib/mysql/ibdata1</tt> file. I first heard about it in <a href="http://www.technocation.org/content/oursql-episode-36%3A-it%2526%2523039%3Bs-not-our-%28de%29fault!-part-1">OurSQL Episode 36: It's Not Our (De)fault!</a>. It's great podcast, but to be honest with each new episode I wish to have only PostgreSQL servers to maintain...
</p>
<p>
To enable this option you will need to create configuration file and restart MySQL server:
</p>
<pre>
koha:/etc/mysql/conf.d# cat &gt; file-per-table.cnf 
[mysqld]
innodb_file_per_table
<em>CTRL+D</em>
koha:/etc/mysql/conf.d# /etc/init.d/mysql restart
</pre>

<p>
This won't change anything, because only new tables will be created in separate files. But, we can use <tt>ALTER TABLE table ENGINE=InnoDB</tt> on each table to force InnoDB to re-read tables and create separate files:
</p>

<pre>
mysqlshow koha --status | grep InnoDB | cut -d'|' -f2 | sed -e 's/^/alter table/' -e 's/$/ engine=InnoDB;/' | mysql -v koha
</pre>

<p>
If you replace <tt>grep InnoDB</tt> with <tt>grep MyISAM</tt> you might use same snippet to convert MyISAM tables into InnoDB (if you still have them or don't use fulltext search).
</p>
<p>
I think that system administration is like gardening. I don't know anything about gardening, but it seems to involve a lot of care here and there, seemingly without much pattern. In that sense, it's similar to wiki editing, you start somewhere and you really don't know where it lead you to.
</p>]]>
        
    </content>
</entry>

<entry>
    <title>SAML2 expirience: implementing SP with perl website</title>
    <link rel="alternate" type="text/html" href="http://blog.rot13.org/2011/06/saml2-sp-with-perl-webapp.html" />
    <id>tag:blog.rot13.org,2011://1.739</id>

    <published>2011-06-12T12:29:47Z</published>
    <updated>2011-06-12T12:28:29Z</updated>

    <summary><![CDATA[ You have to start reading by singing lady Ga-Ga with words: S, s, s, ss... SAML, SMAL2! It will help, really. SAML 2 is latest in long line of different SSO implementation you will have to do sooner or later if you want to be part of larger web. Google and others seems to be using it, so it must be good, right? It has two end-points: identity provider (IdP) which has user accounts and Service Provider (SP) which is usually your application. But of course, it's more complicated than that. For a start, you will need https on your host. I will assume that you already have domain, and you can get free SSL certificates at StartSSL so hop over there if you need one. First, install SimpleSAMLphp. It's pimpliest possible way to get working SAML2 implementation of IdP and SP. You will want to follow first simpleSAMLphp Installation and Configuration and then SimpleSAMLphp Identity Provider QuickStart to configure simple IdP with static accounts so you can test your application against it. You will need both IdP and SP under your control to do development. It will also help if your remote IdP (identity provider which you intend to use) is also simpleSAMLphp (as AAI@EduHr is). Installation is rather easy: dpavlin@lib:/srv$ sudo apt-get install install memcached php5-memcache dpavlin@lib:/srv$ wget http://simplesamlphp.googlecode.com/files/simplesamlphp-1.8.0.tar.gz dpavlin@lib:/srv$ tar xf simplesamlphp-1.8.0.tar.gz dpavlin@lib:/srv$ cd simplesamlphp-1.8.0/ dpavlin@lib:/srv/simplesamlphp-1.8.0$ cp config-templates/* config/ dpavlin@lib:/srv/simplesamlphp-1.8.0$ vi config/config.php You will want to edit following options: auth.adminpassword secretsalt enable.authmemcookie dpavlin@lib:/srv/simplesamlphp-1.8.0$ php5 -l config/config.php No syntax errors detected in config/config.php Interesting part here is authmemcookie option. This allows us to use SP side of simpleSAMLphp and store resulting authentication in memcache and send browser a cookie which we can later read and acquire data from memcache about current user. To configure Apache side, you need Auth MemCookie but it isn't available in Debian package, so I opted for Apache::Auth::AuthMemCookie so I can flexibly modify IdP response before passing it on as environment variables. dpavlin@lib:~$ cat /etc/apache2/conf.d/authmemcookie.conf Alias /simplesaml /srv/simplesamlphp-1.8.0/www perlModule Apache::Auth::AuthMemCookie &lt;Location /cgi-bin&gt; # get redirected here when not authorised ErrorDocument 401 "/simplesaml/authmemcookie.php" PerlAuthenHandler Apache::Auth::AuthMemCookie::authen_handler PerlSetVar AuthMemCookie "AuthMemCookie" PerlSetVar AuthMemServers "127.0.0.1:11211" PerlSetVar AuthMemDebug 1 PerlSetVar AuthMemAttrsInHeaders 0 AuthType Cookie AuthName "Koha SAML" Require valid-user &lt;/Location&gt; To test it, easiest method is to create account in Feide OpenIdP and test against it. After all, it easiest to start with same implementation of SAML2 on both sides just to prevent following scenario: On perl side I first tried Net::SAML2 and found out that it doesn't handle IdP without adding HTTP-Artifact support to the IdP. However, even after that I wasn't managed to make it work with simpleSAMLphp IdP implementation mostly because of my inpatience with SSL configuration of it. On the bright side, for first test I didn't need to modify Koha (Library management software which I'm configuration SAML2 for) at all because it already has support for HTTP authorization....]]></summary>
    <author>
        <name>Dobrica Pavlinušić</name>
        <uri>http://www.rot13.org/~dpavlin/</uri>
    </author>
    
        <category term="hack-of-the-week" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="saml2" label="SAML2" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://blog.rot13.org/">
        <![CDATA[<p>
You have to start reading by singing lady Ga-Ga with words: S, s, s, ss... SAML, SMAL2! It will help, really.
</p>
<p>
<a href="http://www.oasis-open.org/standards#samlv2.0">SAML 2</a> is latest in long line of different SSO implementation you will have to do sooner or later if you want to be part of larger web. Google and others seems to be using it, so it must be good, right?
</p>
<p>
<iframe width="560" height="349" src="http://www.youtube.com/embed/gUmMcecHN9s" frameborder="0" allowfullscreen></iframe>
</p>
<p>
It has two end-points: identity provider (IdP) which has user accounts and Service Provider (SP) which is usually your application. But of course, it's more complicated than that. For a start, you will need https on your host. I will assume that you already have domain, and you can get <a href="https://www.startssl.com/">free SSL certificates at StartSSL</a> so hop over there if you need one.
</p>
<p>
First, install <a href="http://simplesamlphp.org/">SimpleSAMLphp</a>. It's pimpliest possible way to get working SAML2 implementation of IdP and SP. You will want to follow first <a href="http://simplesamlphp.org/docs/1.8/simplesamlphp-install">simpleSAMLphp Installation and Configuration
</a> and then <a href="http://simplesamlphp.org/docs/1.8/simplesamlphp-idp">SimpleSAMLphp Identity Provider QuickStart</a> to configure simple IdP with static accounts so you can test your application against it. You will need both IdP and SP under your control to do development. It will also help if your remote IdP (identity provider which you intend to use) is also simpleSAMLphp (as <a href="http://www.aaiedu.hr/">AAI@EduHr</a> is).
</p>

<p>
Installation is rather easy:
<pre>
dpavlin@lib:/srv$ sudo apt-get install install memcached php5-memcache

dpavlin@lib:/srv$ wget http://simplesamlphp.googlecode.com/files/simplesamlphp-1.8.0.tar.gz

dpavlin@lib:/srv$ tar xf simplesamlphp-1.8.0.tar.gz
dpavlin@lib:/srv$ cd simplesamlphp-1.8.0/
dpavlin@lib:/srv/simplesamlphp-1.8.0$ cp config-templates/* config/
dpavlin@lib:/srv/simplesamlphp-1.8.0$ vi config/config.php
</pre>

You will want to edit following options:
<ul>
<li>auth.adminpassword
<li>secretsalt
<li>enable.authmemcookie
</ul>

<pre>
dpavlin@lib:/srv/simplesamlphp-1.8.0$ php5 -l config/config.php 
No syntax errors detected in config/config.php
</pre>

Interesting part here is <a href="http://simplesamlphp.org/docs/1.8/simplesamlphp-advancedfeatures#section_6">authmemcookie</a> option. This allows us to use SP side of simpleSAMLphp and store resulting authentication in memcache and send browser a cookie which we can later read and acquire data from memcache about current user.
</p>
<p>
To configure Apache side, you need <a href="http://authmemcookie.sourceforge.net/">Auth MemCookie</a> but it isn't available in Debian package, so I opted for <a href="http://search.cpan.org/dist/Apache-Auth-AuthMemCookie/">Apache::Auth::AuthMemCookie</a> so I can flexibly modify IdP response before passing it on as environment variables.

<pre>
dpavlin@lib:~$ cat /etc/apache2/conf.d/authmemcookie.conf 
Alias /simplesaml /srv/simplesamlphp-1.8.0/www
perlModule Apache::Auth::AuthMemCookie
&lt;Location /cgi-bin&gt;
        # get redirected here when not authorised
        ErrorDocument 401 "/simplesaml/authmemcookie.php"
        PerlAuthenHandler Apache::Auth::AuthMemCookie::authen_handler
        PerlSetVar AuthMemCookie "AuthMemCookie"
        PerlSetVar AuthMemServers "127.0.0.1:11211"
        PerlSetVar AuthMemDebug 1
        PerlSetVar AuthMemAttrsInHeaders 0
        AuthType Cookie
        AuthName "Koha SAML"
        Require valid-user
&lt;/Location&gt;
</pre>
</p>

<p>
To test it, easiest method is to create account in <a href="https://openidp.feide.no/">Feide OpenIdP</a> and test against it. After all, it easiest to start with <b>same implementation of SAML2 on both sides</b> just to prevent following scenario:
</p>
<p>
<a href="http://www.dilbert.com/strips/comic/2010-03-17/"><img src="http://blog.rot13.org/2011/06/12/85109.strip.gif"></a>
</p>
<p>
On perl side I first tried <a href="http://search.cpan.org/dist/Net-SAML2/">Net::SAML2</a> and found out that it doesn't handle IdP without
<a href="http://simplesamlphp.org/docs/1.8/simplesamlphp-artifact-idp">adding HTTP-Artifact support to the IdP</a>. However, even after that I wasn't managed to make it work with <a href="http://simplesamlphp.org/docs/1.8/simplesamlphp-idp">simpleSAMLphp IdP</a> implementation mostly because of my inpatience with SSL configuration of it.
</p>
<p>
On the bright side, for first test I didn't need to modify <a href="http://koha-community.org/">Koha (Library management software which I'm configuration SAML2 for)</a> at all because it already has support for HTTP authorization.
</p>]]>
        
    </content>
</entry>

<entry>
    <title>Kindle K3G and DXG</title>
    <link rel="alternate" type="text/html" href="http://blog.rot13.org/2011/05/kindle-k3g-and-dxg.html" />
    <id>tag:blog.rot13.org,2011://1.738</id>

    <published>2011-05-22T18:51:42Z</published>
    <updated>2011-05-23T13:17:19Z</updated>

    <summary> As some of you already know, almost a moth ago we placed order for our first Kindle (3G with wifi). Week after it arrived, we also ordered bigger DXG to complement our reading habits. So why do we have two Kindles and do we have regrets with them? Well, no! This post will try to summarize what I learned since... For a start, both devices have ARMv6, but K3G has 256 Mb of RAM while DXG has only 128 Mb. Both have 4Gb of flash of which about 3.5Gb is available for user content. Both have working 3G connectivity in Croatia. wpa_supplicant on Kindle won&apos;t allow connections to &quot;enterprise&quot; networks (like EduRoam). Smaller K3G is just too small for reading pdf files. Bigger DXG has e-paper in A5 size, so it&apos;s much more useful, but comes with older 2.5.8 firmware which has terrible browser (Netfront as opposed to WebKit in 3.1) and pdf reading without contrast settings (which is very, very useful). But, I was fortunate enough to find mobileread forum post on migration of 3.1 software from K3G to DXG by Yifan Lu to whom I&apos;m eternally grateful for much needed software upgrade. However, even if you don&apos;t want to upgrade Amazon&apos;s own firmware, there is Duokan alternative reader software for Kindle. It has superb support for two column pdf files which allows you to just press next page key and read column on the left (from top to bottom) and then on the right (from top to bottom). It has also various other layouts for reading, and it makes smaller Kindle almost useful for pdf reading (and reading on bigger one a joy). But, sooner or later, you will come across pdf which would really benefit from manual cropping. Take a look at briss which is cross-platform application for cropping PDF files. While we are at software, you should really look at mobileforum&apos;s Kindle hacks thread which documents latest jailbreak (which will give you root permissions on Kindle), usbnetwork (to connect over USB cable) and various fonts and screensaver hacks. Development for kindle can be done using Java2ME (remember that from cell phones?). However, Amazon doesn&apos;t actually seem to give out it&apos;s Kindle development kit but don&apos;t despair: Andrew de Quincey figured out a way to develop kindlets without the KDK. With KDK API from Amazon and JSR217 specification for Java2ME you can be in your marry Java development in no time. I would like to see something like OpenInkport running on Kindle. This would allow free software developers to take full power from this nice e-paper device. If only I didn&apos;t have so much books to read......</summary>
    <author>
        <name>Dobrica Pavlinušić</name>
        <uri>http://www.rot13.org/~dpavlin/</uri>
    </author>
    
        <category term="Kindle" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="en" xml:base="http://blog.rot13.org/">
        <![CDATA[<p>
<a href="http://blog.rot13.org/assets_c/2011/05/5735665422_286f95a5a4_b-97.html" onclick="window.open('http://blog.rot13.org/assets_c/2011/05/5735665422_286f95a5a4_b-97.html','popup','width=683,height=1024,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://blog.rot13.org/assets_c/2011/05/5735665422_286f95a5a4_b-thumb-320x479-97.jpg" width="320" height="479" alt="5735665422_286f95a5a4_b.jpg" class="mt-image-right" style="float: right; margin: 0 0 20px 20px;" /></a>

As some of you already know, almost a moth ago we placed order for our first Kindle (<a href="http://www.amazon.com/Kindle-Wireless-Reader-Wifi-Graphite/dp/B003DZ1Y8Q/">3G with wifi</a>). Week after it arrived, we also ordered bigger <a href="http://www.amazon.com/dp/B002GYWHSQ">DXG</a> to complement our reading habits. So why do we have two Kindles and do we have regrets with them? Well, no! This post will try to summarize what I learned since...
</p>
<p>
For a start, both devices have ARMv6, but K3G has 256 Mb of RAM while DXG has only 128 Mb. Both have 4Gb of flash of which about 3.5Gb is available for user content. Both have working 3G connectivity in Croatia. <a href="http://www.mobileread.com/forums/showthread.php?t=99681">wpa_supplicant on Kindle won't allow connections to "enterprise" networks (like EduRoam)</a>. Smaller K3G is just too small for reading pdf files. Bigger DXG has e-paper in A5 size, so it's much more useful, but comes with older 2.5.8 firmware which has terrible browser (Netfront as opposed to WebKit in 3.1) and pdf reading without contrast settings (which is very, very useful).
</p>
<p>
But, I was fortunate enough to find mobileread forum post on <a href="http://www.mobileread.com/forums/showthread.php?t=127969">migration of 3.1 software from K3G to DXG</a> by <a href="http://yifan.lu/tag/kindle/">Yifan Lu</a> to whom I'm eternally grateful for much needed software upgrade.
</p>
<p>
However, even if you don't want to upgrade Amazon's own firmware, there is <a href="http://www.mobileread.com/forums/showthread.php?t=105316">Duokan alternative reader software for Kindle</a>. It has superb support for two column pdf files which allows you to just press next page key and read column on the left (from top to bottom) and then on the right (from top to bottom). It has also various other layouts for reading, and it makes smaller Kindle almost useful for pdf reading (and reading on bigger one a joy).
</p>
<p>
But, sooner or later, you will come across pdf which would really benefit from manual cropping. Take a look at <a href="http://sourceforge.net/projects/briss/">briss which is cross-platform application for cropping PDF files</a>.
</p>
<p>
While we are at software, you should really look at <a href="http://www.mobileread.com/forums/showthread.php?t=88004">mobileforum's Kindle hacks thread</a> which documents latest jailbreak (which will give you root permissions on Kindle), usbnetwork (to connect over USB cable) and various fonts and screensaver hacks.
</p>
<p>
Development for kindle can be done using Java2ME (remember that from cell phones?). However, <a href="https://kdk.amazon.com/">Amazon doesn't actually seem to give out it's Kindle development kit</a> but don't despair: <a href="http://adq.livejournal.com/tag/kindle">Andrew de Quincey</a> figured out a way to <a href="http://www.mobileread.com/forums/showthread.php?t=100736">develop kindlets without the KDK</a>. With <a href="http://kdk-javadocs.s3.amazonaws.com/index.html">KDK API from Amazon</a> and <a href="http://download.oracle.com/javame/config/cdc/ref-impl/pbp1.1.2/jsr217/index.html">JSR217 specification for Java2ME</a> you can be in your marry Java development in no time.
</p>
<p>
I would like to see something like <a href="http://openinkpot.org/">OpenInkport</a> running on Kindle. This would allow free software developers to take full power from this nice e-paper device. If only I didn't have so much books to read...
</p>]]>
        
    </content>
</entry>

<entry>
    <title>Optimize pdf file size using Ghostscript</title>
    <link rel="alternate" type="text/html" href="http://blog.rot13.org/2011/05/optimize-pdf-file-size-using-ghostscript.html" />
    <id>tag:blog.rot13.org,2011://1.737</id>

    <published>2011-05-11T14:22:27Z</published>
    <updated>2011-05-11T14:31:53Z</updated>

    <summary> We just got our conference booklet, and we need to publish it on the web. But, it has 152 Mb. This seemed excessive, so I googled a bit and found following: $ gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/screen -dNOPAUSE -dQUIET -dBATCH -sOutputFile=output.pdf input.pdf $ ls -al input.pdf output.pdf -r-xr-xr-x 1 dpavlin dpavlin 158511430 May 11 16:23 input.pdf -rw-r--r-- 1 dpavlin dpavlin 1646309 May 11 16:24 output.pdf That&apos;s reduction to 1% of original size. -dPDFSETTINGS=configuration to presets the &quot;distiller parameters&quot; to one of four predefined settings: /screen selects low-resolution output similar to the Acrobat Distiller &quot;Screen Optimized&quot; setting. /ebook selects medium-resolution output similar to the Acrobat Distiller &quot;eBook&quot; setting. /printer selects output similar to the Acrobat Distiller &quot;Print Optimized&quot; setting. /prepress selects output similar to Acrobat Distiller &quot;Prepress Optimized&quot; setting. /default selects output intended to be useful across a wide variety of uses, possibly at the expense of a larger output file....</summary>
    <author>
        <name>Dobrica Pavlinušić</name>
        <uri>http://www.rot13.org/~dpavlin/</uri>
    </author>
    
        <category term="hack-of-the-week" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="pdf" label="pdf" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://blog.rot13.org/">
        <![CDATA[<p>
We just got our conference booklet, and we need to publish it on the web. But, it has <b>152 Mb</b>. This seemed excessive, so I googled a bit and found following:

<pre>
$ gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/screen -dNOPAUSE -dQUIET -dBATCH -sOutputFile=output.pdf input.pdf

$ ls -al input.pdf output.pdf 
-r-xr-xr-x 1 dpavlin dpavlin 158511430 May 11 16:23 input.pdf
-rw-r--r-- 1 dpavlin dpavlin   1646309 May 11 16:24 output.pdf
</pre>

That's reduction to <b>1%</b> of original size.
</p>
<p>
<tt>-dPDFSETTINGS=configuration</tt> to presets the "distiller parameters" to one of four predefined settings:
<ul>
<li><tt>/screen</tt> selects low-resolution output similar to the Acrobat Distiller "Screen Optimized" setting.
<li><tt>/ebook</tt> selects medium-resolution output similar to the Acrobat Distiller "eBook" setting.
<li><tt>/printer</tt> selects output similar to the Acrobat Distiller "Print Optimized" setting.
<li><tt>/prepress</tt> selects output similar to Acrobat Distiller "Prepress Optimized" setting.
<li><tt>/default</tt> selects output intended to be useful across a wide variety of uses, possibly at the expense of a larger output file.
</ul>
]]>
        
    </content>
</entry>

</feed>

