Automatisera skapande av användare och grupper
Skapa, ändra och granska konton i bulk med useradd, chage och hantering av sudoers-fragment.
Automatisera skapande av användare och grupper är en gratis lektion i Bemästra Linux-kommandoraden och Bash-skriptning på CoddyKit. Detta är lektion 1 av 4. Ni kan läsa hela lektionen gratis nedan och sedan öva praktiskt i webbläsaren med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt. Den ingår i lärvägen för Bemästra Linux-kommandoraden och Bash-skriptning, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i Bemästra Linux-kommandoraden och Bash-skriptning innehåller totalt 4 lektioner.
Varför automatisera användarprovisionering?
Att hantera användare en i taget med useradd fungerar bra för en handfull konton, men företagsmiljöer lägger regelbundet till dussintals eller hundratals användare samtidigt. Manuella kommandon blir lätt felbenägna, inkonsekventa och svåra att granska.
Med Bash-skript kan Ni:
- Skapa användare med standardiserade inställningar (skal, hemkatalog och lösenordsprincip) varje gång
- Läsa en CSV-fil eller textfil med nya medarbetare och provisionera dem i en enda körning
- Logga varje åtgärd så att Ni får ett revisionsspår för efterlevnad
- Integrera med pipelines för konfigurationshantering (Ansible, Chef, Jenkins)
Den här lektionen går igenom hur Ni bygger ett användarprovisioneringsskript av produktionskvalitet från grunden. Den behandlar useradd, chage, usermod, grupphantering, sudoers-drop-ins och granskning efter körningen.
Läsa en lista med användare i bulk
Det vedertagna indataformatet för bulkprovisionering är en avgränsad textfil — en post per rad. En typisk CSV-fil kan se ut så här:
username,full_name,group,shell
alice,Alice Smith,developers,/bin/bash
bob,Bob Jones,ops,/bin/zshAnvänd IFS och read i en while-loop för att tolka filen säkert. Om Ni hoppar över rubrikraden med tail -n +2 blir logiken tydligare.
Viktiga defensiva metoder:
- Ta bort inledande och avslutande blanksteg från varje fält
- Hoppa över tomma rader och kommentarsrader som börjar med
# - Kontrollera att obligatoriska fält inte är tomma innan Ni anropar systemkommandon
#!/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"
doneSkapa användare med useradd
useradd är verktyget på låg nivå som skriver till /etc/passwd, /etc/shadow och /etc/group. De viktigaste flaggorna för skript är:
-m— skapa hemkatalogen-s— ange inloggningsskalet-c— GECOS-kommentarsfält (fullständigt namn)-G— kompletterande grupper (kommaseparerade)-e— kontots utgångsdatum (YYYY-MM-DD)
Kontrollera alltid om användaren redan finns med id innan Ni anropar useradd. Om det körs för en befintlig användare returneras avslutskod 9 och ett felmeddelande skrivs ut, vilket kan fylla loggarna i onödan.
Obs! useradd kräver root. Lägg en behörighetskontroll överst i skriptet.
#!/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"
fiAnge initiala lösenord på ett säkert sätt
Hårdkoda aldrig lösenord i skript. Två säkra metoder för bulkprovisionering är:
- Generera ett slumpmässigt initialt lösenord med
openssl randeller/dev/urandom, skriv ut det en gång och tvinga användaren att byta det vid den första inloggningen - Ange ett förhashat lösenord med
usermod -poch en SHA-512-hash, så att klartexten aldrig visas i processlistan
chpasswd är det rekommenderade verktyget för att ange lösenord i skript — det läser par av typen username:password från standardindata, så lösenordet visas aldrig bland kommandoradsargumenten (synliga via ps).
När lösenordet har angetts använder Ni chage -d 0 för att tvinga fram ett omedelbart lösenordsbyte vid nästa inloggning.
#!/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"Hantera lösenordsålder med chage
chage (change age) styr principen för lösenordsålder som lagras i /etc/shadow. Säkerhetsprinciper i företagsmiljöer kräver vanligtvis:
- Maximal lösenordsålder (till exempel 90 dagar)
- Minsta antal dagar innan ett lösenord får ändras igen
- Varningsperiod före utgång
- Låsning av inaktivt konto efter den senaste lösenordsanvändningen
Viktiga flaggor för chage:
-M <days>— maximal lösenordsålder-m <days>— minimal lösenordsålder-W <days>— antal varningsdagar före utgång-I <days>— antal inaktiva dagar före kontolåsning-E <date>— absolut utgångsdatum för kontot-l— visa aktuella inställningar för en användare
#!/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"
doneGrupphantering i bulk
Grupper är den primära mekanismen för att styra åtkomst till resurser. Ett provisioneringsskript måste säkerställa att nödvändiga grupper finns innan användare läggs till i dem — useradd -G nonexistent misslyckas annars.
Använd groupadd idempotent genom att kontrollera avslutskoden: den returnerar 9 om gruppen redan finns. Idiomet getent group <name> är ett portabelt och lättläst alternativ till att söka med grep i /etc/group.
gpasswd -a lägger till en användare i en grupp utan att ersätta befintliga medlemskap (till skillnad från usermod -G, som ersätter listan över kompletterande grupper).
#!/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"
}Fullständigt bulkprovisioneringsskript
Så här sätts allt ihop: ett enda skript läser en CSV-fil, skapar användare och grupper, anger lösenordsprinciper, loggar varje åtgärd och hanterar fel på ett smidigt sätt utan att stoppa hela batchkörningen.
Viktiga designbeslut i skriptet nedan:
- En
LOG_FILEmed tidsstämplar fångar alla åtgärder för granskning - Fel för enskilda användare loggas men avbryter inte loopen (
|| log_error) - Skriptet är idempotent — säkert att köra igen efter delvisa fel
- All utskrift går både till terminalen och loggfilen via
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 ==="Hantera sudoers-drop-in-fragment
Det är riskabelt att redigera /etc/sudoers direkt — ett syntaxfel kan låsa ute alla från sudo. Det säkra tillvägagångssättet är att använda drop-in-filer i /etc/sudoers.d/, där varje fil valideras med visudo -c -f innan den placeras på rätt plats.
God praxis för sudoers-fragment:
- Döp filer efter teamet eller rollen som de ger behörighet till (till exempel
10-developers,20-ops) - Använd gruppbaserade regler (
%developers ALL=(ALL) NOPASSWD: /usr/bin/systemctl) i stället för rader per användare - Ange alltid behörigheterna till
0440och ägarskapet tillroot:root - Validera med
visudo -c— kommandot returnerar en icke-nollkod vid alla syntaxfel
#!/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"Granska befintliga konton
Efter provisioneringen (och enligt ett regelbundet schema) bör Ni granska användardatabasen för avvikelser:
- Konton med UID 0 — alla konton med UID 0 utom root är ett kritiskt säkerhetsfynd
- Konton utan lösenord — poster med ett tomt lösenordsfält eller fältet
!i/etc/shadow - Utgångna konton som fortfarande är aktiva — utdata från
chage -lkan tolkas i bulk - Användare med skal men utan hemkatalog — en felkonfiguration som hindrar inloggning
Det är enkelt att skapa en strukturerad rapport och skicka den till säkerhetsteamet med mail eller genom att lägga till den i en övervakad loggsökväg.
#!/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"Låsa, låsa upp och ta bort konton
Avslut av användarkonton är lika viktigt som onboarding. När en användare slutar är rätt ordningsföljd:
- Lås kontot omedelbart (
usermod -L) — kommandot lägger till!framför hashvärdet för shadow-lösenordet och förhindrar inloggning utan att data tas bort - Återkalla sudo-behörighet — ta bort användarens sudoers-fragment om ett sådant finns
- Överför ägarskapet för användarens filer till en chef eller ett arkivkonto
- Arkivera hemkatalogen som ett tar-arkiv innan den tas bort
- Ta bort kontot med
userdel -r— kommandot tar bort hemkatalogen och e-postkön
usermod -U låser upp ett konto (tar bort prefixet !) och är användbart vid tillfällig avstängning.
#!/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"Testa skriptet med ett dry-run-läge
Provisioneringsskript i produktion måste kunna testas utan sidoeffekter. Implementera ett dry-run-läge med en DRY_RUN-flagga som ersätter alla kommandon som ändrar systemet med echo-stubbar.
Mönstret är enkelt: definiera en hjälpfunktion run() som antingen kör eller skriver ut kommandot beroende på flaggan. Det innebär att:
- Varje kodväg körs under testningen
- Utdata visar exakt vad som skulle hända vid en riktig körning
- CI-pipelines kan validera logiken utan root-åtkomst
Komplettera dry-run med ett särskilt prefix för testanvändare (till exempel test_), så blir det enkelt att städa efter integrationstester.
#!/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 || trueVilket kommando ska Ni använda för att lägga till en användare i en kompletterande grupp utan att ta bort befintliga gruppmedlemskap?
I ett bulkprovisioneringsskript behöver Ni tilldela en befintlig användare gruppen auditors. Användaren är redan medlem i developers och staff. Vilket kommando bevarar alla befintliga medlemskap samtidigt som det nya läggs till?
Lektionsrepetition: automatisera provisionering av användare och grupper
I den här lektionen har Ni byggt en komplett verktygslåda för användarprovisionering av produktionskvalitet. Här är de viktigaste slutsatserna:
- Tolka indata defensivt — använd
IFS/read-loopar, hoppa över tomma rader och kommentarsrader och validera fält innan något systemanrop görs - Grunderna i
useradd— använd alltid-m(hem),-s(skal),-c(kommentar) och-G(grupper); kontrollera förekomsten medidförst för idempotens - Lösenord — ange dem via standardindata till
chpasswdför att hålla klartexten borta från processargumenten; tvinga fram byte vid första inloggningen medchage -d 0 chageför principer — standardisera maximal ålder (-M), varningsdagar (-W) och inaktivitetslåsning (-I) för alla konton som inte är systemkonton- Gruppmedlemskap — använd
gpasswd -aellerusermod -aG(med flaggan-a) för att lägga till medlemskap i stället för att ersätta dem - Sudoers-drop-ins — skriv till
/etc/sudoers.d/, validera medvisudo -c -fföre installation och ange behörigheterna0440 root:root - Avslut av konton — lås (
usermod -L), arkivera hemkatalogen och ta sedan bort kontot; hoppa aldrig över arkiveringssteget - Dry-run-läge — omslut kommandon som ändrar systemet med en hjälpfunktion
run(), så att pipelines kan verifiera logiken utan sidoeffekter som kräver root
Genom att kombinera dessa mönster får Ni ett repeterbart, granskningsbart och säkert automatiseringslager för Linux-identitetshantering i alla skalor.
Lär dig Bash med en AI-lärare – gratis
Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.
- Kurser
- 22
- Lektioner
- 88
Vanliga frågor
Är lektionen ”Automatisera skapande av användare och grupper” gratis?
Ja – hela texten till ”Automatisera skapande av användare och grupper” kan läsas gratis här på webben. Om Ni vill öva interaktivt med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt och låsa upp resten av kursen i Bemästra Linux-kommandoraden och Bash-skriptning, kan Ni uppgradera till CoddyKit PRO. Kursen i Bemästra Linux-kommandoraden och Bash-skriptning innehåller totalt 4 lektioner.
Vad lär jag mig i ”Automatisera skapande av användare och grupper”?
Skapa, ändra och granska konton i bulk med useradd, chage och hantering av sudoers-fragment. Ni övar på Bemästra Linux-kommandoraden och Bash-skriptning med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.
Behöver jag någon erfarenhet för att börja lära mig Bemästra Linux-kommandoraden och Bash-skriptning?
Du behöver inga förkunskaper. Utbildningen i Bemästra Linux-kommandoraden och Bash-skriptning på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 1 av 4.
Hur lång tid tar lektionen ”Automatisera skapande av användare och grupper”?
De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.
Kan jag skriva och köra kod i den här Bemästra Linux-kommandoraden och Bash-skriptning-lektionen?
Ja. Varje Bemästra Linux-kommandoraden och Bash-skriptning-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.
Alla lektioner i den här kursen
- Automatisera skapande av användare och grupper
- Styra systemd-tjänster och skriva unit-filer
- Automatisera diskar, filsystem och monteringar
- Skapa skript för systemhälsa och aviseringar