From 6dc7279a258689ee70538d0b002994c0b1402eb0 Mon Sep 17 00:00:00 2001 From: Ludovic Cartier Date: Tue, 17 Dec 2024 17:48:17 +0100 Subject: [PATCH] initial commit --- handlers/main.yml | 5 ++++ tasks/asserts.yml | 6 +++++ tasks/main.yml | 15 +++++++++++ tasks/requirements.yml | 5 ++++ tasks/sshd.yml | 33 +++++++++++++++++++++++ tasks/sudo.yml | 24 +++++++++++++++++ tasks/user.yml | 60 ++++++++++++++++++++++++++++++++++++++++++ templates/sudoers.j2 | 30 +++++++++++++++++++++ 8 files changed, 178 insertions(+) create mode 100644 handlers/main.yml create mode 100644 tasks/asserts.yml create mode 100644 tasks/main.yml create mode 100644 tasks/requirements.yml create mode 100644 tasks/sshd.yml create mode 100644 tasks/sudo.yml create mode 100644 tasks/user.yml create mode 100644 templates/sudoers.j2 diff --git a/handlers/main.yml b/handlers/main.yml new file mode 100644 index 0000000..51e971d --- /dev/null +++ b/handlers/main.yml @@ -0,0 +1,5 @@ +--- +- name: reload sshd + systemd: + name: sshd + state: reloaded diff --git a/tasks/asserts.yml b/tasks/asserts.yml new file mode 100644 index 0000000..9b94e3c --- /dev/null +++ b/tasks/asserts.yml @@ -0,0 +1,6 @@ +--- +- name: assert | check vars + assert: + that: + - users_system is defined + - users_system|length > 0 diff --git a/tasks/main.yml b/tasks/main.yml new file mode 100644 index 0000000..9a1ac08 --- /dev/null +++ b/tasks/main.yml @@ -0,0 +1,15 @@ +--- +- name: asserts + include_tasks: asserts.yml + +- name: requirements + include_tasks: requirements.yml + +- name: create user accounts + include_tasks: user.yml + +- name: configure sudo + include_tasks: sudo.yml + +- name: configure sshd + include_tasks: sshd.yml diff --git a/tasks/requirements.yml b/tasks/requirements.yml new file mode 100644 index 0000000..b8254d5 --- /dev/null +++ b/tasks/requirements.yml @@ -0,0 +1,5 @@ +--- +- name: user | update APT cache + apt: + update_cache: yes + cache_valid_time: 3600 diff --git a/tasks/sshd.yml b/tasks/sshd.yml new file mode 100644 index 0000000..049a1a3 --- /dev/null +++ b/tasks/sshd.yml @@ -0,0 +1,33 @@ +--- +- name: user | disable SSH access for root + replace: + dest: /etc/ssh/sshd_config + regexp: '^PermitRootLogin (yes|without-password|prohibit-password)' + replace: "PermitRootLogin no" + validate: '/usr/sbin/sshd -T -f %s' + notify: reload shd + +#- name: user | verify AllowUsers directive +# command: "grep -E '^AllowUsers' /etc/ssh/sshd_config" +# changed_when: False +# failed_when: False +# register: grep_allowusers_ssh +# +#- name: "add AllowUsers sshd directive" +# lineinfile: +# dest: /etc/ssh/sshd_config +# line: "\nAllowUsers " +# insertafter: 'Subsystem' +# validate: '/usr/sbin/sshd -T -f %s' +# register: allowusers_added +# when: grep_allowusers_ssh.rc != 0 + +#- name: "append username to AllowUsers sshd directive" +# replace: +# dest: /etc/ssh/sshd_config +# regexp: '^(AllowUsers(?!.*\b{{ item.key }}\b).*)$' +# replace: '\1 {{ item.key }}' +# validate: '/usr/sbin/sshd -T -f %s' +# with_dict: "{{ user.name }}" +# when: allowusers_added +# notify: "reload SSH" diff --git a/tasks/sudo.yml b/tasks/sudo.yml new file mode 100644 index 0000000..91f2f98 --- /dev/null +++ b/tasks/sudo.yml @@ -0,0 +1,24 @@ +--- +- name: user | install dependencies for sudo + apt: + name: sudo + +- name: user | ensure sudoers.d is included in config + lineinfile: + dest: /etc/sudoers + line: "#includedir /etc/sudoers.d" + state: present + validate: "/usr/sbin/visudo -cf %s" + with_items: "{{users_system.user|default([])}}" + when: item.sudo is defined + +- name: user | add custom sudoers + template: + src: "{{ item.sudo.template|default('sudoers.j2') }}" + dest: "/etc/sudoers.d/{{ item.name }}" + owner: root + group: root + mode: 0440 + validate: "/usr/sbin/visudo -cf %s" + with_items: "{{users_system.user|default([])}}" + when: ((item.name is defined and item.name != 'root') and (item.state is undefined or (item.state is defined and item.state != 'absent')) and (item.sudo is defined and item.sudo.content is not defined)) diff --git a/tasks/user.yml b/tasks/user.yml new file mode 100644 index 0000000..915b051 --- /dev/null +++ b/tasks/user.yml @@ -0,0 +1,60 @@ +--- +- name: user | create groups + group: + name: "{{ item.group|default(item.name) }}" + system: '{{ item.system|default(omit) }}' + gid: '{{ item.gid|default(omit) }}' + state: '{{ item.state|default("present") }}' + with_flattened : + - "{{users_system.group|default([])}}" + - "{{users_system.user|default([])}}" + when : ((item.name is defined and item.name != 'root')) + +- name: user | create/modify/delete + user: + name: '{{ item.name }}' + group: '{{ item.group|default(item.name) }}' + groups: "{{ item.groups| default([]) | join(',') or omit }}" + append: '{{ item.append|default("yes")}}' + shell: '{{ item.shell|default("/bin/bash") }}' + uid: '{{ item.uid|default(omit) }}' + non_unique: '{{ item.non_unique|default(omit) }}' + state: '{{ item.state|default("present") }}' + comment: '{{ item.comment|default(omit) }}' + password: '{{ item.password|default("!") }}' + update_password: '{{ item.update_password|default("on_create") }}' + system: '{{ item.system|default(omit) }}' + home: '{{ item.home|default(omit) }}' + createhome: '{{ item.createhome|default(omit) }}' + generate_ssh_key: '{{ item.generate_ssh_key|default(omit) }}' + ssh_key_file: '{{ item.ssh_key_file|default(omit) }}' + ssh_key_passphrase: '{{ item.ssh_key_passphrase|default(omit) }}' + ssh_key_type: '{{ item.ssh_key_ssh_key_type|default("rsa") }}' + ssh_key_bits: '{{ item.ssh_key_bits|default(omit) }}' + ssh_key_comment: '{{ item.ssh_key_comment|default(omit) }}' + expires: '{{ item.expires|default(omit) }}' + move_home: '{{ item.move_home|default(omit) }}' + remove : '{{ item.remove|default(omit) }}' + with_items : "{{users_system.user|default([])}}" + no_log: "{{no_log|default(true)}}" + when: ((item.name is defined and item.name != 'root') and (item.state is undefined or (item.state is defined and item.state != 'absent'))) + +- name: user | ensure home directory mode + file: + path: '{{ item.home|default("/home/" + item.name) }}' + state: directory + mode: '{{ item.mode }}' + loop_control: + label: '{{ item.home|default("/home/" + item.name) }}' + when: + - 'item.mode is defined' + - 'item.state|default("present") != "absent"' + with_items: "{{users_system.user|default([])}}" + +- name: user | handle ssh's authorized keys + authorized_key: + user: "{{ item.name }}" + key: "{{ '\n'.join(item.authorized_keys) | string }}" + state: present + with_items : "{{users_system.user}}" + when: ((item.name is defined and item.name != 'root') and (item.state is undefined or (item.state is defined and item.state != 'absent')) and item.authorized_keys is defined) diff --git a/templates/sudoers.j2 b/templates/sudoers.j2 new file mode 100644 index 0000000..56f7c67 --- /dev/null +++ b/templates/sudoers.j2 @@ -0,0 +1,30 @@ +# {{ ansible_managed }} + +{% for k in item.sudo.defaults|default([]) -%} +Defaults{{ ":" ~ item.name }} {{ k }} +{% endfor -%} +{#### Retrocompatiblity section #################} +{% if item.sudo.user is defined and item.sudo.users is not defined -%} +{% set users = item.sudo.user -%} +{% elif item.sudo.users is defined -%} +{% set users = item.sudo.users -%} +{% endif -%} +{% if 'requiretty' not in item.sudo.defaults|default([]) and '!requiretty' not in item.sudo.defaults|default([]) -%} +{{ "Defaults:" ~ item.name ~ " requiretty" if item.sudo.requiretty is defined and item.sudo.requiretty else "" }} +{{ "Defaults:" ~ item.name ~ " !requiretty" if item.sudo.requiretty is defined and not item.sudo.requiretty else "" }} +{% endif -%} +{#### End retrocompatiblity section ############} +{% for alias in item.sudo.runas_alias|default([]) -%} +Runas_Alias {{ alias }} +{% endfor -%} +{% for alias in item.sudo.cmnd_alias|default([]) -%} +Cmnd_Alias {{ alias }} +{% endfor %} +{% for alias in item.sudo.host_alias|default([]) -%} +Host_Alias {{ alias }} +{% endfor %} +{% for alias in item.sudo.user_alias|default([]) -%} +User_Alias {{ alias }} +{% endfor %} +{{ item.name }} {{ item.sudo.hosts|default('ALL') }}={{ "(" ~ users|default('ALL') ~ ":" ~ item.sudo.groups|default('ALL') ~ ")" }} {{ "NOPASSWD:" if item.sudo.nopasswd|default(false) else "" }} {{ item.sudo.commands|default(['ALL'])|join(', ') }} +{{ item.sudo.append if item.sudo.append is defined else '' }}