Google Authenticator

Author: Eric Anderson
Heirarchy: 03 < December < 2011 < Archive < Eric Anderson

I have been happily using two-factor authentication with my Google account for months. I appreciate the added security and it hasn't been much hastle.

I decided it would be a good idea to implement something similar for access to my server. There are several options available, but I selected using pam_google_authenticator. It integrates with the Google Authenticator phone application and supports backup OTPs for when your phone is unavailable.

Since I am using Arch, the process begins with installing the google-authenticator-libpam-hg package from AUR. Normally this would be an easy task, but for some reason hg clone fails during building. I worked around the problem by running hg clone command manually in my home directory, and then creating a symlink to it for use in the build script. I also installed qrencode for generating QR codes.

Now that it is installed, you have to configure PAM to make use of the new module. I created a new file /etc/pam.d/google-authenticator with the contents:

auth	sufficient accessfile=/etc/security/access-local.conf
auth	sufficient user notin some:users:here
auth	required

The pam_google_authenticator module does the real work, but there are only two cases that I want to require the OTP. I want to require the OTP for all connections from the Internet, but not my LAN. Thus pam_access, with the help of additional configuration, does just that. When turned on, pam_google_authenticator requires all users to use OTP with no provision for users who haven't setup their two-factor authentication yet (it would simply prevent them from logging in). There are several patches I could have applied to fix this problem, but I just went with the simple approach of manually configuring the list of users I want to use two-factor authentication with the pam_succeed_if module. some:users:here is a colon-separated list of users that will be using two-factor authn.

For pam_access, I created /etc/security/access-local.conf:

+ : ALL :
- : ALL : ALL

The first line is where you define your network's subnet. It should likely be something like

To allow PAM to query additional information via SSH, you need to make sure that ChallengeResponseAuthentication is not set to no in /etc/ssh/sshd_config. The default is yes, but in Arch they set it to no, so I just commented out that line in the config and restarted SSH.

As my normal user, I ran google-authenticator which generated a TOTP secret in my home directory. (Assumably) since I had qrencode installed, it also provided a very nice QR code (in the termal even!) that I scanned with my phone to configure the Google Authenticator Android application.

All the preparation work is complete, I now need to enable the setup for ssh. In /etc/pam.d/sshd I added a line under auth required ...:

auth	substack	google-authenticator

After a bit of testing, I verified everything was running as I expected and I now have two-factor authentication for accessing my server via SSH. To enable two-factor for additional accounts I will have the account user run google-authenticator and setup their phone, after which I will add them to the list passed to pam_succeed_if.

XSLT with Python

Author: Eric Anderson
Heirarchy: 13 < April < 2010 < Archive < Eric Anderson

I just thought it had been a long time since my last post. This one wins even more.

I still really like Lighttpd and until recently was only using Apache for mod_svn and mod_xslt. I don't have much choice with mod_svn short of using svnserve (which I may end up doing), but a few months ago (December 12 by the file date) I took up the challenge of replacing mod_xslt.

I did enjoy mod_xslt and can't complain about its performance or memory usage. The fact that the project is dead is disconcerting, but any time the module stops compiling I'm able to get it working again by looking around, posting on the mailing list, or fixing it myself. Really, the only real qualm I have is that it requires Apache.

As an aside, my love for XML has long since passed and so I just want the system to work and I won't make any future enhancements. In general, I am now anti-XML and pro-JSON and -Bencode. My opinion is that there are still uses for XML, but that it is generally overused.

After some time, I developed this CGI script in Python:

#!/usr/bin/env python

from lxml import etree
import cgi
import sys, os


def transform(xml, xslt):
    doc = etree.parse(xml)
    style = etree.XSLT(etree.parse(xslt))

    return style.tostring(style.apply(doc))

if __name__ == "__main__":
    import cgitb

    form = cgi.FieldStorage()
    if "key" not in form or form["key"].value != KEY:
        print "Status: 403 Forbidden"
        print "Content-Type: text/html"
        print "<html><title>403 Forbidden</title><body><h1>403 Forbidden</h1></body></html>"

    xml = form["xmlfile"].value
    xslt = form["xsltfile"].value
    contenttype = form["contenttype"].value

    print "Content-Type:", contenttype
    print transform(xml, xslt)

Luckily I didn't use very many mod_xslt specific features, so everything seemed to "just work." I did lose Content-Type support, so I have to hard-code it as a GET parameter. Notice I added the secret key in there since I didn't want to bother with proper security.

Now for the Lighttpd configuration. Since I can no longer use .htaccess files in different directories to change which XSLT is used, I get this more-ugly config:

url.redirect = ( "^/$" => "/recent/" )
url.rewrite-once = (
    "^(/recent/rss/)(?:index.html|index.xml)?$" => "/cgi-bin/$1/index.xml",
    "^(/recent/atom/)(?:index.html|index.xml)?$" => "/cgi-bin/$1/index.xml",
    "^(/recent/atom/summary/)(?:index.html|index.xml)?$" => "/cgi-bin/$1/index.xml",
    "^(/recent/atom/0\.3/)(?:index.html|index.xml)?$" => "/cgi-bin/$1/index.xml",
    "^((?:/recent/|/archive/).*).(?:html|xml)$" => "/cgi-bin/$1.xml",
    "^((?:/recent|/archive)/(?:.*/)?)$" => "/cgi-bin/$1/index.xml",
index-file.names = ( "index.xml" )

Notice the %%2B's in some of the URLs. Those make it additionally ugly, but I still prefer that stuff over dealing with Apache.

All-in-all, it feels like a reasonably hackish solution, but it works great. I don't care about loss in performance (honestly, who reads a not-updated-in-over-two-years blog?) and if I really care I could convert the script into a Fast-CGI on WSGI script. It is nice to know that this proof-of-concept of a blog is somewhat portable now.

Gtk, Languages, and Memory

Author: Eric Anderson
Heirarchy: 17 < August < 2007 < Archive < Eric Anderson

It has been a long time since my last post. Sorry, but now to business.

Recently I have re-tried to open up to Mono. I certainly do like some of its abilities and features, but the memory usage always worries me. When I compared the memory usage of Banshee and Rhythmbox, I found memory utilization of 80 MiB and 20 MiB, respectively. That mostly shot the Mono idea out of the water. However, then I checked Tomboy memory usage and found it to be reasonable, but still a little high at 16.7 MiB on my computer with three notes. For reference, Pidgin uses 6.9 MiB and Nautilus uses 12.0 MiB.

Then I got to wondering about the baseline memory usage for using GTK+ for different languages. Here are the languages, files, and commands I used.

Languages, Files, and Commands



#include <gtk/gtk.h>

static void
on_destroy (GtkWidget * widget, gpointer data)
    gtk_main_quit ();

main (int argc, char *argv[])
    GtkWidget *window;
    GtkWidget *label;

    gtk_init (&argc, &argv);

    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title (GTK_WINDOW (window), "Hello World");

    g_signal_connect (G_OBJECT (window), "destroy",
                      G_CALLBACK (on_destroy), NULL);

    label = gtk_label_new ("Hello, World");
    gtk_container_add (GTK_CONTAINER (window), label);
    gtk_widget_show_all (window);
    gtk_main ();

    return 0;

gcc hello-world.c -o hello-world `pkg-config --libs --cflags gtk+-2.0`




#include <gtkmm/main.h>
#include <gtkmm/window.h>
#include <gtkmm/label.h>

class HelloWorld : public Gtk::Window
    virtual ~HelloWorld();

    Gtk::Label m_label;

: m_label("Hello, World")
    set_title("Hello World");




int main (int argc, char *argv[])
    Gtk::Main kit(argc, argv);

    HelloWorld helloworld;

    return 0;

g++ hello-world.cpp -o hello-world `pkg-config --libs --cflags gtkmm-2.4`



import gtk

def on_destroy(o):

w = gtk.Window()
w.set_title("Hello World")

w.connect("destroy", on_destroy)

l = gtk.Label("Hello, World")




using Gtk;
using System;

class Hello {

	static void Main()
		Application.Init ();

		Window window = new Window ("Hello World");

		window.DeleteEvent += delete_event;

		window.Add (new Label ("Hello, World"));

		window.ShowAll ();
		Application.Run ();

	static void delete_event (object obj, DeleteEventArgs args)
		 Application.Quit ();

mcs hello-world.cs -pkg:gtk-sharp

mono hello-world.exe


import clr
import Gtk

def delete_event (o, args):
  Gtk.Application.Quit ()

Gtk.Application.Init ()
w = Gtk.Window ("Hello World")

w.DeleteEvent += delete_event

l = Gtk.Label ("Hello, World")
w.ShowAll ()
Gtk.Application.Run ()

mono ipy.exe


All the memory usages were recorded from GNOME's System Monitor. I used the new "Memory" column that is suppose to be less misleading than other measurements.

Language Memory Usage
C 1.9 MiB
C++ 2.7 MiB
Python 6.6 MiB
C# 3.3 MiB
IronPython 29.8 MiB

I tried to do Java as well, but I could not get the Java bindings to compile. I think that this test gave Mono some credibility and removed any consideration for using IronPython from my mind. I was not very surprised with Python's "high" memory usage, since I had already looked into this when looking into GEdit's plugins. This test tells nothing about actual memory usage in typical programs in each of the different languages, just the baseline for how low the memory usage can go.

Avahi and DNS

Author: Eric Anderson
Heirarchy: 19 < September < 2006 < Archive < Eric Anderson

I was playing around with Avahi and DNS and decided that since it was so much fun, I should share my experience.

I already had Avahi set up. Avahi is a Zeroconf (aka Bonjour, Rendezvous) implentiation. Zeroconf allows you to find services on a network. Previously I just used Avahi for finding iTunes shares (with Rhythmbox) and publishing my services (ssh, http, ipp, rsync, etc.).

The Beginning

Previously I noticed, with avahi-discover, that my workstation was published (because public-workstation is enabled by default). I had no idea how to use it though. Looking through Planet GStreamer for the first time I found a post describing how to use this other tid-bit of information.

Getting Automatic Local Hostnames

Up to this point, I had been setting hostnames in /etc/hosts for computers on my network. My network maintains fairly stable IPs, so this was not a big issue. But with Avahi, this can be automatic! I emerged nss-mdns and added mdns (most people probably want mdns4 instead) to /etc/nsswitch.conf the hosts line (now looks like "hosts: files dns mdns").

DNS Caching and Local Domain Setting

At this point, I could go to my machine via mastermind.local, and the ersoft server via wife.local. As I removed wife and mastermind from my hosts file, I realized that dns lookups were much slower when gotten from avahi. Comcast's DNS servers are unbearably slow, so I figured this would be a good time to set up a DNS cache.

I found a post for DNS caching for Ubuntu. Since I already had dnsmasq, I uncommented the listen-address line in /etc/dnsmasq.conf and set it equal to ("listen-address="). Then I ran rc-update add dnsmasq default and /etc/init.d/dnsmasq start.

To configure your system to use this cache you need to modify /etc/dhcp/dhclient.conf. It is very possible that you are missing this file. If you are, just emerge dhcp.

The file is the same place that you can set your default domain name. Setting the domain name allows you to connect to a host via hostname as opposed to hostname.domainname. In my case, without the default domain name set, I would have to connect to mastermind.local to get to my laptop. For most people, their domain name would be local as well. I my dhclient.conf now looks like:

prepend domain-name-servers;
supersede domain-name local;

If you were previously using dhcpcd in Gentoo, you will want to change /etc/conf.d/net to use dhclient. You can achieve this by:

modules=( "dhclient" )

You will need to restart your network device before it will be using the new configuration. If you want to test to see if everything is working, dig is a useful command. It is part of bind-tools. Give dig the argument of the host you want to lookup. It will give you a lot of good DNS information, including "Query time." The query time from the cache should be 0-1 milliseconds.


Author: Eric Anderson
Heirarchy: 19 < March < 2006 < Archive < Eric Anderson

This blog has been very lonely for the past few months and I finally am using it again. I finished a few of the tasks that needed to be done a while back, but not all of them.

Most noticably, I broke the RSS feed (I have no clue how!). It works perfectly fine from the command line, but not from apache... Since I don't like RSS that much anyway, I am not too sad about it breaking.

I have now deprecated the Atom 0.3 feed, so that there are no more links to it. I thought that the feed was valid, but checking it at shows otherwise. It not being valid combined with Atom 1.0 having had many more months to get implemented into agregators and Atom 0.3 becoming officially deprecated made me feel that there is no reason for me to put forth the effort to have it validate and that I should just deprecate it in general.

I finally fixed the stupid double slash in my URLs and removed the leading space in most links (not a real issue, but it was just code cosmetics). I also changed one thing in the Atom 1.0 feed, although I do not remember what now.

You will find a new Atom 1.0 Summaries. This was going to be in addition to the RSS feed, but since it broke, it will just be a substitute for the RSS feed for those people who like to read posts on the actual site. The summary for a post is now character limited and cut at a word boundry instead of taking the first paragraph.

Those whom are very observant may have noticed that all the CSS files now exist. I split the one stylesheet that I had into several different stylesheets and added a print stylesheet. In addition, I actually created the fixed stylesheet layout, so now the "Choose a style" links work. The original CSS did not completely validate, and this has been fixed as well (so that if I removed the hacks and the Mozilla specific parts it would validate).


I have tried out and really enjoyed the lighttpd HTTP web server. I hope to eventually swap this server to it some time in the future. The main problem with swapping is I cannot use mod_xslt, so I will need to find or develop a component to perform the XSLT. If you have not tried out lighty, you should.