<?xml version="1.0"?>
<!DOCTYPE doc SYSTEM "/usr/local/xslt/doc.dtd">
<?xml-stylesheet type="text/xsl" href="/usr/local/xslt/html.xsl"?>
-<doc style="main.css">
+<doc style="gnucomo.css">
<!--
Gnucomo - Gnu Computer Monitoring Tutorial
Original author : Peter Roozemaal
- Version : $Revision: 1.2 $
+ Version : $Revision: 1.6 $
This document is prepared for XMLDoc. Transform to HTML,
LaTeX, Postscript or plain text with XMLDoc utilities and
<para><picture src='logo.png' eps='logo' scale='0.7'/></para>
<author>Peter Roozemaal<code><mathfox@xs4all.nl></code></author>
<author>Arjen Baart <code><arjen@andromeda.nl></code></author>
- <date>October 23, 2003</date>
+ <date>October 25, 2007</date>
<docinfo>
- <infoitem label="Version">0.1</infoitem>
+ <infoitem label="Version">0.2</infoitem>
<infoitem label="Organization">Andromeda Technology & Automation</infoitem>
<infoitem label="Organization">De Winter Information Solutions</infoitem>
</docinfo>
other GnuCoMo documentation, please report it by sending an e-mail to
the mailinglist: <code>gnucomo@dewinter.com</code>.
Please include in your bug report:
+</para>
<itemize>
<item>the GnuCoMo version you've found the bug in</item>
<item>the versions of the packages that gnucomo depends on</item>
</itemize>
-</para>
-
</section>
</chapter>
</para>
<para>
To be able to install and run GnuCoMo you'll need several other packages:
+</para>
<description>
<item tag='PostgreSQL'>
</description>
+<para>
The following packages are optional and provide additional functionality
to GnuCoMo:
+</para>
<description>
<item tag='GnuPG'>
</description>
-</para>
</section>
<section>
<code>create.sql</code>, which is in the <code>src/database</code>
directory of the Gnucomo distribution.
Type the following commands to create the database:
+</para>
<verbatim>
</verbatim>
-With the default installation of PostgreSQL on RedHat 8.0,
-you will probably encounter an authentication problem when you try to
-use the Gnucomo web interface. The problem will look somewhat like this:
-</para>
-
-<para>
-<strong>
-Warning: pg_connect() unable to connect to PostgreSQL server:
-FATAL 1: IDENT authentication failed for user "arjen"
-</strong>
-</para>
-
<para>
-Refer to PostgreSQL Administrator's guide, Chapter 4: Client Authentication.
-You probably have this line in the /var/lib/pgsql/data/pg_hba.conf:
-
-<verbatim>
- local all ident sameuser
-</verbatim>
-
-(I know RedHat 8.0 does this). You need to change this into:
-
-<verbatim>
- local all password
-</verbatim>
-
-This tells PostgreSQL to allow any UNIX user to log into the database
-as any database user on a local socket, using his database password.
-
+[TODO] How to set up database security is yet to be described.
</para>
</section>
<heading>The Gnucomo configuration file</heading>
<para>
+<label name='configuration'/>
All Gnucomo applications use a single configuration file, named
<code>gnucomo.conf</code> by default.
There are three places where this configuration file is stored.
Each parameter is a single value, i.e. there are no provisions to create
structured parameters.
Here is an example of what the Gnucomo configuration file may look like:
+</para>
<verbatim>
<?xml version='1.0'?>
</verbatim>
+<para>
At the root of the tree is an XML element, called <code>gnucomo</code>.
The direct children of the root element in the example above are
<code>database</code> and <code>logging</code>.
<code>logging</code> section specifies how much logging we want the
Gnucomo applications to generate and where we want that information to go.
</para>
+<para>
+Here is a full list of the parameters that are used by Gnucomo, subdivided
+in their various sections:
+</para>
+<itemize>
+
+ <item>
+ <strong>database</strong>
+ <para>
+ All parameters that provide Gnucomo applications access to the database.
+ </para>
+ <description>
+ <item tag='type'>
+ The type of the database server. Currently, only PostgreSQL is supported.
+ </item>
+ <item tag='host'>
+ The hostname of the system on which the database server runs.
+ </item>
+ <item tag='port'>
+ The TCP port used by the database server.
+ </item>
+ <item tag='name'>
+ The name of the database to use for Gnucomo.
+ </item>
+ <item tag='user'>
+ The user name with which to log in on the database server.
+ </item>
+ <item tag='password'>
+ The password used for logging in to the database server.
+ </item>
+ </description>
+ </item>
+
+ <item>
+ <strong>logging</strong>
+ <para>
+ The amount of logging generated by Gnucomo applications and where to send it.
+ </para>
+ <description>
+ <item tag='method'>
+ The method for sending log information.
+ </item>
+ <item tag='destination'>
+ Where the logging information is sent.
+ </item>
+ <item tag='level'>
+ Choose a higher level for more information.
+ </item>
+ </description>
+ </item>
+
+ <item>
+ <strong>logfile</strong>
+ <para>
+ Primarily used by <emph>logrunner</emph>.
+ A list of files that are scanned for system logging that in sent to the Gnucomo server.
+ There can be more than one <strong>logfile</strong> element in a Gnucomo configuration file.
+ </para>
+ <description>
+ <item tag='name'>
+ Name of the file to scan for logging, e.g. <code>/var/log/messages</code>.
+ </item>
+ <item tag='type'>
+ The type of the logging information.
+ Types supported by Gnucomo are <code>system log</code>,
+ <code>apache access log</code> and <code>apache error log</code>.
+ </item>
+ <item tag='fromhost'>
+ Hostname (not a FQDN) of the system for which the log entries are sent.
+ Only log entries that originate from this host are sent to the Gnucomo server.
+ This option applies to system log files that may have log entries for several hosts,
+ in case the system acts as a syslog server.
+ </item>
+ <item tag='filter'>
+ A regular expression to filter out log entries before sending to the Gnucomo server.
+ There may be several <strong>filter</strong> elements in a single
+ <strong>logfile</strong> element.
+ </item>
+ </description>
+ </item>
+
+</itemize>
</section>
<section>
The main gnucomo scripts go into this directory and the PHP class library can be copied
either in a subdirectory <code>classes</code> or <code>../phpclasses</code>.
Here's an example installation:
+</para>
<verbatim>
[gnucomo] # mkdir $DocumentRoot/gnucomo
[gnucomo] # cp src/web/* $DocumentRoot/gnucomo
[gnucomo] # cp -r src/phpclasses $DocumentRoot
</verbatim>
-</para>
</section>
<section>
<para>
The most direct way to invoke <code>gcm_input</code> maually and read
the log file through its standard input:
+</para>
<verbatim>
gcm_input -h server.gnucomo.org </var/log/messages
</verbatim>
+<para>
You'll have to explicitly specify the hostname of the object because
there is no way for <code>gcm_input</code> to know where the log
file comes from.
</para>
<para>
Feeding information into the Gnucomo database can also be done through
-a mail server, such as sendmail.
+a mail server, such as sendmail or postfix.
Create a mail alias that invokes <code>gcm_input</code> as a mailer program.
For example:
+</para>
<verbatim>
gnucomo: "|gcm_input"
</verbatim>
+<para>
With such an email alias, Gnucomo clients can simply send log files and
other reports to this email address:
+</para>
<verbatim>
mail gnucomo@server.gnucomo.org </var/log/messages
</verbatim>
-</para>
<para>
The third method to feed log files into the Gnucomo database is by
using <code>logrunner</code>.
+Where the previous methods can only feed complete logfiles as a whole,
+logrunner can feed partial logiles to the Gnucomo server.
+Logrunner keeps track of the growth of a logfile and converts the newly
+added log entries into an XML message suitable for gcm_input.
+A practical way to deploy logrunner is:
+</para>
+<verbatim>
+ /usr/local/bin/logrunner -1 | mail gnucomo@gnucomo.server
+</verbatim>
+<para>
+Note the '-1' option for logrunner. This option is needed to keep
+logrunner from generating multiple XML documents in one output stream.
+Which logfiles are scanned by logrunner is specified in the Gnucomo
+<ref to='configuration'>configuration file</ref>.
</para>
</section>
<heading>Viewing results</heading>
<para>
Use the web interface to review log entries, notifications and parameters.
+The <emph>Objects</emph> page shows statistics about the data that is collected
+for each monitored object.
+Clicking on the links in the statistics will display the specific data for that object.
+The icon of each object takes you to a form for editing information about that object,
+such as an identification code, physical location and services used by that object.
+</para>
+
+<para>
+After feeding the log entries of monitored objects to the Gnucomo server,
+these log entries can be analyzed by the Gnucomo analyzer daemon, <code>gcm_daemon</code>.
+The present version of Gnucomo does not yet support the operation of a real
+daemon, so you will have to start <code>gcm_daemon</code> explicitly.
+This performs a number of analyses on the log entries and updates the statistics
+for each object.
+When the <code>gcm_daemon</code> finds something out of the ordinary, it will
+create a <emph>Notification</emph>.
+Notifications are created to alert you to the fact that something may be wrong
+with that object.
+</para>
+<para>
+The checks made by Gnucomo are related to services that run on a monitored object.
+A few checks are predefined in Gnucomo.
+You can add more checks to tailor your situation through the <emph>Services</emph> page.
+Click on the icon of a specific service to edit the list of checks that are
+performed for log entries generated by that service.
+Each check consists of a <emph>pattern</emph> in the form of a regular expression
+and an action.
+For example, the following pattern matches a log entry from postfix which states that
+outgoing mail is delivered:
+</para>
+<example>
+ to=.+, relay=.+, delay=[0-9]{1,2}, status=sent \(250 .+\)
+</example>
+<para>
+The action is performed when the regular expression matches with a log entry.
+Each check is tagged with a rank number for defining the order in which the
+checks are applied.
+The first pattern that matches is used to perform the action.
+The very last check is a 'catch all' pattern, predefined in the Gnucomo database.
+When a pattern matches, one of four actions is executed:
+</para>
+<description>
+<item tag='ignore'>
+Simply ignore this log entry.
+</item>
+<item tag='notify'>
+Create a notification.
+The <emph>Issue</emph> for the notification is stated in the <emph>Argument</emph> field.
+</item>
+<item tag='abuse'>
+Add one to the number of abuses detected for the IP address or hostname that is mentioned in
+the log file.
+The argument for this action is almost always "$1", which is the first part of the pattern
+between parenthesis.
+Note that this requires a special form of regular expression in the pattern which will select
+certain parts as a sub expression.
+</item>
+<item tag='forgive'>
+Remove one abuse for the IP address of hostname in the argument.
+</item>
+</description>
+<para>
+A notification is always created with a specific <emph>Issue</emph> which states
+what Gnucomo thinks is going wrong.
+A number of issues are predefined in the Gnucomo database.
+You can create your own issues and have Gnucomo generate notifications with these
+issues on the Issues page.
+</para>
+</section>
+
+<section>
+<heading>Abuse and intrusion detection</heading>
+<para>
+Gnucomo maintains a list of IP addresses that have committed some kind of abuse.
+This can be attempts to send spam, attempts to intrude a system from the internet
+or any other kind of malicious action.
+These abuses are detected by creating the proper patterns in checks for log entries
+as discussed in the previous section.
+Each time an abuse is detected in the log, one abuse is added to the record for
+that <emph>Object</emph> and IP address.
+A reference to the log entry in which the abuse was detected is also maintained.
+When the number of abuses for a certain IP address exceeds the limit (32 in this
+version of Gnucomo), the status for the IP address is set to 'dropped'.
+You can review the list of abusing IP addresses by clicking on the 'Abuse list'
+in the <emph>Objects</emph> page.
+</para>
+<para>
+The most useful application of the abuse list is to maintain a firewall
+and block all IP addresses that have the 'dropped' status.
+To do this automatically, you need to provide access to the database from
+a script that is probably run by root.
+A special user 'firewall' that can only read the abuse list can be created
+with the following SQL commands:
</para>
+<verbatim>
+CREATE USER firewall WITH PASSWORD 'secret';
+GRANT SELECT ON object_abuse TO firewall;
+</verbatim>
+<para>
+When the Gnucomo database runs on a different system than the one
+on which the firewall is maintained, the database server needs to
+provide access from external systems. This implies setting up the
+PostgreSQL configuration and firewall rules.
+The following script then augments the firewall with the information
+from the Gnucomo abuse list:
+</para>
+<verbatim>
+#!/bin/sh
+#
+# Create a firewall script from the gnucomo abuses table
+#
+
+psql "sslmode=require host=server.gnucomno.org dbname=gnucomo user=firewall password=secret"
+ -c "select source from object_abuse
+ where status='dropped' and objectid=$1"|grep -v '^$'>/tmp/gnucomo-abuses
+
+while read ADDRESS
+do
+ echo iptables -I INPUT -s $ADDRESS -j DROP
+done < /tmp/gnucomo-abuses
+</verbatim>
+
</section>
</chapter>
</para>
<section>
+<heading>System resources</heading>
+<para>
+By monitoring the resources of a system, such as memory, cpu, file systems and
+network interfaces, you can keep track on the system's performance and capacity.
+The utilization of these resources varies frequently over time.
+Viewing the values of resource properties provides an excelent insight in
+the system's behaviour.
+Gnucomo can maintain a record of the system resources by using DYNAMIC properties
+in parameters.
+You can define classes of parameters with properties that will reflect the state
+of your systems and feed the numbers into the Gnucomo database by using scripts
+that extract the information from a system and convert this into XML format.
+</para>
+<para>
+As an example, consider the processing load of a system.
+Two metrics can be of interest to keep an eye on the system load:
+The total number of processes and the number of runnable processes.
+These numbers are easily obtained with standard UNIX commands <code>ps</code>
+and <code>uptime</code>.
+To maintain this in Gnucomo, a <emph>class</emph> is needed to define the
+properties we want to maintain.
+For this example, we create a class <strong>systemload</strong> with the properties
+<strong>processes</strong> and <strong>runqueue</strong>.
+Note that both these properties are DYNAMIC.
+The properties for the <strong>systemload</strong> class can be defined by using
+Gnucomo's web interface or typing SQL statements directly into the database:
+</para>
+<verbatim>
+INSERT INTO parameter_class (name, property_name, description, property_type, min, max, notify)
+ VALUES ('systemload', 'processes', 'Total number of processes', 'DYNAMIC', 0, 1000, 'f');
+INSERT INTO parameter_class (name, property_name, description, property_type, min, max, notify)
+ VALUES ('systemload', 'runqueue', '5 minute average length of the run queue', 'DYNAMIC', 0, 5.00, 'f');
+</verbatim>
+<para>
+When the class is defined in the Gnucomo database, we are ready to feed the
+information into Gnucomo through <code>gcm_input</code>.
+The following shell script will create the appropriate XML document with the
+parameter values:
+</para>
+<verbatim>
+#!/bin/sh
+#
+# Gnucomo system load report.
+#
+# Create a parameter report with two values:
+# The total number of processes and the 5-min load average.
+#
+
+
+HOST=`hostname`
+TIME=`date`
+
+echo "<?xml version='1.0'?>"
+echo "<gcmt:message xmlns:gcmt='http://gnucomo.org/transport/'>"
+echo " <gcmt:header>"
+echo " <gcmt:messagetype>XML</gcmt:messagetype>"
+echo " <gcmt:hostname>$HOST</gcmt:hostname>"
+echo " <gcmt:time>$TIME</gcmt:time>"
+echo " </gcmt:header>"
+echo " <gcmt:data>"
+
+echo " <gcmt:parameters gcmt:class='systemload'>"
+
+PROCESSES=`ps ax|wc -l|awk ' {print $1}'`
+LOADAV=` uptime|awk ' { print $11 }' | tr -d ,`
+
+echo "<gcmt:parameter name='Load'>"
+echo " <gcmt:description>System processing load</gcmt:description>"
+echo " <gcmt:property name='processes'>$PROCESSES</gcmt:property>"
+echo " <gcmt:property name='runqueue'>$LOADAV</gcmt:property>"
+echo "</gcmt:parameter>"
+
+echo " </gcmt:parameters>"
+echo " </gcmt:data>"
+echo "</gcmt:message>"
+</verbatim>
+<para>
+Filesystems are predefined in Gnucomo.
+Gcm_input understands the output of most <code>df</code> implementations directly.
+The following examples show how to feed filesystem information into Gnucomo:
+</para>
+<example>
+df -lPk -x tmpfs | gcm_input -h `hostname`
+df -lPi -x tmpfs | gcm_input -h `hostname`
+</example>
+<para>
+Make sure to add the <code>-k</code> option so <code>df</code> reports
+the filesystem sizes in kilobytes.
+</para>
+</section>
+
+<section>
<heading>Installed packages</heading>
<para>
Not the dash ('-') between the name and the version.
On many Linux systems that use the RedHat Package Manager (RPM), such
a list is easily obtained and fed into <emph>gcm_input</emph>:
+</para>
<verbatim>
rpm -qa | gcm_input -h example.gnucomo.org
</verbatim>
+<para>
You will have to repeat this procedure at regular intervals.
Each time you feed a new package list to Gnucomo, Gnucomo will
compare the new list with the package parameters in the database
input for <strong>gcm_input</strong>.
You need to strip off two siffixes off the filenames to make it look like
a <code>rpm -qa</code> output.
-The following script will do just that:
-
-<verbatim>
-
-#!/bin/sh
-#
-# Turn an 'ls' listing of RPM files into an 'rpm -qa' listing
-# Reads a list of filenames, possibly preceeded by a directory and
-# strips the directory path from the beginning and the two suffices
-# from the end of each filename. For example, the name
-# "/mnt/cdrom/RedHat/RPMS/kernel-2.4.20-13.7.i686.rpm" gets turned
-# into a simple "kernel-2.4.20-13.7".
-
-while read filename
-do
- case $filename in
- *.src.rpm)
- ;;
-
- *)
- filename=`basename $filename .rpm`
- case $filename in
- *.athlon)
- rpm=`basename $filename .athlon`
- ;;
- *.i386)
- rpm=`basename $filename .i386`
- ;;
- *.i486)
- rpm=`basename $filename .i486`
- ;;
- *.i586)
- rpm=`basename $filename .i586`
- ;;
- *.i686)
- rpm=`basename $filename .i686`
- ;;
- *.noarch)
- rpm=`basename $filename .noarch`
- ;;
- esac
- echo $rpm
- ;;
- esac
-done
-
-</verbatim>
-
-Suppose this script is stored as <code>ls-rpm</code>, you can apply it
-like this:
+Futhermore, a repository of updates often contains multiple versions of a package
+file.
+You want to make sure that the latest version of each package is recorded in the
+Gnucomo database.
+The (python) script <code>report_repository.py</code> will perfom these tasks:
+</para>
<verbatim>
- ls /mnt/cdrom/RedHat/RPMS | ls-rpm | sort | uniq | gcm_input -h redhat-7.3
+ python report_repository.py /mnt/cdrom/RedHat/RPMS | gcm_input -h redhat-7.3
</verbatim>
+<para>
You can repeat this command to enter additional packages into the database.
For example, to add packages from other CD-ROMs or from a directory where
you keep downloaded updates.