Automatically syncing files between hosts without compromising security

The problem

The goal is to automatically synchronize files between several hosts without compromising the integrity of the separate machines. A nice tool for 2-way sync is unison. To sync files between different machines The Right Way (TM) is to tunnel the unison protocol over ssh. This is well supported by unison.

To run sync automatically (e.g. via cron), you need to create an SSH keypair without passphrase, so unison can log into the other machine without human interaction. This is where the problems start, since anyone who got access to the private key (e.g. by compromising or stealing the machine the private key was on) can log into the other host.

Now ssh has a nice way to restrict what you can do with a specific key, so you can e.g. use the following in the remote hosts ~/.ssh/authorized_keys:

command="/usr/bin/unison -server" ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA8K2cd0yemw...

That way someone who has the private key can't execute arbitrary commands, but just unison in server mode. However it's still possible to tell the unison server to overwrite arbitrary files (which the user has write access to). This is a major problem, since also files like ~/.bashrc can be overwritten, so the next time the user logs in, arbitrary commands will be executed.

A possible solution

One solution is to simply create a new user on the remote host with a disabled password, and let unison run as that user (via adding the appropriate line to $HOME/.ssh/authorized_keys, and telling the local unison to use that username).

That's possible, but the .bashrc trick still works, it's just less likely that the code there is ever executed (root would have to use su to become that user).

For me this solution didn't work out since I wanted to sync my maildir, and it was hard to ensure that file permissions were set in a way that both allowed me to read my mail and allowed unison (running under user unison-sync) to sync the files.

The Right Solution (TM)

All the problems vanish as soon as you run unison under the user you'd normally use, but in a chroot. Now a full-blown chroot takes up a lot of space, and there's once again the danger that someone might enter the chroot and run some kind of shell (though the risk is even lower).

It's best to use a chroot which only contains the bare minimum of files necessary to run unison -server.

You get numerous advantages:

  • No problems with file permissions
  • No shell inside the chroot that would read startup files from $HOME.
  • Hardly any space wasted. The whole chroot is about 4Mb in size
  • Since the chroot is pretty much empty, many common exploits (well, shell codes) won't work

How to do it

greek0@orest:/home/chroots/unichroot$ cat ~/.ssh/authorized_keys
command="/usr/bin/dchroot -q -c unison -- /usr/bin/unison -server" ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA8K2cd0.....

greek0@orest:/home/chroots/unichroot$ grep unison /etc/dchroot.conf
unison /home/chroots/unichroot

greek0@orest:/home/chroots/unichroot$ find . -maxdepth 3 | xargs ls -ld
drwxr-xr-x   2 root   root      4096 2006-08-04 16:39 ./bin
-rwxr-xr-x   1 root   root    576100 2006-08-04 15:06 ./bin/sash
lrwxrwxrwx   1 root   root         4 2006-08-04 16:39 ./bin/zsh -> sash
drwxr-xr-x   3 root   root      4096 2006-08-04 15:10 ./home
drwx------   4 greek0 greek0    4096 2006-08-04 15:18 ./home/greek0
drwx------  31 greek0 greek0    4096 2006-08-04 13:47 ./home/greek0/Maildir
drwx------   2 greek0 greek0    4096 2006-08-04 15:47 ./home/greek0/.unison
drwxr-xr-x   2 root   root      4096 2006-08-04 15:07 ./lib
-rwxr-xr-x   1 root   root     88164 2006-08-04 14:58 ./lib/
-rwxr-xr-x   1 root   root   1151644 2006-08-04 14:56 ./lib/
-rw-r--r--   1 root   root      9592 2006-08-04 14:56 ./lib/
-rw-r--r--   1 root   root    141040 2006-08-04 14:55 ./lib/
-rw-r--r--   1 root   root      9656 2006-08-04 14:55 ./lib/
drwxr-xr-x   3 root   root      4096 2006-08-04 14:53 ./usr
drwxr-xr-x   2 root   root      4096 2006-08-04 14:55 ./usr/bin
lrwxrwxrwx   1 root   root        14 2006-08-04 15:12 ./usr/bin/unison -> unison-2.13.16
-rwxr-xr-x   1 root   root    955784 2006-08-04 14:54 ./usr/bin/unison-2.13.16

The zsh symlink is there because I have /bin/zsh as my shell in /etc/passwd, and dchroot also wants to use it in the chroot (for launching unison).

/home/greek0/Maildir is bind-mounted from outside the chroot, bind-mounting is done at boot-time via /etc/fstab.

The chroot was created manually, simply by copying the files from the host. You obviously need /usr/bin/unison plus all the libraries it depends on. You can find those via readelf -d /usr/bin/unison | grep NEEDED. Additionally you need the dynamic linker /lib/ (seen from readelf -l /usr/bin/unison | grep INTERP -A 1).

One thing to pay attention to is that most of the files copied from /lib are symlinks. Be sure to either use cp without arguments, or use cp -a and copy the link targets too.

published August 05, 2006
tags linux

Tools for mutt



This is a tool that displays Debian bug reports in mutt. You can then directly read all messages sent to the bug and reply. The messages are fetched directly from the web interface, so there is no delay between requesting bug and getting it per email.

This tool was originally written by Christoph Berg, I've made some modifications to make it work in arbitrary directories.


$ mutt-bug bugnumber

Download: mutt-bug


gpg --verify is quite slow when you have large keyrings included (like the debian keyring). This is nasty, since mutt has to wait until gpg is finished when displaying a gpg signed message (with signature verification on). So I've written a tool that splits a huge keyring into a lot of smaller keyrings (one key per keyring) and a shell script to verify signatures, to be used from within mutt. The former tool is called The latter one is first invokes gpg --verify as normal and captures its output. If gpg failed because the key was not found in any keyring, the script looks if the key is in one of the splitted keyrings, and if so, reruns gpg with that keyring included. Otherwise the gpg error is returned.

These scripts are still hacky, if you want to use them you'll probably have to modify them a bit. They aren't too big, so this shouldn't be too much of a problem.

Download: gpgverify

A mutt patch for a more colorful index

This patch enables different colorings for different parts of the index display. For example you can choose one color for the subject, another one for the author, and a third one for the flags.


  • Screenshot #1: Just a random screenshot...
  • Screenshot #2: Notice how messages written by me are differently colored then those from other authors. This is done using indexcolor's author pattern matching.


Debian on Linksys WRT54GS (German)

Notizen zu einem kurzen Vortrag, den ich am 28.8.2005 beim Debienna Treffen gehalten habe.


  • Was ist der WRT54GS?
  • Was sind die Vorteile einer eigenen Firmware?
  • Spielerei
  • Shell auf dem WRT
  • Mehr Möglichkeiten als die offizielle Linksys Firmware z.B: OpenVPN
  • Meine Wahl: OpenWRT
  • Paketsystem, ähnlich Debian
  • Wieso zusätzlich noch Debian installieren?
  • Spielerei
  • Mipsel Architektur
  • Gcc/Binutils -> Code schreiben
  • Debugging
  • Wie macht man's?
  • Debootstrap will nicht (Bashisms)
  • CDebootstrap muss her
  • Debian Binary funktioniert auf OpenWRT nicht (glibc <-> uclibc)
  • Man muss cdebootstrap (und libdebian-installer) .ipkg Pakete mit der OpenWRT Toolchain bauen
  • Nicht genug Platz am WRT (nur 8Mb Flash) -> NFS share
  • Bootstrap am WRT läuft nicht glatt durch weil dpkg fehlt: Das lässt sich zwar in Busybox einkompilieren, das erfordert aber etwas mehr Änderungen, und man muss den ganzen OpenWRT Tree bauen.
  • Einfacherer Weg (etwas hacky): cdebootstrap --arch am NFS server im Share, das scheitert irgendwann, weil Arch-spezifische Sachen fehlschlagen. Dpkg ist dann aber schon entpackt. Danach lässt man cdebootstrap am WRT laufen (selbe Optionen), das merkt, dass schon einiges da ist, und macht dort weiter wo cdebootstrap am Host aufgehört hat
  • Danach: Chroot & Freude an Debian haben!
  • Fragen?
  • Danke für's Zuhören


Source & Binaries

Liegen in /div/wrt/ herum.

wmbutton: dockapp displaying configureable buttons


I have been using wmbutton for quite some time, and I think it's really nice. One thing that has always sucked was the need to recompile just to change the images. So I got the source code of the wmbutton Debian package and added the capability to change the images without a recompile. One day later I discovered that someone (ehflora) had already done this. I got his version and it looked a bit better then mine. While playing around I noticed that wmbutton was leaking memory, so I ran valgrind on it, which confirmed my suspicions. I fixed the Leaks and did some more code cleanup.

I've increased the version number to 0.6. The code is still quite a mess, but at least it's better then before. Feel free to further improve it if you like, there's plenty room for it ;-).


This program is released under the GPL version 2. A copy of the license may be obtained at

Screenshots and more can be found at:

Sourcecode Download

Debian packages

wmbutton is available directly from Debian. Check out the package page.