Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compare decrypted values to see if they are insync #221

Merged

Conversation

alexjfisher
Copy link
Member

When splunk is started, it automatically encrypts certain values when it
finds them in config files. To stop puppet reverting these changes,
I've overriden insync? so that it performs the decryption before
comparing.

Currently only implemented for splunk >= 7.2

Based on description of algorithm in this python based project.
https://github.com/HurricaneLabs/splunksecrets

@alexjfisher alexjfisher added needs-tests enhancement New feature or request labels Apr 6, 2019
decipher.auth_tag = tag
decipher.auth_data = ''

decipher.update(ciphertext) + decipher.final
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dunno if I should catch exceptions here, log a warning, and return something so that puppet can continue??

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMHO things this deep shouldn't rescue exceptions because they're too deep to know what to do about them. That should be done higher up. IMHO only rescue exceptions here if you watch to toss your own customized exception like Spunk::Util::DecodeException blah blah blah IMHO YMMV

Copy link
Member Author

@alexjfisher alexjfisher Apr 9, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The thought was if decryption did fail, it could be because of something like the splunk.secrets file being replaced. If decryption does fail (for whatever reason), it's maybe better for insync? to return false instead of a hard error being thrown and not handled.

I like your advice on rethrowing a custom exception and catching it higher up. I'll leave this as is in this PR, but might work on an enhancement in a separate PR later. Thanks for the tip.

@alexjfisher alexjfisher force-pushed the compare_values_after_decrypting branch 8 times, most recently from 8417f2a to 909ac25 Compare April 8, 2019 16:17
@jorhett
Copy link

jorhett commented Apr 8, 2019

Quick question: would it be possible for Puppet to encrypt the values in a way that Splunk finds acceptable, so as to be more declarative / less subject to changes in Splunk?

context 'default parameters' do
# Using puppet_apply as a helper
it 'works idempotently with no errors' do
pp = <<-EOS
class { '::splunk::enterprise': }
EOS

# Run it twice and test for idempotency
# Run it three times and test for eventual idempotency (Needed for SELINUX limitations)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you be more specific about the need, or link to something at least for the poor lass/lad who has no idea what limitation you're referring to?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very fair point. I've removed this change as it was something I only really needed when testing locally with vagrant_libvirt and it's not otherwise related to this PR.

As for the actual issue. Puppet updates the selinux attributes on the config files on the second run since it defaults these file properties to

the value returned by matchpathcon for the file, if any exists

Puppet doesn't reread these default selinux contexts at any time during a run. Typically, they can be updated by a package being installed (eg splunk). See https://tickets.puppetlabs.com/browse/PUP-2169

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also see #153 (comment)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update: This turned out not to be what was happening on this occasion. There is no selinux policy being installed with the RPM. Instead, on Centos 6 only (when the daemon is run from init.d not systemd), when splunk modifies the config file to encrypt values, it also ends up inadvertently modifying the seluser to unconfined_u (the context under which the process is running as). Puppet then puts it back on the next run.

When splunk is started, it automatically encrypts certain values when it
finds them in config files.  To stop puppet reverting these changes,
I've overriden `insync?` so that it performs the decryption before
comparing.

Currently only implemented for splunk >= 7.2

Based on description of algorithm in this python based project.
https://github.com/HurricaneLabs/splunksecrets
@alexjfisher alexjfisher force-pushed the compare_values_after_decrypting branch from 909ac25 to 24a0da4 Compare April 9, 2019 08:22
@alexjfisher
Copy link
Member Author

Quick question: would it be possible for Puppet to encrypt the values in a way that Splunk finds acceptable, so as to be more declarative / less subject to changes in Splunk?

Quick question, long answer. :)

TL:DR
I've spent some time thinking about this, but think it'd actually end up being quite complicated. The algorithm itself isn't especially tricky, but the implementation could be,

Via a function...
This forces you to manage the content of the splunks.secret file (you wouldn't want to expose it as a fact.) You also need to decide how to generate the Initialisation Vector (16 bytes of data). AFAIK, it doesn't need to be random, but it does have to be unique per use. At the same time, you'd want the function to output the same value every run (maybe not required if also incorporating this change?). You could combine fqdn_rand with a seed that users supplied and put the onus on them for it being different for each value being encrypted.

In the type...
This could be better as you can generate a random IV on the fly and use the splunks.secret file that splunk generates. But the secrets file doesn't exist until the service is started, so it won't be available on the first run. If it's not there, you'd have to write the values unencrypted and by the second run, splunk will have already performed the encryption itself.

I'm not actually sure either solution would be less subject to changes in Splunk. Perhaps even the reverse. For instance, you'd still have to make very sure you were using the correct algorithm based on installed splunk version. (There are currently 2. See https://github.com/HurricaneLabs/splunksecrets).

With all that said, if anyone wants a go at implementing a function or some munging in the type, I'd be interested in seeing what they came up with. PRs welcome and all that! :)

@bastelfreak bastelfreak merged commit f1e973e into voxpupuli:master Apr 9, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants