parsing dhcpd.leases with ruby

Needed to get the IP address of a certain mac from the dhcpd leases file, wrote this, seems to work, albeit short. IANAP, YMMV. All of my programming comes from looking at examples, so any faults of mine are actually someone else’s. Blame fR and niblr!


#!/usr/bin/ruby -w
# getdhcpip.rb Bryan McLellan -- bryanm@widemile.com
# parse through dhcpd.leases in search of a mac to get it's current ip
# assume not malformed. remember that this is a log file and the most recent (bottom) is the most accurate

def lastdhcpip(ourmac)
curLeaseIp = nil
curLeaseMac = nil
lastip = nil

f = File.open("/var/lib/dhcp/dhcpd.leases")
f.each do |line|
case line
when /lease (.*) \{/
curLeaseIp = $1
when /hardware ethernet (.*);/
curLeaseMac = $1
if ourmac == curLeaseMac
lastip = curLeaseIp
end
end
end

f.close
return lastip
end

if ARGV[0]
puts lastdhcpip(ARGV[0])
else
puts "Requires MAC address as argument: getdhcpip.rb 00:00:00:00:00:00"
end

Stopping vmware guests with vmware-cmd

Lots of talk out there about “VMControl error -8: Invalid operation for virtual machine’s current state: Make sure the VMware Server Tools are running” when trying to use “vmware-cmd stop” to stop a VM. Stop by default tries to do a soft stop, where it asks the guest to shut down.

I’m scripting a start followed by a stop so vmware will generate new mac addresses for a vmx, and thie works “vmware-cmd stop hard”. ‘hard’, ‘soft’ and ‘trysoft’ are listed here as options.

Theres information here about how MACs are generated by the way. Removing mac address lines from the vmx file will cause them (and the uuid if it’s removed to) to be generated on startup and added to the vmx file.

Support Contracts

I hate support contracts. Google is always faster than working your way up to technical people. Generally I’ve liked Cisco support, because I can open a TAC case online, and they’re super responsive.

I’ve dis-liked Dell support in the past because when you end up with desktops and laptops on different levels of support, you have to call different places depending on the support level. I want to have a single number, punch in the service tag and have it auto-direct me.

I like Dell’s web-support, but often you put in a Service Tag on enterprise equipment, get someone, and then they tell you it’s too enterprise and they can’t help you so you have to call.

10:37am – Place web support chat on MD3000i Array, non-critical failure.
10:39am – Told they can’t help me
10:40am – Call phone support, operator transfer me based on service tag.
10:45am – Support technician transfer me again, says autodialer or something is inefficient.
10:55am – Work with technician on the phone.
11:10pm – Email support log to technician
11:30pm – Rounding off, I get off the phone, technician is going to send me a new controller.
12:30pm – New controller arrives via “UPS SonicAir” by taxi. Holy Crap.

Alright… That’ll do pig.

running winbindd without smbd and nmbd

Using Winbind rather than pam_ldap can me more reliable at times. These days, you don’t need smbd/nmbd for winbindd to work though. Unfortunately, it sounds like you did once and most the documentation out there says as much.

On debian etch:

Stopping /etc/init.d/samba and winbind, then starting winbind worked fine, winbind appears to default to dual daemon mode, so you don’t need to enable as much in /etc/defaults/winbind these days, ‘-Y’ sets it back to single daemon mode.

Also you’ll notice the init script doesn’t require samba.


#!/bin/sh

### BEGIN INIT INFO
# Provides: winbind
# Required-Start: $network $local_fs $remote_fs
# Required-Stop: $network $local_fs $remote_fs
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: start Winbind daemon
### END INIT INFO

startup web 2.0 operations

While at Haydrian, Adam Logghe sent me this article about startup operations which is sparked by O’Reilly’s rant on startup secret sauce. Not having built a completely automated windows operations deployment system before I can only postulate to a degree, but I disagree with the comment about Microsoft having a leg up on open source because their server team works with there operations team.

In many open source environments, the operations team also happens to be the server operating system team, that is, many operations people in open source are contributers. When starting at Widemile we had a plan to kick start operations. Some of the people here had worked with Adam from HJK in the past. These people are a great example, not only is HJK heavily involved with puppet, including successful deployments, they also develop open source tools like iclassify to tie into puppet and capistrano.

Last night I finished setting up the largest hump for me in our new ops platform. The design is this, servers on vmware guests, with the hosts running on blades with vlan trunking. Working with HJK’s help (I highly recommend these guys, just don’t everyone hire them at once, I like having access to them myself) we’ve got a full puppet deployment and last night I finished transitioning all of the the servers to vlan trunking. Need another web server? Check munin for a vmware host with available load, create a new guest (haven’t automated this yet) and to an automated network install. Then push puppet and iclassify (one command) out, tag the new node in iclassify ( a couple clicks) with it’s role, and puppet pushes out all the required software and configs for that server.

What else do you get out of this? One of the servers wasn’t working today, i couldn’t get to it on the network. I jumped on the console via the vmware server gui and saw one of the interfaces was bridged to the wrong vlan. Fortunately I can change which /dev/vmnet interface on the host the guest is tied to from the vmware management utility in real time without even rebooting the machine, and everything was fixed.

All the benefits of blades aside, the software solutions used here are wonderful. I’ve implemented a few hacks like using the vmware-server ‘backdoor’ to identify what host a guest is on, and have that become an iclassify attribute automatically, usable in iclassify, puppet and capistrano tasks. Now granted, all of this requires a very broad level of experience, but once you get it setup, it’s not much work to maintain. When you’re talking about having piles of servers dropping from the sky, this is what you want already setup, rather than a handful of admins manually doing configurations.

jboss ha weirdness

I don’t know enough about jboss to make an intelligent keyword filled post about this, but I wanted to note that while troubleshooting jboss ha-jndi jms crap, make sure that telneting to port 1099 produces an fqdn. on a couple servers /etc/hosts had a different hostname portion of the fqdn than the hostname alias, and this silently broke JMS. Telneting to 1099 revealed this, or at least, indicated it was dns related as working boxes were giving an fqdn while non working boxes weren’t. I think jgroups isn’t friendly with dns over all.

configuring vmware guest time synchronization

I really want a google certification. That is, a certification that says I am an expert googler. To the uninitiated, google may seem like a simple thing, but finding what you really need usually isn’t.

I saw this forum post while trying to figure out how to configure vmware guest time synchronization with scripts running off of vmware server. Something wasn’t write though:

# vmware-guestd –cmd ‘vmx.set_option time.synchronize.tools.startup 0 1’
Unknown option name

So I went and grabbed the new open-vm-tools source. In ‘lib/include/vm_app.h’

#define TOOLSOPTION_SYNCTIME “synctime”
#define TOOLSOPTION_COPYPASTE “copypaste”
#define TOOLSOPTION_AUTOHIDE “autohide”
#define TOOLSOPTION_BROADCASTIP “broadcastIP”
#define TOOLSOPTION_ENABLEDND “enableDnD”
#define TOOLSOPTION_SYNCTIME_PERIOD “synctime.period”
#define TOOLSOPTION_SYNCTIME_ENABLE “time.synchronize.tools.enable”
#define TOOLSOPTION_SYNCTIME_STARTUP “time.synchronize.tools.startup”

Trying combinations of the last two did nothing, but I did have vmx.set_option as a search term though and eventually found this post that just uses:

vmware-guestd –cmd ‘vmx.set_option synctime 0 1’

Nothing appeared on the screen when I ran this on a guest, but I did notice that the vmx file for the guest on the host automatically changed from:

tools.syncTime = “FALSE”

to

tools.syncTime = “TRUE”

I thought I was going to have to write a sed script and have puppet change all the vmx files and do a reboot of all the guests. Much happier now.

stupid vim notes

I really need to just put my vimrc in a git repo on the tubes somewhere. I’m always forgetting these things. I’m not hardcore about custom configs, but this stuff really helps. If you’re not familiar with these things, this helps.

my ~/.vimrc file usually looks like this:

syntax on # enable coloring for source and scripts
set tabstop=2 # make tabs two spaces instead of five or whatever
set expandtab # uses spaces instead of tabs
set background=dark # make that dark blue text light blue because I use black backgrounds

When you open a dos text file on a unix box, sometimes it’s full of ^M characters. This is because of the CR/LF or CR difference. Sometimes it’s just visually annoying and distracting, sometimes a daemon crashs and burns because of them. I used to use :set filetype with unix/dos or something to convert files. These days I just open the file in vi/vim and do

:% s/^M$//

You need to enter the ^M by typing CTRL+V then CTRL+M.
:% means all lines
s is a substituion regex
^M$ is what you want to match, the $ meaning ‘at the end of the line’
the emptiness inside the // means you want to replace ^M with nothing

then save the file. ( :wq )

getting hostnames between vmware hosts and guests

The vmware-tools are open source now. There’s a open-vm-tools package for lenny/sid, but not etch. There are people out there who have back ported it.

This package appears to make a ‘guestinfo.ip’ variable, which is a method for passing data between the host and guest without networking. There does not appear to be any variables for the hostname of the guest or the host by default, which is REALLY, REALLY dumb. You can make one though.

guest$ /usr/sbin/vmware-guestd –cmd ‘info-get guestinfo.ip’

This is really awesomely funny:

guest$ /usr/sbin/vmware-guestd –cmd ‘info-set guestinfo.hostname’
Two and exactly two arguments expected
guest$ /usr/sbin/vmware-guestd –cmd info-set guestinfo.hostname
Too many mandatory argument(s) on the command line. The maximum is 1.

[04:00pm|btm> HA HA HA HA HA
[04:02pm|jet_li> btm: welcome to my world
[04:02pm|jet_li> btm: here’s a hint. typing harder won’t help
[04:03pm|jet_li> btm: neither will profanity, or throwing things

This does work:

guest$ /usr/sbin/vmware-guestd –cmd ‘info-set guestinfo.hostname foo’

Then on the server you can run ‘vmware-cmd -l’ to list your config files. Then run:

host$ vmware-cmd ‘/path/to/config.vmx’ getguestinfo hostname

And you get:

getguestinfo(hostname) = foo

Now go do something useful with it (I’m going to use it with iClassify and puppet.)

getting a debian-installer ssh shell the hard way

There has to be an easier way…

Boot up into the installer, grab a vty2. (ALT-F2)
anna-install network-console (installs ssh)
network-console-menu (set password)
nano /etc/passwd (set shell to /bin/ash for installer user)

now you can ssh in as installer. if you don’t use network console and just install openssh-server-udeb, you don’t get hostkeys and config files. network-console-menu generates the hostkeys for you. if you don’t change the shell you’ll get dumped into the network-console menu when you ssh in, which is okay if that’s what you want.

all this just to: ‘tar -cvf – . | ssh installer@w.x.y.z tar -xf -C /target’ meh.

creating debian release files for a local repository

In the past I’ve tried to hack the release file with sed, this works better. Namely my local repo’s packages files were not in the Release file, and apt was getting upset about that now that I’m using signatures (SecureApt).

Somewhere make an apt-release.conf (copied and modified from here):

APT::FTPArchive::Release::Codename “etch”;
APT::FTPArchive::Release::Origin “localhost.example.com”;
APT::FTPArchive::Release::Components “main”;
APT::FTPArchive::Release::Label “Local Debian Repository”;
APT::FTPArchive::Release::Architectures “i386 amd64”;
APT::FTPArchive::Release::Suite “stable”;

The use apt-ftparchive to create the release file:

apt-ftparchive release -c /path/to/apt-release.conf \
/path/to/etch \
> /path/to/etch/Release

Then sign it: (you do have a local key and all that jazz, right?)

gpg -b /path/to/etch/Release
mv /path/to/etch/Release.sig /path/to/etch/Release.gpg

Should work fine for ubuntu too.

installing from a signed debian repository day 2

problem #1: the “d-i mirror/*” options don’t support pushing a different key. /usr/share/keyrings/archive.gpg is hardcoded into net-retriver. This can be worked around by modifying the initrd like I did here. This is as of etch / net-retriever 1.15. However, rebuilding the initrd with your keyring only works up until base-installer. I opened bug #467049.

problem #2: base-installer does an mkinitrd near the end chrooted inside /target. This is before apt-setup runs and pulls down “d-i apt-setup/local0/key” do the apt-install that runs get dependencies for mkinitrd fails.

[09:40am|otavio> btm: you can do that putting a file on /target even before base-installer. (but after partitioning)
[09:40am|otavio> btm: /target/etc/apt/apt.conf.d
[09:40am|otavio> btm: it’s ugly but works
[09:49am|otavio> btm: yes, there’s … this requires you to provide a signed repository and a key
[09:50am|otavio> btm: but in a way that it integrates
[09:50am|otavio> btm: i’ve done, long time ago, a patch to base-installer to allow it to, using preseed, install a package with base
[09:51am|otavio> btm: so it could be used for thta case where you _do have_ a package with the key

This is too much work right now. My repo is local, so I’m going to go back to running allow_unauthenticated and trust my network. This explains why all the preseed examples on the internet while warning that allow_unauthenticated is insecure, don’t have an example of the correct solution.

Note that after the reboot you need to do an ‘apt-get update’ to get the Release files and signatures for the local repository before apt-get will stop complaining about the unauthenticated-ness of the packages. Bug #467063.

signing your local debian repository

(project incomplete at this time. I can’t see straight)

Usually when I configure a local PXE install of an apt-mirror i use ‘d-i debian-installer/allow_unauthenticated string true’ so I can add my own packages to a mirror. I think in the future setting up two separate mirrors on different virtual hosts is the solution, because I always leave myself with a messy series of symlinks between the web tree and the apt-mirror tree and my own repositories. Only Adam has ever had to look at my mess, so I’ve survived without too much mockery.

On the most recent adventure I tried hacking the Release file. However recently I’ve had some consultant provided scripts that aren’t fond of the “allow unauthenticated packages?” prompts. This could be worked around with some flags (like –force-yes) but I like to try to clean things up when confronted with them, at least a little bit. There is the preseed option “#d-i apt-setup/local0/key string http://local.server/key” but that just applies to the apt-setup package that configures etc/apt/sources.list on /target. All of the installation comes off of “d-i mirror/*” and I don’t see such an option for passing a key. I assume they’re afraid of a MitM attack, as it looks like this is part of of a debian-archive-keyring package that gets pushed into the initrd when it’s made.

If you’re not familiar with udebs, they’re worth taking a look at. udebs are small debs used in the installer. Both are ar archives that contain three files. You can extract them without using any dpkg utils with ‘ar p data.tar.gz some.udeb | tar xvz’. More info is in an earlier research project with debs here.

I happen to know that some udebs are unpacked when the initrd is made and others are downloaded by the installer and then installed. Looking in the current initrd for etch i386 I found ‘archive.gpg’ in usr/share/keyrings. This is a little interesting as it looks like the latest udeb installs ‘debian-archive-keyring.gpg’ and symlinks it to ‘archive.gpg’ in the postinst (debian script, found in control.tar.gz in the ar (udeb)). There’s no such file, so I guess this particular udeb wasn’t used to create this initrd. That’s fine though, I figured it out.

You’ll need a gpg key:

gpg --gen-key
cd [wherever your Release file is]
gpg -b Release
mv Release.sig Release.gpg

By the way! There’s lots of information on the internet about mounting initrd’s using cramfs. That’s old, and it’s frustrating when I forget that. debian and ubuntu initrd images aren’t cramfs filesystems anymore, use:

mkdir initrd ; cd initrd ; gzip -cd ../initrd.gz | cpio -idmv

‘gzip -cd’ does decompress to stdout, and ‘cpio -idmv’ does “copyin” from the cpio archive, making directories, preserving timestamps and being verbose, respectively.

create a new signature file:

cd usr/share/keyrings
gpg --import < archive.gpg
gpg --export > archive.gpg

In the root of your decompressed initrd cpio tree:

find . | cpio -ovH newc | gzip -9c > ../initrd.new.gz

The -9 on gzip is super-duper compression and you’ll get a kernel panic if you try to boot off an initrd image made without ‘-H newc’.

Putting this in your netboot gets you as far as the stage where debian-installer creates the new initrd for the new box, where it fails because you’re now chrooted into /target but apt-setup hasn’t appeared to have run yet so your key listed in “d-i mirror” hasn’t been installed yet (verify with ‘chroot /target’ then ‘apt-key list’ in the shell of your installer when it fails). We could rebuild the debian-archive-keyring udeb with our key added to the keyring, but then we have to regenerate package files an release files to create all the right md5sums.

Apt-setup runs after base-installer in debian-installer, see here. It looks like base-installer runs debootstrap and passes arguments:

int
main(int argc, char *argv[])
{
char **args;
int i;

di_system_init("run-debootstrap");
debconf = debconfclient_new();
args = (char **)malloc(sizeof(char *) * (argc + 1));
args[0] = "/usr/sbin/debootstrap";
for (i = 1; i < argc; i++)
args[i] = argv[i];
args[argc] = NULL;
return exec_debootstrap(args);
}

And debootstrap has a —-keyring option. I can’t see a way to configure this though. There’s a postinst file that has this hardcoded into a variable, I think this is where the option should be. For now I’m re-enabling allow_unauthenticated, as at the very least apt-setup should install my key, and thus allow the packages I want to install to be “authenticated” after in the reboot.

Adding RT Command by mail extensions on debian

Have: Debian box running request-tracker3.6, installed via apt. Notes for LDAP and that squirrely Display.html bug.

1) Download RT-Extension-CommandByMail

2) unpack, compile, install:

tar -xvzf RT-Extension-CommandByMail-0.05.tar.gz
cd RT-Extension-CommandByMail-0.05
perl Makefile.PL
make
sudo make install

when asked for the location of RT.pm it is ‘/usr/share/request-tracker3.6/lib/’

3) add: ‘@MailPlugins = qw(Auth::MailFrom Filter::TakeAction);’ to the end of ‘/etc/request-tracker3.6/RT_SiteConfig.pm’ (before ‘1;’)

4) restart the webserver: ‘/etc/init.d/apache2 restart’

5) review the list of commands.

6) send an email and try it out (subject: ‘[$rtname #ticketnumber]’, rtname is set in RT_SiteConfig.pm) and put a command on the first line of the email

You’ll have whatever permissions your email account has. So that’s a spoofable security concern, but whatever.

The referenced account is currently locked out and may not be logged on to.

I got this error while trying to use an admin share (c$) via CIFS on office XP desktop that’s in the company domain from my XP laptop that isn’t. I built my office desktop and correctly suspected that the original admin account had the same name as my user account on the laptop. The password on this account didn’t meet domain password requirements and was locked out. Even after setting a password that did meet the requirements and unlocking the account, it kept getting re-locked out every time I tried to connect to the desktop.

At older, crazy security driven companies, I would have blamed someone setting the failed passwords required to lock out an account too low. This practice is horrible because you always have someone say “10 times is obviously a hacker!” that don’t take into account all the microsoft software that secretly caches your passwords and tries to auto log you in to stuff with your password rather than kerberos credentials.

I ended up just renaming the account on the desktop, and then the laptop got a password prompt that I could enter my domain credentials into.