Follow up from the last post: Comments should be working again, although not in a fashion that I’d prefer. I had to completely disable Admin-SSL, thus login and login cookies are no longer secure. If you logged in while it was active, you’ll likely need to log in again before you can post, even if you check the “remember me” box. I’m still looking into why it doesn’t work. There’s a known limitation that shared SSL setups will fail to recognize logins in insecure mode, but they say nothing about dedicated setups like mine, which I would think would imply that it ought to work. Then again, I also had some mod_rewrite rules in place, but I experimented with removing those and so I don’t think they’re part of the problem.
I suppose this isn’t a big deal for you guys, since I doubt anyone will be all torn up over making sure their logins to some random guy’s blog are secure. It affects me more than anyone else, because I’d feel much safer if I could protect the admin parts of the site with a layer of encryption. Still, in places where I really need encryption I can verify it still works, so I guess the blog will just have to be open. :\
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 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.
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….
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.
Sorry for the recent silence, everyone. It wasn’t my intention to seemingly disappear for several weeks. As you might guess, it’s been entirely real life craziness keeping me hopping. There were several occasions were I actually planned to post something, only to get distracted and never get around to it.
Well, here’s some news definitely worth posting. I mentioned quite some time ago my plans to eventually move the blog from its current home—my Linux box Demeter sitting behind my cable modem—to somewhere a bit more stable. Not that Demeter herself is unstable, mind you, but the current hoops we have to jump through just to get the blog online have caused casualties to its usefulness, like killing commenting and making our RSS/Atom feeds go through odd channels. While my dynamic DNS service does an admirable job in getting the raw HTML to you guys, it’s not suitable for a long term solution.
The point is that it looks like the move is going to finally take place, only the final destination isn’t where I originally intended. I was planning to move to Keenspot on the back end, largely because I am already familiar with them and how their servers are set up. Of course, this also meant the blog would be loaded with ads to cover the bandwidth costs (unless, of course, you’re a Keenspot PREMIUM subscriber). Not something I’m particularly thrilled about, but I was viewing it as a necessary evil. (After all, it’s the ads (and PREMIUM) that currently keep GPF a float. Lately all our other revenue streams have been high and dry.)
Well, Chris Wright over at Help Desk managed to change my mind. He pointed me to his current web host, and after taking a cruise around their site and FAQ, I was hooked. I have a number of ambitious online plans in the works, all of which require some rather stringent and quirky software requirements. These guys seem to cater directly to online developers, meaning they’re a lot more likely to accommodate my unusual needs, and their prices are ridiculously beyond reasonable. (I’ve never seen a bandwidth plan as cheap as theirs.) So I’m going to move over to them, at least on a trial basis, to see how things go. If everything goes over well, expect to see some rather obnoxious plugging in the future.
So, what does this mean for you? Right now, not much. For the time being I’ve temporarily disabled sign-ups for commenting. Comments aren’t working right now anyway, and preventing anyone new from signing on should make moving the database easier. (Existing accounts should be intact once the move is complete.) The switch in the DNS should be largely transparent, so those of you who visit the site directly shouldn’t notice anything different (other than the odd nested frame set inserted by the dynamic DNS should be gone).
The real funky stuff will come with the feeds. By now, most of you should be using the “domain:port” URLs for RSS and Atom feeds. These bypass the dynamic DNS and go directly to the web server on the port it’s really running on, not being nested through the DNS’ frames. Unfortunately, there won’t be a graceful transition for the feeds, as I have no intention of running the web server on multiple ports after the move. (It’s technically possible, but probably a waste of resources.) So those of you reading the blog via the feeds might want to come by the site periodically and check in for updates, at least until we know the transition has successfully taken place. New feed URLs will be posted once the move is complete. (Of course, I ought to just go with FeedBurner and hide all this behind-the-scenes garbage, but I’m also lazy and I’d rather do things myself.)
So when is all this going to go down? I’m not quite sure yet. The new host has a waiting list as they allocate hardware dynamically based on demand. I’ve been told it should be “less than a week,” which could be anywhere form one to two days. Tack onto that a day or two for me to move the database and debug everything, and it could easily be a week or more before you’ll notice anything. As usual, though, you should be able to just pop in here anytime and get the latest, regardless of which host we’re currently on.
Most of you are probably wondering what happened yesterday with the blog. For those who may not have seen it, folks visiting the site via a Web browser were being redirected to another site. I won’t post its URL, as I don’t particularly want to give them any more Googleshare, but it seemed to be some sort of portal site in a language I didn’t immediately recognize. Some of you have speculated that this might have had something to do with the impending move to Keenspot, or perhaps with Keenspot’s current DNS server problems. While I wish those were the case, unfortunately they weren’t.
It looks like it was a problem with my dynamic DNS service, DNS2Go. As previously stated, DNS2Go has an HTTP redirection service that lets me forward “www.jeffdarlington.com” on standard HTTP port 80 to the site’s real IP address at its real non-standard port. This is the component that seems to have failed. Going to www.jeffdarlington.com took you to the mysterious site; however, if you went to jeffdarlington.com:8081 (the site’s real port number), you got the blog. (The style sheet didn’t work, of course, because WordPress hard codes the domain name in all URLs, including to the style sheet. But the content itself was still available.)
I put in a support ticket last night with DNS2Go’s tech support and got the following response this morning:
It was something on our end and we have resolved that problem.
Not very descriptive, but accurate; the site is obviously now up. My guess? I think they were hacked, and they don’t want to admit it. Their own main domain was also down during this time, and all of my domains that used the redirection service in some fashion were affected. I haven’t had a chance to independently research this theory with the conference going on and all, but it seems a bit more suspicious to me than just a technical glitch.
Anyway, things are back to normal now. The move to Keenspot is currently slated for the weekend of April 20th, just in case anyone is interested in knowing.
Just a heads-up, gang. As previously mentioned, it looks like the blog is going to be moving. I’ve finally received the official go-ahead from the powers that be at Keenspot that they’re okay with the move. I’m not sure yet when it will officially happen, but seeing as I’ll be on a business trip next week, it might be a week or two. I’ll have to iron out the details with the Keen Tech Crew first.
So what does this mean for you? Well, if you read this blog via a Web browser, probably nothing. Just keep using the old www.jeffdarlington.com domain name and you shouldn’t notice any difference, just that one day the blog won’t have Keenspot ads and the next day it will. Isn’t the magic of DNS grand? (If the ads bother you, then I’ll go ahead and make the prerequisite plug for Keenspot PREMIUM, which removes those ads and puts a few extra bucks in my pocket at the same time.)
If you’re checking for updates via one of the XML feeds like RSS or Atom, you might want to periodically peek in via a browser, especially if I seem even more silent than usual. (Yeah, I know, that’ll be hard to notice as my updates are somewhat sporadic. Sorry about that.) The reason I mention this is that the feed links currently bypass the dynamic DNS’ Web forwarding (i.e. the translation from the domain name on port 80 to the IP on the real port; check this post for the gory details). Unfortunately, when the site moves to Keen, that alternate port will no longer be available and the XML feed links will return back to port 80. To anyone currently using the feeds on the alternate port, the feed will appear to break. You’ll need to keep an eye on the feed URLs to notice when they update. I’ll look into ways to redirect them, but I doubt Keenspot will be willing to jump through those hoops just for me.
If you don’t read this blog, then… well… what are you doing here, then?
I’ll try and keep you apprised of things as often as I can. I plan to move as much data from one site to the other as possible, so hopefully those of you who have already signed up for commenting shouldn’t need to worry about signing up again. Thanks in advance for your patience.
Not a good blog weekend. But now the weekend is over, and everything looks to be back in working order. For the moment. I hope.
Comments should now work, I believe. Tim from Germany came to our rescue again and pointed me toward a WordPress plugin called wpPHPMailer. This wraps the more generic PHPMailer script into a WP plugin and allows WP to send mail via a third-party SMTP server instead of through PHP’s mail() function, which uses the server’s built-in mailer (like sendmail). Thus, I can get around the problem of WP sending out password confirmation e-mails and commenters should be able to register. You’ll find the registration link in the Meta part of the side bar (right above the “brain dump truck” image).
As for why the blog was down all weekend… blame my ISP. Sometime Saturday, our power flickered. The computers were fine, as the laptops went on battery power and the desktops flipped to the UPS. However, something must have happened between the ISP’s router and our cable modem to cause them to “lose” our cable modem’s MAC address. Yeah, I don’t understand that one either. The ISP and the cable modem wouldn’t talk to each other, so we couldn’t get an IP and thus couldn’t get online. My wife (who works from home and thus needs VPN access) called the ISP and got things settled sometime yesterday morning.
Now hopefully I can post about something other than what’s wrong with this blasted site.