Why?
restrict scope of file system access
run any application without root privileges
creates usable "Desktop applications" to integrate into your normal workflow
cut network access for applications that work with confidential stuff to prevent accidental leakage
set MEM and CPU boundaries for your applications
easy rollback with version pinning
works on wayland
gameplayerspecial
Installation:
Tested and verified:
Fedora 35
sudo dnf install python3-pip
pip install --user pyyaml
pip install --user jinja2
git clone https://github.com/mody5bundle/capps && cd capps/
checkmodule -M -m -o capps.mod capps.te
semodule_package -o capps.pp -m capps.mod
sudo semodule -i capps.pp
./capps.py -a firefox -d
Ubuntu 21.10
sudo apt install git python3 python3-pip podman
pip3 install jinja2
git clone https://github.com/mody5bundle/capps && cd capps/
./capps.py -a sandbox -d
Debian 11.3
sudo apt install git python3 python3-pip podman
pip3 install jinja2 pyyaml
git clone https://github.com/mody5bundle/capps && cd capps/
./capps.py -a spotify -d -s
Usage
capps.py [-h] [-a app1 app2 ... [app1 app2 ... ...]] [-c /path/to/config.yaml] [-b] [-r] [-i] [-v] [-s] [-d] [-l]
Start podman container apps.
options:
-h, --help show this help message and exit
-a app1 app2 ... [app1 app2 ... ...], --application-list app1 app2 ... [app1 app2 ... ...]
List of applications to run as defined in config file
-c /path/to/config.yaml, --config /path/to/config.yaml
Path to config file (defaults to config.yaml)
-b, --build (re)build list of provided apps
-r, --run run containers of all provided apps (default)
-i, --install install as desktop application
-v, --verbose enable verbose log output
-s, --stats enable stats output
-d, --debug enable debug log output
-l, --list print available container
Example container that gets Created
podman run --rm -d --hostname firefox \
--name firefox-$RANDOM \
--cap-drop=ALL \
--read-only=true \
--read-only-tmpfs=false \
--systemd=false \
--userns=keep-id \
--security-opt=no-new-privileges \
--memory=2048mb \
--cap-add cap_sys_chroot \
--volume $HOME/Downloads/:/home/firefox/Downloads:rw \
--volume /run/user/$UID/pulse/native:/run/user/$UID/pulse/native:ro \
--volume $XDG_RUNTIME_DIR/$WAYLAND_DISPLAY:/tmp/$WAYLAND_DISPLAY:ro \
localhost/firefox
Example config file for firefox
default_permissions: &default_permissions
cap-drop: ALL
read-only: true
read-only-tmpfs: true
systemd: false
userns: keep-id
security-opt: "no-new-privileges"
volumes:
- &sound "/run/user/$UID/pulse/native:/run/user/$UID/pulse/native:ro"
- &wayland "$XDG_RUNTIME_DIR/$WAYLAND_DISPLAY:/tmp/$WAYLAND_DISPLAY:ro"
- &x11 /tmp/.X11-unix:/tmp/.X11-unix:ro
container:
firefox:
versioncmd: "firefox --version | awk \"'\"{print \\$3}\"'\""
repo: "localhost"
file: "firefox.dockerfile"
path: "./container/firefox/"
icon: "firefox.png"
permissions:
memory: 2048mb
<<: *default_permissions
read-only-tmpfs: false
cap-add:
- "cap_sys_chroot"
volume:
- "$HOME/Downloads/:/home/firefox/Downloads:rw"
- *sound
- *wayland
list images
./capps.py -l
Available Containers in config:
firefox: Mem: 2048mb, Capabilities: ['cap_sys_chroot'], cap-drop: ALL
Available images on host for firefox:
['localhost/firefox:latest', 'localhost/firefox:98.0'] Entrypoint: ['/bin/sh', '-c', '/usr/bin/firefox --private --private-window'] Size: 1178 MB 3391 Minutes old.
['localhost/firefox:97.0.1'] Entrypoint: ['/bin/sh', '-c', '/usr/bin/firefox --private --private-window'] Size: 1182 MB 26452 Minutes old.
['localhost/firefox:96.0'] Entrypoint: ['/bin/sh', '-c', '/usr/bin/firefox --private --private-window'] Size: 1156 MB 96024 Minutes old.
get stats on started container
./capps.py -a firefox -s
NAME MEM CPU READ/WRITE PIDS
firefox-18685: 232.1MB / 2.147GB / 10.81% 3.17% -- / -- 57
firefox-18685: 497.1MB / 2.147GB / 23.15% 2.24% 0B / 2.049MB 226
Selinux:
cat capps.te
checkmodule -M -m -o capps.mod capps.te
semodule_package -o capps.pp -m capps.mod
semodule -i capps.pp
rm -rf capps.{pp,mod}