Pages

Automating User Creation on Multiple Linux Servers Using Bash and CSV

Managing user accounts across multiple Linux servers can quickly become repetitive and error-prone. In this post, we walk through a Bash-based automation approach that creates users on multiple remote servers using a CSV input file.
This solution is ideal for system administrators who want a simple, SSH-based alternative to heavier tools while still maintaining consistency and control.

Overview
The script:
  • Reads user details from a CSV file
  • Creates primary groups with specific GIDs
  • Adds users to up to three secondary groups
  • Creates users only if they do not already exist
  • Executes the process on multiple remote servers passed as arguments
CSV File Format
The script expects the following CSV structure:
user_id,
user_pri_group,
user_pri_group_id,
user_sec_group1,
user_sec_group2,
user_sec_group3,
user_home_dir,
user_shell,
user_password,
user_gecos_info

Sample CSV Input
# user_id,user_pri_group,user_pri_group_id,user_sec_group1,user_sec_group2,user_sec_group3,user_home_dir,user_shell,user_password,user_gecos_info

tasleem,tasleem,1005,apps,dba,sysadm,/home/tasleem,/bin/bash,root123,Tasleem Ahmed Khan
hamzah,hamzah,1006,apps,dba,sysadm,/home/hamzah,/bin/bash,root123,Hamzah Ali Khan

Primary Group Enforcement
The primary group name and GID must be present. If missing, user creation is skipped.

Secondary Group Handling
Up to three secondary groups are supported.
If a group does not exist, it is created automatically.

Idempotent Execution

If a user already exists, the script safely skips creation.

Multi-Server Support
The same CSV file is applied to all servers passed on the command line.

Bash Script
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
#!/bin/bash
#
# Author : adminCtrlX
# Description : Automating User Creation on Multiple Linux Servers Using Bash and CSV
# Usage : ./create_users_remote.sh host1 host2 host3
#

CSV_FILE="/tmp/scripts/users.csv"

if [ $# -lt 1 ]; then
echo "Usage: $0 host1 host2 ... hostN"
exit 1
fi

HOSTS="$@"

tail -n +2 "$CSV_FILE" | while IFS=',' read -r \
user_id pri_group pri_gid sec_grp1 sec_grp2 sec_grp3 home_dir shell password gecos
do
for server in $HOSTS; do
echo "Processing user $user_id on $server..."

ssh "$server" sudo bash <<EOF

if [ -z "$pri_group" ] || [ -z "$pri_gid" ]; then
echo "Primary group or GID missing for $user_id. Skipping."
exit 0
fi

if ! getent group "$pri_group" >/dev/null; then
groupadd -g "$pri_gid" "$pri_group"
fi

SEC_GROUPS=""
for grp in "$sec_grp1" "$sec_grp2" "$sec_grp3"; do
if [ -n "\$grp" ]; then
getent group "\$grp" >/dev/null || groupadd "\$grp"
SEC_GROUPS="\$SEC_GROUPS,\$grp"
fi
done

SEC_GROUPS="\${SEC_GROUPS#,}"

if ! id "$user_id" >/dev/null 2>&1; then
useradd \
-g "$pri_group" \
\${SEC_GROUPS:+-G "\$SEC_GROUPS"} \
-d "$home_dir" \
-s "$shell" \
-c "$gecos" \
-m "$user_id"

echo "$user_id:$password" | chpasswd
echo "User $user_id created successfully on $server"
else
echo "User $user_id already exists on $server"
fi
EOF
done
done
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

How to Run the Script
1. Make the script executable:
# chmod +x create_users_remote.sh

2. Execute it by passing the target servers:
# ./create_users_remote.sh server1 server2 server3

Security Considerations
Storing plain-text passwords in CSV files is not recommended for production environments. Consider:
  • Using hashed passwords
  • Forcing password change on first login
  • Using SSH keys instead of passwords
Conclusion
This Bash-based approach provides a lightweight yet effective way to manage users across multiple Linux servers. It is easy to understand, easy to modify, and suitable for small to medium-scale environments where full configuration management tools may not be required.

Installing Atlassian Jira Software 8.19.0 on RHEL 10

Atlassian Jira is a widely used issue and project tracking tool. In this post, we’ll walk through the installation of Jira Software 8.19.0 on Red Hat Enterprise Linux (RHEL) 10 using the official Linux installer (.bin). This guide assumes you are logged in as the root user.

Prerequisites
Before starting, ensure:
  • RHEL 10 is installed and running
  • You have root or sudo privileges
  • Required ports are free: 8080 (HTTP) & 8005 (Control/RMI)
  • At least 2 GB RAM (4 GB recommended)
Step 1: Download the Jira Installer
Download the Jira Software binary installer from Atlassian’s official site (https://www.atlassian.com/software/jira/download/data-center) and place it in your working directory (for example, /tmp).
Example file:
atlassian-jira-software-8.19.0-x64.bin

Step 2: Make the Installer Executable
Change the file permissions to make the installer executable:
# chmod 775 atlassian-jira-software-8.19.0-x64.bin
Verify permissions:
# ll
Output:
-rwxrwxr-x 1 root root 462430556 Sep 15 2021 atlassian-jira-software-8.19.0-x64.bin

Step 3: Run the Jira Installer
Start the installation:
# ./atlassian-jira-software-8.19.0-x64.bin
The installer will unpack its bundled JRE and launch the setup wizard.

Step 4: Installer Configuration Options
During installation, select the following options:
Installation Type
Choose:
Custom Install (recommended for advanced users)
Installation Directory
/opt/atlassian/jira
Jira Home (Data Directory)
/var/atlassian/application-data/jira
Ports Configuration
Use default ports:
HTTP Port: 8080
Control (RMI) Port: 8005

Run Jira as a Service
Choose:
Yes
This ensures Jira starts automatically on system reboot.

Step 5: Confirm Installation Settings
Summary displayed by the installer:
Installation Directory: /opt/atlassian/jira
Home Directory: /var/atlassian/application-data/jira
HTTP Port: 8080
RMI Port: 8005
Install as Service: Yes
Proceed by selecting Install.

Step 6: Start Jira Software
Once the installation completes, choose:
Start Jira Software 8.19.0 now? Yes
The installer will start Jira and register it as a system service.

Step 7: Access Jira Web Interface
After startup, Jira becomes accessible at:
http://localhost:8080
When you open this URL in your browser, you will see the initial setup screen with two options:

Choose the option that best fits your environment. and login google account

Next show server IP address Example 192.168.10.120 & confirm 
Next Setup Administrator account then Next 
Continue with English 
The screen will show as below and you can create project & import issue.
Conclusion
You have successfully installed Atlassian Jira Software 8.19.0 on RHEL 10 using the official Linux installer. Jira is now running as a service and ready for initial configuration via the web interface.

This setup is ideal for:
Agile project management
Issue tracking
Enterprise team collaboration

Automating Multi-Host Active Directory Join on Linux

Managing Linux servers in an Active Directory (AD) environment can be tedious, especially when you have multiple hosts that need to join the domain. Doing this manually is time-consuming, error-prone, and inconsistent.
In this post, I’ll share a fully automated, secure, and parallelized Bash script that allows you to join multiple Linux hosts to an AD domain, configure SSSD, home directories, and sudo permissions for AD groups — all in one go.

Why Automation Matters
  • Manually joining Linux hosts to AD can involve:
  • Installing the required packages (realmd, sssd, adcli, etc.)
  • Editing /etc/resolv.conf and /etc/hosts
  • Configuring Kerberos encryption
  • Joining the AD domain using credentials
  • Setting up SSSD and home directory creation
  • Granting sudo privileges to AD groups
Doing this across 10, 50, or 100 hosts is not scalable. With this script, it becomes:
Secure – prompts once for your AD password and never stores it in plain text.
Parallel – all hosts are processed simultaneously for faster deployment.
Robust – logs are kept per host, so troubleshooting is easier.

The Script: Multi-Host AD Join
Below is the script. Save it as ad_join_multi_pw.sh, make it executable with chmod +x ad_join_multi_hosts.sh, and run it with your hostnames as arguments:
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
#!/bin/bash
#
# Author : adminCtrlX
# Description : Multi-host AD join with secure password prompt, parallel execution, logs
# Usage : ./ad_join_multi_hosts.sh host1 host2 host3
#
set -euo pipefail

### CHECK ARGUMENTS ###
if [ $# -lt 1 ]; then
echo "Usage: $0 <hostname1> [hostname2 ...]"
exit 1
fi

HOSTS=("$@")
AD_ADMIN="administrator"
AD_SERVER_FQDN="inddcpads01.ppc.com"
DOMAIN="ppc.com"
REALM="PPC.COM"
AD_GROUP="unix_admin"

# Prompt once for the AD password
read -s -p "Enter AD password for $AD_ADMIN: " AD_PASSWORD
echo
echo "===== Starting AD Integration for ${#HOSTS[@]} host(s) ====="

for TARGET_HOST in "${HOSTS[@]}"; do
(
LOG_FILE="/tmp/ad_join_${TARGET_HOST}.log"
echo "===== Starting AD join on $TARGET_HOST =====" | tee -a "$LOG_FILE"

ssh -q root@"$TARGET_HOST" bash -s "$DOMAIN" "$REALM" "$AD_SERVER_FQDN" "$AD_GROUP" "$AD_ADMIN" "$AD_PASSWORD" >> "$LOG_FILE" 2>&1 <<'REMOTE_EOF'

set -euo pipefail

# Assign positional parameters
DOMAIN="$1"
REALM="$2"
AD_SERVER_FQDN="$3"
AD_GROUP="$4"
AD_ADMIN="$5"
AD_PASSWORD="$6"
RESOLV_CONF="/etc/resolv.conf"
HOSTS_FILE="/etc/hosts"
SSSD_CONF="/etc/sssd/sssd.conf"
KRB_CRYPTO="/etc/krb5.conf.d/crypto-policies"
SUDOERS_FILE="/etc/sudoers.d/unix_admin"

echo "===== Running AD Integration on $(hostname) ====="

# Install required packages
dnf install -y realmd sssd oddjob oddjob-mkhomedir adcli samba-common-tools krb5-workstation

# Configure DNS (append safely)
grep -q "$DOMAIN" "$RESOLV_CONF" || echo "search $DOMAIN" >> "$RESOLV_CONF"
grep -q "192.168.10.100" "$RESOLV_CONF" || echo "nameserver 192.168.10.100" >> "$RESOLV_CONF"
grep -q "192.168.20.100" "$RESOLV_CONF" || echo "nameserver 192.168.20.100" >> "$RESOLV_CONF"

# Update /etc/hosts if missing
grep -q "$AD_SERVER_FQDN" "$HOSTS_FILE" || echo "192.168.10.100 $AD_SERVER_FQDN inddcpads01" >> "$HOSTS_FILE"

# Configure Kerberos crypto policies
mkdir -p "$(dirname "$KRB_CRYPTO")"
cat <<KRB > "$KRB_CRYPTO"
[libdefaults]
permitted_enctypes = aes256-cts-hmac-sha1-96 aes256-cts-hmac-sha384-192 camellia256-cts-cmac aes128-cts-hmac-sha1-96 aes128-cts-hmac-sha256-128 camellia128-cts-cmac rc4-hmac
KRB

# Join AD domain using password
echo "$AD_PASSWORD" | realm join -v -U "$AD_ADMIN" "$AD_SERVER_FQDN"

# Configure SSSD
cat <<SSSD > "$SSSD_CONF"
[sssd]
domains = $DOMAIN
services = nss, pam
[domain/$DOMAIN]
id_provider = ad
ad_domain = $DOMAIN
krb5_realm = $REALM
cache_credentials = True
use_fully_qualified_names = False
fallback_homedir = /home/%u
default_shell = /bin/bash
access_provider = simple
simple_allow_groups = $AD_GROUP
SSSD

chmod 600 "$SSSD_CONF"
systemctl enable --now sssd

# Ensure oddjobd for home directories
systemctl enable --now oddjobd.service
authselect select sssd with-mkhomedir --force

# Configure sudoers for AD group
echo "%$AD_GROUP ALL=(ALL) NOPASSWD: ALL" > "$SUDOERS_FILE"
chmod 440 "$SUDOERS_FILE"
visudo -cf "$SUDOERS_FILE"

# Permit AD group
realm permit -g "$AD_GROUP"
echo "===== AD Integration Completed on $(hostname) ====="
REMOTE_EOF
echo "===== Finished AD join on $TARGET_HOST. Log: $LOG_FILE ====="
) &
done

# Wait for all parallel jobs to finish
wait
unset AD_PASSWORD
echo "===== All AD joins completed ====="
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
How It Works
The script prompts for the AD administrator password once and never stores it.
Each host is joined to AD in parallel, logging progress to /tmp/ad_join_<hostname>.log.
DNS and /etc/hosts are updated safely.
Kerberos encryption is configured to meet AD standards.
SSSD is configured for AD authentication, with automatic home directory creation (oddjobd).
The specified AD group (unix_admin) is granted sudo privileges.

Usage Example
chmod +x ad_join_multi_hosts.sh
./ad_join_multi_hosts.sh host1 host2 host3
Check logs for each host in /tmp/ad_join_<hostname>.log.
After completion, all hosts will be AD-joined, with SSSD running and AD users able to log in with home directories and sudo privileges.

Benefits
Fast – parallel execution saves time.
Secure – password handled safely.
Reproducible – consistent configuration across all hosts.
Auditable – per-host logs help track exactly what happened.

This script is perfect for Linux administrators managing multiple AD-integrated servers in enterprise environments.

Automating Linux Active Directory Integration with a Shell Script

Integrating Linux servers with Microsoft Active Directory (AD) is a standard requirement in enterprise environments. While manual configuration works, it becomes inefficient and error-prone when managing multiple servers.
This post explains how to automate Linux–AD integration using a single Bash script, covering installation, configuration, domain joining, access control, and sudo permissions.

Why Use a Script?
Automating AD integration provides:
  • Consistent configuration across servers
  • Faster provisioning
  • Reduced human error
  • Easy reuse for new environments
  • Improved operational reliability
What the Script Accomplishes
The script performs the following:
  • Installs required AD integration packages
  • Configures DNS resolution
  • Updates /etc/hosts
  • Configures Kerberos encryption policies
  • Enables SSSD and automatic home directory creation
  • Joins the Linux system to Active Directory
  • Restricts login access to a specific AD group
  • Configures SSSD securely
  • Grants sudo access to an AD group
  • Restarts required services
Prerequisites
Before running the script, ensure:
  • You are logged in as root
  • The system can reach the AD Domain Controller
  • Correct DNS and domain information is available
  • The AD group unix_admin exists
  • You have AD administrator credentials
Complete AD Integration Script
Save the following script as ad_join.sh:
-------------------------------------------------------------------------------------------------------------------------------------------------------------------
#!/bin/bash
#  Author        : adminCtrlX
#  Description : Automates Linux Active Directory integration on server.
#                     - Installs required packages
#                     - Configures DNS, Kerberos, and SSSD
#                     - Joins the system to Active Directory
#                     - Restricts access to an AD group
#                     - Configures sudo using /etc/sudoers
#  Usage          : ./ad_join.sh

set -e

### VARIABLES ###
DOMAIN="ppc.com"
REALM="PPC.COM"
AD_SERVER_FQDN="inddcpads01.ppc.com"
AD_SERVER_IP1="192.168.10.100"
AD_SERVER_IP2="192.168.20.100"
AD_GROUP="unix_admin"
AD_ADMIN="administrator"
RESOLV_CONF="/etc/resolv.conf"
HOSTS_FILE="/etc/hosts"
SSSD_CONF="/etc/sssd/sssd.conf"
KRB_CRYPTO="/etc/krb5.conf.d/crypto-policies"

echo "===== Starting AD Integration Setup ====="

### STEP 1: Install Required Packages ###
echo "Installing required packages..."
dnf install -y realmd sssd oddjob oddjob-mkhomedir adcli samba-common-tools krb5-workstation

### STEP 2: Configure DNS ###
echo "Configuring DNS..."
cp $RESOLV_CONF ${RESOLV_CONF}.bak
cat <<EOF > $RESOLV_CONF
search $DOMAIN
nameserver $AD_SERVER_IP1
nameserver $AD_SERVER_IP2
EOF

### STEP 3: Update /etc/hosts ###
echo "Updating /etc/hosts..."
cp $HOSTS_FILE ${HOSTS_FILE}.bak
if ! grep -q "$AD_SERVER_FQDN" $HOSTS_FILE; then
echo "$AD_SERVER_IP1 $AD_SERVER_FQDN inddcpads01" >> $HOSTS_FILE
fi

### STEP 4: Configure Kerberos Encryption Types ###
echo "Configuring Kerberos crypto policies..."
cp $KRB_CRYPTO ${KRB_CRYPTO}.bak || true
cat <<EOF > $KRB_CRYPTO
[libdefaults]
permitted_enctypes = aes256-cts-hmac-sha1-96 aes256-cts-hmac-sha384-192 camellia256-cts-cmac aes128-cts-hmac-sha1-96 aes128-cts-hmac-sha256-128 camellia128-cts-cmac rc4-hmac
EOF

### STEP 5: Configure Authselect and Oddjob ###
echo "Configuring authselect and oddjob..."
mkdir -p /etc/authselect
authselect select sssd with-mkhomedir --force
systemctl enable --now oddjobd.service

### STEP 6: Join AD Domain ###
echo "Joining AD domain..."
realm join -v -U $AD_ADMIN $AD_SERVER_FQDN

### STEP 7: Verify Domain Join ###
echo "Verifying domain join..."
realm list

### STEP 8: Permit AD Group Login ###
echo "Permitting AD group access..."
realm permit -g $AD_GROUP

### STEP 9: Configure SSSD ###
echo "Configuring SSSD..."
cp $SSSD_CONF ${SSSD_CONF}.bak || true
cat <<EOF > $SSSD_CONF
[sssd]
domains = $DOMAIN
services = nss, pam
[domain/$DOMAIN]
ad_server = $AD_SERVER_FQDN
ad_domain = $DOMAIN
krb5_realm = $REALM
realmd_tags = manages-system joined-with-adcli
cache_credentials = True
id_provider = ad
krb5_store_password_if_offline = True
default_shell = /bin/bash
ldap_id_mapping = True
use_fully_qualified_names = False
fallback_homedir = /home/%u
access_provider = simple
simple_allow_groups = $AD_GROUP
EOF

chmod 600 $SSSD_CONF

### STEP 10: Restart SSSD ###
echo "Restarting SSSD..."
systemctl restart sssd

### STEP 11: AD Group/User Creation ###
echo "NOTE: Ensure AD group '$AD_GROUP' exists and users are added on the AD server."

### STEP 12: Configure Sudo Access ###
echo "Configuring sudo access..."
if ! grep -q "%$AD_GROUP" /etc/sudoers; then
echo "%$AD_GROUP ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
fi

### STEP 13: Final Test Instructions ###
echo "===== Setup Complete ====="
echo "Test with:"
echo " ssh sysadm@$(hostname)"
echo " sudo su -"
-------------------------------------------------------------------------------------------------------------------------------------------------------------------
How to Run the Script
chmod +x ad_join.sh
./ad_join.sh
You will be prompted for the Active Directory administrator password during the domain join process.

Testing the Configuration
Log in using an AD user:
ssh sysadm@hostname
Verify sudo/root access:
sudo su -
If successful, the system is fully integrated with Active Directory.

Best Practices & Improvements
  • Use /etc/sudoers.d/unix_admin instead of editing /etc/sudoers
  • Configure DNS via nmcli on NetworkManager systems
  • Use keytabs for non-interactive domain joins
  • Convert this script into an Ansible role
  • Add logging and rollback mechanisms
Conclusion
This script provides a clean, repeatable, and enterprise-ready solution for integrating Linux systems with Active Directory. It is ideal for system administrators, DevOps teams, and automated provisioning workflows.

Join a RHEL Linux Server to Active Directory Using SSSD

This guide explains how to join a Linux server to an Active Directory (AD) domain, configure authentication using SSSD, allow AD groups to log in, and grant sudo privileges to a specific AD group.

Prerequisites
  • RHEL Linux Servers 8/9/10
  • Proper DNS connectivity to the AD server
  • AD administrator credentials
  • Root or sudo access on the Linux server
Step 1: Install Required Packages
Install all necessary packages for AD integration.
# dnf install -y realmd sssd oddjob oddjob-mkhomedir adcli samba-common-tools krb5-workstation

Step 2: Configure DNS Resolution
Edit /etc/resolv.conf
# vi /etc/resolv.conf
Add the following entries:
search ppc.com
nameserver 192.168.10.100
nameserver 192.168.20.100
Save and exit:
Press Esc
Type :wq!
Press Enter

Step 3: Update /etc/hosts

# vi /etc/hosts
Add the AD server entry:
192.168.10.100 inddcpads01.ppc.com inddcpads01
Save and exit using :wq!.

Step 4: Configure Kerberos Encryption Types
Edit the crypto policy file:
# vi /etc/krb5.conf.d/crypto-policies
Add the following:
[libdefaults]
permitted_enctypes = aes256-cts-hmac-sha1-96 aes256-cts-hmac-sha384-192 camellia256-cts-cmac aes128-cts-hmac-sha1-96 aes128-cts-hmac-sha256-128 camellia128-cts-cmac rc4-hmac
Save and exit.

Step 5: Configure Authselect and Oddjob
If you see the message:
Directory [/etc/authselect] does not exist, please create it!
Run the following commands:
# mkdir /etc/authselect
# authselect select sssd with-mkhomedir --force
# systemctl enable --now oddjobd.service
This enables automatic home directory creation for AD users.

Step 6: Join the Linux Server to the AD Domain
Join the system to the domain using an AD administrator account:
# realm join -v -U administrator inddcpads01.ppc.com
Enter the AD Administrator password when prompted.

Step 7: Verify Domain Join Status
Check whether the system successfully joined the domain:
# realm list
Confirm that:
The domain is listed
permitted-groups includes the intended AD group

Step 8: Permit an AD Group to Log In
Allow the AD group unix_admin to access the Linux server:
# realm permit -g unix_admin

Step 9: Configure SSSD
Edit the SSSD configuration file:
# vi /etc/sssd/sssd.conf
Update or add the following configuration:
[domain/ppc.com]
ad_server = inddcpads01.ppc.com
ad_domain = ppc.com
krb5_realm = ppc.com
realmd_tags = manages-system joined-with-adcli
cache_credentials = True
id_provider = ad
krb5_store_password_if_offline = True
default_shell = /bin/bash
ldap_id_mapping = True
use_fully_qualified_names = False
fallback_homedir = /home/%u
access_provider = simple
simple_allow_groups = unix_admin

Save and exit.
Important: Ensure correct file permissions:
# chmod 600 /etc/sssd/sssd.conf

Step 10: Restart SSSD Service
# systemctl restart sssd

Step 11: Create AD Group and Add Users (On AD Server)
Create the AD group: unix_admin
Add required AD users (e.g., sysadm) to this group
Allow time for AD replication if needed

Step 12: Configure Sudo Access for AD Group
Edit the sudoers file safely:
# visudo
Add the following line:
%unix_admin ALL=(ALL) NOPASSWD: ALL
This grants passwordless sudo access to all members of the unix_admin group.

Step 13: Test Login and Root Access

Log in using an AD user (example: sysadm)
Verify sudo access:
$ sudo su -
If successful, the user now has root privileges.

Conclusion
You have successfully:
  • Joined  Linux server to Active Directory
  • Configured SSSD authentication
  • Enabled automatic home directory creation
  • Restricted access to a specific AD group
  • Granted sudo/root privileges to AD users
This setup provides centralized authentication, improved security, and easier user management across Linux servers.