The snort2pfsense shell script (snort to pfSense)

Introduction

Josep Pujadas i Jubany

All you need in your snort sensor

?

All you need in your pfSense

22-june-2007

Download snort2pfsense
Configure snort2pfsense
Create the snort2pfsense tables
Load your snort2pfsense whitelist
Run snort2pfsense in interactive mode
Daemonize snort2pfsense
Putting snort2pfsense to work at startup
Miscellaneous snort2pfsense commands
Changelog
snort2pfsense License

 

Introduction

snort2pfsense (snort to pfSense) is a shell script that synchronizes an snort sensor using MySQL output with a pfSense firewall.

With a hard disk platform, pfSense can have snort installed, but if you want to not charge your pfSense box with snort or you have a pfSense embedded system you will find snort2pfsense very useful. snort2pfsense integrates your external snort box with the pfSense firewall.

snort2pfsense uses the expect scripter and makes SSH connections to the console of pfSense.

snort2pfsense looks for the offenders hosts at the MySQL snort database and updates the snort2c PF (Packet Filter) table of pfSense. No matter if you don't have the snort package installed in your pfSense box.

snort2pfsense has its own white list.  The white list can have single hosts an entire networks. If an offender host is white listed it will be never blocked.

snort2pfsense's IP addresses (and masks) are stored as integer numbers at the MySQL database, as snort does. snort2pfsense provides tools to see your IP addresses (and masks) formatted as text. snort2pfsense shows also the host names, resolved using the dig command.

 

 

All you need in your snort sensor

The snort2pfsense script has been tested on a snort sensor with:

FreeBSD 6.2   
snort 2.6.1.4 http://www.freebsd.org/cgi/url.cgi?ports/security/snort/pkg-descr
mysql server 5.1.16 http://www.freebsd.org/cgi/url.cgi?ports/databases/mysql51-server/pkg-descr
mysql client 5.1.16  
expect 5.43.0_3 http://www.freebsd.org/cgi/url.cgi?ports/lang/expect/pkg-descr
since 0.5 http://www.freebsd.org/cgi/url.cgi?ports/misc/since/pkg-descr
snort2pfsense  

 

All you need in your pfSense

SSH access activated, [System] [Advanced] [Enable Secure Shell] using port 22.
pfSense console is activated (default configuration).
Permit the SSH traffic from your sensor to your LAN address.
The time that the offender hosts are in the snort2c PF (Packet Filter) table. pfSense blocks these hosts for the time specified.

The snort2c PF (Packet Filter) table always exists, no matter if you have or not the snort package installed in your pfSense box.

At pfSense SSH shell, type:

cat /cf/conf/config.xml | grep snort2c

and you will see something like:

<command>/usr/bin/nice -n20 /usr/local/sbin/expiretable -t 1800 snort2c</command>

So, bad hosts will be 1800 seconds (a half hour) in the snort2c PF (Packet Filter) table.

If you want to change this value, you can use the "XML method":

http://faq.pfsense.com/index.php?action=artikel&cat=10&id=38&artlang=en&highlight=hidden

Note: pfSense uses expiretable to erase the old hosts in its PF (Packet Filter) tables.

If you didn't yet, make a manual SSH login to your pfSense (from your sensor box) before to run snort2pfsense.  This will store the SSH  fingerprint of pfSense and avoid the "first time" fingerprint question for new connections.

 

Download snort2pfsense

cd /root
mkdir snort2pfsense
chmod 700 snort2pfsense
cd snort2pfsense
Create a folder where to have and run snort2pfsense. It must be a very sure place. Your snort2pfsense script contains users & passwords to access to your pfSense box and your MySQL server.
fetch http://www.bellera.cat/josep/snort2pfsense/snort2pfsense.tar.gz Download the file to your snort2pfsense sure folder.
tar -zxvf snort2pfsense.tar.gz Uncompress the file.
rm snort2pfsense.tar.gz Erase snort2pfsense.tar.gz (optional).
chmod 600 *
chmod 700 snort2pfsense.sh
chown root:wheel *
Be sure with your snort2pfsense files.

 

Configure snort2pfsense

vi snort2pfsense.sh

s2p="/root/snort2pfsense" snort2pfsense's home. Be careful! The script looks for files in this folder. It also creates many files. For example, it creates the snort2pfSense.exp expect script which contains user & password for SSH access to your pfSense.
s2p_log="/var/log/snort" Where to put snort2pfsense.log. This file contains all the expect script execution, as you were typing at the pfSense console. Like this you have a very interesting trace. Be careful, the file can grow very quick. Think to rotate it. snort2pfsense doesn't make for you, as snort doesn't make for its alert file.
pf_ip="192.168.XXX.1" The IP address of your LAN at the pfSense  box. Where to find your pfSense . If you prefer, you can use also a hostname (less sure).
pf_pass="********" The password for your pfSense administrator. It is the same password for the web GUI of pfSense.
pf_sleep="2" Seconds to wait after making a SSH access to the pfSense  box. Perhaps not necessary. snort2pfsense connects only to the pfSense when it needs to change the snort2c PF table (at the pfSense box). In prior versions of snort2pfsense I had some troubles connecting to pfSense and I opted going to sleep some seconds the connections. Consider to put:

pf_sleep="0"

host="127.0.0.1" The IP or hostname for your  MySQL server.
dbname="snort_database" The database name for your snort sensor.
user="admin_snort_database" The administrator user for your snort database.
passwd="********" The password for the administrator user for your snort database.
mailto="user@domain.example" If you want to send a mail with the snort2pfsense activity at user@domain.example. If not, put:

mailto=""

vi snort2pfsense_block.sql
vi snort2pfsense_unblock.sql

SET @pf_timer = 1800; This MySQL variable at snort2pfsense_block.sql and snort2pfsense_unblock.sql files permit to adjust the time that offender hosts are blocked in seconds). It must coincide with the expiretable at the pfSense box. Otherwise, you can have erratic blocking/unblocking. See above.

vi snort2pfsense_whitelist.sql

INSERT INTO snort2pfsense_whitelist (lan, mask) VALUES (INET_ATON('127.0.0.1'), INET_ATON('255.255.255.255')); Put your white listed networks and hosts. Use syntax as examples:

For network 192.168.125.0/24 (two possibilities listed)

I
NSERT INTO snort2pfsense_whitelist (lan, mask) VALUES (INET_ATON('192.168.125.0'), INET_ATON('255.255.255.0'));

INSERT INTO snort2pfsense_whitelist (lan, mask) VALUES (INET_ATON('192.168.125.0'), (POW(2, 32) - POW(2, 32 - 24)));

For host 192.168.125.10 (three possibilities listed)

INSERT INTO snort2pfsense_whitelist (lan, mask) VALUES (INET_ATON('192.168.125.10'), INET_ATON('255.255.255.255'));

INSERT INTO snort2pfsense_whitelist (lan, mask) VALUES (INET_ATON('192.168.125.10'), (POW(2, 32) - POW(2, 32 - 32)));

INSERT INTO snort2pfsense_whitelist (lan, mask) VALUES (INET_ATON('192.168.125.10'), (POW(2, 32) - 1));

Don't forget to whitelist your snort & pfSense boxes !!!

 

Create the snort2pfSense tables

Now you need to create the snort2pfsense tables into your snort MySQL database.

Just type:

./snort2pfsense.sh create

You can use the create option whenever you want. It will drop your snort2pfesense tables and will create it a new time.


Load your snort2pfsense white list

Just type:

./snort2pfsense.sh whitelist

If in the future you want to change your white list, edit snort2pfsense_whitelist.sql and reload it:

vi snort2pfsense_whitelist.sql
./snort2pfsense.sh whitelist

To view your white list (whenever you want), type:

./snort2pfsense.sh whitelist_view

 

Run snort2pfsense in interactive mode

Run snort2pfsense.sh without parameters:

./snort2pfsense.sh

The script will use the standard output to show its activity.

Use Ctl-C if you want to stop it.

 

Daemonize snort2pfsense

Type:

daemon /root/snort2pfsense/snort2pfsense.sh >/dev/null

to put the execution to the background.

If you want to know if the script is running, type:

ps -aux | grep snort2pfsense

and you will see something like:

root 43570 0,0 0,1 1744 1160 ?? Ss 6:23PM 0:51,81 /bin/sh /root/snort2pfsense/snort2pfsense.sh
root 19323 0,0 0,1 1604 976 p0 S+ 12:38PM 0:00,00 grep snort2pfsense

If you want to stop the script, kill its process. At the above example should be:

kill 43570

 

Putting snort2pfsense to work at startup

As root, add a crontab at reboot time:

crontab -e

@reboot /usr/sbin/daemon /root/snort2pfsense/snort2pfsense.sh >/dev/null

If you want to stop and restart snort2pfsense without rebooting you box, follow the steps explained at the Daemonize snort2pfsense section of this page.

 

Miscellaneous snort2pfsense commands

snort2pfsense has some more useful commands not explained yet.

./snort2pfsense blocked Lists the hosts blocked by snort2pfsense.
./snort2pfsense since Shows your snort2pfsense.log file since last time you have done.
./snort2pfsense flush Flushes all blocked hosts. It isn't a good idea to use this option if you have snort2pfsense running in interactive mode or daemonized. I wrote this option just for maintenance. I conserved it because it can be useful in some situations. Stop snort2pfsense before using the flush option.
./snort2pfsense alert Shows your /var/log/snort/alert file since last time you have done. I use BASE to surf my sensor, but sometimes it's faster to look at  the snort alert file.
./snort2pfsense start Puts snort2pfsense in daemonized mode.
./snort2pfsense stop Stops snort2pfsense in daemonized mode.
./snort2pfsense restart Makes stop & start.

 

Changelog

22-june-2007
  • Unblocking actions are now made before blocking actions. This insure if an offender host is unblocked and must be blocked a new time the blocking action will be the last.
12-june-2007
  • Minor changes to this web page.
07-june-2007
  • Added killing states for the offender IP after including it in the snort2c PF table of pfSense. This make more sure & fast the blocking action.
  • Tested with pf_sleep="0". It seems to work. Recommended value for most cases.
  • Added start command.
  • Added stop command.
  • Added restart command.

 

snort2pfsense License

snort2pfsense code and documentation are released under the BSD license, under terms as follows.

Copyright (c) 2007, Josep Pujadas i Jubany
Alls rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.