Home Linux AWS Cloud Docker Python AI
클릭하여 터미널 활성화

리눅스 사용자 계정 자동화 스크립트 | useradd 반복 작업을 Shell로 끝내는 법

// Linux · Shell Script · useradd · 계정관리 · 자동화
사용자 생성·삭제·조회를 한 번에 처리하는 통합 Bash 스크립트 — 보안 취약점 개선 포인트까지

왜 자동화가 필요한가?

리눅스 서버를 운영하다 보면 사용자 계정을 생성하고 관리하는 일이 반복적으로 발생한다. 특히 교육용 서버, 개발 테스트 환경, 또는 다수 인원이 협업하는 프로젝트에서는 수십 명의 계정을 빠르게 만들고 필요 시 삭제하거나 권한을 조정해야 할 일이 빈번하다.

useradd, passwd, usermod, userdel을 수동으로 반복하면 시간 낭비는 물론 오타나 누락으로 인한 보안 문제가 발생할 수 있다. 자동화된 스크립트를 사용하면 다음과 같은 장점이 생긴다.

자동화 장점
반복 제거사용자 수에 상관없이 루프로 자동 처리
보안 강화/dev/urandom 기반 무작위 비밀번호 자동 생성
권한 제어sudo 권한 부여 여부를 선택적으로 처리
백업생성된 계정 정보를 타임스탬프 파일로 자동 저장
안전 삭제삭제 전 확인 절차로 실수 방지

스크립트 구성 및 기능

이 스크립트는 하나의 파일에 네 가지 기능을 담고 있다. 실행하면 아래 메뉴가 출력되고, 번호를 입력해 원하는 작업을 선택한다.

사용자 관리 작업을 선택하세요:
1) 사용자 생성
2) 사용자 삭제
3) 사용자 목록 조회
4) 그룹 목록 조회
번호 입력: _
기능별 동작 요약
1) 사용자 생성생성 수 입력 후 루프 — 아이디, 그룹, sudo 권한 여부 입력, 비밀번호 자동 생성, 백업 파일 저장
2) 사용자 삭제일반 사용자 목록 출력 후 대상 입력, 확인 후 홈 디렉토리까지 삭제
3) 목록 조회/etc/passwd에서 UID 1000 이상인 일반 사용자만 필터링 출력
4) 그룹 조회/etc/group에서 전체 그룹명 출력

스크립트 전문

원본 스크립트에서 몇 가지 취약한 부분을 개선했다. 변경 내용은 아래 "개선 포인트" 섹션에서 별도로 설명한다.

#!/bin/bash

# root 권한 확인
if [ "$(id -u)" -ne 0 ]; then
echo "이 스크립트는 root 권한으로 실행해야 합니다. (sudo ./script.sh)"
exit 1
fi

BACKUP_FILE="user_backup_$(date +%Y%m%d_%H%M%S).txt"

# 사용자 목록 조회 함수
list_users() {
echo "현재 시스템 사용자 목록:"
awk -F: '$3 >= 1000 && $1 != "nobody" { print $1 }' /etc/passwd
}

# 그룹 목록 조회 함수
list_groups() {
echo "현재 시스템 그룹 목록:"
cut -d: -f1 /etc/group
}

# 사용자 생성 함수
create_users() {
read -p "생성할 사용자 수를 입력하세요: " USER_COUNT

# 숫자 유효성 검사
if ! [[ "$USER_COUNT" =~ ^[0-9]+$ ]]; then
echo "올바른 숫자를 입력하세요."
return 1
fi

for ((i=1; i<=USER_COUNT; i++)); do
echo "[$i/$USER_COUNT] 사용자 정보를 입력하세요."

read -p "아이디: " username

# 공백 및 중복 계정 확인
if [ -z "$username" ]; then
echo "아이디를 입력해야 합니다. 건너뜁니다."
continue
fi
if id "$username" &>/dev/null; then
echo "이미 존재하는 계정입니다: $username. 건너뜁니다."
continue
fi

read -p "부여할 그룹명 (없으면 엔터): " group
read -p "sudo 권한 부여? (yes/no): " give_sudo

password=$(tr -dc 'A-Za-z0-9!@#$%^&*' </dev/urandom | head -c 10)

if [ -n "$group" ]; then
if ! getent group "$group" > /dev/null; then
groupadd "$group"
echo "그룹 '$group' 생성됨."
fi
useradd -m -g "$group" "$username"
else
useradd -m "$username"
fi

echo "$username:$password" | chpasswd

if [ "$give_sudo" == "yes" ]; then
usermod -aG sudo "$username"
sudo_status="sudo 권한 있음"
else
sudo_status="sudo 권한 없음"
fi

echo "아이디: $username | 비밀번호: $password | 그룹: ${group:-없음} | $sudo_status" >> "$BACKUP_FILE"
echo "사용자 '$username' 생성 완료"
done

# 백업 파일 권한 제한 (비밀번호 포함 파일이므로 필수)
chmod 600 "$BACKUP_FILE"
echo "모든 사용자 생성이 완료되었습니다."
echo "사용자 정보 백업 파일: $BACKUP_FILE (권한: 600 설정됨)"
}

# 사용자 삭제 함수
delete_user() {
echo "삭제 가능한 사용자 목록:"
awk -F: '$3 >= 1000 && $1 != "nobody" { print $1 }' /etc/passwd

read -p "삭제할 사용자 아이디를 입력하세요: " target

if id "$target" &>/dev/null; then
read -p "'$target' 계정을 정말 삭제하시겠습니까? (yes/no): " confirm
if [ "$confirm" == "yes" ]; then
userdel -r "$target"
echo "사용자 '$target' 삭제 완료 (홈 디렉토리 포함)"
else
echo "삭제 취소됨"
fi
else
echo "사용자 '$target'는 존재하지 않습니다."
fi
}

# 메뉴 선택
echo "사용자 관리 작업을 선택하세요:"
echo "1) 사용자 생성"
echo "2) 사용자 삭제"
echo "3) 사용자 목록 조회"
echo "4) 그룹 목록 조회"
read -p "번호 입력: " choice

case "$choice" in
1) create_users ;;
2) delete_user ;;
3) list_users ;;
4) list_groups ;;
*) echo "잘못된 선택입니다." ;;
esac

비밀번호 자동 생성 방식

비밀번호는 /dev/urandom을 활용해 아래와 같이 생성한다.

password=$(tr -dc 'A-Za-z0-9!@#$%^&*' </dev/urandom | head -c 10)

영문 대소문자, 숫자, 특수문자를 포함한 10자리 비밀번호를 사람이 입력하지 않고 생성하기 때문에 예측 가능성이 낮다. 생성된 비밀번호는 백업 파일에 기록되므로, 초기 로그인 후 사용자에게 전달하거나 아래 명령어로 비밀번호 변경을 강제할 수 있다.

# 첫 로그인 시 비밀번호 변경 강제
$ sudo chage -d 0 username

백업 파일 관리

스크립트는 생성 완료 후 아래 형식으로 계정 정보를 기록한다.

아이디: testuser | 비밀번호: Ab3#xYz9!Q | 그룹: dev | sudo 권한 있음

파일명은 user_backup_날짜_시간.txt 형식이며, 스크립트 내에서 chmod 600을 자동 적용한다. 비밀번호가 담긴 파일이므로 root 외 다른 사용자가 읽을 수 없도록 권한을 제한하는 것이 중요하다.

개선 포인트 — 원본 스크립트의 취약한 부분

공부하면서 작성한 스크립트라 실제 운영 환경에서 문제가 될 수 있는 부분들이 있었다. 아래에 정리한다.

개선된 항목
root 권한 체크 없음 useradd, userdel은 root 전용 명령어인데 권한 확인 없이 실행하면 Permission denied 에러만 출력되고 진행됨. $(id -u)로 초반 체크 추가.
USER_COUNT 검증 없음 문자나 공백을 입력하면 for 루프가 예상치 못하게 동작함. 정규식으로 숫자 여부 검사 추가.
username 유효성 검사 없음 빈 문자열 입력이나 이미 존재하는 계정 입력 시 에러가 발생했다가 다음 단계로 넘어가는 문제. 공백 체크와 중복 계정 체크 추가.
백업 파일 권한 미설정 평문 비밀번호가 저장된 파일인데 기본 umask에 따라 다른 사용자가 읽을 수 있는 상태로 생성될 수 있음. chmod 600 자동 적용 추가.
변수명 sudo 사용 bash에서 sudo는 명령어이므로 변수명으로 사용하면 혼동을 일으킬 수 있음. give_sudo로 변경.

실무 적용 팁

실제 서버 환경에서 이 스크립트를 활용할 때 함께 쓰면 좋은 명령어들을 정리한다.

# 첫 로그인 시 비밀번호 변경 강제 (교육용 서버에 유용)
$ sudo chage -d 0 username

# 그룹을 활용한 파일 접근 권한 제어
$ sudo chgrp devteam /srv/project
$ sudo chmod 2770 /srv/project

# 비밀번호 만료 기간 설정 (30일)
$ sudo chage -M 30 username

# 계정 잠금 (퇴직/일시 비활성화)
$ sudo usermod -L username

# 계정 잠금 해제
$ sudo usermod -U username
이 스크립트는 SSH 키 자동 등록, 비밀번호 만료 설정, 로그인 제한 등으로 확장이 가능하다. 현재 버전을 베이스로 환경에 맞게 기능을 추가해보자.

끝으로

단순히 명령어를 반복하는 것을 넘어, 스크립트로 자동화할 때는 입력 유효성 검사, 권한 확인, 민감 정보 보호까지 함께 고려해야 한다. 처음 작성한 스크립트가 엉성해 보여도 이런 과정을 통해 완성도를 높여가는 게 실력이 쌓이는 방식이다.

// 핵심 정리
root 체크 + 입력 유효성 검사 = 스크립트의 기본 안전장치
백업 파일 chmod 600 = 비밀번호 파일 보안 필수
공부용 스크립트도 보안을 고려하는 습관이 중요하다
Tags: #Linux #ShellScript #useradd #계정관리 #자동화 #Bash