jail

QNX SDP8.0Utilities ReferenceUtilities

Manage network jails

Syntax:

jail [-dhiqv] [-J jid_file] [-cmr] param=value ... [command=command ...]
jail [-qv] [-f conf_file] [-rR] [* | jail ...]
jail [-f conf_file] -e separator

Runs on:

QNX OS

Options:

Specify at least one of the following options to describe the operation to perform: -c, -e, -m, -r.

-c
Create a new jail. The jail identifier (jid) and name parameters (if specified on the command line) must not refer to an existing jail.
-e separator
Display a list of all configured, non-wildcard jails and their parameters. No jail creation, modification, or removal is performed if this option is used. The separator string is used to separate parameters. Use jls to list running jails (see the FreeBSD documentation at https://www.freebsd.org/cgi/man.cgi?query=jls&sektion=8&manpath=FreeBSD+13.4-RELEASE+and+Ports).
-m
Modify an existing jail. One of the jid or name parameters must exist and refer to an existing jail. Some parameters can't be changed when a jail is running.
-r
Remove the jail specified by jid or name. All jailed processes are killed, and all jails that are children of this jail are also removed.
-rc
Restart an existing jail. The jail is first removed and then recreated, as if jail -r was run followed by jail -c.
-cm
Create a jail if it does not exist, or modify the jail if it does exist.
-mr
Modify an existing jail. The jail may be restarted if necessary to modify parameters that could not otherwise be changed.
-cmr
Create a jail if it doesn't exist, or modify (and possibly restart) the jail if it does exist.

Additional options:

-d
Allow making changes to a dying jail.
-f conf_file
Use the specified configuration file instead of the default one (/etc/jail.conf).
-h
Resolve the host.hostname parameter (or hostname) and add all IP addresses returned by the resolver to the list of addresses for this jail. This is equivalent to the ip_hostname parameter.
-i
Output (only) the jail identifier of one or more newly created jails. This implies the -q option.
-J jid_file
Write a jid file that contains the parameters used to start the jail.
-p limit
Specify the number of commands specified by pseudo-parameters (exec.*) that can run simultaneously.
-q
Suppress the message printed whenever a jail is created, modified, or removed. Only error messages are printed.
-R
A variation of the -r option that removes an existing jail without using the configuration file. No removal-related parameters for this jail are used; instead, the jail is simply removed.
-v
Print a message on every operation, such as running commands and mounting filesystems.

Description:

The jail utility creates new jails, or modifies or removes existing jails. It can also print a list of configured jails and their parameters. A jail (or "prison") is specified via the jail.conf file or parameters on the command line:

  • If no arguments are given after the options, the operation (except -r or -R) is performed on all jails specified in jail.conf.
  • A single argument of a jail name operates only on the specified jail.
  • The -r and -R options can remove running jails that aren't in jail.conf, specified by name or jid.
  • An argument of * is a wildcard that operates on all jails, regardless of whether they appear in jail.conf; this is the surest way for -r to remove all jails.

When a jail is specified with parameters directly on the command line, jail.conf is not used.

Parameters

Parameters in jail.conf or on the command line generally use the format name=value.

Some parameters are boolean and can be set either of the following ways:
  • the name alone, with or without a no prefix (e.g., persist or nopersist)
  • specifying the value true or false

Other parameters may have more than one value by specifying either a comma-separated list or += in the configuration file (for details, see the FreeBSD jail.conf documentation at https://www.freebsd.org/cgi/man.cgi?query=jail.conf&sektion=5&manpath=FreeBSD+13.4-RELEASE+and+Ports).

The jail utility recognizes two classes of parameters:
  • True jail parameters, or core parameters, that are passed to io-sock when the jail is created, which can be seen with jls, and can (usually) be changed with jail -m.
  • Pseudo-parameters that are only used by jail itself.

Core parameters

The current set of available jail core parameters can be retrieved via sysctl -d security.jail.param. Any unset parameters are given default values, often based on the current environment.

jid
The jail identifier. This is assigned automatically to a new jail (or can be explicitly set). The jid can be used to identify the jail for later modification or for such commands as jls or jexec (see the FreeBSD jexec documentation at https://www.freebsd.org/cgi/man.cgi?query=jexec&sektion=8&manpath=FreeBSD+13.4-RELEASE+and+Ports).
name
The jail name. This is an arbitrary string that identifies a jail. It cannot contain a . (period). Like the jid, it can be passed to later jail commands or to jls or jexec. If no name is supplied, the name is the same as the jid. Because the name parameter is implied by the jail.conf file format, you don't need to explicitly set it when you use the configuration file.
ip4addr
A list of IPv4 addresses assigned to the jail. If this parameter is set, the jail is restricted to using only these addresses. Any attempts to use other addresses fail, and attempts to use wildcard addresses silently use the jailed address instead. For IPv4, the first address given is used as the source address when source address selection on unbound sockets cannot find a better match. It is only possible to start multiple jails with the same IP address if none of the jails has more than this single overlapping IP address assigned to itself.
ip4.saddrsel
A boolean option to change the behaviour described in the description for ip4addr and disable IPv4 source address selection for the jail in favour of the primary IPv4 address of the jail. Source address selection is enabled by default for all jails and the ip4.nosaddrsel setting of a parent jail is not inherited for any child jails.
ip4
Control the availability of IPv4 addresses. Possible values are:
  • inherit — Allow unrestricted access to all system addresses.
  • new — Restrict addresses via ip4.addr.
  • disable — Stop the jail from using IPv4 entirely.
Setting this parameter implies new.
ip6.addr, ip6.saddrsel, ip6
A set of IPv6 options for the jail that are IPv6 equivalents to ip4.addr, ip4.saddrsel, and ip4.
vnet
Create the jail with its own virtual network stack, with its own network interfaces, addresses, routing table, and so on. Possible values are:
  • inherit — Use the system network stack, possibly with restricted IP addresses.
  • new — Create a new network stack.
host.hostname
The hostname of the jail. Other, similar parameters are host.domainname, host.hostuuid, and host.hostid.
host
Set the origin of hostname and related information. Possible values are:
  • inherit — Use the system information.
  • new — Use the specified core parameter settings.
Setting any of the above fields implies a value of new.
dying
This is true if the jail is in the process of shutting down (read-only).
secpol_types
When using jails in a system with a security policy, a list of comma-separated security types. A process is part of the network jail if their security type is in the list.

Pseudo-parameters

The pseudo-parameters are not passed to io-sock but are instead used by jail to set up the jail environment, often by running specified commands when jails are created or removed. The exec.* command parameters are sh command lines that are run in either the system (the root jail) or jail environment. They may be given multiple values, which run the specified commands in sequence. All commands must succeed (return a zero exit status) for the jail to be created or removed.

exec.prepare
One or more commands to run in the system environment to prepare a jail for creation. These commands are executed before assigning IP addresses and mounting filesystems, so they may be used to create a new jail filesystem if it does not already exist.
exec.prestart
One or more commands to run in the system environment before a jail is created.
exec.created
One or more commands to run in the system environment right after a jail has been created, but before commands (or services) get executed in the jail.
exec.start
One or more commands to run in the jail environment when a jail is created. A typical command to run is sh /etc/rc.
exec.poststart
One or more commands to run in the system environment after a jail is created, and after any exec.start commands have completed.
exec.prestop
One or more commands to run in the system environment before a jail is removed.
exec.stop
One or more commands to run in the jail environment before a jail is removed, and after any exec.prestop commands have completed. A typical command to run is:
sh /etc/rc.shutdown jail
exec.poststop
One or more commands to run in the system environment after a jail is removed.
exec.release
One or more commands to run in the system environment after all other actions are done. These commands are executed after unmounting filesystems and removing IP addresses, so they may be used to remove a jail filesystem if it is no longer needed.
exec.jail_user
The user to run commands as, when running in the jail environment. The default is to run the commands as the current user.
exec.system_user
The user to run commands as, when running in the system environment. The default is to run the commands as the current user.
exec.consolelog
A file to direct command output (stdout and stderr) to.
interface
A network interface to add the jail's IP addresses (ip4.addr and ip6.addr) to. An alias for each address is added to the interface before the jail is created, and is removed from the interface after the jail is removed.
ip4.addr
In addition to the IP addresses that are passed to io-sock, an interface, netmask, and additional parameters (as supported by ifconfig) may also be specified using the following format:
interface|ip-address/netmask param ....
If an interface is given before the IP address, an alias for the address is added to that interface, as it is with the interface parameter. If a netmask in either dotted-quad or CIDR form is given after an IP address, it is used when adding the IP alias. If additional parameters are specified, then they are also used when adding the IP alias.
ip6.addr
In addition to the IP addresses that are passed to io-sock, an interface, prefix, and additional parameters (as supported by ifconfig) may also be specified using the following format:
interface|ip-address/prefix param ...
vnet.interface
A network interface to give to a VNET-enabled jail after is it created. The interface is automatically released when the jail is removed.
ip_hostname
Resolve the host.hostname parameter and add all IP addresses returned by the resolver to the list of addresses (ip4.addr or ip6.addr) for this jail. This may affect default address selection for outgoing IPv4 connections from jails. The address first returned by the resolver for each address family is used as the primary address.

Examples:

The initial examples apply to a system without a security policy. For a discussion of the differences when you use jails with a security policy, with examples, see Jails and security policies.

Creating a jail with a virtual network

The following command creates a jail with a virtual network, without a configuration file:
jail -cv name=netjail vnet 
jail_set(JAIL_CREATE) name=netjail vnet=new 
created
The jls command displays the list of active jails. For example:
jls -v
JID  Hostname                      
Name                          State
IP Address(es)
Jailed Processes
1                                
netjail                       ACTIVE

The first four lines of output display a list of parameters followed by the parameter values in the same order. The example created a jail with values JID=1, Name=netjail, and State=Active. There is no hostname, IP addresses, or currently jailed processes yet.

The example creates the jail with a virtual network (vnet), but does not assign any interfaces to it. Run ifconfig inside the jail to display the available interfaces in the virtual network. Use either jexec or on -j to run commands inside the jail. For example:
jexec netjail ifconfig
enc0: flags=0<> metric 0 mtu 1536
        groups: enc
        nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>
lo0: flags=8008<LOOPBACK,MULTICAST> metric 0 mtu 16384
        options=680003<RXCSUM,TXCSUM,LINKSTATE,RXCSUM_IPV6,TXCSUM_IPV6>
        groups: lo
        nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>
pflog0: flags=0<> metric 0 mtu 33144
        groups: pflog
pfsync0: flags=0<> metric 0 mtu 1500
        syncpeer: 0.0.0.0 maxupd: 128 defer: off
        groups: pfsync
jexec netjail netstat -r
Routing tables
The virtual network the example created has its own firewall and local interface, but no routes. You cannot, for example, use ping to reach localhost. For example:
jexec netjail ping localhost
PING 127.0.0.1 (127.0.0.1): 56 data bytes
ping: sendto: Network is unreachable
The following commands assign the IP address 127.0.0.1 to lo0 to enable local networking within the jail and test the reachability of localhost:
jexec netjail ifconfig lo0 127.0.0.1/8 up
jexec netjail ping localhost              
PING6(56=40+8+8 bytes) ::1 --> ::1
16 bytes from ::1, icmp_seq=0 hlim=64 time=0.995 ms
16 bytes from ::1, icmp_seq=1 hlim=64 time=0.000 ms
16 bytes from ::1, icmp_seq=2 hlim=64 time=0.000 ms

--- localhost ping6 statistics ---
3 packets transmitted, 3 packets received, 0.0% packet loss
round-trip min/avg/max/std-dev = 0.000/0.332/0.995/0.469 ms
Use the jexec utility to confirm that some routes have been populated. For example:
jexec netjail netstat -r     
Routing tables

Internet:
Destination        Gateway            Flags     Netif Expire
localhost          link#2             UH          lo0

Internet6:
Destination        Gateway            Flags     Netif Expire
localhost          link#2             UHS         lo0
fe80::%lo0/64      link#2             U           lo0
fe80::1%lo0        link#2             UHS         lo0

Adding an interface to a virtual network

Virtual networks can be used to limit the visibility of an interface to certain processes. An interface can be added to an existing jail using ifconfig with the vnet option. For example, the following system has the two interfaces vmx0 and vmx1:
ifconfig -l
enc0 lo0 pflog0 pfsync0 vmx0 vmx1
The following commands assign vmx0 to the jail and then show how it is no longer accessible outside the jail:
ifconfig vmx0 vnet netjail
ifconfig -l
enc0 lo0 pflog0 pfsync0 vmx1
The vmx0 interface is accessible for jailed processes. For example:
jexec netjail ifconfig -l
enc0 lo0 pflog0 pfsync0 vmx0
The -vnet option for ifconfig removes an interface from a jail. For example:
ifconfig vmx0 -vnet netjail
ifconfig -l enc0 lo0 pflog0 pfsync0 vmx1 vmx0
jexec netjail ifconfig -l
enc0 lo0 pflog0 pfsync0
Alternatively, you can assign the interface when you create the jail. For example:
jail -c name=netjail vnet vnet.interface=vmx1
jexec netjail ifconfig -l
enc0 lo0 pflog0 pfsync0 vmx1
The jail command can also be used to modify the jail. For example:
jail -c name=netjail vnet
jail -m name=netjail host.hostname=localhost vnet.interface=vmx1

Running a jailed server

The previous examples run ifconfig and netstat inside the jail. The following example illustrates a practical application for jails: running one or more servers inside a jail, which restricts them to a subset of network interfaces. For example, a system has the interfaces vmx0 and vmx1:
ifconfig -l
enc0 lo0 pflog0 pfsync0 vmx0 vmx1

The vmx0 interface is configured on the subnet 172.16.129.0/24 and vmx1 is configured on the subnet 172.16.130.0/24.

The following commands create a jail, assign vmx1 to it, and statically configure its IP address:
jail -c name=netjail vnet vnet.interface=vmx1
jexec netjail ifconfig vmx1 172.16.130.101/24 up 
The following command starts the server:
jexec netjail /tmp/tcp_server &
[1] 364568
Server listening..
Use the jls -v command to verify that there is a jailed process. For example:
# jls -v
   JID  Hostname                      
        Name                          State
        IP Address(es)
        Jailed Processes
     1                                
        netjail                       ACTIVE
        364568  /tmp/tcp_server
The server in this example can only be accessed through vmx1. For example:
./tcp_client 172.16.129.101
connection with the server failed.
 ./tcp_client 172.16.130.101 connected to the server..

Using epairs to jail ssh

An epair is a pair of Ethernet-like software interfaces, which are connected back-to-back with a virtual cross-over cable. For more information, see the FreeBSD documentation at https://www.freebsd.org/cgi/man.cgi?query=epair&manpath=FreeBSD+13.4-RELEASE+and+Ports.

Epairs can be combined with bridges to connect virtual networks, or combined with firewall rules to connect the virtual network with a physical interface.

For example, the following commands create a bridge and an epair:
ifconfig bridge create
bridge0
ifconfig epair create
epair0a
The epair create command creates two interfaces. For example:
ifconfig -g epair
epair0a
epair0b
The following commands add the external interface vmx0 and epair0a to the bridge, place epair0b in the jail, and perform static network configuration:
ifconfig bridge0 addm epair0a addm vmx0 up
ifconfig bridge0 192.168.3.1/24 up
ifconfig epair0a up
jail -c name=netjail vnet vnet.interface=epair0b
jexec netjail ifconfig epair0b 192.168.3.2/24 up
jexec netjail route add default 192.168.3.1
add net default: gateway 192.168.3.1
The following commands create firewall rules to forward traffic from the subnet 192.168.3 over vmx0:
pfctl -s nat
nat on vmx0 inet from 192.168.3.0/24 to any -> 172.16.129.101
rdr on vmx0 inet proto tcp from any to any port = ssh -> 192.168.3.2
pfctl -e
To complete the example configuration, start sshd in the jail. For example:
jexec netjail /usr/sbin/sshd &
When you log into the target using ssh, because the session is jailed, you do not have access to any interfaces outside the jail. For example:
ssh root@172.16.129.101
sysctl security.jail.jailed
security.jail.jailed: 1
ifconfig -l
ifconfig -l
enc0 lo0 pflog0 pfsync0 epair0b

Jails and subprocess inheritance

Jail membership is inherited by all child processes (subprocesses) of a jail.

Programs such as jexec or on -j create a jailed process by calling jail_attach(jid) followed by exec*(), or by spawning and calling jail_attach_pid(jid, child_pid) (jail_attach_pid() is an io-sock extension).

The following code is a simplified version of jexec:
int main(int argc, char *argv[]) {
char *jail_name = argv[1];
int jid = jail_getid(jail_name);
jail_attach(jid);
execvp(argv[1], argv + 1);
}

A child process that is spawned or forked from a jailed parent process such as a shell or sshd should also be jailed. When the child process first connects, io-sock can reliably determine that the child should be jailed. However, io-sock may not be able to reliably determine in which jail to place the child process if the parent process dies and the child does not connect to io-sock within 1-2 seconds after the parent's death. In this case, the connection is rejected with EPERM.

From a security standpoint, the system remains secure because the child process cannot break out of the parent's jail. However, you still need a workaround to ensure that any program can work reliably from within a jail even if the child does not connect soon enough after the parent dies. QNX recommends that you explicitly attach the child to the jail from the parent process before terminating. For example:
int main(int argc, char *argv[]) {
  
int pid = fork();
  
/* if we have the name but not the id of the jail */
char *jail_name = argv[1];
int jid = jail_getid(jail_name);
  
/* if we don't know the name either but know we are jailed */
int jid_size = sizeof(jid);
sysctlbyname("security.jail.jid", &jid, &jid_size, NULL, 0);
  
if (pid == 0) {
execvp(...);
} else if (pid > 0) {
jail_attach_pid(jid, pid);
exit(0);
}
}

Jails and security policies

When a security policy is loaded on the system, io-sock determines the jail membership of a process from its security type. Only processes that interact with io-sock can be put in a jail using security types.

For this environment, you configure io-sock at startup with the following sysctl:
sysctl qnx.sec.jail_types=1
An extra secpol_types parameter must be added to each jail configuration. For example:
jail -c name=netjail vnet secpol_types=jail_t
After this parameter is added, any process spawned with the jail_t security type is put in the netjail jail. For example:
on -T jail_t ifconfig

Up to 127 security types can be assigned to each jail. Each security type can only be assigned to one jail.

When jails are configured to work with security types, the issue with a child process not working after its parent dies described in Jails and subprocess inheritance does not apply.

Contributing author:

Poul-Henning Kamp, Robert Watson, Bjoern A. Zeeb, James Gritton

Page updated: