Skip to content

Commit

Permalink
examples: add an example plugin of an eve filetype
Browse files Browse the repository at this point in the history
This is an example of what adding plugin examples to the Suricata repo
could look like.

This plugin is an example plugin for an EVE filetype. It could be
extended to support outputs like Redis, syslog, etc.

There is one issue with adding plugins like this to an autotools
project, the project can't be built with --disable-shared, which is
more of an autotools limitation, and not really a Suricata issue.
Suricata built with --disable-shared will load plugins just fine.

Note that the examples directory was added as DIST_SUBDIRS as we don't
want normal builds to recurse into it and attempt to build the plugin,
its just an example, but we still need to keep distcheck happy.
  • Loading branch information
jasonish authored and victorjulien committed Nov 17, 2023
1 parent a649a92 commit d2b25af
Show file tree
Hide file tree
Showing 9 changed files with 424 additions and 0 deletions.
12 changes: 12 additions & 0 deletions .github/workflows/builds.yml
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,18 @@ jobs:
test -e /usr/local/lib/suricata/python/suricata/update/configs/modify.conf
test -e /usr/local/lib/suricata/python/suricata/update/configs/threshold.in
test -e /usr/local/lib/suricata/python/suricata/update/configs/update.yaml
- name: Build C json filetype plugin
working-directory: examples/plugins/c-json-filetype
run: make
- name: Check C json filetype plugin
run: test -e examples/plugins/c-json-filetype/.libs/json-filetype.so.0.0.0
- name: Installing headers and library
run: |
make install-headers
make install-library
- name: Test plugin build with Makefile.example
working-directory: examples/plugins/c-json-filetype
run: PATH=/usr/local/bin:$PATH make -f Makefile.example

almalinux-9-templates:
name: AlmaLinux 9 Test Templates
Expand Down
1 change: 1 addition & 0 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ EXTRA_DIST = ChangeLog COPYING LICENSE suricata.yaml.in \
scripts/generate-images.sh
SUBDIRS = $(HTP_DIR) rust src qa rules doc contrib etc python ebpf \
$(SURICATA_UPDATE_DIR)
DIST_SUBDIRS = examples/plugins/c-json-filetype $(SUBDIRS)

CLEANFILES = stamp-h[0-9]*

Expand Down
2 changes: 2 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -2613,6 +2613,8 @@ AC_CONFIG_FILES(suricata.yaml etc/Makefile etc/suricata.logrotate etc/suricata.s
AC_CONFIG_FILES(python/Makefile python/suricata/config/defaults.py)
AC_CONFIG_FILES(ebpf/Makefile)
AC_CONFIG_FILES(libsuricata-config)
AC_CONFIG_FILES(examples/plugins/c-json-filetype/Makefile)

AC_OUTPUT

SURICATA_BUILD_CONF="Suricata Configuration:
Expand Down
6 changes: 6 additions & 0 deletions examples/plugins/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Example Plugins

## c-json-filetype

An example plugin of an EVE/JSON filetype plugin. This type of plugin
is useful if you want to send EVE output to custom destinations.
2 changes: 2 additions & 0 deletions examples/plugins/c-json-filetype/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
*.so
*.la
17 changes: 17 additions & 0 deletions examples/plugins/c-json-filetype/Makefile.am
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
plugindir = ${libdir}/suricata/plugins

if BUILD_SHARED_LIBRARY
plugin_LTLIBRARIES = json-filetype.la
json_filetype_la_LDFLAGS = -module -shared
json_filetype_la_SOURCES = filetype.c

json_filetype_la_CPPFLAGS = -I$(abs_top_srcdir)/rust/gen -I$(abs_top_srcdir)/rust/dist

else

all-local:
@echo
@echo "Shared library support must be enabled to build plugins."
@echo

endif
18 changes: 18 additions & 0 deletions examples/plugins/c-json-filetype/Makefile.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
SRCS := filetype.c

LIBSURICATA_CONFIG ?= libsuricata-config

CPPFLAGS += `$(LIBSURICATA_CONFIG) --cflags`
CPPFLAGS += -DSURICATA_PLUGIN -I.
CPPFLAGS += "-D__SCFILENAME__=\"$(*F)\""

OBJS := $(SRCS:.c=.o)

filetype.so: $(OBJS)
$(CC) -fPIC -shared -o $@ $(OBJS)

%.o: %.c
$(CC) -fPIC $(CPPFLAGS) -c -o $@ $<

clean:
rm -f *.o *.so *~
123 changes: 123 additions & 0 deletions examples/plugins/c-json-filetype/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
# Example EVE Filetype Plugin

## Building

If in the Suricata source directory, this plugin can be built by
running `make` and installed with `make install`.

Note that Suricata must have been built without `--disable-shared`.

## Building Standalone

The file `Makefile.example` is an example of how you might build a
plugin that is distributed separately from the Suricata source code.

It has the following dependencies:

- Suricata is installed
- The Suricata library is installed: `make install-library`
- The Suricata development headers are installed: `make install-headers`
- The program `libsuricata-config` is in your path (installed with
`make install-library`)

The run: `make -f Makefile.example`

Before building this plugin you will need to build and install Suricata from the
git master branch and install the development tools and headers:

- `make install-library`
- `make install-headers`

then make sure the newly installed tool `libsuricata-config` can be
found in your path, for example:
```
libsuricata-config --cflags
```

Then a simple `make` should build this plugin.

Or if the Suricata installation is not in the path, a command like the following
can be used:

```
PATH=/opt/suricata/bin:$PATH make
```

## Usage

To run the plugin, first add the path to the plugin you just compiled to
your `suricata.yaml`, for example:
```
plugins:
- /usr/lib/suricata/plugins/json-filetype.so
```

Then add an output for the plugin:
```
outputs:
- eve-log:
enabled: yes
filetype: json-filetype-plugin
threaded: true
types:
- dns
- tls
- http
```

In the example above we use the name specified in the plugin as the `filetype`
and specify that all `dns`, `tls` and `http` log entries should be sent to the
plugin.

## Details

This plugin demonstrates a Suricata JSON/EVE output plugin
(file-type). The idea of a Suricata EVE output plugin is to provide a
file like interface for the handling of rendered JSON logs. This is
useful for custom destinations not builtin to Suricata or if the
formatted JSON requires some post-processing.

Note: EVE output plugins are not that useful just for reformatting the
JSON output as the plugin does need to handle writing to a file once
the file type has been delegated to the plugin.

### Registering a Plugin

All Suricata plugins make themselves known to Suricata by using a
function named `SCPluginRegister` which is called after Suricata loads
the plugin shared object file. This function must return a `SCPlugin`
struct which contains basic information about the plugin. For
example:

```c
const SCPlugin PluginRegistration = {
.name = "eve-filetype",
.author = "Jason Ish",
.license = "GPLv2",
.Init = TemplateInit,
};

const SCPlugin *SCPluginRegister() {
return &PluginRegistration;
}
```

### Initializing a Plugin

After the plugin has been registered, the `Init` callback will be called. This
is where the plugin will set itself up as a specific type of plugin such as an
EVE output, or a capture method.

This plugins registers itself as an EVE file type using the
`SCRegisterEveFileType` struct. To register as an EVE file type the
following must be provided:

* name: This is the name of the output which will be used in the eve filetype
field in `suricata.yaml` to enable this output.
* Init: The callback called when the output is "opened".
* Deinit: The callback called the output is "closed".
* ThreadInit: Callback called to initialize per thread data (if threaded).
* ThreadDeinit: Callback called to deinitialize per thread data (if threaded).
* Write: The callback called when an EVE record is to be "written".

Please see the code in `filetype.c` for more details about this functions.

0 comments on commit d2b25af

Please sign in to comment.