Ask Your Question
1

Does one can impersonate any node by changing hostname and keeping the certificate?

asked 2017-05-14 17:22:56 -0500

mpellegrin gravatar image

updated 2017-05-15 12:58:46 -0500

smarlow gravatar image

Hi all,

I don't know if it's a bug or a feature, so I just ask.

I have a puppet master run by Passenger.

The configuration is populated from Hiera:

/etc/puppet/hiera.yaml:

---
:backends:
  - yaml
:yaml:
  :datadir: /etc/puppet/hieradata
:hierarchy:
  - "%{::environment}/%{::fqdn}"

The node was already granted (certificate signed) by Puppet Master, and "certname=goodnode" is written in the node configuration.

Auto signing is disabled, I sign manually every new node on the Master (puppet cert sign).

Today I was playing with the node, I changed the hostname. Previously "goodnode", I set it to "badnode", but I let "goodnode" in certname configuration (/etc/puppet/puppet.conf). "badnode" was an existing node in Hiera configuration, it is just an other node managed by the same Master.

After the change, the Puppet agent from "goodnode" then retrieved the "badnode" configuration, without any discussion. What?

Is it an expected behavior? Wasn't the Master supposed to check that the FQDN is correct (checking that the Common Name of the certificate and the FQDN matches) before dumping all the configuration (and secrets) to the node?

In my case, it means that if an attacker gets access to ANY node, it can then become a rogue node and download the configuration of ANY other node, just by changing the hostname, and keeping the certificate!

Is there a way to enforce a check on certificate CN on the master? Is the "%{::fqdn}" Fact safe for use in Hiera configuration?

Thanks in advance for your hints.

EDIT : I changed the fqdn fact by %{::trusted.certname} as the doc suggests, but now the nodes aren't provisioning, the syslog on the master says : "TrustedInformation expected a certificate, but none was given."

It must be giving a certificate, otherwise I would not have been able to sign it in the first place, right?

What am I doing wrong ?

edit retag flag offensive close merge delete

Comments

When you are using trusted information, that needs to included in the certificate generation part of the process. https://docs.puppet.com/puppet/4.10/ssl_attributes_extensions.htmlhttps://docs.puppet.com/puppet/4.10/lang_facts_and_builtin_vars.html#trusted-facts

DarylW gravatar imageDarylW ( 2017-05-15 10:43:38 -0500 )edit

2 Answers

Sort by ยป oldest newest most voted
1

answered 2017-05-15 11:16:51 -0500

mpellegrin gravatar image

updated 2017-05-15 12:38:46 -0500

Thanks for your answer.

My Puppet version is the one packaged for Debian Jessie version : 3.7.2-4

You are right about the Certificate, actually I was missing the X-Client-Cert header ( https://docs.puppet.com/puppetserver/latest/externalssltermination.html#x-client-cert )

I managed to handle it with a slightly different technique than the link you posted :

In Nginx :

passenger_set_header       X-Client-Cert    $ssl_client_cert;

In config.ru :

class SSL_Middleware
  def initialize(app, options = {})
    @app = app
    @options = options
  end

  def call(env)
    env["SSL_CLIENT_CERT"] = env["HTTP_X_CLIENT_CERT"].gsub(/\t/, "\n")
    env["HTTP_X_CLIENT_CERT"] = ''
    # continue processing
    @app.call(env)
  end
end
use SSL_Middleware

Which is simpler and less error-prone than the "26 char split" technique. By the way, my certificates had more than 26 lines.

A dirty print env["SSL_CLIENT_CERT"] in config.ru returns the right value and I do not have the TrustedInformation error in logs anymore.

But I still have problems with provisionning :

On nodes :

Error: Could not retrieve catalog from remote server: Error 400 on SERVER: Could not find data item classes in any Hiera data file and no default supplied at /etc/puppet/environments/production/manifests/site.pp:4 on node xxxx

It's like the trusted value was not defined. It behaves the same if I set only %{::certname} instead of %{::trusted.certname}.

Is there a way to dump the defined facts on the master at execution, to check if %{::certname} / %{::trusted.certname} is set ?

EDIT :

I finally managed to get it working.

I am using the Open Source version, so I was missing trusted_node_data = true in puppet.conf under [master] section https://docs.puppet.com/puppet/3.7/futurelangfactsandbuiltin_vars.html#trusted-facts .

After that, I was able to get it in manifests, but not in hiera.yaml.

To use the trustedarray in Hiera, I had to wrap it in a custom variable as said in : http://shanemadden.net/stackexchange-...

hiera.yaml :

:hierarchy:
  - "%{::environment}/%{::certname_trusted}"

site.pp :

# workaround until the $trusted hash can be used in hiera.. (https://tickets.puppetlabs.com/browse/HI-14)
$certname_trusted = $trusted['certname']

Thanks again for your answers.

edit flag offensive delete link more

Comments

You can run facter -p on the agent machine to get a list of all of the facts that it will send over. If you want to debug on the master I sometimes will run puppet master --no-daemonize --debug --masterport 18140 | tee ~/master.log, and run puppet agent -t --masterport 18140 --noop on the agent.

smarlow gravatar imagesmarlow ( 2017-05-15 11:28:22 -0500 )edit

The above commands will show the hiera lookup sequence in the master's debug logs and you should be able to redirect to the new port if you're not using SRV records. You could also save your facts to a file and feed them in along with your hiera config to the hiera command to simulate the lookup.

smarlow gravatar imagesmarlow ( 2017-05-15 11:32:35 -0500 )edit
1

Glad to see that you got it working. It's worth noting that the bug you listed was fixed in Hiera 2, which I believe began shipping with the first versions of Puppet 4. It's also worth noting that Puppet 3 is now EOL, and it probably makes sense to look at upgrading to version 4 (current is 4.10)

smarlow gravatar imagesmarlow ( 2017-05-15 13:06:03 -0500 )edit
1

answered 2017-05-15 10:52:39 -0500

smarlow gravatar image

updated 2017-05-15 11:25:45 -0500

What version of Puppet are you running?

Based on this I suspect that it is an issue with running the master on Passenger. You may be able to use certname instead of trusted.certname.

It might also make sense for you to switch to using Puppetserver instead of running under Passenger, as this is a more supported configuration for newer versions of Puppet.

edit flag offensive delete link more

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower

Stats

Asked: 2017-05-14 17:22:56 -0500

Seen: 50 times

Last updated: May 15