Skip to content

Instantly share code, notes, and snippets.

@fltd
Last active June 18, 2018 04:00
Show Gist options
  • Save fltd/fb094d64463d8aad64941aed5a0e2784 to your computer and use it in GitHub Desktop.
Save fltd/fb094d64463d8aad64941aed5a0e2784 to your computer and use it in GitHub Desktop.
Fix for pamd issue on Ansible 2.5.5 - roles/galaxy/dev-sec.ssh-hardening/tasks/main.yml

Temporary fix for pamd issue on Ansible 2.5.5

There is a problem with pamd module on Ansible 2.5.5, below is the stack trace captured

Traceback (most recent call last):
  File \"/tmp/ansible_HKVSfA/ansible_module_pamd.py\", line 691, in <module>
    main()
  File \"/tmp/ansible_HKVSfA/ansible_module_pamd.py\", line 645, in main
    pamd.load_rules_from_file()
  File \"/tmp/ansible_HKVSfA/ansible_module_pamd.py\", line 361, in load_rules_from_file
    self.load_rules_from_string(stringline.replace(\"\\\\\
\", \"\"))
  File \"/tmp/ansible_HKVSfA/ansible_module_pamd.py\", line 380, in load_rules_from_string
    self.rules.append(PamdRule.rulefromstring(stringline))
  File \"/tmp/ansible_HKVSfA/ansible_module_pamd.py\", line 312, in rulefromstring
    rule_type = result.group(1)
AttributeError: 'NoneType' object has no attribute 'group'

This temporary fix switch the operation from pamd module to lineinfile module.

I have spotted the pamd.py file has been hugely changed by a commit https://github.com/ansible/ansible/pull/35709/files#diff-305b0e63652b5c15641b13a5261b9d80, hopefully this issue will get fixed.

---
- name: Set OS dependent variables
include_vars: "{{ item }}"
with_first_found:
- "{{ ansible_distribution }}_{{ ansible_distribution_major_version }}.yml"
- "{{ ansible_distribution }}.yml"
- "{{ ansible_os_family }}_{{ ansible_distribution_major_version }}.yml"
- "{{ ansible_os_family }}.yml"
- name: get openssh-version
shell: ssh -V 2>&1 | sed -r 's/.*_([0-9]*\.[0-9]).*/\1/g'
args:
executable: /bin/sh
changed_when: false
register: sshd_version
check_mode: no
- include_tasks: crypto.yml
- name: create revoked_keys and set permissions to root/600
template: src='revoked_keys.j2' dest='/etc/ssh/revoked_keys' mode=0600 owner="{{ ssh_owner }}" group="{{ ssh_group }}"
notify: restart sshd
when: ssh_server_hardening
- name: create sshd_config and set permissions to root/600
template: src='opensshd.conf.j2' dest='/etc/ssh/sshd_config' mode=0600 owner="{{ ssh_owner }}" group="{{ ssh_group }}" validate="/usr/sbin/sshd -T -f %s"
notify: restart sshd
when: ssh_server_hardening
- name: create ssh_config and set permissions to root/644
template: src='openssh.conf.j2' dest='/etc/ssh/ssh_config' mode=0644 owner="{{ ssh_owner }}" group="{{ ssh_group }}"
when: ssh_client_hardening
- name: Check if /etc/ssh/moduli contains weak DH parameters
shell: awk '$5 < {{ sshd_moduli_minimum }}' /etc/ssh/moduli
register: sshd_register_moduli
changed_when: false
check_mode: no
- name: remove all small primes
shell: awk '$5 >= {{ sshd_moduli_minimum }}' /etc/ssh/moduli > /etc/ssh/moduli.new ;
[ -r /etc/ssh/moduli.new -a -s /etc/ssh/moduli.new ] && mv /etc/ssh/moduli.new /etc/ssh/moduli || true
notify: restart sshd
when: sshd_register_moduli.stdout
- include_tasks: ca_keys_and_principals.yml
when: ssh_trusted_user_ca_keys_file != ''
- name: test to see if selinux is installed and running
command: getenforce
register: sestatus
failed_when: false
changed_when: false
check_mode: no
# Install the 2FA packages and setup the config in PAM and SSH
- block:
- name: Install google authenticator PAM module
apt: name=libpam-google-authenticator state=present
when: ansible_distribution == 'Debian' or ansible_distribution == 'Ubuntu'
- name: Install google authenticator PAM module
yum: name=google-authenticator state=present
when: ansible_os_family == 'RedHat' or ansible_os_family == 'Oracle Linux'
- name: Add google auth module to PAM
# pamd doesn't work for now (@ansible 2.5.5)
# Temporarily switch to lineinfile
# https://serverfault.com/questions/913310/modifying-pam-with-ansible
# pamd:
# name: sshd
# type: auth
# control: required
# module_path: pam_google_authenticator.so
lineinfile:
path: /etc/pam.d/sshd
regexp: '^#\s*auth\s+required\s+pam_google_authenticator\.so(\s+#\s*\[.*\])?$'
line: "auth required pam_google_authenticator.so"
insertafter: ".*include.*common-auth"
state: present
- name: Remove password auth from PAM
# pamd doesn't work for now (@ansible 2.5.5)
# Temporarily switch to lineinfile
# https://serverfault.com/questions/913310/modifying-pam-with-ansible
# pamd:
# name: sshd
# type: auth
# control: substack
# module_path: password-auth
# state: absent
lineinfile:
path: /etc/pam.d/login
regexp: '^#\s*auth\s+substack\s+password-auth(\s+#\s*\[.*\])?$'
state: absent
when: ansible_distribution == 'RedHat' or ansible_distribution == 'Oracle Linux' or ansible_distribution == 'Amazon'
- name: Remove password auth from PAM
replace:
dest: /etc/pam.d/sshd
regexp: '^@include common-auth'
replace: '#@include common-auth'
when: ansible_distribution == 'Debian' or ansible_distribution == 'Ubuntu'
when:
- ssh_use_pam
- ssh_challengeresponseauthentication
- ssh_google_auth
- block: # only runs when selinux is installed
- name: install selinux dependencies when selinux is installed on RHEL or Oracle Linux
package: name="{{item}}" state=present
with_items:
- policycoreutils-python
- checkpolicy
when: ansible_os_family == 'RedHat' or ansible_os_family == 'Oracle Linux'
- name: install selinux dependencies when selinux is installed on Debian or Ubuntu
apt: name="{{item}}" state=present
with_items:
- policycoreutils
- checkpolicy
when: ansible_distribution == 'Debian' or ansible_distribution == 'Ubuntu'
- name: check if ssh_password module is already installed
shell: "semodule -l | grep ssh_password"
register: ssh_password_module
failed_when: false
changed_when: false
check_mode: no
# The following tasks only get executed when selinux is in state enforcing, UsePam is "no" and the ssh_password module is installed.
# See this issue for more info: https://github.com/hardening-io/ansible-ssh-hardening/issues/23
- block:
- name: Create selinux custom policy drop folder
file: path='{{ ssh_custom_selinux_dir }}' state=directory owner=root group=root mode=0750
- name: Distributing custom selinux policies
copy: src='ssh_password' dest='{{ ssh_custom_selinux_dir }}'
- name: check and compile policy
shell: checkmodule -M -m -o {{ ssh_custom_selinux_dir }}/ssh_password.mod {{ ssh_custom_selinux_dir }}/ssh_password
- name: create selinux policy module package
shell: semodule_package -o {{ ssh_custom_selinux_dir }}/ssh_password.pp -m {{ ssh_custom_selinux_dir }}/ssh_password.mod
- name: install selinux policy
shell: semodule -i {{ ssh_custom_selinux_dir }}/ssh_password.pp
when: not ssh_use_pam and sestatus.stdout != 'Disabled' and ssh_password_module.stdout.find('ssh_password') != 0
# The following tasks only get executed when selinux is installed, UsePam is "yes" and the ssh_password module is installed.
- name: remove selinux-policy when Pam is used, because Allowing sshd to read the shadow file directly is considered a potential security risk (http://danwalsh.livejournal.com/12333.html)
command: semodule -r ssh_password
when: ssh_use_pam and ssh_password_module.stdout.find('ssh_password') == 0
when: sestatus.rc == 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment