Creating authorized_keys for LDAP users

+1 to sssd. Especially combined with something like Authorized_Keys_Command/Authorized_Keys_Command_User (in sshd_config, if your distro supports it).

You may find this useful as a getting started point if you’re using Ubuntu and SimpleAD and/or can remove the SimpleAD-specific logic... It will soon have CentOS support, too:

On Mar 10, 2015, at 10:41 AM, Ed Ropple eropple@leaf.me wrote:

YMMV, but I'd reconsider the approach you're taking--"configuring users with LDAP" seems like the tail wagging the dog a little. I've had much better luck using SSSD to act as an authentication system that talks to LDAP instead. You can store public keys in your LDAP server, then, and SSSD will do the Right Thing. It's a huge step up over nslcd or ldapd.

I've used it on both CentOS and Ubuntu, with significant success.

Good luck!

-Ed

On Tue, Mar 10, 2015 at 10:15 AM, Morgan Blackthorne stormerider@gmail.com wrote:
So I'm actually looking to do this myself, though I want the config to be:

AuthorizedKeysFile "%h/.ssh/authorized_keys /etc/ssh/%u/authorized_keys"

That way they can use manual keys in addition to the ones I'll be having chef drop in place. However, I'm not currently managing /etc/ssh/sshd_config. What's the best way to modify just that one line? I'm a bit uneasy about trying to just cookbook_file that, given how many different Linux distributions we have (Oracle, Redhat, Debian, Ubuntu, CentOS, etc).

On Jan 26, 2015 4:15 PM, "Douglas Garstang" doug.garstang@gmail.com wrote:
Or... something like:

AuthorizedKeysFile /etc/ssh/authorized_keys/%u

in /etc/ssh/sshd_config. The users account doesn't need to exist first, and it's owned by root and managed by chef, not the user.

Doug.

On Mon, Jan 26, 2015 at 3:56 PM, Douglas Garstang doug.garstang@gmail.com wrote:
Actually, I think it's time for a script.

On Mon, Jan 26, 2015 at 3:55 PM, Douglas Garstang doug.garstang@gmail.com wrote:
So, it would seem this this is a general chef issue then. It's not an LDAP issue, or an ohai issue. It's a chef issue.

A workaround for this limitation sure would be nice. Configuring user with LDAP and then being able to create their ssh keys seems like a pretty standard use case.

Doug.

On Mon, Jan 26, 2015 at 3:52 PM, Noah Kantrowitz noah@coderanger.net wrote:
Chef and Ohai use the Etc library in Ruby, which in turn uses the standard getpw* and getgr* calls. These are configured by nsswitch.conf. If you go look this up, you'll see that that file is only read once for a given process and there is no universal way to clear the config. Some libcs offer non-standard calls for it, but I doubt any of those are exposed to Ruby.

--Noah

On Jan 26, 2015, at 3:29 PM, Douglas Garstang doug.garstang@gmail.com wrote:

Sorry to have to repeat myself, but I can't use 'owner' and 'group' on resources. Even thought LDAP is configured, chef isn't able to see the users and groups.

David suggested I reload ohai. I had no idea this was necessary or required, but I tried it anyway. I put this at the end of my ldap cookbook.

ohai "reload_passwd" do
plugin "etc"
end
log node['etc']['passwd']

What I am seeing, (I'm using vagrant), is that on the first chef run, the LDAP users are not in in the node structure. However, if I reprovision, (without making any changes), then the users ARE there.

In hindsight, isn't this just the typical node not being populated until after the chef run issue?

Doug.

On Mon, Jan 26, 2015 at 3:22 PM, Lamont Granquist lamont@chef.io wrote:
On 1/26/15 2:29 PM, Douglas Garstang wrote:

I'm having trouble setting up users authorized keys. A cookbook that runs earlier in the runlist sets up LDAP. However, due to reasons I don't understand, none of that user information is available during the chef run. I previously posted about this once before. As a result, I can't simply create files and directories and use 'owner' and 'group.

I came up with the below idea. I'm iterating over the ssh keys in a data bag and then for each user running a command as this user. That makes PAM do all the home directory setup for me. I create the ~/.ssh directory in a similar fashion, as the user. All works ok. However, I'm having an issue with adding the array of ssh_keys pulled from the data bag to the users authorized keys file.

include_recipe "slice-ldap"
bag = data_bag("ssh-keys")
for item in bag do
user = data_bag_item('ssh-keys', item)
user_name = user['id']
ssh_keys = user['ssh_keys']
execute "create_home_#{user_name}" do
command "su - #{user_name} -c "ls""
creates "/home/#{user_name}"
notifies :run, "execute[create_ssh_dir_#{user_name}]", :immediately
end
execute "create_ssh_dir_#{user_name}" do
command "su - #{user_name} -c "mkdir /home/#{user_name}/.ssh""
notifies :run, "execute[install_public_rsa_#{user_name}]", :immediately
creates "/home/#{user_name}/.ssh"
end
ssh_keys.each_with_index do |k, index|
log "k = #{k}"
execute "install_public_rsa_#{user_name}" do
command "su - #{user_name} -c "echo '#{k}' >> /home/#{user_name}/.ssh/authorized_keys""
action :nothing
end
end
end

However, I'm having an issue with adding the array of ssh_keys pulled from the data bag to the users authorized keys file. The loop at the end does this, but chef also gives me this warning:

==> default: [2015-01-26T22:23:47+00:00] WARN: Previous execute[install_public_rsa_doug]: /tmp/vagrant-chef-3/chef-solo-1/cookbooks/slice-ssh-keys/recipes/default.rb:38:in block (2 levels) in from_file' ==> default: [2015-01-26T22:23:47+00:00] WARN: Current execute[install_public_rsa_doug]: /tmp/vagrant-chef-3/chef-solo-1/cookbooks/slice-ssh-keys/recipes/default.rb:38:in block (2 levels) in from_file'

Apart from the warning, only the last ssh keys is being added to the authorized_keys file. Even though I'm using echo and >>, the last one is not there. The log statement shows each key, so I know the loop is iterating over both. What gives?

Doug

Yeah the warning is trying to tell you the problem. You're defining multiple resources called execute[install_public_rsa_doug] and the resource collection and the way notifies and subscribes is implemented requires unique names. So you're getting resource cloning and you're only notifying one of those blocks. You could add the index to then name and then subscribe to the previous resources:

ssh_keys.each_with_index do |k, index|
log "k = #{k}"
execute "install_public_rsa_#{user_name}#{index}" do
command "su - #{user_name} -c "echo '#{k}' >> /home/#{user_name}/.ssh/authorized_keys""
subscribes :run, "execute[#{create_ssh_dir
#{user_name}]"
subscribes :run, "execute[#{create_home_#{user_name}]"
action :nothing
end
end

You'll be way better off just doing this though:

file "/home/#{user_name}" do
owner user_name
group user_name # or "users" or whatever
mode "0600"
end

file "/home/#{user_name}/.ssh" do
owner user_name
group user_name
mode "0600"
end

file "/home/#{user_name}/.ssh/authorized_keys" do
owner user_name
group user_name
mode "0600"
content ssh_keys.join("\n")
end

That's idempotent, you don't need the action :nothing or any notifications or subscriptions, you can push new keys out and it'll correctly update, gets the job done with fewer resources, etc. Similarly executing to su is a huge antipattern, so you can replace the rest of that.

--
Regards,

Douglas Garstang
http://www.linkedin.com/in/garstang
Email: doug.garstang@gmail.com
Cell: +1-805-340-5627

--
Regards,

Douglas Garstang
http://www.linkedin.com/in/garstang
Email: doug.garstang@gmail.com
Cell: +1-805-340-5627

--
Regards,

Douglas Garstang
http://www.linkedin.com/in/garstang
Email: doug.garstang@gmail.com
Cell: +1-805-340-5627

--
Regards,

Douglas Garstang
http://www.linkedin.com/in/garstang
Email: doug.garstang@gmail.com
Cell: +1-805-340-5627

And our shop has not had much luck with SSSD, personally. We use a mix of
RHEL, Oracle Linux, CentOS, Amazon Linux, Ubuntu, and Debian. I'd rather
keep the SSH key piece separate from the LDAP piece... we already have an
LDAP config that works.

--
~~ StormeRider ~~

"Every world needs its heroes [...] They inspire us to be better than we
are. And they protect from the darkness that's just around the corner."

(from Smallville Season 6x1: "Zod")

On why I hate the phrase "that's so lame"... http://bit.ly/Ps3uSS

On Tue, Mar 10, 2015 at 7:41 AM, Ed Ropple eropple@leaf.me wrote:

YMMV, but I'd reconsider the approach you're taking--"configuring users
with LDAP" seems like the tail wagging the dog a little. I've had much
better luck using SSSD to act as an authentication system that talks to
LDAP instead. You can store public keys in your LDAP server, then, and SSSD
will do the Right Thing. It's a huge step up over nslcd or ldapd.

I've used it on both CentOS and Ubuntu, with significant success.

Good luck!

-Ed

On Tue, Mar 10, 2015 at 10:15 AM, Morgan Blackthorne <
stormerider@gmail.com> wrote:

So I'm actually looking to do this myself, though I want the config to be:

AuthorizedKeysFile "%h/.ssh/authorized_keys

/etc/ssh/%u/authorized_keys"

That way they can use manual keys in addition to the ones I'll be having
chef drop in place. However, I'm not currently managing
/etc/ssh/sshd_config. What's the best way to modify just that one line? I'm
a bit uneasy about trying to just cookbook_file that, given how many
different Linux distributions we have (Oracle, Redhat, Debian, Ubuntu,
CentOS, etc).
On Jan 26, 2015 4:15 PM, "Douglas Garstang" doug.garstang@gmail.com
wrote:

Or... something like:

AuthorizedKeysFile /etc/ssh/authorized_keys/%u

in /etc/ssh/sshd_config. The users account doesn't need to exist first,
and it's owned by root and managed by chef, not the user.

Doug.

On Mon, Jan 26, 2015 at 3:56 PM, Douglas Garstang <
doug.garstang@gmail.com> wrote:

Actually, I think it's time for a script.

On Mon, Jan 26, 2015 at 3:55 PM, Douglas Garstang <
doug.garstang@gmail.com> wrote:

So, it would seem this this is a general chef issue then. It's not an
LDAP issue, or an ohai issue. It's a chef issue.

A workaround for this limitation sure would be nice. Configuring user
with LDAP and then being able to create their ssh keys seems like a pretty
standard use case.

Doug.

On Mon, Jan 26, 2015 at 3:52 PM, Noah Kantrowitz noah@coderanger.net
wrote:

Chef and Ohai use the Etc library in Ruby, which in turn uses the
standard getpw* and getgr* calls. These are configured by nsswitch.conf. If
you go look this up, you'll see that that file is only read once for a
given process and there is no universal way to clear the config. Some libcs
offer non-standard calls for it, but I doubt any of those are exposed to
Ruby.

--Noah

On Jan 26, 2015, at 3:29 PM, Douglas Garstang <
doug.garstang@gmail.com> wrote:

Sorry to have to repeat myself, but I can't use 'owner' and 'group'
on resources. Even thought LDAP is configured, chef isn't able to see the
users and groups.

David suggested I reload ohai. I had no idea this was necessary or
required, but I tried it anyway. I put this at the end of my ldap cookbook.

ohai "reload_passwd" do
plugin "etc"
end
log node['etc']['passwd']

What I am seeing, (I'm using vagrant), is that on the first chef
run, the LDAP users are not in in the node structure. However, if I
reprovision, (without making any changes), then the users ARE there.

In hindsight, isn't this just the typical node not being
populated until after the chef run issue?

Doug.

On Mon, Jan 26, 2015 at 3:22 PM, Lamont Granquist lamont@chef.io
wrote:
On 1/26/15 2:29 PM, Douglas Garstang wrote:

I'm having trouble setting up users authorized keys. A cookbook
that runs earlier in the runlist sets up LDAP. However, due to reasons I
don't understand, none of that user information is available during the
chef run. I previously posted about this once before. As a result, I can't
simply create files and directories and use 'owner' and 'group.

I came up with the below idea. I'm iterating over the ssh keys in
a data bag and then for each user running a command as this user. That
makes PAM do all the home directory setup for me. I create the ~/.ssh
directory in a similar fashion, as the user. All works ok. However, I'm
having an issue with adding the array of ssh_keys pulled from the data bag
to the users authorized keys file.

include_recipe "slice-ldap"
bag = data_bag("ssh-keys")
for item in bag do
user = data_bag_item('ssh-keys', item)
user_name = user['id']
ssh_keys = user['ssh_keys']
execute "create_home_#{user_name}" do
command "su - #{user_name} -c "ls""
creates "/home/#{user_name}"
notifies :run, "execute[create_ssh_dir_#{user_name}]",
:immediately
end
execute "create_ssh_dir_#{user_name}" do
command "su - #{user_name} -c "mkdir
/home/#{user_name}/.ssh""
notifies :run, "execute[install_public_rsa_#{user_name}]",
:immediately
creates "/home/#{user_name}/.ssh"
end
ssh_keys.each_with_index do |k, index|
log "k = #{k}"
execute "install_public_rsa_#{user_name}" do
command "su - #{user_name} -c "echo '#{k}' >>
/home/#{user_name}/.ssh/authorized_keys""
action :nothing
end
end
end

However, I'm having an issue with adding the array of ssh_keys
pulled from the data bag to the users authorized keys file. The loop at the
end does this, but chef also gives me this warning:

==> default: [2015-01-26T22:23:47+00:00] WARN: Previous
execute[install_public_rsa_doug]:
/tmp/vagrant-chef-3/chef-solo-1/cookbooks/slice-ssh-keys/recipes/default.rb:38:in
block (2 levels) in from_file' ==> default: [2015-01-26T22:23:47+00:00] WARN: Current execute[install_public_rsa_doug]: /tmp/vagrant-chef-3/chef-solo-1/cookbooks/slice-ssh-keys/recipes/default.rb:38:in block (2 levels) in from_file'

Apart from the warning, only the last ssh keys is being added to
the authorized_keys file. Even though I'm using echo and >>, the last one
is not there. The log statement shows each key, so I know the loop is
iterating over both. What gives?

Doug

Yeah the warning is trying to tell you the problem. You're
defining multiple resources called execute[install_public_rsa_doug] and
the resource collection and the way notifies and subscribes is implemented
requires unique names. So you're getting resource cloning and you're only
notifying one of those blocks. You could add the index to then name and
then subscribe to the previous resources:

ssh_keys.each_with_index do |k, index|
log "k = #{k}"
execute "install_public_rsa_#{user_name}#{index}" do
command "su - #{user_name} -c "echo '#{k}' >>
/home/#{user_name}/.ssh/authorized_keys""
subscribes :run, "execute[#{create_ssh_dir
#{user_name}]"
subscribes :run, "execute[#{create_home_#{user_name}]"
action :nothing
end
end

You'll be way better off just doing this though:

file "/home/#{user_name}" do
owner user_name
group user_name # or "users" or whatever
mode "0600"
end

file "/home/#{user_name}/.ssh" do
owner user_name
group user_name
mode "0600"
end

file "/home/#{user_name}/.ssh/authorized_keys" do
owner user_name
group user_name
mode "0600"
content ssh_keys.join("\n")
end

That's idempotent, you don't need the action :nothing or any
notifications or subscriptions, you can push new keys out and it'll
correctly update, gets the job done with fewer resources, etc. Similarly
executing to su is a huge antipattern, so you can replace the rest of that.

--
Regards,

Douglas Garstang
http://www.linkedin.com/in/garstang
Email: doug.garstang@gmail.com
Cell: +1-805-340-5627

--
Regards,

Douglas Garstang
http://www.linkedin.com/in/garstang
Email: doug.garstang@gmail.com
Cell: +1-805-340-5627

--
Regards,

Douglas Garstang
http://www.linkedin.com/in/garstang
Email: doug.garstang@gmail.com
Cell: +1-805-340-5627

--
Regards,

Douglas Garstang
http://www.linkedin.com/in/garstang
Email: doug.garstang@gmail.com
Cell: +1-805-340-5627

Have you looked into OpenSSH’ authorized_keys_command? Might be a nice way to pull keys from github or another “trusted” source and not have them as files on disk at all. YMMV.

On Mar 10, 2015, at 11:03 AM, Morgan Blackthorne stormerider@gmail.com wrote:

And our shop has not had much luck with SSSD, personally. We use a mix of RHEL, Oracle Linux, CentOS, Amazon Linux, Ubuntu, and Debian. I'd rather keep the SSH key piece separate from the LDAP piece... we already have an LDAP config that works.

--
~~ StormeRider ~~

"Every world needs its heroes [...] They inspire us to be better than we are. And they protect from the darkness that's just around the corner."

(from Smallville Season 6x1: "Zod")

On why I hate the phrase "that's so lame"... http://bit.ly/Ps3uSS

On Tue, Mar 10, 2015 at 7:41 AM, Ed Ropple eropple@leaf.me wrote:
YMMV, but I'd reconsider the approach you're taking--"configuring users with LDAP" seems like the tail wagging the dog a little. I've had much better luck using SSSD to act as an authentication system that talks to LDAP instead. You can store public keys in your LDAP server, then, and SSSD will do the Right Thing. It's a huge step up over nslcd or ldapd.

I've used it on both CentOS and Ubuntu, with significant success.

Good luck!

-Ed

On Tue, Mar 10, 2015 at 10:15 AM, Morgan Blackthorne stormerider@gmail.com wrote:
So I'm actually looking to do this myself, though I want the config to be:

AuthorizedKeysFile "%h/.ssh/authorized_keys /etc/ssh/%u/authorized_keys"

That way they can use manual keys in addition to the ones I'll be having chef drop in place. However, I'm not currently managing /etc/ssh/sshd_config. What's the best way to modify just that one line? I'm a bit uneasy about trying to just cookbook_file that, given how many different Linux distributions we have (Oracle, Redhat, Debian, Ubuntu, CentOS, etc).

On Jan 26, 2015 4:15 PM, "Douglas Garstang" doug.garstang@gmail.com wrote:
Or... something like:

AuthorizedKeysFile /etc/ssh/authorized_keys/%u

in /etc/ssh/sshd_config. The users account doesn't need to exist first, and it's owned by root and managed by chef, not the user.

Doug.

On Mon, Jan 26, 2015 at 3:56 PM, Douglas Garstang doug.garstang@gmail.com wrote:
Actually, I think it's time for a script.

On Mon, Jan 26, 2015 at 3:55 PM, Douglas Garstang doug.garstang@gmail.com wrote:
So, it would seem this this is a general chef issue then. It's not an LDAP issue, or an ohai issue. It's a chef issue.

A workaround for this limitation sure would be nice. Configuring user with LDAP and then being able to create their ssh keys seems like a pretty standard use case.

Doug.

On Mon, Jan 26, 2015 at 3:52 PM, Noah Kantrowitz noah@coderanger.net wrote:
Chef and Ohai use the Etc library in Ruby, which in turn uses the standard getpw* and getgr* calls. These are configured by nsswitch.conf. If you go look this up, you'll see that that file is only read once for a given process and there is no universal way to clear the config. Some libcs offer non-standard calls for it, but I doubt any of those are exposed to Ruby.

--Noah

On Jan 26, 2015, at 3:29 PM, Douglas Garstang doug.garstang@gmail.com wrote:

Sorry to have to repeat myself, but I can't use 'owner' and 'group' on resources. Even thought LDAP is configured, chef isn't able to see the users and groups.

David suggested I reload ohai. I had no idea this was necessary or required, but I tried it anyway. I put this at the end of my ldap cookbook.

ohai "reload_passwd" do
plugin "etc"
end
log node['etc']['passwd']

What I am seeing, (I'm using vagrant), is that on the first chef run, the LDAP users are not in in the node structure. However, if I reprovision, (without making any changes), then the users ARE there.

In hindsight, isn't this just the typical node not being populated until after the chef run issue?

Doug.

On Mon, Jan 26, 2015 at 3:22 PM, Lamont Granquist lamont@chef.io wrote:
On 1/26/15 2:29 PM, Douglas Garstang wrote:

I'm having trouble setting up users authorized keys. A cookbook that runs earlier in the runlist sets up LDAP. However, due to reasons I don't understand, none of that user information is available during the chef run. I previously posted about this once before. As a result, I can't simply create files and directories and use 'owner' and 'group.

I came up with the below idea. I'm iterating over the ssh keys in a data bag and then for each user running a command as this user. That makes PAM do all the home directory setup for me. I create the ~/.ssh directory in a similar fashion, as the user. All works ok. However, I'm having an issue with adding the array of ssh_keys pulled from the data bag to the users authorized keys file.

include_recipe "slice-ldap"
bag = data_bag("ssh-keys")
for item in bag do
user = data_bag_item('ssh-keys', item)
user_name = user['id']
ssh_keys = user['ssh_keys']
execute "create_home_#{user_name}" do
command "su - #{user_name} -c "ls""
creates "/home/#{user_name}"
notifies :run, "execute[create_ssh_dir_#{user_name}]", :immediately
end
execute "create_ssh_dir_#{user_name}" do
command "su - #{user_name} -c "mkdir /home/#{user_name}/.ssh""
notifies :run, "execute[install_public_rsa_#{user_name}]", :immediately
creates "/home/#{user_name}/.ssh"
end
ssh_keys.each_with_index do |k, index|
log "k = #{k}"
execute "install_public_rsa_#{user_name}" do
command "su - #{user_name} -c "echo '#{k}' >> /home/#{user_name}/.ssh/authorized_keys""
action :nothing
end
end
end

However, I'm having an issue with adding the array of ssh_keys pulled from the data bag to the users authorized keys file. The loop at the end does this, but chef also gives me this warning:

==> default: [2015-01-26T22:23:47+00:00] WARN: Previous execute[install_public_rsa_doug]: /tmp/vagrant-chef-3/chef-solo-1/cookbooks/slice-ssh-keys/recipes/default.rb:38:in block (2 levels) in from_file' ==> default: [2015-01-26T22:23:47+00:00] WARN: Current execute[install_public_rsa_doug]: /tmp/vagrant-chef-3/chef-solo-1/cookbooks/slice-ssh-keys/recipes/default.rb:38:in block (2 levels) in from_file'

Apart from the warning, only the last ssh keys is being added to the authorized_keys file. Even though I'm using echo and >>, the last one is not there. The log statement shows each key, so I know the loop is iterating over both. What gives?

Doug

Yeah the warning is trying to tell you the problem. You're defining multiple resources called execute[install_public_rsa_doug] and the resource collection and the way notifies and subscribes is implemented requires unique names. So you're getting resource cloning and you're only notifying one of those blocks. You could add the index to then name and then subscribe to the previous resources:

ssh_keys.each_with_index do |k, index|
log "k = #{k}"
execute "install_public_rsa_#{user_name}#{index}" do
command "su - #{user_name} -c "echo '#{k}' >> /home/#{user_name}/.ssh/authorized_keys""
subscribes :run, "execute[#{create_ssh_dir
#{user_name}]"
subscribes :run, "execute[#{create_home_#{user_name}]"
action :nothing
end
end

You'll be way better off just doing this though:

file "/home/#{user_name}" do
owner user_name
group user_name # or "users" or whatever
mode "0600"
end

file "/home/#{user_name}/.ssh" do
owner user_name
group user_name
mode "0600"
end

file "/home/#{user_name}/.ssh/authorized_keys" do
owner user_name
group user_name
mode "0600"
content ssh_keys.join("\n")
end

That's idempotent, you don't need the action :nothing or any notifications or subscriptions, you can push new keys out and it'll correctly update, gets the job done with fewer resources, etc. Similarly executing to su is a huge antipattern, so you can replace the rest of that.

--
Regards,

Douglas Garstang
http://www.linkedin.com/in/garstang
Email: doug.garstang@gmail.com
Cell: +1-805-340-5627

--
Regards,

Douglas Garstang
http://www.linkedin.com/in/garstang
Email: doug.garstang@gmail.com
Cell: +1-805-340-5627

--
Regards,

Douglas Garstang
http://www.linkedin.com/in/garstang
Email: doug.garstang@gmail.com
Cell: +1-805-340-5627

--
Regards,

Douglas Garstang
http://www.linkedin.com/in/garstang
Email: doug.garstang@gmail.com
Cell: +1-805-340-5627

I have not, but I think that that's somewhat irrelevant. No matter if I
store them on disk (which would be preferred as it's simplest, especially
as we mandate proxy usage in the datacenter), or use a command to look the
keys up, I still need to alter the sshd_config file. My question is how
best to do that without replacing the entire file; while I would like to
standardize our config, there are simply too many distros and versions of
distros in play for me to feel comfortable biting that off right now.

--
~~ StormeRider ~~

"Every world needs its heroes [...] They inspire us to be better than we
are. And they protect from the darkness that's just around the corner."

(from Smallville Season 6x1: "Zod")

On why I hate the phrase "that's so lame"... http://bit.ly/Ps3uSS

On Tue, Mar 10, 2015 at 8:16 AM, Matt Juszczak matt@atopia.net wrote:

Have you looked into OpenSSH’ authorized_keys_command? Might be a nice way
to pull keys from github or another “trusted” source and not have them as
files on disk at all. YMMV.

On Mar 10, 2015, at 11:03 AM, Morgan Blackthorne stormerider@gmail.com
wrote:

And our shop has not had much luck with SSSD, personally. We use a mix
of RHEL, Oracle Linux, CentOS, Amazon Linux, Ubuntu, and Debian. I'd rather
keep the SSH key piece separate from the LDAP piece... we already have an
LDAP config that works.

--
~~ StormeRider ~~

"Every world needs its heroes [...] They inspire us to be better than we
are. And they protect from the darkness that's just around the corner."

(from Smallville Season 6x1: "Zod")

On why I hate the phrase "that's so lame"... http://bit.ly/Ps3uSS

On Tue, Mar 10, 2015 at 7:41 AM, Ed Ropple eropple@leaf.me wrote:
YMMV, but I'd reconsider the approach you're taking--"configuring users
with LDAP" seems like the tail wagging the dog a little. I've had much
better luck using SSSD to act as an authentication system that talks to
LDAP instead. You can store public keys in your LDAP server, then, and SSSD
will do the Right Thing. It's a huge step up over nslcd or ldapd.

I've used it on both CentOS and Ubuntu, with significant success.

Good luck!

-Ed

On Tue, Mar 10, 2015 at 10:15 AM, Morgan Blackthorne <
stormerider@gmail.com> wrote:
So I'm actually looking to do this myself, though I want the config to
be:

AuthorizedKeysFile "%h/.ssh/authorized_keys

/etc/ssh/%u/authorized_keys"

That way they can use manual keys in addition to the ones I'll be having
chef drop in place. However, I'm not currently managing
/etc/ssh/sshd_config. What's the best way to modify just that one line? I'm
a bit uneasy about trying to just cookbook_file that, given how many
different Linux distributions we have (Oracle, Redhat, Debian, Ubuntu,
CentOS, etc).

On Jan 26, 2015 4:15 PM, "Douglas Garstang" doug.garstang@gmail.com
wrote:
Or... something like:

AuthorizedKeysFile /etc/ssh/authorized_keys/%u

in /etc/ssh/sshd_config. The users account doesn't need to exist first,
and it's owned by root and managed by chef, not the user.

Doug.

On Mon, Jan 26, 2015 at 3:56 PM, Douglas Garstang <
doug.garstang@gmail.com> wrote:
Actually, I think it's time for a script.

On Mon, Jan 26, 2015 at 3:55 PM, Douglas Garstang <
doug.garstang@gmail.com> wrote:
So, it would seem this this is a general chef issue then. It's not an
LDAP issue, or an ohai issue. It's a chef issue.

A workaround for this limitation sure would be nice. Configuring user
with LDAP and then being able to create their ssh keys seems like a pretty
standard use case.

Doug.

On Mon, Jan 26, 2015 at 3:52 PM, Noah Kantrowitz noah@coderanger.net
wrote:
Chef and Ohai use the Etc library in Ruby, which in turn uses the
standard getpw* and getgr* calls. These are configured by nsswitch.conf. If
you go look this up, you'll see that that file is only read once for a
given process and there is no universal way to clear the config. Some libcs
offer non-standard calls for it, but I doubt any of those are exposed to
Ruby.

--Noah

On Jan 26, 2015, at 3:29 PM, Douglas Garstang doug.garstang@gmail.com
wrote:

Sorry to have to repeat myself, but I can't use 'owner' and 'group' on
resources. Even thought LDAP is configured, chef isn't able to see the
users and groups.

David suggested I reload ohai. I had no idea this was necessary or
required, but I tried it anyway. I put this at the end of my ldap cookbook.

ohai "reload_passwd" do
plugin "etc"
end
log node['etc']['passwd']

What I am seeing, (I'm using vagrant), is that on the first chef run,
the LDAP users are not in in the node structure. However, if I reprovision,
(without making any changes), then the users ARE there.

In hindsight, isn't this just the typical node not being populated
until after the chef run issue?

Doug.

On Mon, Jan 26, 2015 at 3:22 PM, Lamont Granquist lamont@chef.io
wrote:
On 1/26/15 2:29 PM, Douglas Garstang wrote:

I'm having trouble setting up users authorized keys. A cookbook that
runs earlier in the runlist sets up LDAP. However, due to reasons I don't
understand, none of that user information is available during the chef run.
I previously posted about this once before. As a result, I can't simply
create files and directories and use 'owner' and 'group.

I came up with the below idea. I'm iterating over the ssh keys in a
data bag and then for each user running a command as this user. That makes
PAM do all the home directory setup for me. I create the ~/.ssh directory
in a similar fashion, as the user. All works ok. However, I'm having an
issue with adding the array of ssh_keys pulled from the data bag to the
users authorized keys file.

include_recipe "slice-ldap"
bag = data_bag("ssh-keys")
for item in bag do
user = data_bag_item('ssh-keys', item)
user_name = user['id']
ssh_keys = user['ssh_keys']
execute "create_home_#{user_name}" do
command "su - #{user_name} -c "ls""
creates "/home/#{user_name}"
notifies :run, "execute[create_ssh_dir_#{user_name}]",
:immediately
end
execute "create_ssh_dir_#{user_name}" do
command "su - #{user_name} -c "mkdir /home/#{user_name}/.ssh""
notifies :run, "execute[install_public_rsa_#{user_name}]",
:immediately
creates "/home/#{user_name}/.ssh"
end
ssh_keys.each_with_index do |k, index|
log "k = #{k}"
execute "install_public_rsa_#{user_name}" do
command "su - #{user_name} -c "echo '#{k}' >>
/home/#{user_name}/.ssh/authorized_keys""
action :nothing
end
end
end

However, I'm having an issue with adding the array of ssh_keys pulled
from the data bag to the users authorized keys file. The loop at the end
does this, but chef also gives me this warning:

==> default: [2015-01-26T22:23:47+00:00] WARN: Previous
execute[install_public_rsa_doug]:
/tmp/vagrant-chef-3/chef-solo-1/cookbooks/slice-ssh-keys/recipes/default.rb:38:in
block (2 levels) in from_file' ==> default: [2015-01-26T22:23:47+00:00] WARN: Current execute[install_public_rsa_doug]: /tmp/vagrant-chef-3/chef-solo-1/cookbooks/slice-ssh-keys/recipes/default.rb:38:in block (2 levels) in from_file'

Apart from the warning, only the last ssh keys is being added to the
authorized_keys file. Even though I'm using echo and >>, the last one is
not there. The log statement shows each key, so I know the loop is
iterating over both. What gives?

Doug

Yeah the warning is trying to tell you the problem. You're defining
multiple resources called execute[install_public_rsa_doug] and the
resource collection and the way notifies and subscribes is implemented
requires unique names. So you're getting resource cloning and you're only
notifying one of those blocks. You could add the index to then name and
then subscribe to the previous resources:

ssh_keys.each_with_index do |k, index|
log "k = #{k}"
execute "install_public_rsa_#{user_name}#{index}" do
command "su - #{user_name} -c "echo '#{k}' >>
/home/#{user_name}/.ssh/authorized_keys""
subscribes :run, "execute[#{create_ssh_dir
#{user_name}]"
subscribes :run, "execute[#{create_home_#{user_name}]"
action :nothing
end
end

You'll be way better off just doing this though:

file "/home/#{user_name}" do
owner user_name
group user_name # or "users" or whatever
mode "0600"
end

file "/home/#{user_name}/.ssh" do
owner user_name
group user_name
mode "0600"
end

file "/home/#{user_name}/.ssh/authorized_keys" do
owner user_name
group user_name
mode "0600"
content ssh_keys.join("\n")
end

That's idempotent, you don't need the action :nothing or any
notifications or subscriptions, you can push new keys out and it'll
correctly update, gets the job done with fewer resources, etc. Similarly
executing to su is a huge antipattern, so you can replace the rest of that.

--
Regards,

Douglas Garstang
http://www.linkedin.com/in/garstang
Email: doug.garstang@gmail.com
Cell: +1-805-340-5627

--
Regards,

Douglas Garstang
http://www.linkedin.com/in/garstang
Email: doug.garstang@gmail.com
Cell: +1-805-340-5627

--
Regards,

Douglas Garstang
http://www.linkedin.com/in/garstang
Email: doug.garstang@gmail.com
Cell: +1-805-340-5627

--
Regards,

Douglas Garstang
http://www.linkedin.com/in/garstang
Email: doug.garstang@gmail.com
Cell: +1-805-340-5627

You could always use Augeus…. http://augeas.net. I’ve used this elsewhere before, but not sure how well it would function in Chef.

-Matt

On Mar 10, 2015, at 11:22 AM, Morgan Blackthorne stormerider@gmail.com wrote:

I have not, but I think that that's somewhat irrelevant. No matter if I store them on disk (which would be preferred as it's simplest, especially as we mandate proxy usage in the datacenter), or use a command to look the keys up, I still need to alter the sshd_config file. My question is how best to do that without replacing the entire file; while I would like to standardize our config, there are simply too many distros and versions of distros in play for me to feel comfortable biting that off right now.

--
~~ StormeRider ~~

"Every world needs its heroes [...] They inspire us to be better than we are. And they protect from the darkness that's just around the corner."

(from Smallville Season 6x1: "Zod")

On why I hate the phrase "that's so lame"... http://bit.ly/Ps3uSS

On Tue, Mar 10, 2015 at 8:16 AM, Matt Juszczak matt@atopia.net wrote:
Have you looked into OpenSSH’ authorized_keys_command? Might be a nice way to pull keys from github or another “trusted” source and not have them as files on disk at all. YMMV.

On Mar 10, 2015, at 11:03 AM, Morgan Blackthorne stormerider@gmail.com wrote:

And our shop has not had much luck with SSSD, personally. We use a mix of RHEL, Oracle Linux, CentOS, Amazon Linux, Ubuntu, and Debian. I'd rather keep the SSH key piece separate from the LDAP piece... we already have an LDAP config that works.

--
~~ StormeRider ~~

"Every world needs its heroes [...] They inspire us to be better than we are. And they protect from the darkness that's just around the corner."

(from Smallville Season 6x1: "Zod")

On why I hate the phrase "that's so lame"... http://bit.ly/Ps3uSS

On Tue, Mar 10, 2015 at 7:41 AM, Ed Ropple eropple@leaf.me wrote:
YMMV, but I'd reconsider the approach you're taking--"configuring users with LDAP" seems like the tail wagging the dog a little. I've had much better luck using SSSD to act as an authentication system that talks to LDAP instead. You can store public keys in your LDAP server, then, and SSSD will do the Right Thing. It's a huge step up over nslcd or ldapd.

I've used it on both CentOS and Ubuntu, with significant success.

Good luck!

-Ed

On Tue, Mar 10, 2015 at 10:15 AM, Morgan Blackthorne stormerider@gmail.com wrote:
So I'm actually looking to do this myself, though I want the config to be:

AuthorizedKeysFile "%h/.ssh/authorized_keys /etc/ssh/%u/authorized_keys"

That way they can use manual keys in addition to the ones I'll be having chef drop in place. However, I'm not currently managing /etc/ssh/sshd_config. What's the best way to modify just that one line? I'm a bit uneasy about trying to just cookbook_file that, given how many different Linux distributions we have (Oracle, Redhat, Debian, Ubuntu, CentOS, etc).

On Jan 26, 2015 4:15 PM, "Douglas Garstang" doug.garstang@gmail.com wrote:
Or... something like:

AuthorizedKeysFile /etc/ssh/authorized_keys/%u

in /etc/ssh/sshd_config. The users account doesn't need to exist first, and it's owned by root and managed by chef, not the user.

Doug.

On Mon, Jan 26, 2015 at 3:56 PM, Douglas Garstang doug.garstang@gmail.com wrote:
Actually, I think it's time for a script.

On Mon, Jan 26, 2015 at 3:55 PM, Douglas Garstang doug.garstang@gmail.com wrote:
So, it would seem this this is a general chef issue then. It's not an LDAP issue, or an ohai issue. It's a chef issue.

A workaround for this limitation sure would be nice. Configuring user with LDAP and then being able to create their ssh keys seems like a pretty standard use case.

Doug.

On Mon, Jan 26, 2015 at 3:52 PM, Noah Kantrowitz noah@coderanger.net wrote:
Chef and Ohai use the Etc library in Ruby, which in turn uses the standard getpw* and getgr* calls. These are configured by nsswitch.conf. If you go look this up, you'll see that that file is only read once for a given process and there is no universal way to clear the config. Some libcs offer non-standard calls for it, but I doubt any of those are exposed to Ruby.

--Noah

On Jan 26, 2015, at 3:29 PM, Douglas Garstang doug.garstang@gmail.com wrote:

Sorry to have to repeat myself, but I can't use 'owner' and 'group' on resources. Even thought LDAP is configured, chef isn't able to see the users and groups.

David suggested I reload ohai. I had no idea this was necessary or required, but I tried it anyway. I put this at the end of my ldap cookbook.

ohai "reload_passwd" do
plugin "etc"
end
log node['etc']['passwd']

What I am seeing, (I'm using vagrant), is that on the first chef run, the LDAP users are not in in the node structure. However, if I reprovision, (without making any changes), then the users ARE there.

In hindsight, isn't this just the typical node not being populated until after the chef run issue?

Doug.

On Mon, Jan 26, 2015 at 3:22 PM, Lamont Granquist lamont@chef.io wrote:
On 1/26/15 2:29 PM, Douglas Garstang wrote:

I'm having trouble setting up users authorized keys. A cookbook that runs earlier in the runlist sets up LDAP. However, due to reasons I don't understand, none of that user information is available during the chef run. I previously posted about this once before. As a result, I can't simply create files and directories and use 'owner' and 'group.

I came up with the below idea. I'm iterating over the ssh keys in a data bag and then for each user running a command as this user. That makes PAM do all the home directory setup for me. I create the ~/.ssh directory in a similar fashion, as the user. All works ok. However, I'm having an issue with adding the array of ssh_keys pulled from the data bag to the users authorized keys file.

include_recipe "slice-ldap"
bag = data_bag("ssh-keys")
for item in bag do
user = data_bag_item('ssh-keys', item)
user_name = user['id']
ssh_keys = user['ssh_keys']
execute "create_home_#{user_name}" do
command "su - #{user_name} -c "ls""
creates "/home/#{user_name}"
notifies :run, "execute[create_ssh_dir_#{user_name}]", :immediately
end
execute "create_ssh_dir_#{user_name}" do
command "su - #{user_name} -c "mkdir /home/#{user_name}/.ssh""
notifies :run, "execute[install_public_rsa_#{user_name}]", :immediately
creates "/home/#{user_name}/.ssh"
end
ssh_keys.each_with_index do |k, index|
log "k = #{k}"
execute "install_public_rsa_#{user_name}" do
command "su - #{user_name} -c "echo '#{k}' >> /home/#{user_name}/.ssh/authorized_keys""
action :nothing
end
end
end

However, I'm having an issue with adding the array of ssh_keys pulled from the data bag to the users authorized keys file. The loop at the end does this, but chef also gives me this warning:

==> default: [2015-01-26T22:23:47+00:00] WARN: Previous execute[install_public_rsa_doug]: /tmp/vagrant-chef-3/chef-solo-1/cookbooks/slice-ssh-keys/recipes/default.rb:38:in block (2 levels) in from_file' ==> default: [2015-01-26T22:23:47+00:00] WARN: Current execute[install_public_rsa_doug]: /tmp/vagrant-chef-3/chef-solo-1/cookbooks/slice-ssh-keys/recipes/default.rb:38:in block (2 levels) in from_file'

Apart from the warning, only the last ssh keys is being added to the authorized_keys file. Even though I'm using echo and >>, the last one is not there. The log statement shows each key, so I know the loop is iterating over both. What gives?

Doug

Yeah the warning is trying to tell you the problem. You're defining multiple resources called execute[install_public_rsa_doug] and the resource collection and the way notifies and subscribes is implemented requires unique names. So you're getting resource cloning and you're only notifying one of those blocks. You could add the index to then name and then subscribe to the previous resources:

ssh_keys.each_with_index do |k, index|
log "k = #{k}"
execute "install_public_rsa_#{user_name}#{index}" do
command "su - #{user_name} -c "echo '#{k}' >> /home/#{user_name}/.ssh/authorized_keys""
subscribes :run, "execute[#{create_ssh_dir
#{user_name}]"
subscribes :run, "execute[#{create_home_#{user_name}]"
action :nothing
end
end

You'll be way better off just doing this though:

file "/home/#{user_name}" do
owner user_name
group user_name # or "users" or whatever
mode "0600"
end

file "/home/#{user_name}/.ssh" do
owner user_name
group user_name
mode "0600"
end

file "/home/#{user_name}/.ssh/authorized_keys" do
owner user_name
group user_name
mode "0600"
content ssh_keys.join("\n")
end

That's idempotent, you don't need the action :nothing or any notifications or subscriptions, you can push new keys out and it'll correctly update, gets the job done with fewer resources, etc. Similarly executing to su is a huge antipattern, so you can replace the rest of that.

--
Regards,

Douglas Garstang
http://www.linkedin.com/in/garstang
Email: doug.garstang@gmail.com
Cell: +1-805-340-5627

--
Regards,

Douglas Garstang
http://www.linkedin.com/in/garstang
Email: doug.garstang@gmail.com
Cell: +1-805-340-5627

--
Regards,

Douglas Garstang
http://www.linkedin.com/in/garstang
Email: doug.garstang@gmail.com
Cell: +1-805-340-5627

--
Regards,

Douglas Garstang
http://www.linkedin.com/in/garstang
Email: doug.garstang@gmail.com
Cell: +1-805-340-5627