It has come to my attention that comments don’t appear to be working here at the moment. I strongly suspect this is due to the Admin-SSL WordPress plugin that I’m currently using to secure parts of the blog. It seems to forget that you’re logged in when you’re not accessing a secure URL (i.e. you’re not in SSL mode). I’ve tried a few of the workarounds suggested, but none are working. I have a hunch on a few things to try, but that will have to wait until I have more dedicated time to work on it. (I’m currently watching the little guy by myself at the moment.) I’ll post an update when I think it’s been fixed.
I was downloading Fedora 8 yesterday with every intention of (eventually) upgrading Demeter, our Linux box, currently running Fedora Core 5. I say “eventually” because finding time to back everything up, install the new OS, restore all the files and third-party apps, and then spend hours debugging what went wrong is the hardest part of the whole process.
Anyhoo, I thought I’d put good ol’ WinHasher to use to verify the SHA-1 hash and make sure the download was successful. That was, after all, the primary reason I wrote the thing. But then I noticed something incredibly annoying. The DVD ISO for Fedora 8 weighs in at around 3.18GB. WinHasher has no problems hashing such a file as it hashes the file stream as it reads it, so it can hash any file of arbitrary size. But while it’s doing so, there’s absolutely no feedback to the user. In fact, if you use the right-click “Send To” shortcut, unless you go into the Windows Task Manager and check the process list, you won’t even know the thing is running. It seems to go off into la-la land until mysteriously, a minute or two later, it comes back with a mysterious pop-up box with a cryptographic hash in it.
Bad programmer! Bad!
Well, this annoyed me enough to fix it, so I’ve tweaked it now so it actually runs multi-threaded. This is ridiculously easy to do when you use the System.ComponentModel.BackgroundWorker object in .NET. You just create the object, create a few event handlers for it, and tell it to go do its thing. The hardest part is if you want it to report its progress; then you have to tweak your working code to generate a percentage complete so it has something to display. I learned this trick when I was working on Mandelbrot Madness! 2.0; I have no idea why it never occurred to me to incorporate it here. The annoying part about this addition, though, is that there’s no way to report on the progress of an individual hash. System.Security.Cryptography.HashAlgorithm doesn’t provide a way for you to know how far it’s gone, so there’s nothing to feed to BackgroundWorker.ReportProgress(). The comparison feature does, however, let you know how many of the files have been processed so far in the batch.
So if you’re one of the few brave souls who downloaded WinHasher 1.0, please grab 1.1 at the official site. It officially goes up tomorrow (a delay caused by Keenspot‘s parsing to insert the advertising codes). If you haven’t already downloaded it, why not give it a try?
I mentioned last week that I was working on a neat Apache mod_rewrite trick for locking down access to certain administration pages, but that I wasn’t having much success with it. Well, it seems to be working now and, as promised, I wanted to share it with anyone who might be interested. Fair warning to non-technical readers: extreme geekery lies ahead.
First and foremost, I can’t claim full credit for this idea. It borrows some from Steve Gibson‘s roaming authentication scheme outlined in episode #113 of the Security Now! podcast. In that show (and subsequently continued in episode #115), Gibson outlines his method of allowing his employees to access secure portions of his site while traveling. The method described here is not quite as secure as his, as I’m forcing things to happen at the Web server software layer as opposed to the application layer and thus don’t have the same fine granularity of control he has. However, it uses many of the same ideas.
It’s relatively easy with mod_rewrite to protect certain resources of a site by restricting access to certain IP addresses. Consider the following:
RewriteCond %{REQUEST_URI} ^/store/admin/.*
RewriteCond %{REMOTE_ADDR} !^192\.168\.13\.
RewriteCond %{REMOTE_ADDR} !^127\.0\.0\.1$
RewriteRule ^/store/admin/.* /store/ [R,L]
This rule set essentially says: (1) if the requested URL starts with the string “/store/admin/” and (2) the IP address of the requesting client does not begins with “192.168.13.” or (3) is not exactly “127.0.0.1″ then (4) redirect all requests for URLs starting with “/store/admin/” to the root URL of the store, “/store/”. Essentially, we’re only allowing access to what is apparently the administrative portions of an online store to a very limited number of IP addresses, one of which is fully qualified (the “loop-back” address of 127.0.0.1) and the rest belonging to a range (192.168.13.0 through 192.168.13.255). Anyone outside these IPs will be transparently redirected to the front page of the store. (Redirecting is much friendlier than outright forbidding access.) All of this takes place in Apache itself, before we even get to the application and any potential security flaws it might have. There are no worries about hacking the store software itself to deny access. Of course, we can list any number of REMOTE_ADDR entries that we wish; each condition is a regular expression (which are negated here by the “bang” at the front) so we can filter on any octet we want and can easily specify real, outside IPs rather than private ones. For example, for this site I limit access to my various admin sections to the IP of my cable modem and our outside IP at work.
However, what happens when you are required to go on a trip and need to access the administrative parts of the site while on the go? Obviously, you can’t add the hotel’s outside IP to this rule set in advance (imagine asking the front desk for that information), and you probably won’t be able to add it easily once you get there. Sure, WordPress and the store front software have login security on their various admin interfaces, but we’re trying to protect those from hackers, right? Aside from reopening them to the entire Internet before the trip and closing them again once we get back, there aren’t very many options. How then can we identify approved “roaming” users and/or machines so they can access the admin sites without being inside a hard-coded list of IPs?
Gibson’s answer was to optionally set a secure cookie in the user’s browser if they access the admin site within one of the approved IPs first. Being within an approved IP, they aren’t restricted by the access rule and they are allowed to reach the login prompt. During login, they are prompted on whether or not they want to enable roaming access on this particular machine. If they agree, a secure cookie is set in the browser and set to expire at some date in the future. Later, when the user attempts to access the admin site outside of the approved IP list, the site checks to see if the cookie has been set. If present, the user is allowed to log in, just as if they were within one of the approved IPs. The cookie acts as a kind of two-factor authentication: the first factor being “something you know”, the user name and password, and the second being “something you have”, the cookie. Since the cookie is set in secure mode (HTTPS), it will only be sent back to the site over a secure connection. And since (well behaved) browsers only allow a site to read the cookies it has itself set, no other site should be able to read it.
This is all well and good… if you have access to the source of the application you’re trying to secure and you’re willing to hack it. Gibson wrote his own store front, so this was relatively easy for him to integrate. But I want to secure WordPress, a third-party store app, and a few random subdirectories that are pretty much statically built HTML. As much as I like running Open Source software, I usually prefer not to muck around with things if I can help it, lest I screw something up. Thus, I don’t particularly want to hack WP and the store to add this extra layer of functionality. Fortunately, though, mod_rewrite gives us a mechanism through which we can accomplish basically the same thing without modifying the underlying application. In theory, since all this occurs before we even reach the application, one could argue it may even be more secure than the application’s authentication mechanisms themselves.
You can actually set browser cookies via mod_rewrite rules. Consider what happens if we insert the following before the rules we defined above:
RewriteCond %{REMOTE_ADDR} ^192\.168\.13\.
RewriteCond %{HTTP_COOKIE} "!(.+; )*admincookie=uniqueval(; .+)*"
RewriteRule .* - [CO=admincookie:uniqueval:.domainname.tld:43200:/store/]
This rule set essentially says: (1) if the remote IP starts with “192.168.13.” and (2) there isn’t a cookie already set by the name “admincookie” then (3) set a cookie named “admincookie” with the value “uniqueval” for the domain “.domainname.tld” (assuming that’s our real domain name) for a period of 30 days (60 minutes x 24 hours x 30 days = 43,200 minutes) restricted to the path “/store/” and its subdirectories. Now let’s modify the rule set from before:
RewriteCond %{REQUEST_URI} ^/store/admin/.*
RewriteCond %{REMOTE_ADDR} !^192\.168\.13\.
RewriteCond %{REMOTE_ADDR} !^127\.0\.0\.1$
RewriteCond %{HTTP_COOKIE} "!(.+; )*admincookie=uniqueval(; .+)*"
RewriteRule ^/store/admin/.* /store/ [R,L]
Note that we’ve added a new condition. In addition to checking for the approved IP list, we also check to see if the “admincookie” has been set and that its value is what we expect (“uniqueval”). Note the parenthetical parts at the beginning and end of the cookie regex; these should make sure we match the unique cookie name/value pair, regardless of how many cookies are present. (Also note the quotes around this regex; since whitespace delimits the parts of the rewrite statements, the quotes are required to include the spaces after the semicolons in the regex. Without the quotes, the regex produces a “bad flag delimiters” error when Apache parses the configuration file.) Since each approved item’s entry is negated, the rule is only applied if none of them match. So now we should be able to get into the site remotely if and only if we’re inside an approved IP or we have the secret cookie, which we know is only set if we’ve been in one of the approved IPs first. Instant roaming authentication!
To summarize, the primary advantages to this scheme are:
There are, of course, a few caveats:
mod_rewrite to force certain URLs to always use SSL (assuming you have a secure certificate), thereby securing the connection first. All WP admin functions, the GPF Store, and my other secured admin locales here on this site are all secured via SSL, so that helps in keeping my site secure by eliminating sniffing. (Of course, if you go this route, don’t forget to copy any necessary rules from the main Apache configuration file to the SSL config file, as the secure site will be treated as a different virtual host with its own set of rewriting rules. This little hiccup is what was keeping me from publishing this for quite a while.)mod_rewrite does not have the facility to specify secure mode in a cookie set by a rewrite rule. Thus, the above cookie is not secure and will be sent with each request in or below the specified path, encrypted or not. The cookie is then theoretically susceptible to sniffing attacks. Setting a secure mode cookie is easy enough to do in application code, but not apparently so in mod_rewrite.mod_rewrite. (Remember, all this is occurring in Apache before we even reach application code.) Right now, %{HTTP_COOKIE} variable gets all the cookies for a given site/path as one big string, with each name/value pair delimited by a semi-colon and a space (“; “) and the name and value are glued together with an equal sign. I’m looking into a better regex to match this more precisely and I’ll update this post if I find one.I welcome any feedback on how to improve this, especially if anyone knows how to get around the secure and unique cookie caveats.
Appendium: I should also point out that this scheme should be equally usable if you place the code in your master Apache configuration file (usually something like /etc/httpd/conf/httpd.conf on UNIX clones) or in per-directory .htaccess files. I usually prefer to put such rules in the master config file, mostly because it’s more secure (outside of the document root) and only gets parsed and loaded once while .htaccess files are read and parsed each time there’s a request in that directory (or any of its subdirectories). However, that only works if you have access to the master config, which most shared hosting services don’t provide. Of course, such rules placed in an .htaccess file will only apply to that directory and its subdirectories, so you’d have to tweak the rules (such as file paths and the cookie path) as necessary.
Update 11/20/2007: Updated cookie regex to better match the exactly name/value pair; added notes about rotating cookie values.
Update 11/30/2007: Put cookie regex in quotes to correct avoid “bad flag delimiters” parsing errors; added advantage summary to better showcase the advantages of the scheme; updated my cookie value scheme; added highly-random subdirectory alias to avoid unintentional cookie-ing
If you guys haven’t figured it out by now, I’m been becoming quite the Internet security nut over the past few years. A thorough search of the Technology category reveals a good bit of my interests in SSH, SSL, public key cryptography, etc. Maybe I ought to experiment with subcategories and introduce a Security category under Technology….
Anyway, WordPress usually includes some default feeds in the Dashboard after you log in, mostly from WP developers. One recent entry linked to a “geek ramblings” post about creating a secure WordPress install, which in turn references a WordPress security whitepaper over at BlogSecurity. (If you didn’t know any of these sites existed, don’t feel bad. Neither did I until today.) There’s lots of interesting reading there, especially if you’re (a) interested in securing your WordPress site and (b) you happen to be curious and/or adept enough to dabble in a number of arcane Web server settings. I happen to fit both of those criteria.
One of the main reasons I’m mentioning this is that there might be a few changes and improvements for folks who have registered to comment. The site now redirects you to a secure SSL page on login, and your cookies will be stored in secure mode too, meaning they can’t be read unless sent over an SSL connection. This might require you to log in the next time you try to comment, even if you’ve told the site to remember you, because the old cookies won’t be secure and will need to be reset. Otherwise, you probably will never notice the difference unless you go to edit your profile, which most of you probably will never worry about once you’ve registered.
The rest of the changes are all behind the scenes, so I won’t bother you with them. Just read the links if you’re curious. I’m experimenting with some arcane Apache mod_rewrite rules to really locking down the admin pages, all outside the scope of the links listed above, but so far those tests don’t seem to work. However, if I get them to do what I want, I might post them here (to give back to the community and all). It will be pretty sweet and borrows a few ideas from recent episodes of the Security Now! podcast (#113 specifically) to lock down access to the admin site from only certain locations or certain roaming computers.
I can’t think of anybody who actually likes spam. Well, aside from spammers, of course. After all, those guys obviously make thousands, if not millions, of dollars from gullible, attention-starved sellers looking to get noticed by any means, no matter how disreputable. And those being advertised obviously keep coming back because they’re making dough off of the few idiots out there that actually buy spam-advertised products. But the rest of us–the poor, innocent Internet users just trying do our thing, not looking for trouble–we’re the ones getting caught in the deluge. We’re the ones paying for the bandwidth, the filtering, the time sorting through all their mess, trying to decide whether we should reclaim our inboxes or abandon them altogether.
Personally, I have a three-tiered spam filtering solution. It’s a bit convoluted, but it works with a minimum of false positives. Currently, all my mail from their various sources is first redirected to my Pobox.Com account. I’ve been a happy Pobox user since college, when I realized that I was going to graduate soon and I’d have to tell all my friends and family to change their contact lists. Pobox lets you keep the same virtual address while your real address can change behind the scenes, so you never have to give out a new one. This was actually a great idea… before the advent of spam. Honest. Now, not so much. These days, I keep my Pobox address mostly because of their incredible spam filtering, which combines dozens of blacklists and other rules that you can customize. Pobox bounces the most blatant spam offenders, holds most of the rest in case of false positives, then sends me the rest along with a report of what was bounced or held. Anything that gets through Pobox is then forwarded to my GMail account, which has its own very excellent filters. (It’s Google. If anyone knows anything about indexing and analyzing text, it’s them.) Finally, I POP my GMail down to Thunderbird, which filters the incoming message even further. This whittles the thousands of spam messages I get per week (at least 3000 at my last count) down to virtually none, with only a handful that I have to handle manually each day.
None the less, there’s a good bit of humor to be found in spam. I often double-check my Pobox discard report and my GMail and Thunderbird spam folders for false positives, scanning subject lines to make sure I don’t lose the odd piece of fan mail or legitimate commercial message from businesses I actually choose to interact with. And I often find a few gems in there, the odd little quirk that for whatever reason gives me a chuckle. Let me share a few….
I’m not sure if anyone cares, but I’ve been doing a tiny bit of dabbling in releasing Open Source software lately. Since I don’t particularly care to announce them on the GPF News (it isn’t, after all, GPF news), I’ll announce them here. For those of you who might complain that working on these has taken precious time away from the comic, fret not. The tiny bit of time I’ve been able to squeeze in here and there to work on these have been during periods when working on the comic would be impossible, so there’s no way for there to be any conflict.
The first one I’ll announce is the most recent. WinHasher is a Microsoft .NET Framework 2.0 application for generating cryptographic hashes of files. It is both a Windows GUI applet and a console (command line) program, and it operates in two possible modes. The first mode generates the hash of a single file, which you can then use to verify a download or check to see if a file has been tampered with. The second mode takes the hashes of multiple files and compares them; in this way, you can see if two or more files have the same binary contents regardless of their names, locations, and time stamps. The Windows app supports drag-and-drop functionality, and the installer lets you also build shortcuts in your Windows Explorer “Send To” context menu so you can just right-click a file and get its hash.
So why did I build this? Well, the full details are on the site, but the quick version is that I’ve grown tired of not being able to validate the hashes of downloaded files because Windows doesn’t have a built-in hashing program. Linux and the other free UNIX clones have OpenSSL; heck, even Mac OS has OpenSSL under the hood. Not Windows… of course. So instead of downloading a file on a Windows machine, copying it to the Linux box, validating the hash, and moving it back (or worse, just not even validating the hash at all and taking my chances), I hacked together this little program. Then I thought it might be useful enough to share, so I did. If you find it useful, please let me know.
For the really technically inclined out there, most of the hashes are built-in to .NET 2.0, so this was obscenely easy to implement. In fact, 2.0 has an abstract hash algorithm class (System.Security.Cryptography.HashAlgorithm) that all of the built-in hashes implement. The two non-standard hashes, Whirlpool and Tiger, were taken from the Legion of the Bouncy Castle Crypto API, which is actually .NET 1.1 based. I (rather crudely) ported these classes to be subclasses of HashAlgorithm, so they can technically be used as a drop-in replacement of any .NET 2.0 hash. I plan to add additional hashes over time, provided that (a) the original source code is free and (b) I can port it to be a HashAlgorithm subclass.
The second program to mention is actually a bit of an oldie now. (I actually released it back in June.) The Windows version of Mandelbrot Madness! is back, also in a .NET 2.0 edition. I wrote the original in Visual C++ 4.x, but have long since lost the source code. Then the Java version came into being and rapidly surpassed the Windows version, leaving it to suffer from bit rot. Both eventually languished as I lost time to work on them. Well, in December of 2005, I released the not-quite-complete-but-close-enough 4.0 version of Mandelbrot Madness JAVA!, declaring it abandoned. It always bugged me that I never went back and revisited the Visual C++ code, but without the source I was stuck.
Well, to make a long story short, my new job had me learning a new programming language: C#. That had me programing Web sites, but I knew you could also do Windows GUI apps in it as well. So somewhere down the line I got a wild hair and started the agonizing work of porting the Java code from the last version of MMJ! to C#. Actually, Java and C# are similar enough that the porting work wasn’t all that hard. Not only is MM! 2.0 now pretty much identical in functionality to MMJ! 4.0, but I introduced a number of new features that I hope to eventually port back to the Java version. While I still prefer the platform independence of Java, I’ll readily admit that the .NET version is a lot faster on Windows. I think that anyone on that platform that has actually bothered to play with the Java version (both of you) should make the switch. Anyone still using the decrepit old 1.0 version of Win32 MM! should enter the 21st century and upgrade too.
Both programs have been released under version 2 of the GPL (haven’t had time to really review version 3 yet), so the sources are also available. If you have any suggested changes, feel free to pass them along and I might incorporate them into the official builds (giving you credit, of course).
Ordinarily, I don’t go about announcing underlying technology upgrades (for example, I just upgraded iptables and Apache this morning), but I thought this was mildly amusing and I thought I’d share. As the observant among you probably know, I’m running WordPress, which just released version 2.3, nicknamed “Dexter”. It is so named after the “great tenor saxophonist Dexter Gordon.” Darn… I was being hopeful….
Alas, my beloved LifeDrive is out of commission. This past weekend, I was at a local park where my parents were throwing a combined party celebrating my dad’s retirement, my mom’s birthday, their anniversary, and my dad’s birthday (which, coincidentally, all seemed to happen at once and in that order). I was helping clean up after most everyone had left when the LifeDrive was knocked off my hip and took a dive into the concrete floor of the shelter.
A year ago, I probably would have panicked. I had heard so many horror stories about how fragile the LifeDrive was compared to other PDAs, with its internal moving parts (i.e. the hard drive). By this point, though, my LD had taken so many tumbles onto so many hard surfaces that I barely batted an eye. Perhaps I’ve been one of those fortunate few to have found a sweet and juicy apple among bushels of lemons… or perhaps there are fewer soured former LD owners out there than everyone thinks and they’re just more vocal. At any rate, I was more annoyed at the inconvenience than concerned. It had taken far worse roller coaster rides than this thanks to gravity. I picked it up, snapped its clip back on my hip, and went back to my business.
It was when I got home that I noticed this wasn’t a run-of-the-mill bump. When I tried to use the LD the next day, I found the digitizer was no longer registering correctly. The digitizer, for those who aren’t familiar with PDA anatomy, is the sensor that overlays the LCD screen and detects taps and drags with the stylus (or finger, or pen tip, or whatever impromptu pointing device you choose). The digitizer continued to sense the stylus, but the location was grossly off, so badly in fact that the built-in calibration utility wouldn’t work. When I tried to recalibrate it, the taps would be so far out of place that the utility could not register them and would never exit. I did a careful inspection of the case to make sure it wasn’t bent to the point where it pressed against the digitizer and thus interfered with its operation, but unfortunately that wasn’t the case.
So by now it should be on its way to be repaired. Recalling the death and resurrection of my Tungsten C, I contacted Chris Short again, and he should be receiving the device shortly. I once again heartily recommend his services to those who need PDA (especially Palm) repairs.
Of course, it could have been worse. I count my blessings that my cats’ mouths are too small to do that kind of damage.
Sorry again for the silence, everyone. The past several weeks have been rather hectic. Obviously, I’m back from SIGGRAPH, which was earlier this month. The con report on the GPF site is forthcoming; the slideshow is finished, but there’s no link to it from anywhere yet (until this one). Then as soon as I got back, my wife had to first fly to Portland, OR, for a week, then this week she’s in Seattle, WA. Three week-long business trips back-to-back, and whoever isn’t criss-crossing the country is busy watching the little guy. It’s a wonder I’ve had time to do anything except breathe.
Anyway, the second purpose of this quickie post is to let everyone know I’ve made a minor structural change to the blog. I’ve changed the permalink structure from the WordPress default which uses parameters on the query string (http://www.jeffdarlington.com/?p=4) to something hopefully a bit more user-friendly that combines the date and the page “slug” (http://www.jeffdarlington.com/2005/02/17/i-hate-blogs/). I’ve implemented a series of complex Apache mod_rewrite rules that should allow old permalinks to work transparently, not only from the old WordPress query style but also from the old Movable Type links of yore. If anyone encounters a broken link or a link that points to the wrong page, please let me know so I can adjust the rules. Obviously, it would be best if you could update any links you have to this site to the new URLs, but I’ll try to be as accommodating as possible.
I have more interesting things to post, so I’ll hopefully have those up soon.
If you’re seeing this post, then welcome to the new server! Our new host is Slicehost, a small hosting service that caters specifically to online developers. I have to say that so far, I’m pretty impressed. I had a few bumpy points getting SSH started and the initial setup was so bare-bones I had to install a ton of packages just to get functional (including fundamentals like tar and which), but it’s moving a lot faster than the old site sitting behind the cable modem.
Slicehost does one thing that I think is really pretty slick, especially from a hard-core geek’s point of view: Unlike most web hosts who give you a little sandbox to play in and tie your hands on what you can and cannot do, the “slicers” give you your own virtual server with root access. That’s right, you have the keys to the virtual kingdom. That means you decide what gets installed on your box, from the Linux distro (no other OSes are supported at the moment, but they do offer several distros) to the individual server applications. Want a LAMP box? You got it. Prefer Fedora to Ubuntu? (Me! Me!) Here you go. You decide what gets installed. The caveat to such permissiveness, of course, is that if you screw it up, it’s your own darn fault. That’s okay, though, because your virtual server shouldn’t affect anyone else sharing the box and you can rebuild your “slice” at any time, wiping it clean and restoring it to its original pristine state. Pay a nominal extra fee and you’ve got backup snapshots that you can also restore in the case of catastrophic failure.
One thing to watch out for is the waiting list. They appear to allocate hardware dynamically based on their current user base (keeping some servers in reserve for redundancy) and then purchase new machines based on their projected demand. If you sign up for the smallest package with the minimum prepayment plan, you could be looking at several weeks of wait time. However, if you’re willing to pay a little more in advance, you’ll be moved up the list. I decided to prepay for six months instead of three and was told I’d have my “slice” in “less than a week.” I ended up getting it in a few hours. Yep, that’s technically less than a week.
Initial annoyances (I’m not sure I’d call them complaints):
All in all, though, I think I’m going to like this new home. If you’re interested in checking them out, click the link in the first paragraph and poke around. If you decide to sign up, though, come back here and click my referral link. A little kickback is always nice.
Of course, now that we’ve moved, commenting should be re-enabled. If you created an account before the move, it should have been ported over. (The internal user ID numbers got switched around, but since no one was able to post after I switched to WordPress, I don’t think that really matters.) Feel free to log in and make sure your account is accessible.
Feed readers: Please update your feed links now. You’ll find the new RSS and Atom links in the “Feed Me” section of the sidebar. Remember, the old “domain:port” URLs will no longer work.