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 : prajithparammal@gmail.com
##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