• Stars
    star
    425
  • Rank 98,190 (Top 2 %)
  • Language
    Python
  • License
    GNU General Publi...
  • Created over 5 years ago
  • Updated 3 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

This repository contains a tool for generating SELinux security profiles for containers

UDICA logo

udica - Generate SELinux policies for containers!

Build Status

Overview

This repository contains a tool for generating SELinux security profiles for containers. The whole concept is based on "block inheritence" feature inside CIL intermediate language supported by SELinux userspace. The tool creates a policy which combines rules inherited from specified CIL blocks(templates) and rules discovered by inspection of container JSON file, which contains mountpoints and ports definitions.

Final policy could be loaded immediately or moved to another system where it could be loaded via semodule.

What's with the weird name?

The name of this tool is derived from the Slovak word "udica" [uษŸitอกsa], which means "fishing rod". It is a reference to the saying "Give a man a fish and you feed him for a day; teach a man to fish and you feed him for a lifetime." Here udica is the fishing rod that allows you to get the fish (container policy) yourself, instead of always having to ask your local fisherman (SELinux expert) to catch (create) it for you ;)

State

This tool is still in early phase of development. Any feedback, ideas, pull requests are welcome. We're still adding new features, parameters and policy blocks which could be used.

Proof of concept

Tool was created based on following PoC where process of creating policy is described: https://github.com/fedora-selinux/container-selinux-customization

Supported container engines

Udica supports following container engines:

  • CRI-O v1.14.10+
  • docker v1.13+
  • podman v2.0+
  • containerd v1.5.0+ (using nerdctl v0.14+ or crictl)

Installing

Install udica tool with all dependencies

$ sudo dnf install -y podman setools-console git container-selinux
$ git clone https://github.com/containers/udica
$ cd udica && sudo python3 ./setup.py install

Alternatively you can run udica directly from git:

$ python3 -m udica --help

Another way how to install udica is to use fedora repository:

# dnf install udica -y

Or you can use Python Package Index (Pypi):

# pip install udica

Make sure that SELinux is in Enforcing mode

# setenforce 1
# getenforce
Enforcing

Current situation

Let's start podman container with following parameters:

# podman run -v /home:/home:ro -v /var/spool:/var/spool:rw -p 21:21 -it fedora bash
  • Container will bind mount /home with read only perms
  • Container will bind mount /var/spool with read/write perms
  • Container will publish container's port 21 to the host

Container runs with container_t type and c447,c628 categories.

Access mounted /home is not working:

[root@37a3635afb8f /]# cd /home/
[root@37a3635afb8f home]# ls
ls: cannot open directory '.': Permission denied

Because there is no allow rule for container_t to access /home

# sesearch -A -s container_t -t home_root_t
#

Access mounted /var/spool is not working:

[root@37a3635afb8f home]# cd /var/spool/
[root@37a3635afb8f spool]# ls
ls: cannot open directory '.': Permission denied
[root@37a3635afb8f spool]# touch test
touch: cannot touch 'test': Permission denied

Because there is no allow rule for container_t to access /var/spool

# sesearch -A -s container_t -t var_spool_t -c dir -p read
#

On the other hand, what is completely allowed is network access.

# sesearch -A -s container_t -t port_type -c tcp_socket
allow container_net_domain port_type:tcp_socket { name_bind name_connect recv_msg send_msg };
allow sandbox_net_domain port_type:tcp_socket { name_bind name_connect recv_msg send_msg };

# sesearch -A -s container_t -t port_type -c udp_socket
allow container_net_domain port_type:udp_socket { name_bind recv_msg send_msg };
allow sandbox_net_domain port_type:udp_socket { name_bind recv_msg send_msg };

It would be great to restrict this access and allow container bind just on tcp port 21 or with the same label.

Creating SELinux policy for container

To create policy for container, it's necessary to have running container for which a policy will be generated. Container from previous chapter will be used.

Let's find container id using podman ps command:

# podman ps
CONTAINER ID   IMAGE                             COMMAND   CREATED          STATUS              PORTS   NAMES
37a3635afb8f   docker.io/library/fedora:latest   bash      15 minutes ago   Up 15 minutes ago           heuristic_lewin

Container ID is 37a3635afb8f.

To create policy for it udica tool could be used. Parameter '-j' is for container json file and SELinux policy name for container.

# podman inspect 37a3635afb8f > container.json
# udica -j container.json  my_container

or

# podman inspect 37a3635afb8f | udica  my_container

Policy my_container with container id 37a3635afb8f created!

Please load these modules using:
# semodule -i my_container.cil /usr/share/udica/templates/{base_container.cil,net_container.cil,home_container.cil}

Restart the container with: "--security-opt label=type:my_container.process" parameter

Policy is generated. Let's follow instructions from output:

# semodule -i my_container.cil /usr/share/udica/templates/{base_container.cil,net_container.cil,home_container.cil}

# podman run --security-opt label=type:my_container.process -v /home:/home:ro -v /var/spool:/var/spool:rw -p 21:21 -it fedora bash

Container is now running with my_container.process type:

# ps -efZ | grep my_container.process
unconfined_u:system_r:container_runtime_t:s0-s0:c0.c1023 root 2275 434  1 13:49 pts/1 00:00:00 podman run --security-opt label=type:my_container.process -v /home:/home:ro -v /var/spool:/var/spool:rw -p 21:21 -it fedora bash
system_u:system_r:my_container.process:s0:c270,c963 root 2317 2305  0 13:49 pts/0 00:00:00 bash

SELinux now allows access to /home and /var/spool mount points:

[root@814ec56079e5 /]# cd /home
[root@814ec56079e5 home]# ls
lvrabec

[root@814ec56079e5 ~]# cd /var/spool/
[root@814ec56079e5 spool]# touch test
[root@814ec56079e5 spool]#

SELinux now allows binding to tcp/udp port 21, but not to 80:

[root@5bd8cb2ad911 /]# nc -lvp 21
Ncat: Version 7.60 ( https://nmap.org/ncat )
Ncat: Generating a temporary 1024-bit RSA key. Use --ssl-key and --ssl-cert to use a permanent one.
Ncat: SHA-1 fingerprint: 6EEC 102E 6666 5F96 CC4F E5FA A1BE 4A5E 6C76 B6DC
Ncat: Listening on :::21
Ncat: Listening on 0.0.0.0:21

[root@5bd8cb2ad911 /]# nc -lvp 80
Ncat: Version 7.60 ( https://nmap.org/ncat )
Ncat: Generating a temporary 1024-bit RSA key. Use --ssl-key and --ssl-cert to use a permanent one.
Ncat: SHA-1 fingerprint: 6EEC 102E 6666 5F96 CC4F E5FA A1BE 4A5E 6C76 B6DC
Ncat: bind to :::80: Permission denied. QUITTING.

SELinux labels vs. objects they represent

Policies generated by udica work with SELinux labels as opposed to filesystem paths, port numbers etc. This means that allowing access to given path (e.g. path to a directory mounted to your container), port number, or any other resource may also allow access to other resources you didn't specify, since the same SELinux label can be assigned to multiple resources.

For example a container using port 21 will also be given access to ports 989 and 990 by udica, since all the listed ports share a single label.

# sudo semanage port -l | grep 21
ftp_port_t                     tcp      21, 989, 990

Similarly, bind mounting a sub-directory of your home directory will result in a container policy allowing access to almost all the data in the home directory, unless a non-default label is used for the mounted path.

# sudo semanage fcontext -l | grep user_home_t
/home/[^/]+/.+                                     all files          unconfined_u:object_r:user_home_t:s0

Running from a container

To build the udica container to your local registry, run the following command:

$ make image

Once having the image built, it's possible to run udica from whithin a container. The necessary directories to bind-mount are:

  • /sys/fs/selinux
  • /etc/selinux/
  • /var/lib/selinux/

For reference, this would be a way to call the container via podman:

podman run --user root --privileged -ti \
    -v /sys/fs/selinux:/sys/fs/selinux \
    -v /etc/selinux/:/etc/selinux/ \
    -v /var/lib/selinux/:/var/lib/selinux/ \
    --rm --name=udica udica

Testing

Udica repository contains units tests for basic functionality of the tool. To run tests follow these commands:

$ make test

On SELinux enabled systems you can run also (root access required):

# python3 tests/test_integration.py

Udica in OpenShift

Udica could run in OpenShift and generate SELinux policies for pods in the same instance. SELinux policy helper operator is a controller that listens to all pods in the system. It will attempt to generate a policy for pods when the pod is annotated with a specific tag "generate-selinux-policy" and the pod is in a running state. In order to generate the policy, it spawns a pod with the selinux-k8s tool which uses udica to generate the policy. It will spit out a configmap with the appropriate policy.

Real example is demonstrated in following demo.

Demo

asciicast

Known issues

  • It's not possible to detect capabilities used by container in docker engine, therefore you have to use '-c' to specify capabilities for docker container manually.
  • It's not possible to generate custom local policy using "audit2allow -M" tool from AVCs where source context was generated by udica. For this purpose please use '--append-rules' option.
  • In some situations udica fails to identify which container engine is used, therefore "--container-engine" parameter has to be used to inform udica how JSON inspection file should be parsed.

More Repositories

1

podman

Podman: A tool for managing OCI containers and pods.
Go
21,713
star
2

skopeo

Work with remote images registries - retrieving information, images, signing content
Go
7,355
star
3

buildah

A tool that facilitates building OCI images.
Go
7,003
star
4

youki

A container runtime written in Rust
Rust
5,793
star
5

podman-compose

a script to run docker-compose.yml using podman
Python
4,567
star
6

podman-desktop

Podman Desktop - A graphical tool for developing on containers and Kubernetes
TypeScript
4,145
star
7

bubblewrap

Low-level unprivileged sandboxing tool used by Flatpak and similar projects
C
3,601
star
8

crun

A fast and lightweight fully featured OCI runtime and C library for running containers
C
2,759
star
9

toolbox

Tool for interactive command line environments on Linux
Shell
2,284
star
10

krunvm

Create microVMs from OCI images
Rust
1,315
star
11

image

Work with containers' images
Go
822
star
12

libkrun

A dynamic library providing Virtualization-based process isolation capabilities
Rust
655
star
13

storage

Container Storage Library
Go
522
star
14

podman-tui

Podman Terminal UI
Go
494
star
15

fuse-overlayfs

FUSE implementation for overlayfs
C
476
star
16

netavark

Container network stack
Rust
457
star
17

conmon

An OCI container runtime monitor.
C
395
star
18

composefs

a file system for mounting container images
C
368
star
19

build

another build tool for container images (archived, see https://github.com/rkt/rkt/issues/4024)
Go
341
star
20

quadlet

C
330
star
21

oci-seccomp-bpf-hook

OCI hook to trace syscalls and generate a seccomp profile
Go
280
star
22

podman.io_old

Repository for podman.io website using GitHub Pages.
CSS
259
star
23

bootc

Boot and upgrade via container images
Rust
250
star
24

ansible-podman-collections

Repository for Ansible content that can include playbooks, roles, modules, and plugins for use with the Podman tool
Python
233
star
25

container-selinux

SELinux policy files for Container Runtimes
Roff
227
star
26

podman-py

Python bindings for Podman's RESTful API
Python
215
star
27

gvisor-tap-vsock

A new network stack based on gVisor
Go
212
star
28

dnsname

name resolution for containers
Go
178
star
29

oci-spec-rs

OCI Runtime, Image and Distribution Spec in Rust
Rust
173
star
30

common

Location for shared common files in github.com/containers repos.
Go
161
star
31

conmon-rs

An OCI container runtime monitor written in Rust
Rust
157
star
32

aardvark-dns

Authoritative dns server for A/AAAA container records. Forwards other request to host's /etc/resolv.conf
Rust
151
star
33

docker-lvm-plugin

Docker volume plugin for LVM volumes
Go
148
star
34

virtcontainers

A Go package for building hardware virtualized container runtimes
Go
140
star
35

containrs

General purpose container library
Rust
122
star
36

ocicrypt

Encryption libraries for Encrypted OCI Container images
Go
121
star
37

fetchit

FetchIt is used to manage the life cycle and configuration of Podman containers
Go
109
star
38

prometheus-podman-exporter

Prometheus exporter for podman environments exposing containers, pods, images, volumes and networks information.
Go
105
star
39

bluechi

Bluechi is a systemd service controller intended for multi-node environments with a predefined number of nodes and with a focus on highly regulated ecosystems such as those requiring functional safety.
C
96
star
40

crun-vm

An OCI Runtime that enables Podman, Docker, and Kubernetes to run VM images.
Rust
78
star
41

Demos

Repository is a location of user demos for technologies listed on github.com/containers
Shell
77
star
42

shortnames

Shortnames project is collecting registry alias names for shortnames to fully specified container image names.
Python
66
star
43

libkrunfw

A dynamic library bundling the guest payload consumed by libkrun
C
59
star
44

psgo

A ps(1) AIX-format compatible golang library
Go
56
star
45

python-podman

Python bindings and code examples for using Varlink access to Podman Service
Python
50
star
46

nri-plugins

A collection of community maintained NRI plugins
Go
48
star
47

libocispec

a C library for accessing OCI runtime and image spec files
Python
47
star
48

tar-diff

Go
46
star
49

selinuxd

A daemon that manages SELinux policies on a filesystem
Go
37
star
50

podman-desktop-swift

Swift
34
star
51

podman.io

The new podman.io design project
TypeScript
33
star
52

podman-security-bench

Shell
33
star
53

initoverlayfs

C
32
star
54

nydus-storage-plugin

A storage plugin that provided CRI-O/Podman with the ability to lazy mount nydus images.
Go
30
star
55

buildah.io

Repository for the buildah.io web site using GitHub Pages.
HTML
27
star
56

BuildSourceImage

Tool to build a source image based on an existing OCI image
Shell
26
star
57

ansible-podman

Ansible podman is a package to allow ansible playbooks to manage podman containers
Python
26
star
58

oci-fetch

Simple command line tool for fetching the Open Container Initiative image format over various transports.
Go
23
star
59

podman-wsl-fedora

Root FS image of Fedora for Podman Machine on Windows
22
star
60

containertoolbx.org

Website for the Toolbx project
CSS
20
star
61

appstore

Example directory of Kubernetes YAML and Quadlets tested with Podman
Python
18
star
62

automation_images

Shell
17
star
63

containers-image-proxy-rs

containers-image-proxy-rs
Rust
17
star
64

qm

QM is a containerized environment for running Functional Safety qm (Quality Management) software
Shell
17
star
65

libhvee

Special purposed library for Windows HyperV control
Go
16
star
66

podman-machine-qemu

Qemu build for macOS used by the self-contained `podman machine` installer
Shell
16
star
67

oci-umount

C
13
star
68

docs

Repository for all documentation written about tools hosted at github.com/containers
Shell
12
star
69

automation

Automation scripts and configurations common across the containers org. repositories
Shell
12
star
70

netavark-dhcp-proxy-deprecated

DHCP proxy for Netavark
Rust
11
star
71

podman-desktop-extension-bootc

Support for bootable OS containers (bootc) and generating disk images
TypeScript
9
star
72

podhawk

Python
9
star
73

podman-machine-cni

Go
6
star
74

podman-desktop-catalog

Catalog of extensions of Podman Desktop
6
star
75

validator

C
6
star
76

arty

Arty is a tool for managing OCI Artifacts on OCI Registries.
6
star
77

automation_sandbox

Test-repository for experimenting with in-repo automation tools/settings.
Shell
4
star
78

kubensmnt

Shell
4
star
79

podman-desktop-e2e

Podman desktop e2e tests
Go
3
star
80

.github

The README for the containers organization
3
star
81

fetchit-desktop-extension

TypeScript
3
star
82

podman-desktop-extension-minikube

TypeScript
2
star
83

release-keys

2
star
84

podman-wsl-fedora-arm

Fedora ARM distribution for Podman Machine on WSL
2
star
85

ContainerPlumbing

Container Plumbing Conference information.
2
star
86

bootable

Ruby
2
star
87

nri-plugins-operator

Makefile
2
star
88

luksy

offline encryption/decryption using LUKS formats
Go
2
star
89

PodmanHello

Podman Hello Image Repository
Dockerfile
1
star
90

containers.github.io

HTML
1
star
91

winquit

golang module that supports graceful shutdown of Windows applications
Go
1
star
92

podman-installer

1
star
93

ai-lab-recipes

ai-studio-recipes
1
star