First stab at a new jail(8)
Jamie Gritton
jamie at FreeBSD.org
Thu Sep 2 23:13:05 UTC 2010
I've got code for a config-based jail(8) at
http://people.freebsd.org/~jamie/jail.tbz .
It drops in under /usr/src/usr.sbin, but is a big enough change from the
current sources that I didn't bother with a diff.
I haven't yet updated the man page for it, so I'll give a quick overview
here...
Its syntax is an extension of the current jail(8), which is itself an
extension of the previous jail(8). In addition to starting a single
jail with "-c name=value ... command=do something here" or modifying one
with "-m name=value ...", you can just specify a single jail name on the
command line and it will operate on that jail from the config file.
So "jail -c foo" will start up the jail "foo" from /etc/jail.conf (or
whatever file you specify with "-f"). Just saying "jail -c" will start
up all jails in the config file if they aren't already running. More
generally, when running from the config file you can do the following:
jail -c [jailname]
Start the specified jail, or all jails. Note that <jailname> is a
single argument. You can't start multiple jails at once this way (e.g.
jail -c firstjail secondjail), because if you put two arguments, jail(8)
will think you're specifying a jail on the command line with parameters
like "firstjail" and "secondjail". You can start multiple jails with
simple wildcards: specifying "foo.*" will start jails that start with
"foo.". This isn't a regular expression or globbing, but wildcarding
entire name components.
jail -m [jailname].
Modify parameters of the specified jail, or all jails. It will set the
jail to whatever the current parameters in the config file are. Some
parameters, like "path", can only be set on jail startup. If these are
the same in the config file and the currently running jail, it will
silently skip them. If they're different, it will report and error and
not update the jail.
jail -r <jailname>
In this case, the jail name isn't optional, because I thought it would
be too easy to accidentally remove everything. If you want to remove
all jails, you can say "jail-r '*'". If you specify a wildcard, it will
apply only to jails in the config file. But unlike -c and -m, if you
specify a single jail, it will first look it up in the config file but
then back up to looking at currently running jails. Thus "jail -r 47"
will remove the jail with jid 47 just like it currently does, unless you
have a jail called "47" in the config file.
jail -R <jailname>
Similar to jail -r, but this doesn't use the config file at all. The
jailname must be the name or jid of a running jail, or a wildcard. In
this case, the wildcards also apply to running jails, so "jail -R '*'"
will remove all current jails. Since the config file isn't used, no
shutdown scripts will be run and every jail will be removed "hard".
jail -cm [jailname]
Like the "-cm" flags of the current version, this will create a jail if
it doesn't exist, or update it if it does exist. This will make sure
every jail in the config file is up and running.
jail -rc [jailname]
This combination of -r and -c restarts jails - first the entire remove
procedure then the entire create procedure.
jail -mr [jailname]
jail -cmr [jailname]
These variations on -m and -cm will restart a jail if necessary -
instead of exiting on an error when attempting to change a create-only
parameter, it will restart the jail. The -cmr option, which can also
create new jails, can make sure every jail is in exactly the same state
as specified in the config file.
I've described the format of the config while a while back, and I'm
including a small sample config file in the tarball. Right now it
handles all the regular jail parameters, as well as some internal
pseudo-parameters mostly taken from the current rc.d/jail:
allow-dying
Same as the -d flag, allow modifying a dying jail.
depend
Make a jail's startup depend on another jail. The jail won't be started
until every jail it depends on is successfully started first. If you
specify starting a single jail on the command line and it has
dependencies, its dependencies are implicitly included. If you modify a
jail with dependencies, it will make any changes in dependency order,
but will not actually modify jails that aren't specified. The
dependencies apply in reverse order for removing jails.
ip_hostname
Same as the -h flag, implicitly set the jails' ip4.addr and ip6.addr
parameters based on a DNS lookup of the host.hostname parameter.
exec.prestart
exec.start
command
exec.afterstart
exec.poststart
The same as used in rc.d/jail, except that there's also a "command"
parameter as in the current jail(8). The specified programs are
executed in the order given, and each parameter can specify multiple
programs (using the "+=" specifier in the config file). The jail is
created after exec.prestart is run. The exec.start, command, and
exec.afterstart programs are run inside the jail; the exec.prestart and
exec.poststart programs are run in the host system. For backward
compatibility and convenience, "command" stops the parsing of parameters
on the command line, and gives all remaining arguments to the program.
exec.prestop
exec.stop
exec.poststop
The same as used in rc.d/jail. The jail is removed after exec.stop
completes (and after sending all jailed processes SIGTERM and waiting
for them to die). The exec.stop program is run inside the jail; the
exec.prestop and exec.poststop programs are from in the host system.
exec.clean
exec.jail_user
exec.system_jail_user
exec.system_user
Similar to the -l, -u, and -U options. exec.clean is the same as -l,
except that it doesn't require -[uU] to be set as well, but instead uses
the current user (passwd lookup by uid) if no user is specified. If
people aren't using fancy permission models or making jail(8) setuid,
this user will be root. exec.jail_user is the same as the -U option,
and specifies a user to look up in the jail's passwd file when running a
program inside the jail. exec.system_jail_user is a boolean that says
to look up exec.jail_user in the host system's passwd file instead;
specifying both exec.jail_user and exec.system_jail_user is the
equivalent of the -u option. exec.system_user specified a user for
programs that run outside the jail, e.g. from exec.prestart. It has no
analog in the current jail(8).
I haven't yet handled the other rc.d/jail parameters. Those are the
next thing for me to work on, but I think the current version is at
least useful enough to start looking at. Most of the things the
rc.d/jail does can be handled to at least some degree by specifying
exec.prestart and exec.afterstop programs.
- Jamie
More information about the freebsd-jail
mailing list