-
Notifications
You must be signed in to change notification settings - Fork 432
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow basic sandboxing of containers #1413
Changes from all commits
ef35979
f221547
c6de96d
bd6f595
feb0c8d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -15,10 +15,14 @@ _arguments -s \ | |||||
'--pre-init-hooks[additional commands to execute prior to container initialization]:command:' \ | ||||||
'(--init -I)'{-I,--init}'[use init system inside the container]' \ | ||||||
'--nvidia[try to integrate host nVidia drivers in the guest]' \ | ||||||
'--unprivileged[do not drop security measures when creating a container]' \ | ||||||
'--unshare-devsys[do not share host devices and sysfs dirs from host]' \ | ||||||
'--unshare-groups[do not forward user''s additional groups into the container]' \ | ||||||
'--unshare-home[do not mount host home directory into the container]' \ | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. see other comment
Suggested change
|
||||||
'--unshare-ipc[do not share ipc namespace with host]' \ | ||||||
'--unshare-netns[do not share the net namespace with host]' \ | ||||||
'--unshare-process[do not share process namespace with host]' \ | ||||||
'--unshare-root[do not mount host root directory into the container]' \ | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See other comment
Suggested change
|
||||||
'--unshare-all[activate all the unshare flags]' \ | ||||||
'(--compatibility -C)'{-C,--compatibility}'[show list of compatible images]' \ | ||||||
'(--help -h)'{-h,--help}'[show this message]' \ | ||||||
|
Original file line number | Diff line number | Diff line change | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
@@ -80,10 +80,13 @@ init=0 | |||||||||
non_interactive=0 | ||||||||||
nvidia=0 | ||||||||||
nopasswd=0 | ||||||||||
unprivileged=0 | ||||||||||
unshare_ipc=0 | ||||||||||
unshare_groups=0 | ||||||||||
unshare_home=0 | ||||||||||
unshare_netns=0 | ||||||||||
unshare_process=0 | ||||||||||
unshare_root=0 | ||||||||||
unshare_devsys=0 | ||||||||||
|
||||||||||
# Use cd + dirname + pwd so that we do not have relative paths in mount points | ||||||||||
|
@@ -214,11 +217,14 @@ Options: | |||||||||
this will make host's processes not visible from within the container. (assumes --unshare-process) | ||||||||||
may require additional packages depending on the container image: https://github.com/89luca89/distrobox/blob/main/docs/useful_tips.md#using-init-system-inside-a-distrobox | ||||||||||
--nvidia: try to integrate host's nVidia drivers in the guest | ||||||||||
--unshare-devsys: do not share host devices and sysfs dirs from host | ||||||||||
--unshare-groups: do not forward user's additional groups into the container | ||||||||||
--unprivileged: do not drop security measures when creating a container | ||||||||||
--unshare-devsys: do not share host devices and sysfs dirs from host | ||||||||||
--unshare-groups: do not forward user's additional groups into the container | ||||||||||
--unshare-home: do not mount host home directory into the container | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nice description! I think grammatically, there is a small mistake.
Suggested change
|
||||||||||
--unshare-ipc: do not share ipc namespace with host | ||||||||||
--unshare-netns: do not share the net namespace with host | ||||||||||
--unshare-process: do not share process namespace with host | ||||||||||
--unshare-process: do not share process namespace with host | ||||||||||
--unshare-root: do not mount host root directory into the container | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same as the
Suggested change
|
||||||||||
--unshare-all: activate all the unshare flags below | ||||||||||
--compatibility/-C: show list of compatible images | ||||||||||
--help/-h: show this message | ||||||||||
|
@@ -298,6 +304,10 @@ while :; do | |||||||||
shift | ||||||||||
dryrun=1 | ||||||||||
;; | ||||||||||
--unprivileged) | ||||||||||
shift | ||||||||||
unprivileged=1 | ||||||||||
;; | ||||||||||
-r | --root) | ||||||||||
shift | ||||||||||
rootful=1 | ||||||||||
|
@@ -320,6 +330,10 @@ while :; do | |||||||||
shift | ||||||||||
unshare_groups=1 | ||||||||||
;; | ||||||||||
--unshare-home) | ||||||||||
shift | ||||||||||
unshare_home=1 | ||||||||||
;; | ||||||||||
--unshare-netns) | ||||||||||
shift | ||||||||||
unshare_netns=1 | ||||||||||
|
@@ -328,6 +342,10 @@ while :; do | |||||||||
shift | ||||||||||
unshare_process=1 | ||||||||||
;; | ||||||||||
--unshare-root) | ||||||||||
shift | ||||||||||
unshare_root=1 | ||||||||||
;; | ||||||||||
--unshare-devsys) | ||||||||||
shift | ||||||||||
unshare_devsys=1 | ||||||||||
|
@@ -337,8 +355,10 @@ while :; do | |||||||||
unshare_devsys=1 | ||||||||||
unshare_groups=1 | ||||||||||
unshare_ipc=1 | ||||||||||
unshare_home=1 | ||||||||||
Comment on lines
357
to
+358
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These appear to be alphabetically sorted. I'd exchange these to follow the pattern :D
Suggested change
|
||||||||||
unshare_netns=1 | ||||||||||
unshare_process=1 | ||||||||||
unshare_root=1 | ||||||||||
;; | ||||||||||
-C | --compatibility) | ||||||||||
show_compatibility | ||||||||||
|
@@ -640,11 +660,14 @@ get_clone_image() | |||||||||
# init: bool initful | ||||||||||
# nvidia: bool nvidia integration | ||||||||||
# rootful: bool rootful | ||||||||||
# unprivileged: bool unprivileged | ||||||||||
# unshare_devsys: bool unshare devsys | ||||||||||
# unshare_groups: bool unshare groups | ||||||||||
# unshare_home: bool unshare home dir | ||||||||||
# unshare_ipc: bool unshare ipc | ||||||||||
# unshare_netns: bool unshare netns | ||||||||||
# unshare_process: bool unshare proc | ||||||||||
# unshare_root: bool unshare root dir | ||||||||||
# Expected env variables: | ||||||||||
# None | ||||||||||
# Outputs: | ||||||||||
|
@@ -657,10 +680,6 @@ generate_create_command() | |||||||||
result_command="${result_command} | ||||||||||
--hostname \"${container_hostname}\" | ||||||||||
--name \"${container_name}\" | ||||||||||
--privileged | ||||||||||
--security-opt label=disable | ||||||||||
--security-opt apparmor=unconfined | ||||||||||
--pids-limit=-1 | ||||||||||
--user root:root" | ||||||||||
|
||||||||||
if [ "${unshare_ipc}" -eq 0 ]; then | ||||||||||
|
@@ -690,23 +709,24 @@ generate_create_command() | |||||||||
result_command="${result_command} | ||||||||||
--label \"manager=distrobox\" | ||||||||||
--label \"distrobox.unshare_groups=${unshare_groups}\" | ||||||||||
--label \"distrobox.unshare_home=${unshare_home}\" | ||||||||||
--label \"distrobox.unshare_root=${unshare_root}\" | ||||||||||
--env \"SHELL=$(basename "${SHELL:-"/bin/bash"}")\" | ||||||||||
--env \"HOME=${container_user_home}\" | ||||||||||
--env \"container=${container_manager}\" | ||||||||||
--env \"TERMINFO_DIRS=/usr/share/terminfo:/run/host/usr/share/terminfo\" | ||||||||||
--env \"CONTAINER_ID=${container_name}\" | ||||||||||
--volume /tmp:/tmp:rslave | ||||||||||
--volume \"${distrobox_entrypoint_path}\":/usr/bin/entrypoint:ro | ||||||||||
--volume \"${distrobox_export_path}\":/usr/bin/distrobox-export:ro | ||||||||||
--volume \"${distrobox_hostexec_path}\":/usr/bin/distrobox-host-exec:ro | ||||||||||
--volume \"${container_user_home}\":\"${container_user_home}\":rslave" | ||||||||||
--volume \"${distrobox_hostexec_path}\":/usr/bin/distrobox-host-exec:ro" | ||||||||||
|
||||||||||
# Due to breaking change in https://github.com/opencontainers/runc/commit/d4b670fca6d0ac606777376440ffe49686ce15f4 | ||||||||||
# now we cannot mount /:/run/host as before, as it will try to mount RO partitions as RW thus breaking things. | ||||||||||
# This will ensure we will mount directories one-by-one thus avoiding this problem. | ||||||||||
# | ||||||||||
# This happens ONLY with podman+runc, docker and lilipod are unaffected, so let's do this only if we have podman AND runc. | ||||||||||
if echo "${container_manager}" | grep -q "podman" && ${container_manager} info | grep -q runc; then | ||||||||||
if [ "${unshare_root}" -eq 0 ] && | ||||||||||
echo "${container_manager}" | grep -q "podman" && ${container_manager} info | grep -q runc; then | ||||||||||
for rootdir in /*; do | ||||||||||
|
||||||||||
# Skip symlinks | ||||||||||
|
@@ -727,11 +747,18 @@ generate_create_command() | |||||||||
result_command="${result_command} | ||||||||||
--volume ${rootdir}:/run/host${rootdir}:rslave" | ||||||||||
done | ||||||||||
else | ||||||||||
elif [ "${unshare_root}" -eq 0 ]; then | ||||||||||
# We're either on podman+crun, docker or lilipod, let's keep old behaviour | ||||||||||
result_command="${result_command} | ||||||||||
--volume /:/run/host/:rslave" | ||||||||||
fi | ||||||||||
|
||||||||||
if [ "${unprivileged}" -eq 0 ]; then | ||||||||||
result_command="${result_command} | ||||||||||
--privileged | ||||||||||
--security-opt label=disable | ||||||||||
--security-opt apparmor=unconfined | ||||||||||
--pids-limit=-1" | ||||||||||
fi | ||||||||||
|
||||||||||
if [ "${unshare_devsys}" -eq 0 ]; then | ||||||||||
|
@@ -740,6 +767,12 @@ generate_create_command() | |||||||||
--volume /sys:/sys:rslave" | ||||||||||
fi | ||||||||||
|
||||||||||
if [ "${unshare_home}" -eq 0 ]; then | ||||||||||
result_command="${result_command} | ||||||||||
--env \"HOME=${container_user_home}\" | ||||||||||
--volume \"${container_user_home}\":\"${container_user_home}\":rslave" | ||||||||||
fi | ||||||||||
|
||||||||||
# In case of initful containers, we implement a series of mountpoint in order | ||||||||||
# for systemd to work properly inside a container. | ||||||||||
# The following are a flag-based implementation of what podman's --systemd flag | ||||||||||
|
@@ -864,7 +897,8 @@ generate_create_command() | |||||||||
# Mount also the /var/home dir on ostree based systems | ||||||||||
# do this only if $HOME was not already set to /var/home/username | ||||||||||
if [ "${container_user_home}" != "/var/home/${container_user_name}" ] && | ||||||||||
[ -d "/var/home/${container_user_name}" ]; then | ||||||||||
[ -d "/var/home/${container_user_name}" ] && | ||||||||||
[ "${unshare_home}" -eq 0 ]; then | ||||||||||
|
||||||||||
result_command="${result_command} | ||||||||||
--volume \"/var/home/${container_user_name}\":\"/var/home/${container_user_name}\":rslave" | ||||||||||
|
@@ -873,7 +907,8 @@ generate_create_command() | |||||||||
# Mount also the XDG_RUNTIME_DIR to ensure functionality of the apps. | ||||||||||
# This is skipped in case of initful containers, so that a dedicated | ||||||||||
# systemd user session can be used. | ||||||||||
if [ -d "/run/user/${container_user_uid}" ] && [ "${init}" -eq 0 ]; then | ||||||||||
if [ -d "/run/user/${container_user_uid}" ] && [ "${init}" -eq 0 ] && | ||||||||||
[ "${unshare_root}" -eq 0 ]; then | ||||||||||
result_command="${result_command} | ||||||||||
--volume /run/user/${container_user_uid}:/run/user/${container_user_uid}:rslave" | ||||||||||
fi | ||||||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -365,6 +365,8 @@ fi | |
# skip_workdir: bool skip workdir | ||
# verbose: bool verbose | ||
# unshare_groups | ||
# unshare_home | ||
# unshare_root | ||
# distrobox_enter_path | ||
# Expected env variables: | ||
# PATH | ||
|
@@ -427,8 +429,11 @@ generate_enter_command() | |
# pass distrobox-enter path, it will be used in the distrobox-export tool. | ||
if [ "${skip_workdir}" -eq 0 ]; then | ||
workdir="$(echo "${PWD:-${container_home:-"/"}}" | sed -e 's/"/\\\"/g')" | ||
if [ -n "${workdir##*"${container_home}"*}" ]; then | ||
if [ "${unshare_root:-0}" -eq 0 ] && [ -n "${workdir##*"${container_home}"*}" ]; then | ||
workdir="/run/host${workdir}" | ||
elif ! [ "${unshare_home:-0}" -eq 0 ]; then | ||
# Workdir is unshared, we just enter $HOME of the container. | ||
workdir="${container_home}" | ||
Comment on lines
+434
to
+436
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nice fallback! |
||
fi | ||
else | ||
# Skipping workdir we just enter $HOME of the container. | ||
|
@@ -562,11 +567,15 @@ generate_enter_command() | |
container_home="${HOME}" | ||
container_path="${PATH}" | ||
unshare_groups=0 | ||
unshare_home=0 | ||
unshare_root=0 | ||
# Now inspect the container we're working with. | ||
container_status="unknown" | ||
eval "$(${container_manager} inspect --type container --format \ | ||
'container_status={{.State.Status}}; | ||
unshare_groups={{ index .Config.Labels "distrobox.unshare_groups" }}; | ||
unshare_home={{ index .Config.Labels "distrobox.unshare_home" }}; | ||
unshare_root={{ index .Config.Labels "distrobox.unshare_root" }}; | ||
{{range .Config.Env}}{{if slice . 0 5 | eq "HOME="}}container_home={{slice . 5 | printf "%q"}};{{end}}{{end}} | ||
{{range .Config.Env}}{{if slice . 0 5 | eq "PATH="}}container_path={{slice . 5 | printf "%q"}}{{end}}{{end}}' \ | ||
"${container_name}")" | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1423,12 +1423,14 @@ fi | |
# | ||
# Podman supports a mount option to do this at creation time, but we're doing it | ||
# here to support also other container rmanagers which does not support that flag | ||
mount -t devpts devpts -o noexec,nosuid,newinstance,ptmxmode=0666,mode=0620,gid=tty /dev/pts/ | ||
mount --bind /dev/pts/ptmx /dev/ptmx | ||
{ | ||
mount -t devpts devpts -o noexec,nosuid,newinstance,ptmxmode=0666,mode=0620,gid=tty /dev/pts/ | ||
mount --bind /dev/pts/ptmx /dev/ptmx | ||
} || printf "Warning: Cannot mount devpts\n" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nice to have a warning there. Is there a particular reason, why you did not prepend it with "distrobox: ..." or why you don't print to stderr? Not sure how distrobox normally handles warnings. |
||
|
||
# Change mount propagation to shared to make the environment more similar to a | ||
# modern Linux system, e.g. with Systemd as PID 1. | ||
mount --make-rshared / | ||
mount --make-rshared / || printf "Warning: Cannot remount root as shared\n" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same as above |
||
############################################################################### | ||
|
||
############################################################################### | ||
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -36,11 +36,14 @@ graphical apps (X11/Wayland), and audio. | |||||
this will make host's processes not visible from within the container. (assumes --unshare-process) | ||||||
may require additional packages depending on the container image: https://github.com/89luca89/distrobox/blob/main/docs/useful_tips.md#using-init-system-inside-a-distrobox | ||||||
--nvidia: try to integrate host's nVidia drivers in the guest | ||||||
--unprivileged: do not drop security measures when creating a container | ||||||
--unshare-devsys: do not share host devices and sysfs dirs from host | ||||||
--unshare-groups: do not forward user's additional groups into the container | ||||||
--unshare-home: do not mount host home directory into the container | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same as above
Suggested change
|
||||||
--unshare-ipc: do not share ipc namespace with host | ||||||
--unshare-netns: do not share the net namespace with host | ||||||
--unshare-process: do not share process namespace with host | ||||||
--unshare-root: do not mount host root directory into the container | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same as above
Suggested change
|
||||||
--unshare-all: activate all the unshare flags below | ||||||
--compatibility/-C: show list of compatible images | ||||||
--help/-h: show this message | ||||||
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -58,11 +58,14 @@ usb devices and graphical apps (X11/Wayland), and audio. | |||||
this will make host\[aq]s processes not visible from within the container. (assumes --unshare-process) | ||||||
may require additional packages depending on the container image: https://github.com/89luca89/distrobox/blob/main/docs/useful_tips.md#using-init-system-inside-a-distrobox | ||||||
--nvidia: try to integrate host\[aq]s nVidia drivers in the guest | ||||||
--unprivileged: do not drop security measures when creating a container | ||||||
--unshare-devsys: do not share host devices and sysfs dirs from host | ||||||
--unshare-groups: do not forward user\[aq]s additional groups into the container | ||||||
--unshare-home: do not mount host home directory into the container | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same as above
Suggested change
|
||||||
--unshare-ipc: do not share ipc namespace with host | ||||||
--unshare-netns: do not share the net namespace with host | ||||||
--unshare-process: do not share process namespace with host | ||||||
--unshare-root: do not mount host root directory into the container | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same as above
Suggested change
|
||||||
--unshare-all: activate all the unshare flags below | ||||||
--compatibility/-C: show list of compatible images | ||||||
--help/-h: show this message | ||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nice catch!