diff --git a/pillar/top.sls b/pillar/top.sls index ed3e49254..5c81c0287 100644 --- a/pillar/top.sls +++ b/pillar/top.sls @@ -16,6 +16,7 @@ base: - sensoroni.adv_sensoroni - telegraf.soc_telegraf - telegraf.adv_telegraf + - users '* and not *_desktop': - firewall.soc_firewall diff --git a/pillar/users/init.sls b/pillar/users/init.sls new file mode 100644 index 000000000..e1c0e4a9c --- /dev/null +++ b/pillar/users/init.sls @@ -0,0 +1,2 @@ +# users pillar goes in /opt/so/saltstack/local/pillar/users/init.sls +# the users directory may need to be created under /opt/so/saltstack/local/pillar diff --git a/pillar/users/pillar.example b/pillar/users/pillar.example new file mode 100644 index 000000000..57ef7fa79 --- /dev/null +++ b/pillar/users/pillar.example @@ -0,0 +1,18 @@ +users: + sclapton: + # required fields + status: present + # node_access determines which node types the user can access. + # this can either be by grains.role or by final part of the minion id after the _ + node_access: + - standalone + - searchnode + # optional fields + fullname: Stevie Claptoon + uid: 1001 + gid: 1001 + homephone: does not have a phone + groups: + - mygroup1 + - mygroup2 + - wheel # give sudo access diff --git a/pillar/users/pillar.usage b/pillar/users/pillar.usage new file mode 100644 index 000000000..82821f02d --- /dev/null +++ b/pillar/users/pillar.usage @@ -0,0 +1,20 @@ +users: + sclapton: + # required fields + status: + # node_access determines which node types the user can access. + # this can either be by grains.role or by final part of the minion id after the _ + node_access: + - standalone + - searchnode + # optional fields + fullname: + uid: + gid: + roomnumber: + workphone: + homephone: + groups: + - + - + - wheel # give sudo access diff --git a/salt/top.sls b/salt/top.sls index a07f2d9e1..0ebc2ab66 100644 --- a/salt/top.sls +++ b/salt/top.sls @@ -29,6 +29,7 @@ base: - salt.minion-check - salt.lasthighstate - common + - users - docker - docker_clean diff --git a/salt/users/init.sls b/salt/users/init.sls new file mode 100644 index 000000000..02f430e30 --- /dev/null +++ b/salt/users/init.sls @@ -0,0 +1,110 @@ +# The creation of a user will require a pub key placed in /opt/so/saltstack/local/salt/users/authorized_keys/ + +# If a user is changed from present to absent, their usergroup will be removed, but any additional usergroups that were created +# for that user will remain. + +{% from 'users/map.jinja' import reserved_usernames %} + +{% for username, userdeets in pillar.get('users', {}).items() if username not in reserved_usernames %} + {% if 'status' in userdeets %} + {% if userdeets.status == 'absent' %} + +remove_user_{{username}}: + user.absent: + - name: {{ username }} + {% if 'purge' in userdeets %} + - purge: {{ userdeets.purge }} + {% endif %} + - force: True + + {% elif userdeets.status == 'present' %} + + {% if 'node_access' in userdeets %} + {% if grains.role in userdeets.node_access or grains.id.split('_')|last in userdeets.node_access %} + +add_user_group_{{username}}: + group.present: + - name: {{ username }} + {% if 'uid' in userdeets %} + - gid: {{ userdeets.uid }} + {% endif %} + +add_user_{{username}}: + user.present: + - name: {{ username }} + - home: {{ userdeets.get('home', "/home/%s" % username) }} + - shell: {{ userdeets.get('shell', '/bin/bash') }} + - usergroup: True + + {% if 'fullname' in userdeets %} + - fullname: {{ userdeets.fullname }} + {% endif %} + + {% if 'uid' in userdeets %} + - uid: {{ userdeets.uid }} + {% endif %} + + {% if 'gid' in userdeets %} + - gid: {{ userdeets.gid }} + {% endif %} + + {% if 'roomnumber' in userdeets %} + - roomnumber: {{ userdeets.roomnumber }} + {% endif %} + + {% if 'workphone' in userdeets %} + - workphone: {{ userdeets.workphone }} + {% endif %} + + {% if 'homephone' in userdeets %} + - homephone: {{ userdeets.homephone }} + {% endif %} + + {% if 'groups' in userdeets %} + - groups: + {% for group in userdeets.groups %} + - {{ group }} + {% endfor %} + {% endif %} + +{{username}}_authorized_keys: + file.managed: + - name: /home/{{username}}/.ssh/authorized_keys + - source: salt://users/authorized_keys/{{username}} + - user: {{username}} + - group: {{username}} + - mode: 644 + - show_diff: False + - makedirs: True + - require: + - user: add_user_{{username}} + + {% endif %} + {% endif %} + + {% else %} + +unknown_status_or_password_not_provided_for_user_{{username}}: + test.fail_without_changes: + - comment: "Verify status is 'present' or 'absent' and a password is provided for {{username}} in the users pillar." + + {% endif %} + + {% else %} + +status_not_provided_for_user_{{username}}: + test.fail_without_changes: + - comment: "Status should be 'present' or 'absent'." + + {% endif %} +{% endfor %} + +disable_wheel_pwd_required: + file.comment: + - name: /etc/sudoers + - regex: "%wheel\\s+ALL=\\(ALL\\)\\s+ALL" + +allow_wheel_no_pwd: + file.uncomment: + - name: /etc/sudoers + - regex: "%wheel\\s+ALL=\\(ALL\\)\\s+NOPASSWD: ALL" diff --git a/salt/users/map.jinja b/salt/users/map.jinja new file mode 100644 index 000000000..b1f8505ec --- /dev/null +++ b/salt/users/map.jinja @@ -0,0 +1,58 @@ +{% set reserved_usernames = [ + 'root', + 'bin', + 'daemon', + 'adm', + 'lp', + 'sync', + 'shutdown', + 'halt', + 'mail', + 'operator', + 'games', + 'ftp', + 'nobody', + 'systemd-network', + 'dbus', + 'polkitd', + 'tss', + 'sshd', + 'ossec', + 'postfix', + 'chrony', + 'ntp', + 'tcpdump', + 'socore', + 'soremote', + 'elasticsearch', + 'stenographer', + 'suricata', + 'zeek', + 'curator', + 'kratos', + 'kibana', + 'elastalert', + 'ossecm', + 'ossecr', + 'logstash', + 'sys', + 'man', + 'news', + 'uucp', + 'proxy', + 'www-data', + 'backup', + 'list', + 'irc', + 'gnats', + 'systemd-resolve', + 'syslog', + 'messagebus', + '_apt', + 'lxd', + 'uuidd', + 'dnsmasq', + 'landscape', + 'pollinate', + 'ossec' +] %}