jailmaker/README.md

236 lines
12 KiB
Markdown
Raw Normal View History

2023-01-28 22:09:54 +00:00
# Jailmaker
Persistent Linux 'jails' on TrueNAS SCALE to install software (k3s, docker, portainer, podman, etc.) with full access to all files via bind mounts.
2023-01-28 22:09:54 +00:00
2024-04-28 10:04:10 +00:00
## Video Tutorial
[![TrueNAS Scale - Setting up Sandboxes with Jailmaker - YouTube Video](https://img.youtube.com/vi/S0nTRvAHAP8/0.jpg)<br>Watch on YouTube](https://www.youtube.com/watch?v=S0nTRvAHAP8 "TrueNAS Scale - Setting up Sandboxes with Jailmaker - YouTube Video")
2023-01-28 22:09:54 +00:00
## Disclaimer
**USING THIS SCRIPT IS AT YOUR OWN RISK! IT COMES WITHOUT WARRANTY AND IS NOT SUPPORTED BY IXSYSTEMS.**
2023-01-29 11:58:28 +00:00
2023-01-28 22:09:54 +00:00
## Summary
2024-07-16 15:28:19 +00:00
TrueNAS SCALE can create persistent Linux 'jails' with systemd-nspawn. This app helps with the following:
2023-01-28 22:09:54 +00:00
- Setting up the jail so it won't be lost when you update SCALE
2023-10-28 08:52:31 +00:00
- Choosing a distro (Debian 12 strongly recommended, but Ubuntu, Arch Linux or Rocky Linux seem good choices too)
- Will create a ZFS Dataset for each jail if the `jailmaker` directory is a dataset (easy snapshotting)
2023-01-28 22:09:54 +00:00
- Optional: configuring the jail so you can run Docker inside it
2024-04-28 09:57:41 +00:00
- Optional: GPU passthrough (including nvidia GPU with the drivers bind mounted from the host)
2023-01-28 22:09:54 +00:00
- Starting the jail with your config applied
## Installation
2024-07-16 15:28:19 +00:00
Beginning with 24.04 (Dragonfish), TrueNAS SCALE officially includes the systemd-nspawn containerization program in the base system. Technically there's nothing to install. You only need the `jlmkr` app in the right place. [Instructions with screenshots](https://www.truenas.com/docs/scale/scaletutorials/apps/sandboxes/) are provided on the TrueNAS website. Start by creating a new dataset called `jailmaker` with the default settings (from TrueNAS web interface). Then login as the root user and download `jlmkr`.
TODO: update install instructions. For now one may clone or download the repo and run the below commands to create the `jlmkr` zipapp.
2023-01-28 22:09:54 +00:00
```shell
2024-07-16 15:28:19 +00:00
rm -rf /tmp/jlmkr-build
mkdir -p /tmp/jlmkr-build
cd /tmp/jlmkr-build
curl -L https://github.com/Jip-Hop/jailmaker/archive/refs/heads/v3.0.0.tar.gz | tar xvz --strip-components=1
python3 -m zipapp src/jlmkr -p "/usr/bin/env python3" -o jlmkr
cp jlmkr /mnt/mypool/jailmaker/
2023-08-12 16:14:09 +00:00
```
2024-07-16 15:28:19 +00:00
Alternatively one may download and extract `jlmkr` from the build artifacts of the [GitHub Actions](https://github.com/Jip-Hop/jailmaker/actions).
The `jlmkr` app (and the jails + config it creates) are now stored on the `jailmaker` dataset and will survive updates of TrueNAS SCALE. If the automatically created `jails` directory is also a ZFS dataset (which is true for new users), then the `jlmkr` app will automatically create a new dataset for every jail created. This allows you to snapshot individual jails. For legacy users (where the `jails` directory is not a dataset) each jail will be stored in a plain directory.
2024-05-28 18:55:46 +00:00
### Alias
2024-07-16 15:28:19 +00:00
TODO: explain how to run `jlmkr` without using the absolute path. This probably involves building and releasing the `zipapp` on GitHub, downloading it into a directory added to the `PATH`. But this also requires the `jailmaker` directory to be configurable (instead of using the directory the `jlmkr` app itself is in) by using the `JAILMAKER_DIR` env variable.
2024-05-28 18:55:46 +00:00
2024-07-16 15:28:19 +00:00
```bash
mkdir /root/bin
cd /root/bin
curl -o jlmkr --location --remote-name https://some_url
chmod +x jlmkr
cd ../
echo 'export PATH="/root/bin:$PATH"' | tee -a .bashrc .zshrc
echo 'export JAILMAKER_DIR=/mnt/tank/path/to/desired/jailmaker/dir' | tee -a .bashrc .zshrc
2024-05-28 18:55:46 +00:00
```
2023-08-15 12:48:22 +00:00
## Usage
### Create Jail
2023-01-28 22:09:54 +00:00
Creating a jail with the default settings is as simple as:
2023-01-28 22:09:54 +00:00
```shell
2024-07-16 15:28:19 +00:00
./jlmkr create --start myjail
2023-01-28 22:09:54 +00:00
```
You may also specify a path to a config template, for a quick and consistent jail creation process.
```shell
2024-07-16 15:28:19 +00:00
./jlmkr create --start --config /path/to/config/template myjail
2024-03-01 16:35:05 +00:00
```
2024-07-16 15:28:19 +00:00
Or you can override the default config by using flags. See `./jlmkr create --help` for the available options. Anything passed after the jail name will be passed to `systemd-nspawn` when starting the jail. See the `systemd-nspawn` manual for available options, specifically [Mount Options](https://manpages.debian.org/bookworm/systemd-container/systemd-nspawn.1.en.html#Mount_Options) and [Networking Options](https://manpages.debian.org/bookworm/systemd-container/systemd-nspawn.1.en.html#Networking_Options) are frequently used.
2024-03-02 16:20:50 +00:00
```shell
2024-07-16 15:28:19 +00:00
./jlmkr create --start --distro=ubuntu --release=jammy myjail --bind-ro=/mnt
2024-03-02 16:20:50 +00:00
```
2024-03-01 16:35:05 +00:00
If you omit the jail name, the create process is interactive. You'll be presented with questions which guide you through the process.
```shell
2024-07-16 15:28:19 +00:00
./jlmkr create
```
2023-01-29 11:58:28 +00:00
After answering some questions you should have created your first jail (and it should be running if you chose to start it after creating)!
2024-03-01 16:35:05 +00:00
2023-08-15 17:28:43 +00:00
### Startup Jails on Boot
```shell
2024-07-16 15:28:19 +00:00
# Call startup using the absolute path to jlmkr
/mnt/mypool/jailmaker/jlmkr startup
2023-08-15 17:28:43 +00:00
```
2023-01-28 22:09:54 +00:00
2024-07-16 15:28:19 +00:00
In order to start jails automatically after TrueNAS boots, run `/mnt/mypool/jailmaker/jlmkr startup` as Post Init Script with Type `Command` from the TrueNAS web interface. This will start all the jails with `startup=1` in the config file.
2023-01-28 22:09:54 +00:00
2023-08-15 12:48:22 +00:00
### Start Jail
2023-03-02 20:52:16 +00:00
```shell
2024-07-16 15:28:19 +00:00
./jlmkr start myjail
2023-03-02 20:52:16 +00:00
```
2023-08-15 12:48:22 +00:00
### List Jails
2023-03-02 20:52:16 +00:00
2024-05-09 12:33:27 +00:00
See list of jails (including running, startup state, GPU passthrough, distro, and IP).
2023-03-02 20:52:16 +00:00
```shell
2024-07-16 15:28:19 +00:00
./jlmkr list
2023-03-02 20:52:16 +00:00
```
2023-01-28 22:09:54 +00:00
2023-08-15 12:48:22 +00:00
### Execute Command in Jail
2023-08-15 12:45:52 +00:00
2024-05-09 12:33:27 +00:00
You may want to execute a command inside a jail, for example manually from the TrueNAS shell, a shell script or a CRON job. The example below executes the `env` command inside the jail.
2023-08-15 12:45:52 +00:00
```shell
2024-07-16 15:28:19 +00:00
./jlmkr exec myjail env
2023-08-15 12:45:52 +00:00
```
This example executes bash inside the jail with a command as additional argument.
```shell
2024-07-16 15:28:19 +00:00
./jlmkr exec myjail bash -c 'echo test; echo $RANDOM;'
2023-08-15 12:45:52 +00:00
```
2023-08-15 12:48:22 +00:00
### Edit Jail Config
2023-08-14 14:12:33 +00:00
```shell
2024-07-16 15:28:19 +00:00
./jlmkr edit myjail
2023-08-14 14:12:33 +00:00
```
2024-07-16 15:28:19 +00:00
Once you've created a jail, it will exist in a directory inside the `jails` dir next to `jlmkr`. For example `/mnt/mypool/jailmaker/jails/myjail` if you've named your jail `myjail`. You may edit the jail configuration file using the `./jlmkr edit myjail` command. This opens the config file in your favorite editor, as determined by following [Debian's guidelines](https://www.debian.org/doc/debian-policy/ch-customized-programs.html#editors-and-pagers) on the matter. You'll have to stop the jail and start it again with `jlmkr` for these changes to take effect.
2023-08-14 14:12:33 +00:00
2023-08-15 12:48:22 +00:00
### Remove Jail
2023-03-02 20:52:16 +00:00
2024-05-09 12:33:27 +00:00
Delete a jail and remove it's files (requires confirmation).
2023-03-02 20:52:16 +00:00
```shell
2024-07-16 15:28:19 +00:00
./jlmkr remove myjail
2023-03-02 20:52:16 +00:00
```
2023-08-15 12:48:22 +00:00
### Stop Jail
2023-03-03 18:46:25 +00:00
```shell
2024-07-16 15:28:19 +00:00
./jlmkr stop myjail
2023-03-03 18:46:25 +00:00
```
2024-02-08 06:39:54 +00:00
### Restart Jail
```shell
2024-07-16 15:28:19 +00:00
./jlmkr restart myjail
2024-02-08 06:39:54 +00:00
```
2023-08-15 12:48:22 +00:00
### Jail Shell
2023-01-28 22:09:54 +00:00
2024-05-09 12:33:27 +00:00
Switch into the jail's shell.
2023-01-28 22:09:54 +00:00
```shell
2024-07-16 15:28:19 +00:00
./jlmkr shell myjail
2023-01-28 22:09:54 +00:00
```
2023-08-15 12:48:22 +00:00
### Jail Status
2023-01-28 22:09:54 +00:00
```shell
2024-07-16 15:28:19 +00:00
./jlmkr status myjail
2023-01-28 22:09:54 +00:00
```
2023-08-15 12:48:22 +00:00
### Jail Logs
2023-01-28 22:09:54 +00:00
2024-05-09 12:33:27 +00:00
View a jail's logs.
2023-01-28 22:09:54 +00:00
```shell
2024-07-16 15:28:19 +00:00
./jlmkr log myjail
2023-01-28 22:09:54 +00:00
```
2023-08-15 12:48:22 +00:00
### Additional Commands
2023-08-15 11:58:47 +00:00
2024-07-16 15:28:19 +00:00
Expert users may use the following additional commands to manage jails directly: `machinectl`, `systemd-nspawn`, `systemd-run`, `systemctl` and `journalctl`. The `jlmkr` app uses these commands under the hood and implements a subset of their functions. If you use them directly you will bypass any safety checks or configuration done by `jlmkr` and not everything will work in the context of TrueNAS SCALE.
2023-08-15 11:58:47 +00:00
2024-05-28 18:55:46 +00:00
## Security
By default the root user in the jail with uid 0 is mapped to the host's uid 0. This has [obvious security implications](https://linuxcontainers.org/lxc/security/#privileged-containers). If this is not acceptable to you, you may lock down the jails by [limiting capabilities](https://manpages.debian.org/bookworm/systemd-container/systemd-nspawn.1.en.html#Security_Options) and/or using [user namespacing](https://manpages.debian.org/bookworm/systemd-container/systemd-nspawn.1.en.html#User_Namespacing_Options) or use a VM instead.
### Seccomp
Seccomp is a Linux kernel feature that restricts programs from making unauthorized system calls. This means that when seccomp is enabled there can be times where a process run inside a jail will be killed with the error "Operation not permitted." In order to find out which syscall needs to be added to the `--system-call-filter=` configuration you can use `strace`.
For example:
```
# /usr/bin/intel_gpu_top
Failed to initialize PMU! (Operation not permitted)
# strace /usr/bin/intel_gpu_top 2>&1 |grep Operation\ not\ permitted
perf_event_open({type=0x10 /* PERF_TYPE_??? */, size=PERF_ATTR_SIZE_VER7, config=0x100002, sample_period=0, sample_type=0, read_format=PERF_FORMAT_TOTAL_TIME_ENABLED|PERF_FORMAT_GROUP, precise_ip=0 /* arbitrary skid */, use_clockid=1, ...}, -1, 0, -1, 0) = -1 EPERM (Operation not permitted)
write(2, "Failed to initialize PMU! (Opera"..., 52Failed to initialize PMU! (Operation not permitted)
```
The syscall that needs to be added to the `--system-call-filter` option in the `jailmaker` config in this case would be `perf_event_open`. You may need to run strace multiple times.
Seccomp is important for security, but as a last resort can be disabled by setting `seccomp=0` in the jail config.
2023-01-28 22:09:54 +00:00
## Networking
2024-05-09 12:33:27 +00:00
By default a jails will use the same networking namespace, with access to all (physical) interfaces the TrueNAS host has access to. No further setup is required. You may download and install additional packages inside the jail. Note that some ports are already occupied by TrueNAS SCALE (e.g. 443 for the web interface), so your jail can't listen on these ports.
Depending on the service this may be o.k. For example Home Assistant will bind to port 8123, leaving the 80 and 443 ports free from clashes for the TrueNAS web interface. You can then either connect to the service on 8123, or use a reverse proxy such as traefik.
But clashes may happen if you want some services (e.g. traefik) inside the jail to listen on port 443. To workaround this issue when using host networking, you may disable DHCP and add several static IP addresses (Aliases) through the TrueNAS web interface. If you setup the TrueNAS web interface to only listen on one of these IP addresses, the ports on the remaining IP addresses remain available for the jail to listen on.
2023-01-28 22:09:54 +00:00
2024-05-09 12:33:27 +00:00
See [the networking docs](./docs/network.md) for more advanced options (bridge and macvlan networking).
2023-01-28 22:09:54 +00:00
2023-01-28 22:24:12 +00:00
## Docker
2024-05-09 12:33:27 +00:00
Using the [docker config template](./templates/docker/README.md) is recommended if you want to run docker inside the jail. You may of course manually install docker inside a jail. But keep in mind that you need to add `--system-call-filter='add_key keyctl bpf'` (or disable seccomp filtering). It is [not recommended to use host networking for a jail in which you run docker](https://github.com/Jip-Hop/jailmaker/issues/119). Docker needs to manage iptables rules, which it can safely do in its own networking namespace (when using [bridge or macvlan networking](./docs/network.md) for the jail).
2023-01-28 22:24:12 +00:00
2023-10-28 08:52:31 +00:00
## Documentation
2024-05-09 12:33:27 +00:00
Additional documentation can be found in [the docs directory](./docs/) (contributions are welcome!).
2023-10-28 08:52:31 +00:00
2023-01-28 22:09:54 +00:00
## Comparison
2023-08-15 17:28:43 +00:00
TODO: write comparison between systemd-nspawn (without `jailmaker`), LXC, VMs, Docker (on the host).
2023-01-28 22:09:54 +00:00
2024-01-20 15:45:23 +00:00
## Incompatible Distros
2023-01-29 11:58:28 +00:00
2024-07-16 15:28:19 +00:00
The rootfs image `jlmkr` downloads comes from the [Linux Containers Image server](https://images.linuxcontainers.org). These images are made for LXC. We can use them with systemd-nspawn too, although not all of them work properly. For example, the `alpine` image doesn't work well. If you stick with common systemd based distros (Debian, Ubuntu, Arch Linux...) you should be fine.
2024-07-13 03:08:12 +00:00
## Filing Issues and Community Support
2024-05-28 18:55:46 +00:00
When in need of help or when you think you've found a bug in `jailmaker`, [please start with reading this](https://github.com/Jip-Hop/jailmaker/discussions/135).
2023-01-28 22:09:54 +00:00
## References
- [TrueNAS Forum Thread about Jailmaker](https://forums.truenas.com/t/linux-jails-sandboxes-containers-with-jailmaker/417)
2024-03-31 14:44:30 +00:00
- [systemd-nspawn](https://manpages.debian.org/bookworm/systemd-container/systemd-nspawn.1.en.html)
- [machinectl](https://manpages.debian.org/bookworm/systemd-container/machinectl.1.en.html)
- [systemd-run](https://manpages.debian.org/bookworm/systemd/systemd-run.1.en.html)
2023-01-28 22:24:12 +00:00
- [Run docker in systemd-nspawn](https://wiki.archlinux.org/title/systemd-nspawn#Run_docker_in_systemd-nspawn)
2023-06-15 08:12:32 +00:00
- [The original Jailmaker gist](https://gist.github.com/Jip-Hop/4704ba4aa87c99f342b2846ed7885a5d)