crashcart
is a simple command line utility that lets you sideload an image
with linux binaries into an existing container.
Building can be done via nix:
nix build -f ./nixpkgs.nix crashcart
To put crashcart on path:
nix run -f ./nixpkgs.nix crashcart
Image build dependencies:
sudo
nix
docker
crashcart
will load binaries from an image file into a running container. To
build the image, you just need docker installed and then you can use
build_image.sh
:
build_image.sh
The build image script will build a crashcart_builder
image using the
nix image defined in the builder directory. It will then run this builder as a
privileged container. It needs to be privileged because the image is created by
loopback mounting an ext3 filesystem and copying files in. It may be possible
to do this without root privileges using something like e2tools, but this has
yet to be tested.
The crashcart_builder
will take a very long time the first time it is run.
The relocated binaries are built from source via the nix package manager. To prevent
binary collisions, the toolchain is built under a non standard prefix. As a result
nix cannot exploit any upstream build caches. Later builds should go much more quickly
because the nix store is cached in a in the vol directory and bind mounted into the builder.
To add to the list of packages in the resulting image, simply extend the buildEnv in vol/tools.nix
.
To run a command from the crashcart
image, pass the full path:
sudo ./crashcart $PID /dev/crashcart/bin/tcpdump
Where PID is the process ID of the container. You can retrieve the PID by running docker inspect -f "{{.State.Pid}}" `
To manually mount the crashcart
image into a container, use the -m flag.
sudo ./crashcart -m $PID
To manually unmount the crashcart
image from a container, use the -u flag.
sudo ./crashcart -u $PID
Once you have manually mounted the image, you can use docker exec
or
nsenter
to run things inside the container. crashcart
locates its binaries
in /dev/crashcart/bin
or /dev/crashcart/sbin
. To execute
tcpdump
for example, you can use (assuming you have added it to the buildEnv
):
docker exec -it $CONTAINER_ID /dev/crashcart/bin/tcpdump
crashcart
leaves the image mounted as a loopback device. If there are no
containers still using the crashcart
image, you can remove the device as
follows:
sudo losetup -d `readlink crashcart.img.lnk`; sudo rm crashcart.img.lnk
crashcart
doesn't work with user namespaces prior to kernel 4.8. In earlier
versions of the kernel, when you attempt to mount a device inside a mount
namespace that is a child of a user namespace, the kernel returns EPERM. The
logic was changed in 4.8 so that it is possible as long as the caller of mount
is in the init userns.
crashcart
is dual licensed under the Universal Permissive License 1.0 and the
Apache License 2.0.
See LICENSE for more details.