Skip to content

Instantly share code, notes, and snippets.

@kyleneideck
Last active March 3, 2023 06:02
Show Gist options
  • Save kyleneideck/e7a9266a5a23ecc1254b807b16717ce0 to your computer and use it in GitHub Desktop.
Save kyleneideck/e7a9266a5a23ecc1254b807b16717ce0 to your computer and use it in GitHub Desktop.
DRAFT: AppArmor profile for running AUTOMATIC1111's Stable Diffusion web UI in a Docker container
abi <abi/3.0>,
include <tunables/global>
# TODO: Figure out how to remove attach_disconnected. See <https://gitlab.com/apparmor/apparmor/-/issues/125>.
profile docker-sd flags=(attach_disconnected,mediate_deleted) {
include <abstractions/base>
include <abstractions/python>
include <abstractions/nvidia>
include <abstractions/bash>
/dev/nvidia-uvm rw,
#/dev/nvidia-uvm-tools rw,
/proc/sys/vm/mmap_min_addr r,
/sys/devices/system/memory/block_size_bytes r,
/sys/devices/system/cpu/{,**} r,
/sys/devices/system/node/{,**} r,
# allow reading files in /proc/<number>/** or /proc/sys/**
#@{PROC}/{[1-9],[^1-9][^0-9],[^1-9s][^0-9y][^0-9s],[^1-9][^0-9][^0-9][^0-9/]*}/** r,
@{PROC}/[0-9][0-9]*/** r,
@{PROC}/sys/** r,
@{PROC}/devices r,
/dev/pts/* rw,
/dev/tty rw,
#unix (bind),
unix,
/ r,
/dev/ r,
/webui/ rw,
/webui/** wrklmix,
@{PROC}/*/attr/apparmor/current r,
@{PROC}/*/attr/current r,
/bin/ r,
/bin/** rix,
/usr/{,**} rix,
/usr/bin/** rix,
/usr/lib*/** rix,
/usr/local/bin/** rix,
/usr/local/sbin/** rix,
/usr/local/lib/** rix,
/usr/sbin/** rix,
/usr/sbin/** rix,
/usr/share/{,**} r,
/etc/{,**} r,
/home/ r,
/home/diffuser/ rwmixlk,
/home/diffuser/** rwmixlk,
/tmp/{,**} rwixlk,
# From https://github.com/genuinetools/bane/blob/master/docker-nginx-sample
network inet tcp,
network inet udp,
network inet icmp,
network inet stream,
network inet6 tcp,
network inet6 udp,
network inet6 stream,
deny network raw,
deny network packet,
#file,
umount,
deny /bin/** wl,
deny /boot/** wl,
#deny /dev/** wl,
#deny /etc/** wl,
deny /home/[^d]** rwlmkx,
deny /lib/** wl,
deny /lib64/** wl,
deny /media/** wl,
deny /mnt/** wl,
deny /opt/** wl,
deny /proc/** wl,
deny /root/** wl,
deny /sbin/** wl,
deny /srv/** wl,
#deny /tmp/** wl,
deny /sys/** wl,
deny /usr/** wl,
# End https://github.com/genuinetools/bane/blob/master/docker-nginx-sample
# From https://github.com/moby/moby/blob/master/profiles/apparmor/template.go
# Host (privileged) processes may send signals to container processes.
signal (receive) peer=unconfined,
# dockerd may send signals to container processes (for "docker kill").
#signal (receive) peer={{.DaemonProfile}},
# Container processes may send signals amongst themselves.
signal (send,receive) peer=docker-sd,
deny @{PROC}/* w, # deny write for all files directly in /proc (not in a subdir)
# deny write to files not in /proc/<number>/** or /proc/sys/**
deny @{PROC}/{[^1-9],[^1-9][^0-9],[^1-9s][^0-9y][^0-9s],[^1-9][^0-9][^0-9][^0-9/]*}/** w,
deny @{PROC}/sys/[^k]** w, # deny /proc/sys except /proc/sys/k* (effectively /proc/sys/kernel)
deny @{PROC}/sys/kernel/{?,??,[^s][^h][^m]**} w, # deny everything except shm* in /proc/sys/kernel/
deny @{PROC}/sysrq-trigger rwklx,
deny @{PROC}/kcore rwklx,
deny mount,
deny /sys/[^f]*/** wklx,
deny /sys/f[^s]*/** wklx,
deny /sys/fs/[^c]*/** wklx,
deny /sys/fs/c[^g]*/** wklx,
deny /sys/fs/cg[^r]*/** wklx,
deny /sys/firmware/** rwklx,
deny /sys/kernel/security/** rwklx,
# suppress ptrace denials when using 'docker ps' or using 'ps' inside a container
ptrace (trace,read,tracedby,readby) peer=docker-sd,
# End https://github.com/moby/moby/blob/master/profiles/apparmor/template.go
}
FROM nvidia/cuda:12.0.1-base-ubuntu22.04
RUN apt-get update
RUN apt-get install -y wget git python3 python3-venv vim ffmpeg libsm6 libxext6
RUN useradd --uid 4000 -ms /bin/bash diffuser
RUN git clone https://github.com/AUTOMATIC1111/stable-diffusion-webui.git /webui && \
chown -R diffuser:diffuser /webui
USER diffuser
# TODO: These take a minute or two to copy when using rootless Docker. Try rootless nerdctl instead?
COPY --link --chown=4000:4000 venv /webui/venv
COPY --link --chown=4000:4000 models /webui/models
COPY --link --chown=4000:4000 repositories /webui/repositories
COPY --link --chown=4000:4000 extensions /webui/extensions
COPY --chown=diffuser entrypoint.sh /run/entrypoint.sh
ENTRYPOINT ["/run/entrypoint.sh"]
#CMD ["bash","-x","-c","ls -lah /models ; whoami ; ls -lah /sys/kernel/security ; nvidia-smi ; cat /proc/self/attr/apparmor/current"]
# Replace the username and password here.
CMD ["/webui/webui.sh", "--listen", "--xformers", "--gradio-auth", "some_username:some_password"]
#!/bin/bash
# Workaround so we can confine with AppArmor. Rootless Docker doesn't currently
# support --security-opt=apparmor=[...]. The docker-sd profile has to be loaded
# by a user in the sudoers group:
# sudo apparmor_parser -Wr /etc/apparmor.d/docker-sd
#
# From <https://github.com/moby/moby/issues/41931>.
echo "exec docker-sd" > /proc/self/attr/exec
echo "AppArmor confinement:"
cat /proc/self/attr/apparmor/current
echo "$@"
$@
#user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log notice;
#pid /var/run/nginx.pid;
pid /tmp/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/*.conf;
deny 192.168.0.1;
allow 172.17.0.1;
allow 127.0.0.1;
deny all;
auth_basic "Restricted Content";
auth_basic_user_file /etc/nginx/htpasswd;
server { # simple reverse-proxy
listen 7860;
location / {
proxy_pass http://sd:7860;
}
}
}
FROM nginxinc/nginx-unprivileged
# Generate the htpasswd file with:
# printf "<user>:$(openssl passwd -apr1 <your password>)\n" >> htpasswd
COPY --chown=nginx:root htpasswd /etc/nginx/htpasswd
RUN chmod a-w /etc/nginx/htpasswd
COPY --chown=nginx:root nginx.conf /etc/nginx/nginx.conf
RUN chmod a-w /etc/nginx/nginx.conf
#!/bin/bash
sd_ip=$(docker exec sd cat /etc/hosts | grep '^172\.' | awk '{ print $1 }')
if [[ -z "$sd_ip" ]]; then
echo "sd container not running (or failed to get its IP address)." > /dev/stderr
exit 1
fi
docker build --tag sd-proxy -f proxy.Dockerfile .
docker run -it --rm \
--add-host=sd:"$sd_ip" \
-p 127.0.0.1:7860:7860 \
--tmpfs /tmp \
--name sd-proxy \
--security-opt=no-new-privileges \
--cap-drop all \
sd-proxy $@
#!/bin/bash
set -x
gpu_uuid= # Hardcode your GPU's UUID here (e.g. f13bb643-648a-4eab-9cc6-d79f43d7c9d4). Use nvidia-smi to find it.
utility=0
if [[ $utility == 1 ]]; then
gpus='"device=GPU-'$gpu_uuid'","capabilities=compute,utility"'
else
gpus='"device=GPU-'$gpu_uuid'","capabilities=compute"'
fi
docker build --tag sd .
# -security-opt=apparmor= isn't supported in rootless Docker. There's a workaround in Dockerfile.
docker run \
--rm \
-u diffuser \
--gpus "$gpus" \
--cap-drop all \
--security-opt=no-new-privileges \
--tmpfs /tmp \
--name sd \
-it \
sd $@
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment