В этой статье я расскажу вам, как использовать bash-скрипты для автоматической генерации паролей для новых учетных записей пользователей в системе Linux.

Сценарий: Сотрудники службы поддержки тепло приняли скрипт "add-local-user.sh", оценив значительную скорость и эффективность, которую он обеспечивает при создании учетных записей. В свою очередь они посоветовали как можно улучшить этот процесс: добавить функцию автоматической генерации пароля для повышения безопасности и устранения повторяющихся задач, а также реализовать ввод имен учетных записей и комментариев прямо из командной строки для еще более быстрого выполнения операций. Эти изменения не только оптимизируют рабочий процесс команды, но и способствуют повышению общей безопасности и эффективности компании.

Требования к скрипту:

  • Он называется "add-new-local-user.sh". (Мы добавим в название слово new, чтобы обособить его от оригинального скрипта, над которым мы работали в предыдущей части).

  • Следит за тем, чтобы он выполнялся с правами суперпользователя (root). Если скрипт выполняется без прав суперпользователя, он не будет даже пытаться создать пользователя, а вернет код завершения 1.

  • Предоставляет отчет об использовании, подобный тому, что можно найти в man-странице, если пользователь не указал имя учетной записи в командной строке, и возвращает код завершения 1.

  • Использует первый аргумент, указанный в командной строке, в качестве имени пользователя для учетной записи. Все остальные аргументы в командной строке будут рассматриваться как комментарий к учетной записи.

  • Автоматически генерирует пароль для новой учетной записи.

  • Информирует пользователя, если по какой-то причине учетную запись не удалось создать. Если учетная запись не создана, скрипт должен вернуть код завершения 1.

  • Отображает имя пользователя, пароль и хост, на котором была создана учетная запись. Таким образом, сотрудники службы поддержки могут скопировать результаты выполнения скрипта, что облегчает предоставление информации новому владельцу учетной записи.

Что вам понадобится:

  • Терминал Linux

  • Желание научиться чему-то новому)

Шаг 1: Создайте текстовый файл под скрипт

  • Создайте в командной строке новый текстовый файл, содержащий скрипт, над которым мы будем работать.

  • Назовите скрипт "add-new-local-user.sh".

touch add-new-local-user.sh

Шаг 2: Измените разрешения, чтобы получить привилегии запуска исполняемых файлов

  • По умолчанию система безопасности linux не позволяет исполнять файлы без соответствующих разрешений. Разрешения на файл можно изменить с помощью команды "chmod", за которой следуют соответствующие цифровые обозначения.

Например: chmod 755 или chmod 777

  • Для скрипта, над которым мы будем работать, укажем разрешение "755".

chmod 755 add-new-local-user.sh

Шаг 3: Создание скрипта

  • Чтобы обозначить текстовый файл как скрипт, первое, что нужно сделать, — начать первую строку с shebang. Shebang позволяет интерпретатору узнать, как выполнить файл.

  • Первая задача скрипта заключается в том, чтобы проследить, что он выполнялся с привилегиями суперпользователя.

  • Часть крипта, которую вы видите ниже, указывает пользователю в командной строке выполнить скрипт от имени sudo или root. Без привилегий суперпользователя скрипт не отработает должным образом.

Раздел информации о пользователе:

Наша цель заключается в том, чтобы пользователь (персонал службы поддержки) вводил имя учетной записи, а скрипт автоматически генерировал для нее случайный пароль. Каждый пользователь получит свой уникальный пароль, что избавит нас от необходимости вручную создавать пароль для каждого нового пользователя в системе linux.

  • USER_NAME="$1": Эта строка сохраняет первый аргумент, переданный скрипту, в переменной USER_NAME. При запуске скрипта в качестве этого первого аргумента вы указываете имя нового пользователя. 

  • shift: Эта команда сдвигает список аргументов скрипта таким образом, что второй аргумент становится первым, третий — вторым и так далее. Она используется здесь, потому что все остальное после первого аргумента считается комментариями к учетной записи.

  • COMMENT="$@": После сдвига представляет собой все оставшиеся аргументы командной строки, которые присваиваются переменной COMMENT. Они используются в качестве комментария для учетной записи пользователя.

  • PASSWORD=$(date +%s%N | sha256sum | head -c48): Эта строка генерирует пароль, беря текущую дату и время в наносекундах, пропуская их через команду sha256sum для создания хэша, а затем используя head -c48 для получения его первых 48 символов.

  • useradd -c "${COMMENT}" -m ${USER_NAME}: Команда useradd используется для создания нового пользователя с комментарием, указанным в переменной COMMENT, и именем пользователя, указанным в переменной USER_NAME. Параметр -m создает корневой каталог пользователя.

  • if [[ "${?}" -ne 0 ]]: Проверяет код завершения последней команды (в данном случае useradd). — это специальная переменная, которая хранит статус выхода из последней выполненной команды. -ne 0 проверяет, не равен ли этот код 0, что означает, что произошла ошибка.

  • echo 'The account could not be created.': Если команда создания пользователя завершилась неудачей (т.е. условие if истинно), в этой строке будет выведено сообщение о том, что учетную запись создать не удалось.

  • exit 1: Выход из скрипта и возвращение кода 1, который обычно указывает на то, что произошла ошибка.

Раздел с генерацией пароля:

  • echo ${PASSWORD} | passwd — stdin ${USER_NAME}: Устанавливает пароль для нового пользователя, который был введен в качестве первого аргумента. После того как пользователю будет присвоен пароль, он будет выведен в командную строку. Пароль будет передан команде passwd, которая изменит пароль в зависимости от имени пользователя.

  • Следующий оператор if проверяет, была ли команда passwd успешной, смотря на код завершения ($?). Если код не равен 0 (что означает, что произошла ошибка), он выводит "The password for the account could not be set." и выходит из скрипта с кодом завершения 1, указывающим на ошибку.

  • passwd -e ${USER_NAME}: Эта команда заставляет нового пользователя изменить пароль при следующем входе в систему в целях безопасности.

  • Команды echo выводят имя пользователя, сгенерированный пароль и хост (имя компьютера), на котором был создан пользователь. Эта информация выводится на терминал, чтобы человек, выполняющий скрипт, мог сохранить где-нибудь данные о новой учетной записи.

  • exit 0: Скрипт завершает работу с кодом завершения 0, что является условным обозначением успеха.

Весь скрипт целиком:

  • Вот весь скрипт, собранный воедино.

Шаг 4: Проверка скрипта

Теперь мы протестируем наш скрипт и посмотрим, как он работает!

  • Введите имя пользователя, чтобы узнать, будет ли сгенерирован пароль.

  • Обязательно скопируйте один из паролей и сохраните его где-нибудь. Мы будем менять его на новый уникальный пароль.

sudo ./add-new-local.user.sh exampleuser COMMENT
Ex: sudo ./add-new-local.user.sh gbaidoo George Baidoo
Успех
Успех

Пользователь №2

Успех
Успех

Пользователь №3

Успех
Успех

Если вы получите результаты, подобные тем, что можно увидеть на изображениях выше, значит, скрипт работает правильно. Отличная работа!

Попробуйте выполнить скрипт без привилегий sudo или root.

  • Помните, что мы написали скрипт так, чтобы его мог выполнить только пользователь с правами sudo или root. Если вы попытаетесь выполнить этот файл без соответствующих прав, вам будет отказано в доступе и предложено запустить скрипт с sudo.

Замените случайно сгенерированный пароль на уникальный

  • Давайте изменим пароль одного из ваших пользователей, выполнив команду "su" с указанием имени пользователя.

  • Вставьте сгенерированный пароль в раздел "current password" и нажмите Enter.

  • Введите новый пароль дважды, чтобы подтвердить изменение.

su - example
Ex: su - gbaidoo

Поздравляем, если вы дошли до этого момента, значит, вы успешно завершили этот проект! Вы узнали, как написать скрипт, который автоматически генерирует пароли для новых пользователей в системе linux, демонстрируя эффективность и безопасность системного администрирования linux!


Сегодня вечером пройдет открытый урок «Веб-сервер Angie: сравнение с Nginx, новые возможности». Занятие будет полезно для системным администраторам Linux, веб-разработчикам и всем, кто использует Nginx в своих проектах. Записывайтесь по ссылке.

Комментарии (3)


  1. DoMoVoY
    18.04.2024 18:00
    +4

    есть отличный пакет для генерирования паролей. Есть во многих дистрибьютивах по-умолчанию

    pwgen - generate pronounceable passwords

    $ pwgen -N1 -s 12
    Py7nUGQln1mv


  1. Shaman_RSHU
    18.04.2024 18:00
    +4

    Понятно, что статья ради того, чтобы записались на курс. Но зачем все скрипты в виде картинок не лучшего качества публиковать (может конечно стал хуже видеть :)

    И скрипт нужно немного подправить
    #!/bin/bash
    # Creating a script that adds a new user on a local system.
    # A username must be supplied as an argument to the script.
    # Optionally, provide a comment for the account as an argument.
    # A password will be automatically generated for the account.
    # The username, password, and host for the account will be displayed.
    # Make sure the script is being executed with superuser privileges.
    
    if [[ "${UID}" -ne 0 ]]
    then
        echo 'Please run with sudo or as root.'
        exit 1
    fi
    
    # If they don't supply at least one argument, then give them help.
    if [[ "${#}" -lt 1 ]]
    then
        echo "Usage: ${0} USER_NAME [COMMENT]..."
        echo 'Create an account on the local system with the name of USER_NAME and comment field of COMMENT.'
        exit 1
    fi
    
    # The first parameter is the user name
    USER_NAME="${1}"
    # The rest of the parameters are for the account comments.
    shift
    COMMENT="${@}"
    
    # Generate a password
    PASSWORD=$(date +%s%N | sha256sum | head -c48)
    
    # Create the account.
    useradd -c "${COMMENT}" -m ${USER_NAME}
    
    # Check to see if the useradd command succeeded
    # We don't want to tell the user that an account was created when it hasn't been.
    if [[ "${?}" -ne 0 ]]
    then
        echo 'The account could not be created.'
        exit 1
    fi
    
    # Set the password
    echo ${PASSWORD} | passwd --stdin ${USER_NAME}
    
    # Check to see if the passwd command succeeded.
    if [[ "${?}" -ne 0 ]]
    then
        echo 'The password for the account could not be set.'
        exit 1
    fi
    
    # Force password change on first login.
    passwd -e ${USER_NAME}
    
    # Display the username, password, and the host where the user was created.
    echo
    echo 'username:'
    echo "${USER_NAME}"
    echo
    echo 'password:'
    echo "${PASSWORD}"
    echo


  1. RingilNill
    18.04.2024 18:00
    +4

    Ох. Это все настолько плохо, что я даже решил зарегистрироваться

    1. Не нужно придумывать костылей для генерации паролей, если есть необходимость в их генерации. Нужно использовать стандартные утилиты.
    Есть специализированные утилиты с заданием нужны ли спец.символы и прочее, нужны ли цифры, ну и далее по списку. Как простейший пример pwgen. Можно добавить в скрипт проверку есть ли он и сообщение о необходимости доустановки

    Можно не использовать pwgen и его аналоги, а использовать openssl, который есть на всех системах. Примерно так `openssl rand -base64 12`
    Можно вообще ничего не использовать из внешних зависимостей и сделать так `tr -cd '[:alnum:]' </dev/urandom | fold -w16 | head -n1`

    Но не нужно использовать костыли особенно такие как здесь от даты-времени

    1. Для смены пароля юзеру не надо под него suчиться, есть `passwd USERNAME` от рута, например

    2. Сам по себе скрипт для добавления может быть вот таким
      ```bash

      #!/usr/bin/env bash

      EXPECTED_ARGS=1
      E_BADARGS=65

      PASS=$(tr -cd '[:alnum:]' </dev/urandom | fold -w24 | head -n1)

      if [ "$EUID" -ne 0 ]
      then echo "Please run as root"
      exit
      fi

      if [ $# -ne $EXPECTED_ARGS ]; then
      echo "Usage: $0 new_user_name"
      exit $E_BADARGS
      fi

      useradd -s/bin/bash -m "$1"

      echo "1:PASS"|chpasswd

      printf "user: %s\n" "1PASS"
      ```

      В целом ради подобной мелочи не нужно строчить статью, но так как корп.блог то видимо KPI

      Я же хочу, что бы те кому будет подобное нужно не изобретали велосипедов, а думали головой, свой пример скрипта я предложил