Today I'm taking Kenmore to my customer for configuration and testing. and it's time I finally showed a picture. It's an aluminum cube 8"x8"x12", and it's remarkably light.
The modders in the group will scream about how ugly the CD-ROM & floppy drives look, and I am hoping some will have suggestions on how to make them look better. I'm thinking about simply using a USB-based floppy and CD-ROM drive, which I could use on demand with any system that needed it - this machine has a USB-boot-enabled BIOS, so this would also help keep the unit cooler by removing two devices from the case.
I've been using it on my own network for a while, and SpamAssassin is just fantastic. At my customer we'll migrate to Kenmore for a while to test it, then move the software to his outside mail server. That server is now running sendmail, and we have to rip out everything before installing Postfix and the related tools. Once done, I take Kenmore back home and move onto the next customer.
I am also very pleased with the spamc/spamd combination - it's much faster than launching a fresh SpamAssassin process for each message. The client communicates with the server via TCP, and I'm thinking that if they're both running on the same machine, using UNIX domain sockets may well be even faster.
My web site is not the Library of Congress or SecurityFocus, but I try to make it mostly a technical resource site with limited but otherwise solid content. I'd love to think that I stand out for my real research works, such as Realtime Proxy Abuse Triangulation or my better tools like nbtscan.
But noooooooo.
For as long as I can remember, by far the most common Google search strings that bring visitors to my site have been for a lame bit of perl code I wrote: AOL IM Password Decoder. This tool only decodes an obscured password found in the registry, and I wrote it as part of my suite of penetration testing tools. I have no way of getting any random person's password.
A side effect of this is that at least once a month, when I sign onto my AOL IM account, I get a "Who are you?" IM from somebody I've never heard of. I finally figured out that people were passing around a link to my tool, and I was getting added to their buddy lists. I'm not on AIM very often, so when I showed up, people would ask who the hell I was.
This is all very bizarre, and quite depressing. About 9% of my searches are for "AOL passwords", with the next in line being nbtscan at 2%.
What a way to be famous.
While building Nessus on my Red Hat 8.0 system, I found that the "configure" scripts were outright broken. It turns out that the behavior of bash has changed to more accurately reflect POSIX behavior, and this breaks the configure script such that it won't find GTK.
The behavior in question is expanion of the $IFS shell variable, which is the inter-field separator, and it's best illustrated by example:
On older systems, this shows four lines forPART1=a:b PART2=Y:Z IFS=: for part in $PART1:$PART2 do echo "part = $part" done
These patches fix everything as best as I can tell.
nessus-core-1.2.7-config-patch.txt
nessus-core-1.3.4-config-patch.txt
nessus-core-2.0.0-config-patch.txt
Sorry, Jeremy, the patch comments are shorter than the patches themselves
Edit - five minutes after posting this blog entry and sending off my patches, I got the "Nessus 2.0 is out!" announcement over Bugtraq. So much for my timing. But the same patches were required, so I've posted them too.
My project of building "Kenmore", a mail-cleaning appliance, is progressing nicely. I've been running it on two small domains for almost two weeks, and SpamAssassin is doing an amazing job at tagging spam - and I've not yet installed the just-released SpamAssassin 2.50.
This machine won't have any local mail accounts, so all mail will be relayed to their final mail servers. The configuration for backup MX was straightforward enough:
/etc/postfix/main.cf:The relays table tells Postfix which domains it's doing relay for, and the transport table short-circuits the usual MX-lookup for domain routing, and it allows Kenmore to be the primary MX for this domain instead of the ultimate target.relay_domains = $mydestination, hash:/etc/postfix/relays transport_maps = hash:/etc/postfix/transport smtpd_recipient_restrictions = permit_mynetworks, reject_rbl_client relays.ordb.org, reject_unauth_destination/etc/postfix/transport:
mydomain.com smtp:[mailserver.name]:25/etc/postfix/relays:
mydomain.com OK
The downside with this approach is that it relays all mail, including that destined for unknown addresses. This means that Kenmore completely accepts the inbound mail and takes responsibility for it, so when the final destination refuses to accept the message, we're stuck with the job of sending a bounce back to the sender. Since the sender address is often bogus, our outgoing mail queue gets filled up with trash. This sucks.
The solution is to teach Postfix about the local users on the target mail servers, and this is done with the relay_recipient_maps directive in /etc/postfix/main.cf:
The file /etc/postfix/relay_recipients contains a list of all the remote users, so Postfix is able to reject invalid recipients right during the SMTP handshake. We never take ownership of the message, so there are no bounces for us to think about.smtpd_recipient_restrictions = permit_mynetworks, check_recipient_maps, reject_rbl_client relays.ordb.org, reject_unauth_destination relay_recipient_maps = hash:/etc/postfix/relay_recipients
Maintaining the list of remote users can be problematic lest Postfix accept or bounce mail improperly. For very small mail servers it may be possible to edit this list by hand, but otherwise automated systems can be used. We plan on investigating LDAP for this, but for now are still trying to make sure we have a handle on the overall procedures.
Today I was reviewing some C code and found this hideous piece of trash that showed just how badly off the rails a program can go if somebody doesn't know their friendly-neighborhood C library. Let's look at this in some detail:
1 /* 2 * n_int() 3 * 4 * Generic n = nint(x) function, where 'x' is a double and 'n' is 5 * an integer. 'n' is the whole number portion of 'x'. Example: 6 * if x = 2.3456, then n = 2. This code is brute force, but should 7 * work on most C compilers. Additionally, n_int() is only called 8 * a couple of times in the program and this should not have any 9 * noticable performance impact. 10 */ 11 int n_int(double x) 12 { 13 char s[128]; 14 char *p; 15 int n; 16 17 /* 18 * Convert 'x' to character representation. 19 */ 20 sprintf(s, "%10.10lf", x); 21 22 /* 23 * Find the decimal point (or end of string if no '.'). 24 */ 25 p = s; 26 while (*p != '.' && *p != '\0') 27 p++; 28 29 /* 30 * Truncate string at decimal point and convert 31 * the integer portion of the number. 32 */ 33 *p = '\0'; 34 sscanf(s, "%d", &n); 35 36 return (n); 37 }The idea is to truncate the fractional part of the integer, many large steps are being taken that don't need to be. Lines 22-33 look for the decimal point -if any - and truncate it, but this is what the strchr() library function is for.
if ( (p = strchr(s, '.')) != 0 ) *p = '\0';Line 33 uses the overkill sscanf to convert a string to an integer, but when the atoi() function is available, it should be used instead. But since atoi stops once it finds a non-digit anyway, there is no need to truncate the decimal point - this obviates a whole step. Duh.
Those versed in the math library will certainly point to the floor() function, which returns the greatest integer not larger than the given floating point value, and this has great promise. Even accounting specially for negative numbers, the code is much simpler:
int n_int(double x) { int n = (int) floor(x); if ( n < 0 ) n++; return n; }Are we done? No, not quite. Since the goal of this function is simply to perform integral truncation towards zero, why not let the compiler do it for you intrinsicly? This is the usual behavior for float-to-int conversion, so our function now becomes:
int n_int(double x) { return (int) x; }Sigh.
I work at home in a quiet residential neighborhood, and it allows me to engage in something I've done my whole life: hand-taming wild birds. There is a pair of beautiful scrub jays in my back yard, and it didn't take long to get them to come right in the house and take peanuts out of a tub on my desk. I'll soon be ordering some waxworms and working on the hand feeding while working on my laptop on on the back porch.
(click the image for a bigger version)
While following a banner ad, it launched Internet Explorer (not my usual browser), and it opened a panel on the left to WindowsMedia.com. They show news topics with an invitation to "go watch", but this one strikes me as a bit on the gory side. Maybe these should be checked by hand first or something?
I've used Cisco equipment for years and have gotten fairly comfortable with getting around in IOS. Lately, in my role as administrator for Peak Webhosting I've been working on Juniper routers, and it's just been a delight. Such a clean command interface with features that I so much wish Cisco had. Hell, I just wish Cisco could pick one interface and stick with it.
A few of the tidbits that I ran across that are so nice:
"show | compare" does a "diff" between the proposed configuration and the saved one, and it makes it clear what changes have been made.
"commit check" parses the updated configuration and reports errors without installing anything, and this caught a netmask error that would have been painful to clean up after the fact.
There's more, of course, and none of this addresses the quality of the underlying hardware, but I surely can see the difference between a great command interface and a crappy one.
I'm writing some code that needs to configure a networking device via SNMP, and initially the device has no IP address. Though the unit supports DHCP, we can't use it, and we must use SNMP broadcasts to configure the device's IP address. We're using the excellent NET-SNMP toolkit, but it specifically does not support UDP broadcasts (which is done by setting the SO_BROADCAST option on the socket).
We've managed to hack the library to support this, and the changes were pretty straightforward. The patch file has the instructions, which are found here.
The amount of spam in my mbox has risen dramatically, and I've had multiple customers begging for me to find a way to make it stop. I implemented ORDB a long time ago, and though this helped, the spam is just overwhelming and getting worse.
So I'm building a standalone appliance for cleaning - ("kenmore" - sorry Sears) - and it's coming together nicely. It's built on the very cool Shuttle SS51G small-form-factor cabinet w/ motherboard (2GHz Pentium 4, 512M RAM). It's running Red Hat 7.2 with Postfix 2.0.3, and I spent my first time getting this working. Postfix 2 works a bit differently than the previous versions, so I had to brush up. I'm also very intersted in really understanding PostFix, so it's not good enough that the relaying work correctly - I have to know why. Postfix is great.
Then I added SpamAssassin in the "simple filter" mode - the messages are run synchronously through the filter, and it involves a full shell/perl process launch. So far it's working, and my spam is routed automatically to a separate folder on my Mozilla mail clinet. I do only tagging, not deleting.
Next steps:
But this is all very encouraging.
In the office, I now have a stack of Ethernet-based print servers, all of which are being evaluated for a customer project. We were shocked to find that the first device we looked at could not process more than 24 kybtes of data per second, which is way below the roughly 900 kbytes/sec possible by the attached printer.
After evaluating three of these things, I put a sniffer (tcpdump) on the line and decided to figure out what was going on. In the process I got a live lesson in crappy TCP performance that simply jumped from the trace listings.
These would be great four low-end tasks (printing ASCII reports from an accounting system), but they positively suck for image printing.
I've written a Tech Tip evaluating these devices and the methods used for testing
Tech Tip: Measuring Network Printserver Performance