3

the sysadmins are present in the sudoers files of all environments, but other sudoers are not. Different environments all have slightly different sudoers. Most of the time, 90% of users are the same, and 10% vary so we cannot have only one sudoers file for everything.

Right now, we are using puppet with 10 different files with names like sudoers.production1, sudoers.production2, sudoers.production3, sudoers.testing1, sudoers.staging1 and so forth.

Puppet then picks the file to deploy based on the server's $domain (ex: dbserver.staging1.acme.com) or $hardwaremodel. It works fine but it's a nightmare to maintain so many files.

I'd like to autogenerate sudoers files based on the server's domain and have only one big file with all the sudoers permissions for all users and all environments. Something that looks like:

User_Alias ADMINS = abe, bob, carol, dave

case $domain {
 "staging1.acme.com" {
    #add dev1,dev2,tester1,tester2 to sudoers file 
  }
 "testing2.acme.com" {
    #add tester1, tester3, tester4 to sudoers file
  }    

What's the best way to go about this? Suggestions for alternatives are welcome. I'd appreciate any tips.

Update 1:

For security reasons, we'd rather not concatenate a bunch of files from a folder located on a puppet client in case someone puts a file in there (maliciously or not) and either breaks the combined file or inserts something in it.

Most importantly, for usability, we'd like to keep the number of sudoers related files (fragment or complete) on puppet server to either 3 (prod/stage/test) or preferably 1 file. this file would (somehow) generate sudoers files on the puppet server and send one customized file to each puppet client.

The purpose of this would be only searching for a username in a single file and removing it quicker than doing it on 11 files. When adding a user to a bunch of environments, it won't be as quick, but only one file would need to be opened and looked at, greatly reducing the chances of an omission.

our Sudo version is 1.6.9p8 so we can't use /sudoers.d folder, only a sudoers file.

Update2:

I've been googling some and I just found this, which I've spent the past hour looking at:

https://github.com/saz/puppet-sudo#readme

I'm not certain but it looks like it might do the trick. Has anyone used it or heard about it?

gozu
  • 313
  • 2
  • 6
  • 14

3 Answers3

9

What version of sudo? Does your version of sudo support using #includedir option to break things out into a fragment directory /etc/sudoers.d/?

If so, then I suggest you use that functionality to build your config.

Have your main config file delivered to /etc/sudoers that includes all the settings that is common to every host you control. Then have role-specific configuration get dropped into a file within /etc/sudoers.d/.

Each class or puppet section is responsible for updating the small portion of the sudo config directly related to that class.

Zoredache
  • 128,755
  • 40
  • 271
  • 413
  • Oooh, that could be nice. Is that available in CentOS/RHEL? – ewwhite Dec 04 '12 at 18:14
  • we have Sudo version 1.6.9p8. We are not currently using sudoers.d folders. maybe because the solaris version of sudo we're using doesn't support it? – gozu Dec 04 '12 at 18:16
  • @ewwhite, from what I read it is available in RHEL 5.5 and above. Haven't tested though. http://rhn.redhat.com/errata/RHBA-2010-0212.html – Zoredache Dec 04 '12 at 18:41
  • @gozu, the `#includedir` is a relatively new option. It wouldn't surprise me that it isn't supported everywhere. If that is not available, then you can achieve similar functionality using a concatenate pattern. Basically you deliver all the fragements, and then have some tool merge them into a single file. See https://github.com/ripienaar/puppet-concat or http://projects.puppetlabs.com/projects/puppet/wiki/Generating_a_config_file_from_fragments and http://serverfault.com/a/441048/984 – Zoredache Dec 04 '12 at 18:45
  • For security reasons, we'd rather not concatenate a bunch of files from a folder in case someone puts a file in there (maliciously or not) and breaks the file or inserts something in the sudoers file. Most importantly, for usability, we'd like to keep the number of sudoers related files (fragment or complete) on puppet server to either 3 (prod/stage/test) or preferably 1 file. this file would (somehow) generate sudoers files on the puppet server and send one customized file to each puppet client. – gozu Dec 04 '12 at 20:15
  • @gozu, given those requirements, then you probably should be looking at building a template as ewwhite suggested. There are a few ways to generate a config on the puppet server, but using a template is the most common method. – Zoredache Dec 04 '12 at 21:06
3

You can have a look at virtual resources and realize: https://puppet.com/docs/puppet/latest/lang_virtual.html.

This does exactly that: on some systems you 'realize' the resource and on some you don't.

рüффп
  • 620
  • 1
  • 11
  • 24
silviud
  • 2,677
  • 2
  • 16
  • 19
  • Any examples you know of? It's an interesting approach. – gozu Dec 06 '12 at 18:18
  • make something that can be included by all systems - let's call it base so class base { @user { sysadmin: ensure => present } } and then on the systems where you want to include this you just 'realize' it as class admins { include base; User <| title == sysadmin |> } - there is also a function called realize that behaves a bit different. For the systems where you want the database users you proceed the same - include base and if you want to 'realize' the user you just use the above example - Basically what virtual resources give is the ability to include the resource on multiple hosts. – silviud Dec 07 '12 at 18:49
2

You can do with using Puppet templates... Site-specific configuration with a small ruby snippet/variable for the user you need. (I'll post an example later)

The traditional way of handling this is by using group definitions instead of named-users in your /etc/sudoers. It may be less of a hassle to manage.

ewwhite
  • 194,921
  • 91
  • 434
  • 799
  • Don't forget the possibility of using unix groups to handle this. – ewwhite Dec 05 '12 at 05:42
  • I'm not sure what you mean exactly. We are already using groups in the sudoers files right now. admin group, tester group, etc. But on any environment, there are anywhere from 2 to 12 "special" singleton users who can't be grouped with anybody else. I think you're right that puppet templates are the way to go for me. Hopefully your example will help me grok it. In the meantime I'm reading up on puppet templates. Suggestions are welcome :) – gozu Dec 05 '12 at 16:35
  • Have you been able to find that example? I'd like to see it before I decide :) – gozu Dec 06 '12 at 18:16