Random Links for Wednesday, October 24th

Some random interesting links from Slashdot for today:

Secure rsnapshot backups over the WAN via SSH

Since I moved all of my WAN-facing stuff (mail, web, this blog, svn etc.) to a virtual server with Linode, and just have a desktop at home, it’s no longer practical to use Bacula for backups. Linode manages daily and weekly backups through their backup service, but they’ll only restore a full filesystem at a time. I wanted something that would keep daily and weekly incremental backups long enough that I could find a file changed (or accidentally deleted) a few days or weeks ago. Since I’d be backing up to my desktop at home (which is on a residential dynamic IP connection), the logical solution was something using rsync. Even better than that is the rsnapshot tool, which builds upon rsync and hard links to manage incremental backups with as little disk usage as possible (though I’d certainly recommend excluding log files).

I’m pretty strict about security. Since my home connection has a dynamic IP, things are a bit more complicated – I can’t push from the server, I can’t ACL or firewall the server to just my home IP, and an IPsec VPN would be difficult to accomplish (not to mention add a lot of overhead to big file transfers). So, I opted for a solution that uses SSH key-based authentication, forced comands, and a C wrapper.

The configuration of rsync and rsnapshot is mostly out of the scope of this post. There are plenty of good resources for that, so I’ll just cover the things that won’t be found in most tutorials. Also, I’ll be referring to the remote machine to be backed up as the “remote host” and the local machine which triggers the backup and stores the data as the “local host”.

Local Host Setup – Part I

  1. Choose and create a directory to store your backups in. I have a 1TB external disk mounted at /mnt/backup/, so I chose /mnt/backup/rsnapshot/.
  2. Generate two sets of password-less SSH keys using the ssh-keygen program. One will be used to run the rsync command on the remote host, the other will be used to trigger your pre- and post-backup scripts. Name them accordingly (i.e. “remoteHostname_remoteBackupUsername_cmd” and “remoteHostname_remoteBackupUsername_rsync”). Now, get (scp) the public key for each pair to the remote host.

Remote Host Setup

  1. Ensure that rsync is installed on the host.
  2. Create a user to run the backups. I called this user “rsyncuser”. Create a home directory, and a group for the user. Do not set a password (you don’t want password logins).
  3. Copy the public key files you created above to the user’s ~/.ssh/ directory.
  4. Cat the “remoteHostname_remoteBackupUsername_cmd” public key into the user’s ~/.ssh/authorized_keys file.
  5. Now comes the first fun part. Let’s assume that your pre- and post-backup scripts are /root/bin/rsnapshot-pre.sh and /root/bin/rsnapshot-post.sh, respectively. As root, grab a copy of cmd-wrapper.c (from subversion or at the bottom of this post). Modify for your use – the only thing likely to change is line 38, which ensures it will only run for a member of GID 502. Change this to rsyncuser’s GID. Compile the wrapper with gcc -o cmd-wrapper cmd-wrapper.c. Copy it to rsyncuser’s home directory (/home/rsyncuser), chown root:rsyncuser and chmod 4750. Yes, this sets the SUID bit. The program will now be owned by root, and runnable as root by rsyncuser (or, more specifically, any member of the rsyncuser group).
  6. Open rsyncuser’s .ssh/authorized_keys file in a text editor. At the beginning of the “remoteHostname_remoteBackupUsername_cmd” key line, prepend command="/home/rsyncuser/cmd-wrapper". This sets up SSH forced command (there’s a good overview in O’Reilly’s SSH: The Definitive Guide) so that when this key is used to login, it will directly execute /home/rsyncuser/cmd-wrapper and then exit, without allowing access to anything else.
  7. Add rsyncuser to AllowUsers in /etc/ssh/sshd_config (you do limit user access via SSH, right?) and then reload sshd.
  8. Now, if you SSH to rsyncuser@remoteHost from the local host, using the “_cmd” ssh key and a command of “pre” (i.e. ssh -i /path/to/remoteHostname_remoteBackupUsername_cmd rsyncuser@remoteHost pre), it should execute /root/bin/rsnapshot-pre.sh ad root, and you should see the output locally.
  9. Repeat the above step for the post-backup script (replacing “pre” above with “post”). You should now have your pre- and post-backup scripts working, and triggered remotely. (Note: these steps, and some of the other setup here, is a bit more complex so that it will work better with rsnapshot backups of multiple remote hosts.)
  10. Cat the “remoteHostname_remoteBackupUsername_rsync” public key into the backup user’s ~/.ssh/authorized_keys file.
  11. As root, grab a copy of rsync-wrapper.c (from subversion or at the bottom of this post). Modify for your use – the only thing likely to change is line 38, which ensures it will only run for a member of GID 502 (change this to rsyncuser’s GID), and perhaps the path of or arguments passed to rsync (the wrapper will call /usr/bin/rsync --server --sender -vlogDtprRe.iLsf --numeric-ids . /). Compile the wrapper with gcc -o rsync-wrapper rsync-wrapper.c. Copy it to rsyncuser’s home directory (/home/rsyncuser), chown root:rsyncuser and chmod 4750.
  12. Open rsyncuser’s .ssh/authorized_keys file in a text editor. At the beginning of the “remoteHostname_remoteBackupUsername_rsync” key line, prepend command="/home/rsyncuser/rsync-wrapper". This will run rsync with the arguments specified in rsync-wrapper.c every time this key is used to login.

Local Host Setup – Part II

I use totally separate configs for each host that I backup, to keep things clean and to let me enable, disable, or tweak one remote backup without affecting the others.

  1. Create host-specific pre- and post-backup scripts. I put them in /etc/rsnapshot.d/.
    /etc/rsnapshot.d/pre-remoteHostName.sh:

    #!/bin/bash
     
    # do anything else needed on the local system before a backup
    ssh -i /path/to/remoteHostname_remoteBackupUsername_cmd rsyncuser@remoteHost pre

    /etc/rsnapshot.d/post-remoteHostName.sh:

    #!/bin/bash
     
    # do anything else needed on the local system after a backup
    ssh -i /path/to/remoteHostname_remoteBackupUsername_cmd rsyncuser@remoteHost post
  2. Setup a set of rsync include and exclude files (see man rsync(1), --include-from= and --exclude-from=). I put mine at /etc/rsnapshot.d/rsync-include-remoteHostName.txt and /etc/rsnapshot.d/rsync-exclude-remoteHostName.txt, respectively. (Examples included at the bottom of this post).
  3. Configure rsnapshot. I use a separate config file for each remote host. Copy the default /etc/rsnapshot.conf to /etc/rsnapshot-remoteHostName.conf. The important items are rsync_short_args, rsync_long_args, ssh_args, cmd_preexec, cmd_postexec and backup. Here’s an example of my config file, with comments and blank lines removed:
    config_version  1.2
    snapshot_root   /mnt/backup/rsnapshot/
    cmd_cp          /bin/cp
    cmd_rm          /bin/rm
    cmd_rsync       /usr/bin/rsync
    cmd_ssh         /usr/bin/ssh
    cmd_logger      /bin/logger
    cmd_du          /usr/bin/du
    cmd_rsnapshot_diff      /usr/bin/rsnapshot-diff
    interval        daily   14 # save 14 daily backups
    interval        weekly  6 # save 6 weekly backups
    verbose         2
    loglevel        3
    logfile /var/log/rsnapshot-remoteHostName.log
    lockfile        /var/run/rsnapshot-remoteHostName.pid
    rsync_short_args        -a
    rsync_long_args --delete --numeric-ids --relative --delete-excluded
    ssh_args        -i /path/to/remoteHostname_remoteBackupUsername_rsync
    exclude_file    /etc/rsnapshot.d/rsync-exclude-remoteHostName.txt
    include_file    /etc/rsnapshot.d/rsync-include-remoteHostName.txt
    link_dest       1
    use_lazy_deletes        1
    cmd_preexec     /etc/rsnapshot.d/pre-remoteHostName.sh
    cmd_postexec    /etc/rsnapshot.d/post-remoteHostName.sh
    backup  rsyncuser@remoteHostName:/      remoteHostName/

    The backup line is what tells rsync what to back up (/ on remoteHostName, logging in as rsyncuser), and where to back up to (snapshot_root/remoteHostName/).

  4. Create two scripts that will actually trigger the backups, which I’ll call /root/bin/rsnapshot-daily.sh and /root/bin/rsnapshot-weekly.sh:
    /root/bin/rsnapshot-daily.sh:

    #!/bin/bash
     
    /usr/bin/rsnapshot -c /etc/rsnapshot-remoteHostName.conf daily
    # add other hosts here; note, they'll run in series

    /root/bin/rsnapshot-weekly.sh:

    #!/bin/bash
     
    /usr/bin/rsnapshot -c /etc/rsnapshot-remoteHostName.conf weekly
    # add other hosts here; note, they'll run in series
  5. Add two entries to root’s croontab to run the rsnapshot backups. Adjust the following days and times to your liking:
    0 1 * * Mon /root/bin/rsnapshot-weekly.sh # run the weekly backups every Monday at 01:00
    30 2 * * * /root/bin/rsnapshot-daily.sh # run the daily backups every day at 02:30, which *should* be after the weekly finished on Monday morning
  6. Check, after the next scheduled runs, that everything appears to have run correctly. If you want, you can manually trigger the daily script and watch what happens. If you do this more than once, you should delete the directories it creates, or else rotation will be messed up. If you have issues with rsync, aside from the usual troubleshooting, check that rsync-wrapper.c is calling rsync with the same arguments that rsnapshot is sending. It may be useful to use my print-cmd.sh script in place of the “rsync-wrapper” forced command. This script will simply log the command rsnapshot calls via SSH.

Assuming all of this worked, you should now have a fairly secure SSH-based remotely-triggered backup system. In a follow-up post I provide my Nagios Check Plugin for Rsnapshot Backups.

The referenced scripts, config files, etc. are below:

cmd-wrapper.c:

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
#include <strings.h>
#include <stdlib.h>
 
/********************************************
 * Wrapper - Secure Yourself                
 *                                          
 * 2007 - Mike Golvach - eggi@comcast.net   
 * Modified 2012 by Jason Antman <jason@jasonantman.com> <http://www.jasonantman.com>
 *  - configured for use as pre- and post-backup script wrapper
 *                                          
 * USAGE: cmd-wrapper [pre|post]
 *
 * $HeadURL: http://svn.jasonantman.com/misc-scripts/cmd-wrapper.c $
 * $LastChangedRevision: 26 $
 *                                          
 ********************************************/
 
/* Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License */
 
/* Define global variables */
 
int gid;
 
/* main(int argc, char **argv) - main process loop */
 
int main(int argc, char **argv, char **envp)
{
  char *origcmd;
 
  origcmd = getenv("SSH_ORIGINAL_COMMAND");
 
  /* printf ("Original Command:%s\n", origcmd); */
 
  /* Set euid and egid to actual user */
 
  gid = getgid();
  setegid(getgid());
  seteuid(getuid());
 
  /* Confirm user is in GROUP(502) group */
 
  if ( gid != 502 ) {
    printf("User Not Authorized! Exiting...\n");
    exit(1);
  }
 
  /* Check argc count only at this point */
 
  if ( argc != 1 ) {
    printf("Usage: cmd-wrapper [pre|post]\n");
    exit(1);
  }
 
  /* Set uid, gid, euid and egid to root */
 
  setegid(0);
  seteuid(0);
  setgid(0);
  setuid(0);
 
  /* Check argv for proper arguments and run
   * the corresponding script, if invoked.
   */
 
  if ( strncmp(origcmd, "pre", 3) == 0 ) {
    if (execl("/root/bin/rsnapshot-pre.sh", "rsnapshot-pre.sh", NULL) < 0) {
      perror("Execl:");
    }
  } else if ( strncmp(origcmd, "post", 4) == 0 ) {
    if (execl("/root/bin/rsnapshot-post.sh", "rsnapshot-post.sh", NULL) < 0) {
      perror("Execl:");
    }
  } else {
    printf("ERROR: Invalid command: %s\n", origcmd);
    printf("Usage: COMMAND [pre|post]\n");
    exit(1);
  }
  exit(0);
}

rsync-wrapper.c:

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
#include <strings.h>
 
/********************************************
 * Wrapper - Secure Yourself                
 *                                          
 * 2007 - Mike Golvach - eggi@comcast.net   
 * Modified 2012 by Jason Antman <jason@jasonantman.com> <http://www.jasonantman.com>
 *  - configured for use as rsync wrapper
 *                                          
 * $HeadURL: http://svn.jasonantman.com/misc-scripts/rsync-wrapper.c $
 * $LastChangedRevision: 26 $
 *                                          
 ********************************************/
 
/* Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License */
 
/* Define global variables */
 
int gid;
 
/* main(int argc, char **argv) - main process loop */
 
int main(int argc, char **argv)
{
 
  /* Set euid and egid to actual user */
 
  gid = getgid();
  setegid(getgid());
  seteuid(getuid());
 
  /* Confirm user is in GROUP(502) group */
 
  if ( gid != 502 ) {
    printf("User Not Authorized! Exiting...\n");
    exit(1);
  }
 
  /* Check argc count only at this point */
 
  if ( argc != 1 ) {
    printf("Usage: rsync-wrapper\n");
    exit(1);
  }
 
  /* Set uid, gid, euid and egid to root */
 
  setegid(0);
  seteuid(0);
  setgid(0);
  setuid(0);
 
  /* Check argv for proper arguments and run
   * the corresponding script, if invoked.
   */
  if (execl("/usr/bin/rsync", "rsync", "--server", "--sender", "-vlogDtprRe.iLsf", "--numeric-ids", ".", "/", NULL) < 0) {
    perror("Execl:");
  }
  exit(0);
}

/etc/rsnapshot.d/rsync-include-remoteHostName.txt:

# Include
+ /dev/console
+ /dev/initctl
+ /dev/null
+ /dev/zero
+ /usr/local/*

/etc/rsnapshot.d/rsync-exclude-remoteHostName.txt:

# Exclude
- /cgroup/*
- /dev/*
- /lib/*
- lost+found/
- /proc/*
- /sys/
- /tmp/
- /var/log/*

php-suhosin syslog issues

I just installed php-suhosin 0.9.29 from EPEL on a CentOS 5.6 box. I’m running a whole bunch of name-based vhosts in Apache, and have a bunch of web apps, so I opted to run suhosin in simulation mode (don’t actually block anything, but log errors) and have it log via syslog to a single file. Unfortunately, when I configured this, the syslog messages started showing up in the wrong place, apparently with the wrong facility and priority. After some roundabout debugging (at first assuming syslogd to be the problem), I determined that, for whatever really strange reason (perhaps an incorrect syslog.h on the EPEL box that built the suhosin package?) the LOG_* constants were incorrect. I looked up the correct integer values in /usr/include/sys/syslog.h and the following configuration directives accomplished the task correctly:

suhosin.log.syslog.facility = 128
; 128 = LOG_LOCAL0
 
suhosin.log.syslog.priority = 5
; 5 = LOG_NOTICE

This one line puts suhosin into simulation mode, where it only logs errors instead of enforcing on them:

suhosin.simulation = On

Consolidation of nmap port scan results to HTML table

I spent a good part of the weekend auditing the security of my infrastructure at home, since I haven’t given it much attention lately. One of my first steps was doing a port scan with nmap of my public IPs from a remote host, both to make sure there’s nothing showing up that shouldn’t be and to get an idea of what a potential attacker might see. However, given all of nmap’s options for different TCP scans, it seemed like a lot of data to sort through. Without finding any good solution in my cursory search, I wrote up a little PHP script that takes any number of XML nmap scan files on the command line, parses out the hosts and ports found in each of them, and presents a nice table showing the result for each host/port for each scan file.

The current version of the script can be found at http://svn.jasonantman.com/misc-scripts/nmap-xml-to-table.php, and simply called as ./nmap-xml-to-table.php file1.xml file2.xml [...] and outputs HTML to stdout.

Vyatta VC5 – Snort alerts to syslog

I’m running a Vyatta vyatta router at home – in my opinion it’s pretty near “enterprise grade”, and I’m running the Community/Core (read: no-cost and almost all Free) on commodity hardware with great performance. Granted, I’m still on the older version (5 as opposed to the current 6) since an upgrade will require total downtime and a spare set of SCSI disks for the machine it’s on, but it still works quite well. Today I decided to enable the Snort IDS on the box. It actually worked quite well (albeit stuck at older rules until I upgrade to Vyatta VC6) and didn’t put much more load on the box. For the time being I decided to just have it alert on problems and not drop anything, as I’m getting pretty high false positives and the older Vyatta version doesn’t seem to have a way to disregard rules.

My biggest complaint was that Vyatta didn’t see fit to allow alerts by syslog. I’m not a big fan of keeping information like IDS logs stuck on the router – I don’t like logging in to it any more than I have to, it doesn’t have much storage, and I’d also like to keep stuff like this in a more secure location. Through a bit of digging, I found the /opt/vyatta/share/perl5/VyattaSnortConfig.pm Perl module which generates the Snort config file from Vyatta’s CLI stuff. Looking through the Perl code, I found the definition of the snort.conf output statements:

my $output_def =<<EOD;
  output alert_unified: alert, limit $log_limit
  output log_null
EOD

I simply added a line output alert_syslog: log_local3 log_notice after the output alert_unified line.

my $output_def =<<EOD;
  output alert_unified: alert, limit $log_limit
  output alert_syslog: log_local3 log_notice
  output log_null
EOD

I then went into Vyatta configuration and changed a rule from alert to pass, committed, changed back, committed, and /etc/snort/snort.conf now had my syslog lines. I’m now getting snort alerts to local3 in syslog, which is fed to my centralized log server. My next project is to find or write something which will parse these logs, generate a daily summary email, and maybe check them hourly and alert on any big changes. I also might just cron an emailing of the output from Vyatta’s show ips summary command. So far I have over 11,000 events logged in about 12 hours.

Managing Ubiquiti Networks MAC ACLs from a script

I have a small web-based tool for allowing members of an organization to register their wireless MAC addresses, and then automatically adding them to the MAC ACL on Ubiquiti AirOSv2 APs. It’s a pretty quick hack, along with a simple and ugly web-based tool, but it gets the job done for a non-profit with only 25 people. After posting about it on the Ubiquiti forum and getting a request from someone for the code, I decided to put it out there for anyone who wants it. The script is mostly based on SCPing configs to and from the AP and SSHing in to run commands, and will need passwordless public key auth to the AP.

The code itself is in subversion at http://svn.jasonantman.com/misc-scripts/ubiquiti-mac-acl/. It’s composed of four files:

  • updateAPconfigs.php.inc – the main PHP file with three functions for working with the APs
  • wirelessTools.php – My PHP page for users to add MACs. It’s pretty rough and is mostly based on handling our LDAP authentication/group framework, but it gives a fair example of how I store MACs in a MySQL table and then rebuild a given AP config file with the current list of MACs. I doubt it will be useful to anyone else as more than an example.
  • wireless.sql – The schema for the SQL database I use to store MACs.
  • README.txt – Readme file including some warnings on the lack of error checking in the functions.

Hopefully this will be of some use to someone. I should probably mention two important things here. First, the AP only accepts up to 32 MAC addresses, so if you feed the makeNewConfigFile() function an array with more than 32, it will just stop at the 32nd. Also, be aware, this SCPs a config file to the AP, runs cfgmtd and the reboots the AP. If you send it a bad config file, who knows what will happen. If you allow your users to add MAC addresses, your APs will reboot every time someone adds one.

All I ask is that if you use this, leave a comment to thank me, and if you make any changes/additions/bugfixes, please send them back to me.

Also, I have some Nagios check scripts that are useful for Ubiquiti APs.

How to make software distribution secure

We were seeing some strange behavior with Mac client machines on the network lately, specifically with DNS queries (I’d guess that a lot of it has to do with Bonjour), but the discussion touched on the DNS Changer trojan for Mac. I’d really never heard about it before, and after some basic reading, it really got me thinking about the state of software packaging, updates, and distribution. Granted, some of my observations would require sweeping changes to how packaging is handled (even on the *nixes), and would require buy-in from more than just the vendor and distributor (well, I guess MS can probably pressure ISVs to do whatever they want), but seems to be the only way to keep appliancization from becoming the solution to security issues. I’ve written about this before, and a while ago in respect to Linux, but here’s my current take on what needs to be done to software packaging to allow our machines to stay secure, no matter what OS they run.

  1. Allow packages to be installed as a user. This is a mammoth task under Windows or Mac, but still an issue under Linux. The DNS Changer trojan is a case in point – there’s no reason a “video codec” would need to be installed system-wide, and if that were simply installed user-specific, the malicious installer would never have the privileges to change system-wide DNS settings. This is also a big issue under Linux. Yum, apt, rpm, etc. should (if run as a non-root user) install packages in a user-local path under /home by default. Of course, this would mean many things would need to change in order to cope – perhaps even a change to the LSB spec.
  2. Warn about inconsistencies on package installation. The package installation program should warn a user (whether installing packages system-wide or local to a user) if the package is going to modify system-wide files, i.e. files not specifically placed by that package and that package only.
  3. Real package management for Windows and Mac It’s about time that Apple and Microsoft admit that people without billions in funding can come up with good ideas. Get rid of these Installer programs (the many many different ones). Each OS should pick a package format, develop a yum-like (or, even better, zypper-like) package management program that understands repositories. I don’t know how they’d cope with the pervasive license keys and DRM in the non-nix world, but I’m sure they could figure out a way that still allowed sane package management. The idea here is that vendors run repositories and are responsible for their GPG keys, so trojans claiming to be an update to a given vendor’s software would be rejected. Also, isn’t it about time that you can update all your software on Windows or Mac through one tool?
  4. Filesystem-based IDS for Windows and Mac Assuming it will take a while to get everyone onboard with the packaging idea, and noting that users of these OSes like installing applications from arbitrary sources, there should be an OS-level feature to audit all filesystem changes made by untrusted/unsigned applications, and a way to alert the user to these changes if they appear suspisious (essentially what Spybot Search & Destroy / TeaTimer do, but builtin to the OS).
  5. Vendor support of packaging/repositories – Along with the idea of repositories, vendors should have a trust or signing system for ISVs signing keys. If users are installing arbitrary software, making them trust an arbitrary key won’t do anything to improve security. Microsoft and Apple need to run a CA that signs the package signing keys of their ISVs. The also – and here’s the big one – need to have a parallel framework for “independent developers”. I.e. something that doesn’t cost any money for the packagers, and allows them to at least give a “this person is who they say they are” message.
  6. Finally, Make package management pervasive – Have a real push to apply the packaging and signing keys standard to all software for the OS.

On a final note, applicable to both the current state of Linux packaging and my ideas about Mac and Windows… DNS is the ideal method of key distribution (granted, yes, this just means that the security of the packager’s DNS records, and their servers and signing key, is just more of an issue). But even with Yum and Zypper, it seems to me to be logical that the packager’s public key should be stored in a DNS record (or at a URL stored in a DNS TXT record). That way, it wouldn’t be up to an end user to import and trust a key, they’d just have to trust the repository (i.e. software.adobe.com) and the package manager would pull down the key and verify that package X in software.adobe.com is, in fact, signed by the software.adobe.com key.

How To Wipe a Bunch of Machines Quickly

Updated 2009-03-05, see bottom.

At work the other week, we decommissioned 24 old desktops – Dell GX280′s that were used in the student labs as print release stations. They didn’t have anything sensitive on them, just Windows XP, but with licensing and all we have to wipe Windows off of them before surplussing them. Since there were 24 of them, it wasn’t exactly going to be the quickest task. Moreover, the GX280′s we used don’t have any removable media drives.

A few people mentioned Darik’s Boot And Nuke (DBAN), which is a bootable Linux distro (CD or floppy) aimed at wiping all of the fixed disks attached to a machine. While they do offer an “Enterprise” version that supports network booting (and logging wipe verifications to a central machine), the pricing isn’t exactly favorable for a small project (or something that just needs Windows to go away, not a DoD-grade 7-pass overwrite with random data). Between the lack of a CD drive and the apparent need to select wiping options at boot, this didn’t seem to be the best method for me.

Luckily, with a little googling, I came by the Cobbler project, a ready-to-run install server aimed at automating network-based OS installation. It turns out that Cobbler has a wiki article on system retirement that deals with using Cobbler to automate a network boot of DBAN. Cobbler takes control of DHCP and TFTP, boots the machine(s) to a PXE boot menu, and allows selection of one of the cobbler “profiles”.

The general procedure is something along these lines:

  1. Get the DBAN iso and grab the .ima image off of it. Loopback mount it.
  2. Copy the initrd and kernel into /opt/cobbler/dban as initrd.img and vmlinuz, respectively.
  3. Assuming you have cobblerd running (cobbler check), add a Distro for DBAN: cobbler distro add --name=DBAN-1.0.7-i386 --kernel=/opt/cobbler/dban/vmlinuz --initrd=/opt/cobbler/dban/initrd.img --kopts="root=/dev/ram0 init=/rc nuke=dwipe floppy=0,16,cmos"
  4. Add a Profile for it: cobbler profile add --name=DBAN-1.0.7-i386 --distro=DBAN-1.0.7-i386
  5. cobbler sync

Assuming all went well, when we PXE boot a machine on the same LAN as the Cobbler system, we’ll get DHCP and a PXE boot menu which will list DBAN-1.0.7.i386 as one of the options. On some of the GX280′s that I did, I had to go into the BIOS and enable PXE boot (or select PXE from the BIOS boot menu). Now, when DBAN boots, we’ll get the standard dmesg output and then a selection screen allowing us to pick a wipe type (I used the single pass all zeros for just getting rid of the old OS) and select which disks to wipe. If you use the default wipe, just press “space” to select all disks and then “F10″ to begin the wipe.

This process allowed me to wipe 7 machines at once (8 port KVM, 1 port for the server). With a better KVM or (even better yet) a totally automatic system as described below, it would essentially be limited to whatever the server and network hardware will handle.

To add a little more automation, we can run cobbler system add --name=default --profile=DBAN-1.0.7-i386 which adds a default profile to Cobbler, saying that any machines with MACs not specifically assigned to a profile should boot the DBAN profile, and bypassing the PXE boot menu.

WARNING: what follows will setup Cobbler and DBAN to automatically wipe all PXE-booting devices without ANY human intervention. Use at your own risk and, for God’s sake, don’t plug your server into a production network (I recommend this only in a lab environment with a dedicated switch, all machines in one physical area, and no possibility of getting on the same ‘net as production machines).

It’s theoretically possible to totally automate this setup. According to the DBAN docs, it will also accept kernel options (kopts) that effect how dnuke works – specifically, --autonuke to tell it to wipe without human intervention and a method option such as --method=zero to select the wipe method. This means that if we PXE boot with kernel options set to nuke="dwipe --autonuke --method=zero" we should go straight to the dwipe utility (the heart of DBAN) and automatically wipe all disks by writing zeros once – without operator intervention. Unfortunately, there’s a bug in the current (1.4.0) Cobbler which prevents quote-encapsulated strings in kopts, meaning that we can’t set one kernel option to a string with whitespace as needed here. If this bug is fixed, it should allow this process to work without any operator intervention, assuming the clients will PXE boot.

Updated 2009-03-05 I haven’t tested it yet, but apparently the Cobbler bug preventing complex kernel options has been fixed. The fix should be included in the 1.4.3 release and is currently in the development tree.

Internet Security, Microsoft Lies

Internet Security

So, this semester I’m taking a class on Internet Security. Our textbook is Management of Internet Security, 2nd Edition by Michael E. Whitman and Herbert J. Mattord. It seems pretty basic, and very much focused on the management side of things (as opposed to technical). The table of contents is as follows:

  1. Introduction to the Management of Information Security
  2. Planning for Security
  3. Planning for Contingencies
  4. Information Security Policy
  5. Developing the Security Program
  6. Security Management Models and Practices
  7. Risk Management: Identifying and Assessing Risk
  8. Risk Management: Assessing and Controlling Risk
  9. Protection Mechanisms
  10. Personnel and Security
  11. Law and Ethics
  12. Information Security Project Management

Now, given that it’s really a “management” book, I can’t say I’m surprised that it reads like an essay that was graded on a scale of buzzwords-per-sentence. However, it seems to be missing the one chapter that’s the most important – actually, the only chapter that would be in the book if I wrote it – “How to get management to allocate the money you need for proper security.” In fact, skimming over the book, I found a lot of content on general management planning, job descriptions, sample policies, and a lot of other pie-in-the-sky stuff, but not one concrete section dedicated to the most difficult part of security – getting the “resources” to do it right!

Microsoft Lies

Why we would spend time analyzing corporate mission statements in an Internet Security class, I have no idea. That seems, to me, too much like what we covered in “Management of Technological Organizations.” But, we do, and one of the examples used is Microsoft’s Mission and Values statement. Perhaps, being the F/OSS advocate that I am, my reading of it was a bit cynical. Let’s take a look at it.

“At Microsoft, our mission and values are to help people and business throughout the world realize their full potential.” Well, we’re off to a good start. Aside from the fact that they want you to realize that potential using only their software, and use their power and money to actively monopolize (or attempt to) most industries that they enter, this seems pretty run-of-the-mill.

Corporate Citizenship: “Every successful corporation has a responsibility to use its resources and influence to make a positive impact on the world and its people. Microsoft’s Global Citizenship Initiative is focused on mobilizing our resources across the company and around the world, to create opportunities in the communities where we do business, and to fulfill our commitment to serving the public good through innovative technologies and partnerships.” Well. Now we’re getting somewhere. Apparently “a positive impact on the world and its people” is defined as trying to monopolize every sector that Microsoft touches, whether attempting to crush and then buy-out the competition, or through flat-out FUD and billion-dollar marketing campaigns. Hmm… innovative partnerships… as in Novell?

Legal and Corporate Affairs: “Microsoft’s Legal and Corporate Affairs Group works on the cutting edge of business and regulatory issues around the world.” Well, I can’t argue with that, they sure are on the cutting edge. What started with Bill Gates mailing out whiny letters about pirated Altair BASIC has now turned into a global juggernaut, capable of forcing the creation of ISO standards at their whim, and successfully quashing any dissent about obviously flawed and under-reviewed “standards” (which, in fact, simply describe current software, rather than setting any real standard).

Values: As a company, and as individuals, we value integrity, honesty, openness, personal excellence, constructive self-criticism, continual self-improvement, and mutual respect. We are committed to our customers and partners and have a passion for technology. We take on big challenges, and pride ourselves on seeing them through. We hold ourselves accountable to our customers, shareholders, partners, and employees by honoring our commitments, providing results, and striving for the highest quality.

  1. integrity – i.e. not creating a draft ISO standard and then offering monetary incentives for acceptance.
  2. honesty – when it works. Intentionally making Vista-Capable labeling so ambiguous that it even confuses Microsoft executives? Fine.
  3. openness um… did they seriously say that? Openness like… protocol interoperability? Standards that can be implemented without patent violations? An “Open Specification Promise” that doesn’t come with a three page FAQ? Nope. Not Microsoft.
  4. constructive self-criticism – Ok, I’ll give them this one. They do, rarely, criticize themselves. Though “constructive” usually means making comments about the poor design of a previous product, and suggesting that everyone upgrade to the new version.
  5. continual self-improvement – I’ll give them this one too. In fact, they’re so crazy about it that they’ve been improving the same codebase for decades!
  6. mutual respect – See above.
  7. We hold ourselves accountable to our customers – Ok. They are offering to allow users to downgrade from Vista to XP.
  8. striving for the highest quality – I don’t think so. They’re striving for products that have the highest market share. As long as the quality is acceptable to the majority of users, and the products do what the majority of users need, that’s fine. But wait… apparently they even missed that goal with Vista.

This is just the opinion of one person. My motivations may be diverse, and surely there’s a bit of zealotry in there. After all, if Ford told me I couldn’t put fog lights on my car myself, I had to bring it to the dealer and pay $400, I’d stop buying their cars – and make sure everyone else knew what they did. But there’s also my ever-present desire to make sure people know both sides of the story, and all the facts. The mainstream media (specifically dumbed-down television) rarely reports on the less cheerful side of Microsoft, like the ISO “standard” scandal, or the Vista letters, or the Vista-Capable fiasco. And I find this to be horribly disturbing. Many people don’t realize that there are alternatives to Microsoft products, even ones that are provided by such big names as Sun Microsystems and IBM. But, most striking, is Microsoft’s overwhelming monopoly. Windows’ market share is currently 90.66% or higher. I ask you, what other industries which affect not only consumers, but nearly every aspect of our daily lives (as computing does) would be allowed to have such a monopoly? It has happened in many other American industries – oil, steel, the railroads, telephone service. Where is the government now?

What happened to the America that made massive monopolies illegal? Have we forgotten a supremely part of our history that began in 1980 with the Sherman Act? Or even the recent events with Bell? In order to truly stimulate competition in the software industry, and provide for not only choice but the improved quality, reliability, and security that comes with true software competition, something needs to be done. For starters, how about breaking Microsoft into separate entities – browser, Office, OS, server, etc. And – the important part – preventing any package sales, discounts, or bundling between the separate types of software (and separate companies).