Skip to content

Commit 10cdbb3

Browse files
committed
docs: Pare down and document AppArmor file; simplify some CI elements
- Remove all unnecessary AppArmor rules, document all directives. - In testing, use a sandbox dir name that doesn't depend on the Python version. There's only ever one at a time in the container. This also simplifies the AppArmor profile and allows us to just have one sudoers file. - Remove example AppArmor profile from README; just point to the one in the apparmor-profiles dir so that we can have a single copy that is maintained with best practices. - Document a more general apparmor_parser directive (`--replace` is usable on both the first and subsequent runs) that surfaces and enforces warnings. This would e.g. fail the load if the ABI mismatches. - Add some breadcrumbs on what the testing files are used for.
1 parent 276c76d commit 10cdbb3

7 files changed

+93
-125
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ jobs:
2323
steps:
2424
- uses: actions/checkout@v4
2525
- name: Parse custom apparmor profile with ABI 3.0
26-
run: sudo apparmor_parser -r -W apparmor-profiles/home.sandbox.codejail_sandbox-python3.bin.python-abi3
26+
run: sudo apparmor_parser -r -W apparmor-profiles/home.sandbox.codejail_sandbox.bin.python-abi3
2727

2828
- name: Build latest code changes into CI image
2929
run: |

Dockerfile

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
# Used for running codejail unit tests.
2+
#
3+
# Sandbox path and ABI version must be kept in sync with AppArmor profile.
4+
15
ARG ubuntu_version="24.04"
26

37
FROM ubuntu:${ubuntu_version}
@@ -19,7 +23,7 @@ RUN pip install virtualenv
1923
ENV CODEJAIL_GROUP=sandbox
2024
ENV CODEJAIL_SANDBOX_CALLER=ubuntu
2125
ENV CODEJAIL_TEST_USER=sandbox
22-
ENV CODEJAIL_TEST_VENV=/home/sandbox/codejail_sandbox-python${python_version}
26+
ENV CODEJAIL_TEST_VENV=/home/sandbox/codejail_sandbox
2327

2428
# Create Virtualenv for sandbox user
2529
RUN virtualenv -p python${python_version} --always-copy $CODEJAIL_TEST_VENV
@@ -65,7 +69,7 @@ RUN pip install -r /codejail/requirements/sandbox.txt -r /codejail/requirements/
6569
COPY . /codejail
6670

6771
# Setup sudoers file
68-
COPY sudoers-file/01-sandbox-python-${python_version} /etc/sudoers.d/01-sandbox
72+
COPY sudoers-file/01-sandbox-python /etc/sudoers.d/01-sandbox
6973

7074
# Change Sudoers file permissions
7175
RUN chmod 0440 /etc/sudoers.d/01-sandbox

README.rst

Lines changed: 5 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -114,61 +114,17 @@ Other details here that depend on your configuration:
114114
(Note that the ``find`` binary can run arbitrary code, so this is not a safe sudoers file for non-codejail purposes.)
115115

116116
5. Edit an AppArmor profile. This is a text file specifying the limits on the
117-
sandboxed Python executable. The file must be in ``/etc/apparmor.d`` and must
117+
sandboxed Python executable. The file must be in ``/etc/apparmor.d`` and should
118118
be named based on the executable, with slashes replaced by dots. For
119119
example, if your sandboxed Python is at ``/home/chris/ve/myproj-sandbox/bin/python``,
120-
then your AppArmor profile must be ``/etc/apparmor.d/home.chris.ve.myproj-sandbox.bin.python``::
120+
then your AppArmor profile must be ``/etc/apparmor.d/home.chris.ve.myproj-sandbox.bin.python``.
121121

122-
$ sudo vim /etc/apparmor.d/home.chris.ve.myproj-sandbox.bin.python
123-
124-
#include <tunables/global>
125-
126-
<SANDENV>/bin/python {
127-
#include <abstractions/base>
128-
#include <abstractions/python>
129-
130-
<CODEJAIL_CHECKOUT>/** mr,
131-
<SANDENV>/** mr,
132-
# If you have code that the sandbox must be able to access, add lines
133-
# pointing to those directories:
134-
/the/path/to/your/sandbox-packages/** r,
135-
136-
/tmp/codejail-*/ rix,
137-
/tmp/codejail-*/** wrix,
138-
}
139-
140-
Depending on your OS and AppArmor version you may need to specify a policy
141-
ABI to ensure the restrictions are being correctly applied. Modern ubuntu
142-
versions using AppArmor V3 should use the 3.0 ABI in order to enable
143-
network confinment rules. A profile using the ABI 3.0 would look as
144-
follows::
145-
146-
$ sudo vim /etc/apparmor.d/home.chris.ve.myproj-sandbox.bin.python
147-
148-
abi <abi/3.0>,
149-
#include <tunables/global>
150-
151-
<SANDENV>/bin/python {
152-
#include <abstractions/base>
153-
#include <abstractions/python>
154-
155-
<CODEJAIL_CHECKOUT>/** mr,
156-
<SANDENV>/** mr,
157-
# If you have code that the sandbox must be able to access, add lines
158-
# pointing to those directories:
159-
/the/path/to/your/sandbox-packages/** r,
160-
161-
/tmp/codejail-*/ rix,
162-
/tmp/codejail-*/** wrix,
163-
}
164-
165-
You can also look at the
166-
``apparmor-profiles/home.sandbox.codejail_sandbox-python3.bin.python-abi3``
167-
file which is used for testing for a full profile example.
122+
See sample profile in ``apparmor-profiles/``. The profile **must be
123+
customized** to match your sandbox location.
168124

169125
6. Parse the profiles::
170126

171-
$ sudo apparmor_parser <APPARMOR_FILE>
127+
$ sudo apparmor_parser --replace --warn=all --warn=no-debug-cache --Werror <APPARMOR_FILE>
172128

173129
7. Reactivate your project's main virtualenv again.
174130

apparmor-profiles/home.sandbox.codejail_sandbox-python3.bin.python-abi3

Lines changed: 0 additions & 64 deletions
This file was deleted.
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
# Used for running codejail unit tests, but should also be maintained as a
2+
# general example.
3+
#
4+
# Sandbox path must be kept in sync with Dockerfile.
5+
6+
7+
# AppArmor profile for running codejail.
8+
#
9+
# Changes to this profile must be coordinated carefully with changes to the
10+
# filesystem layout -- in particular, the sandbox path must match, otherwise
11+
# the profile will provide no security at all.
12+
#
13+
# #=========#
14+
# # WARNING #
15+
# #=========#
16+
#
17+
# Failure to apply a secure apparmor profile *will* likely result in a
18+
# full compromise of the host by an attacker. AppArmor is *mandatory*
19+
# for using codejail -- this is not just for hardening.
20+
#
21+
# This profile is written for AppArmor 3 or higher (Ubuntu 22.04 or higher).
22+
23+
24+
25+
# Require that the system understands the feature set that this policy was written
26+
# for. If we didn't include this, then on Ubuntu >= 22.04, AppArmor might assume
27+
# the wrong feature set was requested, and some rules might become too permissive.
28+
# See https://github.com/netblue30/firejail/issues/3659#issuecomment-711074899
29+
#
30+
# This should also be set to match the installed AppArmor version.
31+
abi <abi/3.0>,
32+
33+
# Sets standard variables used by abstractions/base, later. Controlled
34+
# by OS, see /etc/apparmor.d/tunables/global for contents.
35+
include <tunables/global>
36+
37+
# `mediate_deleted` instructs apparmor to continue to make policy decisions
38+
# in cases where a confined executable has a file descriptor even after the
39+
# file is removed from the filesystem. It's unclear if this is important for
40+
# sandboxing, but it doesn't seem like it would loosen security or interfere
41+
# with functionality to include it.
42+
#
43+
# `no_attach_disconnected` is default, but is explicitly indicated
44+
# here because `attach_disconnected` is very commonly used in
45+
# example profiles despite being a security risk (due to allowing
46+
# disconnected objects to masquerade as other, trusted paths in the
47+
# filesystem).
48+
profile openedx_codejail_sandbox /home/sandbox/codejail_sandbox/bin/python flags=(mediate_deleted, no_attach_disconnected) {
49+
50+
# Allow access to a variety of commonly needed, generally safe things
51+
# (such as reading /usr/lib, /dev/random, free memory levels, etc.)
52+
#
53+
# Manpage: "Includes files that should be readable and writable in all profiles."
54+
#
55+
# We could instead list these directives explicitly out of caution but
56+
# it would get pretty verbose.
57+
include <abstractions/base>
58+
59+
# Read and run binaries and libraries in the virtualenv. This
60+
# includes the sandbox's copy of Python as well as any
61+
# dependencies that have been installed for inclusion in
62+
# sandboxes.
63+
#
64+
# m: executable mapping, required for shared libraries used by some
65+
# Python dependencies with C compontents, eg `nltk`.
66+
/home/sandbox/codejail_sandbox/** mr,
67+
68+
# Allow access to the temporary directories that are set up by
69+
# codejail, one for each code-exec call. Each /tmp/code-XXXXX
70+
# contains one execution.
71+
/tmp/codejail-*/ rix,
72+
/tmp/codejail-*/** wrix,
73+
74+
# Allow receiving a kill signal from the webapp when the execution
75+
# runs beyond time limits.
76+
signal (receive) set=(kill),
77+
}
Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1-
ubuntu ALL=(sandbox) SETENV:NOPASSWD:/home/sandbox/codejail_sandbox-python3.11/bin/python
1+
# Used for running codejail unit tests.
2+
3+
ubuntu ALL=(sandbox) SETENV:NOPASSWD:/home/sandbox/codejail_sandbox/bin/python
24
ubuntu ALL=(sandbox) SETENV:NOPASSWD:/usr/bin/find
35
ubuntu ALL=(ALL) NOPASSWD:/usr/bin/pkill
46

5-
Defaults!/home/sandbox/codejail_sandbox-python3.11/bin/python !requiretty
7+
Defaults!/home/sandbox/codejail_sandbox/bin/python !requiretty
68
Defaults!/usr/bin/find !requiretty
79
Defaults!/usr/bin/pkill !requiretty

sudoers-file/01-sandbox-python-3.8

Lines changed: 0 additions & 7 deletions
This file was deleted.

0 commit comments

Comments
 (0)