Welcome to Nginx!

If you're reading this, it's thanks to Nginx.  As of about midnight last night, all content on SystemOverlord.com is being served up by Nginx.  I did this for two reasons: Nginx has a much smaller memory profile than Apache, which is important when running on a 512MB VPS, and Nginx's preferred PHP path is through a FastCGI interface, which allows me to run separate PHP FastCGIs under different users for each application on my server.  Privilege separation for different webapps has always been a big thing security-wise, and I'm glad I was able to get it going with a minimum of fuss.  Wordpress, Nginx, MySQL, and Ubuntu Server powered, all on a Linode VPS!

Announcing NetStatUI: A PyGTK interface for network statistics

NetStatUI is my first significant FOSS release. It’s also my first significant Python project and my first use of GTK+. Yes, that’s a lot of firsts all at once, so I apologize if I’ve done things sub-optimally. I’m still learning some of the wonderful niceties of Python (a subject of a later post) and so I may have done some things “the other way.” NetStatUI is a program to display statistics and information about the IP connections currently on your system. It is an attempt to provide a usable NetStat work-alike for the desktop user. Many new users are shy of the command line, and having a graphical version may be useful.

Homepage: https://launchpad.net/netstatui

NetStatUI has several caveats, and many more TODOs, described below. This is my first significant Python application, my first GTK+ application, and probably my first significant FOSS application. Feedback is welcomed and appreciated.


Displaying hostnames is INCREDIBLY slow. For some reason, Python’s implementation of socket.gethostbyaddr() is very slow. We do cache lookups to speed up future calls, but the first time a full screen is looked up, it can take 30s+ NetStatUI does not support Unix domain sockets. At present, there are no plans to change this. If you need Unix domain sockets, you likely know how to use netstat(8). If you need Unix domain sockets and DON’T know how to use netstat(8), I’d love to hear what your use case is. For some things, NetStatUI requires root access. I hate running things on my desktop as root when I can avoid it, but NetStatUI gathers process information by walking the /proc tree, and only root can read other user’s process information. See the -p option to netstat(8) for more details. TODO:

NetStatUI is intended to have columns to display per-connection bandwidth usage. My intent is to gather this information via the conntrack interface. Parsing ip_conntrack is non-trivial, but there is a Python binding for libconntrack. I’ll need to test it out and see if it meets the needs of NetStatUI. The Kill Process and TCPDump buttons are clickable, but don’t do anything. Those are likely to be implemented in short order. While the GPL does not require this, I’d appreciate that if you create a derivative work, you let me know so I can see what you’ve done. My contact information is at the top of this document. Thanks for giving NetStatUI a try!

To obtain NetStatUI right now, you’ll need to use the bzr distributed version control tool. As NetStatUI is hosted on launchpad, it’s as simple as bzr branch lp:netstatui.

IPv6: On my Linode, and at Home

Hurricane Electric, ARIN, and others, report that we may be as close as 12 days to exhaustion of the main IPv4 pool.  Accordingly, I decided it was time to get both my VPS and my home network IPv6-ready.  It wasn't as painful as I feared, though doing it in DD-WRT is a bigger pain than it should be.  If I had an OpenWRT router, it looks like it would be easier.

Is 25 Old?

I’ve begun to feel… restless. Periodically, I feel that I haven’t done anything significant, made contributions, achieved anything. Tonight I couldn’t sleep, so I decided to do a little browsing to see who how old some notable figures were at the time they started or achieved something significant. This list includes many of the people who inspire me, and some who are just well known and have made large achievements. It’s notable that the average achievement age is 23.


  • Bill Gates founds Microsoft
  • Matt Mullenweg launches WordPress


  • Mark Zuckerberg launches Facebook
  • Ian Murdock founds the Debian Project


  • Steve Jobs co-founds Apple Computer
  • Rob Malda starts Slashdot (then Chips & Dips)


  • Linus Torvalds releases Linux 0.01
  • Darren Kitchen launches Hak.5
  • Mark Shuttleworth founds Thawte
  • Dries Buytaert releases the first version of Drupal


  • Miguel de Icaza starts the Gnome Project


  • Steve Wozniak co-founds Apple Computer


  • Kevin Rose launches Digg
  • Theo de Raadt starts the OpenBSD Project
  • Patrick Volkerding founds the Slackware Linux Project


  • Richard Stallman founds the GNU Project

It looks like 27 is about the upper limit for the kind of creative and innovative work I’ve wished I could achieve. Unfortunately, I’ve begun to believe that I just don’t possess the imagination and inspiration necessary for notable achievements. The technology world is a very young one.

Learn Regular Expressions. Seriously.

I can't tell you the number of IT Professionals (whether developers, sys admins, etc.) who have told me that it's not worth their time to learn regular expressions. I thought that way at one point, but now I'm astounded at that thought. Regular Expressions are one of the most powerful tools available for working with data.

I'm currently working on a tool that reads /proc/net/tcp.  Trying to parse that without regular expressions would be dozens of lines of code.  With regular expressions (in Python) I have a one-liner to parse each line of the file.  And that's for a file that's intended to be machine-readable.  (Though, admittedly, /proc/net/tcp is a lot less machine-readable than, say, /etc/passwd.)

The authors of the RE engines have done the hard work and figured out how to optimize the parsing of the lines and matching the RE.  For stupidly simple cases, an RE may be slower, but once you get to complex parsing, it's much easier.

The only thing I haven't figured out is how to parse values that don't conform to a particular order (ala GNU getopts).