Создание пользователя в Linux средствами Python: полное руководство

Раздел: Системное администрирование -> Администрирование

Основные подходы к созданию пользователей

Каким образом автоматизировать добавление локальной учётной записи в Linux с помощью Python?

Наиболее эффективным решением является использование модуля subprocess для вызова системной команды useradd. Этот метод обеспечивает полный контроль над параметрами, обработку ошибок и совместимость с любым дистрибутивом.


import subprocess
import crypt

def create_user(username, password, home_dir=None):
    """Создание пользователя с указанными параметрами."""
    cmd = ['useradd', '-m']  # -m создаёт домашнюю директорию
    if home_dir:
        cmd.extend(['-d', home_dir])
    cmd.append(username)
    
    try:
        subprocess.run(cmd, check=True, capture_output=True, text=True)
        # Установка пароля через chpasswd (пароль передаётся через stdin)
        passwd_proc = subprocess.run(
            ['chpasswd'],
            input=f"{username}:{password}\n",
            capture_output=True,
            text=True,
            check=True
        )
    except subprocess.CalledProcessError as e:
        raise RuntimeError(f"Ошибка создания пользователя: {e.stderr}")
    return True

Python git bash (работа с git и bash в python)

Пояснение шагов:

  • useradd -m создаёт пользователя и его домашний каталог.
  • chpasswd принимает пары имя:пароль через stdin, что безопаснее передачи в аргументах.
  • Параметр check=True вызывает исключение при коде возврата, отличном от 0.

Типичные проблемы:

  • Недостаточные привилегии – скрипт должен выполняться от root или через sudo.
  • Пользователь уже существует – useradd вернёт код 9, нужно проверить через id username или обработать исключение.
  • Некорректный формат пароля – chpasswd может не принять пароль, если он слишком простой (зависит от настроек PAM).

Как быстро создать пользователя без сложной обработки ошибок?

Метод с использованием os.system – самый простой, но не рекомендуется для production из-за отсутствия обработки ошибок и уязвимостей.


import os
os.system(f"useradd -m {username}")
os.system(f"echo '{username}:{password}' | chpasswd")
  

Python host file (редактирование файла hosts)

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

Как задать пароль с шифрованием при создании?

Команда useradd может принять уже зашифрованный пароль через опцию -p. Python модуль crypt позволяет сгенерировать хеш.


import crypt
import subprocess

salt = crypt.mksalt(crypt.METHOD_SHA512)
encrypted = crypt.crypt(password, salt)
subprocess.run(['useradd', '-m', '-p', encrypted, username], check=True)
  

Python установка программы (установка программы на python)

Обратите внимание: опция -p передаёт хеш в открытом виде в аргументах процесса, что может быть зафиксировано в списке процессов. Используйте только в защищённой среде.

Какие шаги выполняются при создании пользователя на уровне файлов? (прямое редактирование)

Для понимания процесса можно вручную добавить записи в /etc/passwd, /etc/shadow, /etc/group и создать домашнюю директорию. Однако это крайне опасный подход и требует прав root.


import pwd, grp, os, crypt

# Пример добавления записи в passwd (неполный, без проверок)
uid = 1500
gid = 1500
home_dir = f"/home/{username}"
entry = f"{username}:x:{uid}:{gid}:{username}:{home_dir}:/bin/bash\n"
with open('/etc/passwd', 'a') as f:
    f.write(entry)
# Аналогично shadow, group, создание директории
  

создание пользователя python (создание пользователя в системе с помощью python)

Ошибки: некорректные UID, отсутствие блокировок файлов, нарушение целостности базы пользователей. Применять только в учебных целях.

Как создать пользователя в централизованной системе аутентификации (LDAP)?

Для LDAP используется библиотека python-ldap. Пример добавления записи в дерево LDAP:


import ldap

conn = ldap.initialize('ldap://localhost')
conn.simple_bind_s('cn=admin,dc=example,dc=com', 'admin_password')

dn = f"uid={username},ou=people,dc=example,dc=com"
attrs = {
    'objectClass': [b'inetOrgPerson', b'posixAccount', b'top'],
    'uid': [username.encode()],
    'cn': [username.encode()],
    'sn': [username.encode()],
    'uidNumber': [str(uid).encode()],
    'gidNumber': [str(gid).encode()],
    'homeDirectory': [f"/home/{username}".encode()],
    'loginShell': [b'/bin/bash'],
    'userPassword': [encrypted.encode()],
}
conn.add_s(dn, ldap.modlist.addModlist(attrs))
  

терминал python 3 (открытие терминала python 3)

Проблемы: требуется настроенный LDAP-сервер, правильная схема, атрибуты. Ошибки подключения или недостаточные права приводят к исключениям.

Как создать пользователя в Windows из Python?

В Windows используется команда net user через subprocess. Требуются права администратора.


import subprocess

def create_windows_user(username, password):
    cmd = ['net', 'user', username, password, '/add']
    result = subprocess.run(cmd, capture_output=True, text=True)
    if result.returncode != 0:
        raise RuntimeError(result.stderr)
    # Добавление в группу (опционально)
    subprocess.run(['net', 'localgroup', 'Users', username, '/add'], check=True)
  

Ошибки: имя пользователя может нарушать политики, пароль не соответствует требованиям сложности. Команда должна выполняться в командной строке с повышением привилегий.

Расширенные примеры с детальным разбором

Ниже приведены более сложные сценарии, включающие проверки, логирование и работу с группами.

Пример 1. Создание пользователя с настройками по умолчанию и проверкой существования

Пример

#!/usr/bin/env python3
import subprocess
import sys
import logging

logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')

def user_exists(username):
    """Проверка существования пользователя через id."""
    result = subprocess.run(['id', username], capture_output=True, text=True)
    return result.returncode == 0

def create_user_advanced(username, password, groups=None, expire_days=None):
    if user_exists(username):
        logging.warning(f"Пользователь {username} уже существует. Пропуск.")
        return False
    
    cmd = ['useradd', '-m', '-s', '/bin/bash']
    if groups:
        cmd.extend(['-G', ','.join(groups)])
    if expire_days is not None:
        # Добавление срока действия учётной записи (в днях с 1970-01-01)
        import datetime
        expire_date = datetime.datetime.now() + datetime.timedelta(days=expire_days)
        days_since_epoch = (expire_date - datetime.datetime(1970,1,1)).days
        cmd.extend(['-e', str(days_since_epoch)])
    cmd.append(username)
    
    try:
        subprocess.run(cmd, check=True, capture_output=True, text=True)
        # Установка пароля
        pwd_proc = subprocess.run(
            ['chpasswd'],
            input=f"{username}:{password}\n",
            capture_output=True,
            text=True,
            check=True
        )
        logging.info(f"Пользователь {username} успешно создан.")
        return True
    except subprocess.CalledProcessError as e:
        logging.error(f"Ошибка при создании {username}: {e.stderr}")
        return False

if __name__ == '__main__':
    create_user_advanced('testuser', 'StrongPass123', groups=['wheel'], expire_days=90)
2025-03-25 12:00:00,000 - INFO - Пользователь testuser успешно создан.

Пример 2. Создание пользователя с генерацией случайного пароля и экспортом в файл

Пример

import secrets
import string
import subprocess

def generate_password(length=16):
    alphabet = string.ascii_letters + string.digits + string.punctuation
    return ''.join(secrets.choice(alphabet) for _ in range(length))

def create_user_with_random_password(username):
    password = generate_password()
    try:
        subprocess.run(['useradd', '-m', username], check=True, capture_output=True)
        subprocess.run(['chpasswd'], input=f"{username}:{password}\n", check=True, capture_output=True, text=True)
        # Сохранение пароля в файл с ограниченными правами
        with open(f"/tmp/{username}_password.txt", 'w') as f:
            f.write(password)
        os.chmod(f"/tmp/{username}_password.txt", 0o600)
        print(f"Пользователь {username} создан. Пароль сохранён в /tmp/{username}_password.txt")
    except subprocess.CalledProcessError as e:
        print(f"Ошибка: {e.stderr}")
Пользователь testuser создан. Пароль сохранён в /tmp/testuser_password.txt

Пример 3. Массовое создание пользователей из CSV-файла

Пример

import csv
import subprocess

def create_users_from_csv(csv_path):
    with open(csv_path, newline='') as f:
        reader = csv.DictReader(f)
        for row in reader:
            username = row['username']
            password = row['password']
            groups = row.get('groups', '').split(',')
            cmd = ['useradd', '-m', username]
            if groups:
                cmd.extend(['-G', ','.join(groups)])
            try:
                subprocess.run(cmd, check=True, capture_output=True)
                subprocess.run(['chpasswd'], input=f"{username}:{password}\n", check=True, capture_output=True, text=True)
                print(f"OK: {username}")
            except subprocess.CalledProcessError as e:
                print(f"FAIL: {username} - {e.stderr}")

Пример CSV:

Пример

username,password,groups
ivanov,Secret123,users
petrova,Qwerty!456,admin
OK: ivanov
OK: petrova

Пример 4. Создание пользователя в Windows с добавлением в группу и установкой срока действия пароля

Пример

import subprocess
import datetime

def create_win_user(username, password, group='Users', days_until_expire=30):
    # Создание пользователя
    subprocess.run(['net', 'user', username, password, '/add', '/passwordchg:yes'], check=True)
    # Добавление в локальную группу
    subprocess.run(['net', 'localgroup', group, username, '/add'], check=True)
    # Установка срока действия пароля (в днях от текущей даты)
    expire_date = datetime.datetime.now() + datetime.timedelta(days=days_until_expire)
    # Преобразование в формат для net user: MM/DD/YYYY
    expire_str = expire_date.strftime('%m/%d/%Y')
    subprocess.run(['net', 'user', username, f'/expires:{expire_str}'], check=True)

Результат: пользователь создаётся и получает ограничения по сроку пароля. Команды выполняются в контексте администратора.

Создание пользователя в системе с помощью Python - comments

En
создание пользователя python (python)