May 2009 Archives

May 31 2009

BSA

Posted in bugs; by Miek Gieben; comments: 0

The BSA wants companies to fill out a list with all machines they have and the software it runs. For each PC you must provide a list of the Windows version and every program and their versions (and keys).

Suppose I had Windows at home (which sadly I do, it came with the EeeBox I bought). I think the list would look something like this:

Or I'm I going about it the wrong way?


May 31 2009

Group policy in Linux

Posted in linux; by Miek Gieben; comments: 0

Suppose you want to limit access to some servers, only people member of a specific group (or multiple groups) may log in.

The following is one way to tackle this. In this example I will configure ssh access in such a way that only people from the admin group can login. The nice thing is that this will work regardless of any Kerberos or LDAP usage.

Preparation

In /etc/pam.d find the "service" which you want to add a group policy to. For instance sshd, edit that file (this is with Ubuntu):

Remove the comment so that, this:

# Uncomment and edit /etc/security/access.conf if you need to set complex
# access limits that are hard to express in sshd_config.
# account  required     pam_access.so

becomes:

# Uncomment and edit /etc/security/access.conf if you need to set
# complex # access limits that are hard to express in sshd_config.
account  required     pam_access.so

After that you can edit /etc/security/access.conf.

Setting policy

The actual policy is set in the access.conf file located in /etc/security. Currently the fall-through behavior is to let everybody log in. So first we want make sure nobody can login. Per line there are several columns, the columns are separated with colons and have the following meaning (also see access.conf(5)).

+/- : WHO : WHERE

A + means access granted, a - means denied. WHO can be a user or a group and WHERE is used (among other things) to say you can only login from a specific ip address. The whole syntax reminds me of TCPD wrappers.

So to disallow logins access.conf should only have one line:

- : ALL : ALL

This means nobody can login:

% slogin miekg@localhost
 A T O O M  ---  foton.atoom.net

   $Hash: sshd_banner b93d7ef 1230802346 miekg $

miekg@localhost's password: 
Connection closed by 127.0.0.1

Yep, that works.

Now we extend access.conf to only allow me (miekg) to login:

+ : miekg: ALL
- : ALL : ALL

Testing with slogin confirms that I'm now able to login.

Now only people in the admin group are allowed:

+ : (admin) : ALL
- : miekg : ALL
- : ALL : ALL

Notice that the miekg-entry is still there, but it will never be reached because I'm also a member of the admin group. And indeed I can now login with ssh.

To use multiple groups you can use the following:

+ : (admin) (root) : ALL

This means if you are a member of admin or root you are allowed to login. I have yet to think of a way to say you must be a member of both groups.


May 24 2009

Kerberos

Posted in linux; by Miek Gieben; comments: 0

Mental note to self

Having a host listed in a listprincs output isn't enough to have single-sign-on working.

You have explicitly add it with ktadd host/your.host.com

So in my case:

# kdadmin.local
....
kadmin.local:  addprinc -randkey host/charm.atoom.net
...
kadmin.local:  quit

And then you can do a (on charm.atoom.net):

% kinit
Password for miekg@ATOOM.NET: 
% slogin elektron.atoom.net

And have a password-less login to my server.


May 24 2009

A/V heaven

Posted in dreambox; by Miek Gieben; comments: 1

I'm in an A/V heaven, my Dreambox is working great. My raid setup is doing very well.

And now I've also bought a Dolby 5.1 digital sound receiver. The sound is so much better, than the lousy stereo I got from our TV.

Only thing left is to rework the cabling and mounting the speakers to the wall.

Watched "2001: A Space Odyssey" again last night :-).


May 22 2009

Zsh prompt updates

Posted in zsh; by Miek Gieben; comments: 0

I wanted some git information in the prompt I currently have. While thinking and googling about this, a quote on Bart's log got me thinking. I don't need to see my current host, nor do I need to see my current user name.

I always login under my own account (miekg) and if I do change accounts, I probably will be forced to use bash. So showing the current user name is quite useless.

Showing the host you are logged into is also only worth showing when you ssh-ing to a remote host.

So my default prompt now only shows the prompt (%) on the left and the current directory (~) on the right, like this:

Default zsh prompt

Very clean.

When logging into a remote system, the hostname of the system is added (in grey) to the right side of the prompt, like so: (I'm ssh-ing to my other host called elektron, which is electron in Dutch)

Remote zsh prompt

The code to do this:

[[ -n "$SSH_CLIENT" ]] && __ZH=$HOST

if $SSH_CLIENT is set, set $__ZH to the current hostname, then use $__ZH in your prompt.

Next I wanted some git support in my prompt, there are lots of sites which can help you. I stole code from all of them :)

There was however one annoying thing. I store my entire home directory in git, but I don't want to see git information about it all the time. So I created the following function to detect if my the current git repository was the one from my home directory:

zsh_git_home() {
# I have my homedir in git, quite annoying to see 'master' all the time
git_dir=$(git rev-parse --git-dir 2> /dev/null)
[[ -z "$git_dir" ]] && return 0
[[ $(realpath "$git_dir") == $HOME/.git ]] && return 0
return 1
}

If I enter a git repository the current branch is put into the prompt at the left side, here I enter a repository with the master branch. (Note: as the window is very small my path is truncated)

Branch zsh prompt

Code is from Bart.

One other thing I added is that if the working directory is not clean (i.e. you have made some changes) an exclamation mark is added. Like so:

Branch change zsh prompt

The code for this can be found on the sites listed above.

Of course my other prompt features still work. Here is a shot with one background job. Notice that ^Z suspends this program and leaves an exit code of 20, which is shown in red:

Showing all

I'm still figuring out ways to get even more colors in the prompt :)


May 21 2009

DNSSEC deployment

Posted in dns(sec); by Miek Gieben; comments: 0

I've done some work in the development of the DNSSEC protocol, this culminated (for me) in RFC 4641. At the time I was a big proponent of DNSSEC. I still think the DNS should be improved and also believe DNSSEC is one of the best solutions. I'm however not as sure about this as I once was. This is because of several reasons.

The first one being the development of the NSECn record.

I was always a believer in the cleanliness of the DNSSEC protocol. At the time we had a KEY, SIG and NXT record. Later we got the DS record to make it all work better and make a secure delegation operationally possible.

DNSSEC was already complicated, but it was still something you could explain in a day. It was also clear that huge zones like .com could not deploy DNSSEC. Franky because they were too flat and too big, signing such zones would lead to zone files which would be larger than 10 GB -- which in 2000 was huge.

I always thought, well no DNSSEC for .com then. There are lots of other (smaller) zones which can handle the increase in size very well. And why not create a separate TLD (say .secure) for DNSSEC deployment?

Sadly this is not what happened, we got the NSEC (next secure) record, which makes it possible to sign only pieces of a zone. This allows for a gradual deployment of DNSSEC signed zones in say .com. It took the WG three tries to get this right, from NSEC we had NSEC2 and finally NSEC3. This also triggered all kinds of notification mechanism, so a zone can signal to a resolver "You can expect NSEC3's from me, be prepared!". This is so not like the DNS we all love to hate.

This made an already complicated protocol even more complicated.

In my opinion this all went into the protocol because one (1!) zone could not deploy DNSSEC.

The NSECn movement also lead to some other issues which made the WG to decide to rollover the type codes of the DNSSEC records. From KEY, SIG, and NXT we went to DNSKEY, RRSIG and NSEC3. This wasn't such a bad thing, but it gave people saying "DNSSEC is still not ready" ammunition.

The other major thing that happened was that real cryptographers came in. I do have a background in math (I studied computer science), but I'm not a cryptographer in any sense of the word. Keep in mind though that the current DNS is very trivial to hack. There are lots of other attacks possible too. I would even go as far as to say: It is dangerous to use the DNS as it stands right now. For the record, the notion that the DNS is insecure was discovered in 1995 by Steven M. Bellovin.

The only finished solution for protecting the DNS is DNSSEC. And with protecting I mean detecting that something is amiss. DNSSEC does not prevent anything it only helps to detect attacks.

Then came the crypto guys...

I would say: "Aah just use a 1024 bits RSA key and you will be fine." They would say: "Yes, but such keys can be broken in 2 years - you will not be safe!" They do have a point, no security at all it sometimes better then thinking you have security while you do not. But this is the freaking DNS we are talking about, it something goes wrong with DNSSEC security you just fall back to the go'old DNS we have now (i.e. no security at all).

But it is hard to reason with people how do cryptography for a living. I got the distinct impression that everything related to DNSSEC should be 100% cryptographically secure.

This made an already complicated protocol even more complicated.

So here we are in 2009. Some countries have deployed DNSSEC, we are finally seeing some client software emerging so that people can actually benefit from DNSSEC. (Server side DNSSEC sounds nice, but it does not give the end-user any security). It has taken at least 5 years longer then any of us expected at the time. And remember a lot of goverments are now pushing DNSSEC, so it still is not a pull from the market.

It also remains to be seen if the administration complexities of the protocol outway the security benefits it gives. Also there have not been any attacks (as far as I know) on the DNSSEC enabled zones and no private keys have been stolen.

Once something like that happens I see two outcomes. One. The DNSSEC and TLD registry communities handle this brilliantly and it will become a triumph for DNSSEC. Or, two, DNSSEC will die on the spot.

During my time at NLnetLabs I created a timeline, which among other things has the following quote from the Matrix:

We have only bits and pieces of information. What we know for certain is that, at some point in the early Twenty-first Century, all of mankind was united in celebration. Through the blinding inebriation of hubris, we marveled at our magnificence as we gave birth to A.I. DNSSEC.

-- Morpheus, the Matrix

I'm glad that .nl has decided to give DNSSEC a chance.


May 21 2009

Short URLs

Posted in nanoblogger; by Miek Gieben; comments: 3

Not wanting to miss anything on this short urls business, I've implemented something similar in nanoblogger.

How? With a shell script and symlinks, my dear Watson. As with all shell scripting this is probably something you can do drunk.

First I need to get a list of all my articles so that I can link to them. Next I take this permalink address, pipe it through sha1sum, take the last 10 characters and make a symlink from the permalink path and presto: short urls

The shell one-liner becomes something like this (note: I've put the echo in there so you can see what happens).

#!/bin/bash
NB_ARCHIVES=/home/miekg/miek.nl/blog/archives
NB_SHORT=/home/miekg/miek.nl/s
for i in $(find $NB_ARCHIVES -type d -wholename "*2???/*/*/*" -print)
do
    HASH=$(echo $i | sha1sum)
    echo ln -sf $i $NB_SHORT/${HASH:30:10}
done

This scripts can be dropped in your plugin directory, so that it runs after each update in nanoblogger.

In your short urls directory (here: miek.nl/s) you can just use ls and grep to find out which short url links to what article.


May 18 2009

mkfs.ntfs /dev/sdc1

Posted in linux; by Miek Gieben; comments: 3

Oh my God --- why?? This is a 250 GB disk with a USB2 interface, so I'm in for a long wait apparently.

# mkfs.ntfs /dev/sdc1
Cluster size has been automatically set to 4096 bytes.
Initializing device with zeroes:   4%

It this the Windows-way or is mkfs.ntfs a little bit brain dead?


May 14 2009

Non root (remote) backups with rdup

Posted in rdup; by Miek Gieben; comments: 0

When doing a remote backup you are probably using a non-root account and ssh. As using the root account with ssh is considered bad practise. This has the consequence that all files created "at the other side" have their ownership set to the user that is used for the transfer. In my case this means all files and directories are of miekg/miekg.

There are a few ways around this:

  1. Use root to transfer the files. Only this user can change the ownership to other users.

  2. Maybe there is some SELinux or a capability which can give ordinary user the ability to change file ownership?

  3. Store an unpacked rdup archive. This is just like using tar.

  4. Store the original ownership data in a separate file and re-insert this info upon a restore.

Item 1. and 2. speak for them self, so I want to detail 3. and 4.

3. ala tar

With not unpacking I mean just leaving the original rdup -c output, for a full backup this is (with added compression):

rdup -c /dev/null /home | gzip > /tmp/home.rdup.gz

Now you can transfer home.rdup.gz anywhere you want. Unpacking/restoring becomes:

zcat home.rdup.gz | rdup-up -t /saved_files

This is exactly the same as using tar and it also has the same problem. The archive file can become very large. I'm using the same technique however to store backups on Amazon's S3.

4. Separate storage of ownership

It is possible to have an unpacked archive at a remote system and being able to restore this with the original ownership information intact.

I'm still pondering on how to integrate this nicely in rdup-simple. Ideas welcome!

To make it all work we would need the following:

  • a list of all the files and their ownership
  • a means to update this list with every incremental backup
  • a means to re-insert this information when restoring.

creating ownership list

This can be done with the (new! in the not yet released 1.0.0 version) rdup-up -vv switch. This will tell rdup-up to dump a file of uid/gid and filenames to standard output. It looks like this:

rdup -c /dev/null ~/bin | rdup-up -vvnt /tmp/back
+ 0 0 /tmp/back/home
+ 1000 1000 /tmp/back/home/miekg
+ 1000 1000 /tmp/back/home/miekg/bin
+ 1000 1000 /tmp/back/home/miekg/bin/apache2-ssl-certificate
+ 1000 1000 /tmp/back/home/miekg/bin/cx
+ 1000 1000 /tmp/back/home/miekg/bin/docpurge
+ 1000 1000 /tmp/back/home/miekg/bin/eee
+ 1000 1000 /tmp/back/home/miekg/bin/gb.pl
+ 1000 1000 /tmp/back/home/miekg/bin/gconf
...

The output is formatted as: +|- uid gid filename .

During the backup you must save this list somewhere.

updating the list with each incremental

Naturally when you make an incremental dump this list should also be updated as files get removed and others get added. So for now, Perl to the rescue. The following script reads 2 rdup-up -vv created lists and will merge them to a new one.

uid-merge:

#!/usr/bin/perl -wl
use strict;

my %l;
die "Need a conv file (rdup-up -vv output)\n" if ($#ARGV == -1);
open CONV, $ARGV[0] or die "Can not open $ARGV[0]\n";
shift;

while (<CONV>) {
chomp;
my ($p, $uid, $gid, $name) = split / /, $_, 4;
$l{$name} = [ $uid, $gid ];
}
close CONV;

# read another conv file and merge it with the previous one
# - -> remove entry
# + -> overwrite OR add entry
while (<>) {
chomp;
my ($p, $uid, $gid, $name) = split / /, $_, 4;

if ( defined $l{$name} ) {
    # we got something in the previous list
    if ($p eq "+") {
    $l{$name} = [ $uid, $gid ];
    } else {
    delete $l{$name};
    }
} else {
    # nothing in previous list
    if ($p eq "+") {
    $l{$name} = [ $uid, $gid ];
    }
}
}

foreach (keys %l) {
print "+ @{$l{$_}} $_";
}

Usage:

uid-merge saved-file < incremental-update > saved-file2`
mv saved-file2 saved-file

And saved-file is your new list.

re-inserting this information during a restore

Now we want to fool rdup so that the correct uid/gid information is inserted upon a restore. The following script will just do that. It will read the standard rdup output and will replace the uid/gid info with the one from saved-list. Let's recall how standard rdup output looks:

rdup /dev/null ~/bin | sed -n '4,5p'
+- 0775 1001 1001 39 902 /home/miekg/bin/apache2-ssl-certificate
+- 0775 1001 1001 18 14 /home/miekg/bin/cx

Now uid-conv (displayed below) comes in. In our case it will replace those 1001's with the (correct) values of 1000.

rdup /dev/null ~/bin | uid-conv saved-file | sed -n '4,5p'
+- 0775 1000 1000 39 902 /home/miekg/bin/apache2-ssl-certificate
+- 0775 1000 1000 18 14 /home/miekg/bin/cx

uid-conv:

#!/usr/bin/perl -wl
use strict;

my %l;
die "Need a conv file (rdup-up -vv output)\n" if ($#ARGV == -1);
open CONV, $ARGV[0] or die "Can not open $ARGV[0]\n";
shift;

while (<CONV>) {
chomp;
my ($p, $uid, $gid, $name) = split / /, $_, 4;
$l{$name} = [ $uid, $gid ];
}
close CONV;

while (<>) {
chomp;
my @e = split / /, $_, 7;
if ( defined $l{$e[6]} ) {
    ($e[2], $e[3]) = @{$l{$e[6]}}
}
print "@e";
}

putting it all together

For the sake of simplicity only a full dump is shown.

Making the full backup (from mymachine to backuphost):

rdup -c /dev/null ~/bin | ssh miekg@backuphost \
'rdup-up -vv -t /backups/mymachine > /backups/my.list'

We can forgot about uid-merge as we only do a full backup.

Restore (from backuphost to mymachine). Note this MUST connect as root to mymachine otherwise you have the same problem as when you created the backup...So for the restore you must enable root-access in ssh. But after the restore you can disable it again.

rdup /dev/null /backups/mymachine | \
uid-conv /backups/my.list | rdup-tr | \
ssh root@mymachine 'rdup-up -t /home/restore'

A few things happen here. We let rdup (without the -c switch!) create a file list of the files in the backup. Then we use uid-conv to re-insert the correct uid/gid information. Next we give the file list to rdup-tr which will read the files' content from disk. So after rdup-tr has run we have correct meta data (i.e. correct ownership) and the file data. This is then given to ssh which will connect to mymachine where rdup-up is run which restores it to /home/restore.

And presto.


May 11 2009

Related articles in nanoblogger

Posted in nanoblogger; by Miek Gieben; comments: 0

All these wordpress blogs have a related articles line below the blog entries. Sadly nanoblogger does not have such a capability, so I wrote my own. It's not a plugin in the nanoblogger sense of the word, it may be possible to rewrite it as a regular plugin, but I do not now how...

So for now a simple shell script, which you can find here.

Usage within a template

In your templates you should include the following:

$(/home/miekg/miek.nl/blog/bin/related $NB_EntryID)

the shell script returns the related articles separated with comma's.


May 11 2009

New teletekst script

Posted in linux; by Miek Gieben; comments: 1

I've update the teletekst script a little. It now outputs utf8 and uses LWP::Simple so no external commands are called anymore.

You can find it here.


May 09 2009

KDE XFCE rocks

Posted in linux; by Miek Gieben; comments: 1

I could not agree more with Christoph Haas.

I've tried KDE briefly during the last 6 months or so, but it never really stuck.

Some observations.

  1. I've bought an EeeBox (Dual Atom, with 1 GB of ram), boy, how slow is KDE. Do I really need a Vista capable machine to run KDE?

  2. I like my current (XFCE) desktop. Why? Because it's nice and clean. I have no use for desktop icons. I have no use for fancy clocks running on my desktop. I have no use for any fancy stuff running on my desktop. Why?

    Because I don't see my desktop as I'm running lots of terminal sessions!

  3. Basically any desktop environment should be able to display all it's important information in a (top) panel no larger then 24 pixels. This is what I have now with XFCE and I love it. The first KDE4 version I used (4.1 I think it was), could only handle a bottom panel. Luckily this is now fixed.

  4. Even if I would switch to KDE, I will probably still need Firefox. And Firefox is a GTK application and call me stupid but I hate mixing toolkits... Firefix looks like shit in a KDE env. Yes Konqi is nice - but I'm way too much used to Firefox now.

  5. I don't like using the mouse.

  6. Basic stuff like a KDE network manager didn't work when I was ready to try KDE. Well no network, no KDE.

As I'm a long time Linux user, I've used lots of desktop environments and window managers. I even used KDE1.2 (or KDE2) for quite some time. But alas, KDE never captured my imagination so it did not stick. After that I switched to WindowMaker and kept using that for a few years. Then with Ubuntu I just started to use Gnome as it was nice and clean. But Gnome seems to have lost its lustre and was also running quite slow. So currently I'm a XFCE user and I'm very happy with it.


May 04 2009

DejaGNU based testsuite in rdup

Posted in rdup; by Miek Gieben; comments: 0

Well after two days of figuring out I have some sort of working setup. It still uses way too much shell code IMO, but at least it works. If I find the time I might try to do a write-up of how to write tests in dejagnu because I found it hard to do.

In the rdup source you can now do a make check which should like this:

[ -d testlogs ] || mkdir testlogs
chmod +x testsuite/rdup/rdup*helper
runtest 
Test Run By miekg on Mon May  4 20:38:23 2009
Native configuration is i686-pc-linux-gnu

        === rdup tests ===

Schedule of variations:
unix

Running target unix
Using /usr/share/dejagnu/baseboards/unix.exp as board description file for target.
Using /usr/share/dejagnu/config/unix.exp as generic interface file for target.
WARNING: Couldn't find tool config file for unix, using default.
Running ./testsuite/rdup/rdup.full.exp ...
Running ./testsuite/rdup/rdup.incr.exp ...
Running ./testsuite/rdup/rdup.ln-up.exp ...
Running ./testsuite/rdup/rdup.ln.exp ...
Running ./testsuite/rdup/rdup.m-flag.exp ...
Running ./testsuite/rdup/rdup.mvdir.exp ...
Running ./testsuite/rdup/rdup.newdir.exp ...
Running ./testsuite/rdup/rdup.nonzero.exp ...
Running ./testsuite/rdup/rdup.pipeline.exp ...
Running ./testsuite/rdup/rdup.r-flag.exp ...
Running ./testsuite/rdup/rdup.rdup-up.exp ...
Running ./testsuite/rdup/rdup.run-tr.exp ...
Running ./testsuite/rdup/rdup.run-up.exp ...
Running ./testsuite/rdup/rdup.run.exp ...

        === rdup Summary ===

# of expected passes        14

14 tests which are all passed :) For details I refer to the source.


May 03 2009

rdup 0.9.9 released

Posted in rdup; by Miek Gieben; comments: 0

Rdup version 0.9.9 has just been released. It has the fix for the ownership bug ,and it features a new testsuite based on DejaGNU. This (finally) allows user to conduct a make check to run the tests.

Not all tests are ported over from my older private test suite, because I still need to learn a lot about DejaGnu and I wanted to release a new rdup version asap.

Quick download

sha1: f60f964436d3635fcab8455f223a8d0fdcc17821


May 01 2009

rdup-up bug

Posted in rdup, bugs; by Miek Gieben; comments: 0

While preparing for the 1.0.0 release for rdup I found a bug in rdup-up: it does not chown() the files it creates.

Needless to say, this is fixed in the latest git version.

I now want to convert my shell test suite kludge to something people can run a their computer, so that they can send me the output of a make test.