This is the user guide for working with Confine. A more detailed step-by-step tutorial can be found here.
NOTE: It is assumed that the Installation Guide has been followed.
There are four main sections in this guide:
Confine generates Seccomp profiles which can be used in launching Docker containers. In this section, we will show the basics of running and killing containers. All Docker commands should be run as root, so we will be using sudo.
1. View list of containers:
sudo docker container ls -a
The output will show a list of containers both running and killed. The format is as follows:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2. Let's launch a container with the default Seccomp policy. The format of the command format is: sudo docker run --name [any-name] -td [docker-image-name].
sudo docker run --name test1 -td nginx
3. Now let's view the list of containers again:
sudo docker container ls -a
The output will show a list of containers both running and killed. The format is as follows:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES [long hash] nginx "/docker-entrypoint.…" 2 seconds ago Up 1 second 80/tcp test1
4. If we try to launch another container with the same name we will get an error from Docker. So each container should have a unique name. Run the following command:
sudo docker run --name test1 -td nginx
You should get an error with the following format:
docker: Error response from daemon: Conflict. The container name "/test1" is already in use by container "[long hash]". You have to remove (or rename) that container to be able to reuse that name.
5. Now we will kill the previously launched container.
sudo docker kill test1
6. Let's view the list of containers again.
sudo docker container ls -a
The output should be as follows:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES [long hash] nginx "/docker-entrypoint.…" [x] minutes ago Exited(137) seconds ago 80/tcp test1
7. Now we will delete the previously launched container.
sudo docker rm test1
8. Run a container with a custom Seccomp profile. sudo docker run --name [any-name] --security-opt seccomp=[path-to-seccomp-profile] -td [docker-image-name]
sudo docker run --name container-hardened --security-opt seccomp=results/nginx.seccomp.json -td nginx
9. Connect to a running container instance and launch bash/sh/. sudo docker exec -it [container-name] [any-shell]
sudo docker exec -it nginx-container /bin/bash
10. Extract IP address of running container: sudo docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' [container-name]
sudo docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' nginx-container
The main script in this repo is the confine.py file which uses previously created call graphs for musl-libc and glibc, along with a list of images and creates respective Seccomp profiles for each.
-l: glibc callgraph -m: musl-libc callgraph -i: input file containing JSON of images (more details provided below) -o: path to store binaries and libraries extracted from container -p: path to Docker default seccomp profile -r: path to store results (seccomp profiles created) -g: path to special cases containers like golang ones (more details provided below) -d: debugging enabled or disabled --skip: [Optional] In case you set this option, the script will not run the analysis for previously run images which have their results inserted into the profile.results.csv file. -f: [Optional] glibc shared object -n: [Optional] musl-libc shared object --finegrain: [Optional] Passing this argument enables the fine grained policy generation. Using this feature is not advised, since it is under development. --othercfgfolder: [Optional] In case you enable the fine grained analysis through setting --finegrain, you must set this option as well. This folder should contain the call graph for the other libraries used in the fine grained analysis. --allbinaries: [Optional] Passing this argument causes the extraction of all binaries instead of only the ones run during the 30 seconds. This would cause an extremely more conservative filter.
Change your current working directory to the root of the respository (/home/ubuntu/confine).
cd /home/ubuntu/confine
Execute the main script to generate Seccomp profiles for the enabled images.
sudo python3.7 confine.py -l libc-callgraphs/glibc.callgraph -m libc-callgraphs/musllibc.callgraph -i images.json -o output/ -p default.seccomp.json -r results/ -g go.syscalls/
The JSON input file has the following format:
{ "nginx": { "enable": "false", "image-name": "nginx", "image-url": "nginx", "category": [ "ApplicationInfrastructure" ], "options": "", "args": "", "dependencies": {} } }
Note:
The only keys which are required for any item in the JSON file are
enable, image-name
and image-url. The rest are optional. Some Docker images
need a set of options to run correctly. Such as passing configuration options
or setting environment variables. Docker supports two types of arguments, one
is for options which are used by Docker and
the other is args which are
arguments passed directly to the application running in the container.
For example the MySQL Docker
image must be run with the options below:
-e MYSQL_ROOT_PASSWORD=my-secret-pw
These options are typically specified in the image page on
Docker Hub.