0Pricing
DevOps Bootcamp · Pelajaran

Mengotomatiskan Penyediaan Pengguna dan Grup

Buat, ubah, dan audit akun secara massal menggunakan useradd, chage, serta pengelolaan fragmen sudoers.

Mengotomatiskan Penyediaan Pengguna dan Grup adalah pelajaran DevOps Bootcamp gratis di CoddyKit. Ini adalah pelajaran 1 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar DevOps Bootcamp, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus DevOps Bootcamp mencakup 4 pelajaran total.

Mengapa Mengotomatiskan Penyediaan Pengguna?

Mengelola pengguna satu per satu dengan useradd cukup baik untuk beberapa akun, tetapi lingkungan perusahaan biasanya menambahkan puluhan atau ratusan pengguna secara bersamaan. Perintah manual rentan terhadap kesalahan, tidak konsisten, dan tidak dapat diaudit.

Penulisan skrip Bash memungkinkan Anda untuk:

  • Membuat pengguna dengan pengaturan standar (shell, direktori beranda, kebijakan kata sandi) setiap kali
  • Membaca CSV atau berkas teks berisi karyawan baru dan menyediakan akun mereka dalam satu kali eksekusi
  • Mencatat setiap tindakan sehingga Anda memiliki jejak audit untuk kepatuhan
  • Mengintegrasikan sistem dengan alur manajemen konfigurasi (Ansible, Chef, Jenkins)

Pelajaran ini membahas pembuatan skrip penyediaan pengguna siap produksi dari awal, termasuk useradd, chage, usermod, pengelolaan grup, berkas tambahan sudoers, dan audit setelah eksekusi.

Membaca Daftar Pengguna Massal

Format masukan kanonis untuk penyediaan massal adalah berkas teks yang dibatasi pemisah — satu catatan per baris. CSV biasanya dapat terlihat seperti ini:

username,full_name,group,shell
alice,Alice Smith,developers,/bin/bash
bob,Bob Jones,ops,/bin/zsh

Gunakan IFS dan read di dalam perulangan while untuk menguraikannya dengan aman. Lewati baris tajuk dengan tail -n +2 agar logikanya tetap rapi.

Praktik pertahanan utama:

  • Hapus spasi di awal dan akhir dari setiap bidang
  • Lewati baris kosong dan baris komentar yang diawali #
  • Validasikan bahwa bidang wajib tidak kosong sebelum memanggil perintah sistem apa pun
#!/usr/bin/env bash
# parse_users.sh — safely read a CSV of users
set -euo pipefail

USER_FILE="${1:-users.csv}"

[[ -f "$USER_FILE" ]] || { echo "ERROR: $USER_FILE not found"; exit 1; }

tail -n +2 "$USER_FILE" | while IFS=',' read -r username full_name group shell; do
  # trim whitespace
  username="${username// /}"
  [[ -z "$username" || "$username" == \#* ]] && continue

  echo "Parsed -> user=$username group=$group shell=$shell"
done

Membuat Pengguna dengan useradd

useradd adalah utilitas tingkat rendah yang menulis ke /etc/passwd, /etc/shadow, dan /etc/group. Opsi paling penting untuk penulisan skrip adalah:

  • -m — membuat direktori beranda
  • -s — menetapkan shell login
  • -c — bidang komentar GECOS (nama lengkap)
  • -G — grup tambahan (dipisahkan dengan koma)
  • -e — tanggal kedaluwarsa akun (YYYY-MM-DD)

Selalu periksa apakah pengguna sudah ada dengan id sebelum memanggil useradd; menjalankannya pada pengguna yang sudah ada akan mengembalikan kode keluar 9 dan mencetak kesalahan yang dapat memenuhi catatan log.

Catatan: useradd memerlukan hak root. Bungkus skrip Anda dengan pemeriksaan hak istimewa di bagian awal.

#!/usr/bin/env bash
# create_user.sh — idempotent single-user creation
set -euo pipefail

[[ $EUID -ne 0 ]] && { echo "Must run as root"; exit 1; }

USERNAME="$1"
FULL_NAME="${2:-}"
GROUP="${3:-staff}"
SHELL="${4:-/bin/bash}"

if id "$USERNAME" &>/dev/null; then
  echo "[SKIP] User $USERNAME already exists"
else
  useradd \
    --create-home \
    --shell "$SHELL" \
    --comment "$FULL_NAME" \
    --groups "$GROUP" \
    "$USERNAME"
  echo "[OK] Created $USERNAME"
fi

Menetapkan Kata Sandi Awal dengan Aman

Jangan pernah menanamkan kata sandi secara langsung dalam skrip. Dua pendekatan aman untuk penyediaan massal adalah:

  • Buat kata sandi awal acak dengan openssl rand atau /dev/urandom, tampilkan sekali, lalu paksa pengguna untuk menggantinya saat login pertama
  • Tetapkan kata sandi yang telah di-hash menggunakan usermod -p dengan hash SHA-512 sehingga teks biasa tidak pernah muncul dalam daftar proses

chpasswd adalah alat yang direkomendasikan untuk menetapkan kata sandi melalui skrip — alat ini membaca pasangan username:password dari stdin, sehingga kata sandi tidak pernah muncul dalam argumen baris perintah (yang dapat dilihat melalui ps).

Setelah menetapkan kata sandi, gunakan chage -d 0 untuk memaksa pengaturan ulang kata sandi segera pada login berikutnya.

#!/usr/bin/env bash
# set_temp_password.sh
set -euo pipefail

[[ $EUID -ne 0 ]] && { echo "Must run as root"; exit 1; }

USERNAME="$1"

# Generate a 16-char random password (alphanumeric only)
TMP_PASS=$(tr -dc 'A-Za-z0-9' < /dev/urandom | head -c 16)

# Set password via chpasswd (password never in argv)
echo "${USERNAME}:${TMP_PASS}" | chpasswd

# Force password change on next login
chage -d 0 "$USERNAME"

echo "[OK] Temporary password for $USERNAME: $TMP_PASS"
echo "[OK] User must change password on first login"

Mengelola Masa Berlaku Kata Sandi dengan chage

chage (mengubah masa berlaku) mengendalikan kebijakan masa berlaku kata sandi yang disimpan dalam /etc/shadow. Kebijakan keamanan perusahaan biasanya mewajibkan:

  • Masa berlaku maksimum kata sandi (misalnya, 90 hari)
  • Jumlah hari minimum sebelum kata sandi dapat diubah lagi
  • Periode peringatan sebelum kedaluwarsa
  • Penguncian akun karena tidak aktif setelah penggunaan kata sandi terakhir

Opsi utama chage:

  • -M <days> — masa berlaku maksimum kata sandi
  • -m <days> — masa berlaku minimum kata sandi
  • -W <days> — jumlah hari peringatan sebelum kedaluwarsa
  • -I <days> — jumlah hari tidak aktif sebelum akun dikunci
  • -E <date> — kedaluwarsa akun absolut
  • -l — menampilkan pengaturan saat ini untuk pengguna
#!/usr/bin/env bash
# apply_password_policy.sh — enforce org-wide ageing policy
set -euo pipefail

[[ $EUID -ne 0 ]] && { echo "Must run as root"; exit 1; }

# Policy constants
MAX_AGE=90
MIN_AGE=1
WARN_DAYS=14
INACTIVE_DAYS=30

apply_policy() {
  local user="$1"
  chage \
    -M "$MAX_AGE" \
    -m "$MIN_AGE" \
    -W "$WARN_DAYS" \
    -I "$INACTIVE_DAYS" \
    "$user"
  echo "[OK] Policy applied to $user"
}

# Apply to all non-system users (UID >= 1000)
awk -F: '$3 >= 1000 && $3 < 65534 { print $1 }' /etc/passwd | while read -r user; do
  apply_policy "$user"
done

Pengelolaan Grup Secara Massal

Grup merupakan mekanisme utama untuk mengendalikan akses ke sumber daya. Skrip penyediaan harus memastikan bahwa grup yang diperlukan sudah ada sebelum menambahkan pengguna ke dalamnya — useradd -G nonexistent akan gagal.

Gunakan groupadd secara idempoten dengan memeriksa kode keluar: perintah ini mengembalikan 9 jika grup sudah ada. Idiom getent group <name> adalah alternatif yang portabel dan mudah dibaca daripada mencari dengan grep di /etc/group.

gpasswd -a menambahkan pengguna ke grup tanpa mengganti keanggotaan yang sudah ada (berbeda dengan usermod -G, yang mengganti daftar grup tambahan).

#!/usr/bin/env bash
# ensure_groups.sh — create groups if missing, then add users
set -euo pipefail

[[ $EUID -ne 0 ]] && { echo "Must run as root"; exit 1; }

REQUIRED_GROUPS=(developers ops security auditors)

for grp in "${REQUIRED_GROUPS[@]}"; do
  if getent group "$grp" &>/dev/null; then
    echo "[SKIP] Group $grp already exists"
  else
    groupadd "$grp"
    echo "[OK] Created group $grp"
  fi
done

# Safely add a user to a group (append, don't replace)
add_to_group() {
  local user="$1" group="$2"
  gpasswd -a "$user" "$group" 2>/dev/null && echo "[OK] $user -> $group"
}

Skrip Penyediaan Massal Lengkap

Menggabungkan semuanya: satu skrip membaca CSV, membuat pengguna dan grup, menetapkan kebijakan kata sandi, mencatat setiap tindakan, serta menangani kesalahan dengan baik tanpa menghentikan seluruh kumpulan.

Keputusan desain penting dalam skrip di bawah ini:

  • LOG_FILE dengan cap waktu merekam semua operasi untuk audit
  • Kesalahan untuk pengguna tertentu dicatat, tetapi tidak menghentikan perulangan (|| log_error)
  • Skrip bersifat idempoten — aman untuk dijalankan kembali setelah kegagalan sebagian
  • Semua keluaran dikirim ke terminal dan berkas log melalui tee
#!/usr/bin/env bash
# bulk_provision.sh — production user provisioning
set -uo pipefail

[[ $EUID -ne 0 ]] && { echo "Must run as root"; exit 1; }

USER_FILE="${1:-users.csv}"
LOG_FILE="/var/log/user_provision_$(date +%F).log"

log()  { echo "[$(date '+%F %T')] $*" | tee -a "$LOG_FILE"; }
err()  { log "ERROR: $*"; }

log "=== Provisioning started from $USER_FILE ==="

tail -n +2 "$USER_FILE" | while IFS=',' read -r username fullname group shell; do
  username="${username// /}"
  [[ -z "$username" || "$username" == \#* ]] && continue
  group="${group:-staff}"
  shell="${shell:-/bin/bash}"

  # Ensure group exists
  getent group "$group" &>/dev/null || groupadd "$group"

  # Create user idempotently
  if id "$username" &>/dev/null; then
    log "[SKIP] $username exists"
  else
    useradd -m -s "$shell" -c "$fullname" -G "$group" "$username" || { err "useradd failed for $username"; continue; }
    TMP="$(tr -dc 'A-Za-z0-9' < /dev/urandom | head -c 14)"
    echo "${username}:${TMP}" | chpasswd
    chage -M 90 -m 1 -W 14 -I 30 -d 0 "$username"
    log "[OK] $username created (group=$group) tmp_pass=$TMP"
  fi
done

log "=== Provisioning complete ==="

Pengelolaan Fragmen Tambahan sudoers

Mengedit /etc/sudoers secara langsung berbahaya — kesalahan sintaks akan mengunci semua orang dari sudo. Pendekatan yang aman adalah menggunakan berkas tambahan di /etc/sudoers.d/, yang masing-masing divalidasi dengan visudo -c -f sebelum ditempatkan.

Praktik terbaik untuk fragmen sudoers:

  • Beri nama berkas sesuai tim atau peran yang diberi akses (misalnya, 10-developers, 20-ops)
  • Gunakan aturan berbasis grup (%developers ALL=(ALL) NOPASSWD: /usr/bin/systemctl) alih-alih baris per pengguna
  • Selalu tetapkan izin ke 0440 dan kepemilikan ke root:root
  • Validasikan dengan visudo -c — perintah ini keluar dengan nilai bukan nol jika terdapat kesalahan sintaks
#!/usr/bin/env bash
# write_sudoers_fragment.sh
set -euo pipefail

[[ $EUID -ne 0 ]] && { echo "Must run as root"; exit 1; }

FRAGMENT_NAME="${1:-10-developers}"
SUDOERS_DIR="/etc/sudoers.d"
TMP_FILE="$(mktemp)"

# Write the fragment to a temp file first
cat > "$TMP_FILE" << 'EOF'
# Developers: restart services and view journals without full root
%developers ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart *, /usr/bin/journalctl
%ops        ALL=(ALL) NOPASSWD: ALL
EOF

# Validate BEFORE installing
if visudo -c -f "$TMP_FILE"; then
  install -m 0440 -o root -g root "$TMP_FILE" "${SUDOERS_DIR}/${FRAGMENT_NAME}"
  echo "[OK] Installed ${SUDOERS_DIR}/${FRAGMENT_NAME}"
else
  echo "[ERROR] sudoers syntax check failed — fragment NOT installed"
  rm -f "$TMP_FILE"
  exit 1
fi
rm -f "$TMP_FILE"

Mengaudit Akun yang Sudah Ada

Setelah penyediaan (dan secara berkala), Anda harus mengaudit basis data pengguna untuk menemukan anomali:

  • Akun UID 0 — akun apa pun dengan UID 0 selain root merupakan temuan keamanan kritis
  • Akun tanpa kata sandi — entri dengan bidang kata sandi kosong atau berisi ! dalam /etc/shadow
  • Akun kedaluwarsa yang masih aktif — keluaran chage -l dapat diuraikan secara massal
  • Pengguna dengan shell tetapi tanpa direktori beranda — kesalahan konfigurasi yang mengganggu login

Membuat laporan terstruktur dan mengirimkannya melalui email kepada tim keamanan mudah dilakukan dengan mail atau dengan menambahkan isinya ke jalur log yang dipantau.

#!/usr/bin/env bash
# audit_users.sh — produce a security-relevant user report
set -uo pipefail

REPORT="/var/log/user_audit_$(date +%F).txt"

echo "=== User Audit Report $(date) ===" > "$REPORT"

echo "" >> "$REPORT"
echo "--- Accounts with UID 0 (should be root only) ---" >> "$REPORT"
awk -F: '$3 == 0 { print $1 }' /etc/passwd >> "$REPORT"

echo "" >> "$REPORT"
echo "--- Accounts with empty password field ---" >> "$REPORT"
awk -F: '($2 == "" || $2 == "!") && $3 >= 1000 { print $1 }' /etc/shadow 2>/dev/null >> "$REPORT" || echo "  (requires root)" >> "$REPORT"

echo "" >> "$REPORT"
echo "--- Normal users (UID 1000-60000) ---" >> "$REPORT"
awk -F: '$3 >= 1000 && $3 < 60000 { printf "%-20s uid=%-6s shell=%s\n", $1, $3, $7 }' /etc/passwd >> "$REPORT"

cat "$REPORT"
echo "Report saved to $REPORT"

Mengunci, Membuka Kunci, dan Menghapus Akun

Proses keluar pengguna sama pentingnya dengan proses masuknya. Ketika pengguna meninggalkan organisasi, urutan yang benar adalah:

  1. Kunci akun segera (usermod -L) — menambahkan awalan ! pada hash kata sandi shadow, sehingga login dicegah tanpa menghapus data
  2. Cabut sudo — hapus fragmen sudoers mereka jika ada
  3. Alihkan kepemilikan berkas mereka kepada manajer atau akun arsip
  4. Arsipkan direktori beranda sebagai tarball sebelum menghapusnya
  5. Hapus dengan userdel -r — menghapus beranda dan spool surat

usermod -U membuka kunci akun (menghapus awalan !), yang berguna untuk penangguhan sementara.

#!/usr/bin/env bash
# offboard_user.sh — lock, archive, then optionally delete
set -euo pipefail

[[ $EUID -ne 0 ]] && { echo "Must run as root"; exit 1; }

USERNAME="$1"
ARCHIVE_DIR="/srv/archived-homes"
mkdir -p "$ARCHIVE_DIR"

# 1. Lock account
usermod -L "$USERNAME"
echo "[OK] Account $USERNAME locked"

# 2. Remove sudoers fragment if present
SUDOERS_FILE="/etc/sudoers.d/${USERNAME}"
[[ -f "$SUDOERS_FILE" ]] && rm -f "$SUDOERS_FILE" && echo "[OK] Removed sudoers fragment"

# 3. Archive home directory
HOME_DIR="$(getent passwd "$USERNAME" | cut -d: -f6)"
if [[ -d "$HOME_DIR" ]]; then
  tar -czf "${ARCHIVE_DIR}/${USERNAME}_$(date +%F).tar.gz" -C "$(dirname "$HOME_DIR")" "$(basename "$HOME_DIR")"
  echo "[OK] Home archived to ${ARCHIVE_DIR}/${USERNAME}_$(date +%F).tar.gz"
fi

echo "[NOTICE] Review archive, then run: userdel -r $USERNAME"

Menguji Skrip dengan Mode Dry-Run

Skrip penyediaan untuk produksi harus dapat diuji tanpa efek samping. Terapkan mode dry-run menggunakan tanda DRY_RUN yang mengganti semua perintah yang mengubah sistem dengan pengganti echo.

Polanya sederhana: tentukan pembantu run() yang menjalankan atau menampilkan kembali perintah, bergantung pada tanda tersebut. Pendekatan ini berarti:

  • Setiap jalur kode dijalankan selama pengujian
  • Keluaran menampilkan dengan tepat apa yang akan terjadi pada eksekusi langsung
  • Alur CI dapat memvalidasi logika tanpa akses root

Lengkapi dry-run dengan awalan pengguna pengujian khusus (misalnya, test_) agar pembersihan setelah pengujian integrasi menjadi mudah.

#!/usr/bin/env bash
# provision_with_dryrun.sh
set -euo pipefail

DRY_RUN="${DRY_RUN:-false}"

# Wrapper: execute or echo
run() {
  if [[ "$DRY_RUN" == "true" ]]; then
    echo "[DRY-RUN] $*"
  else
    "$@"
  fi
}

create_user() {
  local user="$1" group="$2"
  if id "$user" &>/dev/null; then
    echo "[SKIP] $user exists"
    return
  fi
  run useradd -m -s /bin/bash -G "$group" "$user"
  run chage -M 90 -m 1 -W 14 -d 0 "$user"
  echo "[OK] $user provisioned (dry=$DRY_RUN)"
}

# Test run
DRY_RUN=true create_user testuser developers
echo "---"
create_user realuser developers 2>/dev/null || true

Perintah Apa yang Harus Digunakan untuk Menambahkan Pengguna ke Grup Tambahan Tanpa Menghapus Keanggotaan Grup yang Sudah Ada?

Dalam skrip penyediaan massal, Anda perlu menambahkan pengguna yang sudah ada ke grup auditors. Pengguna tersebut sudah menjadi anggota developers dan staff. Perintah mana yang mempertahankan semua keanggotaan yang sudah ada sekaligus menambahkan keanggotaan baru?

Ringkasan Pelajaran: Mengotomatiskan Penyediaan Pengguna dan Grup

Dalam pelajaran ini, Anda membuat perangkat bantu penyediaan pengguna yang lengkap dan siap produksi. Berikut inti pembahasannya:

  • Uraikan masukan secara defensif — gunakan perulangan IFS/read, lewati baris kosong dan komentar, serta validasikan bidang sebelum pemanggilan sistem apa pun
  • Dasar-dasar useradd — selalu gunakan -m (beranda), -s (shell), -c (komentar), dan -G (grup); periksa keberadaan dengan id terlebih dahulu untuk idempotensi
  • Kata sandi — tetapkan melalui stdin chpasswd agar teks biasa tidak masuk ke argumen proses; wajibkan pengaturan ulang saat login pertama dengan chage -d 0
  • chage untuk kebijakan — standarkan masa berlaku maksimum (-M), hari peringatan (-W), dan penguncian karena tidak aktif (-I) untuk semua akun non-sistem
  • Keanggotaan grup — gunakan gpasswd -a atau usermod -aG (dengan tanda -a) untuk menambahkan, bukan mengganti, keanggotaan
  • Fragmen tambahan sudoers — tulis ke /etc/sudoers.d/, validasikan dengan visudo -c -f sebelum memasangnya, dan tetapkan izin 0440 root:root
  • Proses keluar pengguna — kunci (usermod -L), arsipkan beranda, lalu hapus; jangan pernah melewati langkah pengarsipan
  • Mode dry-run — bungkus perintah yang mengubah sistem dalam pembantu run() agar alur dapat memverifikasi logika tanpa efek samping yang memerlukan root

Menggabungkan pola-pola ini memberi Anda lapisan otomatisasi yang dapat diulang, diaudit, dan aman untuk pengelolaan identitas Linux dalam skala apa pun.

Pertanyaan yang Sering Diajukan

Apakah pelajaran “Mengotomatiskan Penyediaan Pengguna dan Grup” gratis?

Ya — teks lengkap “Mengotomatiskan Penyediaan Pengguna dan Grup” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus DevOps Bootcamp, upgrade ke CoddyKit PRO. Kursus DevOps Bootcamp mencakup 4 pelajaran total.

Apa yang akan aku pelajari di “Mengotomatiskan Penyediaan Pengguna dan Grup”?

Buat, ubah, dan audit akun secara massal menggunakan useradd, chage, serta pengelolaan fragmen sudoers. Kamu berlatih DevOps Bootcamp dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.

Apakah aku perlu pengalaman untuk memulai DevOps Bootcamp?

Tidak diperlukan pengalaman sebelumnya. DevOps Bootcamp di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 1 dari 4.

Berapa lama pelajaran “Mengotomatiskan Penyediaan Pengguna dan Grup” memakan waktu?

Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.

Bisakah aku menulis dan menjalankan kode dalam pelajaran DevOps Bootcamp ini?

Ya. Setiap pelajaran DevOps Bootcamp menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.

Semua pelajaran dalam kursus ini

  1. Mengotomatiskan Penyediaan Pengguna dan Grup
  2. Mengendalikan Layanan systemd dan Menulis File Unit
  3. Otomatisasi Disk, Sistem File, dan Mount
  4. Membangun Skrip Pemeriksaan Kesehatan Sistem dan Peringatan
← Kembali ke DevOps Bootcamp