เทคนิคการเพิ่ม user ในระบบ linux คราวละมากๆ

จาก Wiki Opensource

บันทึกนี้ปรับปรุงล่าสุดเมื่อวันที่ 10-07-2561

ดูแลโดย WIBOON

  • ทดสอบกับ linux ubuntu server 14.04, 18.04
  • เป็นวิธีการเพิ่ม user ในระบบ linux คราวละมากๆ ด้วย shell script สำหรับ 1สร้างไฟล์รายชื่อ 2เพิ่ม user และ 3ลบ user
  • ต้องมีการติดตั้งโปรแกรมชื่อ apg เพื่อทำชุดตัวอักษรแบบ random และโปรแกรม mkpasswd เพื่อสร้างรหัสผ่านอัตโนมัติในขณะเพิ่ม user (/etc/shadow) โดยที่ใน script จะมีการตรวจสอบให้ว่ามีโปรแกรมที่จำเป็นอยู่หรือไม่


วิธีนำไปใช้

ดาวน์โหลด shell script มาติดตั้ง
wget ftp.psu.ac.th/pub/psu-installer/bulkuseradd/makeusername.sh
wget ftp.psu.ac.th/pub/psu-installer/bulkuseradd/bulkuseradd.sh
wget ftp.psu.ac.th/pub/psu-installer/bulkuseradd/bulkuserdel.sh

สร้างไฟล์รายชื่อ
รัน bash makeusername.sh
จะมีคำแนะนำว่าต้องใส่ option ใดบ้าง
bash makeusername.sh name min max
เช่น
bash makeusername.sh student 1 3
จะได้ output คือ
student1
student2
student3
Do you wish to save to file? y
Enter filename: student-group1.txt


เพิ่ม user มากๆ จากไฟล์รายชื่อที่สร้างไว้
รัน sudo bash bulkuseradd.sh
จะมีคำแนะนำว่าต้องใส่ option ใดบ้าง
bash bulkuseradd.sh path/to/filename
เช่น
bash bulkuseradd.sh student-group1.txt
จะได้ output คือ
... Processing adding user student1
... Processing adding user student2
... Processing adding user student3
Finished, the original filename student-group1.txt replaced with student-group1.txt_yyyymmddhhmm.csv consists of lines with username:password format.
ตรวจสอบ
tail -3 /etc/passwd
จะได้ output คือ
student1:x:1007:1007::/home/student1:/bin/bash
student2:x:1008:1008::/home/student2:/bin/bash
student3:x:1009:1009::/home/student3:/bin/bash
และ
sudo tail -3 student-group1.txt_yyyymmddhhmm.csv
โดยที่ yyyy คือปีค.ศ. mm คือ เดือน dd คือวันที่ hh คือ ชม. mm คือ นาที ที่รัน script เพื่อเพิ่ม user
จะได้ output คือ
student1:4v9xys6zsh
student2:t3cn2n6aey
student3:7ac8yc54vx


ลบ user มากๆ
ให้สร้างไฟล์รายชื่อใหม่ด้วยคำสั่ง bash makeusername.sh student 1 3 ด้วยนะ เช่น ตั้งชื่อไฟล์ no-student-group1.txt
รัน sudo bash bulkuserdel.sh
จะมีคำแนะนำว่าต้องใส่ option ใดบ้าง
sudo bash bulkuserdel.sh path/to/filename
เช่น
sudo bash bulkuserdel.sh no-student-group1.txt
จะได้ output คือ
...Processing deleting user student1
userdel: student1 mail spool (/var/mail/student1) not found
...Processing deleting user student2
userdel: student2 mail spool (/var/mail/student2) not found
...Processing deleting user student3
userdel: student3 mail spool (/var/mail/student3) not found
Finished, the original filename no-student-group1.txt replaced with no-student-group1.txt_yyyymmddhhmm_del.csv consists of lines with username:status format.
ตรวจสอบ
sudo tail -3 no-student-group1.txt_yyyymmddhhrr_del.csv
จะได้ output ดังนี้
student1:deleted
student2:deleted
student3:deleted


[file: makeusername.sh]
#!/bin/bash

#updates WIBOON 2556-04-17

exitusage() 
{
  echo "usage: sh $0 name min max"
  exit 
}

checkinput() 
{ 
  echo $1 | grep -Eq '^(\+|-)?[0-9]+$'
  return $?
}

if [ "$1" = "--help" ] ; then
  exitusage
fi
if [ -z "$1" ] ; then
  echo "need name"
  exitusage
else
  NAME=$1
fi
if [ -z "$2" ] ; then
  echo "need min"
  exitusage
else
  checkinput $2 || exitusage && COUNT=$2
fi
if [ -z "$3" ] ; then
  echo "need max"
  exitusage
else
  checkinput $3 || exitusage && MAX=$3
fi

PFILE=/tmp/$1.$$

while [ ${COUNT} -le ${MAX} ]
do
  #STRPADD=`printf "%02d" ${COUNT}`
  #echo "${NAME}${STRPADD}"
  echo "${NAME}${COUNT}"
  echo "${NAME}${COUNT}" >> ${PFILE}
  COUNT=$(( ${COUNT} + 1 ))
done
while true; do
    read -p "Do you wish to save to file? " yn
    case $yn in
        [Yy]* ) CONFIRM_SAVE="yes"; break;;
        [Nn]* ) CONFIRM_SAVE="no"; break;;
        * ) echo "Please answer y or n.";;
    esac
done
if [ "${CONFIRM_SAVE}" = "no" ]; then
  exit 
fi
read -p "Enter filename: " filename
if [ -f $filename ] ; then
   echo "$filename does exist"
else
   cat ${PFILE} > $filename
   rm ${PFILE}
fi


[file: bulkuseradd.sh]
#!/bin/bash

#updates by WIBOON 2558-01-29, 2561-07-10

#Add multiple users with bulk import
#You can import multiple users into the file server from a single file source. The file must be a text file and adhere to the required format.
#For example
#Filename: usergroup1
#user1
#user2
#user3
#
#When finished, the original filename will be replace with a filename_timestamp.csv consists of lines with username:password format.

exitusage()
{
  echo "usage: sudo sh $0 path/to/filename"
  echo "path/to/filename is a file consists of one username per line i.e."
  echo "user1"
  echo "user2"
  exit
}

if [ -z "$(which apg)" ] ; then
  echo "need program apg, try: sudo apt-get install apg"
  exit
fi
if [ -z "$(which mkpasswd)" ] ; then
  echo "need program mkpasswd, try: sudo apt-get install whois"
  exit
fi
if [ -z "$(id -nG|grep -w "root")" ] ; then
  echo "need root, or try: sudo sh $0"
  exit
fi
if [ "$1" = "--help" ] ; then
  exitusage
fi
if [ -z "$1" ] ; then
  echo "need filename"
  exitusage
fi

TODAY=$(date "+%Y%m%d%H%M")
IN_FILENAME=$1
HOME_DIR="/home"
OUT_FILENAME=${IN_FILENAME}_${TODAY}.csv

if [ ! -f ${IN_FILENAME} ] ; then
  echo "File not found"
  exit
fi

sudo touch ${OUT_FILENAME}

for USERDETAILS in $(cat ${IN_FILENAME})
do
  MYUSER="$(echo ${USERDETAILS})"
  PASSWD="$(apg -n 1 -a 1 -M nL -m 10 -x 10 -E ijl0oqg)"
  echo "...Processing adding user ${MYUSER}"
  if [ ! -z "$(getent passwd ${MYUSER})" ]; then
    echo "username exist"
    sudo echo "${MYUSER}:invalid" >> ${OUT_FILENAME}
  else
    sudo useradd -m -b ${HOME_DIR} -s /bin/bash ${MYUSER} -p `mkpasswd ${PASSWD}`
    sudo echo "${MYUSER}:${PASSWD}" >> ${OUT_FILENAME}
  fi
  sleep 1
done

isnologin=false
if [ -f /sbin/nologin ] ; then
  isnologin=true
  NOLOGIN=/sbin/nologin
else
  if [ -f /usr/sbin/nologin ] ; then
    isnologin=true
    NOLOGIN=/usr/sbin/nologin
  else
    if [ -f /bin/false ] ; then
      isnologin=true
      NOLOGIN=/bin/false
    fi
  fi
fi
if [ "${isnologin}" = "true" ]; then
  while true; do
    echo " "
    echo "Do you want these users can remote access with ssh to server?"
    echo "Answer y = have username and password and can remote access with ssh to server"
    echo -n "Answer n = have username and password only"
    read -p " {y/n)" yn
    case $yn in
        [Yy]* ) CONFIRM_ANS="yes"; break;;
        [Nn]* ) CONFIRM_ANS="no"; break;;
        * ) echo "Please answer y or n.";;
    esac
  done
  if [ "${CONFIRM_ANS}" = "no" ]; then
    echo "Modify user shell from /bin/bash to ${NOLOGIN}"
    for USERDETAILS in $(cat ${OUT_FILENAME})
    do
      MYUSER="$(echo ${USERDETAILS}|cut -d':' -f1)"
      if [ ! -z "$(getent passwd ${MYUSER})" ]; then
        echo "modifying username ${MYUSER}"
        sudo usermod -s ${NOLOGIN} ${MYUSER}
      fi
      sleep 1
    done
  fi
fi

sudo chmod go-rwx ${OUT_FILENAME}
sudo rm -f ${IN_FILENAME}
echo " "
echo "Finished, the original filename ${IN_FILENAME} replaced with ${OUT_FILENAME} consists of lines with username:password format."
#END


[file: bulkuserdel.sh]
#!/bin/bash

#updates by WIBOON 2558-01-29

#Delete multiple users
#You can delete multiple users from PSU-netdrive file server from a single file source. The file must be a text file and adhere to the required format. 
#For example 
#Filename: usergroup1
#user1
#user2
#user3
#
#When finished, the original filename will be replace with a filename_timestamp.csv consists of lines with username:status format.

exitusage()
{
  echo "usage: sudo sh $0 path/to/filename"
  echo "path/to/filename is a file consists of one username per line i.e."
  echo "user1"
  echo "user2"
  exit 
}

if [ -z "$(id -nG|grep -w "root")" ] ; then
  echo "need root, or try: sudo sh $0"
  exit
fi
if [ "$1" = "--help" ] ; then
  exitusage
fi
if [ -z "$1" ] ; then
  echo "need filename"
  exitusage
fi

TODAY=$(date "+%Y%m%d%H%M")
IN_FILENAME=$1
HOME_DIR="/home"
OUT_FILENAME=${IN_FILENAME}_${TODAY}_del.csv

if [ ! -f ${IN_FILENAME} ] ; then
  echo "File not found"
  exit
fi

sudo touch ${OUT_FILENAME}

for USERDETAILS in $(cat ${IN_FILENAME})
do
  MYUSER=$(echo ${USERDETAILS})
  echo "...Processing deleting user ${MYUSER}"
  if [ ! -z "$(getent passwd ${MYUSER})" ] ; then
    sudo userdel -r ${MYUSER} 
    sudo echo "${MYUSER}:deleted" >> ${OUT_FILENAME}
  else
    sudo echo "${MYUSER}:invalid" >> ${OUT_FILENAME}
  fi
done
sudo chmod go-rwx ${OUT_FILENAME}
sudo rm -f ${IN_FILENAME}
echo "Finished, the original filename ${IN_FILENAME} replaced with ${OUT_FILENAME} consists of lines with username:status format."
#END