Isolating Python and Jupyter using firejail
Motivation for this is already documented in e.g. python security post. Here the aim is to be able run isolated Python processes on a fully ad-hoc basis without need to be thinking about long-lived containers. This approach is based more on filesystem hierarchy and integrates better with traditional unix tools.
Aims
- Python processes can only read and write data within a project filesystem tree
- Python can see the internet only during installation of packages, but during this time it can not see the rest of project
- During running the project Python can not communicate with internet, and can not change any information which it sees during stage (2)
- Can use Jupyter and friends as normal
Implementation
The project directory has to exist before start:
export PROJ=$HOME/j/t3
mkdir -p $PROJ
I am using pyenv to install arbitrary python versions, so give access to it. In first step of creating the virtual env there is no need for network:
firejail --whitelist=$HOME/.pyenv/ --read-only=$HOME/.pyenv/ --whitelist=$PROJ --net=none python3 -m venv $PROJ/.venv
To install packages enable network, but disable access to rest of project, only allow the .venv:
firejail --whitelist=$HOME/.pyenv/ --read-only=$HOME/.pyenv/ --whitelist=$PROJ/.venv $PROJ/.venv/bin/pip3 install --upgrade pybind11 setuptools jupyter
To run Jupyter disable networking but launch Jupyter listening on a Unix socket. Mount the “.venv” read-only so that any subsequent package installs with network can not leak info:
firejail --whitelist=$HOME/.pyenv/ --read-only=$HOME/.pyenv/ --whitelist=$PROJ --read-only=$PROJ/.venv --net=none $PROJ/.venv/bin/jupyter notebook --sock $PROJ/jupyter.sock --no-browser