-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathcreate_users.sh
More file actions
183 lines (165 loc) · 6.47 KB
/
create_users.sh
File metadata and controls
183 lines (165 loc) · 6.47 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
#!/bin/bash
set -euo pipefail
umask 077
echo "Create users start"
usage() {
cat <<'EOF'
Usage:
/root/create_users.sh
Создать пользователей из файлов (поведение по умолчанию, используется при старте контейнера).
/root/create_users.sh add <username> <password> [--sudo]
Добавить/обновить пользователя в уже запущенном контейнере и сразу выдать доступ по SSH.
Запуск только с привилегиями root/sudo.
EOF
}
require_superuser() {
if [ "$(id -u)" -ne 0 ]; then
echo "Эта операция требует привилегий суперпользователя (sudo/root)." >&2
exit 1
fi
}
# Функция для создания пользователя, если он не существует
create_user_if_not_exists() {
local username="$1"
local password="$2"
local is_sudo="$3"
if id "$username" &>/dev/null; then
echo "User $username already exists, updating password"
echo "$username:$password" | chpasswd
if [ "$is_sudo" = "true" ]; then
usermod -aG sudo "$username" 2>/dev/null || true
fi
# Гарантировать интерактивную оболочку с историей и стрелками
current_shell="$(getent passwd "$username" | cut -d: -f7 || echo "")"
if [ "$current_shell" != "/bin/bash" ]; then
usermod -s /bin/bash "$username" 2>/dev/null || true
fi
else
echo "Creating user $username"
useradd -m -s /bin/bash "$username" && echo "$username:$password" | chpasswd
if [ "$is_sudo" = "true" ]; then
adduser "$username" sudo
fi
fi
# Обеспечить корректные права на домашнюю директорию
local home_dir="/home/$username"
mkdir -p "$home_dir"
chown "$username:$username" "$home_dir"
chmod 700 "$home_dir"
}
# Управление списком AllowUsers для SSH
ALLOW_USERS=""
load_allow_users_from_config() {
# Считать текущий AllowUsers из sshd_config, если есть
if grep -q '^AllowUsers' /etc/ssh/sshd_config 2>/dev/null; then
local existing
existing="$(awk '/^AllowUsers/{for(i=2;i<=NF;i++)print $i}' /etc/ssh/sshd_config)"
if [ -n "$existing" ]; then
# Разбиваем по пробелам и добавляем
while IFS= read -r u; do
[ -z "$u" ] && continue
case " $ALLOW_USERS " in
*" $u "*) ;;
*) ALLOW_USERS="$ALLOW_USERS $u" ;;
esac
done <<EOF
$existing
EOF
fi
fi
}
add_allow_user() {
local u="$1"
[ -z "$u" ] && return 0
case " $ALLOW_USERS " in
*" $u "*) ;;
*) ALLOW_USERS="$ALLOW_USERS $u" ;;
esac
}
apply_allow_users() {
[ -z "$ALLOW_USERS" ] && return 0
# Нормализуем пробелы и удаляем дубликаты
ALLOW_USERS="$(
echo "$ALLOW_USERS" | tr ' ' '\n' | sed '/^$/d' | awk '!seen[$0]++' | paste -sd' ' -
)"
if grep -q '^AllowUsers' /etc/ssh/sshd_config; then
sed -i "s/^AllowUsers.*/AllowUsers $ALLOW_USERS/" /etc/ssh/sshd_config
else
echo "AllowUsers $ALLOW_USERS" >> /etc/ssh/sshd_config
fi
# Применить изменения без перезапуска контейнера.
# Бьём SIGUP только в мастер-процесс sshd, чтобы не ронять активные сессии.
if [ -f /run/sshd.pid ]; then
kill -HUP "$(cat /run/sshd.pid)" 2>/dev/null || true
else
master_pid="$(pidof sshd 2>/dev/null | awk '{print $1}' || true)"
[ -n "${master_pid:-}" ] && kill -HUP "$master_pid" 2>/dev/null || true
fi
}
# Режим добавления пользователя в уже запущенном контейнере
if [ "${1:-}" = "add" ]; then
require_superuser
# Сохранить текущий AllowUsers и расширить новым пользователем
load_allow_users_from_config
shift
want_sudo="false"
username=""
password=""
while [ $# -gt 0 ]; do
case "$1" in
--sudo)
want_sudo="true"
shift
;;
-h|--help)
usage
exit 0
;;
*)
if [ -z "$username" ]; then
username="$1"
elif [ -z "$password" ]; then
password="$1"
else
echo "Слишком много аргументов." >&2
usage
exit 1
fi
shift
;;
esac
done
if [ -z "$username" ] || [ -z "$password" ]; then
echo "Нужно указать имя пользователя и пароль." >&2
usage
exit 1
fi
create_user_if_not_exists "$username" "$password" "$want_sudo"
add_allow_user "$username"
apply_allow_users
echo "Пользователь $username создан/обновлён (sudo=$want_sudo)."
exit 0
fi
# Определяем источники файлов с пользователями (секреты/монтирование)
SUPERUSERS_FILE=""
USERS_FILE=""
if [ -f /run/secrets/superusers.txt ]; then SUPERUSERS_FILE="/run/secrets/superusers.txt"; elif [ -f /root/superusers.txt ]; then SUPERUSERS_FILE="/root/superusers.txt"; fi
if [ -f /run/secrets/users.txt ]; then USERS_FILE="/run/secrets/users.txt"; elif [ -f /root/users.txt ]; then USERS_FILE="/root/users.txt"; fi
# Создание суперпользователей
if [ -n "${SUPERUSERS_FILE:-}" ] && [ -f "$SUPERUSERS_FILE" ]; then
while IFS=: read -r username password; do
[ -z "${username:-}" ] && continue
create_user_if_not_exists "$username" "$password" "true"
add_allow_user "$username"
done < "$SUPERUSERS_FILE"
fi
# Создание обычных пользователей
if [ -n "${USERS_FILE:-}" ] && [ -f "$USERS_FILE" ]; then
while IFS=: read -r username password; do
[ -z "${username:-}" ] && continue
create_user_if_not_exists "$username" "$password" "false"
add_allow_user "$username"
done < "$USERS_FILE"
fi
apply_allow_users
echo "Create users done!"