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?
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)
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)