# $Id: README 150 2015-01-06 11:01:01Z portmaster $

INTRODUCTION
============

JailAdmin is a simple system for administering FreeBSD jail environments.
It consists of four files:

  Jail.pm - General-purpose module for gathering information, starting,
            and stopping jails.

  jailadmin - Perl program that serves as a command line interface to
              Jail.pm.

  jailadmin.conf - Site-specific configuration options.

  jail.sh - An rc.d file to start and stop jails at system boot or shutdown.

The optional SNMP components are:

  jail-snmp - Plugin to the net-snmp package.
  
  jail-snmp-persist - Persistent version of jail-snmp that avoids the
                      startup overhead inherent in launching a new copy every
                      time the associated OIDs are polled.

  JAIL-MIB.txt - MIB file describing the SNMP attributes.

TERMINOLOGY
===========

   Server:
      A named set of attributes uniquely describing a jail environment.
      This extra layer of abstraction provides a consistent anchor for
      jails whose hostnames and IPs may change.

CONFIGURATION
=============

Edit jailadmin.conf with your favorite editor. It has an extremely simple
format:

   - All global options are defined as 'key = value'

   - All server-specific options are defined by the appropriate servername
     on a line by itself, followed by one or more lines beginning with a
     space, in the format 'key: value'

   - Leading and trailing whitespace are ignored, except for the leading
     whitespace that distinguishes server-specific options (as above).

   - All characters on a line after a pound sign '#' are ignored.

   - Blank lines are ignored.

The sample configuration file is heavily documented, and all available
options are defined there.

Example:

Let's assume 4 servers (named 'server1', 'server2', 'server3', 'server4').
They're all rooted in subdirectories of /var/jail . They're all webservers
to different domains.

jailadmin.conf could be written as:

########################################
jaildir=/var/jail

server1
    ip: 10.0.1.2
    hostname: www.domain1.com

server2
    ip: 10.0.1.3
    hostname: www.domain2.com

server3
    ip: 10.0.1.4
    hostname: www.domain3.com

server4
    ip: 10.0.1.5
    hostname: www.domain4.com
########################################


USAGE
=====

jailadmin takes at least two arguments, 'operation' and one or more
servernames, where servernames are the name of the entries or groups
defined in jailadmin.conf, and operation is one of 'start', 'stop',
and 'status'.

'start' is pretty simple, but it does check to make sure that the specified
jail is not currently running (defined as having one or more processes
imprisoned within it).

'stop' invokes two distinctly different modes of operation. The first,
"naive", works as follows:

It sends a TERM signal to all processes within the jail. After a 5-second
wait, if processes are still running, then it waits another 10 seconds.
All processes still running at that time are sent a KILL signal. This is
similar to FreeBSD's own shutdown process, although vastly less
sophisticated.

The second, "emulated", works by first invoking /etc/rc.shutdown within a
jail. After that script has completed, it follows the "naive" process
detailed above, to remove all lingering processes.

Recent versions of jailadmin can parallelize stages of the shutdown process
for several jails at once, so that the waiting periods can be made as
concurrent as possible. For example, given 10 jails where each needs to
wait for the full 15 seconds, the total shutdown time can be reduced from
150 seconds, to 15. This is very nice for quickly rebooting a number of
servers.

'status' returns a ps(1)-like status report. For example:

    Server: virtual3

    USER   PID  %CPU  %MEM  RSS TT STAT    TIME COMMAND
    root 96703   0.0   0.1  908 ?? SsJ  0:00.19 /usr/sbin/syslogd -s
    root 96760   0.0   0.2 3028 ?? SsJ  0:00.16 /usr/sbin/sshd
    root 96767   0.0   0.1 1096 ?? IsJ  0:00.05 /usr/sbin/cron -s


NOTES
=====

By default, Jail.pm expects it's configuration file to be
/usr/local/etc/jailadmin.conf. However, upon initialization, it calls
Getopt::Long::GetOptions to look for a command line argument '--conffile'
to read instead. Therefore, all programs that use Jail.pm (such as
jailadmin), can use any other configuration file.

Example:

  jailadmin --conffile /tmp/generatedfile server2 start

Jail.pm aggressively caches all information it acquires from it's
environment; you may call any of it's functions as often as you like with
little performance degradation. However, this also means that it's
information may be out-of-date, particularly it's cache of running processes
and their information. Call Jail::updateProcessList to force the module to
reload this information as needed. For example, after calling
Jail::signalProcs(), you would probably want to see if any processes are
still running in a particular jail. updateProcessList() will ensure that
you're examining current data.

Jail.pm can use FreeBSD's jls(8) and jexec(8) commands to simplify and speed
up the control of jail environments and data gathering. Furthermore, they
remove the requirement of having /proc mounted in the host environment, which
is certainly appealing to the security-conscious. There is virtually no ill
effect from using these tools in a "normal" jail environment that's based on
a cloned FreeBSD system. However, extremely minimal jails (such as those
containing a single server process) or those based on emulated Linux systems
(where the ps(1) command still looks in /proc for details) may require the
continued use of the old system. To enable the use of jls(8) and jexec(8)
globally, set "default_usejtools=1" inside jailadmin.conf. That value may
be overridden for individual jails.

SNMP
====

As of version 1.3, the jailadmin package comes with an SNMP extension for
the UCD-SNMP snmpd. By adding the extension and the included MIB
definitions to your snmpd configuration, you can easily monitor your jail
environments with the same tools you're already using to track your network
usage, hardware capacity, and other interesting data.

An example tree traversal:

  # snmpwalk localhost mycommunity .1.3.6.1.4.1.2021.255
  enterprises.ucdavis.jail.general.numJails = 3
  enterprises.ucdavis.jail.jailTable.jailIndex.1 = 1
  enterprises.ucdavis.jail.jailTable.jailIndex.2 = 2
  enterprises.ucdavis.jail.jailTable.jailIndex.3 = 3
  enterprises.ucdavis.jail.jailTable.jailServer.1 = "vserver1"
  enterprises.ucdavis.jail.jailTable.jailServer.2 = "vserver2"
  enterprises.ucdavis.jail.jailTable.jailServer.3 = "vserver3"
  enterprises.ucdavis.jail.jailTable.jailHostname.1 = "server1.int"
  enterprises.ucdavis.jail.jailTable.jailHostname.2 = "server2.int"
  enterprises.ucdavis.jail.jailTable.jailHostname.3 = "server3.int"
  enterprises.ucdavis.jail.jailTable.jailIp.1 = IpAddress: 10.0.5.1
  enterprises.ucdavis.jail.jailTable.jailIp.2 = IpAddress: 10.0.5.2
  enterprises.ucdavis.jail.jailTable.jailIp.3 = IpAddress: 10.0.5.3
  enterprises.ucdavis.jail.jailTable.jailNumProcs.1 = 6
  enterprises.ucdavis.jail.jailTable.jailNumProcs.2 = 23
  enterprises.ucdavis.jail.jailTable.jailNumProcs.3 = 14

Future support for read-write settings is being considered. Imagine being
able to start or stop a jail by writing to jailTable.isRunning.n without
leaving your OpenView or Netcool console!


CREDITS
=======

This package was developed by Kirk Strauser <kirk@struaser.com> with the
help and guidance of generous contributors. In no particular order, they
include:

  - Dar Larsson
  - Jeremy Bobbio
