Thursday, September 13, 2012

How to Mitigate CRIME attack in Apache

Perhaps you've seen the new CRIME attack on Compression in TLS connections.

The exploit uses a sidechannel attack (a piece of JavaScript running on the victim's machine) to repeatedly query a server and compare the time it takes each request to complete to eventually learn what the contents of an HTTP cookie is (while examining the encrypted packets on the wire using main-in-the-middle). Proof of concepts have been shown against Github, Dropbox and Stripe.

If you're running Apache you'll probably want to mitigate the attack, so here's how.

Mitigation in Apache 2.4.3+

Just add the line 'SSLCompression off' to your SSL configuration and restart Apache.

Mitigation in Apache 2.2 and Apache <= 2.4.2

Unfortunately older versions of Apache don't have an option to disable SSL compression (it's still being backported as of this writing). There are three options you have, one will work, the other two maybe not.

The first option is to recompile OpenSSL without zlib support; this will prevent the DEFLATE compression method from being used by the SSL module. This is a pain, but is guaranteed. You should still be able to use mod_deflate to compress HTML, however.

The second option you have is to patch Apache 2.2.22 (and possibly earlier versions) to include an SSLCompression option like in Apache 2.4.3. I just created this patch based on the 2.4.3 patch, but have not tested it. The code was pretty much verbatim the same however, so it should work. The patch is here.

The third option may not actually prevent the attack, but it's an idea I had. The configuration looks like this:

    SSLOptions +StrictRequire
    <Location />
    SSLRequire (  %{SSL_COMPRESS_METHOD} ne "DEFLATE" )
    </Location>

This will force any request to fail in "<Location />" if the request used SSL compression. The browser may still send a cookie with ssl compression, however, so the server may still cache the request and might have a similar side-chain attack vector to the original exploit. Use with caution and verify for yourself if the exploit is still viable.


Resources:


https://httpd.apache.org/docs/2.4/mod/mod_ssl.html#sslcompression
https://issues.apache.org/bugzilla/show_bug.cgi?id=53219

Monday, August 20, 2012

How Not to Install Software

Before I had written a single C program I knew what ld and gcc and autoconf were. I knew the difference between a library and an application, and quickly learned what 'core' software was. All of this I learned because I wanted to use Linux.



When I was a Windows user, there wasn't much I needed to know to install a new program. First you check the system requirements of the program ('Windows 98 SE? Got it!'). Next you'd download the program. The following week when the download was finished, you start the installer. Then go make a sandwich. When you come back, you get to configure the software using a handy wizard. Finally it would be done, and you would click on an icon and run your program.

Linux was a different animal. If you wanted a piece of software that didn't come with your distribution, you had to check if someone had made a package. Since they usually didn't, it meant downloading the program and compiling it. After the first couple attempts you'd figure out what the cryptic commands were ('./configure', 'make', 'make install'). Ah, fresh brewed software!

But wait - what's this error? Searching the web you might find some other person who'd had a similar bug, and they needed some extra software installed. Reading more you finally figure out what you need to get, and try to download and install that. Rinse and repeat for each new error.

Once you had struggled for a day or two with getting this thing installed you finally get to use it. It's great. You delete the source files and forget about all the stuff you installed, until one day you need to install something else.

It wants a different version of a library. OK, i'll just download that version, compile it, and try to install...

Shit, it's not working. Both libraries are installed and now other programs aren't working! I can't even use Gnome now! What's going on?! Finally in desperation I delete everything I installed in /usr/local/* and re-install all the packages from my distribution. The old stuff works again, and none of my custom software exists anymore. I'm back to square one.



From years of fighting software and many, many mistakes, I learned how software likes to be handled. Applications like to pretend they live in their own universe. Libraries like to pretend they are the only version that will ever exist. And operating systems like to pretend 3rd party software does not exist.

Distribution-provided software is very sensitive. If you want to keep using the distribution's tools, you have to keep all their software pure and pristine. The royal family of software, as it were. If there is an official package, you must use it, and never overwrite it with non-packaged software.

Third-party software likes to do it's own thing. Install where it wants to install, modify what it wants to modify, run how it wants to run. There are no guarantees here unless you start mucking with the code or the installer. Making matters worse, it usually expects you to install everything as root, making it much more likely you will screw something up by accident.



Why does this system perpetuate itself? Because users of Unix-like operating systems are expected to take on the task of becoming an expert. There is no expectation that software 'just work'. It's a near miracle if you can install packaged software without having to track down its dependencies, and impossible to install something from source without intoning the secret language of the command-line.

This shouldn't be the case. Windows and Mac have had single-file installers with no dependency requirements for decades. Even popular third-party software for Linux and BSD comes with all its dependencies, either in source or as binaries, to work around the dread art of installing software. Though this has consequences in a few corner cases, it works much better than the sea of wild technical expertise required to manage what should be a point-and-click operation.

There doesn't seem to be an end in sight. Linux distributions and software developers continue to work in silos in spite of the users who are the audience for the collective product. We sit and dream of one day using a free computer system that our grandmothers could use without needing to call us for support. But this train can't be built by a person alone. Only a collective compromise and the backs of all invested parties will build the track for us to run our trains on. In the mean time i'll keep moving product by hand.

Monday, July 30, 2012

Authentic Steam Watches

Why don't more steampunk novels involve the mechanics/engineering of victorian-era devices? Watches and gears are everywhere in steampunk culture, but it seems there's never technical discussion of them in or relating to the plot.

I got a pocket watch recently, and as is natural to me I find myself gravitating to the technical aspects. (Wikipedia) For instance, Railroads demanded very specific standards for their time pieces, lest a train derail from being off-time by a couple minutes. Therefore there are specific watches which are engineered to be very robust and keep time much more accurately.

There's even technical words which i've never heard of before, such as 'isochronism' - keeping the same time even if parts of the whole start to change. Apparently this is even used in some modern technical documents; USB has an isochronous transfer mode.

One of the things that stood out was how temperature changes the operating of the device. Extreme cold or heat will contract or expand the steel balance, causing the watch to run slow or fast. They engineered a solution which involves mating it to a brass balance and having two cuts in both, though that leads to only keeping accurate time in either extreme cold or hot environments. Special alloys ended up fixing the problem for good, though that was post-Victorian, essentially.

You could even extend some knowledge of watchmaking to other parts of a story. Jewels are often used as a hard, durable, low-friction mounting point for the moving pieces of a pocket watch. You could include in your story a plot device where one particular jewel (though normally valueless) unlocks some key to some device made thousands of years ago, as part of some detective novel revolving around ancient devices with a modern spin.

There's a plethora of technical jargon specific to pocket watches which might be nice to include in the story. If you want to write for geeks/nerds, including technical details like this can't hurt.


Some neat facts:
  • Wrist watches ('wristlets') were considered feminine and unmanly until they were introduced by the military and finally made standard issue in the 1940's.
  • The vest-pocket in a three piece suit is intended for a pocket watch. Since vests fell out of fashion, the only place to put a pocket for a watch was in trousers. Hence that little pocket you tend to put change in or try to cram a cellphone into.
  • A four-minute delay in one watch caused a train wreck, hence Railroad chronometers will (among other things) keep time to within 30 seconds in a week.

Tuesday, July 24, 2012

HSTS makes CAs obsolete

I was in the toilet, where most of my brilliant ideas come from, and I was thinking about HTTP. How it's a bit crufty and old (13 years), how it could use significant upgrades to enhance delivery of content. I thought about SPDY and how i'm wary of the 'features' it mandates, like SSL.I don't like SSL in general (it's a pain in the ass) and I like being forced to pay to serve my own content even less.

Then I thought about HSTS and how it makes it easier to connect to a site securely. Sure, it has nothing to do with transport or encryption directly, but the aim was to keep the connection secure by preventing an attack on a browser's ability to *not* use SSL. And I remembered that browsers like Chrome ship with implicit lists of sites which should have HSTS enabled by default. And then it hit me.

With an HSTS-enabled flag for a website in your browser, if you also shipped a certificate fingerprint, it basically bypasses the need for a Certificate Authority.

Think of SSH. What's the one time your connection is in peril?

The authenticity of host 'syw4e.info (97.107.132.9)' can't be established.
RSA key fingerprint is 57:f9:cf:53:3a:fb:a4:af:e0:96:3c:20:99:30:82:8e.
Are you sure you want to continue connecting (yes/no)?

That question is all that stands between you logging into a real server and a fake server, and establishing a secure connection or not. If you had that key fingerprint already you would know if it was authentic, and you could go on with your life without answering stupid questions.

This is exactly what happens when you visit a site with a self-signed certificate, only it's much more complicated than it needs to be. If your browser simply had a list of those fingerprints (similar to the list of HSTS-enabled websites Chrome has) it could connect securely, automatically, without having to verify against a 3rd-party Certificate Authority.

Though this would make the browser's connections about as secure as with SSH, this isn't practical. There are lots of websites out there. We can't possibly keep a list of all of them in the browser. But if you believe in the idea that HSTS makes us more secure than without it, simply accepting and keeping the first certificate you got would be just as secure, right? Well, there's a problem there.

Websites are constantly changing their certificates. They add and remove hardware regularly, and sometimes revoke certificates if there's suspicion their private key might have been compromised. They also change before they expire. So even if we had a list of the initial certificates' fingerprints, what happens when they change?

In order to support a dynamic network of secured systems, there would need to be an extension to the encryption protocol that allowed downloading updates for future certificates. In addition, sites could publish a list of 'trusted' hosts (perhaps even on different domains) which can also update the fingerprint, so that if host A.B.C is down, you can still get an update for it's certificate fingerprint from B.B.C, or even D.C. In this way, a very simple peer-to-peer network of whitelisted hosts could share updates about the security of the network, without being explicitly tied to a few for-profit corporations (SSL CAs).

So then you may ask, what about internal servers? How can we ensure a user going to a closed, internet-less site knows they're connecting securely? The answer there is, of course, hypocrisy.

If you want your client to be connected securely, you have to exchange some secrets. It's mandatory for encryption to be secure. Maybe it's a HMAC'd challenge-response pair, or a shared key or certificate. You need to share something ahead of time.

With SSL, it's been the chain of certificates from Certificate Authorities that live in your computer and in your browser - up to 650 or more of them! So we can keep that system alive, and keep paying CAs for the 'extra assurance' we need for things like online banking, and offline encrypted connections. But we can also share our own secrets.

Take the case of the 'pay-for-wifi' connection abroad. You connect to the wifi and try to check your e-mail, and are redirected to a page asking you to put in your credit card details. Well wait just a minute! Is that the real page, or did some hacker put that up? With CAs you would be assured, because you have their chain of trust in your browser. But if you don't want to use CAs, you could input the certificate fingerprint yourself, perhaps if it was printed on the wall next to the access point's SSID and WPA-PSK passphrase.

tl;dr


But I digress. The main thing to take away from this post is how HSTS has dramatically changed our perception of 'secure web'. Instead of demanding that all connections are secure, we accept that on the very first visit, we might be getting a 'real' HSTS response from a website, or there might be an attacker lying in wait.

Of course i'm not as smart as I seem. Somebody else has already thought of all this and created it, and is trying to get the browsers and big internet players to buy in. It's not going so well. But since HSTS is already implemented in extremely popular browsers, they must have already accepted the idea of the no-assured-trust-on-first-visit model of security - for the HTTP protocol, anyway. If they accept that, then they're only a step away from the same security that SSH depends upon.

Considering all this, it seems that there's a disconnect in the reality of browser security. The browser and big-internet-guys already assume their connection might be compromised on the first visit. Yet they won't accept this new model that avoids the need for Certificate Authorities. Once implemented, SPDY adoption might actually skyrocket, because the protocol wouldn't be beholden to paying third-parties and depending on all 650 of them for security. I just hope progress and the pursuit of better security wins out over commercial interests.

Friday, July 13, 2012

How to Scale in the Real World

Every so often i'll see a blog post about "scaling lessons I learned when launching my startup." It's painful to read. Lessons like "use monitoring" and "you can use metrics for your application!" and "sharding is good".

Then they go into the hacks. "Add artificial load to your server so when it breaks, you can remove the extra load, and you have more capacity!" "Take a server offline every once in a while." "Automatically kill anything which has too much memory or CPU or takes too long." "Memcache memcache memcache." "Giving developers root makes their lives easier, and mine too!"

Yes, we were all beginners once. These little nuggets are a window into years ago when I too thought it was a good idea to make untested changes and restart services in the middle of the day, or up the limit on max connections until the server fell over, then scrambling to add another server. We learn from our mistakes.

The thing is, no book or blog post you read about scaling will work for everyone. Everyone experiences it differently because both the technology and what you're using it for is different. So you need to be flexible while relying on a little bit of old folks' wisdom. And yes, I just called myself 'old folks' at 28. Jesus i'm arrogant.

Anyway. Here's how I think of scaling in the real world. Keep in mind i'm only talking about "scaling" and not "keeping a fully-redundant high-performance site operating at peak optimization", because that's five different things and way more complex than a single blog post.

Step 1. BE AFRAID


A good mindset of fear and paranoia will help you plan and execute everything you do to scale your site. You should be aware of everything you do and what it's consequences could be. Fear of the site going down, fear of what happens when I push this commit out, fear of bottlenecking i/o, fear of accidental ddos'ing, fear of getting hacked.

Fear is a great motivator. You should also keep in mind it's just a job and calm the hell down, but in general being wary of things breaking or degrading should be high in your mind when you do anything. It will help you plan and execute your plan in ways that will minimize risk and maximize the value of changes.

Step 2. HAVE A GOAL


So your startup is going to revolutionize the way people take a bath by making a social network for rubber ducky owners. Great idea, but that's not the goal i'm talking about. Your goals towards scaling should have specific things you want to accomplish, such as a number of users on your site at the same time, or the average speed of anyone browsing any part of the site. You will execute your goals by building out your site to meet exactly these criteria.

Now you might be saying, but I want to scale infinitely! Can't you just tell me how to configure Redis so i'll never run out of capacity? The answer is of course, No. All scaling has upper limits. The point is to figure out how far you can go ahead of time, so that when you're getting nearer to the limit, you know to make a new goal and plan for that.

Imagine eBay. At some point they probably had a generic way to scale for a while, so they could keep adding servers and bandwidth and keep up with demand. But at some point, you outgrow datacenters. You outgrow coasts and continents. Will your little auction site keep churning away when it's stretched out across the globe, still using a static map file in Apache that needs to be reloaded every time you add an application server? The goals have to be re-imagined at some point. Figuring yours out will make it easier to focus on the 'now' while keeping an eye on the future.

Step 3. PLAN


A scaling plan is basically your architecture manifesto. Keep in mind, it's based on your goals, which should change as you grow, so don't be stuck on one kind of technology or way of doing something. Whatever it is you're doing, there's a different, probably better way to do it, so don't get too caught up with the details. To begin, take your goal and look at every single layer from the client to your app's guts and back.

Let's take a goal which says "I want to maintain 30,000 hits per second of traffic." Starting with the browser client, where is your traffic going? Probably to a web server. If it's going straight to your web servers, you're going to need to sustain over 30K connections, which is a problem for just one web server. If you were going to a CDN that would be much easier to deal with, and you can probably get by with one frontend caching proxy server like Varnish (though that's not redundant at all, your goal didn't include redundancy...). It will have to be a really beefy box to keep a good and fast cache, though. You'll probably also want to enforce cache headers to the CDN to make sure it's not pulling your whole site from the origin every 2 seconds.

So you have 30K HPS to static content. Wonderful! Oh what's that? You wanted to display a social graph of your rubber ducky empire to every user? Shit. I guess we need more stuff. MySQL for a database (because it's easy and universal), Starman for an application server (because fuck you Perl is more than good enough), Memcached for your "fast" application cache, and one of those Map/Reduce thingies for making your social graph (i'm not a real developer, I don't know how that shit works). But how do you configure them? How many do you need? What happens if you outgrow something? Calm down. And keep in mind it doesn't really matter what you pick, you'll figure out how to scale it soon enough.

First write your application for the stack you picked. It doesn't matter what your application is or how shitty it runs as that has nothing to do with scaling. Scaling happens once the piece of crap code is done. This is how scrappy start-ups can afford to write terrible on-the-fly hacks and still survive launch week. So now that your app is running, you need to gather benchmarks.

To gather benchmarks we need metrics. To get metrics you either write something yourself or grab something that's actually good, like collectd. Configure it to gather everything under the sun and send it somewhere not on the box it's collecting on. Then populate your system with fake data and start hammering all the parts of the site. This is useful later as you can keep testing functionality and capacity as your site grows.

As you test your site, see how much of the resources are used up by the meager benchmark you've made. Now compare that to your goal and add about 20% to that number, and you know how much resources you'll need to hit your goal. Now just allocate enough capacity to get there. Keep in mind disk i/o, bandwidth, cpu, database queries, connection pool numbers, cache hit percentage, etc etc.

These numbers are not just basic information you need for capacity planning, it's critical in monitoring your live site to see when you unexpectedly hit a bottleneck. All of these criteria should have monitoring alerts trigger if they get anywhere near 80%, or double in a less-than-manageable amount of time. (Can you double your database capacity in an hour? No? Then you should probably get alerts if any of your database metrics go up by 50% in a half-hour.)

Now that you know the basic resources you'll need to achieve your goals, tune your stack. This is where "premature optimization" is actually a great thing. For example, your resource numbers for MySQL probably look ridiculous - 50 servers just to handle 30k HPS? Apparently people forget that MySQL (like most tools) needs to be tuned to reach its peak performance. Once you tune your stack you can go back to your benchmarking tools and fine-tune the performance to get the numbers more efficient.

But let's be honest: the goal is not to get the fastest performing stack, it's to get a stack that can perform. You might start to rethink your application when you find out it's just not performing very well. In general it's a mistake to redesign your app just because it looks like scaling is taking a lot more resources than it should. As a famous customer support representative once said, "The future is gonna cost more money," and your application will get slower over time. Focus on scaling and let someone else optimize the application.

With realistic numbers about how your site can perform, you can start allocating resources.Your goal was 30K HPS, but you only get 100 hits per second right now. If you have no historical data to plot the growth of traffic, just shoot for 10 times the traffic you're doing now and allocate resources for that. Before you have a launch day or big advertising push or something, check your historical data and do another 10x increase beforehand. If you're not using the cloud, make sure your provider can allocate resources at the drop of a hat for you, or that you have spares to use. If you're using the cloud, make sure you have all the steps down-pat for adding your resources in real time, so if you suddenly get a million users signing up to your site you know how to throw more resources in place.

The "we just got 10,000,000 signups!" scenario is extremely rare. But for cases of unexpected, goal-smashing growth, you need to have an emergency plan as well. You can find examples of them around the web. Typically it's a combination of handicaps to your site to keep some core functionality running. The last thing you want is for everything to go down. It's better to cap the number of incoming connections and allow a slow stream of users to use the site while you rush to obtain more resources to grow the site in time. Anything can become a bottleneck - network traffic, disk i/o, memory ceiling, database connections/queries, etc. Be aware of the maximum level for each criteria by comparing the resource use from your metrics with the configuration of each software component.

The last thing you want, which you'll add probably as you realize you don't have the money or capacity to just keep adding resources, is caching. In short: Cache Everything. Cache on your frontends. Cache on your backends. Cache to disk. Cache in memory. Cache the highest-used pages. Use a bigger journal to cache in the filesystem. If you desperately need iops, using tmpfs and writing changes occasionally with rsync is a form of caching. You can send users to the same servers to maximize cache hits at the cost of high-resource hot spots, or send them random places for better spread-out load at the loss of cache hits and increase in global resource use. Figure out what works best for your application.


Step 4. EXECUTION


So you have your goal, you have your plan, now you need to put it into practice. Scaling is one of those things where you don't need it until you need it. So being prepared to execute your plan at a moment's notice is pretty important. Usually it involves fire drills where your site goes down or you lose capacity and you need to add more quickly. But the management of your site is important as well.

Are your changes automatic? Do you have good revision control and deployment, and can you revert your changes immediately? Is your application's use of your infrastructure abstract enough that you can change backend pieces without ever touching your code? Can you roll out new services at the push of a button? Have you been testing your changes?

It seems obvious, but many times the problem with rapid scaling is simply a lack of best practices. All those little things you ignore because you're a startup and you don't have time to implement configuration management because of your 'just ship it' mentality? Once you've shipped it, and you suddenly need to scale, you get bit in the ass by the eventuality of your apathy to best practices.

Scaling is a never-ending process of analyzing data, testing limits, and growing your infrastructure. There's no easy way to do it, but at the same time, pretty much anyone can do it. The reason scrappy kids right out of school that jump on the startup bandwagon can keep tiny sites operating at huge numbers is because the actual work of adding resources is trivial. You figure out what you're lacking and you add more of it. The key is being constantly aware of what is going on and keeping one step ahead.

Thursday, March 29, 2012

Gender disparity in tech: Free classes bucking the trend?

I recently facilitated a class on Object Oriented Programming with Java. I helped coordinate with the teacher and students to get everyone together at the right time and place for the class, and pass messages to/from the teacher. The class was free and community-organized so there was no traditional academic structure. Anyone who wanted could come.

Half way through the class I noticed something interesting.

At least 75% of the class was made up by women. When asked, most of the students (both male and female) had practically zero programming experience and mostly worked in web development or graphic design.

I was trying to figure out why such a class would bring so many women when all I usually hear is how women are under-represented in tech fields. Then I remembered how most of the classes put together by this organization have a significant female attendance, on average. Almost all of the advertising for these classes is word of mouth, and since many of the organizers are female it makes sense that their social networks would comprise at least partially of women or women-centric user groups.

Now i'm thinking more about the dynamic that males have with each other and how that relates to them getting into the tech field. Would they be less likely to jump into classes if they knew they'd be the only woman in the class? Some might say no, but i've been in classes with all women and it can be a little intimidating for me, a guy. If the entire tech field was dominated by women, would there be a stigma against men getting into tech, because it might mean men are being "girly"?

Of course this was just one class so it's impossible to take anything solid away from something like how many people attended. But my guess is if there were women teaching classes to women, there might be a bigger turn out than is expected in more typical academic settings.

Tuesday, February 28, 2012

hacking

Hacking is not programming.
Hacking is not learning.
Hacking is not making.
Hacking is not sharing.
Hacking is not networking.
Hacking is not something you do.

Hacking is how you do something.

Saturday, February 11, 2012

Captive Portal Security part 1

CAPTIVE PORTAL SECURITY, pt. 1

by Peter Willis


INTRODUCTION

This brief paper will focus on the security policies of networks which require payment or web-based authentication before authorization. The topics of discussion will range from common set-up of captive portals, the methods available to circumvent authorization and ways to prevent attacks. A future paper will go over the captive portals themselves, their design and attack considerations.

TABLE OF CONTENTS

I. CAPTIVE PORTAL OVERVIEW
II. ATTACK METHODOLOGY
III. DEFENSE TACTICS
IV. SUMMARY
V. REFERENCES


I. CAPTIVE PORTAL OVERVIEW

What is a captive portal? A captive portal (or CP) is a generic term for any network which presents an interface, usually via a website, to authorize a user to access a network or the internet. Typically these will be in the fashion of a website where one accepts an agreement not to tamper with the network. It can also cover college campus log-in screens, corporate guest account access, for-pay wifi hotspots, etc.

In this paper I will mostly be discussing the "wifi hotspot" form of CP, where either after payment, user authorization or clicking on an "Accept" button will get you access to the internet. Many attacks to circumvent these networks rely on remote dedicated servers and thus won't be suitable to bypass all forms of CPs (as some networks are intended to grant access to internal-only networks).


II. ATTACK METHODOLOGY

There are many different attacks one can perform to circumvent a CP, ranging from the simplistic to complex. Each has its benefits and weaknesses, relating to performance, reliability and possibility of detection by IDS. I will briefly outline the methods here with more examples/detail given during the paper.


1. Tunnel over DNS

This method involves tunneling network and transport-level packets encoded over DNS records. The reason this attack works is due to the design of the DNS system. A domain or sub-domain can delegate where the answers for their DNS records come from using an NS record. The NS record points to your 3rd-party server. The useful part for bypassing CPs comes in here because most caching nameservers (like those on a CP) must forward on requests to your server if they want to be answered properly, which means we can use the CP as a sort of DNS proxy. Set up a custom nameserver that can pack and unpack packets and a client to transmit them and you have yourself a two-way connection with a server on the internet. Make an SSH connection through it and you have a secure tunnel.

One tool used to exploit this property of DNS is iodine[1]. This tool has enhanced security and methods to auto-detect the type of network it passes through and get the best connection possible. Unfortunately it doesn't work as well in the real world as it does on paper.

The original implementation, OzymanDNS by Daniel Kaminsky, is (once modified) actually the most reliably working solution, even if it works as a presentation layer instead of tunneling raw IP packets. This actually gives a couple benefits in that it can be run by an unpriviledged user (on the client side) and is modular/easy to hack on (written in perl). I have modified a version of this code[2] to optimize it and reduce CPU use, but it's not pretty: an average of about 7 kilobits per second is what you'll see. But if you really need brief access it works just about anywhere.


2. Tunnel over ICMP

Surprisingly difficult to exploit in the real world, this protocol offers an alternative tunnel through a firewall for those that don't block it. Networks use ICMP for all kinds of things, most notably passing errors and routing information when necessary as well as the ubiquitous 'ping' messages. If you can't ping there may still be alternative methods to tunnel data through this protocol, but in general the ping is the simplest.

The attack works like this: send an ICMP message (which being layer 3 is not always restricted the way IP sub-protocols are) with an IP or other packet encoded in its payload similar to tunneling over DNS. The benfit of this method is (when it works) it can provide a highly reliable connection without excessive lag (around 24 kilobits per second bandwidth on average). The tool icmptx[3] works well.

A bigger problem looms with IPv6 though, as there is a newer ICMP (icmpv6) which imposes restrictions on the number of icmp packets per second - around 6 per second. This seriously hampers the performance of any application trying to tunnel data through the protocol, but luckily nobody uses IPv6 yet. In general most CPs seem to block ICMP packets.


3. Firewall pinholes

Seldom probed by anyone but the most desperate CP hackers, most firewalls do allow one or more tcp or udp ports outbound to remote hosts (usually on the internet). These will allow you to tunnel an arbitrary protocol as long as it works over the transport protocol of the pinhole.

My favorite of these is tunneling OpenVPN tunnels over udp port 53 - the DNS port. Some CPs allow port 53 outbound to any host on the internet without checking to see if it's passing DNS requests, which is a big mistake. Unfortunately some CPs intercept and rewrite any traffic going over port 53 to provide their own custom DNS responses which breaks this method.

Sometimes strange high-numbered ports are open to the remote host. The simple way to tell this is to run a tcpdump or custom application on the remote host and scan every port from the CP's network to identify the one that's open. With an automated script this can be accomplished easily and once a hole is found the tunnel will provide full bandwidth to the attacker. For attacking CPs that allow access to internal networks you may be able to craft specific packets which when successfully passed through present a different response, thus enumerating open ports.


4. Transparent proxies

Often times the best holes come from an incorrectly set-up network proxy. Often the ACLs on HTTP proxies are set up only enough to block basic requests and don't handle the whole spectrum of possible HTTP requests. Sometimes you can use the proxy as simply as configuring the CP's gateway IP in your browser's proxy settings. However, sometimes a 3rd party server will help us with the extra mile of getting through their ACLs.

The simplest attack in this case is simply looking for an open proxy on some host on the network. Nmap[4] is bundled with scripts which will quickly detect open proxies. Sometimes one needs to abuse the HTTP specifications to find a hole in a particular implementation of an HTTP proxy. Some ACLs can be bypassed by merely changing CRLF to LF in your request or using a different HTTP method. Some authentication/authorization software even have rules in place to allow you to bypass authorization by adding a "?.jpg", "?.css", "?.xml" or other extention to your request. Sometimes header injection can be used to provide a quick jump through a backend proxy.

However, this may only give you HTTP or HTTPS access through the CP. To pass arbitrary data through the proxy it must allow you to use the CONNECT method to reach a remote host. Usually this is allowed because the SSL port (tcp port 443) needs to transmit encrypted packets which are only passed through a proxy with the CONNECT method. If a CONNECT is supported we can take advantage of a 3rd-party server on the internet to tunnel arbitrary packets over HTTP.

An HTTP proxy is set up on the internet which passes connections on to an internal SSH server on port 22. A client then uses proxytunnel[5] to connect to the CP's gateway and from there issues a CONNECT to the 3rd-party proxy, usually on port 443 (but port 80 is a good alternative to have set up). The final request is made to CONNECT to that machine's ssh port. If all goes well you should be able to use this new connection with your SSH client and forward arbitrary data over it. All the CP sees is HTTP or HTTPS traffic being forwarded from one proxy to another. The end result is a high-bandwidth tunnel through the proxy.

A tool[6] included with this paper will allow you to quickly probe ports found on a CP gateway for common problems in HTTP implementations and look for a way out.


5. MAC spoofing

The last method is the only one which is present in all wireless and some wired CPs by design. Once a host is authorized by the CP, its mac and IP address are allowed unrestricted access. All one needs to do is sniff traffic on the network, find a host that is authorized, and spoof its IP and mac address. Spoofing a mac is dependent on your network card and driver but most modern network devices today support it. The downside of course is you have to observe someone already authenticated, but in places such as a crowded airport lobby this may be less difficult than it seems.


6. Miscellaneous

Of course there are many more methods to circumvent CP access with varying degrees of success. Other methods include use of fuzzers, creative source routing/probing, the abuse of cisco protocols for proxy clustering, and the abuse of "convenience" features of some authentication servers.


III. DEFENSE TACTICS


I can't tell you how to perform these attacks without at least trying to tell you how to fix your own broken networks, so here's the white-hat portion of the paper.

First of all, block all unauthenticated traffic (of any layer) destined for the internet. There's no reason for any client to be able to pass any packets without being authed, so just put that rule at the top of your firewall. That'll stop firewall pinhole attacks and IP over ICMP.

To stop IP over DNS, simply have all DNS requests from unauthed sources return the same record every time... The IP of your CP gateway. Not only will this work fine with your transparent HTTP proxy (your proxy should be sending a redirect to your gateway's website anyway for authentication purposes), you can also run many service-specific proxies that will handle requests and inform the client to auth first via http. SSL won't work, but screw them for trying to be secure.

To stop HTTP transparent proxy abuse, pick a very secure and well-established proxy server that's stable and has all security patches and bug fixes up to date. Make sure you craft your ACLs to explicitly stop ALL requests coming from an unauthed host. It should only return the redirect to your authentication website. If for example the server differentiates between requests which are terminated by LF or CRLF, you should probaly write a lot more rules than less and cover all the possibilities.

For other methods of abuse, make sure your CP solution has no unneeded services or ports available on the network. These can be easy targets for attack (who here has checked if snmp is enabled on their gateway? ssh?) and the less attack vectors the less likely an attacker will get through. Audit all your systems to ensure they don't accidentally allow more access than is necessary.


IV. SUMMARY


Almost all CPs today can be bypassed in one way or another. Clearly there's a certain amount of risk vs reward where a company just doesn't care if the top 1% of users can gain access without authorization. That's good for us hackers, but can be bad for the CP provider.

Did you know that since its inception, Starbucks and McDonald's for-pay wifi had open squid proxies on every default gateway? All you needed to do was run an nmap scan to find it, set it in your browser's proxy list and surf for free. (Oh, and the payment network McDonald's uses to process credit cards uses the same network) Did you know there's a major mobile voice and data service provider which has not one but THREE holes in its service, allowing anyone to use their service for free anywhere in the USA with 3G coverage?

Even if Bradley Manning was not able to get a CDROM of US embassy cables out of a secured facility, he might have been able to find a way though network firewalls using these same techniques and tunnel the data out. It's not that far-fetched: as corporations increasingly lock the internet away from their employees, industrious hackers find new more challenging methods to circumvent their restrictions and get the access they want. With this in mind, those implementing the controls should be wary of the many methods of attack involved and the potential for abuse.

This paper has not covered the possibility of attacking the web applications which authenticate users trying to gain access to the network. I am not a web application pen tester so i'll let someone else review those holes.


V. REFERENCES

1. iodine - http://code.kryo.se/iodine/

2. dnstunnel - http://psydev.syw4e.info/new/dnstunnel/

3. icmptx - http://thomer.com/icmptx/

4. nmap - http://nmap.org/

5. proxytunnel - http://proxytunnel.sourceforge.net/

6. quickprobeportal.pl - http://psydev.syw4e.info/new/misc/quickprobeportal.pl

Thursday, January 12, 2012

Hackerne.ws DNS temporarily broken

If you're going to update DNS, use a tool that sanity checks your configuration as well as running your zones in a sandbox before deploying them. Otherwise this happens and your site goes down:

willisp@darkstar ~/ $ dig hackerne.ws

; <<>> DiG 9.4-ESV-R4 <<>> hackerne.ws
;; global options: printcmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 43879
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;hackerne.ws. IN A

;; ANSWER SECTION:
hackerne.ws. 16 IN CNAME 174.132.225.106.

;; Query time: 80 msec
;; SERVER: 150.123.71.14#53(150.123.71.14)
;; WHEN: Thu Jan 12 09:57:05 2012
;; MSG SIZE rcvd: 58

They soon fixed the problem so i'm not trying to give them too hard a time, but it's a good lesson in why even modest sites should do quality control for all production-touching changes. Unless you're really familiar with DNS the above mistake might get overlooked quickly while troubleshooting.

Wednesday, December 28, 2011

thought for making development-to-production code pushes less prone to bit rot

you know that familiar problem where your development environment isn't in sync with the production servers? you upgrade the software so you can test new features, you push to production, and HOLY SHIT the site breaks because you weren't developing on the same platform. that is, if you aren't already doing the fucking upgrade polka just trying to get the newer software shoehorned into the old-ass legacy PROD machine. here's a potential fix.

you keep your codebase locked to your system configuration. if a dev server's software changes (or really, if anything on the system changes), you take a snapshot and you force the code to be tagged or whatever to the new snapshot. in this way the code is always in line with any given system configuration so you know what code works with what system configuration.

also, you always keep a system that matches your production machine. your HEAD development tree may be a wild jungle but only code you commit to the branch that is the same as the production machine can be tested, and only the development machine with the exact same system configuration as the production machine can test the code. so you will have your HEAD dev system and your PROD dev system, and the PROD dev system will mirror the PROD machine, not the other way around. you can call this "QC"/"QA" if you want but dev systems usually have local edits and don't do normal deployments and other bullshit bit rot creep.

so on the HEAD machine developers can test whatever the fuck they want, but until it works on the PROD dev machine it can't be deployed to PROD. this will also force you to actually do unit testing and other fun shit to prove the PROD dev code works as expected before you can deploy it. yay!

Wednesday, December 21, 2011

FUCK ANDROID

AAARRRGHHH.

I need to make a phone call to a local business right now. I can't, because every time I dial the number and press 'Dial' the "3G Data" option window pops up. It simply will not dial the number. I have put up with your shit, Android, and i'm done with it.

This isn't the first problem you've had. Your apps seem to crash daily, or one app sucks up "35% CPU" and makes every other app lag like my grandmother in molasses. Stock apps like the Browser and Maps can bring the whole thing to it's knees. And in these weird states, on the few times I actually receive a phone call, I can't swipe to answer it because the UI is too lagged. Let's not even talk about the native text messaging, which is not only the laggiest SMS i've ever used but the first phone to actually fail to send SMS's on a regular basis.

Google's apps in particular seem to suck. Google Voice takes about 30 seconds just to refresh the text messages once I open the app. Maps has weird bugs so that if I lock the screen while viewing the map, the map freezes and I have to kill it and restart it. Randomly the whole device will just appear sluggish even if I haven't been using it. And some apps become impossible to uninstall, becoming nag-ware for registration or payment.

A PHONE SHOULD BE A PHONE. All I wanted was to have GPS, Maps and Browsing built into my phone, and maybe a nice camera (but years later apparently Sony is the only company capable of putting a decent camera in a phone). But that was too much for you, Android. You had to be fancy. And now i'm throwing you away.

Nobody should be making Web Apps

let's face it. you're doing it wrong. it's not your fault; the rest of the world told you it was okay to try to emulate every aspect of a normal native application, but in a web browser. don't fret, because i'm about to explain why everything you do is wrong and how you can fix it. but first let me ask you a question.

what do you want to accomplish?

A. producing a markup-driven portable readable user agent-independent interpreted document to present information to a user?

B. letting a user interact with a custom application with which you provide services and solutions for some problem they have for which they don't have a tool to solve it?




if it's A you chose the correct platform. a web browser is designed to retrieve, present and traverse information through a vast network of resources. it has the flexibility, speed and low cost of resources to let you pull tons of content quickly and easily. after all, we all have at least a gigabyte of RAM. you should be able to browse hundreds of pages and never max out that amount of RAM - right?

if it's B this is the wrong choice, and for a simple reason: a browser is not an application platform. it was never designed to provide for you all the tools you need to support the myriad of applications' needs. imagine all the components of an operating system and what it provides to allow simple applications to do simple things. now consider a web browser and what it provides. starting to get the picture? here's a simple comparison: an operating system is a fortune 500 company and a web browser is a guy with a lemonade stand. no matter how many 'features' he can sell you, the super low-calorie healthy organic sweetener, the water sourced from natural local clean purified streams, whatever: it's still lemonade.




technical reasons why web apps are dumb:
  1. in a very literal sense the browser is becoming Frankenstein. slow, kludgy, gigantic, unstable, a security risk.
  2. verifying if my credit card number was typed in correctly is fine, but javascript should never run actual applications or libraries.
  3. applications that can interact with the local machine natively can do a wide array of things limited only by your own security policies and the extent of your hardware and installed libraries (which can be bundled with apps). web apps have to have the right browser installed, the right version, and compete with whatever other crap is slowly churning away, restricted by hacked-on browser security policies designed to keep your browser from hurting you.
  4. web applications are not only sensitive to the user's browser & network connection, they require your server backend to provide most of the computation resources. now not only can a user not rely on the application as much, you have to put up the cost of their cpu & network time, which is much more difficult than it is expensive when you really start getting users.
  5. the user doesn't really give a shit how their magical box provides them what they want. they just want it immediately and forever and free. so you're not really tied to using the web as long as you can provide them the same experience or better.
  6. seriously - Web Sockets?! are you people fucking insane? why not a Web Virtual Memory Manager or Web Filesystems? or how about WebDirectX? ..... oh. nevermind. *headdesk* i can't wait for Real-Time Web Pages.




i know what you're saying: what the hell else am i supposed to do? make native apps? i would compare the smartphone mobile app market to the desktop app market but the truth is it's ridiculously easier to bring in customers for mobile apps. and yes it's probably ten times easier building web apps with all the fancy friendly frameworks that can be tied together to push out new complete tools in hours instead of days or weeks. but that's also no excuse because it's all just code; we could build easy frameworks for native or mobile apps too. what is the alternative? is there one?

i don't think there is. Yet. you see, where the web browser fails us we have an opportunity to create a new kind of application. something that's dynamic and ubiquitous yet conforms to standards. something easy to deploy, cross-platform and portable. something using tools and libraries implemented in fast native code. something with an intuitive interface that exposes a universal "store front" to download or buy applications to suit our needs. something local AND scalable. sounds like a pipe dream.

maybe we can't have everything. but i see pieces of this idea in different places. when i look at Steam i see most of what's necessary for a store for applications, a content delivery system, a (mostly) secure user authentication mechanism. if it were possible to take the simplicity of Python (but you know, without the annoying parts) and make it reeeeallly cross-platform by design, then produce simple frameworks to speed up building of new complete tools.




the last thing you'd need is a way to make it sexy enough for everyone to pick up and start using. there's the difficult part. it seems to me that the competition of a few major players and the evolution of standards for new web technology is what led the arms race to bring "web apps" as the most ubiquitous computing platform for user interaction (next to mobile apps). that and the trendy, almost generation-specific explosion of investment of time in javascript-based frameworks led everyone to just build web apps by default. the new solution has to be needed for something for anyone to pick it up. you could start it as a browser pet project, but it seems uncertain whether other browsers would pick up the technology or wait it out.

this is where my sleep deprivation and the hour's worth of work i need to put in makes me ramble more than usual. my main point here is: make it easy, make it convenient, and make it somehow better than what we've had before. the end goal is of course, to stop creating bloated-ass crazy insecure web browsers that threaten our financial and personal lives and instead make stable, powerful applications which don't need a specific kind of browser or class of machine to run (necessarily).

bottom line: browsers aren't an operating system and the world wide web is not the internet. the former merely is part of the latter.




(disclaimer: i don't write web apps)

Wednesday, November 2, 2011

what nobody using Linux gets about usability

nobody cares what makes your operating system work. they don't want to perform steps, or look up guides, or learn how to do something. everything they want to do should be completely intuitive.

in Linux, it is never intuitive.

programs are usually some weird alternative program with a strange name that isn't intuitive at all. Linux and Mac have cross-platform applications which everyone just knows about. Linux doesn't, in general. i mean sure there's apps, but nobody in Windows or Mac uses open source programs. think about that for a minute.

you always need to know what kind of 'package' to download, and some weird method of installing it, and possibly 'dependencies'. nobody in Windows knows what the fuck a dependency is, or why they'd ever come into contact with one.

nobody in Windows ever uses a console. "What is this, DOS?" it's fucking retarded. the mere idea that a shell even *exists* on a Linux computer is kind of ridiculous. the idea that command-line programs are so robust and friendly to a command-line user, just serves as a crutch for the techies who have no easy way to do the same thing from the GUI.

the motto of Linux development should be: No More Console.

the second motto of Linux should be: No More Knowledge.

a complete idiot should be able to use a computer with no more than 2 minutes of playing around. it should also be the least scary as possible for them. usually Linux GUIs are incredibly complex and scary for users. they also usually look incredibly toy-like and cheap, but that's not really a usability thing.

Linux should work like the iPad.

think about that.

Tuesday, October 25, 2011

Getting wifi to work on an Asus Eee PC 1015PEM

This asus has a Broadcom BCM4313 wifi card. The linux kernel that ships with Slackware 13.37 comes with an open-source driver for this wifi card. Unfortunately, it does not come with the firmware for the card, so the driver is useless. If you try to download and install the driver from Broadcom it crashes the machine (even if you blacklist every other module).

The solution is to download and install the firmware according to the driver's README (which you can find at /usr/src/linux-2.6.37.6/drivers/staging/brcm80211/README). Once the drivers are copied to /lib/firmware/brcm/ you need to make symlinks "bcm43xx-0.fw" and "bcm43xx_hdr-0.fw" to the files which look closest like those.

Of course the git repository that has the files is not working, so you have to pull them from somewhere else. You can get the archive from debian here: http://packages.debian.org/sid/firmware-brcm80211 (download the source package's .tar.gz file and extract it)

Once you set up the firmware, just reboot and the machine should attempt to load the brcm80211 module and the right firmware automatically. Don't use the "wl" driver from broadcom as it will crash the machine. Add "wl", "b43" and "ssb" to the /etc/modprobe.d/blacklist.conf file just in case it tries to load those.

UPDATE

Apparently, that stuff doesn't work the way it should. You have to upgrade to the latest 2.6 kernel (2.6.39.4 as of this writing) and load the 'brcmsmac' driver, as this is the new driver used by the BCM4313 on the latest 2.6 kernels. Blacklist all the other drivers first ('wl', 'brcm80211', 'b43', 'ssb', 'b43-legacy', 'bcma'). I'm not sure if this is because the latest firmware is incompatible with older driver versions, but it kept crashing my machine to do anything but use the latest kernel and the brcmsmac driver with the latest firmware. What a pain in the ass.

Monday, October 24, 2011

pNFS is in Linux 3.x!

I totally missed it, but pNFS is officially in Linux 3.0 and beyond. If you need simple, stable, parallel network filesystem that is included with vanilla Linux kernels, now you have it. Any NFS 4.1 compatible client should be able to use servers set up with pNFS.

Here's the docs I found so far on it:

http://wiki.linux-nfs.org/wiki/index.php/PNFS_Setup_Instructions
http://wiki.linux-nfs.org/wiki/index.php/Configuring_pNFS/spnfsd
http://wiki.linux-nfs.org/wiki/index.php/PNFS_Block_Server_Setup_Instructions
http://wiki.linux-nfs.org/wiki/index.php/Fedora_pNFS_Client_Setup

Thursday, October 20, 2011

most new startup companies are stupid

Let me go down the list of some kinds of startup companies from Start-Up 100 and why they're stupid.

Advertising and Marketing
Right off the bat, a bunch of useless bullshit. I don't ever WANT to see an advertisement or marketing. I want to be able to find that shit if i'm looking for it, but I don't want any of it to just show up somewhere.

Audio and Media
More stupid "web 2.0" websites based around music and other crap. Internet radio has existed for well over a decade. I don't need another place to not find the music I want to hear. (Pandora sucks, Spotify sucks, Grooveshark sucks... it all sucks. I'll turn on Shoutcast or Last.FM Radio if I want random music that I kind of like)

Education, Recruitment and Jobs
First of all, if you didn't get a normal education, some web 2.0 shell of a company probably isn't going to educate you any better. We have Dice and Monster, and people who are competent at what they do will network and find jobs in person like normal.

Enterprise: Security, Storage, Collaboration, Databases
Finally, startups intended for technology. Too bad all of them suck. Most people i've seen who try to develop startups have not worked very long in tech so they design or implement poorly and if they survive it's from sheer luck. Most of these solutions are crap or unnecessary.

Finance, Payments and Ecommerce
Again, i'm pretty sure all the big contenders have already been created. It'd be interesting if they actually had a new way to deal with finance or ecommerce, but most of it's been done and there's not a lot of room for innovation.

Gaming, Virtual Worlds
Ok, here's something that actually has promise. Make a stupid game which is addicting and make a billion dollars like Rovio.

Social Networking and Collaboration
JUST. LET. IT. DIE.
Social networking is a fad. You know what the original social network was? AOL. Just let the shit die. God I hate social networks.

Travel and Transport
I guess there's still a few niche/boutique businesses you could start in this space. But if it's another "how to look up cheap flights" website, just kill yourself.


What I would like to see more of are startups that are intended on bettering mankind, or fixing a common problem, or pioneering a new technology (a *real* new technology, not just a new shitty website or NoSQL garbage tool nobody wants). Medical device startups are really cool. Startups that develop technology for the 3rd world are cool. I'm still waiting on somebody to build a company that just services new companies, giving them turn-key solutions to build new networks and support them. I'll go work for them.

Saturday, October 8, 2011

note to self for change management system

if a hack like extra privs is applied to a system to allow a dev to fix some issue in production or something, should be a system in place to automatically revoke privs after a given time. or specify a date/time range that the privs should be added, so you can specify "during maintenance window sunday 5am-9am developer Steve gets weblogic sudo access". as a matter of principle, all changes should be allowed to have date ranges applied to control when the changes happen. if the date/time starts but has no end, assume end time is indefinite. if start time and end time are the same, change is only applied once.

all account access should have defined end dates (for example, contractor steve has a 6 month contract, so all his access should have an expiry time set). BEFORE access is revoked email alerts will be generated for 2 weeks out, 1 week out, 3 days out, 1 day out before access expires to alert somebody before his access goes out the window. most configuration should not have expiry times because it's assumed if it is in config management it's meant to be there indefinitely, but for quick hacks where we know we don't want it to be there long we can set expiry times and will get alerts before it expires.

Monday, September 26, 2011

dumb network policies and systems practices

"jump server". just the term itself conjures up an image of "getting around" security or the network. it's a HACK. unless there's a big problem with your network, you should be able to allow access directly to the server you need to get to. connecting to one host just to connect to another host is retarded.

the only thing that is a potential benefit is that you're essentially forcing any network communication through one protocol (which can subsequently be circumvented on the jump server, depending) and (again, depending on the jump server) authenticating twice.

the bad things? it's incredibly, incredibly slow to transfer files. functionality with different protocols becomes broken. and you're circumventing the firewalls and network security. once you tunnel to the jump box it becomes much more difficult to determine who is connecting to where (after the jump box). and attacks on the internal network get much more interesting, not to mention if you escalate privs on the jump box you can piggyback any connection any other user is making from the jump box. not to mention you're forcing a new layer of complication onto your users so doing their job becomes more of a hassle - which almost by definition inspires people to break good convention for the sake of convenience. not to mention it's a waste of resources.



systems guys, don't jerk your users around. if there's a way you can get something done quicker, do it. for example: resizing logical partitions in a VM guest.

if your user wants 10GB more added to their work partition, get a procedure in place so you can do it live. rebooting the server should not be necessary for most admin tasks on a unix host.

don't believe me? read this blog post explaining how to extend an LVM volume while the box is still up. hey, now i don't have to wait a day to keep doing my work on a server which was allocated way fewer resources than it should have had!

Monday, September 19, 2011

secure kickstarting of new linux servers

PXE is not secure. Not only does it rely on broadcast requests for a PXE server, it uses UDP and TFTP to serve files, thus removing any remaining security features. It also can't be used on WANs and typically requires admin infrastructure and VLANs set up wherever the boxes will be installed, so lots of admin overhead is required.

To get around these problems and provide a secure mechanism for remote install you should use a pre-built linux image on CD-ROM or floppy disk. Most servers today come with one or the other, and both provide enough space to include a kernel and tiny compressed initrd with barebones networking tools.

The kernel should obviously be the newest vanilla kernel possible, patched to include any relevant hardware support. The more vanilla the better as you can quickly pick up the newest released kernel and build it without needing to modify vendor-specific patches.

The initrd should probably be based on an LZMA-compressed mini filesystem or cpio archive. Usually something custom like squashfs works the best. You'll need to build busybox and the dropbear ssh client in a uClibc buildroot environment to make it as small as possible. Bundle an ssh key for the admin server along with DNS and IP information for the server (in case DNS resolution fails, it can try the last known good IP address(es)). It should try indefinitely to get an IP address, and once it gets one it should make an SSH connection. Once SSH connection is established it should download install scripts and execute them. All downloads happen through the secure SSH tunnel.

The initrd should also include proxytunnel and potentially openvpn or another UDP-based SSL tunnel so it can fall back to trying to connect through HTTP or udp port 53. You may need cntlm to work with NTLM proxies as proxytunnel's support does not seem to work for all versions of NTLM. Also, rsync should probably be included, or downloaded immediately once a network connection is established. Big apps can always be downloaded to a tmpfs partition later once the SSH connection is established. The initrd should also use a bootloader that can pass custom arguments to the initrd at boot time, for example to specify proxy or IP settings. It should probably support Web Proxy Autodiscovery Protocol for corporate environments.

If you have room, you may also want to bundle grub with the initrd. This can help you recover a system if it fails and it will allow you to install grub over whatever's currently on the hard drive. A good grub configuration to install would include options to boot from hard drive, CDROM or floppy, so as long as you have remote console you can reboot the box and select the install image from grub at boot time without needing to change BIOS settings.

Finally, each client image should be modified before burning/imaging to have custom ssh keys. You want each boot image to be able to be revoked from the admin server's login list, in case a boot image/disk is compromised or stolen. Granted, you're not giving this thing any more rights than access to your kickstart file tree, and that shouldn't have anything super confidential on it anyway. To customize the ssh keys per image you can have a script which generates new images, creates keys for each one and renames the image file to something specific to the machine. Match up the specific piece of hardware with this unique image file in your network's inventory database.

The kickstart server should have IP addresses dedicated only for the kickstart clients. An HTTP reverse proxy should be installed for ports 80 and 443 so that the client can use proxytunnel to connect to SSH through HTTP proxies. Optionally an openvpn daemon should be enabled on port 53 in case a client's firewall has an open outbound port 53. Each kickstart server's SSH daemon (listening only on the kickstart IPs) should use the same host keys so they can be copied to the initrd and you won't have to worry about the server host keys changing per box, messing up the initial connection from the clients. You could manage all the kickstart host keys independently but why complicate matters further?

In the end what you have is a client install CD or floppy which can boot up on a network, connect securely to a remote server, configure itself and follow setup instructions given by the remote server. It can even deliver detailed information about the host on boot-up so it can then download instructions specific to the machine type. When the machine boots up for the first time, select the CDROM or floppy and run it; as it boots it can install grub on the hard drive so you never even have to change the BIOS boot order. I recommend having the initrd grub config default to boot from hard disk; you can always manually select the remote install function and it's safer to default to booting from hard disk if the CD or floppy will stay in the machine.

Yes, this is a lot more maintenance than a simple PXE server. This is not intended for use in all environments. But if you need a truly secure, remote-accessible machine kickstarting solution, this one will do the job across all kinds of network types.

P.S. You can substitute ssh for a minimal HTTPS client and a copy of the server's certificate on the initrd so you don't have to rely on CAs. I personally don't trust 3rd party certificate authorities (as more and more evidence shows that states can snoop on SSL traffic without problems).

Tuesday, August 23, 2011

A tip for handling long downtime

So you push out a piece of code and it eats your live database. The site is broken. You need to take it down to repair the database. So you're going to keep your site down for how long? 30 minutes? 6 hours?

If you're trying to "fix" a database and you're keeping your site down until it's done, get a read-only copy of an old snapshot of the database + site code up. Put up a banner on all pages saying the site is under emergency maintenance so parts of the site are temporarily disabled.

This way your users get to continue using at least the read-only parts of the site and not all of your traffic goes out the window. Keep this in mind when developing the site too; not being able to update a hit counter in the database for a specific page should be a soft error, for example.

If you don't have a place to host this temporary database + site code, think about having such a place. Secondary/failover hosts would work at a time like this, or maybe your single host(s) need more capacity.