grml-debootstrap
grml-debootstrap copied to clipboard
Git HEAD: Host's hostname leaks into system being installed
Even without custom pre/chroot/post scripts, there are places where the host's hostname (i.e. the one of the machine executing grml-deboostrap) leaks into the system being installed. The consequences are:
- A "broken" postfix setup
- Information disclosure
These are step to reproduce on the shell:
$ sudo grml-debootstrap --hostname hostname-leak-demo --vmfile --target hostname-leak-demo.img --password .... --release wheezy
$ mkdir hostname-leak-demo.d
$ sudo kpartx -a -p p hostname-leak-demo.img
$ mount /dev/mapper/loop1p1 hostname-leak-demo.d
$ sudo mount /dev/mapper/loop........p1 hostname-leak-demo.d
$ sudo chroot hostname-leak-demo.d /bin/fgrep -Rl "$(hostname)" /etc/ 2>/dev/null
/etc/aliases.db
/etc/lvm/backup/hidden1
/etc/lvm/backup/hidden2
/etc/ssh/ssh_host_rsa_key.pub
/etc/ssh/ssh_host_ecdsa_key.pub
/etc/ssh/ssh_host_dsa_key.pub
/etc/postfix/main.cf
I'm currently experimenting with a workaround. The idea is to add a script /usr/local/sbin/hostname
with content
#! /bin/bash
cat /etc/hostname
It does seem to help for postfix, but it's not waterproof, e.g. SSH public keys keep leaking.
PS: I'm running grep inside the chroot since absolute symlinks go to the host system, otherwise.
Possibly this could be solved via unshare --uts
, recent util-linux versions got a nice feature: http://karelzak.blogspot.co.at/2015/04/persistent-namespaces.html
Though we'd have to either check for the according unshare feature (which isn't available even on Debian/jessie) or come up with another way.
unshare --uts
(without a parameter) is available since Debian wheezy at least. --fork
and --pid
require more recent versions.
But the unshare --uts=*
(with a paramter) not, and that's what could be useful for us. Unsure whether we get a decent solution with what we have.
How about /usr/bin/env unshare --uts bash
for the shebang line or about exec unshare --uts "$0" "$@"
from inside grml-debootstrap? For the latter, some "signaling" would be needed to prevent an endless loop, e.g. a magic environment variable.
Either approach would allow grml-debootstrap to call "hostname ...." itself and the call to debootststrap would inherit the UTS namespace and see the same hostname.
Interesting idea, did you give /usr/bin/env unshare --uts bash
a try with a chroot "$TARGET" hostname "$HOSTNAME"
or so already, is this enough to solve our problem?
Tried myself now: unshare --uts bash
as is does not work, see:
$ echo -e '#! /usr/bin/env unshare --uts bash\nhostname foobar\nhostname' > uts.sh
$ chmod a+x uts.sh
$ sudo ./uts.sh
/usr/bin/env: unshare --uts bash: No such file or directory
That due to the nature of how shebang parsing works to my understanding. What does work, is putting a bash wrapper of our own into the shebang line:
$ sudo bash -c 'echo -e "#! /bin/bash\nexec unshare --uts -- bash \"\$@\"" > /usr/local/bin/uts-bash'
$ sudo chmod a+x /usr/local/bin/uts-bash
$ hostname
original
$ sudo uts-bash -c 'hostname; hostname foobar; hostname'
original
foobar
$ hostname
original
So with a wrapper like that in the shebang of grml-debootstrap, calling hostname
becomes an option. To avoid name conflicts, I would call the wrapper grml-deboostrap-uts-bash or so.
PS: Please note the "--" before "bash".
PS: Due to
$ unshare --uts -- bash
unshare: unshare failed: Operation not permitted
that wrapper should check for being root and exit with something helpful saying that grml-debootstrap needs root permissions, maybe. Should be easy to do.
Thanks for playing with this, looks like a possible solution for us then! We'd have to install the uts-bash script at a specific location though which is then used by the main grml-debootstrap script.
It would need to be somewhere in root's $PATH if you want to use #! /usr/bin/env grml-debootstrap-uts-bash
. Without env, it could be anywhere, e.g. #! /usr/.../grml-debootstrap-uts-bash
but it would be less flexibale with regard to the wrappers development.
I believe, as far as FHS is concerned, "internal binaries" is the keyword here and /usr/lib/
or /usr/lib/grml-dedebootstrap/
seem the locations of choice to me: http://www.pathname.com/fhs/pub/fhs-2.3.html#USRLIBLIBRARIESFORPROGRAMMINGANDPA .
ACK, /usr/lib/grml-debootstrap/
sounds good to me.
Alternatively, would temporarily (when you need networking) mounting of the host's /etc/resolv.conf
, /etc/hosts
, /etc/hostname
and /etc/network/interfaces
inside the chroot also solve this?
This is how it's done in @Whonix's build script. (chroot-raw)
mount --bind "$WHONIX_BINARY/system-files-backup/resolv.conf" "$CHROOT_FOLDER/etc/resolv.conf"
mount --bind "$WHONIX_BINARY/system-files-backup/hosts" "$CHROOT_FOLDER/etc/hosts"
mount --bind "$WHONIX_BINARY/system-files-backup/hostname" "$CHROOT_FOLDER/etc/hostname"
mount --bind "$WHONIX_BINARY/system-files-backup/interfaces" "$CHROOT_FOLDER/etc/network/interfaces"
(Using copies of the host's /etc/resolv.conf
etc. to prevent anything from within the host making modifications to the host's system files. Therefore no need to mount those read-only. Anything from within the chroot is free to write to these files with no risk.)
@adrelanos interesting approach, this is also similar to what docker does IIRC. Definitely worth a try!