An OCI runtime wrapper that modifies containers' runtime configuration according to specified rules before forwarding the container to a real runtime for creation.
This can be used to enforce certain policies on created containers, or to work around limitations in higher-level container management tools such as Docker.
Download the latest release, extract the tarball, and copy the binary to an appropriate location:
$ tar xzf oci-interceptor_x86_64-unknown-linux-gnu.tar.gz
$ cp oci-interceptor /usr/local/binAlternatively, build and install from source:
$ cargo install --locked --path .Currently, prebuilt binaries are only available for x86 Linux (glibc-based). Other platforms must installed from source.
All oci-interceptor flags are prefixed with --oi in order to avoid conflicts with the underlying OCI runtime.
Usage: oci-interceptor [OPTIONS] [runtime-options]...
Arguments:
[runtime-options]... All additional options will be forwarded to the OCI runtime.
Options:
--oi-runtime-path <runtime-path>
Path to OCI runtime. [default: runc]
--oi-readonly-networking-mounts
Mount networking files as readonly
--oi-write-debug-output
Write debug output
--oi-debug-output-dir <debug-output-dir>
Debug output location [default: /var/log/oci-interceptor]
--oi-env <NAME=VALUE>
Set an environment variable if not already present in config
--oi-env-force <NAME=VALUE>
Override an environment variable, regardless of any original value
--oi-version
Print version
--oi-help
Print help
The Docker daemon
configuration
must be modified to add this runtime. If you want it to be invoked every time a container is
created, you should also make it the default runtime (instead of runc).
If you are not using an alternative OCI runtime such as crun or youki, you can omit the --oi-runtime-path
option, as it defaults to runc, the default runtime bundled with Docker.
{
"default-runtime": "oci-interceptor",
"runtimes": {
"oci-interceptor": {
"path": "/usr/local/bin/oci-interceptor",
"runtimeArgs": [
"--oi-readonly-networking-mounts"
]
}
}
}The Docker daemon must be restarted (systemctl restart docker.service) in order to apply changes to this configuration file.
Note that if you set oci-interceptor as the default runtime, you can still bypass it for a specific container by specifying docker run --runtime=runc.
While it is not possible to override runtimeArgs with a docker run option, you could specify multiple interceptor "runtimes" (with different flags) and switch between them using docker run --runtime=<name>.
Works around the fact that Docker mounts the following files as read/write by default:
/etc/hosts/etc/hostname/etc/resolv.conf
When XFS project quotas are used to restrict a container's writable layer size, these files provide an escape hatch for malicious users to fill the host storage volume.
This can usually only be circumvented by manually creating read-only bind mounts over these paths (in which case Docker can no longer manage the container's DNS configuration) or by making the entire rootfs read-only (which severely constrains the workloads possible inside the container).
To avoid this issue, specify the --oi-readonly-networking-mounts flag. This modifies these mounts to be read-only, preventing writes from inside the container.
- Workaround for moby#13152, moby#41991 (without custom bind mounts or making entire rootfs readonly)
- Optionally reverts moby#5129
Allows specifying default environment variable values for containers without using docker run --env or --env-file.
Use --oi-env <NAME=VALUE> to set a default for an environment variable. This will not take precedence over a value explicitly specified via docker run --env or --env-file.
Alternatively, use --oi-env-force <NAME=VALUE> to force an certain value even when otherwise specified via docker run --env or --env-file.
- Workaround for moby#16699 (supports arbitrary environment variables, not only proxy config)
- Solution for https://stackoverflow.com/questions/33775075/how-to-set-default-docker-environment-variables
- Solution for https://stackoverflow.com/questions/50644143/dockerd-set-default-environment-variable-for-all-containers
Specify the --oi-write-debug-output flag to write original, parsed, and modified container configs to the directory specified as --oi-debug-output-dir (default /var/log/oci-interceptor).
The resulting files will be named:
<container_hostname>_original.json(the original config)<container_hostname>_parsed.json(the parsed config)<container_hostname>_modified.json(the modified config, only written if modification occurred)
Additionally, forwarded calls to the underlying OCI runtime will be appended to the file runtime_calls.log within the debug output directory.