|
|
@ -6,6 +6,7 @@ |
|
|
|
- openssh-server |
|
|
|
- openssh-server |
|
|
|
- openssh-clients |
|
|
|
- openssh-clients |
|
|
|
when: ansible_os_family == 'RedHat' |
|
|
|
when: ansible_os_family == 'RedHat' |
|
|
|
|
|
|
|
tags: ssh |
|
|
|
|
|
|
|
|
|
|
|
- name: Install ssh components |
|
|
|
- name: Install ssh components |
|
|
|
apt: |
|
|
|
apt: |
|
|
@ -13,28 +14,34 @@ |
|
|
|
- openssh-server |
|
|
|
- openssh-server |
|
|
|
- openssh-client |
|
|
|
- openssh-client |
|
|
|
when: ansible_os_family == 'Debian' |
|
|
|
when: ansible_os_family == 'Debian' |
|
|
|
|
|
|
|
tags: ssh |
|
|
|
|
|
|
|
|
|
|
|
- name: Allow ssh port in SELinux |
|
|
|
- name: Allow ssh port in SELinux |
|
|
|
seport: ports={{ sshd_ports|join(',') }} proto=tcp setype=ssh_port_t state=present |
|
|
|
seport: ports={{ sshd_ports|join(',') }} proto=tcp setype=ssh_port_t state=present |
|
|
|
when: ansible_selinux.status == 'enabled' |
|
|
|
when: ansible_selinux.status == 'enabled' |
|
|
|
|
|
|
|
tags: ssh |
|
|
|
|
|
|
|
|
|
|
|
- name: Combine SSH users |
|
|
|
- name: Combine SSH users |
|
|
|
set_fact: |
|
|
|
set_fact: |
|
|
|
ssh_users: "{{ ssh_users + ssh_extra_users | default([]) }}" |
|
|
|
ssh_users: "{{ ssh_users + ssh_extra_users | default([]) }}" |
|
|
|
|
|
|
|
tags: ssh |
|
|
|
|
|
|
|
|
|
|
|
- name: Deploy sshd configuration |
|
|
|
- name: Deploy sshd configuration |
|
|
|
template: src=sshd_config.j2 dest=/etc/ssh/sshd_config backup=yes |
|
|
|
template: src=sshd_config.j2 dest=/etc/ssh/sshd_config backup=yes |
|
|
|
notify: restart sshd |
|
|
|
notify: restart sshd |
|
|
|
|
|
|
|
tags: ssh |
|
|
|
|
|
|
|
|
|
|
|
- name: Set SSH rate limit |
|
|
|
- name: Set SSH rate limit |
|
|
|
iptables_raw: |
|
|
|
iptables_raw: |
|
|
|
name: sshd_limit |
|
|
|
name: sshd_limit |
|
|
|
rules: "-A INPUT -p tcp -m state --state NEW -m multiport --dports {{ sshd_ports | join(',') }} -m recent --name ssh_limit --set\n |
|
|
|
rules: | |
|
|
|
-A INPUT -p tcp -m state --state NEW -m multiport --dports {{ sshd_ports | join(',') }} -m recent --name ssh_limit --rcheck --seconds 60 --hitcount {{ sshd_max_conn_per_minute }} -j LOG --log-prefix \"Firewall (ssh limit): \"\n |
|
|
|
-A INPUT -p tcp -m state --state NEW -m multiport --dports {{ sshd_ports | join(',') }} -m recent --name ssh_limit --set |
|
|
|
-A INPUT -p tcp -m state --state NEW -m multiport --dports {{ sshd_ports | join(',') }} -m recent --name ssh_limit --rcheck --seconds 60 --hitcount {{ sshd_max_conn_per_minute }} -j REJECT" |
|
|
|
-A INPUT -p tcp -m state --state NEW -m multiport --dports {{ sshd_ports | join(',') }} -m recent --name ssh_limit --rcheck --seconds 60 --hitcount {{ sshd_max_conn_per_minute }} -j LOG --log-prefix "Firewall (ssh limit): " |
|
|
|
|
|
|
|
-A INPUT -p tcp -m state --state NEW -m multiport --dports {{ sshd_ports | join(',') }} -m recent --name ssh_limit --rcheck --seconds 60 --hitcount {{ sshd_max_conn_per_minute }} -j REJECT |
|
|
|
state: "{{ (sshd_max_conn_per_minute > 0) | ternary('present','absent') }}" |
|
|
|
state: "{{ (sshd_max_conn_per_minute > 0) | ternary('present','absent') }}" |
|
|
|
weight: 10 |
|
|
|
weight: 10 |
|
|
|
when: iptables_manage | default(True) |
|
|
|
when: iptables_manage | default(True) |
|
|
|
|
|
|
|
tags: ssh,firewall |
|
|
|
|
|
|
|
|
|
|
|
- name: Handle ssh ports |
|
|
|
- name: Handle ssh ports |
|
|
|
iptables_raw: |
|
|
|
iptables_raw: |
|
|
@ -42,15 +49,18 @@ |
|
|
|
state: "{{ (sshd_src_ip is defined and sshd_src_ip | length > 0) | ternary('present','absent') }}" |
|
|
|
state: "{{ (sshd_src_ip is defined and sshd_src_ip | length > 0) | ternary('present','absent') }}" |
|
|
|
rules: "-A INPUT -m state --state new -p tcp -m multiport --dports {{ sshd_ports | join(',') }} -s {{ sshd_src_ip | join(',') }} -j ACCEPT" |
|
|
|
rules: "-A INPUT -m state --state new -p tcp -m multiport --dports {{ sshd_ports | join(',') }} -s {{ sshd_src_ip | join(',') }} -j ACCEPT" |
|
|
|
when: iptables_manage | default(True) |
|
|
|
when: iptables_manage | default(True) |
|
|
|
|
|
|
|
tags: ssh,firewall |
|
|
|
|
|
|
|
|
|
|
|
- name: Create top level authorized keys directory |
|
|
|
- name: Create top level authorized keys directory |
|
|
|
file: path=/etc/ssh/authorized_keys/ state=directory mode=755 owner=root group=root |
|
|
|
file: path=/etc/ssh/authorized_keys/ state=directory mode=755 owner=root group=root |
|
|
|
|
|
|
|
tags: ssh |
|
|
|
|
|
|
|
|
|
|
|
- name: Create an SSH key pair for root |
|
|
|
- name: Create an SSH key pair for root |
|
|
|
user: |
|
|
|
user: |
|
|
|
name: root |
|
|
|
name: root |
|
|
|
generate_ssh_key: yes |
|
|
|
generate_ssh_key: yes |
|
|
|
ssh_key_file: .ssh/id_rsa |
|
|
|
ssh_key_file: .ssh/id_rsa |
|
|
|
|
|
|
|
tags: ssh |
|
|
|
|
|
|
|
|
|
|
|
# Do this in two times, to prevent hitting a bug in ansible |
|
|
|
# Do this in two times, to prevent hitting a bug in ansible |
|
|
|
# where usermod could be called before useradd |
|
|
|
# where usermod could be called before useradd |
|
|
@ -61,15 +71,18 @@ |
|
|
|
with_items: "{{ ssh_users }}" |
|
|
|
with_items: "{{ ssh_users }}" |
|
|
|
register: ssh_create_user |
|
|
|
register: ssh_create_user |
|
|
|
when: item.create_user | default(False) |
|
|
|
when: item.create_user | default(False) |
|
|
|
|
|
|
|
tags: ssh |
|
|
|
|
|
|
|
|
|
|
|
- name: Check if sssd is installed |
|
|
|
- name: Check if sssd is installed |
|
|
|
stat: path=/usr/sbin/sss_cache |
|
|
|
stat: path=/usr/sbin/sss_cache |
|
|
|
register: ssh_sss_cache |
|
|
|
register: ssh_sss_cache |
|
|
|
|
|
|
|
tags: ssh |
|
|
|
|
|
|
|
|
|
|
|
# Flush sss cache so we can modify freshly created users |
|
|
|
# Flush sss cache so we can modify freshly created users |
|
|
|
- name: Reset sss cache |
|
|
|
- name: Reset sss cache |
|
|
|
command: sss_cache -E |
|
|
|
command: sss_cache -E |
|
|
|
when: ssh_sss_cache.stat.exists and ssh_create_user.results | selectattr('changed','equalto',True) | list | length > 0 |
|
|
|
when: ssh_sss_cache.stat.exists and ssh_create_user.results | selectattr('changed','equalto',True) | list | length > 0 |
|
|
|
|
|
|
|
tags: ssh |
|
|
|
|
|
|
|
|
|
|
|
- name: Set ssh user attributes |
|
|
|
- name: Set ssh user attributes |
|
|
|
user: |
|
|
|
user: |
|
|
@ -78,11 +91,13 @@ |
|
|
|
shell: "{{ item.shell | default(omit) }}" |
|
|
|
shell: "{{ item.shell | default(omit) }}" |
|
|
|
with_items: "{{ ssh_users }}" |
|
|
|
with_items: "{{ ssh_users }}" |
|
|
|
when: item.create_user | default(False) |
|
|
|
when: item.create_user | default(False) |
|
|
|
|
|
|
|
tags: ssh |
|
|
|
|
|
|
|
|
|
|
|
- name: Create private dir for Authorized keys |
|
|
|
- name: Create private dir for Authorized keys |
|
|
|
file: path=/etc/ssh/authorized_keys/{{ item.name }} state=directory mode=700 owner={{ item.name }} |
|
|
|
file: path=/etc/ssh/authorized_keys/{{ item.name }} state=directory mode=700 owner={{ item.name }} |
|
|
|
ignore_errors: True # Needed eg, if LDAP isn't available on first run |
|
|
|
ignore_errors: True # Needed eg, if LDAP isn't available on first run |
|
|
|
with_items: "{{ ssh_users }}" |
|
|
|
with_items: "{{ ssh_users }}" |
|
|
|
|
|
|
|
tags: ssh |
|
|
|
|
|
|
|
|
|
|
|
- name: Deploy ssh user keys |
|
|
|
- name: Deploy ssh user keys |
|
|
|
authorized_key: |
|
|
|
authorized_key: |
|
|
@ -95,6 +110,7 @@ |
|
|
|
ignore_errors: True # Needed eg, if LDAP isn't available on first run |
|
|
|
ignore_errors: True # Needed eg, if LDAP isn't available on first run |
|
|
|
#when: item.ssh_keys is defined |
|
|
|
#when: item.ssh_keys is defined |
|
|
|
with_items: "{{ ssh_users }}" |
|
|
|
with_items: "{{ ssh_users }}" |
|
|
|
|
|
|
|
tags: ssh |
|
|
|
|
|
|
|
|
|
|
|
- name: Ensure permissions and ownership on authorized_keys files |
|
|
|
- name: Ensure permissions and ownership on authorized_keys files |
|
|
|
file: |
|
|
|
file: |
|
|
@ -104,16 +120,20 @@ |
|
|
|
when: item.ssh_keys is defined |
|
|
|
when: item.ssh_keys is defined |
|
|
|
ignore_errors: True |
|
|
|
ignore_errors: True |
|
|
|
with_items: "{{ ssh_users }}" |
|
|
|
with_items: "{{ ssh_users }}" |
|
|
|
|
|
|
|
tags: ssh |
|
|
|
|
|
|
|
|
|
|
|
- name: List all authorized keys directories |
|
|
|
- name: List all authorized keys directories |
|
|
|
shell: ls -1 /etc/ssh/authorized_keys | xargs -n1 basename |
|
|
|
shell: ls -1 /etc/ssh/authorized_keys | xargs -n1 basename |
|
|
|
register: existing_ssh_keys |
|
|
|
register: existing_ssh_keys |
|
|
|
changed_when: False |
|
|
|
changed_when: False |
|
|
|
|
|
|
|
tags: ssh |
|
|
|
|
|
|
|
|
|
|
|
- name: Remove unmanaged ssh keys |
|
|
|
- name: Remove unmanaged ssh keys |
|
|
|
file: path=/etc/ssh/authorized_keys/{{ item }} state=absent |
|
|
|
file: path=/etc/ssh/authorized_keys/{{ item }} state=absent |
|
|
|
with_items: "{{ existing_ssh_keys.stdout_lines | default([]) }}" |
|
|
|
with_items: "{{ existing_ssh_keys.stdout_lines | default([]) }}" |
|
|
|
when: item not in ssh_users | map(attribute='name') |
|
|
|
when: item not in ssh_users | map(attribute='name') |
|
|
|
|
|
|
|
tags: ssh |
|
|
|
|
|
|
|
|
|
|
|
- name: Deploy sudo fragment |
|
|
|
- name: Deploy sudo fragment |
|
|
|
template: src=sudo.j2 dest=/etc/sudoers.d/ssh_users mode=600 |
|
|
|
template: src=sudo.j2 dest=/etc/sudoers.d/ssh_users mode=600 |
|
|
|
|
|
|
|
tags: ssh |
|
|
|