snort3 / libdaq

LibDAQ: The Data AcQuisition Library
Other
46 stars 39 forks source link

NFQ DAQ and unprivileged operation #11

Open amishmm opened 3 years ago

amishmm commented 3 years ago

I am trying to migrate Snort from 2.9.17 to 3.1.0.0

I run snort in inline mode with NFQ DAQ.

Till snort 2.9.17 snort used to work fine. But now that I am trying to run snort 3.1.0 it gives this error:

ERROR: Cannot drop privileges - at least one of the configured DAQ modules does not support unprivileged operation.

Looking at the NFQ module code I see that README file mentions this:

Last I checked, the process cannot operate in unprivileged mode. This needs to be revalidated, but the module is marked as such in the meantime.

I think this comment indeed needs a re-validation based on how it worked in snort 2.9.17 (atleast for me)?

There can be two things why it worked in snort 2.9.17

  1. Snort 2.9.17 first bound to NFQ before dropping privilege and hence it worked (Just my guess. Not sure if it is so)
  2. NFQ DAQ actually works even after dropping privilege. In that case marking it as DAQ_TYPE_NO_UNPRIV is incorrect and needs to be changed.

I do not know about DAQ, NFQ and internals. But I do request a review on setting DAQ NFQ module as DAQ_TYPE_NO_UNPRIV

I use Arch Linux and I run snort 3 using this: snort -Q -u snort -g snort -c /etc/snort/snort.lua -l /var/log/snort --tweaks local

DeepFusion commented 3 months ago

Did you get any luck in running libdaq in reduced privileges? As far as I have tries all kind of setup scenarios, it does not work for me. The only setup that works for me is to run snort3 in such configuration:

To disable promiscuity and disable GRO/LRO

[Unit]
Description=Set Snort 3 NIC in promiscuous mode and Disable GRO, LRO on boot
After=network.target

[Service]
Type=oneshot
ExecStart=/usr/sbin/ip link set dev ${default_interface} promisc off
ExecStart=/usr/sbin/ethtool -K ${default_interface} gro off lro off
TimeoutStartSec=0
RemainAfterExit=yes

[Install]
WantedBy=default.target

Snort NIPS service file

[Unit]
Description=Snort NIPS Daemon
After=syslog.target network.target

[Service]
Type=simple
User=root
Group=snort
ProtectHome=true
ProtectKernelTunables=true
ProtectKernelModules=true
ProtectControlGroups=true
CapabilityBoundingSet=CAP_NET_RAW CAP_NET_ADMIN
ExecStart=/usr/local/bin/snort -c /etc/snort/snort.lua -s 65535 -k none -l /var/log/snort -D -m 0x1b --create-pidfile --plugin-path /etc/snort/so_rules/
#Tried these various options: --daq-dir /usr/local/lib/snort/daq/ --daq nfq --daq-var queue=0 --daq-var uid=998 -m 0x1b -u snort -g snort --create-pidfile --plugin-path /etc/snort/so_rules/
ExecStop=/bin/kill -9
Restart=on-failure
RestartSec=120s
AppArmorProfile=/usr/local/bin/snort

[Install]
WantedBy=multi-user.target

Snippet of snort3 configuration file

ips =
{
    mode = inline,
    enable_builtin_rules = true,
    include = "/etc/snort/rules/pulledpork.rules",
    variables = default_variables,
    action_override = 'block'
}
alert_json = {
        file = true,
        limit = 1000,
        fields = 'seconds action class b64_data dir dst_addr dst_ap dst_port eth_dst eth_len \
        eth_src eth_type gid icmp_code icmp_id icmp_seq icmp_type iface ip_id ip_len msg mpls \
        pkt_gen pkt_len pkt_num priority proto rev rule service sid src_addr src_ap src_port \
        target tcp_ack tcp_flags tcp_len tcp_seq tcp_win tos ttl udp_len vlan timestamp',
}
daq = {
    module_dirs = {'/usr/local/lib/snort/daq'},
    inputs = { '0' },
    modules = {
        {
            name = 'nfq',
            mode = 'inline',
            variables = { 'queue_maxlen=8192', 'fail_open', 'queue=0', 'device=${default_interface}' }
        }
    }
}

IPTABLES rule

iptables -I INPUT -i "${default_interface}" -j NFQUEUE --queue-num 0 --queue-bypass

Apparmor profile for snor3

include <tunables/global>

/usr/local/bin/snort {
  include <abstractions/base>
  include <abstractions/nameservice>

  capability net_admin,
  capability net_raw,

  network inet,
  network inet6,

  deny @{PROC}/@{pid}/cmdline r,
  deny @{PROC}/@{pid}/environ r,
  deny @{PROC}/@{pid}/fd/** rw,
  deny @{PROC}/@{pid}/fdinfo/** rw,
  deny @{PROC}/@{pid}/io rw,
  deny @{PROC}/@{pid}/stat rw,
  deny @{PROC}/@{pid}/statm rw,
  deny @{PROC}/@{pid}/status rw,

  /bin/kill rix,
  /bin/sh rix,
  /dev/null rw,
  /dev/urandom rw,
  /etc/** mr,
  /etc/snort/** r,
  /home/** mr,
  /lib/** r,
  /lib64/** r,
  /proc/** r,
  /sys/** r,
  /usr/** mr,
  /usr/local/bin/snort r,
  /usr/local/lib/snort/ r,
  /var/** mr,
  /var/log/snort/** rw,
  owner /var/** mrwk,

}

It works like this in IPS mode, and successfully drops offending packes, but I am not sure if this is a secure option to run snort3 as root. Anyone, comments are more than welcome.