Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

filter sudoers file by host specifics #26

Open
aabognah opened this issue Nov 6, 2015 · 5 comments
Open

filter sudoers file by host specifics #26

aabognah opened this issue Nov 6, 2015 · 5 comments

Comments

@aabognah
Copy link

aabognah commented Nov 6, 2015

The sudoers file currently includes all pillar data. this means that a host sudoers file will include all the aliases for example even if it does not use them. It would be nice to have the sudoers file tailored to the host to isolate issues. for instance, now if I go in and add a new hosts aliase and make a mistake in the pillar so that salt cant catch it because its yaml correct but sudoers file wont parse it (it happened believe me) this will break all sudoers files in all hosts. but if the aliases are added only in the files that use them this will limit the impact of a mistake like this.
How would one go about doing so? is it possible to have multiple sudoers pillar files and filter what goes into the sudoers file based on host its going on?

@0xf10e
Copy link

0xf10e commented Nov 7, 2015

To filter by host the pillar structure for this formula needs to change.

My private template for /etc/sudoers at work (which precedes this formula and my bosses' OK to throw this kinda stuff on GitHub) uses s/t like this:

sudo:
  Privileges:
    "Comment for this priv spec":
      User: jdoe
      Host: www.example.com
      Runas: root:root
      Commands:
        - service httpd restart
        - service httpd configtest

This forces comments on the operator but I found no other way to introduce a key to form a dictionary with the priv specs as values.
Lists of dictionaries are just horrible to read, especially in Salt's state output.

Of course, aliases are accepted for users, hosts, etc but their actual existence in pillar isn't checked ;)
And host defaults to ALL and user defaults to root:root.

@0xf10e
Copy link

0xf10e commented Nov 7, 2015

Filtering for the current host would be easy in my pillar format for plain hostnames.

But I think filtering for host aliases containing the current host will be difficult or at least complex in any format.

@aabognah
Copy link
Author

Thanks @0xf10e for the reply. I like the privileges pillar idea. but can you elaborate more on how incorporate this pillar format with this sudoers formula?

@0xf10e
Copy link

0xf10e commented Dec 21, 2015

@aabognah I'll see if I can throw together something using my format and filtering for hosts.

@aabognah
Copy link
Author

I came up with a format that I think works for me.

First I changed the pillars structure as follows:

# User privilege specification
users:
  root:
    hosts: ALL
    options: (ALL)
    commands: ALL
  user1:
    hosts: 
      - host1
      - host2
    commands: ALL
  user3:
    hosts: ['host1', 'host2']
    options: (ALL)
    commands: ['com1','com2','com3']

and in the sudoers file template I change:

# User privilege specification
{%- for user,specs in users.items() %}
  {%- for spec in specs %}
{{ user }} {{ spec }}
  {%- endfor %}
{%- endfor %}

To this:

# User privilege specification
{%- for user,specs in users.items() %}
  {%- for host in specs['hosts'] %}
    {%- if host == grains['host'] %}
{{ user }} {{ specs['hosts'] }} = {{ specs['options'] | default('') }} {{ specs['commands'] }}
    {%- endif %}
  {%- endfor %}
{%- endfor %}

There are a couple checks in the template to make sure the a line is not added twice and to propurly join lists in the suborders format (using ','.join()).

I've also made similar changes in the aliases section to only add aliases that are referenced in the privileges section.

# Cmnd alias specification
{%- for name,commands in command_aliases.items() %}
  {%- set alias_added = False %}
  {%- for user, specs in users.items() %}
    {%- for command in specs['commands'] %}
      {%- if command == name and alias_added == False %}
Cmnd_Alias {{ name }} = {{ ",".join(commands) }}
      {%- set alias_added = True %}
      {%- endif %}
    {%- endfor %}
  {%- endfor %}
{%- endfor %}

All of this allows having one big sudoers template with all aliases and specification for all hosts but only the bits relevant to the host will be part of its sudoers file.

Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants