Sunday, April 23, 2006

Committed IPv6 support for syslog-ng

I have finished IPv6 support for syslog-ng, I'm wondering how this will improve the number of people actually using the new syslog-ng 1.9.x tree.

In the implementation I've created separate udp6() and tcp6() source and destination drivers, because this was somewhat easier to implement. I'm expecting some portability trouble, but otherwise the implementation is nice and simple.

Some smaller fixes went in recently as well, like:
  • avoid chown/chmod files that do not exist as it clobbered error reporting,
  • added close-on-exec flag to file descriptors to avoid child processes to inherit tcp/udp connection fds,
  • fixed an off-by-one in flush_lines calculation,
  • a possible memory leak, and
  • a fix for non-existing filter references in the internal() message path
Apart from IPv6 support these are mainly bugfixes and I'm confident we can have a 2.0.0 real soon now.

Monday, April 17, 2006

syslog-ng and IPv6

I received an email last week asking about IPv6 support in syslog-ng. The question also referred to an IPv6 application page where most of the system logging applications were listed red showing that they lack IPv6 support.

I started hacking on it but I thought I would ask you how important you think adding IPv6 support to syslog-ng is?

My idea was to add tcp6() and udp6() source and destination drivers, however a lot of applications seem to do IPv6 support with a single listener, e.g. open an AF_INET6 socket and assume that the system shares IPv4 and IPv6 sockets. Which of the two approaches is preferable? The first gives more control the latter seems to be a bit easier to use, it works out of the box.

Saturday, April 15, 2006

Released syslog-ng 1.9.10 for real this time

Just a quick one this time, I have released syslog-ng 1.9.10 available at the usual places. The release contains mainly bugfixes and an implementation of the previously missing netmask() filter and support for bad_hostname() and check_hostname() options.

Sunday, April 09, 2006

Timezone woes

As I have written in my previous post there was a timezone related problem triggered by one of the unit test programs of syslog-ng. Apart from a minor issue in the testprogram itself, it turned out that there's a timezone conversion problem at the reception of messages. Syslog-ng 1.9.x has support for messages that use the ISO 6501 timestamp. As an example the current local time here right now in ISO 6501 is: 2006-04-09T22:43:24+02:00. The important part is that it includes an explicit timezone offset. This offset is processed by syslog-ng and it can convert timezones when necessary.

I spent about half a day to fix timezone conversion, I even used a pen and a sheet of paper to do some calculations. All I can say that there's an important building block missing from the POSIX time handling functions, which would have made my job as an application developer way easier: one that converts a broken down time representation to a UNIX time_t value, where the time to be converted is NOT in the local timezone, but in GMT. The other side of this conversion exists: localtime() converts a UNIX timestamp to the local timezone, and gmtime() does the same but instead of using the local timezone and daylight saving settings, it uses GMT as timezone.

The only portable function to convert a human readable timestamp to UNIX timestamp is mktime(3), which assumes that the converted timestamp is in local time. At first blick this can be easily used in place of our imaginery mktimegm() function: mktime() returns a value offseted by the local timezone, but we also know the local timezone offset, so we substract this from the return value of mktime() and we have a stamp in GMT, right? No, not right.

There are cases when mktime() changes its incoming broken down time representation when Daylight Saving kicks in: the value of "2006-03-26 02:00:00 CET" does not exist, it is equal to "2006-03-26 03:00:00 CEST" (CET is +01:00, CEST the daylight saving time is +02:00), and this happens to every value in this time interval, e.g. 2:33 CET becomes 3:33 CEST.

Remember, I have a timestamp with an explicitly specified timezone offset where the daylight saving settings of the syslog-ng process should not count, e.g. the sender sends something like 2006-03-26 02:00:00 +02:00, which is converted to 2006-03-26 03:00:00 +02:00 by the mktime() function, e.g. it is off one hour. And all this happens only in the transition hour. Good, heh?

The solution was to check this change in the time by mktime() and adjust the returned value, this seems to work reasonably well for the transition hour.

While writing this post I have found that there is a GNU extension defined, a function named timegm(3), which seems to do exactly what I have wanted. The problem that this function does not seem to be too portable. The notes in the manpage say that for achieve timegm() functionality, the application should change its own environment, set the TZ environment variable, call mktime(), and reset the environment variable. This does not look too clean I would even call that ugly. IIRC setenv() allocates memory, I would need to call this kludge for each and every incoming message.

I think this important hole in the API should be plugged, there are a lot of applications that need to work with various timezones and I have a bet that a lot of those work incorrectly in daylight saving transition hours.

I already have one example: GNU date program also allows specifying an explicit timezone offset:

bazsi@bzorp:~$ date -d "2006-03-26 01:59:59 +0100"
Sun Mar 26 01:59:59 CET 2006
bazsi@bzorp:~$ date -d "2006-03-26 02:00:00 +0100"
Sun Mar 26 04:00:00 CEST 2006

The second one should only be one second later than the first, e.g. it should be 03:00:00 CEST, and not 04:00:00 CEST. Try it with your favourite application :)

Thursday, April 06, 2006

Almost released syslog-ng 1.9.10

... but at the end I didn't. I prepared the NEWS file, changed version number etc, but the end it turned out that one of my unit test program which tests macro expansions failed.

I still have not looked into the issue, hopefully it is only the test program, time related macros seem to use a bad timezone offset. Again I seem to have made a timezone related bug :(

Although timezones and time related functions seem to be simple at first, it proved to be a problematic area, it already had a lot of bugs and again here is this one. Not to mention the problem that different platforms have different set of variables/functions to cover the issue. For instance "timezone" is a global variable on Linux and a function on BSD. Linux has a "tm_gmtoff" member in "struct tm", BSD doesn't.

OK, I quit whining now :) Hopefully I'm going to have some free time to look into this bug in the nearfuture.

I also have two other issues on my radar for syslog-ng 1.9.10, first I've received some reports about missing configuration keywords (namely bad_hostnames and check_hostnames), and second I want to change some currently reserved words to identifiers, so that "kernel" can be used as the name of sources again. And oh yes, I have also received a report on an abort(), although I don't have enough info on this one yet.

One thing is certain: the 1.9.10 release of syslog-ng is coming.

Saturday, April 01, 2006

SSH publickey authentication implemented

I have hacked on our SSH gateway today to add publickey authentication support. By the way I may not have explained this before, so a short introduction is due: Zorp is an application layer gateway with support for 21 protocols, among them an SSH gateway capable of looking into the encrypted SSH stream and restricting the protocol to a subset that you really want to allow to your users. (e.g. you can forbid TCP port forwarding while still allowing terminal access).

The problem with publickey authentication is that the signature covers the so called SSH session_id which is a unique value derived during key exchange. My proxy implements a man-in-the-middle, so the client<->proxy and proxy<->server connections have a different session id, thus simply replaying the authentication packets of the client will not work since the SSH session ids do not match.

The solution is that we are going to replace user keys transparently when crossing the firewall, which means that private keys need to be stored there. This is both a feature and a drawback: a feature since you can control which keys you are allowing to leave your perimeter and a drawback as this requires additional management tasks. It would have been so much nicer if we could do this transparently, but I am afraid this is not possible unless we modify all clients out there or alternatively we manage to find a way to crack the Diffie-Hellmann key exchange algorithm.

On the syslog-ng side I have committed a fix to make files over 2GB work again. It should be available in the next snapshot shortly. I'm also thinking about preparing 1.9.10 with the fixes accumulated so far.