You may have found many great resources on how to set up jails on latest FreeBSD, however there is scant information on how to go about creating a barebones jail with nothing but the one process that you want to isolate.
I was curious if I could contain a statically compiled web server that I wrote while learning Rust all by itself in a jail instead of having a full userland.
The benefits are:
- Storage space requirement is trivial: 5MB
- No need to update the jail separately since there is only one additional binary to daemonize the web app
- Updating the web app is as simple as stopping the jail, replacing the binary and restarting, with a shell script on the host, that's fast.
- If an intruder does manage to break in, there is no shell, utility programs or interpreters to leverage
- Working FreeBSD 12.1 machine (this should work on older versions, but I have not tested)
- Working internet connection to download a package (daemonize)
- Static-linked binary web app (with Rust, use
cargo build --release
) - A bit of patience
First, create directories for the jail.
mkdir -p /usr/local/jail/www/{app,dev,lib,libexec,var}
mkdir -p /usr/local/jail/www/var/{log,run}
This will create the following tree structure:
[/usr/local/jail/www]# tree
.
├── app
├── dev
├── lib
├── libexec
└── var
├── log
└── run
6 directories, 0 files
Now copy a few required binaries to the jail:
cp /libexec/ld-elf.so.1 /usr/local/jail/www/libexec/
cp /lib/{libc.so.7,libgcc_s.so.1,libm.so.5,libthr.so.3} /usr/local/jail/www/lib/
The directory tree should look like this:
[/usr/local/jail/www]# tree
.
├── app
├── dev
├── lib
│ ├── libc.so.7
│ ├── libgcc_s.so.1
│ ├── libm.so.5
│ └── libthr.so.3
├── libexec
│ └── ld-elf.so.1
└── var
├── log
└── run
7 directories, 5 files
Install the package daemonize
on host:
pkg install daemonize
Copy the daemonize binary to jail:
cp /usr/local/bin/daemonize /usr/local/jail/www/app/
Now copy your static-linked web app to jail.
Here I'm copying the Rust web app created using Rocket.rs
and compiled for release (cargo build --release
)
cp /home/hiway/source/webapp/target/release/webapp /usr/local/jail/www/app/
The directory tree should look like this now:
[/usr/local/jail/www]# tree
.
├── app
│ ├── daemonize
│ └── webapp
├── dev
├── lib
│ ├── libc.so.7
│ ├── libgcc_s.so.1
│ ├── libm.so.5
│ └── libthr.so.3
├── libexec
│ └── ld-elf.so.1
└── var
├── log
└── run
Next, we will set up jails service.
Edit or create /etc/jail.conf
using your preferred text editor and append the following to it:
Remember to review the values such as ip4.addr
and replace with appropriate values for the interface, ip address and subnet.
www {
host.hostname = "www";
ip4.addr = "wlan0|192.168.0.99/24";
path = "/usr/local/jail/www";
mount.devfs;
exec.start = "/app/daemonize -v -a \
-o /var/log/www.stdout \
-e /var/log/www.stderr \
-p /var/run/www.pid /app/webapp";
exec.stop = "";
}
Enable jail service:
sysrc jail_enable=YES
And finally, start the jail:
service jail start www
Visit http://192.168.0.99:8000/
from your browser and verify that it works.
12.1 died more than a year ago; https://bokut.in/freebsd-patch-level-table/#unsupported.
Please, can you update this for a supported release of FreeBSD? Thanks.