New server unable to fetch configuration from Puppetmaster due to some ssl error

Solution 1:

Concise answer

The issue CRL is not yet valid for indicates that the time between the Puppet-agent and the Puppetmaster is out of sync. Sync the time (NTP). Remove the certificate from the Puppet-agent and Puppetmaster as well and run Puppet on the agent.


Comprehensive answer

CRL is not yet valid for resides in the following snippet.

The following test code snippet describes what causes the issue:

it 'includes the CRL issuer in the verify error message' do
  crl = OpenSSL::X509::CRL.new
  crl.issuer = OpenSSL::X509::Name.new([['CN','Puppet CA: puppetmaster.example.com']])
  crl.last_update = Time.now + 24 * 60 * 60
  ssl_context.stubs(:current_crl).returns(crl)

  subject.call(false, ssl_context)
  expect(subject.verify_errors).to eq(["CRL is not yet valid for /CN=Puppet CA: puppetmaster.example.com"])
end

ssl_context

let(:ssl_context) do
  mock('OpenSSL::X509::StoreContext')
end

subject

subject do
  described_class.new(ssl_configuration,
  ssl_host)
end

The code includes snippets from the OpenSSL::X509::CRL class.

issuer=(p1)

               static VALUE
ossl_x509crl_set_issuer(VALUE self, VALUE issuer)
{
    X509_CRL *crl;

    GetX509CRL(self, crl);

    if (!X509_CRL_set_issuer_name(crl, GetX509NamePtr(issuer))) { /* DUPs name */
        ossl_raise(eX509CRLError, NULL);
    }
    return issuer;
}

last_update=(p1)

               static VALUE
ossl_x509crl_set_last_update(VALUE self, VALUE time)
{
    X509_CRL *crl;
    time_t sec;

    sec = time_to_time_t(time);
    GetX509CRL(self, crl);
    if (!X509_time_adj(crl->crl->lastUpdate, 0, &sec)) {
        ossl_raise(eX509CRLError, NULL);
    }

    return time;
}

The last_updated time will be the current time plus an additional day and will be passed to the subject function that calls the call function that resides in the default_validator class.

class Puppet::SSL::Validator::DefaultValidator #< class Puppet::SSL::Validator
  attr_reader :peer_certs
  attr_reader :verify_errors
  attr_reader :ssl_configuration

  FIVE_MINUTES_AS_SECONDS = 5 * 60

  def initialize(
    ssl_configuration = Puppet::SSL::Configuration.new(
    Puppet[:localcacert], {
      :ca_auth_file => Puppet[:ssl_client_ca_auth]
    }),

    ssl_host = Puppet::SSL::Host.localhost)
    reset!
    @ssl_configuration = ssl_configuration
    @ssl_host = ssl_host
  end

  def call(preverify_ok, store_context)
    if preverify_ok
      ...
    else
      ...
      crl = store_context.current_crl
      if crl
        if crl.last_update && crl.last_update < Time.now + FIVE_MINUTES_AS_SECONDS
          ...
        else
          @verify_errors << "#{error_string} for #{crl.issuer}"
        end
        ...
      end
    end
  end

If preverify_ok is false the else clause is applicable. As if crl.last_update && crl.last_update < Time.now + FIVE_MINUTES_AS_SECONDS results in false because the time has been stubbed with an additional day the else statement will be applicable. The evaluation of @verify_errors << "#{error_string} for #{crl.issuer}" results in CRL is not yet valid for /CN=Puppet CA: puppetmaster.example.com.

In order to solve the issue:

  1. Sync the time between the Puppet-agent and the Puppetmaster. Does the NTP server run (well) on both nodes?
  2. Remove or rename the complete ssl folder (/var/lib/puppet/ssl) from the agent.
  3. Revoke the cert from the master by issuing sudo puppet cert clean <fqdn-puppet-agent>
  4. Sign the cert if autosign is disabled
  5. Run puppet on the agent

In conclusion, the time on Puppet-agents and Puppetmaster should be synced all the time. Exceeding the maximum allowed deviation of 5 minutes will cause the issue.

Solution 2:

Ran into the same issue.

Our puppet setup is version controlled using GitHub, so every time we provision a new puppetmaster, we run into cert issues. Normally puppet ca --clean --all works, but we have found the following more reliable:

rm -rf $(puppet master --configprint ssldir)