5

When I had to repair my Debian system, I tried to use schroot due the convenience of not having to mount bind several partitions. But, contrary to my expectations, schroot decided to override my passwd file and other configuration files (in /etc and my home directory) which I didn't like (and sometimes causes weird messages). Is there a way to prevent that behavior?

I used the type directory for schroot, since it seemed the one I needed. I checked the man page and only found a --preserve-environment option, but from its description I'm not sure if it preserves the chrooted system environment or just copies my user environment to the chroot session instead of a clean slate (which is the default).

4

Schroot does a number of things to make the chrooted system usable. This job is performed by scripts in /etc/schroot/setup.d/. These actions are configured by files in the profile directory of the schroot, which is indicated by the profile key in the schroot configuration and defaults to /etc/schroot/default/ (the schroot configuration can also specify other file locations, see the manual for details). Startup actions include:

  • Mount some filesystems as indicated by the file fstab in the profile directory.
  • Copy files from the host system to the chroot. The list of files to copy is read from the file copyfiles from the profile directory.
  • Overwrite NSS databases in the chroot, read from the host. The list of databases to overwrite is read from the file nssdatabases from the profile directory. This is similar to copying files, but it doesn't just e.g. copy /etc/passwd into the chroot, it also retrieves entries from other sources such as NIS or LDAP.

By default, copyfiles contains /etc/resolv.conf, to ensure that programs in the chroot will have DNS access like those outside the chroot. The default chroot setup assumes that you want the same users inside and outside the chroot, so nssdatabases contains all the usual databases including passwd, and the default profile's fstab contains not only filesystems like /proc and /dev which are essential to the working of many programs, but also /home.

If you don't want to overwrite anything in the chroot, declare a schroot profile without copyfiles and nssdatabases. You'll probably want to have an fstab that mounts the essentials but not /home.

A more useful schroot configuration would reproduce the human user accounts and their home directories, but not the system accounts. Reproducing the system accounts is unfortunate because there may be different accounts inside and outside the chroot. For example, Debian and their derivatives use dynamically-assigned accounts for most system software, so the correspondence between username and number for most system accounts depends on the order in which programs were installed. To do that, remove passwd, shadow, group and gshadow from the nssdatabases file, and write your own script that adds only the accounts that should be copied.

You can write the following script as /etc/schroot/setup.d/20appendaccounts to copy only accounts in the real user range.

#!/bin/sh
## Append users and groups from the host.
set -e

. "$SETUP_DATA_DIR/common-data"
. "$SETUP_DATA_DIR/common-functions"
. "$SETUP_DATA_DIR/common-config"

if [ -z "$SETUP_NSSDATABASES" ] || ! [ -f "$SETUP_NSSDATABASES" ]; then
  exit 0
fi

DATABASES='group gshadow passwd shadow'

want () {
  grep -qx "#>>$1" "$SETUP_NSSDATABASES"
}

start () {
  sed -i -e '/^#begin added by schroot$/,/^#end added by schroot$/d' "$tmpfile"
  {
    echo '#begin added by schroot'
    getent "$db" | case $db in
      ## passwd, group: copy the range for local human accounts
      passwd) awk -F : "$FIRST_UID <= \$3 && \$3 <= $LAST_UID";;
      group) awk -F : "$FIRST_GID <= \$3 && \$3 <= $LAST_GID";;
      ## shadow, gshadow: copy only entries with a password hash
      shadow|gshadow) awk -F : '$2 ~ /^\$/';;
    esac
    echo '#end added by schroot'
  } >>"$tmpfile"
}

iterate () {
  for db in $DATABASES; do
    want "$db" || continue
    dbfile=$CHROOT_PATH/etc/$db
    tmpfile=$dbfile.$$
    [ -f "$dbfile" ] || continue
    cp -f -- "$dbfile" "$tmpfile"
    "$@"
    if ! [ -s "$tmpfile" ] || cmp -s -- "$dbfile" "$tmpfile"; then
      rm -f -- "$tmpfile"
    else
      mv -- "$tmpfile" "$dbfile"
    fi
  done
}

case $STAGE in
  setup-start|setup-recover)
    FIRST_UID=1000
    LAST_UID=29999
    FIRST_GID=1000
    LAST_GID=29999
    if [ -e /etc/adduser.conf ]; then . /etc/adduser.conf; fi
    umask 600
    iterate start;;
esac

Edit the nssdatabases file of your profile to contain the following lines, or put setup.nssdatabases=default/nssdatabases-append in the schroot profile and write the following lines to default/nssdatabases.

#>>passwd
#>>shadow
#>>group
#>>gshadow
services
protocols
networks
hosts

Schroot does not overwrite any file in your home directory in its default configuration. --preserve-environment is about environment variables and not relevant here.

  • I had some trouble with this: Initially I failed to set the comments in the nssdatabases correctly, which resulted in users/groups not getting created. Next, I expected it to resolve group differences between my host system and the chroot automatically; it only operates on groups over 1000. If cdroom is group 100 on your host, then you should change it to group 100 on your chroot (and chown any files as necessary), etc. – bobpaul Jul 18 '17 at 5:07
1

I created a second profile called foo; you could just make these to the default profile directly. Profiles are subdirectories of /etc/schroot/, e.g. /etc/schroot/foo/, /etc/schroot/default/.

diff -ruw default/fstab foo/fstab
--- default/fstab       2014-05-25 14:03:42.000000000 -0700
+++ foo/fstab   2014-04-03 16:36:42.644336952 -0700
@@ -7,7 +7,7 @@
 /sys            /sys            none    rw,bind         0       0
 /dev            /dev            none    rw,bind         0       0
 /dev/pts        /dev/pts        none    rw,bind         0       0
-/home           /home           none    rw,bind         0       0
+#/home           /home           none    rw,bind         0       0
 /tmp            /tmp            none    rw,bind         0       0

 # It may be desirable to have access to /run, especially if you wish
diff -ruw default/nssdatabases foo/nssdatabases
--- default/nssdatabases        2014-05-25 14:03:42.000000000 -0700
+++ foo/nssdatabases    2014-04-03 16:36:55.760398695 -0700
@@ -1,11 +1,11 @@
 # System databases to copy into the chroot from the host system.
 #
 # <database name>
-passwd
-shadow
-group
-gshadow
-services
-protocols
-networks
-hosts
+#passwd
+#shadow
+#group
+#gshadow
+#services
+#protocols
+#networks
+#hosts

/etc/default/copyfiles also exists, but I left that in there, since you usually do want /etc/resolv.conf to be copied.

  • @Braiam re: edit, that comment is part of the diff. – o11c Oct 11 '14 at 3:11
  • Ok, so you just suggest to disable them in the profile directories? Got it. – Braiam Oct 11 '14 at 3:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.