Notes on Open Policy Agent and Docker Security
I am starting to work with Open Policy Agent (OPA) for Kubernetes. OPA is largely known for its ability to behave as a powerful Admission Controller for Kubernetes.
However, I find that Open Policy Agent is a great Admission Controller/Policy Enforcement tool for Docker, HTTP REST API and other technologies as well.
This is a public note on some possible options to enforce security policy for Docker deployments, with Open Policy Agent (OPA)
>> tested on Ubuntu 18.04
Installation
Install the Policy Agent with docker plugin
- Create a Policy directory under
/etc/docker
mkdir -p /etc/docker/policies # to load policies
vim /etc/docker/policies/authz.rego #to create a policy
- Install the plugin with
docker plugin
docker plugin install openpolicyagent/opa-docker-authz-v2:0.4 opa-args="-policy-file /opa/policies/authz.rego"
# link policy file to the plugin
Plugin "openpolicyagent/opa-docker-authz-v2:0.4" is requesting the following privileges:
- mount: [/etc/docker]
Do you grant the above permissions? [y/N] y
0.4: Pulling from openpolicyagent/opa-docker-authz-v2
d93242d88c4c: Download complete
Digest: sha256:03ee6dfeda0ffe561980ef43fe91f9fd05b093757623887da724bb42b02f3113
Status: Downloaded newer image for openpolicyagent/opa-docker-authz-v2:0.4
Installed plugin openpolicyagent/opa-docker-authz-v2:0.4
- Add Plugin to the Docker Daemon
root@container-dummy-os:/# cat > /etc/docker/daemon.json <<EOF
> {
> "authorization-plugins": ["openpolicyagent/opa-docker-authz-v2:0.4"]
> }
> EOF
As you can see, you are adding an additional Authorization Layer to running the docker daemon based on what's specified in the policy file
Let's create a security policy
I am going to create a simple authorization policy to disallow containers to be run with the --privileged
flag (which disables all SYSCALL limits on the container)
I add this to the /etc/docker/policies/authz.rego
file
package docker.authz
default allow = false
allow {
not deny
}
deny {
priv_containers
}
priv_containers {
input.Body.HostConfig.Privileged == true
}
As you can see, I can specify multiple deny
policies by naming them. I set the parameters for the --privileged
flag by the params passed by Docker API when attributes are passed from the API to the Daemon.
This should now enforce system-wide, with a deny
everytime when someone attempts to run a privileged container
This works!
docker run -p 5000:5000 some_app:latest
But this should be blocked!
docker run --privileged alpine sh
docker: Error response from daemon: authorization denied by plugin openpolicyagent/opa-docker-authz-v2:0.4: request rejected by administrative policy.
See 'docker run --help'.
I find that this is a great way to setup preventative controls on Docker Runtimes, especially to block low-hanging insecure settings like:
- Privileged containers
seccomp:unconfined
or lack of--security-opts
flag- Resource limits on CPU, memory, etc
- Restricted port bindings
- Block run as user
uid0
- Sensitive Environment Variables with keywords like
password