تُعدّ الحسابات المهجورة سطح هجوم تقليدياً، لذا يعطّل هذا السكربت عمليات الدخول التي لم تُستخدم لفترة طويلة. يستهدف الأشخاص الحقيقيين فقط باختيار المستخدمين ذوي المعرّف 1000 فأعلى ممن لديهم أصداف دخول فعلية من /etc/passwd، بينما تحمي قائمة بيضاء الأسماء الحساسة مثل root. لكل مرشح يقرأ lastlog لإيجاد آخر دخول، ويعتبر "Never logged in" غير نشط، وإلا يحوّل الطابع الزمني إلى ثوانٍ منذ الحقبة لمقارنته بالعتبة. الحسابات المقفلة مسبقاً (التي يظهرها passwd -S بالحالة L) تُبلَّغ وتُتخطّى. افتراضياً يعمل السكربت في الوضع التجريبي فيطبع ما سيفعله لمراجعته قبل التنفيذ. وعند تمرير apply ينفّذ فعلياً: usermod -L يقفل كلمة المرور ويُحوَّل الصدف إلى nologin لطبقة حماية إضافية. ويمنح الجدول المنسّق للمستخدم وآخر دخول والإجراء نتيجة واضحة قابلة للتدقيق.
قفل المستخدمين غير النشطين
يجد الحسابات البشرية التي لم تُسجّل دخولاً بعد مدة محددة ويقفلها، مع وضع تجريبي آمن افتراضياً.
13 مشاهدة
مشاركة
السكربت
تحميل .shbash
#!/usr/bin/env bash
# Lock interactive accounts that have not logged in for N days.
#
# Usage:
# sudo ./lock_inactive_users.sh # default: 90 days, dry-run
# sudo ./lock_inactive_users.sh 60 # 60-day threshold, dry-run
# sudo ./lock_inactive_users.sh 60 apply # actually lock the accounts
set -euo pipefail
DAYS="${1:-90}" # inactivity threshold in days
MODE="${2:-dryrun}" # 'apply' to lock; anything else = dry run
if [[ "$(id -u)" -ne 0 ]]; then
echo "Error: must run as root." >&2
exit 1
fi
# Accounts we never want to touch (system/service accounts).
WHITELIST="root|sync|halt|shutdown|nobody"
# Only consider "human" accounts: UID >= 1000 and a real login shell.
# We pull these from /etc/passwd.
mapfile -t USERS < <(
awk -F: '$3 >= 1000 && $7 !~ /(nologin|false)$/ {print $1}' /etc/passwd
)
now_epoch=$(date +%s)
threshold_secs=$(( DAYS * 86400 ))
printf "%-16s %-22s %-10s\n" "USER" "LAST LOGIN" "ACTION"
printf '%.0s-' {1..50}; echo
for user in "${USERS[@]}"; do
# Never lock whitelisted accounts.
[[ "$user" =~ ^(${WHITELIST})$ ]] && continue
# 'lastlog -u' shows the most recent login for one user.
# "**Never logged in**" means the account has never been used.
last_line=$(lastlog -u "$user" | tail -n1)
if echo "$last_line" | grep -q "Never logged in"; then
last_display="never"
inactive=1
else
# Extract the date portion (everything after the port/host columns).
last_date=$(echo "$last_line" | awk '{print $(NF-5), $(NF-4), $(NF-3), $(NF-2), $NF}')
last_epoch=$(date -d "$last_date" +%s 2>/dev/null || echo 0)
last_display=$(date -d "@$last_epoch" "+%Y-%m-%d" 2>/dev/null || echo "unknown")
if (( last_epoch > 0 && (now_epoch - last_epoch) > threshold_secs )); then
inactive=1
else
inactive=0
fi
fi
# Skip accounts that are already locked (passwd -S shows status 'L').
status=$(passwd -S "$user" 2>/dev/null | awk '{print $2}')
if [[ "$status" == "L" ]]; then
printf "%-16s %-22s %-10s\n" "$user" "$last_display" "already-locked"
continue
fi
if [[ "$inactive" -eq 1 ]]; then
if [[ "$MODE" == "apply" ]]; then
# Lock the password AND set the shell to nologin for defence-in-depth.
usermod -L "$user"
usermod -s /usr/sbin/nologin "$user" 2>/dev/null || \
usermod -s /sbin/nologin "$user"
printf "%-16s %-22s %-10s\n" "$user" "$last_display" "LOCKED"
else
printf "%-16s %-22s %-10s\n" "$user" "$last_display" "would-lock"
fi
else
printf "%-16s %-22s %-10s\n" "$user" "$last_display" "active"
fi
done
[[ "$MODE" != "apply" ]] && echo -e "\n(dry run — re-run with 'apply' to enforce)"كيفية التشغيل
راجع السكربت أولاً، ثم حمّله أو انسخه وشغّله في بيئتك.
قد يعجبك أيضاً
bashlinuxمبتدئ
عرض نسخ الحوسبة في GCP
إظهار كل آلة افتراضية في Compute Engine ضمن مشروع مع المنطقة ونوع الآلة والحالة وعناوين IP.
bashlinuxمتوسط
مزامنة مجلد إلى مضيف بعيد عبر rsync فوق SSH
يطابق مجلداً محلياً مع خادم بعيد بأمان عبر SSH.
pythoncross-platformمتوسط
حاسبة موعد التشغيل التالي لتعبير cron
عند إعطاء تعبير cron يطبع المواعيد التالية لتشغيله مع العد التنازلي لكل منها.