| Plugins |
| ======= |
|
|
| Plugins are supported in several places: Event Processing and the REST api. |
|
|
| Event Processing |
| ---------------- |
| The front-end event processing portion of MozDef supports python `mq plugins`_ to allow customization of the input chain. |
| Plugins are simple python modules than can register for events with a priority, so they only see events with certain |
| dictionary items/values and will get them in a predefined order. |
|
|
| To create a plugin, make a python class that presents a registration dictionary and a priority as follows: |
|
|
| :: |
|
|
| class message(object): |
| def __init__(self): |
| |
| as a list of lower case strings or values to match with an event |
| set the priority if you have a preference for order of plugins to run. |
| 0 goes first, 100 is assumed/default if not sent |
| |
| self.registration = [ |
| self.priority = 20 |
|
|
|
|
| Message Processing |
| ^^^^^^^^^^^^^^^^^^ |
|
|
| To process a message, define an onMessage function within your class as follows: |
|
|
| :: |
|
|
| def onMessage(self, message, metadata): |
| #do something interesting with the message or metadata |
| return (message, metadata) |
|
|
|
|
| The plugin will receive a copy of the incoming event as a python dictionary in the |
|
|
| If you return the message as None (i.e. message=None) the message will be dropped and not be processed any further. |
| If you modify the metadata the new values will be used when the message is posted to elastic search. You can use this |
| to assign custom document types, set static document _id values, etc. |
|
|
|
|
| Plugin Registration |
| ^^^^^^^^^^^^^^^^^^^ |
|
|
| Simply place the .py file in the plugins directory where the esworker.py is located, restart the esworker.py process |
| and it will recognize the plugin and pass it events as it sees them. |
|
|
|
|
| REST Plugins |
| ------------ |
|
|
| The REST API for MozDef also supports `rest plugins`_ which allow you to customize your handling of API calls to suit your environment. |
| Plugins are simple python modules than can register for REST endpoints with a priority, so they only see calls for that endpoint |
| and will get them in a predefined order. |
|
|
|
|
| To create a REST API plugin simply create a python class that presents a registration dictionary and priority as follows: |
|
|
| :: |
|
|
| class message(object): |
| def __init__(self): |
| |
| as a list of lower case strings to match with an rest endpoint |
| (i.e. blockip matches /blockip) |
| set the priority if you have a preference for order of plugins |
| 0 goes first, 100 is assumed/default if not sent |
|
|
| Plugins will register in Meteor with attributes: |
| name: (as below) |
| description: (as below) |
| priority: (as below) |
| file: "plugins.filename" where filename.py is the plugin code. |
|
|
| Plugin gets sent main rest options as: |
| self.restoptions |
| self.restoptions[ |
| used by the restapi |
|
|
| |
|
|
| self.registration = [ |
| self.priority = 10 |
| self.name = "Banhammer" |
| self.description = "BGP Blackhole" |
|
|
|
|
| The registration is the REST endpoint for which your plugin will receive a copy of the request/response objects to use or modify. |
| The priority allows you to order your plugins if needed so that they operate on data in a defined pattern. |
| The name and description are passed to the Meteor UI for use in dialog boxes, etc so the user can make choices when needed |
| to include/exclude plugins. For example the /blockip endpoint allows you to register multiple methods of blocking an IP |
| to match your environment: firewalls, BGP tables, DNS blackholes can all be independently implemented and chosen by the user |
| at run time. |
|
|
|
|
| Message Processing |
| ^^^^^^^^^^^^^^^^^^ |
|
|
| To process a message, define an onMessage function within your class as follows: |
|
|
| :: |
|
|
| def onMessage(self, request, response): |
| |
| request: https://bottlepy.org/docs/dev/api.html#the-request-object |
| response: https://bottlepy.org/docs/dev/api.html#the-response-object |
|
|
| |
| response.headers[ |
|
|
|
|
| It |
| Other than that, you are free to perform whatever processing you need within the plugin being sure to |
| return the request, response object once done: |
|
|
| :: |
|
|
| return (request, response) |
|
|
|
|
|
|
| Plugin Registration |
| ^^^^^^^^^^^^^^^^^^^ |
|
|
| Simply place the .py file in the rest/plugins directory, restart the REST API process |
| and it will recognize the plugin and pass it events as it sees them. |
|
|
|
|
|
|
| Alert Plugins |
| ------------- |
|
|
| The alert pipeline also supports `alert plugins`_ which allow you to modify an alert |
|
|
| Create a sample plugin in alerts/plugins: |
|
|
| :: |
|
|
| class message(object): |
| def __init__(self): |
| |
| adds a new field |
| to the alert if sourceipaddress is 127.0.0.1 |
| |
|
|
| self.registration = "sourceipaddress" |
| self.priority = 1 |
|
|
|
|
|
|
| This plugin |
|
|
|
|
| Message Processing |
| ^^^^^^^^^^^^^^^^^^ |
|
|
| To process a message, define an onMessage function within your class as follows: |
|
|
| :: |
|
|
| def onMessage(self, message): |
| if |
| message[ |
| return message |
|
|
|
|
| It |
|
|
|
|
| Plugin Registration |
| ^^^^^^^^^^^^^^^^^^^ |
|
|
| Simply place the .py file in the alerts/plugins directory, restart the alerts process |
| and it will recognize the plugin and pass it alerts based on registration. |
|
|
|
|
|
|
| .. _mq plugins: https://github.com/mozilla/MozDef/tree/master/mq/plugins |
| .. _rest plugins: https://github.com/mozilla/MozDef/tree/master/rest/plugins |
| .. _alert plugins: https://github.com/mozilla/MozDef/tree/master/alerts/plugins |
|
|