Compile Suricata v5.0.3 with PF_RING v7.6.0 on Ubuntu 20.04

While working on my TOR relay project I was trying to compile Suricata with pf_ring but couldn’t find any documentation for the latest releases. This blog post will provide instructions to compile the latest stable version of Suricata and pf_ring. In addition, this blog post contains instructions for the infrastructure-as-code written in Ansible to automate the installation and step-by-step instructions for a manual installation.

Background

What is PF_RING?

PF_RING is a high speed packet capture library that turns a commodity PC into an efficient and cheap network measurement box suitable for both packet and active traffic analysis and manipulation.

What is Suricata

Suricata is an open source network threat detection engine that provides capabilities including intrusion detection (IDS), intrusion prevention (IPS) and network security monitoring. It does extremely well with deep packet inspection and pattern matching which makes it incredibly useful for threat and attack detection.

Automate compiling Suricata and PF_RING with Ansible

  1. git clone https://github.com/CptOfEvilMinions/BlogProjects.git
  2. cd BlogProjects/suricatav5-pf_ring
  3. vim hosts.ini
    1. Replace 172.16.125.130 with the IP address of the host to run this playbook on
    2. Save and exit
  4. vim groups_vars/all.yml
    1. Replace ens33 for monitoring_interface with the interface you want Suricata to monitor
    2. Save and exit
  5. ansible-playbook -i hosts.ini deploy_suricata_pf_ring.yml -u <user with admin perms> -K
    1. Enter a password for user

Manually compile Suricata and PF_RING

Update kernel and freeze it

  1. apt update -y && apt upgrade -y && apt dist-upgrade -y && apt autoremove -y
    1. Update system and kernel
    2. Install Linux kernel headers
  2. REBOOT
  3. apt install linux-headers-$(uname -r)
  4. apt --purge autoremove
  5. apt-mark hold linux-image-generic linux-headers-generic
    1. DISABLING kernel updates
    2. Because we compiled PFRing in this kernel, any kernel builds may cause the PFRing module to fail to load.  You will need to recompile PFRing if you update your kernel after compiling.

Compile and install PF_RING v7.6.0

  1. apt install wget cmake make gcc g++ flex git bison libpcap-dev libssl-dev python3-dev swig zlib1g-dev libgeoip-dev build-essential libelf-dev pkg-config -y
    1. Install dependencies
  2. cd /tmp && wget https://github.com/ntop/PF_RING/archive/7.6.0.tar.gz
    1. Download PF_RING
  3. tar -xvzf 7.6.0.tar.gz
  4. mv PF_RING-7.6.0 /opt/pf_ring && rm /tmp/7.6.0.tar.gz
  5. Kernel module
    1. cd /opt/pf_ring/kernel
    2. make
      1. Make pf_ring kernel module
    3. make install
      1. Install kernel module
    4. insmod ./pf_ring.ko
      1. Load kernel module
  6. Libpf_ring
    1. cd ../userland/lib
    2. ./configure
    3. make
    4. make install
  7. Libpcap
    1. cd ../../userland/libpcap
    2. ./configure
    3. make
    4. make install
  8. cp /opt/pf_ring/package/usr/local/bin/pf_ringctl /usr/local/bin/pf_ringctl
    1. Copy pf_ringctl to an executable path
  9. cp /opt/pf_ring/package/etc/systemd/system/pf_ring.service /etc/systemd/system/pf_ring.service
  10. systemctl daemon-reload
  11. systemctl enable pf_ring
  12. systemctl start pf_ring
  13. systemctl status pf_ring

Compile and install Suricata v5.0.3

  1. apt install libpcre3 libpcre3-dbg libpcre3-dev build-essential libpcap-dev libnet1-dev libyaml-0-2 libyaml-dev pkg-config zlib1g zlib1g-dev libcap-ng-dev libcap-ng0 make libmagic-dev libjansson-dev libnss3-dev libgeoip-dev liblua5.1-dev libhiredis-dev libevent-dev python-yaml rustc cargo liblz4-dev -y
    1. Install dependencies
  2. cd /tmp && wget https://www.openinfosecfoundation.org/download/suricata-5.0.3.tar.gz
    1. Download Suricata
  3. tar -xvzf suricata-5.0.3.tar.gz
  4. cd /tmp/suricata-5.0.3
  5. LIBS="-lrt" ./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var --enable-pfring --with-libpfring-includes=/usr/local/include --with-libpfring-libraries=/usr/local/lib
  6. make
  7. make install
  8. make install-conf
    1. Creates a log directory (/var/log/suricata), config directory (/etc/suricata), and a rules directory (/var/lib/suricata)
  9. Suricata.yaml
    1. cp /etc/suricata/suricata.yaml /etc/suricata/suricata.yaml.bak
      1. Create a backup of Suricata config
    2. chmod 400 /etc/suricata/suricata.yaml.bak
    3. wget https://raw.githubusercontent.com/CptOfEvilMinions/BlogProjects/master/suricatav5-pf_ring/conf/suricata/suricata.yaml -O /etc/suricata/suricata.yaml
      1. Download Suricata main config
    4. sed -i 's/{{ monitoring_interface }}/<monitor interface>/g' /etc/suricata/suricata.yaml
      1. Replace “{{ monitoring_interface }}” with the network interface you want to monitor
  10. Create a system user for Suricata
    1. adduser --disabled-login --shell /bin/false --system --home /nonexistent --no-create-home --ingroup root suricata
    2. chown -R suricata:root /var/log/suricata
  11. Suricata defaults
    1. wget https://raw.githubusercontent.com/CptOfEvilMinions/BlogProjects/master/suricatav5-pf_ring/conf/suricata/default_suricata_pf-ring -O /etc/default/suricata
      1. Specifies the default settings to run Suricata
  12. Suricata service script
    1. wget https://raw.githubusercontent.com/CptOfEvilMinions/BlogProjects/master/suricatav5-pf_ring/conf/suricata/suricata-pf_ring-init.sh -O /etc/init.d/suricata
    2. chmod +x /etc/init.d/suricata
    3. /etc/init.d/suricata start
    4. systemctl enable suricata
    5. systemctl restart suricata

Setup Suricata-update for rules

  1. mkdir /etc/suricata/rules
    1. Make a directory for local rules
  2. Disable rules
    1. touch /etc/suricata/rules/disable.conf
    2. Place any rules you want to disable in this config
    3. Here for more information
  3. Custom rules
    1. touch /etc/suricata/rules/local.rules
    2. Place any custom rules you want in this config
  4. wget https://raw.githubusercontent.com/CptOfEvilMinions/BlogProjects/master/suricatav5-pf_ring/conf/suricata/suricata_update.yaml -O /etc/suricata/update.yaml
  5. sed -i 's#{{ suricata_rules_dir }}#/etc/suricata/rules#g' /etc/suricata/update.yaml
    1. Set the location of the Suricata custom rules directory
  6. suricata-update
    1. Init rules directory
  7. suricata-update update-sources
  8. suricata-update list-sources
  9. suricata-update enable-source <source>
    1. Open source sources to enable
      1. et/open – Emerging Threats Open Ruleset
      2. oisf/trafficid – Suricata Traffic ID ruleset
      3. ptresearch/attackdetection – Positive Technologies Attack Detection Team ruleset
      4. sslbl/ssl-fp-blacklist – Abuse.ch SSL Blacklist
      5. sslbl/ja3-fingerprints – Abuse.ch Suricata JA3 Fingerprint Ruleset
      6. etnetera/aggressive – Etnetera aggressive IP blacklist
      7. tgreen/hunting – Threat hunting rules
  10. suricata-update
  11. systemctl restart suricata

Testing Suricata

Ping test

  1. echo 'alert icmp any any -> any any (msg:"PING detected"; sid:2; rev:1;)' >> /etc/suricata/rules/local.rules
  2. suricata-update
    1. We can see one new rule was added since the last update
  3. systemctl restart suricata
  4. ping -c 4 8.8.8.8
  5. cat /var/log/suricata/eve.json | grep 'event_type":"alert"'

Lessons learned

I am currently reading a book called “Cracking the Coding Interview” and it is a great book. One interesting part of the book is their matrix to describe projects you worked on and the matrix contains the following sections which are: challenges, mistakes/failures, enjoyed, leadership, conflicts, and what would you do differently. I am going to try and use this model at the end of my blog posts to summarize and reflect on the things I learn. I don’t blog to post things that I know, I blog to learn new things and to share the knowledge of my security research.

New skills/knowledge

  • Compile Suricata v5.0.3 with pf_ring v7.6
  • Suricata rule making
  • How to configure suricata-update
  • Learned how to use “{% raw %}” for Ansible templates

Challenges

  • The default service init.d script doesn’t support PF_RING.  I had to modify the original init.d script to include support for PF_RING.
  • The only official guide to compile Suricata with PF_RING is from the Ubuntu 12.04 era.
  • Ansible kept interpreting the %d in the Suricata.yaml config when it should have treated it as a string

What You’d Do Differently

  • I wasn’t able to get PF_RING flow tables working to filter out traffic like Netflix and Youtube.

References

Leave a Reply

Your email address will not be published. Required fields are marked *