Security

Are there any recommended best practices for storing login credentials using the Splunk Python SDK?

Champion

Hi,

We are creating some new Splunk commands, which will connect to external data-sources using the Splunk Python SDK. Are there any recommended best practices for storing login credentials?

0 Karma

Splunk Employee
Splunk Employee

If it helps, I use Splunk's secret and openssl to encrypt 3rd party credentials when using python for Splunk.

Encrypting

#import the necessary
import os
import subprocess

#open file we want to write creds to
writecreds=open('awscreds.conf','wb')

#prompt user for account
awsaccount=raw_input("Enter your account:")

#process the account using Splunk's openssl and secret
a = subprocess.Popen('echo ' + repr(awsaccount) + ' | openssl bf -e -a -pass file:%s' % (os.path.join(os.environ['SPLUNK_HOME'],'etc','auth', 'splunk.secret')), shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE)


#write the encrypted account info to the file
writecreds.write("account = "+str(a.stdout.read().split()[0]))
writecreds.write("\n")


#prompt user for password
awspass=raw_input("Enter your password:")


#process the password using Splunk's openssl and secret
p = subprocess.Popen('echo ' + repr(awspass) + ' | openssl bf -e -a -pass file:%s' % (os.path.join(os.environ['SPLUNK_HOME'],'etc','auth', 'splunk.secret')), shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE)


#write the encrypted password to the file
writecreds.write("pass = "+str(p.stdout.read().split()[0]))
writecreds.write("\n")


#close the file
writecreds.close()

Now what you will have is a file that looks like this -

bash-3.2# cat awscreds.conf

account = U2FsdGVkX1+027SjzZEi00kN40bB7g0OSuRAcp8Ac/E=
pass = U2FsdGVkX1+LjV842JUyjz2g8fW7F+35rdawGJu3jVE=

Now we're set to use these creds anyway we want

#import the necessary
import os
import subprocess


#set up our cred dictionary
creds = {}


#open the file we created above and read line by line splitting by the first "="
with open("awscreds.conf") as credfile:
    for line in credfile:
        name, var = line.partition("=")[::2]
        creds[name.strip()] = var.strip()


#decrypt the password
p = subprocess.Popen('echo ' + creds['pass'] + ' | openssl bf -d -a -pass file:%s' % (os.path.join(os.environ['SPLUNK_HOME'],'etc','auth', 'splunk.secret')), shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE)


#decrypt the account
a = subprocess.Popen('echo ' + creds['account'] + ' | openssl bf -d -a -pass file:%s' % (os.path.join(os.environ['SPLUNK_HOME'],'etc','auth', 'splunk.secret')), shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE)

#do whatever you want with them. Here we just print them.
print a.stdout.read().split()[0]
print p.stdout.read().split()[0]

Both should be run in Splunk's context. For example -
$SPLUNK_HOME/bin/splunk cmd python encrypt.py

In action -

bash-3.2# /Applications/splunk/bin/splunk cmd python encrypt.py
Enter your account:awsaccount1
Enter your password:myawspassword

bash-3.2# cat awscreds.conf
account = U2FsdGVkX1+027SjzZEi00kN40bB7g0OSuRAcp8Ac/E=
pass = U2FsdGVkX1+LjV842JUyjz2g8fW7F+35rdawGJu3jVE=


bash-3.2# /Applications/splunk/bin/splunk cmd python decrypt.py
awsaccount1

myawspassword
    

You can modify this for use within your script without having the user prompt so you can simply write/read from the conf file if you want.

Note that this is a limited case as it will take ONLY the secret of the instance you run this on. IE if you have searchhead clustering, or what have you. The Splunk secret will be different so you won't be able to replicate the password file between search heads.

0 Karma

Champion

It's good, thanks. But, if it's not usable on a SHC, then it won't work for me, as we are trying to create custom commands that will run from the SHC.

0 Karma

Splunk Employee
Splunk Employee

If your splunk.secret is the same on the search heads then this will work fine.

0 Karma

Ultra Champion

Good point @flynt. Having the splunk.secret file the same on all SHC saves a ton of headaches with any hashed items beyond this scenario.

0 Karma

Ultra Champion

Bingo! This is awesome. I say throw it on splunkbase!

0 Karma

Ultra Champion

I assume the credential you are referring to are for the external data-sources and not the local Splunk instance. I bet you can store them in a conf file where they can take advantage of the Splunk mechanism for hashing passwords. I have no clue how to implement that though 😞

0 Karma

Champion

That's what I was thinking - store them, and then have splunk hash them. Just not sure how...

0 Karma