For those of you concerned about securing the alerting channel of Snort to your Demarc console, it's possible to use stunnel to protect the mysql port.

 

REQUIREMENTS

 

 

CREATING YOUR CERTIFICATE AUTHORITY

 

First, we'll create a Certificate Authority for your Sensor Group. We'll start by making a directory hierarchy for your CA:

 

$ cd /usr/share/ssl

$ mkdir DemarcCA

$ mkdir DemarcCA/certs

$ mkdir DemarcCA/crl

$ mkdir DemarcCA/newcerts

$ mkdir DemarcCA/private

$ echo "01" > DemarcCA/serial

$ touch DemarcCA/index.txt

 

Once you have created the directory structure, you should probably edit your openssl configuration file. It will most likely be named openssl.cnf -- check your distribution's documentation for where this file might be located. Under RedHat Linux, it'll be in /usr/share/ssl. OpenSSL will always tell you what configuration file it is using if you attempt to generate a Certificate -- you can also find it that way. You can use a different file, but it’s easier to find the configuration file that OpenSSL uses and modify it. If you do choose to use a different file, anytime we run the “openssl” command, you should use “-config filename” as one of the arguments.

 

In order to run a CA, you have to edit this file. When you generate certificates, the OpenSSL library will use this file to determine where it should keep information about generated certificates. You may find this configuration file works:

 

#

# openssl.cnf for DemarcCA

#

HOME                    = .

RANDFILE                = $ENV::HOME/.rnd

oid_section             = new_oids

 

[ new_oids ]

 

[ ca ]

 

default_ca      = CA_default

 

[ CA_default ]

 

dir             = /usr/share/ssl/DemarcCA

certs           = $dir/certs

crl_dir         = $dir/crl

database        = $dir/index.txt

new_certs_dir   = $dir/newcerts

certificate     = $dir/certs/demarcCA.pem       # The CA certificate

serial          = $dir/serial

crl             = $dir/crl.pem

private_key     = $dir/private/demarcCA.key

RANDFILE        = $dir/private/.rand

x509_extensions = usr_cert

default_days    = 365

default_crl_days= 30

default_md      = md5

preserve        = no

policy          = policy_match

 

[ policy_match ]

 

countryName             = match

stateOrProvinceName     = match

organizationName        = match

organizationalUnitName  = optional

commonName              = supplied

emailAddress            = optional

 

[ policy_anything ]

 

countryName             = optional

stateOrProvinceName     = optional

localityName            = optional

organizationName        = optional

organizationalUnitName  = optional

commonName              = supplied

emailAddress            = optional

 

[ req ]

 

default_bits            = 1024

default_keyfile         = privkey.pem

distinguished_name      = req_distinguished_name

attributes              = req_attributes

x509_extensions = v3_ca

string_mask = nombstr

 

[ req_distinguished_name ]

 

countryName                     = Country Name (2 letter code)

countryName_default             = US

countryName_min                 = 2

countryName_max                 = 2

stateOrProvinceName             = State or Province Name (full name)

stateOrProvinceName_default     = Change me in openssl.cnf

localityName                    = Locality Name (eg, city)

localityName_default            = Change me in openssl.cnf

0.organizationName              = Organization Name (eg, company)

0.organizationName_default      = Change me in openssl.cnf

organizationalUnitName          = Organizational Unit Name (eg, section)

organizationalUnitName_default  = Change me in openssl.cnf

commonName                      = Common Name (eg, your name or your server\'s hostname)

commonName_max                  = 64

emailAddress                    = Email Address

emailAddress_max                = 40

emailAddress_default            = Change me in openssl.cnf

 

[ req_attributes ]

 

challengePassword               = A challenge password

challengePassword_min           = 4

challengePassword_max           = 20

unstructuredName                = An optional company name

 

[ usr_cert ]

 

basicConstraints=CA:FALSE

nsComment                       = "Demarc CA OpenSSL Generated Certificate"

subjectKeyIdentifier=hash

authorityKeyIdentifier=keyid,issuer:always

 

[ v3_req ]

 

basicConstraints = CA:FALSE

keyUsage = nonRepudiation, digitalSignature, keyEncipherment

 

[ v3_ca ]

 

subjectKeyIdentifier=hash

authorityKeyIdentifier=keyid:always,issuer:always

basicConstraints = CA:true

 

[ crl_ext ]

 

authorityKeyIdentifier=keyid:always,issuer:always

 

 

Note that you’ll especially want to configure the req_distinguished_name section. Once this config file is in place, you can generate the CA certificate. We’ll generate one that lasts 10 years. This should be okay since we’re the only ones that will use this cert, and it will be signing other certs that should last a shorter time.

 

$ openssl req -new -x509 -keyout DemarcCA/private/demarcCA.key \

       –out DemarcCA/certs/demarcCA.pem -days 3650

 

OpenSSL will prompt you for a number of pieces of information. It is important that you answer each question to the best of your ability and REMEMBER WHAT YOU ENTERED. It will come back to haunt you later.

 

The dialog will look something like this:

 

Using configuration from /usr/share/ssl/openssl.cnf

Generating a 1024 bit RSA private key

.........++++++

.....................................++++++

writing new private key to 'DemarcCA/private/demarcCA.key'

Enter PEM pass phrase:

Verifying password - Enter PEM pass phrase:

 

Pick a good passphrase. You'll need it later to sign sensor certificates!

 

You are about to be asked to enter information that will be incorporated

into your certificate request.

What you are about to enter is what is called a Distinguished Name or a DN.

There are quite a few fields but you can leave some blank

For some fields there will be a default value,

If you enter '.', the field will be left blank.

-----

Country Name (2 letter code) [US]: US

State or Province Name (full name) []: New York

Locality Name (eg, city) []: New York

Organization Name (eg, company) []: Big Time, Inc.

Organizational Unit Name (eg, section) []: Security Team

Common Name (eg, your name or your server's hostname) []:Demarc Sensor Certificate Authority

Email Address []: security@myowndomain.org

 

Note in the above dialog that the Common Name is set to your CA name. You can pick anything you want, really – whatever you want your CA to be known.

 

At this point, you'll have a couple of files generated for your CA. One is the CA's private key -- you'll want to protect it. One is the CA's public key -- the one with the .pem extension.

 

$ chmod 400 DemarcCA/private/demarcCA.key

$ chown root.root DemarcCA/private/demarcCA.key

 

Congratulations! You are now ready to start generating certificates from your brand-new CA!

 

GENERATING A CLIENT CERTIFICATE

 

Now you’ve put the Demarc client on a remote box – for the sake of argument, we’ll call this client “Demarc SID 2”. The hostname of the machine is “sensor2”. Knowing only that, we’re ready to start with a client certificate. On the CA machine, do this:

 

$ cd /usr/share/ssl/DemarcCA

$ openssl req -new -keyout newreq.pem -out newreq.pem –days 365

 

The dialog will look similar to when you generated the CA certificate. When prompted for the Common Name, use the hostname “sensor2” – or its fully qualified domain name. The file newreq.pem now contains both the sensor’s private key and certificate request. Now we sign the certificate with the CA’s certificate:

 

$ openssl ca -policy policy_anything -out newcert.pem \

     -infiles newreq.pem

 

You’ll see a dialog that looks like the following. Where the user is prompted for a passphrase, enter the CA’s passphrase.

 

Using configuration from /usr/share/ssl/openssl.cnf

Enter PEM pass phrase:

Check that the request matches the signature

Signature ok

The Subjects Distinguished Name is as follows

countryName           :PRINTABLE:'US'

stateOrProvinceName   :PRINTABLE:'New York'

localityName          :PRINTABLE:'New York'

organizationName      :PRINTABLE:'Big Time, Inc.'

organizationalUnitName:PRINTABLE:'Security Team'

commonName            :PRINTABLE:'sensor2'

emailAddress          :IA5STRING:'security@bigtime.org'

Certificate is to be certified until Jul 31 21:53:42 2002 GMT (365 days)

Sign the certificate? [y/n]:y

 

 

1 out of 1 certificate requests certified, commit? [y/n]y

Write out database with 1 new entries

Data Base Updated

 

At this point, you will have two files in the current directory. One is named “newreq.pem” and contains both the original certificate request and the server’s given private key. This key is encrypted with the passphrase you used when generating the request. The other file is named “newcert.pem” and contains the CA signed certificate.

 

These are the two files you’ll need to create a secure tunnel back to the Demarc console where your CA resides. You’ll need to transfer those files securely to the remote sensor (hint: use SSH). While you’re at it, transfer a copy of the CA’s certificate over to the remote sensor, too. It’s in /usr/share/ssl/DemarcCA/certs/demarcCA.pem.

 

After you’ve transferred those two files off to the remote server, clean up a bit.

 

$ rm newreq.pem

$ rm newcert.pem

 

You don’t have to worry about the newly issued cert – you have a copy of it stored in your CA. But you do have to worry about the newreq.pem file as it contains your private key. Did you check to see if you really DID copy it? :>

 

After you’ve cleaned up, follow these same steps again to generate a certificate for your Demarc main server (hostname “demarc1” or something like that). The same instructions will apply. Once you’ve generated the key and request, sign it. Once signed, hang on to the new files. We’ll need them shortly.

 



SETTING UP THE SERVER SIDE OF THE TUNNEL

 

Now we’re ready to play with stunnel. We’ll start by configuring the Demarc server’s stunnel proxy. We have the following goals in mind:

 

-          We want to only allow connections from certain clients that have a certificate signed by us.

-          We want to provide encrypted MySQL service on port 3307/tcp for authenticated users.

 

With those goals in mind, we first set up our stunnel configuration area. As root:

 

# mkdir /etc/stunnel

# mkdir /etc/stunnel/keys

# mkdir /etc/stunnel/clients

# cd /etc/stunnel

 

Your private key, now sitting in the newreq.pem that you just generated, is encrypted. We’ll have to decrypt it so stunnel can use it. Do this:

 

# openssl rsa -in /usr/share/ssl/DemarcCA/newreq.pem \

       -out /usr/share/ssl/DemarcCA/server.key

 

This will prompt you for this certificate’s passphrase, and then write the unencrypted key to disk. Of course, you’ll want to protect this key.

 

# cat /usr/share/ssl/DemarcCA/server.key \

       /usr/share/ssl/DemarcCA/newcert.pem > \

       keys/server.key

# chmod 400 /etc/stunnel/keys

# chmod 400 /etc/stunnel/clients

# chmod 400 /etc/stunnel/keys/server.key

# rm /usr/share/ssl/DemarcCA/newreq.pem

# rm /usr/share/ssl/DemarcCA/server.key

 

That will put the server’s key in the directory, ready for use. Note that stunnel likes to have the private key and certificate in the same file.

 

Now you’re going to create a file in the clients directory that will tell stunnel to only allow a connection from a particular certificate. Just creating a link to that certificate does this. This gets a little tricky, so watch closely:

 

# cat /usr/share/ssl/DemarcCA/index.txt

V       020731215342Z           01      unknown /C=US/ST=New York/L=New York/O=Big Time, Inc./OU=Security Team/CN=sensor2/Email=security@bigtime.org

V       020731216432Z           02      unknown /C=US/ST=New York/L=New York/O=Big Time, Inc./OU=Security Team/CN=demarc1/Email=security@bigtime.org

 

This file tells you what certificates have been issued by the CA. You should have two lines showing. You’re looking for the certificate for the remote sensor – he’s going to be your client. Note the two numbers in the third column and the entry for the Common Name (CN=). This will tell you what you need to know.

 

In this case, the certificate of our client is the first line. The third column says that this certificate is serial number “01”. Our common name – as we had generated the certificate – is “sensor2”. Now we’re ready to make sure stunnel knows about this certificate.

 

# ln –s /usr/share/ssl/DemarcCA/newcerts/01.pem \

          “/etc/stunnel/clients/`openssl x509 -hash -noout –in \

           /usr/share/ssl/DemarcCA/newcerts/01.pem`.0”

       

That’s a rather complex command line, but it does something relatively simple. It merely creates a link to the CA’s copy of the client’s certificate named with its x509 hash.

 

You should get something that looks like this:

 

# ls /etc/stunnel/clients

60eb6d4e.0

 

That file should be a link to the certificate with serial number 01 in the CA’s own local certificate store.

 

Now we’re ready to fire up the SSL tunnel.

 

# stunnel -d 3307 -r 3306 \

     -A /usr/share/ssl/DemarcCA/certs/demarcCA.pem \

     -p /etc/stunnel/keys/server.key -v 2 -a /etc/stunnel/clients

 

This command line does the following:

 

-          Brings up port 3307/tcp and connects it to port 3306 on the local host.

-          Informs stunnel where the CA’s certificate is.

-          Informs stunnel where its own private key is.

-          Tells stunnel to look in /etc/stunnel/clients to find out who its clients are.

-          Tells stunnel to verify every connection and certificate it gets against the contents of /etc/stunnel/clients.

 

Now you’re finished with the server. We’ll now move on to the configuration of the remote sensor client.

 

CONFIGURING THE REMOTE CLIENT TUNNEL

 

First, let’s create the directories we’ll use for stunnel. As root:

 

# mkdir /etc/stunnel

# mkdir /etc/stunnel/keys

# mkdir /etc/stunnel/clients

# cd /etc/stunnel

 

As with the server’s stunnel private key, the key you have in newreq.pem is encrypted. Stunnel wants an unencrypted key, so:

 

# openssl rsa -in /home/user/newreq.pem -out /home/user/server.key

# cat /home/user/server.key /home/user/newcert.pem > keys/server.key

# chmod 400 /etc/stunnel/keys

# chmod 400 /etc/stunnel/clients

# chmod 400 /etc/stunnel/keys/server.key

# rm /home/user/newreq.pem /home/user/server.key

 

You’ll remember that stunnel likes to have the private key and certificate in the same file. Once you’ve completed the configuration above, make sure the CA’s certificate is placed into the keys directory as well.

 

# mv /home/user/demarcCA.pem /etc/stunnel/keys

 

Now we’re ready to start the client side of the connection.

 

# stunnel -c -A /etc/stunnel/keys/demarcCA.pem \

    -p /etc/stunnel/keys/server.key -d localhost:3306 \

    -r demarc1:3307 -v 2

 

This command line does the following:

 

Tells stunnel to act as a client.

Informs stunnel as to where the CA’s cert is.

Informs stunnel where its own key is.

Brings up port 3306/tcp on localhost (127.0.0.1).

Connects it to port 3307/tcp on the server (demarc1).

Tells stunnel to verify the certificate it gets from demarc1 against its CA cert.

 

Interestingly, when you bind stunnel to a localhost port, it won’t allow anyone else to connect to this port remotely. This will be useful to us when we’re configuring the client.

 

Important: Please note that when you’re configuring a sensor that is running MySQL already, you’ll have to bind to a port on localhost OTHER than 3306/tcp. MySQL by default binds to all addresses, and this includes localhost. You’ll know if this is the case immediately once you start the stunnel instance because you’ll see something similar to:

 

2001.08.01 17:00:42 LOG3[19385:1024]: bind: Address already in use (98)

 

If this is the case, change the –d localhost:3306 to –d localhost:4040 and try the command again.

 

CONFIGURING THE REMOTE DEMARC CLIENT

 

This is easy. Really easy.

 

You already know to modify the SID value in the script. And you already know that you need to modify the database configuration. Instead of pointing the remote client at the remote server directly, just point IT to 127.0.0.1 (localhost). Like so:

 

my $db_user                     = "snort_user";

my $db_password                 = "mypass";

my $db_host                     = "127.0.0.1";

my $db_name                     = "snort";

 

Then, in the snort.conf configuration for the remote sensor (Demarc SID 2), make sure that your database line looks like:

 

output database: alert, mysql, user=snort_user password=mypass dbname=snort host=127.0.0.1

 

And, if you had to configure the remote snort sensor’s stunnel command line differently because of a local MySQL server instance, you’ll need to add:

 

my $db_port                     = "4040";

 

You’ll then need to modify the client script to add this port to the connection. Around line 966, find a line that starts with:

 

$db = DBI->connect("dbi:mysql:

 

Change that line to add in the $db_port you just defined:

 

$db = DBI->connect("dbi:mysql:host=$db_host;port=$db_port;database=$db_name", $
db_user , $db_password) || &red("Connection Problem! ". $DBI::errstr);

 

You’ll also have to modify your snort output rule:

 

output database: alert, mysql, user=snort_user password=mypass dbname=snort host=127.0.0.1 port=4040

 

If you just want to make sure that the database connectivity is working, use the MySQL client:

 

# mysql –host=127.0.0.1 –user=snort_user –p

Password:

 

Welcome to the MySQL monitor.  Commands end with ; or \g.

Your MySQL connection id is 80 to server version: 3.23.36

 

Type 'help;' or '\h' for help. Type '\c' to clear the buffer

 

mysql>

 

A simple “show databases;” should be enough to prove that it’s working okay.

 

You now have a secure transport for your snort logs and your snort configuration files managed by Demarc! Congratulations, pat yourself on the back.

 

 

Thanks to Dan Brown for fixes and suggestions!