Possible to copy ssh key from node A to node B?

1,832 views
Skip to first unread message

Sandra Schlichting

unread,
Aug 30, 2012, 9:41:20 AM8/30/12
to puppet...@googlegroups.com
Hi,

I would like to write a class that can copy /root/.ssh/id_dsa from node A to node B.

class sshkeycopy {
   exec {"ssh-keygen -q -t dsa -f /root/.ssh/id_dsa -P ''":
      creates => "/root/.ssh/id_dsa.pub"
   }
   file {"/root/.ssh/id_dsa":
      mode   => "644",
      owner  => root,
      group  => root,
   }
   exec {"???":
      subscribe => Exec["ssh-keygen -q -t dsa -f /root/.ssh/id_dsa -P ''"],
      refreshonly => true
   }
}

The puppet master can login to node B without passphrase and append a key

cat .ssh/id_rsa.pub | ssh b@B 'cat >> .ssh/authorized_keys'

So the question is how to copy /root/.ssh/id_dsa.pub from node A to the puppet master and then push it to node B?

Hugs,
Sandra

Eric Shamow

unread,
Aug 30, 2012, 9:42:53 AM8/30/12
to puppet...@googlegroups.com
Sandra,

On the run so no time to write up a quick example - but take a look at exported resources.  There's a design patterns page --


These are designed to do what you're looking for.

-Eric

--

Eric Shamow
Professional Services

Join us for PuppetConf 2012 at the Mission Bay Convention Center in San Francisco, California on September 27th and 28th --> http://bit.ly/pcsig12

--
You received this message because you are subscribed to the Google Groups "Puppet Users" group.
To view this discussion on the web visit https://groups.google.com/d/msg/puppet-users/-/UZoM9krZK74J.
To post to this group, send email to puppet...@googlegroups.com.
To unsubscribe from this group, send email to puppet-users...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.

Sandra Schlichting

unread,
Aug 30, 2012, 11:27:58 AM8/30/12
to puppet...@googlegroups.com
Hi Eric
 
On the run so no time to write up a quick example - but take a look at exported resources.  There's a design patterns page --


These are designed to do what you're looking for.
 
Wow. That looks very complicated. =) I suppose it requires a database backend?

Does there exist a SSH key management module, where the puppet master generates the private and public keys and pushes them to the nodes?

Hugs,
Sandra

Matthew Burgess

unread,
Aug 30, 2012, 11:39:34 AM8/30/12
to puppet...@googlegroups.com
On 8/30/12, Sandra Schlichting <littles...@gmail.com> wrote:
> Does there exist a SSH key management module, where the puppet master
> generates the private and public keys and pushes them to the nodes?

There's an sshauth module at
http://projects.reductivelabs.com/projects/puppet/wiki/Module_Ssh_Auth_Patterns
that I've used successfully on a 2.7.x puppetmaster. It handles
public & private key generation and exchange, but doesn't handle
known_hosts. It doesn't require a DB backend though; the keys are
stored on the puppetmaster and just pushed out to nodes that need
them.

There are a number of ssh related modules on the forge
(http://forge.puppetlabs.com/modules?q=ssh) but I've not used any of
them so can't comment on their usefulness or robustness.

Hope this helps,

Matt.

Calvin Walton

unread,
Aug 30, 2012, 11:40:38 AM8/30/12
to puppet...@googlegroups.com
On Thu, 2012-08-30 at 09:42 -0400, Eric Shamow wrote:
> On Thursday, August 30, 2012 at 9:41 AM, Sandra Schlichting wrote:
>
> > Hi,
> >
> > I would like to write a class that can copy /root/.ssh/id_dsa from node A to node B.
> >
> >
> > The puppet master can login to node B without passphrase and append a key
> >
> > cat .ssh/id_rsa.pub | ssh b@B 'cat >> .ssh/authorized_keys'
> >
> > So the question is how to copy /root/.ssh/id_dsa.pub from node A to the puppet master and then push it to node B?

> On the run so no time to write up a quick example - but take a look at
> exported resources. There's a design patterns page --
>
> http://docs.puppetlabs.com/guides/exported_resources.html
>
> These are designed to do what you're looking for.

Exported resources can do most of what you want, but there's still one
key problem that they don't solve: Getting the ssh public key
(/root/.ssh/id_rsa.pub or whatever) from the node to the puppet master.

The only solution that I've seen for this so far is to write a custom
fact which would read the key from root/.ssh/id_rsa.pub and store it in
a variable like $root_ssh_id_rsa_pub or something - but that requires
that you run puppet twice! First to generate the key, then second to
read the key from the fact and publish the exported resource.

Does anyone have any better ideas?

I currently have a really nasty hack with a generator script that runs
on the puppet master, which works, but is a bit fragile - and will fail
if I ever want to scale to multiple puppet masters. It looks like this:
https://gist.github.com/3531206

--
Calvin Walton <calvin...@kepstin.ca>

Chad Huneycutt

unread,
Aug 30, 2012, 1:39:33 PM8/30/12
to puppet...@googlegroups.com
Here is the script we use to do the same. I am not proud of all the
locking stuff. Not sure if it is necessary or not, but it works.
Just set $hostkeydir and $userkeydir for your environment, and it will
manage ssh host keys. It will also do user keys, but I didn't put
examples of that in the gist.

git://gist.github.com/3534504.git

--
Chad M. Huneycutt

Sandra Schlichting

unread,
Aug 31, 2012, 5:21:17 AM8/31/12
to puppet...@googlegroups.com
Hi Chad


Here is the script we use to do the same.  I am not proud of all the
locking stuff.  Not sure if it is necessary or not, but it works.
Just set $hostkeydir and $userkeydir for your environment, and it will
manage ssh host keys.  It will also do user keys, but I didn't put
examples of that in the gist.

git://gist.github.com/3534504.git

It looks very impressive, but I can't really figure out how to use it.

 ~/ssh# ./sshkeys.pl --dsa --host=ttt.e.com --user=rrr --genknownhosts 
Unable to open lock file at ./sshkeys.pl line 239.
~/ssh# ./sshkeys.pl --dsa --host=ttt.e.com --user=rrr --genknownhosts --addauth
Unknown option: addauth

I have set

our $hostkeydir = '/root/ssh/hostkeys';
our $userkeydir = '/root/ssh/userkeys';
our $known_hosts_copy = '/root/ssh/gen/ssh_known_hosts';

If you could share the puppet module you use, it would be very helpful =)

Hugs,
Sandra

Sandra Schlichting

unread,
Aug 31, 2012, 8:32:09 AM8/31/12
to puppet...@googlegroups.com, matthew....@googlemail.com
There's an sshauth module at
http://projects.reductivelabs.com/projects/puppet/wiki/Module_Ssh_Auth_Patterns
that I've used successfully on a 2.7.x puppetmaster.  It handles
public & private key generation and exchange, but doesn't handle
known_hosts.  It doesn't require a DB backend though; the keys are
stored on the puppetmaster and just pushed out to nodes that need
them.

That sounds exactly what I need =)

About known_hosts. So that just means I have to login the first time myself, and answer "yes" to the fingerprint?
 
There are a number of ssh related modules on the forge
(http://forge.puppetlabs.com/modules?q=ssh) but I've not used any of
them so can't comment on their usefulness or robustness.

This one also looks good

Have you tried that one?

Hugs,
Sandra


David Schmitt

unread,
Aug 31, 2012, 8:46:35 AM8/31/12
to puppet...@googlegroups.com
On 31.08.2012 14:32, Sandra Schlichting wrote:
> There's an sshauth module at
> http://projects.reductivelabs.com/projects/puppet/wiki/Module_Ssh_Auth_Patterns
> <http://projects.reductivelabs.com/projects/puppet/wiki/Module_Ssh_Auth_Patterns>
>
> that I've used successfully on a 2.7.x puppetmaster. It handles
> public & private key generation and exchange, but doesn't handle
> known_hosts. It doesn't require a DB backend though; the keys are
> stored on the puppetmaster and just pushed out to nodes that need
> them.
>
>
> That sounds exactly what I need =)
>
> About known_hosts. So that just means I have to login the first time
> myself, and answer "yes" to the fingerprint?

Err, no. In a well-maintained environment, it should never be necessary
to manually approve a host key.

Usually you should always distribute all host keys to all clients with
one of the common @@ssh_key Export/Collect patterns. That is totally
unrelated to authentication though.


Regards, D

Sandra Schlichting

unread,
Aug 31, 2012, 9:38:03 AM8/31/12
to puppet...@googlegroups.com
Err, no. In a well-maintained environment, it should never be necessary
to manually approve a host key.

I would prefer that too.
 
Usually you should always distribute all host keys to all clients with
one of the common @@ssh_key Export/Collect patterns. That is totally
unrelated to authentication though.

Can it be done without introducing a database?

I would really like not introduce a database to my puppet master.


jcbollinger

unread,
Aug 31, 2012, 10:11:31 AM8/31/12
to puppet...@googlegroups.com
It depends a bit on how you define "database".   Certainly you need some kind of data store on the master in which to record the keys you want to distribute.  To use exported resources for the job, that data store must be managed by a relational DBMS.
 
If you're willing to put a fair amount of effort into it, however, then you could likely work up something that recorded keys in an hiera-accessible data file, or even in a Puppet manifest file.  The Puppet code for distributing the keys in this case wouldn't need to be much more complicated, but you'd have that whole custom <something> for managing the keys.
 
John
 

Chad Huneycutt

unread,
Aug 31, 2012, 11:16:43 AM8/31/12
to puppet...@googlegroups.com
Sorry, Sandra, I started to add a comment at the bottom with usage,
but apparently I never saved it. Although the script can do user keys
as well, this just addresses host keys. I have a cron script that
generates the known hosts file as well:

0,10,20,30,40,50 * * * * /tr01/scripts/sshkeys.pl --genknownhosts

The script will either retrieve the key if it already exists, or
generate a new one if it doesn't. $ccbp_realname is just the fqdn.

class ssh::server::rh {
$rsahostkey = generate("$pm_scripts/sshkeys.pl", "--private",
"--rsa", "--host", "$ccbp_realname")
$rsahostkeypub = generate("$pm_scripts/sshkeys.pl", "--rsa",
"--host", "$ccbp_realname")
$dsahostkey = generate("$pm_scripts/sshkeys.pl", "--private",
"--dsa", "--host", "$ccbp_realname")
$dsahostkeypub = generate("$pm_scripts/sshkeys.pl", "--dsa",
"--host", "$ccbp_realname")

file { "/etc/ssh/ssh_host_rsa_key":
content => $rsahostkey,
mode => 0400, owner => root, group => root,
}

file { "/etc/ssh/ssh_host_rsa_key.pub":
content => $rsahostkeypub,
mode => 0444, owner => root, group => root,
}

file { "/etc/ssh/ssh_host_dsa_key":
content => $dsahostkey,
mode => 0400, owner => root, group => root,
}

file { "/etc/ssh/ssh_host_dsa_key.pub":
content => $dsahostkeypub,
mode => 0444, owner => root, group => root,
> --
> You received this message because you are subscribed to the Google Groups
> "Puppet Users" group.
> To view this discussion on the web visit
> https://groups.google.com/d/msg/puppet-users/-/vR7zhEKP9FoJ.
>
> To post to this group, send email to puppet...@googlegroups.com.
> To unsubscribe from this group, send email to
> puppet-users...@googlegroups.com.
> For more options, visit this group at
> http://groups.google.com/group/puppet-users?hl=en.



--
Chad M. Huneycutt

David Schmitt

unread,
Aug 31, 2012, 5:08:27 PM8/31/12
to puppet...@googlegroups.com
As John said, some kind of store'll be unavoidable. If you're concerned
about performance, puppetdb seems the way to go. I've had awesome
results compared to classic storeconfig.

If you're generally ill-disposed re RDBMS on your puppetmaster, you'll
probably go best by generating all keys on the master and push the
processed files from there to the nodes. For one site, I've whipped up
that solution in a few hours, complete with puppet integration: a
puppet/ruby function checks whether the key is already available or
needs to be created, another function creates the know_hosts.

The downside of the second method is that you collect all your private
keys on the puppet master. Not that that would make any difference in
case of a break-in on your puppetmaster...


Best Regards, David

Sandra Schlichting

unread,
Sep 4, 2012, 10:37:50 AM9/4/12
to puppet...@googlegroups.com
Hi Chad
 
Sorry, Sandra, I started to add a comment at the bottom with usage,
but apparently I never saved it.  Although the script can do user keys
as well, this just addresses host keys.  I have a cron script that
generates the known hosts file as well:
[snip]

Wow. Easy and simple solution to a complex problem.

Thanks for your scripts =)

Hugs,
Sandra

Reply all
Reply to author
Forward
0 new messages