[MODULES-7608] purge_ssh_keys doesn't purge keys when multiple keys with same comment are in authorized_keys file Created: 2015/01/14  Updated: 2018/10/26

Status: Accepted
Project: Modules
Component/s: sshkeys_core
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Sebastian Reitenbach Assignee: Unassigned
Resolution: Unresolved Votes: 5
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

OpenBSD 5.7-beta, amd64, i386, ...
Clients and servers both on OpenBSD


Issue Links:
Duplicate
Template:
Epic Link: ssh_authorized_key Type/Provider Improvements
Team: Coremunity
QA Contact: Eric Thompson

 Description   

For all managed user accounts, I have:
purge_ssh_keys: true

However, on each puppet run, I see the warning:

Warning: /Ssh_authorized_key[root@wormhole.intern]: Cannot schedule without a schedule-containing catalog
Warning: /Ssh_authorized_key[sebastia@wormhole.intern]: Cannot schedule without a schedule-containing catalog

And those keys don't get purged.

I use saz-ssh module to manage the authorized_keys contents.
The keys that start with V4_* or V6_* in the comment are managed and pushed out to the client via that module. The others were there before,
and were expected to get purged.

  1. HEADER: This file was autogenerated at 2015-01-08 20:09:40 +0100
  2. HEADER: by puppet. While it can still be managed manually, it
  3. HEADER: is definitely not recommended.
    from="10.0.0.27" ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDPkwyOD0nt9ZCCZucBrWqtLEfRBcmK3PeaYVvwA3B5ezWvQdOSTUU4od2inD6yb723Zdov17yxGQo9ImywtkQV/EXKIxdWFOlfVGbxbqPhoEY2hQrBwK9OyLeyQnU3Iq7yzi4WIWCtl+ZOogxkg5u8pbq75dOJkgOEk/x7wfYU+P
    GcXXhtXc1hJUYlM9GMgZ3NCV4V1TFacPyclvmoDKWdYo6mNhecZz3XSs7r2oOCfa5N4CfAvb8pMgDJtKu8dZhmr6ac4mML6JzGhXkIZAILrO6cpRLQX+ONR+SqsmfhXsKhZjZPMadW53G2VV+Dp6kAvb1HIIqCxqCa3AB58FwD root@wormhole.intern
    from="2a01:4f8:100:818b:ffff::27" ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDPkwyOD0nt9ZCCZucBrWqtLEfRBcmK3PeaYVvwA3B5ezWvQdOSTUU4od2inD6yb723Zdov17yxGQo9ImywtkQV/EXKIxdWFOlfVGbxbqPhoEY2hQrBwK9OyLeyQnU3Iq7yzi4WIWCtl+ZOogxkg5u8pbq75
    dOJkgOEk/x7wfYU+PGcXXhtXc1hJUYlM9GMgZ3NCV4V1TFacPyclvmoDKWdYo6mNhecZz3XSs7r2oOCfa5N4CfAvb8pMgDJtKu8dZhmr6ac4mML6JzGhXkIZAILrO6cpRLQX+ONR+SqsmfhXsKhZjZPMadW53G2VV+Dp6kAvb1HIIqCxqCa3AB58FwD root@wormhole.intern
    from="10.0.0.37" ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC8gbP6RLzNVWD2hAI8ryl0qksU6+I0L8THRfo8/5gVwcMbkUmp5CV1VesUBnNdq9jA+si1A/5SGg1htdLDrgXdztgBtqQ6w2YwHsU2lkw2an4g2nNXCTqaWG7lcuGxCYxsEhpxZWZEgZNKIHyWnYCJE2AZdG8YLXOlECuND6h6r6
    4FL42a/02jsYopwkCgJ41qdo+LZMV7u83Ga26gQPrBrFNYJ6VIfrC2TpaE80BOEzg2aWzmGL/OU8cFZQjibzgDMu7c+Qhux3bcCAuiPlJy62vDetc6QryLQ7+z1zuav3hP+hzttpffNrXWIhDK8b4uDe9jlgdptEIb6FoYASAr sebastia@wormhole.intern
    from="2a01:4f8:100:818b:ffff::37" ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC8gbP6RLzNVWD2hAI8ryl0qksU6+I0L8THRfo8/5gVwcMbkUmp5CV1VesUBnNdq9jA+si1A/5SGg1htdLDrgXdztgBtqQ6w2YwHsU2lkw2an4g2nNXCTqaWG7lcuGxCYxsEhpxZWZEgZNKIHyWnYCJE2AZd
    G8YLXOlECuND6h6r64FL42a/02jsYopwkCgJ41qdo+LZMV7u83Ga26gQPrBrFNYJ6VIfrC2TpaE80BOEzg2aWzmGL/OU8cFZQjibzgDMu7c+Qhux3bcCAuiPlJy62vDetc6QryLQ7+z1zuav3hP+hzttpffNrXWIhDK8b4uDe9jlgdptEIb6FoYASAr sebastia@wormhole.intern
    from="10.0.0.37" ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC8gbP6RLzNVWD2hAI8ryl0qksU6+I0L8THRfo8/5gVwcMbkUmp5CV1VesUBnNdq9jA+si1A/5SGg1htdLDrgXdztgBtqQ6w2YwHsU2lkw2an4g2nNXCTqaWG7lcuGxCYxsEhpxZWZEgZNKIHyWnYCJE2AZdG8YLXOlECuND6h6r6
    4FL42a/02jsYopwkCgJ41qdo+LZMV7u83Ga26gQPrBrFNYJ6VIfrC2TpaE80BOEzg2aWzmGL/OU8cFZQjibzgDMu7c+Qhux3bcCAuiPlJy62vDetc6QryLQ7+z1zuav3hP+hzttpffNrXWIhDK8b4uDe9jlgdptEIb6FoYASAr V4_ROOTsebastia@wormhole.intern
    from="2a01:4f8:100:818b:ffff::37" ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC8gbP6RLzNVWD2hAI8ryl0qksU6+I0L8THRfo8/5gVwcMbkUmp5CV1VesUBnNdq9jA+si1A/5SGg1htdLDrgXdztgBtqQ6w2YwHsU2lkw2an4g2nNXCTqaWG7lcuGxCYxsEhpxZWZEgZNKIHyWnYCJE2AZd
    G8YLXOlECuND6h6r64FL42a/02jsYopwkCgJ41qdo+LZMV7u83Ga26gQPrBrFNYJ6VIfrC2TpaE80BOEzg2aWzmGL/OU8cFZQjibzgDMu7c+Qhux3bcCAuiPlJy62vDetc6QryLQ7+z1zuav3hP+hzttpffNrXWIhDK8b4uDe9jlgdptEIb6FoYASAr V6_ROOTsebastia@wormhole.intern
    from="10.0.0.27" ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDPkwyOD0nt9ZCCZucBrWqtLEfRBcmK3PeaYVvwA3B5ezWvQdOSTUU4od2inD6yb723Zdov17yxGQo9ImywtkQV/EXKIxdWFOlfVGbxbqPhoEY2hQrBwK9OyLeyQnU3Iq7yzi4WIWCtl+ZOogxkg5u8pbq75dOJkgOEk/x7wfYU+P
    GcXXhtXc1hJUYlM9GMgZ3NCV4V1TFacPyclvmoDKWdYo6mNhecZz3XSs7r2oOCfa5N4CfAvb8pMgDJtKu8dZhmr6ac4mML6JzGhXkIZAILrO6cpRLQX+ONR+SqsmfhXsKhZjZPMadW53G2VV+Dp6kAvb1HIIqCxqCa3AB58FwD V4_ROOTroot@wormhole.intern
    from="2a01:4f8:100:818b:ffff::27" ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDPkwyOD0nt9ZCCZucBrWqtLEfRBcmK3PeaYVvwA3B5ezWvQdOSTUU4od2inD6yb723Zdov17yxGQo9ImywtkQV/EXKIxdWFOlfVGbxbqPhoEY2hQrBwK9OyLeyQnU3Iq7yzi4WIWCtl+ZOogxkg5u8pbq75
    dOJkgOEk/x7wfYU+PGcXXhtXc1hJUYlM9GMgZ3NCV4V1TFacPyclvmoDKWdYo6mNhecZz3XSs7r2oOCfa5N4CfAvb8pMgDJtKu8dZhmr6ac4mML6JzGhXkIZAILrO6cpRLQX+ONR+SqsmfhXsKhZjZPMadW53G2VV+Dp6kAvb1HIIqCxqCa3AB58FwD V6_ROOTroot@wormhole.intern


 Comments   
Comment by Sebastian Reitenbach [ 2015/01/14 ]

I made another quick test, and found that, the cause of the problem seems to be that multiple keys have the same comment.

What I did was to remove one of the keys that had "root@wormhole.intern" as comment, and reran the puppet client.

The remaining key was purged:

(/Stage[main]/Accounts/Ssh_authorized_key[root@wormhole.intern]/ensure) removed

and only one remaining warning in the logs:
/Ssh_authorized_key[sebastia@wormhole.ds9]) Cannot schedule without a schedule-containing catalog

Comment by Andy Miller [ 2015/02/24 ]

This issue is impacting me as well. I have two keys, RSA and DSS for accessing a systems (for legacy reasons). Since they're for accessing the same system, they have the same comment. The config is vended to me for compliance reasons, so even if I go about all my serves and fix it, the problem will routinely come up. A more unique way of tracking these would be great. Perhaps by public key fingerprint?

Comment by Jason Corley [ 2015/03/27 ]

I made a simple vagrant test for this. files I used were:

  • Vagrantfile:

    VAGRANTFILE_API_VERSION = "2"
     
    Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
      config.vm.box = "puppetlabs/centos-7.0-64-puppet"
      config.vm.box_url = "https://atlas.hashicorp.com/puppetlabs/boxes/centos-7.0-64-puppet"
      config.vm.provision "puppet" do |puppet|
        puppet.module_path = "modules"
      end
    end
    

  • manifests/default.pp:

    node default {
      include ::accounts
    }
    

  • modules/accounts/manifests/init.pp:

    class accounts {
      group { 'testuser':
        ensure => present,
        gid    => 5000,
      }
     
      user { 'testuser':
        ensure         => present,
        purge_ssh_keys => true,
        comment        => 'Test User',
        gid            => '5000',
        uid            => '5000',
        home           => '/home/testuser',
        shell          => '/bin/bash',
        managehome     => true,
        require        => Group['testuser'],
      }
     
      ssh_authorized_key { 'testuser@bogusemail':
        ensure => present,
        type   => 'ssh-rsa',
        user   => 'testuser',
        key    => 'ABC123',
      }
    }
    

run 'vagrant up' followed by 'vagrant provision'. when the user is created use 'vagrant ssh' and run the following to add one line to /home/testuser/.ssh/authorized_keys:

sudo sh -c "echo 'ssh-dss 987XYZ bogusemail@testuser' >> /home/testuser/.ssh/authorized_keys"

log out and run 'vagrant provision' again. output should look something like this:

$ vagrant provision
==> default: Running provisioner: puppet...
==> default: Running Puppet with default.pp...
==> default: Notice: Compiled catalog for localhost.nc.rr.com in environment production in 0.34 seconds
==> default: Notice: /Stage[main]/Accounts/Ssh_authorized_key[bogusemail@testuser]/ensure: removed
==> default: Notice: Finished catalog run in 0.03 seconds

now run 'vagrant ssh' again and this time add the bogus entry twice:

sudo sh -c "printf 'ssh-dss 987XYZ bogusemail@testuser\nssh-dss 987XYZ bogusemail@testuser\n' >> /home/testuser/.ssh/authorized_keys"

this time 'vagrant provision' will not function and will look something like this:

$ vagrant provision
==> default: Running provisioner: puppet...
==> default: Running Puppet with default.pp...
==> default: Notice: Compiled catalog for localhost.nc.rr.com in environment production in 0.29 seconds
==> default: Warning: /Ssh_authorized_key[bogusemail@testuser]: Cannot schedule without a schedule-containing catalog
==> default: Notice: Finished catalog run in 0.01 seconds

Comment by Don Lind [ 2015/05/26 ]

This affects 3.7.1 as well.

Comment by Christoph Tavan [ 2016/04/26 ]

Are there any plans to fix this issue? Being unable to reliably purge unmanaged SSH keys has a potential security impact so it would be great to improve this.

Comment by Tessa Lau [ 2017/02/02 ]

Affects me too, in Puppet 4.6. We are migrating from a single user account with shared access (everyone has their SSH key into the authorized keys file) to individual user accounts. I can't seem to make that work because of this bug. Any suggested workarounds?

Comment by Russell Howe [ 2017/06/06 ]

I have also observed the same warning in Puppet's output. It looks like this happens if you have keys with spaces in their comments. The warning is not always given when there are problems, so puppet may silently be preserving SSH keys on your hosts which you would expect to be removed.

Here's a script to exercise this bug (tested on puppet 3.6 - don't ask!)

#!/bin/bash
 
set -ux
 
U=alice
H=/home/$U
A_KEYS=$H/.ssh/authorized_keys
 
userdel -r "$U" || :
 
# Keys with comments containing spaces where the last word is the same
puppet apply --execute "
ssh_authorized_key { ['test key', 'another test key']:
  user => '$U', key => 'x', type => 'ssh-rsa'
}
user { '${U}': ensure => present, home => '${H}', managehome => true }"
echo "Should contain: 'test key' and 'another test key'"
cat "$A_KEYS"
puppet apply --execute "
ssh_authorized_key { ['test key2', 'another test key2']:
  user => '${U}', key => 'x', type => 'ssh-rsa'
}
user { '${U}': ensure => present, home => '${H}', purge_ssh_keys => true }"
echo "Should contain: 'test key2' and 'another test key2'"
cat "$A_KEYS"
puppet apply --execute "
ssh_authorized_key { ['test key2', 'another test key2']:
  user => '${U}', key => 'x', type => 'ssh-rsa'
}
user { '${U}': ensure => present, home => '${H}', purge_ssh_keys => true }"
echo "Should contain: 'test key2' and 'another test key2'"
cat "$A_KEYS"
rm -f "$A_KEYS"
 
# A mixture of keys with comments containing spaces where the last word is the same and single-word comments which match the last word in multi-word comments
puppet apply --execute "
ssh_authorized_key { ['test key', 'test key2']:
  user => '${U}', key => 'x', type => 'ssh-rsa'
}"
echo "Should contain: 'test key' and 'test key2'"
cat "$A_KEYS"
puppet apply --execute "
ssh_authorized_key { ['test key3', 'test key4']:
  user => '${U}', key => 'x', type => 'ssh-rsa'
}
user { '${U}': ensure => present, home => '${H}', purge_ssh_keys => true }"
echo "Should contain: 'test key3' and 'test key4'"
cat "$A_KEYS"
puppet apply --execute "
ssh_authorized_key { ['key3', 'key4']:
  user => '${U}', key => 'x', type => 'ssh-rsa'
}
user { '${U}': ensure => present, home => '${H}', purge_ssh_keys => true }"
echo "Should contain: 'test key3' and 'test key4'"
cat "$A_KEYS"
rm -f "$A_KEYS"
 
# Keys with comments not containing whitespace
puppet apply --execute "
ssh_authorized_key { ['key', 'key2']:
  user => '${U}', key => 'x', type => 'ssh-rsa'
}"
echo "Should contain: 'key' and 'key2'"
cat "$A_KEYS"
puppet apply --execute "
ssh_authorized_key { ['key3', 'key4']:
  user => '${U}', key => 'x', type => 'ssh-rsa'
}
user { '${U}': ensure => present, home => '${H}', purge_ssh_keys => true }"
echo "Should contain: 'key3' and 'key4'"
cat "$A_KEYS"
puppet apply --execute "
ssh_authorized_key { ['key3', 'key4']:
  user => '${U}', key => 'x', type => 'ssh-rsa'
}
user { '${U}': ensure => present, home => '${H}', purge_ssh_keys => true }"
echo "Should contain: 'key3' and 'key4'"
cat "$A_KEYS"

Comment by Russell Howe [ 2017/06/06 ]

Looks like the keys with comments containing spaces bug was fixed in 3.7: PUP-2737

Generated at Sun Jan 19 19:34:38 PST 2020 using JIRA 7.7.1#77002-sha1:e75ca93d5574d9409c0630b81c894d9065296414.