Last active
March 16, 2025 14:16
-
-
Save redsfyre/8f4887ba9440a008661cbdfef1b3d8eb to your computer and use it in GitHub Desktop.
An example script for Wazuh - Opsgenie integrations. You need to edit the issue_data variable within the generate_msg function. For example, you should write the name of the team you created on opsgenie in the responder field. Find "XXXX Team" in the code below. Below code tested on Wazuh 4.3.7
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# Copyright (C) 2015, Wazuh Inc. | |
# Created by Wazuh, Inc. <[email protected]>. | |
# This program is free software; you can redistribute it and/or modify it under the terms of GPLv2 | |
WPYTHON_BIN="framework/python/bin/python3" | |
SCRIPT_PATH_NAME="$0" | |
DIR_NAME="$(cd $(dirname ${SCRIPT_PATH_NAME}); pwd -P)" | |
SCRIPT_NAME="$(basename ${SCRIPT_PATH_NAME})" | |
case ${DIR_NAME} in | |
*/active-response/bin | */wodles*) | |
if [ -z "${WAZUH_PATH}" ]; then | |
WAZUH_PATH="$(cd ${DIR_NAME}/../..; pwd)" | |
fi | |
PYTHON_SCRIPT="${DIR_NAME}/${SCRIPT_NAME}.py" | |
;; | |
*/bin) | |
if [ -z "${WAZUH_PATH}" ]; then | |
WAZUH_PATH="$(cd ${DIR_NAME}/..; pwd)" | |
fi | |
PYTHON_SCRIPT="${WAZUH_PATH}/framework/scripts/${SCRIPT_NAME}.py" | |
;; | |
*/integrations) | |
if [ -z "${WAZUH_PATH}" ]; then | |
WAZUH_PATH="$(cd ${DIR_NAME}/..; pwd)" | |
fi | |
PYTHON_SCRIPT="${DIR_NAME}/${SCRIPT_NAME}.py" | |
;; | |
esac | |
${WAZUH_PATH}/${WPYTHON_BIN} ${PYTHON_SCRIPT} "$@" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
import sys | |
import json | |
import time | |
import os | |
try: | |
import requests | |
from requests.auth import HTTPBasicAuth | |
except Exception as e: | |
print ("No module named requests. Please install using: pip install requests") | |
sys.exit(1) | |
# Global variables | |
debug_enabled = False | |
pwd = os.path.dirname(os.path.dirname(os.path.realpath(__file__))) | |
json_alert = {} | |
now = time.strftime("%a %b %d %H:%M:%S %Z %Y") | |
# Set paths | |
log_file = '{0}/logs/integrations.log'.format(pwd) | |
def main(args): | |
debug("# Starting") | |
# Read args | |
alert_file_location = args[1] | |
api_key = args[2] | |
hook_url = args[3] | |
debug("# Webhook") | |
debug(hook_url) | |
debug("# File location") | |
debug(alert_file_location) | |
# Load alert. Parse JSON object. | |
with open(alert_file_location) as alert_file: | |
json_alert = json.load(alert_file) | |
debug("# Processing alert") | |
debug(json_alert) | |
debug("# Generating message") | |
msg = generate_msg(json_alert) | |
debug(msg) | |
debug("# Sending message") | |
send_msg(msg, api_key, hook_url) | |
def debug(msg): | |
if debug_enabled: | |
msg = "{0}: {1}\n".format(now, msg) | |
print(msg) | |
f = open(log_file, "a") | |
f.write(msg) | |
f.close() | |
def generate_msg(alert): | |
alert_level = alert['rule']['level'] | |
ruleid = alert['rule']['id'] | |
description = alert['rule']['description'] | |
agentid = alert['agent']['id'] | |
agentname = alert['agent']['name'] | |
full_log = alert['full_log'] | |
issue_data = { | |
"message": 'Wazuh alert' + ' - ' + agentname + ' - ' + description, | |
"alias": 'Wazuh alert' + ' - ' + agentname + ' - ' + description, | |
"description": full_log, | |
"responders": [{"name": "XXXX Team", "type": "team"}], | |
"visibleTo": [{'name': 'all', "type": "team"}], | |
"tags": ['Wazuh', 'Alert', 'Level ' + str(alert_level), 'Rule ' + str(ruleid), 'Agent ' + str(agentid)], | |
"actions": ['acknowledge', 'close'], | |
"details": {}, | |
"entity": 'Wazuh alert' + ' - ' + agentname + ' - ' + description, | |
"priority": "P3" | |
} | |
return json.dumps(issue_data) | |
def send_msg(msg, api_key, hook_url): | |
headers = {'content-type': 'application/json','Authorization': 'GenieKey ' + api_key} | |
res = requests.post(hook_url, data=msg, headers=headers) | |
debug(res) | |
if __name__ == "__main__": | |
try: | |
# Check arguments | |
bad_arguments = False | |
if len(sys.argv) >= 4: | |
msg = '{0} {1} {2} {3} {4}'.format( | |
now, | |
sys.argv[1], | |
sys.argv[2], | |
sys.argv[3], | |
sys.argv[4] if len(sys.argv) > 4 else '', | |
) | |
debug_enabled = (len(sys.argv) > 4 and sys.argv[4] == 'debug') | |
else: | |
msg = '{0} Wrong arguments'.format(now) | |
bad_arguments = True | |
# Logging the call | |
f = open(log_file, 'a') | |
f.write(msg + '\n') | |
f.close() | |
if bad_arguments: | |
debug("# Exiting: Bad arguments.") | |
sys.exit(1) | |
# Main function | |
main(sys.argv) | |
except Exception as e: | |
debug(str(e)) | |
raise |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!--Opsgenie Integration --> | |
<integration> | |
<name>custom-opsgenieintegration</name> | |
<hook_url>WEBHOOK</hook_url> | |
<level>12</level> | |
<api_key>API_KEY</api_key> | |
<alert_format>json</alert_format> | |
</integration> |
Thank you very much, it works! When you install this module you must also remember to set the correct groups and permissions.
Thank you very much, it works! When you install this module you must also remember to set the correct groups and permissions.
I'm glad to hear that @mpeirone . This is one of the first projects that I share with the community, and I was very happy that it really worked for someone.
Also in the new wazuh versions there is a new feature called active response. I haven't had a chance to try it yet, but maybe it works better than this.
AFAIK the Opsgenie API has not changed in the last two years, but it may be useful to review the relevant documentations.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The name of the custom integration must start with "custom-" and the rest of the name must not have a "-" sign. Otherwise the integration is not triggered by Wazuh