Microsoft did it right! (Making a case for DNS SRV records)

Yes the people over at Microsoft do (quite?) some stuff the correct way. Among those things is the excessive usage of DNS SRV records.

I’m saying this because I think a some tools will benefit from the usage, namely:

  • Firefox (that even benefits end users not only IT people) and
  • Configuration Management Tools

Consider the following use cases:

  • Mass hosting SSL enabled websites
  • Discovering where get information or where to put it for automated tools
  • Automagically discover where a login service is

The tool that comes to my mind first is puppet. We use the tool quite extensively in our infrastructure and now deploying a new host is actually just the work of a few minutes. Thanks to my colleagues who invested vast amounts of time into setting up all the modules we need puppet will nearly automatically configure a host and even set up tests in Nagios to make sure service availability.

However the main “problem” remaining (although solved by using a packages tailored to our needs) is the conventions a default puppet installation makes. Namely it expects the master host to be reachable by DNS on a host named “puppet“. That isn’t consistent with the naming scheme we made up for our hosts. So why not use a perfectly available standard to discover where the correct endpoint is (yes Microsoft keeps to a standard – at least in some way)?

Staying with the example of puppet I’d like to see that puppet tries to find the master node by doing a DNS query that asks for the _x-puppet._tcp.example.com SRV record. So in accordance to our naming schema we could simply answer with its-devl-puppet01.example.com or any other suitable host.

So what about the rest of the above examples?

Consider SSL mass hosting with a single IP and say you give each VHost another port starting at 8441.

_https._tcp.example.com. 3600 IN SRV 0 10 8441 www.example.com.
_https._tcp.example.net. 3600 IN SRV 0 10 8442 www.example.net.
_https._tcp.example.org. 3600 IN SRV 0 10 8443 www.example.org.

Granted with Server Name Indication that problem is already solved, but I know a few setups that for certain reasons won’t be able to upgrade to packages that are able to use that technique. And personally I think that this approach is nicer especially since it solves this problem for every service. Take Thunderbird 3, it tries autodiscovery but quite often fails. If there was a _pop3._tcp.example.com SRV entry it would just work.

Also granted, there are quite a few protocols that already benefit from this, Kerberos clients, should do, (or rather “RFC4120 compliant clients” should do) autodiscovery in the way I described it.

So actually this is a plea to the developers out there. If you create services that expect some endpoint reachable over TCP or UDP don’t just juse a “This is the default hostname convention”. Nothing wrong with that as a fallback, but please (please, please) also allow us SysAdmins who have to deal with compliance rules to use existing ways to specify where to connect to that automagically work, and don’t have to edit a file on every box or instance we have to take care of.

Especially for cases like configuration management, once tested we like to roll stuff out on quite a few boxes, and to keep maintenance low we also love it if we can use the default upstream sources (be it from the favorite distribution or the original upstream). And that is the case I’m making here. We have to be compliant with some rules and probably have (or have to) access more boxes than a single developer, so we may encounter cases you haven’t thought of.

We are happy to send you accurate bug reports but please listen to us sometimes.

Enough begging for today…

Python Class Methods


Just a short reminder how to easily create class methods in python. Useful for creating factory methods that return the instance of a certain class.

user@localhost:~$ python
Python 2.4.4 (#2, Apr 15 2008, 23:43:20)
[GCC 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)] on linux2
Type "help", "copyright", "credits" or "license" for more information.

>>> class foo(object):
...     def __init__(self, s):
...             self.s = s
...     @classmethod
...     def from_string(cls, in_):
...             return cls(in_)
...     @classmethod
...     def from_int(cls, in_):
...             return cls(int(in_))
...
>>> s = foo.from_string("foo")
>>> s = foo.from_int("foo")
Traceback (most recent call last):
File "", line 1, in ?
File "", line 9, in from_int
ValueError: invalid literal for int(): foo
>>> s = foo.from_int("2")
>>> s = foo.from_int("0x2")
Traceback (most recent call last):
File "", line 1, in ?
File "", line 9, in from_int
ValueError: invalid literal for int(): 0x2
>>> s = foo.from_int(0xe)
>>> s.s
14

This in fact works quite fine except for one thing:

Python method are first class objects, if you have die above in a module named foo.py you will need the following code:

Python 2.6.4 (r264:77598, Jan 18 2010, 11:44:15)
[GCC 4.3.4] on linux2
>>> import foo
>>> o = foo.foo.from_string("1")
>>> o.s
'1'

Quite a lot of typing, you may want to consider the following:

Python 2.6.4 (r264:77598, Jan 18 2010, 11:44:15)
[GCC 4.3.4] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import foo
>>> foo.from_string("a")
<foo.foo object at 0x7f0c78d94350>
>>> o = foo.from_string("a")
>>> o.s
'a'

A lot less to type isn’t it?

To get that working just create a module that looks like this:

def from_string(value):
    return foo(value)

def from_int(value):
    return foo(int(value))

class foo(object):
    def __init__(self, s):
            self.s = s

Postfix – A Complete Failure!

Yes this is a rant.

  • I used to like postfix
  • Until now I never had the need to do deeper analysis of the postfix logs
  • I always thought exim was way too complicated

2 of the 3 points above changed right now at this very moment. I still think exim is way to complicated but that’s probably because I never had to care about configuring it. However we need to analyze the log data of email deliveries, receptions, failures and whatnot.

How hard can it be?” – at least that was my first thought. It can be very hard.

Just compare:

  • the documentation of postfix’ log format: here and here
  • the documentation of exim’s log format: here

Postfix just died for me from this very moment….