Get up to 50% off on CKA, CKAD, CKS, KCNA, KCSA exams and courses!

SSSD AD integration on RHEL7 using Ansible

SSSD AD integration on RHEL7 using Ansible
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

Share :

Related Posts

Ansible Nested Loop with List and Dictionary

Ansible loops are simple and powerful with mixed data. You will sure say “awesome” when you realize the easiness with loops.

Running Ansible Ad-Hoc commands

Running Ansible Ad-Hoc commands

We have already run few ad-hoc command to list down the hosts in earlier sections.

How to Create, Increase or Decrease Project Quota in OpenShift

How to Create, Increase or Decrease Project Quota in OpenShift

Image Credit : https://www.joc.com Usually application owner or project owner will specify the quota settings (Memory and CPU) during project …

OpenShift Cluster – How to Drain or Evacuate a Node for Maintenance

OpenShift Cluster – How to Drain or Evacuate a Node for Maintenance

Image : www.oemoffhighway.com As we know OpenShift clusters are bundled with multiple compute nodes, master nodes, infra nodes etc, it’s not a big …

OpenShift Container Platform 3.11 Installation Documents

OpenShift Container Platform 3.11 Installation Documents

Since OCP 3.11 is available now, you may refer below documents for OpenShift Container Platform 3.11 Installation on different infrastructure or …

Ansible and Jenkins integration – Red Hat Webinar

Ansible and Jenkins integration – Red Hat Webinar

Join this Red Hat webinar to see how to use Jenkins pipelines to deploy simple applications using Ansible Tower.