Jail
It is a mechanism that allows multiple virtual FreeBSD environments to be created on a FreeBSD environment.
A jail is an extension of chroot, and a jail environment (called a prisoners) built on a host ring (called a jailer) behaves as a FreeBSD machine running separately from the host environment.
The prisoner cannot directly attach to the jailer or another parallel prisoner.
Features of JAIL
・High speed operation because it is not emulation.
・Each prisoner can be assigned an IP address different from that of the jailer.
・Since the same file system is used for a jailer and a prisoner, it is necessary to be careful about the assignment of UID/GID.
This time, build two prisoners (prisoner1 and prisoner2) in jailer (FreeBSD14.4)
Building Jail
1.Creation of PRISONER base directory
Create a directory (jail) that will be the root directory for prisoner1 and prisoner2. In this case, we will create them in /home, but you can create them anywhere you like.
|
1 2 3 |
# mkdir /home/jail # mkdir /home/jail/prisoner1 # mkdir /home/jail/prisoner2 |
2.Base System Installation
Install the base system on prisoner1 and prisoner2. Download base.txz from the FreeBSD repository and extract it to prisoner1 and prisoner2.
|
1 2 3 4 |
# fetch ftp://ftp.freebsd.org/pub/FreeBSD/releases/amd64/amd64/14.3-RELEASE/base.txz # tar -zxpf base.txz -C /home/jail/prisoner1 # tar -zxpf base.txz -C /home/jail/prisoner2 # rm base.txz |
3.Copy /etc/resolv.conf
Create a "resolv.conf" file for prisoner1 and prisoner2 to enable name resolution.
Since the contents of "resolv.conf" are the same as those of jailer, copy this file from the jailer side.
|
1 2 |
# cp -p /etc/resolv.conf /home/jail/prisoner1/etc/ # cp -p /etc/resolv.conf /home/jail/prisoner2/etc/ |
4.Suppress kernel-related log output in prisoner
Edit "syslog.conf" to prevent kernel-related output in prisoner1 and prisoner2 logs.
|
1 2 3 4 |
# vi /home/jail/prisoner1/etc/syslog.conf Line 7 : comment-out #*.err;kern.warning;auth.notice;mail.crit /dev/console |
|
1 2 3 4 |
# vi /home/jail/prisoner2/etc/syslog.conf Line 7 : comment-out #*.err;kern.warning;auth.notice;mail.crit /dev/console |
5.Stopping adjkerntz
Edit the crontab so that the kernel time zone is not set by each prisoner's cron.
(Since the kernel time zone is set periodically by the jailer's cron, it is not necessary to set the time zone by the prisoner's cron.)
|
1 2 3 4 |
# vi /home/jail/prisoner1/etc/crontab Line 22 : comment-out #1,31 0-5 * * * root adjkerntz -a |
|
1 2 3 4 |
# vi /home/jail/prisoner2/etc/crontab Line 22 : comment-out #1,31 0-5 * * * root adjkerntz -a |
6.Settings for PRISONER name resolution
Edit "hosts" so that prisoner1 and prisoner2 can resolve their own names.
Add the IP address and FQDN pairs to be assigned to prisoner1 and prisoner2.
|
1 2 3 4 |
# vi /home/jail/prisoner1/etc/hosts Add to last line 192.168.11.31 bsd1.korodes.com |
|
1 2 3 4 |
# vi /home/jail/prisoner2/etc/hosts Add to last line 192.168.11.32 bsd2.korodes.com |
7.Setting up a jailer and prisoner to avoid duplicating UID/GIDs
In a jail, the jailer and each prisoner share a single file system, so if the UID/GID used on the jailer side is used on the prisoner side without modification, the user on the jailer side can treat the user's files on the prisoner side as his or her own. Therefore, the user on the jailer side and each user on the prisoner side must be treated as the same. Therefore, it is necessary to assign non-overlapping UID/GIDs to the jailer and each prisoner.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
# vi /etc/pw.conf defaultpasswd no minuid 10000 maxuid 19999 mingid 10000 maxgid 19999 # vi /home/jail/prisoner1/etc/pw.conf defaultpasswd no minuid 20000 maxuid 29999 mingid 20000 maxgid 29999 # vi /home/jail/prisoner2/etc/pw.conf defaultpasswd no minuid 30000 maxuid 39999 mingid 30000 maxgid 39999 |
※ However, for predefined users such as "root" and users added via ports such as "pgsql" and "postfix", the same UID/GID is assigned to the jailer and prisoner.
To change the UID/GID of these users, use "vipw" to change the UID/GID directly.
(Changing the UID/GID with "vipw" does not automatically update the UID/GID of the owner of files owned by these users, so it is necessary to chown/chgrp them.)
8.Mounting of prisoner1 and prisoner2 devfs
Mount the dev of each prisoner so that the device is available on each prisoner.
|
1 2 |
# mount -t devfs devfs /home/jail/prisoner1/dev # mount -t devfs devfs /home/jail/prisoner2/dev |
9.Settings in PRISONER
Use "chroot" to move to the root directory of PRISONER1 and PRISONER2 and configure the settings.
(Use "exit" to return to the jailer side from the chrooted directory.)
|
1 2 3 4 5 |
# chroot /home/jail/prisoner1 # touch /etc/wall_cmos_clock # ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime # passwd root # exit |
|
1 2 3 4 5 |
# chroot /home/jail/prisoner2 # touch /etc/wall_cmos_clock # ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime # passwd root # exit |
At the end of each, set the root password for that prisoner (this password is distinct from the root password for the jailer).
10.Configuration for starting the jail environment
On the jailer side, set the IP address, FQDN, etc. to be assigned to the prisoner1 and prisoner2 sides.
Add the following to the end of "/etc/rc.conf".
em0 should be set to the name of the interface of each user.
|
1 2 3 4 5 6 7 8 |
# vi /etc/rc.conf ifconfig_em0_alias0="inet 192.168.11.31 netmask 255.255.255.255" ifconfig_em0_alias1="inet 192.168.11.32 netmask 255.255.255.255" jail_enable="YES" jail_list="prisoner1 prisoner2 " #jail_sysvipc_allow="YES" |
"jail_sysvipc_allow=" is a setting to allow or deny access to shared memory from processes on the prisoner.
For security purposes, set to "NO", but set to "YES" when running software that uses shared memory, such as PostgreSQL.
Describe the settings of prisoner1 and prisoner2 in "/etc/jail.conf" as follows
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
# vi /etc/jail.conf prisoner1 { jid=1; path="/home/jail/prisoner1"; ip4.addr=192.168.11.31; host.hostname="bsd1.korodes.com"; allow.chflags=1; allow.raw_sockets=1; exec.start="/bin/sh /etc/rc"; exec.stop="/bin/sh /etc/rc.shutdown jail"; interface=em0; mount.devfs; devfs_ruleset=4; } prisoner2 { jid=2; path="/home/jail/prisoner2"; ip4.addr=192.168.11.32; host.hostname="bsd2.korodes.com"; allow.chflags=1; allow.raw_sockets=1; exec.start="/bin/sh /etc/rc"; exec.stop="/bin/sh /etc/rc.shutdown jail"; interface=em0; mount.devfs; devfs_ruleset=4; } |
By default, programs that use raw sockets such as traceroute, ping, WIDE-DHCP using bpf, etc. do not work properly in prisoner
To use these programs, add the setting "allow.raw_sockets;" in each prisoner setting in "/etc/jail.conf".
Reboot the system
Enable each prisoner.
11.Remove PRISONER
To rebuild the PRISONER environment from scratch again, delete and rebuild PRISONER as follows
When deleting PRISONER1
|
1 2 3 4 5 |
# /etc/rc.d/jail stop prisoner1 # chflags -R noschg /home/jail/prisoner1/* # rm -R /home/jail/prisoner1/* |
12.Jail-related commands available in Jailer
①List of prisonser in operation
|
1 2 3 4 |
# jls JID IP Address Hostname Path 1 192.168.11.31 bsd1.korodes.com /home/jail/prisoner1 2 192.168.11.32 bsd2.korodes.com /home/jail/prisoner2 |
The "JID" displayed on the leftmost side is an ID assigned to a prisoner, and is used to identify the prisoner to be moved by "jexec" as described below.
➁Transition from JAILER to PRISONER
JWhen transitioning to a PRISONER with an ID of "1" using the shell "/bin/csh"
|
1 |
# jexec 1 /bin/csh |
➂Start/Stop PRISONER
|
1 2 3 4 5 6 7 8 9 10 11 |
Stopping all prisonser # /etc/rc.d/jail stop Start of all prisoner # /etc/rc.d/jail start Start by specifying a specific prisoner # /etc/rc.d/jail start prisoner1 Stop by specifying a specific prisoner # /etc/rc.d/jail stop prisoner1 |
13. Ping from jail to host machine
Transition to and execute prisoner1 with a JID of "1".
|
1 |
# jexec 1 /bin/csh |
Ping host machine (192.168.11.83) 3 times
|
1 2 3 4 5 6 7 8 9 |
# ping -c 3 192.168.11.83 PING 192.168.11.83 (192.168.11.83): 56 data bytes 64 bytes from 192.168.11.83: icmp_seq=0 ttl=64 time=0.122 ms 64 bytes from 192.168.11.83: icmp_seq=1 ttl=64 time=1.401 ms 64 bytes from 192.168.11.83: icmp_seq=2 ttl=64 time=0.339 ms --- 192.168.11.83 ping statistics --- 3 packets transmitted, 3 packets received, 0.0% packet loss round-trip min/avg/max/stddev = 0.122/0.621/1.401/0.559 ms |
Creating a Jail Using Bastille, the Jail Manager for FreeBSD
Bastille is a very lightweight open-source software tool for managing jails on FreeBSD.
Set up a jail using Bastille.
Bastille Install
|
1 2 |
# pkg update # pkg install bastille |
Enable Bastille
|
1 |
# service bastille enable |
Since I want to use the ZFS filesystem in the jail, I need to edit two options in /usr/local/etc/bastille/bastille.conf
|
1 2 3 4 5 |
# vi /usr/local/etc/bastille/bastille.conf Change lines 60–61 as follows bastille_zfs_enable="YES" bastille_zfs_zpool="zroot" |
Check all mounted zpools
|
1 2 3 4 |
# zpool list NAME SIZE ALLOC FREE CKPOINT EXPANDSZ FRAG CAP DEDUP HEALTH AL TROOT zroot 37.5G 7.35G 30.1G - - 4% 19% 1.00x ONLINE - |
Deploy the core system
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
# bastille bootstrap 14.4-RELEASE Attempting to bootstrap FreeBSD release: 14.4-RELEASE Fetching MANIFEST... /usr/local/bastille/cache/14.4-RELEASE/MANIFES 1046 B 7978 kBps 00s Fetching distfile: base.txz /usr/local/bastille/cache/14.4-RELEASE/base.tx 154 MB 22 MBps 07s Validating checksum for archive: base.txz MANIFEST: 769f60a6eea2938ad6b7943cfbcc17dfaf7d1f7ba59a32b869a00349302df853 DOWNLOAD: 769f60a6eea2938ad6b7943cfbcc17dfaf7d1f7ba59a32b869a00349302df853 Checksum validated. Extracting archive: base.txz Bootstrap successful. See 'bastille --help' for available commands. |
Create a jail named "jail1" with the IP address 192.168.11.33
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
# bastille create jail1 14.4-RELEASE 192.168.11.33 em0 Attempting to create jail: jail1 Valid IP: 192.168.11.33 Valid interface: em0 Creating a thinjail... [jail1]: jail1: created [jail1]: Applying template: default/thin... [jail1]: Applying template: default/base... [jail1]: [jail1]: [jail1]: [jail1]: daily_status_world_kernel: -> NO [jail1]: syslogd_flags: -s -> -ss [jail1]: sendmail_enable: NONE -> NO [jail1]: sendmail_submit_enable: YES -> NO [jail1]: sendmail_outbound_enable: YES -> NO [jail1]: sendmail_msp_queue_enable: YES -> NO [jail1]: cron_flags: -> -J 60 [jail1]: /etc/resolv.conf -> /usr/local/bastille/jails/jail1/root/etc/resolv.conf Template applied: default/base Template applied: default/thin [jail1]: jail1: removed [jail1]: jail1: created |
Useful commands for working with Bastille
Show all jails
|
1 2 3 |
# bastille list JID Name Boot Prio State Type IP Address Published Ports Release Tags 4 jail1 on 99 Up thin 192.168.11.33 - 14.4-RELEASE - |
Cloning jails--Clone jail1 to create jail2 with the IP address (192.168.11.34)
|
1 |
# bastille clone -l jail1 jail2 192.168.11.34 |
Removing a jail--To remove jail2:
|
1 2 3 4 5 |
# service bastille stop # bastille destroy jail2 # bastille list JID Name Boot Prio State Type IP Address Published Ports Release Tags - jail1 on 99 Down thin 192.168.11.33 - 14.4-RELEASE - |
Move to jail1
|
1 2 3 4 5 6 7 8 9 |
# service bastille start [jail1]: jail1: created # bastille console jail1 [jail1]: root@jail1:~ # |
