I managed to get some preliminary code working yesterday and later
today when I get home I'll get the chance to test it with the real
plug in to see whether SSL works. If it does, I'll propose some
changes to include SSL capability to the PGSQL plugin.
OK, I've just done some testing using the PGSQL plugin with hard-coded
values to create a secure (SSL) connection and verify how that plugin
works. In short - it is absolutely flawless!
I am able to establish 4 types of SSL connections between ulogd and my
PostgreSQL database server and conducted tests on various (known)
attacks to see how it behaves - it passes with flying colours!
In the mean time, I found a bug and a "maybe" bug:
1. pgsql-ulogd2 script:
CREATE TABLE ulog2 (
[...]
timestamp timestamp NOT NULL default 'now'
The above will insert a string, equivalent to the current timestamp when
the table was created as a default value (which PostgreSQL will
automatically convert to timestamp) and *not* when a record is inserted
into the table. The correct syntax is:
"timestamp" timestamp NOT NULL default now()
2. When I start using NFCT and it does the logging to the database, I am
getting endless sequences of the following statement in the main
ulogd.log file:
<5> ulogd_inpflow_NFCT.c:697 unsupported message type
I don't know whether there is something I am doing wrong or whether
there is a message which ulogd cannot interpret. Maybe a bug, maybe not,
I don't know.
So, for SSL implementation in the PGSQL plugin, this is how I see it:
PostgreSQL (the server) allows for 6 different types of SSL connections
to be established between it and a client [1]:
Option Description
~~~~~~ ~~~~~~~~~~~
disable only try a non-SSL connection
allow first try a non-SSL connection; if that fails, try an SSL
connection
prefer (default) first try an SSL connection; if that fails, try
a non-SSL connection
require only try an SSL connection
verify-ca only try an SSL connection, and verify that the server
certificate is issued by a trusted CA
verify-full only try an SSL connection, verify that the server
certificate is issued by a trusted CA and that the server host name
matches that in the certificate
The above option is configured with the "sslmode" connection option
("sslmode=verfify-full" for example). In earlier PostgreSQL versions
(below 8, I think), there was only one possible option and that was
"requiressl" ("requiressl=1" is equivalent to "sslmode=require" above,
while "requiressl=0" is the equivalent to "sslmode=prefer").
As far as verification goes, there is one additional parameter which
could also be deployed on the PostgreSQL server to check request and
check the client certificate as well. So verification and checking could
be a dual process on both the client and the server.
In addition to the above parameter, 4 other connection options can be
specified:
sslcert - This parameter specifies the file name of the client SSL
certificate, replacing the default ‘~/.postgresql/postgresql.crt’. This
parameter is ignored if an SSL connection is not made.
sslkey - This parameter specifies the location for the secret key used
for the client certificate. It can either specify a file name that will
be used instead of the default ‘~/.postgresql/postgresql.key’, or it can
specify a key obtained from an external “engine” (engines are OpenSSL
loadable modules). An external engine specification should consist of a
colon-separated engine name and an engine-specific key identifier. This
parameter is ignored if an SSL connection is not made. If this key is
protected with a password, this will be asked when the connection is
made. On the server side, it is stored internally and asked once when
the server starts up. on the client side it is asked every time an
attempt for a connection is made.
sslrootcert - This parameter specifies the name of a file containing SSL
certificate authority (CA) certificate(s). If the file exists, the
server's certificate will be verified to be signed by one of these
authorities. The default is ‘~/.postgresql/root.crt’.
sslcrl - This parameter specifies the file name of the SSL certificate
revocation list (CRL). Certificates listed in this file, if it exists,
will be rejected while attempting to authenticate the server's
certificate. The default is ‘~/.postgresql/root.crl’.
So, the way I see it, we can mirror all of the above 5 options,
including their default values quite easily and let PGconn do the rest
(please note that the PG .so object library takes care of opening the
certificate files as well as checking and validating the various
certificates contained within - this is done transparently to the client
- PGSQL plugin in this case). The modifications to the PGSQL plugin
would be minimal and will consists of little more than adding the above
parameters and then passing their values as connection options to PGconn.
As far as hardening the access to the system tables goes, the way I see
it there are 2 possible options:
1. Change the meaning of the "table" plugin parameter to point to a
user-defined table, which contains a single row where all column names
of the main ulogd table are stored. This option *will* brake backward
compatibility!
2. Keep the existing "table" option and add a separate parameter
(probably called "columns" or "table_columns" or something like that),
which will contain a single row with the description of all usable
columns in the "table" table where the main ulogd logging will take place.
I think option 2 is better, though at the expense of adding an extra
configuration parameter, in addition to the 5 new ones for SSL support I
listed above.
A few other observations and a query: Currently, there isn't a
"user-friendly" NCFT view implemented in the PGSQL plugin, similar to
the one designed for NFLOG (the one implemented for NFLOG is called
ulog, I think) where the various numeric and raw values are "deciphered"
for the end user and presented in a nice format to be understood more
easily.
All NFCT logs are currently dumped, quite literally, in the ulogd2_ct
table. Such a view would be very easy to create - I could do it and
submit it together with the above changes if there is interest.
One last question - is there a way where I could get *all* possible
values which a given filter plugin interprets, like source/destination
IP address/subnet, interface names etc?
The reason I am asking this is because if I could use or implement a
command line parameter (similar to "ulogd -i"), which asks every filter
plugin to list the names of the parameters it processes from the input
plugin, then I could build a reliable set of parameters which are then
used to build a complete database script to be used in the creating the
database schema which is then used by ulogd2.
Currently, I am only guessing what each plugin processes - it is like a
black box, which isn't good-enough for me.
[1] - PostgreSQL v9.0 Programmer's Manual -
http://www.network-theory.co.uk/docs/postgresql9/vol2/DatabaseConnectionControlFunctions.html
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html