首页 > 技术文章 > Snort3安装和配置

thresh 2021-06-29 12:02 原文

Snort3安装和配置

介绍

之前安装和配置过Snort2,但Snort2与3有较多不同,这里通过参考snort3安装文档完成snort3的配置。本指南展示了如何使用Splunk将Snort3设置为完整的网络入侵检测系统(NIDS)和安全信息以及Ubuntu上的事件管理(SIEM)系统。本指南的目的是介绍启动基于Snort和Splunk的NIDS和SIEM,以便可以修改Snort和Splunk以满足特定需求。
关于Snort3:Snort 3是基于规则的网络入侵检测和预防软件(NIDS/NIPS)。
关于Splunk:Splunk是一个安全信息和事件管理(SIEM)系统,它收集、存储并允许轻松地进行分析以及可视化数据,包括Snort创建的警报。
关于PulledPork:PulledPork用于下载和合并规则集(Snort用于匹配的签名集合)恶意交易)。
关于OpenAppID:Snort OpenAppID允许Snort识别、控制和测量网络上正在使用的应用程序。开放应用程序ID由一组匹配特定类型网络数据的包(签名)组成,包括第7层应用程序,如Facebook、DNS、netflix、discus和google,以及使用这些服务的应用程序(chrome、http、https等)。
软件要求:本指南已经在64位LTS版本的Ubuntu 18.04中测试成功

安装Snort

首先,确保系统是最新的,并且具有最新的程序包列表:

sudo apt-get update && sudo apt-get dist-upgrade -y

确保系统具有正确的时间和时区。当我们稍后开始处理警报时,这对Splunk非常重要。下面的命令将允许选择时区:

sudo dpkg-reconfigure tzdata

下载一些源tarball和其他文件,我们希望将它们存储在一个文件夹中:

mkdir ~/snort_src
cd ~/snort_src

安装Snort 3必备组件

sudo apt-get install -y build-essential autotools-dev libdumbnet-dev libluajit-5.1-dev libpcap-dev zlib1g-dev pkg-config libhwloc-dev cmake liblzma-dev openssl libssl-dev cpputest libsqlite3-dev libtool uuid-dev git autoconf bison flex libcmocka-dev libnetfilter-queue-dev libunwind-dev libmnl-dev ethtool

下载并安装safec,以便对某些旧式C库调用进行运行时边界检查

cd ~/snort_src
wget https://github.com/rurban/safeclib/releases/download/v02092020/libsafec-02092020.tar.gz
tar -xzvf libsafec-02092020.tar.gz
cd libsafec-02092020.0-g6d921f
./configure
make
sudo make install

Snort 3使用Hyperscan进行快速模式匹配。可以从Ubuntu存储库安装一个旧版本的Hyperscan,但是

Hyperscan对Snort的操作和性能至关重要,最好编译Hyperscan的最新稳定版本。Hyperscan有一个

需求数量,包括PCRE、gper工具、ragel和Boost库。

首先安装PCRE:Perl兼容的正则表达式。不使用Ubuntu存储库,因为它有一个旧版本:

cd ~/snort_src/
wget https://ftp.pcre.org/pub/pcre/pcre-8.44.tar.gz
tar -xzvf pcre-8.44.tar.gz
cd pcre-8.44
./configure
make
sudo make install

下载和安装 gpertools 2.8:

cd ~/snort_src
wget https://github.com/gperftools/gperftools/releases/download/gperftools-2.8/gperftools-2.8.tar.gz
tar -xzvf gperftools-2.8.tar.gz
cd gperftools-2.8
./configure
make
sudo make install

下载和安装 Ragel:

cd ~/snort_src
wget http://www.colm.net/files/ragel/ragel-6.10.tar.gz
tar -xzvf ragel-6.10.tar.gz
cd ragel-6.10
./configure
make
sudo make install

最后,下载(但不要安装)Boost C++库:

cd ~/snort_src
wget https://boostorg.jfrog.io/artifactory/main/release/1.74.0/source/boost_1_74_0.tar.gz
tar -xvzf boost_1_74_0.tar.gz

从源代码处安装Hyperscan 5.3,参考Boost源目录的位置:

cd ~/snort_src
wget https://github.com/intel/hyperscan/archive/v5.3.0.tar.gz
tar -xvzf v5.3.0.tar.gz
mkdir ~/snort_src/hyperscan-5.3.0-build
cd hyperscan-5.3.0-build/
cmake -DCMAKE_INSTALL_PREFIX=/usr/local -DBOOST_ROOT=~/snort_src/boost_1_74_0/ ../hyperscan-5.3.0
make
sudo make install

安装flatbuffers:

cd ~/snort_src
wget https://github.com/google/flatbuffers/archive/v1.12.0.tar.gz -O flatbuffers-v1.12.0.tar.gz
tar -xzvf flatbuffers-v1.12.0.tar.gz
mkdir flatbuffers-build
cd flatbuffers-build
cmake ../flatbuffers-1.12.0
make
sudo make install

接下来,从Snort网站下载并安装数据采集库(DAQ)。请注意,Snort3使用的数据采集卡与Snort 2.9.0系列不同。在Snort网站上查看libdaq的更新版本,以防在编写本指南后发布了更新的版本,或者出现丢失此文件的错误

cd ~/snort_src
###wget https://www.snort.org/downloads/snortplus/libdaq-3.0.0.tar.gz
wget https://github.com/snort3/libdaq/archive/refs/tags/v3.0.3.tar.gz
tar -xzvf libdaq-3.0.0.tar.gz
cd libdaq-3.0.0
./bootstrap
./configure
make
sudo make install

更新共享库:

sudo ldconfig

现在可以从github存储库下载、编译和安装Snort3了。如果对启用其他编译时功能感兴趣,例如处理大型(超过2GB)PCAP文件的能力,或者新的命令行shell:运行./configure cmake.sh--帮助列出所有可选功能,并将它们附加到下面的./configure\u cmake.sh命令中。在Snort网站上查看Snort3的更新版本。

下载并安装,默认设置为:

cd ~/snort_src
###wget https://www.snort.org/downloads/snortplus/snort3-3.1.0.0.tar.gz
wget https://github.com/snort3/snort3/archive/refs/tags/3.1.5.0.tar.gz
tar -xzvf snort3-3.1.0.0.tar.gz
cd snort3-3.1.0.0
./configure_cmake.sh --prefix=/usr/local --enable-tcmalloc
cd build
make
sudo make install

Snort现在应该安装在/usr/local/下。最后,验证Snort是否正确运行。为此,我们向snort可执行文件传递-V标志

(版本为大写V):

/usr/local/bin/snort -V

可以看到类似于以下内容的输出:

/usr/local/bin/snort -V
    ,,_ -*> Snort++ <*-
    o" )~ Version 3.1.0.0
    '''' By Martin Roesch & The Snort Team
    http://snort.org/contact#team
    Copyright (C) 2014-2020 Cisco and/or its affiliates. All rights reserved.
    Copyright (C) 1998-2013 Sourcefire, Inc., et al.
    Using DAQ version 3.0.0
    Using LuaJIT version 2.1.0-beta3
    Using OpenSSL 1.1.1f 31 Mar 2020
    Using libpcap version 1.9.1 (with TPACKET_V3)
    Using PCRE version 8.44 2020-02-12
    Using ZLIB version 1.2.11
    Using FlatBuffers 1.12.0
    Using Hyperscan version 5.3.0 2021-01-19
    Using LZMA version 5.2.4

如果输出与上述类似,Snort已安装并工作。

现在让我们用默认配置文件测试Snort:

snort -c /usr/local/etc/snort/snort.lua

内容结束的输出:

Snort successfully validated the configuration (with 0 warnings).
o")~ Snort exiting

配置网卡

现代网卡使用卸载(例如LRO)来处理硬件中的网络数据包重新组装,而不是在软件中。对于大多数情况,这是首选,因为它减少了系统的负载。对于NIDS,禁用LRO和GRO,因为这会截断更长的数据包(更多信息请参阅Snort2手册)

我们需要创建一个systemD服务来更改这些设置。首先使用ifconfig确定snort要监听的接口的名称,如果在ubuntu20上,则使用newip address show命令。

知道Snort将监听的网络接口的名称:检查这些接口的large-receive-o  load(LRO)和generic-receive-offload(GRO)的状态。在下面的示例中,我的接口名是ens3(根据系统类型,通常也会将eth0或ens160视为接口名)。使用ethtool检查状态:

sudo ethtool -k ens3 | grep receive-offload
    generic-receive-offload: on
    large-receive-offload: off [fixed]

从这个输出中,可以看到GRO被启用,而LRO被禁用(“fixed”表示不能更改)。需要确保两者都设置为“off”(或“off[fixed]”)。可以使用ethtool命令来禁用LRO和GRO,但是该设置不会在重新启动时保持不变。解决方案是创建一个systemD脚本,以便在每次系统启动时设置它。

创建systemD脚本:

sudo vi /lib/systemd/system/ethtool.service
	##内容,输入以下信息,用接口名称替换ens3:
	[Unit]
    Description=Ethtool Configration for Network Interface
    [Service]
    Requires=network.target
    Type=oneshot
    ExecStart=/sbin/ethtool -K ens3 gro off
    ExecStart=/sbin/ethtool -K ens3 lro off
    [Install]
    WantedBy=multi-user.target

创建文件后,启用并启动服务:

sudo systemctl enable ethtool
sudo service ethtool start

这些设置现在将在重新启动时保持不变。可以如上所述使用ethtool验证设置。

配置Snort规则集

创建一些Snort规则所需的文件夹和文件:

sudo mkdir /usr/local/etc/rules
sudo mkdir /usr/local/etc/so_rules/
sudo mkdir /usr/local/etc/lists/
sudo touch /usr/local/etc/rules/snort.rules
sudo touch /usr/local/etc/rules/local.rules
sudo touch /usr/local/etc/lists/default.blocklist
sudo mkdir /var/log/snort

将在上面创建的local.rules文件中创建一个规则:

sudo vi /usr/local/etc/rules/local.rules

此规则将检测ICMP事务,对于测试Snort是否正常工作和生成警报非常有用。将以下行粘贴到local.rules文件中(确保准确复制这行,必须在该文件中的每个分号中有一个空格aଌ才能正确解析警报):

alert icmp any any -> any any ( msg:"ICMP Traffic Detected"; sid:10000001; metadata:policy security-ips alert; )

现在运行Snort并让它加载local.rules文件(带有-R标志),以确保正确加载这些规则(验证规则的格式是否正确):

snort -c /usr/local/etc/snort/snort.lua -R /usr/local/etc/rules/local.rules

输出应以“Snort成功验证配置”结束。不应该有任何警告或错误。如果在输出中向上滚动,会看到这个规则加载成功(在rule counts部分下)。

现在,在接口上以检测模式运行Snort(将下面的eth0更改为与的接口名称匹配),并将所有警报打印到控制台:

sudo snort -c /usr/local/etc/snort/snort.lua -R /usr/local/etc/rules/local.rules \
-i eth0 -A alert_fast -s 65535 -k none

我们在这里使用的标志是:

Flag 描述
-c /usr/local/etc/snort/snort.lua snort.lua配置文件
R /usr/local/etc/rules/local.rules 包含一个ICMP规则的规则文件的路径。
-i eth0 要监听的接口
-A alert_fast 使用alert_fast快速输出插件将警报写入控制台。
-s 65535 设置snaplen,使Snort不会截断和丢弃过大的数据包
-k none 忽略错误的校验和,否则snort将丢弃具有错误校验和的数据包

Snort将加载配置,然后显示:

Commencing packet processing
++ [0] eth0

这意味着snort当前正在侦听该接口上的所有流量,并将其与加载的规则进行比较。当流量与规则匹配时,Snort将向控制台写入警报。现在,从该计算机上的另一个窗口(打开一个新的终端窗口或第二个ssh会话),使用ping命令生成穿过正在侦听的接口的数据包(如果从另一台计算机连接,则ping到该接口的IP地址;如果在同一台计算机上,则只ping外部IP地址)。看到屏幕上打印的警报:

###警报信息
1 2 / 15 −2 1: 0 2: 2 6. 97 6 073 [ * * ] [ 1 : 1 0 0 0 0 0 0 1 : 0 ] " ICMP T r a f f i c De tec te d " [ * * ] [ P r i o r i t y : 0 ] { ICMP } 1 0 . 1 0 . 1 0 . 1 −> 1 0 . 1 0 . 1 0 . 8 8
1 2 / 15 −2 1: 0 2: 2 6. 9 7 6 15 7 [ * * ] [ 1 : 1 0 0 0 0 0 0 1 : 0 ] " ICMP T r a f f i c De tec te d " [ * * ] [ P r i o r i t y : 0 ] { ICMP } 1 0 . 1 0 . 1 0 . 8 8 −> 1 0 . 1 0 . 1 0 . 1

使用ctrl-c停止Snort。这是测试Snort的一个很好的规则,但是在实际的生产使用过程中可能会有点嘈杂,所以如果愿意的话,可以用hash符号来注释它。

接下来,让我们编辑snort.lua文件。此文件是我们在启动时传递给Snort的配置文件:

sudo vi /usr/local/etc/snort/snort.lua

接下来,我们要启用解码器和检查器警报(Snort检测到的恶意流量,而不是规则,因为格式更复杂),并且我们要告诉ips模块规则文件的位置(PulledPork稍后将为我们创建此文件)

向下滚动到第169行,并查找标题为ips的部分。在这里,我们从enable_builtin_rules=true中取消注释(删除前面的两个破折号),并启用pulledpork规则。请注意,lua使用四个空格,而不是制表符来缩进这些行(这是必需的)。此部分应如下所示(删除注释,166行左右):

ips =
{
    enable_builtin_rules = true,
    include = RULE_PATH .. "/local.rules",
    variables = default_variables
 }

测试配置文件(因为我们已经做了更改):

snort -c /usr/local/etc/snort/snort.lua

现在可以如上所述运行snort,但是不会在命令行上明确地传递local.rules文件,因为已经将它包含在snort.lua文件的ips部分中:

sudo snort -c /usr/local/etc/snort/snort.lua -i eth0 -A alert_fast -s 65535 -k none

按上述方式Ping接口,会再次看到写入控制台的警报

PulledPork

PulledWork是我们用来下载和合并Snort规则集的脚本。要从Snort下载主要的免费规则集,需要一个oinkcode。在Snort网站上注册并在继续之前保存的oinkcode,因为最流行的免费规则集需要oinkcode。

安装PulledWork先决条件:

sudo apt-get install -y libcrypt-ssleay-perl liblwp-useragent-determined-perl

接下来,下载PulledPork的最新版本,并通过将perl文件复制到/usr/local/bin和所需的配置文件复制到/usr/local/etc/PulledPork来安装它:

cd ~/snort_src
wget https://github.com/shirkdog/pulledpork/archive/master.tar.gz -O pulledpork-master.tar.gz
tar xzvf pulledpork-master.tar.gz
cd pulledpork-master/
sudo cp pulledpork.pl /usr/local/bin
sudo chmod +x /usr/local/bin/pulledpork.pl
sudo mkdir /usr/local/etc/pulledpork
sudo cp etc/*.conf /usr/local/etc/pulledpork

测试PulledPork是否运行,方法是使用-V标志运行它,如下所示,查找以下输出:

/usr/local/bin/pulledpork.pl -V
    PulledPork v0.8.0 - The only positive thing to come out of 2020...well this and take-out liquor!

现在我们确定PulledWork已运行,我们需要对其进行配置:

sudo vi /usr/local/etc/pulledpork/pulledpork.conf

第19行,需要更改URL,然后用在snort.com网站注册时获得的oinkcode替换。这将告诉PulledPork从何处下载规则。

rule_url=https://www.snort.org/rules/|snortrules-snapshot.tar.gz|<oinkcode>

第21行:评出社区规则。这些不需要,因为它们包含在我们上面包含的注册规则集中:

#rule_url=https://snort.org/downloads/community/|community-rules.tar.gz|Community

第72行:需要指向正确的snort.rules文件,PulledWork将保存从local.rules文件下载并包含的所有规则:

rule_path=/usr/local/etc/rules/snort.rules

第87行:需要告诉PulledPork local.rules文件从何处复制规则(并复制到snort.rules中):

local_rules=/usr/local/etc/rules/local.rules

第94行:这告诉PulledPork以较新的sid_msg格式输出有关规则的元数据:

sid_msg_version=2

第110行:告诉PulledPork在哪里保存已编译的规则:

sorule_path=/usr/local/etc/so_rules/

第134行,将发行版改为Ubuntu-18-4(即使你运行的是ubuntu20)。这将告诉PulledWork哪个版本的编译规则与我们的系统兼容:

distro=Ubuntu-18-4

第142行:这告诉PulledPork在何处保存阻止列表(已知的恶意IP地址,应该被阻止):

block_list=/usr/local/etc/lists/default.blocklist

第151行:告诉PulledPork块和允许列表的默认位置

IPRVersion=/usr/local/etc/lists

第186行:告诉PulledPork Snort守护进程将当前运行的PID保存在何处,以便PulledPork在安装新规则后可以向Snort发送消息,以便Snort加载新规则:

pid_path=/var/log/snort/snort.pid

第209行:取消对此行的注释以启用下载的规则文件中的所有规则。这些规则被分为不同的规则集,这取决于想要检测trafic的攻击性。如果在IPS模式下运行(阻止而不是检测传输),可能会考虑使用“ballanted”规则集而不是“security”,因为“security”规则集在检测可能是恶意的或可能是正常的流量方面更具攻击性:

ips_policy=security

运行PulledPork,将配置文件传递给它并执行额外的日志记录。这将下载最新的规则集,将它们与local.rules文件中的任何规则合并,并将所有规则保存到snort.rules中,同时将黑名单条目保存在defautl.blocklist文件中:

sudo /usr/local/bin/pulledpork.pl -c /usr/local/etc/pulledpork/pulledpork.conf -l -P -E -H SIGHUP

使用以下标志:

Flag 描述
-c /usr/local/etc/pulledpork/pulledpork.conf PulledWork配置文件
-l 将重要信息记录到syslog
-P 即使未下载新规则,也处理规则
-E 仅允许写入排除
H SIGHUP 通过传递SIGHUP信号使Snort重新加载配置

输出结果如下:

Rule Stats...
New:-------15047
Deleted:---0
Enabled Rules:----15048
Dropped Rules:----0
Disabled Rules:---0
Total Rules:------15048
IP Blocklist Stats...
Total IPs:-----760
Done
Please review /var/log/sid_changes.log for additional details
Fly Piggy Fly!

如果可以,下一步是将此命令转换为计划任务,以便我们可以每天更新规则集:

sudo crontab -e

Snort团队要求在PulledPork连接到他们的服务器时随机化,以帮助实现负载平衡。在下面的例子中,我们每天13:44检查PulledWork。将分钟值(下面的44)更改为0到59之间的值,将小时值(下面的13)更改为00到23之间的值:

44 13 * * * /usr/local/bin/pulledpork.pl -c /usr/local/etc/pulledpork/pulledpork.conf -l -P -E -H SIGHUP

检查snort.rules文件,应该会看到一些新的规则。
修改snort.lua以加载snort.rules而不是local.rules文件(local.rules中的规则通过PulledPork自动添加到snort.rules文件中,并与所有下载的规则一起使用,可以在snort.rules文件的末尾看到local.rules中的任何规则):

#167行
ips =
{
    enable_builtin_rules = true,
    include = RULE_PATH .. "/snort.rules",
    variables = default_variables
}

测试Snort以查看这些规则是否正确加载:

snort -c /usr/local/etc/snort/snort.lua

向上滚动,将看到如下内容:

rule counts
total rules loaded: 15573
text rules: 15048
builtin rules: 525
option chains: 15573
chain headers: 330

配置Snort插件

我们希望在snort.lua文件中启用一些功能:

sudo vi /usr/local/etc/snort/snort.lua

首先,让我们配置HOME\u NET变量。这是指我们正在防御的本地子网(规则使用此信息来确定警报是否匹配)。在此处设置本地子网信息以匹配子网。我下面的子网是带有24位子网掩码的10.0.0.0网络:

24	HOME_NET = '10.0.0.0/24'

启用hyperscan(更快的模式匹配):更多信息,请将其放在重新命名检查器之后,但在第3节:配置绑定之前:

104 search_engine = { search_method = "hyperscan" }
105
106 detection = {
107 hyperscan_literals = true,
108 pcre_to_regex = true
109 }

启用信誉阻止列表。从reputationinspector中删除注释(整个声誉块周围的块注释),并启用黑名单(从“黑名单**行”前面删除两个破折号):

96 reputation=
97 {
98 blacklist = BLACK_LIST_PATH .. "/default.blocklist"
99 --whitelist = 'whitelist file name with ip lists'
100 }

既然已经进行了更改,再次验证配置:

snort -c /usr/local/etc/snort/snort.lua

JSON警报输出插件

为了方便地将Snort 3警报日志文件导入到选择的SIEM中(如Splunk),需要使用alert\u json输出插件将所有警报写入json格式的文本文件。启用json输出插件很简单,只需修改snort.lua文件(在第7节:配置输出中,大约230行):

sudo vi /usr/local/etc/snort/snort.lua

首先,如下所示启用alert_json插件。记住,缩进使用4个空格而不是制表符

alert_json =
{
    file = true,
    limit = 100,
    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',

}

在alert_json插件中,我们指定了三个选项:

1.首先,我们使用file选项将警报输出到json格式的文件(而不是控制台)。

2.接下来,我们指定limit选项来告诉Snort何时滚动到新文件。当输出文件达到10 MB时,将使用文件名中的当前unixtime创建一个新文件。对于测试,我们将其设置为100MB,但是在生产系统上,可能希望增加这个数字,这取决于如何进行日志管理/轮换。

3.最后,我们指定fields选项,该选项标识json输出中应该包含警报中的哪些特定字段。在这个例子中,我们选择了所有可能的字段作为输出。

注意:在测试之后,可以选择删除其中的一些字段(vlan和mpls字段是不必要的,b64_data包含整个数据包负载,可以删除这些数据包负载以节省空间,尽管此字段中有很多好的信息)。不要删除“秒”字段,并确保它始终是列出的第一个字段。这将允许Splunk正确处理事件。

现在我们要运行Snort,并生成一些警报。这些警报将写入/var/log/snort。运行下面的命令,然后再次ping接口(就像我们以前所做的那样,生成与local.rules文件中的规则匹配的流量):

sudo /usr/local/bin/snort -c /usr/local/etc/snort/snort.lua -s 65535 \
-k none -l /var/log/snort -i ens33 -m 0x1b

我们为此命令添加了几个新标志:

Flag 描述
-l var/log/snort 应该写入日志文件的目录
-m 0x1b 033文件权限的Umask(rw-r–r–)

在snort启动后,将不会看到任何输出到屏幕上,因为我们已经启用了alert_json输出模块(该模块按照上面命令中的指定写入/var/log/snort)。停止snort(ctrl-c),然后检查/var/log/snort

cat /var/log/snort/alert_json.txt

在文件中看到JSON格式的警报数据:

{ "seconds" : 1608147213, "action" : "allow", "class" : "none", "b64_data" : "
DWHaXwAAAADO0wgAAAAAABAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc=", "dir" : "S2C", "
dst_addr" : "10.10.10.1", "dst_ap" : "10.10.10.1:0", "eth_dst" : "52:54:00:1F:8A:1C", "eth_len" :
98, "eth_src" : "52:54:00:70:78:9F", "eth_type" : "0x800", "gid" : 1, "icmp_code" : 0, "icmp_id" :
5203, "icmp_seq" : 3, "icmp_type" : 0, "iface" : "ens3", "ip_id" : 3006, "ip_len" : 64, "msg" : "
ICMP Traffic Detected", "mpls" : 0, "pkt_gen" : "raw", "pkt_len" : 84, "pkt_num" : 8, "priority" :
0, "proto" : "ICMP", "rev" : 0, "rule" : "1:10000001:0", "service" : "unknown", "sid" : 10000001, "
src_addr" : "10.10.10.88", "src_ap" : "10.10.10.88:0", "tos" : 0, "ttl" : 64, "vlan" : 0, "
timestamp" : "12/16-20:33:33.603502" }

Snort启动脚本

我们创建一个systemD脚本,以便在启动时自动运行snort。出于安全原因,我们还将让snort作为常规(非root)用户在启动时运行。首先创建snort用户和组:

sudo groupadd snort
sudo useradd snort -r -s /sbin/nologin -c SNORT_IDS -g snort

删除旧日志文件(如果要保留,请移动它们):

sudo rm /var/log/snort/*

我们需要授予“snort”用户对日志目录的权限:

sudo chmod -R 5775 /var/log/snort
sudo chown -R snort:snort /var/log/snort

创建systemD服务文件:

sudo vi /lib/systemd/system/snort3.service

具有以下内容(更改以太网适配器eth0以匹配适配器):

[Unit]
Description=Snort3 NIDS Daemon
After=syslog.target network.target
[Service]
Type=simple
ExecStart=/usr/local/bin/snort -c /usr/local/etc/snort/snort.lua -s 65535 \
-k none -l /var/log/snort -D -u snort -g snort -i ens33 -m 0x1b --create-pidfile
[Install]
WantedBy=multi-user.target

下面是在Snort中使用的所有标志的分类:

Flag 描述
/usr/local/bin/snort 这是snort二进制文件的路径。这里不使用sudo,因为脚本将以提升的(根)权限启动。
-c /usr/local/etc/snort/snort.lua snort.lua配置文件。
-s 65535 设置snaplen,使Snort不会截断和丢弃过大的数据包。
-k none 忽略错误的校验和,否则snort将丢弃具有错误校验和的数据包,并且不会对它们进行计算。
-l /var/log/snort Snort将存储其输出的所有日志文件的文件夹的路径。
-D 作为守护进程运行。
-u snort 启动后(以及执行任何需要提升权限的操作时),切换为以“snort”用户身份运行。
-g snort 启动后,作为“snort”组运行。
-i eth0 要监听的接口。
-m 0x1b 文件权限为033的Umask。
--create-pidfile 在日志目录中创建一个PID文件(这样pulledpork可以在加载新规则后重新启动snort)

启用Snort systemD服务并启动它:

sudo systemctl enable snort3
sudo service snort3 start

检查服务的状态:

service snort3 status

输出应类似于以下内容,显示“active(running)”:

service snort3 status
    * snort3.service - Snort3 NIDS Daemon
    Loaded: loaded (/lib/systemd/system/snort3.service; enabled; vendor preset: enabled)
    Active: active (running) since Tue 2018-12-11 16:48:44 EST; 2min 57s ago

如果有任何问题,可以使用以下命令检查服务的完整输出:

sudo journalctl -u snort3.service

Splunk

Splunk是我们将用作SIEM(安全信息和事件管理)解决方案的软件,它将以图形方式(通过web界面)显示Snort生成的所有警报,并将为我们提供一些强大的工具来搜索和理解这些警报,以及从中提取更深入的信息。Splunk对于我们使用它的方式来说是免费的(就像在成本上一样)(尽管可以购买一个许可证来获得与管理大型Splunk安装相关的附加功能)。替代软件是Elasticstack的ELK stack(我在这里不使用它,因为配置更复杂)。

安装Splunk

需要在Splunk的网站上创建一个免费帐户来下载软件和附加组件。导航到Splunk的主页,点击右上角的Free Splunk按钮,创建一个新帐户(如果你已经有帐户,也可以登录)。在Splunk Free下,单击“Splunk Enterprise”下标题为下载免费60天试用版的链接。[下载][https://www.splunk.com/en_us/download/splunk-enterprise.html]

在下载页面上,单击Linux选项卡,然后单击.deb旁边的download Now按钮(因为我们运行的是基于Debian的Ubuntu系统)。同意许可证,然后单击“立即开始下载”按钮。下载页面将自动打开一个窗口,以将下载保存到本地系统。如果想使用wget下载安装程序,可以取消此下载,然后单击“通过命令行下载”(wget)复制wget字符串以供下载。下载量约为370MB。

一旦系统上安装了Splunk安装程序,就需要安装它。从保存安装程序的目录:

sudo dpkg -i splunk-8.*.deb
sudo chown -R splunk:splunk /opt/splunk

这将把Splunk安装到/opt/Splunk。请注意,安装的卷Splunk必须有5GB的可用空间,否则Splunk将无法启动。Splunk存储所有收集到的日志数据的索引位于安装位置的子文件夹中,因此请确保此卷上有足够的空间来存储希望收集的所有数据。

现在第一次启动Splunk(接受许可证并使用所有默认选项),系统将提示为Splunk创建一个新的管理用户和密码。保存这些凭据,因为我们稍后将使用它们登录到web界面:

sudo /opt/splunk/bin/splunk start --answer-yes --accept-license

然后要配置Splunk在引导时自动启动。还将为Splunk启用systemD并启动服务(而不是Splunk systemD服务名称中的大写“S”)。

sudo /opt/splunk/bin/splunk stop
sudo /opt/splunk/bin/splunk enable boot-start -systemd-managed 1
sudo chown -R splunk:splunk /opt/splunk
sudo service Splunkd start

Splunk服务器现在正在侦听此服务器的端口8000(http://localhost:8000(如果是从本地计算机连接,或从另一台计算机通过此系统的IP地址连接)。用户名和密码是安装Splunk时设置的。

Splunk目前使用免费的企业试用许可证运行,提供60天的所有企业功能,并允许每天索引5GB的日志数据。唯一的功能,我们将失去一旦试用许可证到期,将影响这个安装是删除已验证的登录。转换为免费许可证后,将不会提示登录到Splunk web界面。

Splunk Enterprise提供了许多功能,包括自动更新Splunk实例及其自动运行的Splunk应用程序的部署服务器、具有可配置权限的多个用户帐户、负载平衡和其他功能。

配置Splunk

现在使用在Splunk安装期间创建的用户名和密码登录到Splunk实例。Splunk服务器正在监听端口8000(http://localhost:8000).

我们需要安装一个Splunk插件(称为Add-on),它允许我们轻松地接收(收集)Snort 3创建的日志并对其进行规范化(确保字段命名与NIDS数据一致,这样Splunk应用程序就可以轻松地显示我们的数据)。

要安装此应用程序,请在Splunk实例的主页上,单击Splunk web界面左侧标题为+查找更多应用程序的链接:

image-20210609204127583

这将进入Splunkbase,这是一个Splunk插件的在线存储库,它扩展并增强了Splunk安装的功能。在Splunkbase中搜索Snort3,看到一个结果:snort3json警报。单击此加载项旁边的绿色安装按钮:

image-20210609204202219

输入注册下载Splunk时使用Splunk创建的用户名和密码(不是为本地Splunk服务器实例创建的用户名和密码)。接受条款和条件,然后单击“登录并安装”。安装完成后,单击“完成”。

接下来我们要安装CyberChef for Splunk插件,它允许我们将b64_data字段转换为可读文本。如上所述,在Splunkbase中搜索“cyberchef”,单击cyberchef旁边的green install按钮以获取Splunk,登录,然后安装:

接下来,我们需要配置Snort 3 JSON Alerts插件,告诉Splunk Snort 3生成的日志文件存储在哪里,以便Splunk能够接收它们。我们使用配置文件从命令行执行此操作:

sudo mkdir /opt/splunk/etc/apps/TA_Snort3_json/local
sudo touch /opt/splunk/etc/apps/TA_Snort3_json/local/inputs.conf
sudo vi /opt/splunk/etc/apps/TA_Snort3_json/local/inputs.conf

在此inputs.conf文件中输入以下文本:

[monitor:///var/log/snort/*alert_json.txt*]
sourcetype = snort3:alert:json

重启Splunk:

sudo service Splunkd restart

现在,当Splunk启动时,它将扫描/var/log/snort目录中的json文件,将它们分配给sourcetype of snort3:alert:json把它们记录下去,这样我们就可以搜索它们了。

从Splunk实例中登录(因为重新启动了服务器),单击左上角的Splunk>Enterprise链接,然后单击左侧的Search and Reporting app链接。在“搜索”字段中,输入以下文本:

sourcetype="snort3:alert:json"

然后单击绿色放大镜图标开始搜索。

image-20210609204644013

这将显示服务器正在收集的所有事件。可能看不到很多事件,特别是如果删除了从pcap文件创建的旧json文件。如果没有看到任何警报,可以使用ping创建一些新警报(请记住,我们之前创建了该规则)。在生成的事件和Splunk中显示的事件之间有一点延迟。如果仍然看不到任何警报,请将“时间范围”(搜索图标旁边的下拉列表设置为“过去24小时”)更改为“所有时间”,然后重新运行搜索。如果仍然没有看到任何事件,请检查/var/log/snort文件夹中是否有json文件。

使用Splunk

本指南不深入介绍如何使用Splunk。Splunk提供了非常好的免费资源,我在下面提到了这一点。

下面是一些简单的搜索,你可能会发现有助于开始。要在包含时间、源、目标和消息的表中显示所有事件,请运行以下搜索:

sourcetype="snort3:alert:json"
| table _time src_ap dst_ap msg

按目的地显示所有事件的计数:

sourcetype="snort3:alert:json"
| stats count by dest

要在地图上显示所有事件源:

sourcetype="snort3:alert:json"
| iplocation src_addr
| stats count by Country
| geom geo_countries featureIdField="Country"

(可能需要单击“可视化”选项卡,然后单击“折线图”并将其更改为Choropleth地图)

对于许多事件,都会有base64编码的有效负载数据(b64_data)字段(http和SMTP就是一个很好的例子)。为了转换这些数据以便我们可以读取,我们使用“cyberchef”函数为每个事件转换数据(动态),并为每个事件添加一个名为“decrypted”的新字段:

 sourcetype="snort3:alert:json" dest_port=80
| cyberchef infield='b64_data' outfield=decrypted operation="FromBase64"
| table src_addr, dst_addr, rule, msg, decrypted

使用Splunk的一些优秀免费资源包括:

[EBook][https://www.splunk.com/en_us/form/exploring-splunk-search-processing-language-spl-primer-and-cookbook.html]

[Free Online Training][https://www.splunk.com/en_us/training/free-courses/splunk-fundamentals-1.html]

正在清理安装

Splunk目前运行的是免费企业试用模式,仅适用于60天。我们希望将此许可证转换为免费模式,这与企业模式类似,只是删除了一些功能。注意到缺少的功能是使用用户名和密码登录服务器(允许任何人登录)。还失去了一些与集群相关的功能,以及将Splunk应用程序部署到其他服务器的能力(当有多个服务器或系统要从中收集日志时非常有用)。

要更改许可证,请单击右上栏的“设置”,然后单击“许可证”:

单击更改许可证组。选择“免费许可证”,然后单击“保存”。单击“立即重新启动”,然后单击“确定”。

现在,会发现无法从远程计算机访问spunkweb界面,这没关系,我们将在下一节中使用反向代理解决这个问题。

反向代理Splunk Web

使用免费许可证的Splunk不会阻止使用用户名和密码进行访问,并且只允许从本地计算机进行访问(取决于切换许可证时是否在本地连接)。在这里,我们将设置一个反向代理,apache监听该服务器的端口80,这将需要一个密码,并将重定向到Splunk接口。

安装apache和代理模块:

sudo apt-get install -y apache2 apache2-utils
sudo a2enmod proxy
sudo a2enmod proxy_http
sudo systemctl restart apache2

创建新用户。系统将提示输入密码。记住用户和密码,以后将使用它。可以通过以下方式创建多个用户:

sudo touch /etc/apache2/.htpasswd
sudo htpasswd /etc/apache2/.htpasswd <username>

编辑apache配置文件,以在端口80上设置代理侦听:

sudo vi /etc/apache2/sites-available/000-default.conf

在此文件中输入以下信息。如果已经有一个<VirtualHost*:80>部分,请将下面的设置添加到该部分中。告诉apache在端口80上侦听,需要身份验证(htaccess文件中的用户/密码),然后将所有授权的连接转发到端口8000(splunk正在侦听)。

<VirtualHost *:80>
ProxyPreserveHost On
ProxyPass / http://127.0.0.1:8000/
ProxyPassReverse / http://127.0.0.1:8000/
<Proxy *>
Order deny,allow
Allow from all
Authtype Basic
Authname "Password Required"
AuthUserFile /etc/apache2/.htpasswd
Require valid-user
</Proxy>
</VirtualHost>

验证我们的apache配置:

sudo apachectl -t

可能会得到一个关于服务器FQDN的错误,这并不重要。

重新启动apache以加载更改:

sudo systemctl restart apache2

将Splunk配置为仅接受来自本地计算机的连接(通过代理重定向):

sudo vi /opt/splunk/etc/system/local/web.conf

在“设置”部分下,添加一行:server.socket_host=localhost(如果文件为空,只需添加以下两行,否则将server.socket添加到“设置”部分):

[settings]
server.socket_host = localhost

重新启动splunk以注册更改:

sudo service Splunkd restart

现在尝试连接到端口80上的splunk服务器,系统会提示输入用户名和密码。如果尝试连接到端口8000,无法连接(除非是从同一台计算机连接)。

OpenAppID(可选)

OpenAppID允许识别应用层(第7层)通信量。可以创建对应用程序层流量进行操作的规则(比如阻止facebook),并记录检测到的每种类型流量的流量统计信息。更多信息。OpenAppID是Snort的一个可选功能,如果您想检测或阻止流量类型(facebook、FTP等),或者收集Snort服务器检测到的每种流量的数据量指标,则应该启用它。

Snort团队在社区的帮助下组装了一个探测器包,可以下载并安装它,称为applicationdetector包。首先下载OpenAppID detector包并解压缩文件:

cd ~/snort_src/
wget https://snort.org/downloads/openappid/15607 -O OpenAppId-15607.tgz
tar -xzvf OpenAppId-15607.tgz
sudo cp -R odp /usr/local/lib/

注意:如果得到一个文件不存在的错误,那么Snort团队可能更新了规则集。浏览到https://snort.org/downloads#openappid,并下载snort-openappid.tar.gz。

接下来,我们需要下载Snort Extras存储库,它包含了额外的检查器和插件,包括appid_listener,它将允许我们以JSON格式输出appid统计信息。

cd ~/snort_src/
git clone https://github.com/snort3/snort3_extra.git
cd ./snort3_extra/
export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig/
./configure_cmake.sh --prefix=/usr/local
cd build
make
sudo make install

接下来,我们需要编辑Snort配置文件以指向这个odp目录:

sudo vi /usr/local/etc/snort/snort.lua

找到以下部分并在configure Inspection部分中进行如下配置(修改appid部分,并添加新的appid\u listener部分):

appid =
{
    app_detector_dir = '/usr/local/lib',
}

appid_listener =
{
    json_logging = true,
    file = "/var/log/snort/appid-output.log",
}

既然已经做了更改,请如上所述验证snort.lua文件。

使用新规则修改local.rules文件,该规则将检测facebook流量。

alert tcp any any -> any any ( msg:"Facebook Detected"; appids:"Facebook"; sid:10000002; metadata:policy security-ips alert; )

现在是测试snort_extras插件是否可以加载(这需要额外的命令行opton)以及新规则是否正确格式化的好时机:

snort -c /usr/local/etc/snort/snort.lua -R /usr/local/etc/rules/local.rules \
--plugin-path=/usr/local/lib/snort_extra

在继续之前修复所有错误。-pluginpath参数告诉snort从提取的snort_extra包中加载其他插件,包括appid_listener 插件。

我们需要做两件事,现在我们已经添加了一个新的规则,并修改了配置。首先,我们需要pulledpork来重新创建snort.rules文件(包括新规则),该文件还将重新加载snort

sudo /usr/local/bin/pulledpork.pl -c /usr/local/etc/pulledpork/pulledpork.conf -l -P -H SIGHUP

其次,我们需要修改systemD Snort脚本,使其能够加载appid_listener 目录

sudo vi /lib/systemd/system/snort3.service

添加 --plugin-path 选项:

ExecStart=/usr/local/bin/snort -c /usr/local/etc/snort/snort.lua -s 65535 \
-k none -l /var/log/snort -D -u snort -g snort -i ens3 -m 0x1b --create-pidfile \
--plugin-path=/usr/local/lib/snort_extra

重新加载systemd文件并重新加载snort,然后验证服务是否正在运行:

sudo systemctl enable snort3
sudo service snort3 restart
service snort3 status

生成一些facebook流量(wget facebook.com),将看到写入splunk(和json日志文件)的警报:

sourcetype="snort3:alert:json" msg="Facebook Detected"

还会在日志目录中看到一个新文件:/var/log/snort/appid-output.log,其中包含json格式的trafic统计信息:

{ "session_num": "0.58", "pkt_time": "2020-12-19 09:51:46.540562", "pkt_num": 1665, "apps": { "service"
: "HTTPS", "client": "SSL client", "payload": "Facebook", "misc": null, "referred": null }, "proto"
: "TCP", "client_info": { "ip": "10.10.10.88", "port": 33942, "version": null }, "service_info": {
"ip": "185.60.216.35", "port": 443, "version": null, "vendor": null }, "user_info": { "id": 0, "
username": null, "login_status": "n/a" }, "tls_host": "www.facebook.com", "dns_host": null, "http":
{ "http2_stream": null, "host": null, "url": null, "user_agent": null, "response_code": null, "
referrer": null } }

服务字段告诉检测到此流量的服务。

将splunk配置为读取appid stats:接下来,我们需要配置Snort 3json警报插件来告诉splunk OpenAppID日志文件的存储位置。就像以前一样,我们使用配置文件从命令行执行此操作:

sudo vi /opt/splunk/etc/apps/TA_Snort3_json/local/inputs.conf

将以下文本添加到此inputs.conf文件中(不要删除指向警报文件的其他部分):

[monitor:///var/log/snort/*appid-output.log*]
sourcetype = snort3:openappid:json

重启Splunk:

sudo service Splunkd restart

现在在splunk中搜索OpenAppID数据

search sourcetype="snort3:openappid:json"

结论

有关运行Snort 3和编译选项的更多信息,请参阅Snort 3博客。Snort 3与Snort 2.9.9.x系列有很大不同。配置文件和规则文件都是不同的,两个版本之间不兼容。可以使用附带的snort2lua命令将旧的Snort 2配置和规则文件转换为Snort 3格式。
参考文档Snort 3.1.0.0 on Ubuntu 18 & 20

推荐阅读