Container-Explorer is a tool to explore containerd installation on a mounted image.

Overview

Container-Explorer

Container-Explorer is a tool to explore containerd installation on a mounted image.

Container-Explorer attempts to provide the similar exploration functionalities provided by ctr utility.

Container-Explorer provides the following options:

  • Explore namespaces
  • Explore containers
  • Explore snapshots
  • Explore images
  • Explore contents
  • Mount container

Usage

Using Virtual Machine Image

Container-Explorer can explore an offline containerd by using a commandline switch --image-root that refers the location of mounted image containing containerd. The section below shows the container-explorer commands:

  1. Mount the image containing containerd
# sudo mount -o ro /mnt/tags/tag001 /mnt/cases/case001
  1. Run container-explorer commands to explore containers
# container-explorer --image-root /mnt/cases/case001 list namespaces
# container-explorer --image-root /mnt/cases/case001 list containers
# container-explorer --image-root /mnt/cases/case001 list snapshots
# container-explorer --image-root /mnt/cases/case001 list images
# container-explorer --image-root /mnt/cases/case001 list contents
  1. Identify the container that needs investigation. Note the container ID and namespace
# sudo container-explorer -n 
   
     --image-root /mnt/cases/case001 
    
      /mnt/container

    
   

NOTE: container-explorer assumes that mount point /mnt/container already exists.

  1. Perform analysis of the mounted container
  2. Unmount the mounted container
# sudo umount /mnt/container

Using containerd Directory

containerd uses /var/lib/containerd as the default directory. Analyst can copy /var/lib/containerd and use it for analysis.

The figure shows container-explorer commands to analyse a copied directory.

# container-explorer -c test_data/var/lib/containerd list namespaces
# container-explorer -n default -c test_data/var/lib/containerd mount nginx-demo /tmp/mnt/case01

Using bolt Databases

containerd stores information in bolt (https://pkg.go.dev/go.etcd.io/bbolt) database. containerd uses the following two databases:

  • /var/lib/containerd/io.containerd.metadata.v1.bolt/meta.db
  • /var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/metadata.db

Analyst can use the following container-explorer commands to explore containerd settings.

# container-explorer -m test_data/meta.db -s test_data/metadata.db list namespaces

Running Tests

The script run_test.sh runs container-explorer tests on sample containerd data generated by using containerd-specimens (https://github.com/dfirlabs/containerd-specimens).

  1. Clone container-explorer and containerd-specimens
$ git clone https://github.com/google/container-explorer
$ git clone https://github.com/dfirlabs/containerd-specimens
  1. Change directory to containerd-specimens
$ cd containerd-specimens
  1. Run generate-specimens.sh script to generate test data
$ sudo bash generate-specimens.sh

NOTE If the script generate-specimens.sh does not generate test data. You can run reset-containerd.sh to uninstall and install containerd package.

!!WARNING!!: reset-containerd.sh deletes existing containers. Please use carefully.

  1. Change directory to container-explorer
$ cd ../container-explorer
  1. Run container-explorer test script run_test.sh
$ sudo bash run_test.sh
You might also like...
Amazon ECS Container Agent: a component of Amazon Elastic Container Service
Amazon ECS Container Agent: a component of Amazon Elastic Container Service

Amazon ECS Container Agent The Amazon ECS Container Agent is a component of Amazon Elastic Container Service (Amazon ECS) and is responsible for manag

The Container Storage Interface (CSI) Driver for Fortress Block Storage This driver allows you to use Fortress Block Storage with your container orchestrator

fortress-csi The Container Storage Interface (CSI) Driver for Fortress Block Storage This driver allows you to use Fortress Block Storage with your co

Kubernetes workload controller for container image deployment

kube-image-deployer kube-image-deployer는 Docker Registry의 Image:Tag를 감시하는 Kubernetes Controller입니다. Keel과 유사하지만 단일 태그만 감시하며 더 간결하게 동작합니다. Container, I

Image clone controller is a kubernetes controller to safe guard against the risk of container images disappearing

Image clone controller image clone controller is a kubernetes controller to safe guard against the risk of container images disappearing from public r

Returns which registry from the container image name

Returns which registry from the container image name

Container image sweeper kube

container-image-sweeper-kube container-image-sweeper-kube は、不要になった Docker イメージを自

Undock - Extract contents of a container image in a local folder
Undock - Extract contents of a container image in a local folder

About Undock is a CLI application that allows you to extract contents of a conta

k8s-image-swapper Mirror images into your own registry and swap image references automatically.
k8s-image-swapper Mirror images into your own registry and swap image references automatically.

k8s-image-swapper Mirror images into your own registry and swap image references automatically. k8s-image-swapper is a mutating webhook for Kubernetes

This action prints "true" if image is required to update based on the base image update.

container-image-updater This action prints "true" if image is required to update based on the base image update. Inputs Name Type Description base-ima

Comments
  • Can't compile binary on a fresh Ubuntu bionic

    Can't compile binary on a fresh Ubuntu bionic

    There is probably some go relevant setup required in the README

    # go build -ldflags '-s -w' -o $HOME/container-explorer cmd/main.go
    cmd/main.go:22:2: cannot find package "github.com/google/container-explorer/cmd/commands" in any of:
            /usr/lib/go-1.10/src/github.com/google/container-explorer/cmd/commands (from $GOROOT)
            /home/user/go/src/github.com/google/container-explorer/cmd/commands (from $GOPATH)
    cmd/main.go:23:2: cannot find package "github.com/sirupsen/logrus" in any of:
            /usr/lib/go-1.10/src/github.com/sirupsen/logrus (from $GOROOT)
            /home/user/go/src/github.com/sirupsen/logrus (from $GOPATH)
    cmd/main.go:24:2: cannot find package "github.com/urfave/cli" in any of:
            /usr/lib/go-1.10/src/github.com/urfave/cli (from $GOROOT)
            /home/user/go/src/github.com/urfave/cli (from $GOPATH)
            ```
    opened by rgayon 2
  • mount uses the wrong order of lowerdirs for overlayfs

    mount uses the wrong order of lowerdirs for overlayfs

    Ahoi @roshanmaskey ! First of all: Thank your for your super cool tool! Came in really handy as i am currently working on a master thesis about Kubernetes forensics. :)

    I've evaluated your tool for post-mortem forensics by using an exported image from a saved virtual machine which is a worker node in a Kubernetes cluster, where i deployed a pod that pulls a specially crafted container that downloads two more files when active.

    When the container runs and DownloadFiles.sh has been executed, the directory /home/SampleFiles/ contains the following files:

    # ls -la /home/SampleFiles/
    total 8336
    drwxr-xr-x 1 root root    4096 Nov 17 17:59 .
    drwxr-xr-x 1 root root    4096 Nov 15 23:58 ..
    -rwxr-xr-x 1 root root    1089 Nov 15 23:50 DownloadFiles.sh
    -rwxr-xr-x 1 root root 2155399 Nov 15 21:09 File01.2MB.tmp
    -rwxr-xr-x 1 root root 2097180 Nov 15 21:09 File02.2MB.tmp
    -rw-r--r-- 1 root root 2155399 Nov 17 17:59 File03.2MB.tmp
    -rw-r--r-- 1 root root 2097180 Nov 17 17:59 File04.2MB.tmp
    

    The used image for the container is: docker.io/pr3l14t0r/forensics:craftedfiles

    I've now stumbled across a problem with the implementation of the container mount options.

    Context

    I can see the contents of that container by manually digging through the snapshotter fs directories by using Autopsy or whatever tool which is capable of parsing the exported disk image.

    Now i want to try to mount the container using your tool.

    This is how the mount options for the container look like when you run findmnt on the worker node when live:

    Target                                                                                                                                                        Source                 FSType     Options
    ------                                                                                                                                                        ------                 ------     -------
    /run/containerd/io.containerd.runtime.v2.task/k8s.io/2df8c9bf881593eea104ed0cce6234582aef7f26a13fdf034ca1fdd6abf60b46/rootfs                                  overlay                overlay    rw,relatime,lowerdir=/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/44/fs:/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/43/fs:/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/42/fs:/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/41/fs:/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/40/fs:/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/39/fs,upperdir=/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/45/fs,workdir=/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/45/work,xino=off
    

    Notice that the commited layers are mounted from last to first, so 44-39 being the lowerdirs and 45 being the upper- and work-dir reflecting the live file system mounted into the container.

    So.. the "lowest" lowerdir - the first layer of a container image - needs to be specified last in the lowerdir= parameter.

    The Issue

    When mounting this container with container-explorer, the following (debug) output is given:

    container-explorer --debug --image-root /tmp/investigation -n k8s.io mount 2df8c9bf881593eea104ed0cce6234582aef7f26a13fdf034ca1fdd6abf60b46 /mnt/container
    
    DEBU[0000] user mount command                            containerid=2df8c9bf881593eea104ed0cce6234582aef7f26a13fdf034ca1fdd6abf60b46 mountpoint=/mnt/container namespace=k8s.io
    DEBU[0000] container environment                         container-root=/var/lib/containerd image-root=/tmp/investigation manifest-file=
    DEBU[0000] updated metadata file                         path=/tmp/investigation/var/lib/containerd/io.containerd.metadata.v1.bolt/meta.db
    DEBU[0000] snapshot information for container 2df8c9bf881593eea104ed0cce6234582aef7f26a13fdf034ca1fdd6abf60b46  id=2df8c9bf881593eea104ed0cce6234582aef7f26a13fdf034ca1fdd6abf60b46 image="sha256:84e90d9540723be712a71a8ed21f082847b89f444d9c9c8a9d2696682d1f9848" snapshotkey=2df8c9bf881593eea104ed0cce6234582aef7f26a13fdf034ca1fdd6abf60b46 snapshotter=overlayfs
    DEBU[0000] container root directory                      path=/tmp/investigation/var/lib/containerd
    DEBU[0000] snapshotter root directory                    path=/tmp/investigation/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs
    DEBU[0000] snapshotter database file                     path=/tmp/investigation/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/metadata.db
    DEBU[0000] snapshotter root directory                    path=/tmp/investigation/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs
    DEBU[0000] overlay directories                           lowerdir="/tmp/investigation/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/39/fs:/tmp/investigation/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/40/fs:/tmp/investigation/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/41/fs:/tmp/investigation/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/42/fs:/tmp/investigation/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/43/fs:/tmp/investigation/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/44/fs" upperdir=/tmp/investigation/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/45/fs workdir=/tmp/investigation/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/45/work
    DEBU[0000] mount command options: [-t overlay overlay -o ro,lowerdir=/tmp/investigation/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/39/fs:/tmp/investigation/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/40/fs:/tmp/investigation/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/41/fs:/tmp/investigation/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/42/fs:/tmp/investigation/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/43/fs:/tmp/investigation/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/44/fs:/tmp/investigation/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/45/fs /mnt/container]
    [email protected]:/go#
    

    You see in the mount options that the fs directories are mounted as lowerdirs from 39-45, which is actually the wrong order. The first commited layer of an image would overwrite everything that the other layers are doing to it.

    This is proven by the follwing command:

    [email protected]:/go# ls -la /mnt/container/home/SampleFiles/
    total 8
    drwxr-xr-x 2 root root 4096 Nov 15 23:58 .
    drwxr-xr-x 1 root root 4096 Apr 15  2020 ..
    [email protected]:/go#
    

    The files shown above are not listed as they got deleted. They are present in layer 45 but not in 39, thus 39 will remove the files.

    Solution

    If you manually change the order in the mount command, everything is fine again:

    # create mountpoint
    mkdir /mnt/container
    
    # mount dirs
    mount -t overlay overlay -o ro,lowerdir=/tmp/investigation/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/45/fs:/tmp/investigation/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/44/fs:/tmp/investigation/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/43/fs:/tmp/investigation/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/42/fs:/tmp/investigation/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/41/fs:/tmp/investigation/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/40/fs:/tmp/investigation/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/39/fs /mnt/container
    
    # List mount directory
    ls -la /mnt/container/home/SampleFiles/
    
    total 8336
    drwxr-xr-x 1 root root    4096 Nov 17 17:59 .
    drwxr-xr-x 1 root root    4096 Nov 15 23:58 ..
    -rwxr-xr-x 1 root root    1089 Nov 15 23:50 DownloadFiles.sh
    -rwxr-xr-x 1 root root 2155399 Nov 15 21:09 File01.2MB.tmp
    -rwxr-xr-x 1 root root 2097180 Nov 15 21:09 File02.2MB.tmp
    -rw-r--r-- 1 root root 2155399 Nov 17 17:59 File03.2MB.tmp
    -rw-r--r-- 1 root root 2097180 Nov 17 17:59 File04.2MB.tmp
    

    So long story short: You need to reverse the order of lowerdirs that you pass to mount. :)

    Unfortunately i am not that skilled in Go and need the current time heavily to finish my thesis.. Otherwise i'd try to come up with a PR, so please have mercy.. :D

    Kind regards, pr3l14t0r

    PS: If needed i can export the /var/lib/containerd directory of my exported image for you to test. But you can reproduce this with any other "once deployed" container that has an image using multiple layers.

    opened by pr3l14t0r 2
Releases(0.0.5)
Owner
Google
Google ❤️ Open Source
Google
Repositório para a aula sobre integração do containerd com Golang

Integrando containers nativamente usando Golang Este é o código finalizado da aplicação Já pensou em uma alternativa ao Docker? Que tal manipular cont

Rocketseat Experts Club 3 May 4, 2021
Installs containerd on Windows, optionally with default CNI plugins

containerd-installer Installs containerd on Windows, optionally with default CNI plugins Usage NAME: containerd-installer.exe - Install containerd

Markus Lippert 14 Nov 27, 2022
Nydus-snapshotter - A containerd snapshotter with capability of on-demand read

Nydus Snapshotter Nydus-snapshotter is a non-core sub-project of containerd. Pul

containerd 53 Dec 14, 2022
Runwasi - A containerd shim which runs wasm workloads in wasmtime

containerd-shim-wasmtime-v1 This is a containerd shim which runs wasm workloads

Brian Goff 329 Dec 28, 2022
AWS Data Transfer Cost Explorer

The AWS Data Transfer Cost Explorer The AWS Data Transfer Cost Explorer tool analyzes the billed Data Transfer items in your AWS account and presents

Oğuzhan YILMAZ 90 Jul 18, 2022
Tree style (files) explorer for p9p acme.

xplor, a tree-style (file) explorer for (plan9port) Acme screenshot, regular screenshot, monospaced Xplor is written for Acme, the Plan 9 text editing

Shingirai Chanakira 0 Nov 25, 2021
A tool to restart a Docker container with a newer version of the image

repull A tool to restart a Docker container with a newer version of an image used by the container Often you may need to pull a newer version of an im

Eugene 25 Nov 28, 2022
Explore Docker registries and manipulate Docker images!

L/S tags Utility and API to manipulate (analyze, synchronize and aggregate) images across different Docker registries. Example invocation $ lstags alp

Ivan Ilves 302 Nov 25, 2022
Moby Project - a collaborative project for the container ecosystem to assemble container-based systems

The Moby Project Moby is an open-source project created by Docker to enable and accelerate software containerization. It provides a "Lego set" of tool

Moby 64.9k Jan 8, 2023
Boxygen is a container as code framework that allows you to build container images from code

Boxygen is a container as code framework that allows you to build container images from code, allowing integration of container image builds into other tooling such as servers or CLI tooling.

nitric 5 Dec 13, 2021