Persistent Storage

Five collections can hold data persistently, that is, data available to multiple requests: GLOBAL, RESOURCE, IP, SESSION and USER. They are available in both ModSecurity v2 and libModSecurity v3, but the storage behind them differs (see below).

Every collection contains several built-in variables that are available and are read-only unless otherwise specified:

  1. CREATE_TIME - date/time of the creation of the collection.
  2. IS_NEW - set to 1 if the collection is new (not yet persisted) otherwise set to 0.
  3. KEY - the value of the initcol variable (the client’s IP address in the example).
  4. LAST_UPDATE_TIME - date/time of the last update to the collection.
  5. TIMEOUT - date/time in seconds when the collection will be updated on disk from memory (if no other updates occur). This variable may be set if you wish to specify an explicit expiration time (default is 3600 seconds, configurable with SecCollectionTimeout). The TIMEOUT is updated every time that the values of an entry is changed.
  6. UPDATE_COUNTER - how many times the collection has been updated since creation.
  7. UPDATE_RATE - is the average rate updates per minute since creation.

To create a collection to hold session variables (SESSION) use action setsid. To create a collection to hold user variables (USER) use action setuid. To create a collection to hold client address variables (IP), global data or resource-specific data, use action initcol.

Note

Persistent collections can only be initialized once per transaction.

Note

ModSecurity implements atomic updates of persistent variables only for integer variables (counters) at this time. Variables are read from storage whenever initcol is encountered in the rules and persisted at the end of request processing. Counters are adjusted by applying a delta generated by re-reading the persisted data just before being persisted. This keeps counter data consistent even if the counter was modified and persisted by another thread/process during the transaction.

Storage backends

ModSecurity v2

ModSecurity v2 stores each collection in an SDBM database file (APR’s apr_sdbm) in the directory set by SecDataDir; the directory must be writable by the web server user. SDBM is limited to storing a maximum of 1008 bytes per key, which may be a limitation if you are attempting to store a considerable amount of data in variables for a single key. The files are shared by all Apache worker processes on the host.

libModSecurity v3

libModSecurity v3 keeps the collections in memory, per process by default (src/collection/backend/in_memory-per_process.cc). The data does not survive a restart and is not shared between worker processes, so with NGINX each worker sees its own copy of IP, GLOBAL and the other collections. SecDataDir is accepted by the parser for compatibility with modsecurity.conf-recommended but has no effect.

If the library is built with --with-lmdb, the collections are stored in an LMDB database instead, which is shared by all processes on the host. The database file is modsec-shared-collections in the working directory of the process (the path is fixed by the backend; SecDataDir is not consulted). LMDB has, by default, a maximum key length of 511 bytes.

Warning

In libModSecurity v3, setvar actions in a rule are executed before initcol in the same rule, so a variable written by the rule that initializes a collection is lost when the collection did not exist yet. Initialize the collection in one rule and write to it in a later rule.