I recently used a small bit of OCaml code to help generate bash scripts for sandboxing programs via bubblewrap and have found the suite to be fairly useful and saved a fair bit of typing.
The repo: https://github.com/darrenldl/sandboxing
Note: This is not a well packaged project right now, and has no versioning. I suggest forking the repo if you actually plan on using it. Might do proper packaging work at some point, however.
Syscall filter handling
Seccomp BPF compilation (for syscall filter) can also be handled via the suite in OCaml’s side. (If you’ve seen this project over at Discord before, then this part is the new addtion that was previously absent)
- Context: right now bubblewrap only allows specification of syscall filtering via a compiled BPF file, this is handled by the suite as follows:
OCaml code --generates–> C code --generates–> BPF filter
Firefox example
Some code for firefox is as follows
OCaml side
Firefox profile specification in bw-script-gen/src/profiles.ml
let make_firefox_profile ~(suffix : string option) : profile =
let name = match suffix with None -> "firefox" | Some s -> "firefox-" ^ s in
{
name;
cmd = "/usr/lib/firefox/firefox --ProfileManager";
home_jail_dir = Some name;
syscall_blacklist = default_syscall_blacklist;
args =
usr_share_common
@ usr_lib_lib64_bin_common
@ etc_common
@ proc_dev_common
@ tmp_run_common
@ sound_common
@ wayland_common
@ dconf_common
@ dbus_common
@ set_up_jail_home ~tmp:false ~name
@ [
Bind ("$HOME/.mozilla", Some "/home/jail/.mozilla");
Bind ("$HOME/.cache/mozilla", Some "/home/jail/.cache/mozilla");
Unsetenv "DBUS_SESSION_BUS_ADDRESS";
Setenv ("SHELL", "/bin/false");
Setenv ("USER", "nobody");
Setenv ("LOGNAME", "nobody");
Setenv ("MOZ_ENABLE_WAYLAND", "1");
Hostname "jail";
Unshare_user;
Unshare_pid;
Unshare_uts;
Unshare_ipc;
Unshare_cgroup;
New_session;
];
}
C code
The generated C code for compiling the BPF file can be seen here: https://github.com/darrenldl/sandboxing/blob/master/seccomp-bpf/firefox.c
Bash script
The generated bash script:
#!/usr/bin/env bash
set -euxo pipefail
gcc "$(dirname $0)"/../seccomp-bpf/firefox.c -lseccomp -o "$(dirname $0)"/../seccomp-bpf/firefox.exe
"$(dirname $0)"/../seccomp-bpf/firefox.exe
mv firefox_seccomp_filter.bpf "$(dirname $0)"/../seccomp-bpf
mkdir -p "$HOME/jails/firefox"
mkdir -p "$HOME/jails/firefox/Downloads"
bwrap \
--ro-bind "/usr/share/X11" "/usr/share/X11" \
--ro-bind "/usr/share/icons" "/usr/share/icons" \
--ro-bind-try "/usr/share/fontconfig" "/usr/share/fontconfig" \
--ro-bind "/usr/share/fonts" "/usr/share/fonts" \
--ro-bind "/usr/share/mime" "/usr/share/mime" \
--ro-bind "/usr/share/ca-certificates" "/usr/share/ca-certificates" \
--ro-bind "/usr/share/glib-2.0" "/usr/share/glib-2.0" \
--ro-bind "/usr/lib" "/usr/lib" \
--ro-bind "/usr/lib64" "/usr/lib64" \
--tmpfs "/usr/lib/modules" \
--tmpfs "/usr/lib/systemd" \
--symlink "/usr/lib" "/lib" \
--symlink "/usr/lib64" "/lib64" \
--ro-bind "/usr/bin" "/usr/bin" \
--symlink "/usr/bin" "/bin" \
--symlink "/usr/bin" "/sbin" \
--ro-bind "/etc/fonts" "/etc/fonts" \
--ro-bind "/etc/machine-id" "/etc/machine-id" \
--ro-bind "/etc/resolv.conf" "/etc/resolv.conf" \
--proc "/proc" \
--dev "/dev" \
--tmpfs "/tmp" \
--tmpfs "/run" \
--ro-bind-try "/usr/share/gst-plugins-bad" "/usr/share/gst-plugins-bad" \
--ro-bind-try "/usr/share/gst-plugins-base" "/usr/share/gst-plugins-base" \
--ro-bind-try "/usr/share/gstreamer-1.0" "/usr/share/gstreamer-1.0" \
--ro-bind "/run/user/$UID/pulse" "/run/user/$UID/pulse" \
--ro-bind "/run/user/$UID/wayland-0" "/run/user/$UID/wayland-0" \
--setenv "QT_QPA_PLATFORM" "wayland" \
--bind "/run/user/$UID/dconf" "/run/user/$UID/dconf" \
--ro-bind "/run/user/$UID/bus" "/run/user/$UID/bus" \
--bind "$HOME/jails/firefox" "/home/jail" \
--setenv "HOME" "/home/jail" \
--bind "$HOME/.mozilla" "/home/jail/.mozilla" \
--bind "$HOME/.cache/mozilla" "/home/jail/.cache/mozilla" \
--unsetenv "DBUS_SESSION_BUS_ADDRESS" \
--setenv "SHELL" "/bin/false" \
--setenv "USER" "nobody" \
--setenv "LOGNAME" "nobody" \
--setenv "MOZ_ENABLE_WAYLAND" "1" \
--hostname "jail" \
--unshare-user \
--unshare-pid \
--unshare-uts \
--unshare-ipc \
--unshare-cgroup \
--new-session \
--seccomp 10 10<"$(dirname $0)"/../seccomp-bpf/firefox_seccomp_filter.bpf \
/usr/lib/firefox/firefox --ProfileManager