SSSD AD integration on RHEL7 using Ansible

Prajith Parammal

Linux Specialist

Latest posts by Prajith Parammal (see all)

Image : https://defendernetwork.com

Most of the time , we have requirement to integrate Linux systems in our environment with AD for Centralized user management. It will be tedious , if we have 100+ or more Linux servers in the environment. Below is the end to end playbook for sssd AD integration on Red hat servers.

#author : [email protected]
##Version : 1.0
- name: Install and configure AD authentication
  hosts: all_linux
  vars_prompt:
    - name: "bind_password"
      prompt: "Password for AD admin user"
      private: yes
  vars_files:
    - ./Answer_file

###############################################
  tasks:
    - name: Install necessary rpms for sssd config
      yum:
        name: libselinux-python,realmd,oddjob,oddjob-mkhomedir,sssd,adcli,samba-common-tools
        state: present

###############################################
    - name: Check if machine is bound
      shell: /bin/bash -c "getent passwd  {{ ad_login_test_user }}@{{ addomain }} | grep {{ ad_login_test_user }}"
      register: realmd_bound
      changed_when: false
      ignore_errors: true
###############################################
    - name: leaving Realm
      command: /bin/bash -c "realm leave"
      when: realmd_bound|failed
      ignore_errors: true
###############################################
    - name: Removing existing config files
      file:
        path: "{{ item }}"
        state: absent
      with_items:
        - /etc/krb5.keytab
        - /var/lib/sss/db/*
        - /var/log/sssd/*
        - /etc/sssd/sssd.conf
        - /etc/sudoers.d/installSssd
      when: realmd_bound|failed
###############################################
    - name: Copy Pam.d files
      copy: src={{ item.src }} dest={{ item.dest }}
      with_items:
        - { src: '/etc/pam.d/system-auth-ac', dest: '/etc/pam.d/system-auth-ac.0' }
        - { src: '/etc/pam.d/password-auth-ac', dest: '/etc/pam.d/password-auth-ac.0' }
      when: realmd_bound|failed
      ignore_errors: true
###############################################
    - name: Creating symlink system-auth and password-auth
      file: src={{ item.src }} dest={{ item.dest }} state=link
      with_items:
        - { src: '/etc/pam.d/system-auth-ac', dest: '/etc/pam.d/system-auth' }
        - { src: '/etc/pam.d/password-auth-ac', dest: '/etc/pam.d/password-auth' }
      when: realmd_bound|failed
      ignore_errors: true
###############################################
    - name: Join system to AD and put the computer object in the Linux OU
      command: /bin/bash -c "echo {{ bind_password }} | realm join --user={{ ad_join_admin }} {{ addomain }} && sleep 10"
      no_log: True
      when: realmd_bound|failed
###############################################
    - name: Stopping sssd service
      service:
        name: sssd
        state: stopped
      when: realmd_bound|failed
###############################################
    - name: Removing logs and db files
      file:
        path: "{{ item }}"
        state: absent
      with_items:
        - /var/lib/sss/db/*
        - /var/log/sssd/*
      when: realmd_bound|failed
###############################################
    - name: Adding DOmain SID to sssd.conf
      blockinfile:
        path: /etc/sssd/sssd.conf
        block: |
          ldap_idmap_default_domain_sid={{ domainsid }}
          dyndns_update = false
          ldap_use_tokengroups = True
          ldap_group_nesting_level = 0
          ldap_groups_use_matching_rule_in_chain = True
          ldap_initgroups_use_matching_rule_in_chain = True
      notify:
        - restart sssd
###############################################
    - name: Setting default domain to login
      lineinfile:
        dest: /etc/sssd/sssd.conf
        line: 'default_domain_suffix = {{ addomain }}'
        insertafter: '^\[sssd\]'
###############################################
    - name: Starting sssd
      service:
        name: sssd
        state: started
        enabled: yes
      when: realmd_bound|failed
###############################################
    - name: Restrict access based on specific ad group
      command: /bin/bash -c "/usr/sbin/realm permit -g {{ group_list }}"
      notify:
        - restart sssd

    - name: Clearing and updating sssd sudo groups
      file:
        path: /etc/sudoers.d/installSssd
        state: absent

    - name: Add sudoers groups for cassandra systems
      lineinfile:
        dest: /etc/sudoers.d/installSssd
        line: "%{{ item }}@{{ addomain }} ALL=(ALL) NOPASSWD: ALL"
        create: yes
      with_items: "{{ all_cassandra_sudo_list }}"
      when: inventory_hostname in groups['all_cassandra']
      ignore_errors: true

    - name: Add sudoers groups for ora db systems
      lineinfile:
        dest: /etc/sudoers.d/installSssd
        line: "%{{ item }}@{{ addomain }} ALL=(ALL) NOPASSWD: ALL"
        create: yes
      with_items: "{{ oracle_sudo_list }}"
      when: inventory_hostname in groups['oracle']
      ignore_errors: true

    - name: Add sudoers groups for ora db systems
      lineinfile:
        dest: /etc/sudoers.d/installSssd
        line: "%{{ item }}@{{ addomain }} ALL=(ALL) NOPASSWD: ALL"
        create: yes
      with_items: "{{ wave1_sudo_list }}"
      when: inventory_hostname in groups['wave1']
      ignore_errors: true

    - name: Add sudoers groups for ora db systems
      lineinfile:
        dest: /etc/sudoers.d/installSssd
        line: "%{{ item }}@{{ addomain }} ALL=(ALL) NOPASSWD: ALL"
        create: yes
      with_items: "{{ ldap_sudo_list }}"
      when: inventory_hostname in groups['ldap']
      ignore_errors: true

    - name: Add sudoers groups for ora db systems
      lineinfile:
        dest: /etc/sudoers.d/installSssd
        line: "%{{ item }}@{{ addomain }} ALL=(ALL) NOPASSWD: ALL"
        create: yes
      with_items: "{{ wave2_sudo_list }}"
      when: inventory_hostname in groups['wave2']
      ignore_errors: true


###############################################
    - name: configure root history by SUDOER
      blockinfile:
        path: /root/.bashrc
        block: |
          HISTFILE="$HOME/.bash_history_${SUDO_USER}_$(date '+%F_%T')"
          export HISTFILE
      when: realmd_bound|failed
###############################################
  handlers:
    - name: restart sssd
      service:
        name: sssd
        state: restarted

Above playbook works with inventory file (obviously) and a variable file (here, Answer_file). You can refer to below examples for creating both and make changes to the values as per your infrastructure.

Sample Answer_file File:

Basically it contains all the sudo groups that you want to add for a specific group of servers in your host or inventory file. When ever you have a new set of sudo group for your new server group , you need to add entries as below in this Answer_file and update main playbook task to cater those. ( as in example task name: Add sudoers groups for ora db systems in above playbook)

all_cassandra_sudo_list:
  - LNX-Admins-GG
  - CAS-Admins-GG
  - ROS_SYSOPS_ADMINS

oracle_sudo_list:
  - LNX-Admins-GG
  - ROS_SYSOPS_ADMINS
  - ORC-Admins-GG

wave1_sudo_list:
  - LNX-Admins-GG
  - ROS_SYSOPS_ADMINS

ldap_sudo_list:
  - LNX-Admins-GG
  - ROS_SYSOPS_ADMINS

wave2_sudo_list:
  - LNX-Admins-GG
  - ROS_SYSOPS_ADMINS

Sample hosts file

[all_linux:children]
all_cassandra
oracle
wave1
ldap
wave2

[all_linux:vars]
domainsid=S-1-5-21-xxx-xxxx-xxxx--xxx-xxxx  ## must get domain-sid of your domain network; use command get-ADDomain powershell command)
ad_join_admin=svc_msv_ad_join ## Admin user info which can join linux machine to specific AD
ad_login_test_user=parapra  # Name of any AD user name which you can query to make sure sssd is able to fetch info if it is successfully joined to AD.
addomain=test.local ## name of your Domain 

[all_cassandra:children]
cassandra
cassandra_with_terabytes_filesystem

[all_cassandra:vars]
group_list=LNX-Admins-GG CAS-Admins-GG ## group list should be specific to let the play book know which AD groups is allowed for a particular server group

[cassandra]
DERSSBHCAS401 ansible_host=10.154.132.211
DERSSBHCAS402 ansible_host=10.154.132.212


[cassandra_with_terabytes_filesystem]
DERSSBHCAS303 ansible_host=10.154.132.243
DERSSBHCAS304 ansible_host=10.154.132.244


[oracle]
DERSSBHORC250 ansible_host=10.154.132.233
DERSSBHORC350 ansible_host=10.154.132.234

[oracle:vars]
group_list=LNX-Admins-GG ORC-Admins-GG ## group list should be specific to let the play book know which AD groups is allowed for a particular server group

[wave1]
DERSSBHGW401 ansible_host=10.154.132.217
DERSSBHGW402 ansible_host=10.154.132.218


[wave1:vars]
group_list=LNX-Admins-GG ## group list should be specific to let the play book know which AD groups is allowed for a particular server group

[ldap]
DERSSBHLDP001A ansible_host=10.154.132.231
DERSSBHLDP001B ansible_host=10.154.132.232

[ldap:vars]
group_list=LNX-Admins-GG ## group list should be specific to let the play book know which AD groups is allowed for a particular server group

[wave2]
DERSSBHGW301 ansible_host=10.154.132.166
DERSSBHGW302 ansible_host=10.154.132.167


[wave2:vars]
group_list=LNX-Admins-GG ## group list should be specific to let the play book know which AD groups is allowed for a particular server group

Please leave any queries or doubts which you don’t understand, I am more than happy to clear it out. Thank you

Prajith Parammal

Linux Specialist

You may also like...

Leave a Reply

avatar

This site uses Akismet to reduce spam. Learn how your comment data is processed.

  Subscribe  
Notify of
%d bloggers like this: