Contents
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.2)
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.2-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.228 ms 64 bytes from 192.168.11.83: icmp_seq=1 ttl=64 time=0.306 ms 64 bytes from 192.168.11.83: icmp_seq=2 ttl=64 time=1.359 ms --- 192.168.11.83 ping statistics --- 3 packets transmitted, 3 packets received, 0.0% packet loss round-trip min/avg/max/stddev = 0.228/0.631/1.359/0.516 ms |