Archive

access splunk from python using certificate

damucka
Contributor

Hello,

I need to access Splunk from python. At the moment my code looks as follows:

# -*- coding: utf-8 -*-
"""
Created on Tue Dec 11 14:24:58 2018

@author: D038423
"""

# -*- coding: utf-8 -*-
"""
Created on Tue Dec 11 14:00:58 2018

@author: D038423
"""

import urllib
import urllib.parse
import urllib.request as urllibrequest
import requests
import re
from xml.dom import minidom

def pretty_print_POST(req):
    """
    At this point it is completely built and ready
    to be fired; it is "prepared".

    However pay attention at the formatting used in 
    this function because it is programmed to be pretty 
    printed and may differ from the actual request.
    """
    print('{}\n{}\n{}\n\n{}'.format(
        '-----------START-----------',
        req.method + ' ' + req.url,
        '\n'.join('{}: {}'.format(k, v) for k, v in req.headers.items()),
        req.body,
    ))


base_url = 'https://splunk.mo.sap.corp:8089'
username = 'C5271127'
password = 'XXXXX'
search_query = "search=savedsearch BWP_nodes_in_sync"

# encoded = urllib.parse.urlencode(({password}).encode('utf8'))
# print (urllib.parse.urldecode(password))

# Login and get the session key
request = urllibrequest.Request(base_url + '/servicesNS/admin/search/auth/login', 
    data = urllib.parse.urlencode({'username': username, 'password': password}).encode("utf-8"))


#prepared = request.prepare()
#pretty_print_POST(request)


server_content = urllibrequest.urlopen(request)

session_key = minidom.parseString(server_content.read()).\
        getElementsByTagName('sessionKey')[0].childNodes[0].nodeValue
print ("Session Key: %s" % session_key) 

# Perform a search
r = requests.post(base_url + '/services/search/jobs/', data=search_query,
    headers = { 'Authorization': ('Splunk %s' %session_key)},
    verify = False)

print (r.text.split('\n')[1])
prog = re.compile(r'[^\d]+(\d+\.\d+)[^\d]+')
id = prog.match(r.text.split('\n')[1]).group(1)

print (base_url + '/services/search/jobs/%s/results' % id)
r = requests.get(base_url + '/services/search/jobs/%s/results' % id, data="output_mode=csv",
    headers = { 'Authorization': ('Splunk %s' %session_key)},
    verify = False)
print (r.text)

But unfortunately it does not work - I am getting error that the certificate is false.

RLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:833)>

My Splunk admin said the user / password authentication is not possible, I have to use the certificate.

So, how would the above code need to look like if I would like to use the certificate for the user C5271127?

Kind Regards,
Kamil

Tags (1)
0 Karma

worshamn
Contributor

I don't have the exact answer but have some ideas for you to try. Depending on how authentication is setup on this Splunk server, if you did have a locally created account then username and password would certainly work but that error sounds more like that the certificate is self-signed and that your Python client doesn't recognize the CA that signed it. You could try temporarily bypass verification https://stackoverflow.com/questions/27835619/urllib-and-ssl-certificate-verify-failed-error.

I would recommend trying this out first in postman like this article shows https://answers.splunk.com/answers/692463/how-to-access-splunk-api-in-postman.html (note that you put the search in the body as raw and as is).

Lastly, another option is use the Splunk Python SDK instead (http://dev.splunk.com/python) which abstracts many things like this for you.