[sf-lug] chroot(2): Re: Sandboxing Zoom (etc.)

Michael Paoli Michael.Paoli at cal.berkeley.edu
Fri Jun 12 01:50:54 PDT 2020


> From: "Akkana Peck" <akkana at shallowsky.com>
> Subject: Re: [sf-lug] Sandboxing Zoom (etc.)
> Date: Thu, 11 Jun 2020 10:54:42 -0600

> I haven't had much luck setting up chroot environments by hand.
> I always fall down a "just one more library" rabbit hole and after
> a couple of hours of "I just need one more library" and I still
> can't run anything, I give up. Are there programs that can help
> set them up?

Yeah, setting up a secure - and generally pretty minimal (to be
secure) chroot environment can be rather to quite non-trivial.
It's generally much easier when doing it for a program that was
purpose built to be able to run chroot - but even then, not uncommon
to bump into at least some minor "gottchas".

So, BIND9 ... very chroot capable - even has option to support it, etc.
And ... when going from Debian 9 to Debian 10 - and bit of version
upgrade on BIND9 too ... did my older chroot setup for BIND work?
Almost but not quite.
I had to add one more thing under my chroot for the newer
BIND9 version ... Let's see, ah ...
Also, additionally for Debian 10 Buster, /usr/share/dns is also needed  
under the chroot
https://wiki.debian.org/Bind9#Bind_Chroot
So, for BIND9, in addition to its various configuration and
data files, state tracking, etc. that it needs under chroot,
it also needs these files:
/dev/null
/dev/random
Tools to help set up such chroot stuff?  I typically start minimal,
and see what breaks.  Often it's hard to "see", though.  E.g. I
remember many moons ago ... NCSA web server ... soon "everybody" thought
they could write a web server too.  Including Oracle.  And, knowing
often how grossly insecure Oracle was (most notably if anyone ever
stepped beyond/outside their database itself), when we had reason to
use - or at least investigate using and running an Oracle web server,
I (and my boss agreed) - uhm, yeah, we're gonna lock that puppy down
hard in a chroot.  If that works, then *maybe* ...
So, went about that task.  It was very annoying, as often it would
just outright fail, with no clues to stdout, stderr, logs, etc.
Eventually used truss(1).  I think the last thing I found that it
was attempting to use (because it was missing from the chroot) and
failed quite immediately after, was /dev/zero - or some other
dev file like that.  Got that last one added to the
chroot ... and then finally had it working.
Well, nowadays, Linux ... strace(1).  Mostly look at what it
tries to {stat,lstat,open,access,...}(2) and fails - most especially
where same exists outside of the chroot, and often what it fails
to access immediately, or rather to quite close in sequence, just
prior to it failing.   Not exactly high-level elegant tool,
but it'll generally work quite well enough (and applied
iteratively) to get the job done.  Also, ldd(1) is very handy.
Once upon a time I had (probably still have somewhere) program I wrote
that would use ldd(1) to not only chase down dependencies, but to
recursively chase down all those (library) dependencies (and
related symbolic links and such).  I wasn't so much using it for
chroot, but making customized recovery environments - typically
there'd be some utilities I'd want to add to the general distro
recovery environments ... e.g. like some important SCSI tape
related command(s) for dealing with doing recovery/restore
from tape.  I likewise remember once upon a time, SCO Xenix/Unix,
notably lacking from recovery environment was the date(1) command,
so there way no way to set the system time - and get correct ctimes
when doing a restore - without it - so I added date(1) and its
dependencies, to my recovery environment media.  In any case,
such would also be useful for chroot.

>> And one thing many folks far too often get wrong.
>> chroot and the like were *never* intended to secure processes
>> running as root (superuser, UID 0).  There are far too many ways
>> UID 0 can relatively easily punch out of chroot restrictions
>
> Interesting. I don't think it applies to the Zoom case but it's
> good to know.

Yeah, there are some other security "gottchas" for chroot too.
There, at least in general, are *some* files that should "always" -
or at least almost always - be present in chroot.  Namely because
some libraries and/or utilities, etc. may do some not-so-secure things
(or default to such) if the files are missing.  E.g. a secure minimal
hardened /etc/passwd, and /etc/group ... probably the corresponding
shadow files too - likewise minimized and hardened.  E.g. a
minimized hardened /etc/passwd file for chroot might contain
only and exactly:
root:x:0:0:root:/root:
and have perms/ownerships:
$ ls -nd /etc/passwd
-r--r--r-- 1 0 0 23 Jun 11 19:23 /etc/passwd
$
And /etc/shadow may have only:
root:!*:::::::
And ownership and perms 0:0 400.

Hmmm, ... I'm curious, haven't done it in a while :-) ... let me run
the exercise ... set up a quite minimal chroot - see how little I
need actually put in it for it to function.
Let's have nothing more than ls(1) and sh(1) in it ... where sh(1) is
dash(1), as it typically is on Debian (helluva lot less cruft to drag
in than for bash(1)).  Let me see what that takes.  And, I'll do it
on Debian stable (amd64).

I'll make a separate filesystem for it (can clamp down on mount perms),
rw for now - can make it ro later ... can also later shrink to
remove excess unneeded space.  And, for this exercise, I'll skip
adding all the "should also be in there to be secure" bits - I'll
leave that as a, uh, "exercise for the reader".  ;-)
And I will do the bits to change to a non-root UID and unprivileged
group, so it ought be dang near impossible to bust out of the
chroot.  "Of course" there are additional security things that can
be layered atop it, but let's see what going at least this far takes.

$ lsb_release -d && cat /etc/debian_version && uname -m
Description:    Debian GNU/Linux 10 (buster)
10.4
x86_64
$

# lvcreate -l 25 -n chroot balug
   Logical volume "chroot" created.
#

To eventually be ro and small,
so don't care about journaling or reserved blocks:

# mkfs -t ext2 /dev/balug/chroot
# tune2fs -L chroot -r 0 /dev/balug/chroot
#

May place it elsewhere later, when mounted ro, for "real", but for now:
# mktemp -d /var/tmp/tmp.XXXXXXXXXX
/var/tmp/tmp.ZQq3GndBFh
# chmod u=rwx,go=rx /var/tmp/tmp.ZQq3GndBFh
# mount -o nosuid,nodev /dev/balug/chroot /var/tmp/tmp.ZQq3GndBFh
#

For fresh installs of Debian stable, these might be under /usr/bin,
rather than /bin (this one was upgraded), but in any case ...
$ (cd /bin && pwd -P && ls -ld ls sh dash)
/bin
-rwxr-xr-x 1 root root 121464 Jan 17  2019 dash
-rwxr-xr-x 1 root root 138856 Feb 28  2019 ls
lrwxrwxrwx 1 root root      4 Jan 17  2019 sh -> dash
$

Throughout, we'll generally go, as feasible, with most restrictive
permissions, etc. (least privilege principle).

Also, we don't want the root of our new filesystem to be the
chroot - as that would expose lost+found, so we'll create a directory
one more layer down.

And here, leading "> " is generally PS1 shown, not entered

# cd /var/tmp/tmp.ZQq3GndBFh && umask 022 && mkdir chroot && cd chroot
# mkdir bin && umask 0666 && (cd bin && { >ls && >dash && ln -s dash sh
> })
# (cd /bin && ls -ld ls *sh)
---------- 1 root root 0 Jun 12 05:21 dash
---------- 1 root root 0 Jun 12 05:21 ls
lrwxrwxrwx 1 root root 4 Jun 12 05:21 sh -> dash
# (cd /bin && chmod a+x dash ls && ls -ld dash ls)
---x--x--x 1 root root 0 Jun 12 05:21 dash
---x--x--x 1 root root 0 Jun 12 05:21 ls
# umask 022
#

$ ldd /bin/dash /bin/ls | sed -e 's/ (.*$//'
/bin/dash:
         linux-vdso.so.1
         libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6
         /lib64/ld-linux-x86-64.so.2
/bin/ls:
         linux-vdso.so.1
         libselinux.so.1 => /lib/x86_64-linux-gnu/libselinux.so.1
         libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6
         libpcre.so.3 => /lib/x86_64-linux-gnu/libpcre.so.3
         libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2
         /lib64/ld-linux-x86-64.so.2
         libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0
$

$ ldd /lib/x86_64-linux-gnu/libc.so.6 /lib/x86_64-linux-gnu/libdl.so.2 \
> /lib/x86_64-linux-gnu/libpcre.so.3 \
> /lib/x86_64-linux-gnu/libpthread.so.0 \
> /lib/x86_64-linux-gnu/libselinux.so.1 /lib64/ld-linux-x86-64.so.2 |
> sed -e 's/ (.*$//' | sort -u | sed -e '/^\/.*:$/d' | fgrep /
         /lib64/ld-linux-x86-64.so.2
         libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6
         libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2
         libpcre.so.3 => /lib/x86_64-linux-gnu/libpcre.so.3
         libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0
$

$ find /lib/x86_64-linux-gnu/libc.so.6 \
> /lib/x86_64-linux-gnu/libdl.so.2 /lib/x86_64-linux-gnu/libpcre.so.3 \
> /lib/x86_64-linux-gnu/libpthread.so.0 \
> /lib/x86_64-linux-gnu/libselinux.so.1 /lib64/ld-linux-x86-64.so.2 \
> -prune -type l -print -exec readlink \{\} \;
/lib/x86_64-linux-gnu/libc.so.6
libc-2.28.so
/lib/x86_64-linux-gnu/libdl.so.2
libdl-2.28.so
/lib/x86_64-linux-gnu/libpcre.so.3
libpcre.so.3.13.3
/lib/x86_64-linux-gnu/libpthread.so.0
libpthread-2.28.so
/lib64/ld-linux-x86-64.so.2
/lib/x86_64-linux-gnu/ld-2.28.so
$

$ find /lib/x86_64-linux-gnu/libc-2.28.so \
> /lib/x86_64-linux-gnu/libdl-2.28.so \
> /lib/x86_64-linux-gnu/libpcre.so.3.13.3 \
> /lib/x86_64-linux-gnu/libpthread-2.28.so \
> /lib/x86_64-linux-gnu/ld-2.28.so -prune -type l -print -exec \
> readlink \{\} \;
$

# (cd / && umask 0666 && find bin/dash bin/ls \
> lib/x86_64-linux-gnu/ld-2.28.so lib/x86_64-linux-gnu/libc-2.28.so \
> lib/x86_64-linux-gnu/libc.so.6 lib/x86_64-linux-gnu/libdl-2.28.so \
> lib/x86_64-linux-gnu/libdl.so.2 lib/x86_64-linux-gnu/libpcre.so.3 \
> lib/x86_64-linux-gnu/libpcre.so.3.13.3 \
> lib/x86_64-linux-gnu/libpthread-2.28.so \
> lib/x86_64-linux-gnu/libpthread.so.0 \
> lib/x86_64-linux-gnu/libselinux.so.1 lib64/ld-linux-x86-64.so.2 \
> -prune -print0 | pax -rw -0d /var/tmp/tmp.ZQq3GndBFh/chroot/)
#

Let's review and adjust permissions:
# find . -exec ls -ld \{\} \; | awk '{print $1;}' | sort -u
----------
---x--x--x
d--x--x--x
drwxr-xr-x
lrwxrwxrwx
# find . -type f ! -type l -perm 0 -exec chmod a+x \{\} \;

I forget, do the binary libraries need only r, but not x?
Let's do both for the moment, and adjust later.
# find lib -type f ! -type l -exec chmod a+rx \{\} \;

We'll want a relatively minimal /etc/passwd and /etc/group,
but let's put a teensy bit more in, so ls will be able to lookup
some data for our target user and group memberships (otherwise ls -l and
-o options without -n will just give numeric UID/GID).

# su - mpaoli -c id
uid=1607(mpaoli) gid=1607(mpaoli) groups=1607(mpaoli)
# vi etc/passwd

$ more etc/* | cat
::::::::::::::
etc/group
::::::::::::::
root:x:0:
mpaoli:x:1607:
::::::::::::::
etc/passwd
::::::::::::::
root:x:0:0::/:
mpaoli:x:1607:1607::/:
$

Let's see if we have enough in place to test it out.
We want to do the chroot, then drop to our target user.
Since we don't have su or sudo in our chroot,
we'll see if we can leverage perl's internals to do this and
to exec our chrooted shell.

# env - HOME=/ perl -e '$^W=1; use strict;
> chroot(q(/var/tmp/tmp.ZQq3GndBFh/chroot));
> ($(,$))=(1607,q(1607 1607)); ($<,$>)=(1607,1607);
> exec {q(/bin/sh)} (q(-sh));'
$ ls -al /etc
total 4
drwxr-xr-x 2 0 0 1024 Jun 12 06:08 .
drwxr-xr-x 6 0 0 1024 Jun 12 06:25 ..
-rw-r--r-- 1 0 0   25 Jun 12 06:08 group
-rw-r--r-- 1 0 0   38 Jun 12 06:09 passwd
$

And, that's enough that it (mostly) works!  "Of course" we haven't fully
secured it ... yet.

Let's tighten the screws ...

Binary libraries mostly need only r, but not x

# find lib* -type f -exec chmod a=r \{\} \;

A bit too tight, fails now.

divide & conquer ...
the just right minimal perms on the library files:
# find lib -type f -exec ls -dln \{\} \;
-r--r--r-- 1 0 0 14592 May  1  2019 lib/x86_64-linux-gnu/libdl-2.28.so
-r--r--r-- 1 0 0 1824496 May  1  2019 lib/x86_64-linux-gnu/libc-2.28.so
-r--r--r-- 1 0 0 146968 May  1  2019 lib/x86_64-linux-gnu/libpthread-2.28.so
---x--x--x 1 0 0 165632 May  1  2019 lib/x86_64-linux-gnu/ld-2.28.so
-r--r--r-- 1 0 0 155296 Jun 29  2018 lib/x86_64-linux-gnu/libselinux.so.1
-r--r--r-- 1 0 0 468944 Mar  7  2019 lib/x86_64-linux-gnu/libpcre.so.3.13.3
#

# chmod a=r etc/*
# chmod a=rx etc bin .

We don't "really" need r on directories, but without it, ls, and shell
*, etc. won't be able to determine contents except by being given an
explicit match (no wildcards or reading).  So we'll leave r on just
those 3 directories - for demonstration purposes (and so ls and such can
do a wee bit more there).

Let's clamp down on our top chroot dir, so only the group (and
superuser) can get in there, that group having no other members other
than our target user, and our target user not being given ownership of
the directory or anything under the chroot, won't be able to change
those perms - but will restrict (via group) to only that user (and
superuser) from getting in there.
# chgrp mpaoli . && chmod o= .; ls -ld .; ls -ldn .
dr-xr-x--- 6 root mpaoli 1024 Jun 12 06:25 .
dr-xr-x--- 6 0 1607 1024 Jun 12 06:25 .
#

Retesting the chroot - mostly works, but ls isn't mapping GID to group
name even where it's in /etc/group.  Likewise for UID mapping.
Maybe we need /etc/nsswitch.conf or the like?

Let's see if strace(1) will give us a hint.
[pid  1677] openat(AT_FDCWD, "/etc/nsswitch.conf", O_RDONLY|O_CLOEXEC)  
= -1 ENOENT (No such file or directory)
Maybe I guessed well ... let's try a minimal /etc/nsswitch.conf, then
see if that suffices.

$ ls -ld etc/nsswitch.conf && cat etc/nsswitch.conf
-r--r--r-- 1 root root 44 Jun 12 07:10 etc/nsswitch.conf
passwd:         files
group:          files
$

Nope, that doesn't suffice.  I can see from the strace there's lots
of stuff it attempts to access that fails - due to it not being there.
But, what does it actually *need*?

Of all the stuff it tries to access that fails (and ignoring sockets and
the like - just guessing those don't matter here) ... quite a list ...
but then filter it to only those that exist outside the chroot, and
we have only:
/etc/ld.so.cache
/etc/localtime
/lib/x86_64-linux-gnu/libnss_files.so.2
/proc/filesystems
/proc/mounts
/usr/lib
/usr/lib/x86_64-linux-gnu
So, I'm guessing:
/lib/x86_64-linux-gnu/libnss_files.so.2
both because of name, and also it's the first thing tried right after
opening /etc/nsswitch.conf

$ ldd /lib/x86_64-linux-gnu/libnss_files.so.2 | sed -e 's/ (.*$//'
         linux-vdso.so.1
         libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6
         /lib64/ld-linux-x86-64.so.2
$ readlink /lib/x86_64-linux-gnu/libnss_files.so.2
libnss_files-2.28.so
$ ls -ld /lib/x86_64-linux-gnu/libnss_files-2.28.so
-rw-r--r-- 1 root root 55792 May  1  2019  
/lib/x86_64-linux-gnu/libnss_files-2.28.so
$

# (cd /lib/x86_64-linux-gnu/ && find libnss_files.so.2 \
> libnss_files-2.28.so -prune -print0 | pax -rw -0d \
> /var/tmp/tmp.ZQq3GndBFh/chroot/lib/x86_64-linux-gnu/)
# chmod a=r lib/x86_64-linux-gnu/libnss_files-2.28.so

And now it works!

Let's harden our mount and put it somewhere more appropriate,
then retest.
# cd && umount /var/tmp/tmp.ZQq3GndBFh && rm -rf /var/tmp/tmp.ZQq3GndBFh
# (umask 022 && mkdir /usr/local/chroot)
# mount -o nosuid,nodev,ro,noatime /dev/balug/chroot /usr/local/chroot
# cd /

And retesting ...
not sure what the
sh: 0: getcwd() failed: No such file or directory
glitch is caused by ...
... but an explicit chdir before the exec seems to clear that issue
# (cd / && env - HOME=/ perl -e '$^W=1; use strict;
> chroot(q(/usr/local/chroot/chroot)); ($(,$))=(1607,q(1607 1607));
> ($<,$>)=(1607,1607); exec {q(/bin/sh)} (q(-sh));')
sh: 0: getcwd() failed: No such file or directory
$ exit
# (cd / && env - HOME=/ perl -e '$^W=1; use strict;
> chroot(q(/usr/local/chroot/chroot)); ($(,$))=(1607,q(1607 1607));
> ($<,$>)=(1607,1607); chdir(q(/)); exec {q(/bin/sh)} (q(-sh));')
$ ls -ld / /file /etc/*
dr-xr-x--- 6 root   mpaoli 1024 Jun 12 07:47 /
-r--r--r-- 1 root   root     25 Jun 12 06:08 /etc/group
-r--r--r-- 1 root   root     44 Jun 12 07:10 /etc/nsswitch.conf
-r--r--r-- 1 root   root     38 Jun 12 06:09 /etc/passwd
-rw-r--r-- 1 mpaoli mpaoli    0 Jun 12 07:01 /file
$

Well, okay, our target user owns only and exactly one file under the
chroot.  I put that one there mostly just to test the UID to name
mapping functionality of ls, and for other than just 0 (root).

$ ls -al /
total 6
dr-xr-x--- 6 root   mpaoli 1024 Jun 12 07:47 .
dr-xr-x--- 6 root   mpaoli 1024 Jun 12 07:47 ..
dr-xr-xr-x 2 root   root   1024 Jun 12 06:25 bin
dr-xr-xr-x 2 root   root   1024 Jun 12 07:09 etc
-rw-r--r-- 1 mpaoli mpaoli    0 Jun 12 07:01 file
d--x--x--x 3 root   root   1024 Jun 12 05:56 lib
d--x--x--x 2 root   root   1024 Jun 12 05:56 lib64
$ cd lib
$ ls
ls: cannot open directory '.': Permission denied
$ cd x86_64-linux-gnu
$ ls
ls: cannot open directory '.': Permission denied
$ ls -ld ld-2.28.so libc-2.28.so libc.so.6 libdl-2.28.so libdl.so.2 \
> libnss_files-2.28.so libnss_files.so.2 libpcre.so.3 \
> libpcre.so.3.13.3 libpthread-2.28.so libpthread.so.0 libselinux.so.1
---x--x--x 1 root root  165632 May  1  2019 ld-2.28.so
-r--r--r-- 1 root root 1824496 May  1  2019 libc-2.28.so
lrwxrwxrwx 1 root root      12 May  1  2019 libc.so.6 -> libc-2.28.so
-r--r--r-- 1 root root   14592 May  1  2019 libdl-2.28.so
lrwxrwxrwx 1 root root      13 May  1  2019 libdl.so.2 -> libdl-2.28.so
-r--r--r-- 1 root root   55792 May  1  2019 libnss_files-2.28.so
lrwxrwxrwx 1 root root      20 May  1  2019 libnss_files.so.2 ->  
libnss_files-2.28.so
lrwxrwxrwx 1 root root      17 Mar  7  2019 libpcre.so.3 -> libpcre.so.3.13.3
-r--r--r-- 1 root root  468944 Mar  7  2019 libpcre.so.3.13.3
-r--r--r-- 1 root root  146968 May  1  2019 libpthread-2.28.so
lrwxrwxrwx 1 root root      18 May  1  2019 libpthread.so.0 ->  
libpthread-2.28.so
-r--r--r-- 1 root root  155296 Jun 29  2018 libselinux.so.1
$ exit
#

And, what have we for permissions and such in our chroot?
# cd /usr/local/chroot/chroot
# find . ! -type l -exec ls -ld \{\} \; | sort
---x--x--x 1 root root 121464 Jan 17  2019 ./bin/dash
---x--x--x 1 root root 138856 Feb 28  2019 ./bin/ls
---x--x--x 1 root root 165632 May  1  2019 ./lib/x86_64-linux-gnu/ld-2.28.so
-r--r--r-- 1 root root 14592 May  1  2019 ./lib/x86_64-linux-gnu/libdl-2.28.so
-r--r--r-- 1 root root 146968 May  1  2019  
./lib/x86_64-linux-gnu/libpthread-2.28.so
-r--r--r-- 1 root root 155296 Jun 29  2018  
./lib/x86_64-linux-gnu/libselinux.so.1
-r--r--r-- 1 root root 1824496 May  1  2019  
./lib/x86_64-linux-gnu/libc-2.28.so
-r--r--r-- 1 root root 25 Jun 12 06:08 ./etc/group
-r--r--r-- 1 root root 38 Jun 12 06:09 ./etc/passwd
-r--r--r-- 1 root root 44 Jun 12 07:10 ./etc/nsswitch.conf
-r--r--r-- 1 root root 468944 Mar  7  2019  
./lib/x86_64-linux-gnu/libpcre.so.3.13.3
-r--r--r-- 1 root root 55792 May  1  2019  
./lib/x86_64-linux-gnu/libnss_files-2.28.so
-rw-r--r-- 1 mpaoli mpaoli 0 Jun 12 07:01 ./file
d--x--x--x 2 root root 1024 Jun 12 05:56 ./lib64
d--x--x--x 2 root root 1024 Jun 12 07:28 ./lib/x86_64-linux-gnu
d--x--x--x 3 root root 1024 Jun 12 05:56 ./lib
dr-xr-x--- 6 root mpaoli 1024 Jun 12 07:47 .
dr-xr-xr-x 2 root root 1024 Jun 12 06:25 ./bin
dr-xr-xr-x 2 root root 1024 Jun 12 07:09 ./etc
# find . -type l -print -exec readlink \{\} \; |
> sed -ne '/^\.\//h;/^\.\//!{H;x;s/\n/ -> /;p}'
./bin/sh -> dash
./lib/x86_64-linux-gnu/libc.so.6 -> libc-2.28.so
./lib/x86_64-linux-gnu/libdl.so.2 -> libdl-2.28.so
./lib/x86_64-linux-gnu/libpthread.so.0 -> libpthread-2.28.so
./lib/x86_64-linux-gnu/libpcre.so.3 -> libpcre.so.3.13.3
./lib/x86_64-linux-gnu/libnss_files.so.2 -> libnss_files-2.28.so
./lib64/ld-linux-x86-64.so.2 -> /lib/x86_64-linux-gnu/ld-2.28.so
# find . -type l \( ! -user 0 -o ! -group 0 \) -print
#

And one can also see from the above, all the symbolic links are 0:0
(root:root) ownerships.  And, permissions on symbolic links don't
matter, so I didn't show those.

So, yes, doable, but can be nontrivial bit of work.  Probably easier
if there are(?) some nice tools to automagically handle most or
all of that ... perhaps there are (likely), and there certainly
are tools for doing various bundling and packaging for running
under chroot(2), etc. ... not sure if there are also (good) tools
to minimize permissions and such and what actually gets placed
under the chroot(2).

And, ldd(1) and strace(1) come in quite handy for determining what's
needed and/or why it doesn't (quite) work.




More information about the sf-lug mailing list