Sysadmin

We need a security standard for USB and other plug-in devices

Studies have shown that if you leave USB sticks on the ground outside an office building, 60% of them will get picked up and plugged into a computer in the building. If you put the company logo on the sticks, closer to 90% of them will get picked up and plugged in.

USB sticks, as you probably know, can pretend to be CD-ROMs and that means on many Windows systems, the computer will execute an “autorun” binary on the stick, giving it control of your machine. (And many people run as administrator.) While other systems may not do this, almost every system allows a USB stick to pretend to be a keyboard, and as a keyboard it also can easily take full control of your machine, waiting for the machine to be idle so you won’t see it if need be. Plugging malicious sticks into computers is how Stuxnet took over Iranian centrifuges, and yet we all do this.

I wish we could trust unknown USB and bluetooth devices, but we can’t, not when they can be pointing devices and mice and drives we might run code from.

New OS generations have to create a trust framework for plug-in hardware, which includes USB and firewire and to a lesser degree even eSata.

When we plug in any device that might have power over the machine, the system should ask us if we wish to trust it, and how much. By default, we would give minimum trust to drives, and no trust to pointing devices or keyboards and the like. CD-Roms would not get the ability to autorun, though it could be granted by those willing to take this risk, poor a choice as it is.

Once we grant the trust, the devices should be able to store a provided key. After that, the device can then use this key to authenticate itself and regain that trust when plugged in again. Going forward all devices should do this.

The problem is they currently don’t, and people won’t accept obsoleting all their devices. Fortunately devices that look like writable drives can just have a token placed on the drive. This token would change every time, making it hard to clone.

Some devices can be given a unique identifier, or a semi-unique one. For devices that have any form of serial number, this can be remembered and the trust level associated with it. Most devices at least have a lot of identifiers related to the make and model of device. Trusting this would mean that once you trusted a keyboard, any keyboard of the same make and model would also be trusted. This is not super-secure but prevents generic attacks — attacks would have to be directly aimed at you. To avoid a device trying to pretend to be every type of keyboard until one is accepted, the attempted connection of too many devices without a trust confirmation should lock out the port until a confirmation is given.

The protocol for verification should be simple so it can be placed on an inexpensive chip that can be mass produced. In particular, the industry would mass produce small USB pass-through authentication devices that should cost no more than $1. These devices could be stuck on the plugs of old devices to make it possible for them to authenticate. They could look like hubs, or be truly pass-through.

All of this would make USB attacks harder. In the other direction, I believe as I have written before that there is value in creating classes of untrusted or less trusted hardware. For example, an untrusted USB drive might be marked so that executable code can’t be loaded from it, only classes of files and archives that are well understood by the OS. And an untrusted keyboard would only be allowed to type in boxes that say they will accept input from an untrusted keyboard. You could write the text of emails with the untrusted keyboard, but not enter URLs into the URL bar or passwords into password boxes. (Browser forms would have to indicate that an untrusted keyboard could be used.) In all cases, a mini text-editor would be available for use with the untrusted keyboard, from where one could cut and paste using a trusted device into other boxes.

A computer that as yet has no trusted devices of a given class would have to trust the first one plugged in. Ie. if you have a new computer that’s never had a keyboard, it has to trust its first keyboard unless there is another way to confirm trust when that first keyboard is plugged in. Fortunately mobile devices all have built in input hardware that can be trusted at manufacture, avoiding this issue. If a computer has lost all its input devices and needs a new one, you could either trust implicitly, or provide a pairing code to type on the new keyboard (would not work for mouse) to show you are really there. But this is only a risk on systems that normally have no input device at all.

For an even stronger level of trust, we might want to be able to encrypt the data going through. This stops the insertion of malicious hubs or other MITM intercepts that might try to log keystrokes or other data. Encryption may not be practical in low power devices that need to be drives and send data very fast, but it would be fine for all low speed devices.

Of course, we should not trust our networks, even our home networks. Laptops and mobile devices constantly roam outside the home network where they are not protected, and then come back inside able to attack if trusted. However, some security designers know this and design for this.

Yes, this adds some extra UI the first time you plug something in. But that’s hopefully rare and this is a big gaping hole in the security of most of our devices, because people are always plugging in USB drives, dongles and more.

A BIOS and OS designed for very fast booting (and aborting)

We all know how annoying it is that today’s much faster computers take such a long time to boot, and OS developers are working on speeding it up. Some time ago I proposed a defragmenter that notice what blocks were read in what order at boot and put the contiguous on the disk. I was told that experiments with this had not had much success, but more recently I read reports of how the latest Linux distributions will boot as much a 3 times faster on solid state disks as on rotating ones. There are some SSDs with performance that high (and higher) but typical ones range more in the 120 mb/second rate, better than 80 mb/second HDDs but getting more wins from the complete lack of latency.

However, today I want to consider something which is a large portion of the boot time, namely the power-on-self-test or “POST.” This is what the BIOS does before it gets ready to load the real OS. It’s important, but on many systems is quite slow.

I propose an effort to make the POST multitask with the loading of the real OS. Particularly on dual-core systems, this would be done by having one core do the POST and other BIOS (after testing all the cores of course) and other cores be used by the OS for loading. There are ways to do all this with one core I will discuss below, but this one is simple and almost all new computers have multiple cores.

Of course, the OS has to know it’s not supposed to touch certain hardware until after the BIOS is done initializing it and testing it. And so, there should be BIOS APIs to allow the OS to ask about this and get events as BIOS operations conclude. The OS, until given ownership of the screen, would output its status updates to the screen via a BIOS call. In fact, it would do that with all hardware, though the screen, keyboard and primary hard disk are the main items. When I say the OS, I actually mean both the bootloader that loads the OS and the OS itself once it is handed off to.

Next, the BIOS should, as soon as it has identified that the primary boot hard disks are ready, begin transferring data from the boot area into RAM. Almost all machines have far more RAM than they need to boot, and so pre-loading all blocks needed for boot into a cache, done in optimal order, will mean that by the time the OS kernal takes over, many of the disk blocks it will want to read will already be sitting in ram. Ideally, as I noted, the blocks should have been pre-stored in contiguous zones on the disk by an algorithm that watched the prior boots to see what was accessed and when.

Indeed, if there are multiple drives, the pre-loader could be configured to read from all of them, in a striping approach. Done properly, a freshly booted computer, once the drives had spun up, would start reading the few hundred megabytes of files it needs to boot from multiple drives into ram. All of this should be doable in just a few seconds on RAID style machines, where 3 disks striped can deliver 200mb/second or more of disk read performance. But even on a single drive, it should be quick. It would begin with the OS kernel and boot files, but then pre-cache all the pages from files used in typical boots. For any special new files, only a few seeks will be required after this is done.  read more »

Do we need a time delay after password failures?

Most programs that ask for a password will put in a delay if you get it wrong. They do this to stop password crackers from quickly trying lots of passwords. The delay makes brute force attacks impossible, in theory.

But what does it really do? There are two situations. In one situation, you have some state on the party entering the password, such as IP address, or a shell session, or terminal. So you can slow them down later. For example, you could let a user have 3 or 4 quick tries at a password with no delay, and then put in a very long delay on the 5th, even if they close off the login session and open another one. Put all the delay at the end of the 4 tries (or at the start of the next 4) rather than between each try. It's all the same to a cracking program.

Alternately, you have no way to identify them, in which case rather than sit through a delay, they can just open another session. But you can put a delay on that other session or any other attempt to log into that user. Once again you don't have to make things slow for the user who just made a typo. And of course, typos are common since most programs don't show you what you're typing. (This turns out to be very frustrating when logging in from a mobile device where the keyboards are highly unreliable and you can't see what you are typing!)

A Package packager to compartmentalize my system changes

First, let me introduce a new blog topic, Sysadmin where I will cover computer system administration and OS design issues, notably in Linux and related systems.

My goal is to reduce the nightmare that is system administration and upgrading.

One step that goes partway in my plan would be a special software system that would build for a user a specialized operating system “package” or set of packages. This magic package would, when applied to a virgin distribution of the operating system, convert it into the customized form that the user likes.

The program would work from a modified system, and a copy of a map (with timestamps and hashes) of the original virgin OS from which the user began. First, it would note what packages the user had installed, and declare dependencies for these packages. Thus, installing this magic package would cause the installation of all the packages the user likes, and all that they depend on.

In order to do this well, it would try to determine which packages the user actually used (with access or file change times) and perhaps consider making two different dependency setups — one for the core packages that are frequently used, and another for packages that were probably just tried and never used. A GUI to help users sort packages into those classes would be handy. It must also determine that those packages are still available, dealing with potential conflicts and name change concerns. Right now, most package managers insist that all dependencies be available or they will abort the entire install. To get around this, many of the packages might well be listed as “recommended” rather than required, or options to allow install of the package with missing 1st level (but not 2nd level) dependencies would be used.  read more »

A Posix (universal API) for package management

As part of my series on the horrors of modern system administration and upgrading, let me propose the need for a universal API, over all operating systems, for accessing data from, and some control of the package management system.

There have been many efforts in the past to standardize programming APIs within all the unix-like operating systems, some of them extending into MS Windows, such as Posix. Posix is a bit small to write very complex programs fully portably but it’s a start. Any such API can make your portability easier if it can’t make it trivial the way it’s supposed to.

But there has been little effort to standardize the next level, machine administration and configuration. Today a large part of that is done with the package manager. Indeed, the package manager is the soul (and curse) of most major OS distributions. One of the biggest answers to “what’s the difference between debian and Fedora” is “dpkg and apt, vs. rpm and yum.” (Yes you can, and I do, use apt with rpm.)

Now the truth is that from a user perspective, these package managers don’t actually look very different. They all install and remove packages by name, perform upgrades, handle dependencies etc. Add-ons like apt and GUI package managers help users search and auto-install all dependencies. To the user, the most common requests are to find and install a package, and to upgrade it or the system.  read more »

Upgrading: ask me few questions, and ask them together

One of my current peeves is just how much time we spend maintaining and upgrading computer operating systems, even as ordinary users. The workload for this is unacceptably high, though it’s not as though people are unaware of the problem.

Right now I’m updating one system to the beta of the new Ubuntu Feisty Fawn. (Ubuntu is the Linux distro I currently recommend.) They have done some work on building a single upgrader, which is good, but I was shocked to see an old problem resurface. In a 2 hour upgrade process, it asked me questions it didn’t need to ask me, and worse, it asked them at different times in the process.  read more »

Sysadmin services trading

I've ranted before about just how hard it has become to configure and administer computers. And there are services where you can hire sysadmins to help you, primarily aimed at novice users.

But we advanced users often need help today, too. Mostly when we run into problems we go to message boards, or do web searches and find advice on what to do. And once we get good on a package we can generally fix problems with it in no time.

I would love a service where I can trade my skill with some packages for help from others on other packages. There are some packages I know well, and could probably install for you or fix for you in a jiffy. Somebody else can do the same favour for me. In both cases we would explain what we did so the other person learned.

All of this would take place remotely, with VNC or ssh. Of course, this opens up a big question about trust. A reputation system would be a big start, but might not be enough. Of course you would want a complete log of all files changed, and how they were changed -- this service might apply more to just editing scripts and not compiling new binaries. Best of all, you could arrange to have a virtualized version of your machine around for the helper to use. After examining the differences you could apply to them to your real machine. Though in the end, you still need reputations so that people wanting to hack machines would not get into the system. They might have to be vetted as much as any outside consultant you would hire for money.

There seems a real efficiency to be had if this could be made to work. How often have you pounded for hours on something that a person skilled with the particular software could fix in minutes? How often could you do the same for others? Indeed, in many cases the person helping you might well be one of the developers of a system, who also would be learning about user problems. (Admittedly those developers would quickly earn enough credit to not have to maintain any other part of their system.)

The real tool would be truly secure operating systems where you can trust a stranger to work on one component.

Now that virtualizers are here, let's default to letting you run your old system

Virtualizer technology, that lets you create a virtual machine in which to run another “guest” operating system on top of your own, seems to have arrived. It’s common for servers (for security) and for testing, as well as things like running Windows on linux or a Mac. There are several good free ones. One, kvm, is built into the lastest Linux kernel (2.6.20). Microsoft offers their own.

I propose that when an OS distribution does a major upgrade, it encapsulate your old environment as much as possible in a compressed virtualizer disk image. Then it should allow you to bring up your old environment on demand in a virtual machine. This way you can be confident that you can always get back to programs and files from your old machine — in effect, you are keeping it around, virtualized. If things break, you can see how they broke. In an emergency, you can go back and do things within your old machine. It can also allow you to migrate functions from your old machine to your new one more gradually. Virtual machines can have their own IP address (or even have the original one. While they can’t access all the hardware they can do quite a bit.

Of course this takes lots of disk space, but disk space is cheap, and the core of an OS (ie. not including personal user files like photo archives and videos) is usually only a few gigabytes — peanuts by today’s standards. There is a risk here, that if you run the old system and give it access to those personal files (for example run your photo organizer) you could do some damage. OSs don’t get do a great division between “your” files for OS and program config and “your” large data repositories. One could imagine an overlay filesystem which can only read the real files, and puts any writes into an overlay only seen by the virtual mount.

One can also do it the other way — run the new OS in the virtual machine until you have it tested and working, and then “flip the switch” to make the new OS be native and the old OS be virtual at the next boot. However, that means the new OS won’t get native hardware access, which you usually want when installing and configuring an OS upgrade or update.

All this would be particuarly handing if doing an “upgrade” that moves from, say, Fedora to Ubuntu, or more extreme, Windows to Linux. In such cases it is common to just leave the old hard disk partition alone and make a new one, but one must dual boot. Having the automatic ability to virtualize the old OS would be very handy for doing the transition. Microsoft could do the same trick for upgrades from old versions to Vista.

Of course, one must be careful the two machines don’t look too alike. They must not use the same MAC address or IP if they run internet services. They must, temporarily at least, have a different hostname. And they must not make incompatible changes, as I noted, to the same files if they’re going to share any.

Since hard disks keep getting bigger with every upgrade, it’s not out of the question that you might not keep your entire machine history behind as a series of virtual machine images. You could imagine going back to the computer environment you had 20 years ago, on demand, just for fun, or to recover old data formats — you name it. With disks growing as they are, we should not throw anything away, even entire computer environments.

A first solution to linux dependencies part 2 -- yes, service packs

Last week I wrote about linux’s problems with dependencies and upgrades and promised some suggestions this week.

There are a couple of ideas here to be stolen from (sacrilige) windows which could be a start here, though they aren’t my long term solution.

Microsoft takes a different approach to updates, which consists of little patches and big service packs. The service packs integrate a lot of changes, including major changes, into one upgrade. They are not very frequent, and in some ways akin to the major distribution releases of systems like Ubuntu (but not its parent Debian ), Fedora Core and SuSE.

Installing a service pack is certainly not without risks, but the very particular combination of new libraries and changed apps in a service pack is extensively tested together, as is also the case for a major revision of a linux distribution. Generally installing one of these packs has been a safe procedure. Most windows programs also do not use hand-edited configuration files for local changes, and so don’t suffer from the upgrade problems associated with this particular technique nearly as much.  read more »

The linux package upgrade nightmare, part 1

We all spend far too much of our time doing sysadmin. I’m upgrading and it’s as usual far more work than it should be. I have a long term plan for this but right now I want to talk about one of Linux’s greatest flaws — the dependencies in the major distributions.

When Unix/Linux began, installing free software consisted of downloading it, getting it to compile on your machine, and then installing it, hopefully with its install scripts. This always works but much can go wrong. It’s also lots of work and it’s too disconnected a process. Linuxes, starting with Red Hat, moved to the idea of precompiled binary packages and a package manager. That later was developed into an automated system where you can just say, “I want package X” and it downloads and installs that program and everything else it needs to run with a single command. When it works, it “just works” which is great.

When you have a fresh, recent OS, that is. Because when packagers build packages, they usually do so on a recent machine, typically fully updated. And the package tools then decide the new package “depends” on the latest version of all the libraries and other tools it uses. You can’t install it without upgrading all the other tools, if you can do this at all.

This would make sense if the packages really depended on the very latest libraries. Sometimes they do, but more often they don’t. However, nobody wants to test extensively with old libraries, and serious developers don’t want to run old distributions, so this is what you get.

So as your system ages, if you don’t keep it fully up to date, you run into a serious problem. At first you will find that if you want to install some new software, or upgrade to the lastest version to get a fix, you also have to upgrade a lot of other stuff that you don’t know much about. Most of the time, this works. But sometimes the other upgrades are hard, or face a problem, one you don’t have time to deal with.

However, as your system ages more, it gets worse. Once you are no longer running the most recent distribution release, nobody is even compiling for your old release any more. If you need the latest release of a program you care about, in order to fix a bug or get a new feature, the package system will no longer help you. Running that new release or program requires a much more serious update of your computer, with major libraries and more — in many ways the entire system. And so you do that, but you need to be careful. This often goes wrong in one way or another, so you must only do it at a time when you would be OK not having your system for a day, and taking a day or more to work on things. No, it doesn’t usually take a day — but it might. And you have to be ready for that rare contingency. Just to get the latest version of a program you care about.

Compare this to Windows. By and large, most binary software packages for windows will install on very old versions of Windows. Quite often they will still run on Windows 95, long ago abandoned by Microsoft. Win98 is still supported. Of late, it has been more common to get packages that insist on 7 year old Windows 2000. It’s fairly rare to get something that insists on 5-year-old Windows XP, except from Microsoft itself, which wants everybody to need to buy upgrades.

Getting a new program for your 5 year old Linux is very unlikley. This is tolerated because Linux is free. There is no financial reason not to have the latest version of any package. Windows coders won’t make their program demand Windows XP because they don’t want to force you to buy a whole new OS just to run their program. Linux coders forget that the price of the OS is often a fairly small part of the cost of an upgrade.

Systems have gotten better at automatic upgrades over time, but still most people I know don’t trust them. Actively used systems acquire bit-rot over time, things start going wrong. If they’re really wrong you fix them, but after a while the legacy problems pile up. In many cases a fresh install is the best solution. Even though a fresh install means a lot of work recreating your old environment. Windows fresh installs are terrible, and only recently got better.

Linux has been much better at the incremental upgrade, but even there fresh installs are called for from time to time. Debian and its children, in theory, should be able to just upgrade forever, but in practice only a few people are that lucky.

One of the big curses (one I hope to have a fix for) is the configuration file. Programs all have their configuration files. However, most software authors pre-load the configuration file with helpful comments and default configurations. The user, after installing, edits the configuration file to get things as they like, either by hand, or with a GUI in the program. When a new version of the program comes along, there is a new version of the “default” configuration file, with new comments, and new default configuration. Often it’s wrong to run your old version, or doing so will slowly build more bit-rot, so your version doesn’t operate as nicely as a fresh one. You have to go in and manually merge the two files.

Some of the better software packages have realized they must divide the configuration — and even the comments — made by the package author or the OS distribution editor from the local changes made by the user. Better programs have their configuration file “include” a normally empty local file, or even better all files in a local directory. This does not allow comments but it’s a start.

Unfortunately the programs that do this are few, and so any major upgrade can be scary. And unfortunately, the more you hold off on upgrading the scarier it will be. Most individual package upgrades go smoothly, most of the time. But if you leave it so you need to upgrade 200 packages at once, the odds of some problem that diverts you increase, and eventually they become close to 100%.

Ubuntu, which is probably my favourite distribution, has announced that their “Dapper Drake” distribution, from mid 2006, will be supported for desktop use for 3 years, and 5 years for server use. I presume that means they will keep compiling new packages to run on the older base of Dapper, and test all upgrades. This is great, but it’s thanks to the generousity of Mark Shuttleworth, who uses his internet wealth to be a fabulous sugar daddy to the Linux and Ubuntu movements. Already the next release is out, “Edgy” and it’s newer and better than Dapper, but with half the support promise. It will be interesting to see what people choose.

When it comes to hardware, Linux is even worse. Each driver works with precisely one kernel it is compiled for. Woe onto you once you decide to support some non-standard hardware in your Linux box that needs a special driver. Compiling a new driver isn’t hard once, until you realize you must do it all again any time you would like to slightly upgrade your kernel. Most users simply don’t upgrade their kernels unless they face a screaming need, like fixing a major bug, or buying some new hardware. Linux kernels come out every couple of weeks for the eager, but few are so eager.

As I get older, I find I don’t have the time to compile everything from source, or to sysadmin every piece of software I want to use. I think there are solutions to some of these problems, and a simple first one will be talked about in the next installment, namely an analog of Service Packs

Syndicate content