Snort on FreeBSD

This page has become quite dated and should be viewed as an historical reference only.

Below is a step-by-step guide from soup to nuts on building an NIDS that utilizes Snort, MySQL, and Acid to collect, analyze, and report potentially malicious network traffic.

Click here if you’re impatient and just want to get to the good stuff.

Conventions

Throughout these instructions you’ll notice that instead of using the vi editor I use ee (easy editor). This is my personal preference because it is MUCH easier to use for the uninitiated (like me).

All commands are designated by a preceding pound-sign (#) and all are in the italic font. For example:

# cd /usr/ports/net/cvsup-without-gui

Unique input will be designated with [brackets]. For example; if you need to create a user and you want to create the user Foo, when I use the term [username] you would replace that with Foo without the [brackets].

Assumptions

I’m assuming the reader has a vague working knowledge of Unix and how to navigate and manipulate files and directories as needed. An invaluable reference for the Unix n00b is “FreeBSD Unleashed” by Michael Urban & Brian Tiemann.

I’m also assuming the reader has a solid understanding of the theory behind intrusion detection (ID), packet filtering, and somewhat-advanced networking concepts. This paper is NOT intended to teach anything about intrussion detection or network security.

Scope

The sole purpose of this document is to help you install and update FreeBSD. Then install Snort and all necessary components to be able to log to a MySQL database and query that database using ACID. Finally to secure the machine.

The short-list:

  1. Gather and assemble your hardware
  2. Install FreeBSD (latest Release version at time of writing: 5.3.0)
  3. Makeworld to update your source code and ports tree1
  4. Install the following ports:
    • portupgrade
    • Apache13-modssl
    • wget
    • jpgraph
    • adodb
    • libnet
    • MySQL server
    • Snort (Version 2.1.3 as of this writing)
    • Acid (Version v0.9.6b21 as of this writing)
  5. Configure Snort
  6. Configure Apache
  7. Configure Acid
  8. Configure MySQL
  9. Enable Snort to run on startup and update rules daily
  10. Test IDS functionality
  11. Enable/configure IPFW
  12. Test again
  13. Deploy
  14. References

FreeBSD Installation and Configuration

I was able to download the ISO of FreeBSD from their website and burn it to CD. I then used that to install the OS.

Once the OS is correctly installed from CD we are going to use CVSUP to update our entire operating system and then our entire ports tree. This will ensure that we are up-to-the-minute on our OS and all applications we will be installing. It is extremely important for us to ensure that the NIDS foundation (FreeBSD) is rock-solid.

  1. Skip the Kernel Configuration and continue with Installation
  2. Select “Standard” Installation
  3. Select your hard disk
  4. Select “BootMgr” to install the FreeBSD boot manager
  5. Continue setting up your slices. One word of caution; I configure Snort to place all logs in /var/log, so the default 256 MB size for the /var slice needs to be changed here. I typically choose “Auto” then delete /var and /usr and recreate /usr with around 5GB and /var with the remaining space.
  6. Select #8 “User,” select “Yes” to install the ports collection, then scroll down a few lines, hit Custom and choose to install all of the source.
  7. Select installation media (in my case “CD”)
  8. Confirm that you know you’ll loose data that may be on the disk
  9. Configure your Ethernet device
    1. Select the card (most likely the top of the list, if you have multiple cards, you’ll see entries like fxp0, fxp1, etc)
    2. Don’t try IPV6
    3. Don’t use DHCP
    4. Configure the IP settings for your card
    5. Select “YES” to bring up the interface
  10. Select “NO”, we don’t want the machine to act as a gateway
  11. Select “YES” for SSH authentication so you can administer the machine securely
  12. Don’t configure INETD, FTP, or NFS
  13. Accept the default kernel security (moderate)
  14. Customize the console settings if you want
  15. Set the time zone
  16. Don’t enable Linux binary compatibility
  17. No need for a USB mouse
  18. Skip the Package selection
  19. Create a user (type “wheel” in the Member Groups field to make this user an admin)
  20. Create a good root password
  21. Exit Install
  22. Install CVSUP-without-gui (Internet connection needed from here on)
    1. # CD /usr/ports/net/cvsup-without-gui
    2. # make ; make install clean
  23. At the prompt for “gettext,” install the example files and html man files if you’d like
  24. # rehash
  25. # mkdir /home/ncvs/
  26. MakeWorld to update your source tree and ports tree1
    1. Edit the cvs-supfile

      # cd /usr/share/examples/cvsup

      # ee cvs-supfile

      In the host= field, use the CVSUP mirror site closest to you. For example, my line reads:

      *default host=cvsup11.FreeBSD.org

      Scroll down to “# ports-all” and uncomment the line so that we update our ports collections as well (more on this later).

    2. # cvsup -g -L 2 cvs-supfile (this process takes a while)
    3. # cd /usr/src
    4. # make -j4 buildworld (this step took even longer than cvsup)
    5. Build and install your kernel (yes, we could tweak the kernel, but that’s beyond the scope of this paper)
      1. # make buildkernel
      2. # make depend
      3. # make installkernel
      4. Reboot

      When the machine comes back up:

      # cd /usr/src

      # make installworld

      Now test to make sure our kernel and binaries are in sych:

      #top

      This should show a list of running processes. Hit the “Q” key to quit. If you get an error, your binaries and kernel are out of synch and you should start over.

      # mergemaster -a

  27. Now we’ll edit the login banner, the Message Of The Day (MOTD). You can use the following MOTD or you can write your own:

    # ee /etc/motd

    Use of this network is restricted to authorized users. User activity is monitored and recorded by system personnel. Anyone using this Network expressly consents to such monitoring and recording. BE ADVISED: if possible criminal activity is detected, system records, along with certain personal information, may be provided to law enforcement officials.

  28. Next we’ll secure SSH:

    # ee /etc/ssh/sshd_config

    We want to add the following:

    PermitRootLogin no

    AllowUsers userA userB userC

    Protocol 2

    LoginGraceTime 20s

    MaxStartups 5

    Banner /etc/ssh/sshd_banner

    Now we’ll create the SSH banner (you can use the banner above or create your own:

    # ee /etc/ssh/sshd_banner

    Enter your banner text and save and exit.

Application Installation

Now we have a solid base on which to start building. Next we’re going to start installing applications:

The first application we’ll install is portupgrade, which simplifies upgrading our ports.

Freebsddiary has a very good article about portupgrade.

Upgrading your ports can be a little confusing to someone who is new to FreeBSD (and in my case, to Unix in general). So here’s how it was explained to me by a good friend.

You use CVS to upgrade the available packages. CVS downloads the source for all the packages in /usr/ports, wether their installed or not, and doesn’t update what is installed. Portupgrade upgrades the installed ports. So our process for upgrading our installed ports is to first use CVS to download the most recent packages available, then we’ll use portupgrade to upgrade the installed ports from the updated packages. Make sense?

You’ll also remember that when we updated our main source tree above, we also updated our ports collections. Therefore we really don’t need to run CVS this time, but in the future, you’ll CVS-up then portupgrade.

  1. # cd /usr/ports/sysutils/portupgrade/
  2. # make install distclean

    Next we’ll back up the package database

  3. # cd /var/db
  4. # tar cvfz var.db.pkg.tgz pkg

    Now we’ll configure CVS to upgrade the available packages (this step only upgrades the available ports in /usr/ports. We aren’t upgrading the installed ports yet).

  5. # cd /usr/share/examples/cvsup
  6. As we did before, we need to choose a mirror physically close to us to download the ports. I use cvsup11.freebsd.org. So search for and change the following to the mirror nearest you:

  7. *default host=

    If you are bandwidth-challenged, you can comment out “ports-all” then scroll through the various collections and uncomment the collections you want. Keep in mind that you MUST uncomment “ports-base” if you do this.

    Once your ports-supfile is to your liking, update your ports:

  8. # cvsup -g -L 2 ports-supfile

    Once that completes, you need to make the index:

  9. #cd /usr/ports && make index

    Now that we have updated packages available we’ll continue installing ports. Also, since this is a fresh install, we won’t run portupgrade. But when we need to, the command is:

  10. # /usr/local/sbin/portupgrade -ra

On to the rest of the software:

  1. # cd /usr/ports/misc/screen/
  2. # make ; make install clean
  3. # cd ../../net/libnet
  4. # make ; make install clean
  5. # cd ../../security/snort
  6. # make -DWITH_MYSQL ; make install (don’t clean here, we need the “work” directory and clean deletes it)

    The following ports only need to be installed on the machine that will receive and display the alerts. So if you are building a sensor plus a machine to receive and display alerts, the ports below will be installed on the alert machine.

  7. # cd /usr/ports/www/apache13-modssl
  8. # make
  9. # make certificate

    Here you follow the directions to create a certificate for the server. At step 4, you have a choice of encrypting the private keys now. This is a good idea, but the only problem is every time you restart apache, it will ask for your passphrase to decrypt your private keys and I don’t know (yet) how to script that. So I have chosen not to encrypt my private keys yet.

    Once the certificate is created:

  10. # make install clean
  11. # /usr/local/etc/rc.d/apache.sh start

    This starts apache so that we can test it from another machine. Simply go to another machine, type the machines IP address in your browser and you should have success. Then type https:// and the machines IP and again, we should have success.

  12. # cd ../../graphics/jpgraph
  13. # make ; make install clean
  14. # cd ../../databases/adodb
  15. # make ; make install clean

    Choose “Apache2″

  16. # cd ../../security/acid
  17. # make ; make install clean
  18. # rehash

Application Configuration

Snort Configuration

  1. # cp /usr/local/etc/snort.conf-sample /usr/local/etc/snort.conf
  2. # chmod 644 /usr/local/etc/snort.conf
  3. # ee /usr/local/etc/snort.conf

    Scroll down to var HOME_NET any and replace any with the subnet of your internal subnet. Also, below that, add the following:

    var IDS X.X.X.X
    var ADMIN [X.X.X.X,X.X.X.X]

    In the above, replace the X.X.X.X with the appropriate IP addresses. Also, if you are listing more than one IP, you MUST include the [brackets] and no spaces between IP’s.

    Now, when writing custom rules, we can reference the above IP’s by their corresponding variable. (This will be more clear later, when we write a few basic rules)

  4. Now go to Section # 3 and uncomment and change output database: alert, mysql, user=[snortusername] password=[snortuserpass] dbname=snort host=localhost sensor_name=[Name_of_server]”.

    For sensor_name you should give it an intuitive name, because Acid will report this name. So for example, if you run multiple NIDS’s on a network, all reporting to the same SQL dbase, the sensor name will help you sort it out mentally.

    Also, there seems to be some confusion as to the difference between logging and alerting to the dbase. The following was posted to the Snort-users list on 2-26-2002 by Martin Roesch (Snort’s author):

    “…The “alert” action in Snort is hard coded to do two things when an event
    is detected by Snort, write an event to the alert facility and log as
    much as possible/desired to the output facility. The “log” action
    merely logs the current packet to the logging facility without
    generating an alert. This is done so you can log interesting things
    (telnet sessions, whatever) without having to generate an alert on every
    packet.

    The database plugin is something of an anomaly because it doesn’t
    separate the two functionalities very much. The “log” option attaches
    the log facility and the “alert” option attaches it to the alert
    facility. What this means in practical terms is that if the db plugin
    is in alert mode, it will only receive output from alert rules, whereas
    if it’s in “log” mode it will receive output from both log and alert
    rules.”

    Now this becomes relevant becuase if the above statment says: output database: log, portscans won’t be displayed properly in the Acid console. So if you would like to see portscans, change log to alert. Just keep in mind that when you are researching events of interest (EOI), there is more data in the /var/log/snort directory.

    References:

    1FreeBSD Unleashed” Michael Urban & Brian Tiemann, ISBN: 0672322064
    2FisherSolutions.com
    3FreeBSDDiary.org
    4“How to setup and Secure Snort, MySQL and Acid on FreeBSD 4.6 Release” PDF By Keith Tokash
    5FreeBSD Handbook
    6SecurityFocus.com Complete Snort-based IDS Architecture, Part One
    7Apache-server.com/
    8ACID: Installation and Configuration
    9Network Intrusion Detection Third Edition, Stephen Northcutt & Judy Novak, ISBN: 0735712654
    10[Snort-users] Listserv Archives