Alerting

Setting a webhook alert via a proxy server

stepowsk
Engager

I'm trying to set up a webhook alert, but the splunk server cannot contact the HTTP endpoint directly and must talk HTTP via a proxy server. Is it possible to configure splunk to use a HTTP proxy?

Tags (1)

sduff_splunk
Splunk Employee
Splunk Employee

The webhook.py script doesn't take into account proxies. You can replace /opt/splunk/etc/apps/alert_webhook/webhook.py with the following, and configure the proxy instead of the existing 127.0.0.1.

import sys
import json
import urllib2
import csv
import gzip
from collections import OrderedDict


def send_webhook_request(url, body, user_agent=None):
    if url is None:
        print >> sys.stderr, "ERROR No URL provided"
        return False
    print >> sys.stderr, "INFO Sending POST request to url=%s with size=%d bytes payload" % (url, len(body))
    print >> sys.stderr, "DEBUG Body: %s" % body
    try:
        # sduff - install proxy handler
        proxy = urllib2.ProxyHandler({'http': '127.0.0.1'})
        opener = urllib2.build_opener(proxy)
        urllib2.install_opener(opener)
        # sduff - end of proxy handler code

        req = urllib2.Request(url, body, {"Content-Type": "application/json", "User-Agent": user_agent})
        res = urllib2.urlopen(req)
        if 200 <= res.code < 300:
            print >> sys.stderr, "INFO Webhook receiver responded with HTTP status=%d" % res.code
            return True
        else:
            print >> sys.stderr, "ERROR Webhook receiver responded with HTTP status=%d" % res.code
            return False
    except urllib2.HTTPError, e:
        print >> sys.stderr, "ERROR Error sending webhook request: %s" % e
    except urllib2.URLError, e:
        print >> sys.stderr, "ERROR Error sending webhook request: %s" % e
    except ValueError, e:
        print >> sys.stderr, "ERROR Invalid URL: %s" % e
    return False


if __name__ == "__main__":
    if len(sys.argv) < 2 or sys.argv[1] != "--execute":
        print >> sys.stderr, "FATAL Unsupported execution mode (expected --execute flag)"
        sys.exit(1)
    try:
        settings = json.loads(sys.stdin.read())
        url = settings['configuration'].get('url')
        body = OrderedDict(
            sid=settings.get('sid'),
            search_name=settings.get('search_name'),
            app=settings.get('app'),
            owner=settings.get('owner'),
            results_link=settings.get('results_link'),
            result=settings.get('result')
        )
        user_agent = settings['configuration'].get('user_agent', 'Splunk')
        if not send_webhook_request(url, json.dumps(body), user_agent=user_agent):
            sys.exit(2)
    except Exception, e:
        print >> sys.stderr, "ERROR Unexpected error: %s" % e
sys.exit(3)

I'll chase internally to see if this can be updated, and also made to use the proxy set in Splunk, or at least, the Environment variables.
(I'll post updates to https://gist.github.com/sduff/3c461f05f907ebd08e7f128237705a0f)

dmarling
Builder

I recently had to deal with this too and found this answer, but it's out of date of the current webhook.py.  I figured having a more recent example that is python3 compatible would be beneficial.  Replace 127.0.0.1 with the proxy host you need to use.

 

import sys
import json
import csv
import gzip
from collections import OrderedDict
from future.moves.urllib.request import urlopen, Request, ProxyHandler, build_opener, install_opener
from future.moves.urllib.error import HTTPError, URLError

def send_webhook_request(url, body, user_agent=None):
    if url is None:
        sys.stderr.write("ERROR No URL provided\n")
        return False
    sys.stderr.write("INFO Sending POST request to url=%s with size=%d bytes payload\n" % (url, len(body)))
    sys.stderr.write("DEBUG Body: %s\n" % body)
    try:
        proxy = ProxyHandler({'http': 'http://127.0.0.1:80', 'https': 'https://127.0.0.1:80'})
        opener = build_opener(proxy)
        install_opener(opener)
        if sys.version_info >= (3, 0) and type(body) == str:
            body = body.encode()
        req = Request(url, body, {"Content-Type": "application/json", "User-Agent": user_agent})
        res = urlopen(req)
        if 200 <= res.code < 300:
            sys.stderr.write("INFO Webhook receiver responded with HTTP status=%d\n" % res.code)
            return True
        else:
            sys.stderr.write("ERROR Webhook receiver responded with HTTP status=%d\n" % res.code)
            return False
    except HTTPError as e:
        sys.stderr.write("ERROR Error sending webhook request: %s\n" % e)
    except URLError as e:
        sys.stderr.write("ERROR Error sending webhook request: %s\n" % e)
    except ValueError as e:
        sys.stderr.write("ERROR Invalid URL: %s\n" % e)
    return False


if __name__ == "__main__":
    if len(sys.argv) < 2 or sys.argv[1] != "--execute":
        sys.stderr.write("FATAL Unsupported execution mode (expected --execute flag)\n")
        sys.exit(1)
    try:
        settings = json.loads(sys.stdin.read())
        url = settings['configuration'].get('url')
        body = OrderedDict(
            sid=settings.get('sid'),
            search_name=settings.get('search_name'),
            app=settings.get('app'),
            owner=settings.get('owner'),
            results_link=settings.get('results_link'),
            result=settings.get('result')
        )
        user_agent = settings['configuration'].get('user_agent', 'Splunk')
        if not send_webhook_request(url, json.dumps(body), user_agent=user_agent):
            sys.exit(2)
    except Exception as e:
        sys.stderr.write("ERROR Unexpected error: %s\n" % e)
        sys.exit(3)

 

If this comment/answer was helpful, please up vote it. Thank you.
Tags (3)
0 Karma