In this short article, I discuss the way to run a full-blown FreeBSD jail, with some common tunings to get it more “normal”.
I assume the host has two network interfaces. The “vtnet0” is Internet-facing and “vtnet1” is the intranet, where the jail will be running on. This way, the jail does not have direct access to the Internet. I also assume we set up the jail at “/root/myjail”. You can define other locations you want.
Installing a Jail
To run an operating system, one need to install it on some media. In context of a jail, we install it to a directory. The FreeBSD handbook tells you to install from source and it is not necessary since BSD system files are mostly tar balls. Download what you require like this. For a minimal system, you will need the “base.txz”. Hmm, no, “kernel.txz” is not required for the jail.
mkdir /root/myjail tar Jxvf base.txz -C /root/myjail
Running a Jail
To run a jail, in particular, with networking, try the following command.
jail -c path=/root/myjail name=myjail \ interface=vtnet1 ip4.addr=10.0.250.240 \ exec.start="/bin/sh /etc/rc"
Where are We?
Here is what it looks like. No, we are not inside the jail. The so-called resource configuration script completed execution and we get back to the shell of the host.
Attaching to Jail
Attaching to a jail is simple. We can simply start one more process in the jail. (There is no such requirement all processes originate from the same process tree.)
jexec myjail /bin/tcsh
When finished, you can get out by hanging up the shell (Ctrl-D). That’s right, you won’t kill the jail by doing this.
Inside the jail, try ping other places, like the host IP…
# ping 10.0.250.1 ping: ssend socket: Operation not permitted
To allow ping, you need to change the following, in the host. If you want to allow this from the beginning, the “allow.raw_sockets=1” option can be passed when the jail is initiated next time.
jail -m name=myjail allow.raw_sockets=1
The Intranet now works. What about going to the Internet?
# ping 126.96.36.199 PING 188.8.131.52 (184.108.40.206): 56 data bytes
Seems there is something wrong with the routing. Modify the PF rules in the host. Put this line before the first block / pass statement. (I assume you have a PF firewall installed.). After you reload the rules (“service pf reload”), it should work.
nat pass vtnet0 from vtnet1:network to any -> (vtnet0)
Domain Name Resolve
Let’s randomly pick a domain name to ping.
# ping yahoo.com ping: cannot resolve yahoo.com: Host name lookup failure
Ask your network administrators if there are suggested name servers. If you have nothing in concern, use anything that works. For my laziness, I use the shortest IP addresses I can recite. Do this inside the guest:
# cat >> /etc/resolv.conf << EOF nameserver 220.127.116.11 nameserver 18.104.22.168 EOF
Or, in the host:
# cat >> /root/myjail/etc/resolv.conf << EOF nameserver 22.214.171.124 nameserver 126.96.36.199 EOF
System tools like “ps” does not work by default:
# ps ps: empty file: invalid argument
I think there could be better ways. But the simplest way is to mount the device file system:
mount -t devfs devfs /root/myjail/dev
Please note it is not necessary a good idea to people you don’t trust.