5.2. The details of servsock

This program provides an TCP socket for sockserv. After a sockserv process has successfully connected a child process is forked off for this communication. The child process consists of two threads. One thread simply receives alerts via the TCP socket and stores them in memory, see picture sockserv/servsock process. The second thread feeds the stored alerts to a database.

To successfully connect there are a few things which must be fullfilled:

Through the threading design and the use of a memory buffer the risk of loosing alerts is minimized. If more alerts are available than servsock can insert into the database[1] the alerts are buffered in memory.

To reduce the problem on memory shortage due to a high overload, the number of alerts in the buffer can be limited. This is done as with sockserv via two parameters, the LowWater and HighWater marks. If more alerts than the HighWater mark are buffered in memory as many alerts are dropped until the LowWater mark is reached. All dropped alerts are written to an unix domain socket. The program drop is able to receive these alerts and send them via email to a list of recipients.

If either sockserv can not connect to servsock on startup or the connection is closed during runtime the program tries to reopen the connection after a short delay for several times.

All output can be redirected to syslog, using the facility LOCAL0 and level INFO. A daemon mode is also supported. Finally, statistics could be printed on a periodical basis or once by sending a SIGUSR1 to the servsock master process. This process will advice all child processes to print the statitistics.

5.2.1. Options

There are several options available:

   servsock [-bCdefhlnqTuv] [-A delay] [-c config] [-D dropsocket]
            [-H HighWater] [-L LowWater] [-m mode] [-M priority] 
            [-p port] [-P pidfile] [-s snortsocket] [-S server]
            [-U alertsocket] [-V area,level] [-w dir] [-W SwapDir] [-Z TimeZone]

The servsock options in detail

-A delay

Print every delay seconds statistics about received, sent and dropped alerts. The change of these values between delay seconds is printed in brackets. See also option -l.

-b

Start the process in the background: daemon mode. This automatically activates option -l.

-d

Dump the actual configuration on startup. This is useful if both, a configuration file (see ) and command line options are used in combination and for debbuging purposes

-C

Specifies the use of a red-black tree to cache sig_id values of the database. This speeds up the INSERTs in the database but you have to enable it during the configuration run with the --enable-cache. See also the configure file option DBCache.

-c config

Specifies which configuration file should be used. The default is servsock.conf

-D dropsocket

If there are more than HighWater alerts buffered then the newest alerts are dropped to dropsocket until the LowWater mark is reached.

-e

Specifies the use of PREPARE statements with the database. This may speeds up the INSERTs in the database but you have to enable it during the configuration run with the --enable-prepare. See also the configure file option DBPrepare. This works only with the PostgreSQL database.

-f

Store additional information in the database so that a pcap file can be created with the program getpacket. Note: You need an extended database schema to use this option. See the file README.payload in the distribution.

-h

Print a help message and exit.

-H HighWater

Sets the HighWater mark, see option -D. There is no default value used.

-l

Log statitiscs to syslog instead of stdout. See also option -A.

-L LowWater

Sets the LowWater mark, see option -D. There is no default value used.

-m mode

Sets the umask to mode for the daemon mode. This affects the mode for the created unix socket and pid file. The mode can be either given in ascii, octal (with leading 0) or hex (with leading 0x) format.

-M priority

Sets the required priority for alerts to be written to AlertSocket. The program alert is able to read these alerts and send emails to a list of recipients.

-n

Do not resolve the full qualified names of the sensors, use the IP addresses instead. This will avoid conflicts with the database if on a new connection the DNS resolution fails or resolves to another name.

-p port

Defines on which port servsock should listen, see also option -S.

-P pidfile

Filename to store the PID. Note: This file must be writeable by the user running servsock!

-q

Enable quiet dropping, no dropped alerts were written to the dropsocket, see option -D.

-r

Store additional information in the database so that a pcap file including all tagged packets relating to an alert can be created with the program getpacket. Note: You need an extended database schema to use this option. See the file README.payload in the distribution.

-s socketname

Defines the name and directory where the unix domain socket of the database is opened. A value of NULL results in an internal NULL pointer, this is useful in combination with PostgreSQL. It is also possible to use a TCP socket via hostname:port.

-S server

Defines the interface where servsock should listen on. The name can be either a full qualified domain name[2] or an IP address. The default is 0.0.0.0 to bind on all available and configured interfaces. See also option -p.

-T

Enable trust modus for the database. If set, it is assumed that the alert description is already part of the database. If this is not the case, all these informations are inserted. So it is safe to enable this feature unless the transfer of alert message is disabled in snort. But this (removing of the alert message within snort) is a very experimental feature and is usually disabled by default. (But would save 256 Bytes on the wire!)

-U alertsocket

Specifies where the unix domain socket of the alert program can be found, see also -M.

-u

Disables the use of the alertsocket. This is useful if the alert is activated in the configuration file but there is no alert program running. So it is only useful for debugging.

-v

Print version information.

-w dir

Sets the working directory in daemon mode to dir. The default is to use the current working directory. It is useful to choose / to avoid blocking of mounted filesystems.

-W SwapDir

Sets the directory where the swap file sensor_SensorName is created and alerts are buffered if the database connection is lost.

-V area,value

Sets the debug level of the program. Area specifies the section of the code which should generate debug output. value should be between 0 (disabled) and 9 (maximum output). For further information read the file README.debug.

-Z TimeZone

Specifies which timezone should be used to store the time in the database (local timezone versus UTC). A ZimeZone of zero means to use the same timezone as localtime, any other value would result in the use of UTC. The default is to use the local timezone.

5.2.2. The configuration file of servsock

Additionally to the command line arguments there are some options which must be set via the configuration file. At least the database configuration has to be set in the configuration file[3].

The command line options have precedence above the settings in the configuartion file. If an option is mentioned on the command line this value is used regardless of the settings in the configuration file.

On the other hand all parameters of the command line can be set in the configuration file (except option -u). So the command line options are more suitable for quick tests.

The format of the file is simple, the first word is a keyword and the second is the value. They are separated by a colon (:) or equal sign (=). White spaces are allowed in any number.

The values can be put in single (') or double (") quotes, all between is used as the value with one exception. This exception is the comment sign (#). All entries after this sign are ignored. To use the command sign it has to be escaped with a backslash: \#.

To use white spaces in a value they must be surrounded by quotes.

So all this results in a value with space, exept the last one without quotes. This will result in spa:

'spa ce' = "spa ce" = spa ce
All keywords are case insensitive (but not the values!).

The parameters of the configuration file for servsock in detail

DBuser: name

Specifies the name of the database user who is allowed to do INSERTs, SELECTs and UPDATEs of tables. The default is snort.

DBpassword: password

Specifies the password used among with the DBuser name to connect to the database. Note: An empty password has to be represented by empty quotes, which is the default.

DBname: name

Name of the database where servsock should insert the alerts, defaults to snort.

DBtype: name

Type of the database to use. Actually only MySQL and PostgreSQL are supported and have to be enabled at compile time of servsock. No default is set since it is not clear which database support was enabled at compile time of servsock.

DBencoding: name

Defines the encoding scheme wich is used to insert the payload into the database. Allowed values are hex, base64 and ascii. The base64 encoding requires less memory in the database but it makes it difficult to search for special entries in the payload. The ascii[4] encoding stores only ascii characters in the database, all binary data is replaced by a dot. So the only really useful option is the hex scheme which is the default or base64 if saving of database space is desired.

DBtrust: value

A non-zero value enables the trust modus for the database. If this modus is enabled it is assumed that all possible signatures are already part of the database. This will result in slight faster INSERTs since less detailed SELECT statements are needed[5]. It is safe to enable this even if you are not sure, missing signatures will still be inserted. The equivalent command line is -T.

DBCache: value

A non-zero value enables the use of a cache for the sig_id. Since during inserts the only SELECTs are done to get the sig_id. The cache is implemented as a red-black tree. To use this option you have to enable it during the configure run with --enable-cache. The equivalent command line to activate the use of the cache is -C.

DBPrepare: value

A non-zero value enables the use of PREPARE with the database. This may speed up the INSERTs. To use this option you have to enable it during the configure run with --enable-prepare. This works only with the PostgreSQL database. The equivalent command line to activate this feature is -e.

DBtrans: value

A non-zero value enables the use of transactions together with the database. If you use the MySQL database you have to use tables of type InnoDB, otherwise the transactions are simply ignored.

PIDFile: pidfile

Specifies which file should be used to store the PID. This file must be writeable by the user running servsock! This correspond to option -P.

SocketName: socketname

This specifies where to find the unix domain socket of the database. If the word NULL (all capital!) is given, the database libraries find the socket by their own mechanism. This is useful in combination with the PostgreSQL database. This is equal to the -s. If socketname contains a colon (:) the first part is interpreted as a hostname, the second as a port number and a TCP connection to the database is used.

ServerName: name

Defines on which interface defined by the address servsock should listen on. Possible values for name are either full qualified names (not very useful) or a dotted IP address. The default is 0.0.0.0 to listen on all available interfaces.

ServerPort: value

Defines the port where servsock will listen on. The default is port 1234. Compare to option -p.

AlarmDelay: value

Write every value seconds statistics of received, sent and dropped alerts. In braces the differences to the last output are printed. See option -A.

Syslog: value

If the value is non-zero then the statistics are logged via syslog and not printed to stdout. The facility is LOCAL0 and the level is INFO. Compare to option -l

FQNSensor: value

With a value of zero the IP address of the sensor is used as sensor name in conjunction with the database. The equivalent command line option is -n.

AlertSocket: alertsocket

Name of the unix domain socket where alerts with high priority are written to. See option -U. If alertsocket has the name NULL then the alert feature is disabled.

UnixPriority: value

The value determines the minimum priority where alerts are additionally written to the AlertSocket[6]. The command line equivalent is the option -M.

DropSocket: dropsocket

Name of the unix domain socket where alerts are dropped to if the number of queued alerts reaches the HighWater mark. Compare to option -H. If dropsocket has the name NULL then the drop feature is disabled.

DropQuiet: value

If value is not zero then all dropped alerts are not written to the DropSocket. Note: Dropping is not disabled by this parameter.

HighWater: value

If the number of queued alerts reaches this value then servsock begins to drop alerts to the DropSocket. This corresponds to option -H.

LowWater: value

This value must be smaller than HighWater[7]. If the HighWater mark is reached so many alerts are dropped to the DropSocket until this LowWater value is reached. This corresponds to option -L.

DaemonMode: value

A non-zero value enables the daemon mode, the program forks into the background. This automatically activates the Syslog option. See option -b.

Umask: mode

Sets the umask to mode for the DaemonMode. This affects the mode for the created PIDFile. The mode can be either given in ascii, octal (with leading 0) or hex (with leading 0x). This is equal to the option -m.

SwapDir: SwapDir

Sets the directory where the swap file sensor_SensorName is created. This file is used to swap out alerts if the database has gone and is read in again if the database is available and the remote sensor connects again. The default is to use /var/tmp. See option -W.

FullPayload: value

Store additional information in the database so that a pcap file can be created with the program getpacket. Note: You need an extended database schema to use this option. See the file README.payload in the distribution and option -f.

Reference: value

Store additional information in the database so that a pcap file including all tagged packets can be created with the program getpacket. Note: You need an extended database schema to use this option. See the file README.payload in the distribution and option -r.

Debug: area,value

Sets the debug level of the program. Area specifies the section of the code which should generate debug output. value should be between 0 (disabled) and 9 (maximum output). For further information read the file README.debug. See option -V.

TimeZone: area,value

Specifies which timezone should be used. A value of zero for TimeZone results in the use of the timezone of localtime. Any other value will result in the use of UTC. See also option -Z.

5.2.3. Signalhandling

Currently the following signals are used with servsock:

SIGUSR1

Print statitics about received, sent and dropped alerts.

SIGINT

Cancels the master process, prints the final statistics and makes a clean exit. The socketname and PIDfile are removed. The child processes dump the buffered alerts to the swap file and exit.

SIGTERM

This signal results in the same behaviour as SIGINT.

SIGHUP[3]

If this signal is received by the master process then servsock stops each child process by sending a SIGTERM signal and restarts itself[8]. First all buffered alerts are written to the swap files and the final statistics are printed. Further SocketName and PIDFile are removed to enable a restart of the program. (Otherwise the program would fail since the PID did not change!) The child processes simply ignore the SIGHUP signal.

The actual version of servsock uses a control thread to change some parameters during runtime. This thread is also used to print statistics on a periodically interval instead of using signals.

5.2.4. Some additional notes

The drop and alert features are not enabled by default and have to be compiled in servsock separately. If it is not compiled in then the options -D, -L and -H are missing for the drop and the options -M, -u and -U are missing for the alert program in the output of the -h option.

In contrast to sockserv the LowWater and HighWater marks have to be choosen with more caution. First there are more processes running than the servsock processes especially the database. Further the bottleneck is not the network, it is usually the database. So it is quite normal that here the number of buffered alerts increase rapidly on heavy attacks.

Since the sensor name is taken from the IP address of the computer running sockserv (the remote sensor) there is only one sockserv instance per IP address allowed. Otherwise there will be a lot of collisions of inserts related to the database. (Two different sensors with the same name try to insert two different alerts with the same database Sensor ID, for example.)

If the connection dies, sockserv opens a new connection and a new servsock process is forked off. But if the old servsock thread feeding the database did not finished yet there arises a problem like the same sensor is logging twice times. Therefore servsock has a list of up to 25 (see the configure option --with-maxclients to adjust this value) running child processes with the sensor name they are dealing with. So if there is still one process running any new connection of a sockserv process with the same sensor name is rejected!

On startup a handshake must be fullfilled. During this phase the endianess of both partner, the availability of the database and the presence of a non-zero swap file are checked. Depending on the result a conncetion is either allowed, temporarily rejected or permanently denied.

If a SIGHUP[3] signal is received by the process with the PID stored in the PIDFile all child processes are terminated first. If there are buffered alerts it can take some time until all of them are written to the swap files. So a time delay on restart is not uncommon.

If either a SIGINT or SIGTERM is received by the servsock process handling a connection then all buffered alerts are written to the swapfile. Since this are threaded programs this may cause some problems with Linux using linuxthreads instead of the newer NTPL implementation. Note, the NTPL is only available with kernel 2.6.

Nore: With the old linuxthreads you will see two processes for each thread, one in user land and one in kernel land instead of one process. Therefore it may cause some problems with the signal handler, not all PIDs behave the same.

If a PIDFile exists the program checks for a running process with the id of this file. If one is found the program exits to avoid running the same program twice. But there is no check for which program is running, only if there is one in the process list!

Notes

[1]

Sometimes databases hang on many inserts due to things like internal garbage collection. In addition there are many tables which have to be filled in for each alert. All this will slow down the insert rate of the database.

[2]

This not really useful since central server have usually more than on interface or you need a full qualified domain name for only this interface. Most name server resolve IP addresses in a round robin procedure for more than one IP address. So the interface on which servsock bounds would not be unambigous.

[3]

Especially the password for the database should not appear in the processlist.

[4]

This option should be removed in the future in favour of using hex, it is only available to be compatible with the database output plugin of snort.

[5]

This behaviour is a little bit different to the default one. Here we check or all values like revision and priority even if they are zero. In the other case we check for NULL values if they are zero. Indeed I think if the values are not set in the rule (aka the value is zero) this value should be inserted with the rule in opposite to keep it a NULL value. This behaviour was changed in FLoP-1.6.0.

[6]

This keyword should be replaced by AlertPriority in a future release.

[7]

The mimimum difference between this two marks should be at least greater than 10.

[8]

This results in a time delay for a restart since first it must be waited until all child processes exit.