Пост

Собираем Samba NAS в Proxmox LXC. Часть 2: Рабочая шара для файлов

Настраиваем рабочую Samba-шару Share в Proxmox LXC: SMB3 only, пользователь, права доступа, smb.conf и bash-скрипт установки.

Собираем Samba NAS в Proxmox LXC. Часть 2: Рабочая шара для файлов

Задача

В первой части мы спроектировали архитектуру Samba/NAS под Proxmox.

Теперь создадим первую рабочую шару:

1
\\nas\share

Это будет основная writable-шара для авторизованного пользователя.

Требования:

  • установить Samba;
  • включить SMB3-only;
  • отключить устаревшую аутентификацию;
  • создать Unix-пользователя;
  • добавить пользователя в Samba;
  • создать каталог /srv/samba/share;
  • настроить права;
  • создать /etc/samba/smb.conf;
  • проверить конфиг;
  • перезапустить сервис;
  • проверить подключение.

В этой статье мы делаем базовый фундамент. [secure], audit и [public] добавим в следующих частях.


Исходные данные

Сервер:

1
2
Proxmox LXC
└── Debian / Ubuntu / TurnKey Linux

Шара:

1
/srv/samba/share

Пользователь:

1
samba

Скрипт:

1
setup-samba-share.sh

Почему не хранить пароль прямо в скрипте

В быстрых черновиках часто встречается так:

1
SAMBA_PASS="password"

Для статьи и реальной практики лучше так не делать.

Правильнее:

  • запросить пароль интерактивно;
  • не писать его в историю команд;
  • не хранить его в Git;
  • не коммитить секреты в репозиторий.

Поэтому скрипт ниже спросит пароль сам.


Скрипт setup-samba-share.sh

Создай файл:

1
nano setup-samba-share.sh

Вставь:

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
#!/usr/bin/env bash
set -Eeuo pipefail

# ============================================================
# SMB на bash. Часть 2. Share
# Базовая настройка Samba SMB3-only и рабочей шары [share]
# ============================================================

SAMBA_USER="${SAMBA_USER:-samba}"
SHARE_NAME="${SHARE_NAME:-share}"
SHARE_DIR="${SHARE_DIR:-/srv/samba/share}"
SMB_CONF="${SMB_CONF:-/etc/samba/smb.conf}"

require_root() {
  if [[ "${EUID}" -ne 0 ]]; then
    echo "Ошибка: запусти скрипт от root"
    exit 1
  fi
}

ask_password() {
  if [[ -n "${SAMBA_PASS:-}" ]]; then
    return
  fi

  read -rsp "Введите пароль для пользователя Samba '${SAMBA_USER}': " SAMBA_PASS
  echo
  read -rsp "Повторите пароль: " SAMBA_PASS_CONFIRM
  echo

  if [[ "${SAMBA_PASS}" != "${SAMBA_PASS_CONFIRM}" ]]; then
    echo "Ошибка: пароли не совпадают"
    exit 1
  fi

  if [[ -z "${SAMBA_PASS}" ]]; then
    echo "Ошибка: пароль не может быть пустым"
    exit 1
  fi
}

install_packages() {
  echo "==> Устанавливаем Samba и ACL"
  apt update
  apt install -y samba smbclient acl
}

create_user() {
  if ! id "${SAMBA_USER}" &>/dev/null; then
    echo "==> Создаём Unix-пользователя ${SAMBA_USER}"
    useradd -m -s /usr/sbin/nologin "${SAMBA_USER}"
  else
    echo "==> Unix-пользователь ${SAMBA_USER} уже существует"
  fi

  echo "==> Обновляем пароль Unix-пользователя"
  echo "${SAMBA_USER}:${SAMBA_PASS}" | chpasswd
}

prepare_share_dir() {
  echo "==> Создаём каталог ${SHARE_DIR}"
  mkdir -p "${SHARE_DIR}"

  echo "==> Настраиваем владельца и права"
  chown "${SAMBA_USER}:${SAMBA_USER}" "${SHARE_DIR}"
  chmod 0770 "${SHARE_DIR}"

  # Сбрасываем лишние ACL, если они были.
  setfacl -b "${SHARE_DIR}" 2>/dev/null || true
}

create_samba_user() {
  echo "==> Добавляем пользователя в базу Samba"
  printf "%s\n%s\n" "${SAMBA_PASS}" "${SAMBA_PASS}" | smbpasswd -a "${SAMBA_USER}"
  smbpasswd -e "${SAMBA_USER}"
}

backup_config() {
  if [[ -f "${SMB_CONF}" ]]; then
    local backup="${SMB_CONF}.bak.$(date +%F_%H-%M-%S)"
    echo "==> Делаем backup ${backup}"
    cp "${SMB_CONF}" "${backup}"
  fi
}

write_config() {
  echo "==> Пишем новый ${SMB_CONF}"

  cat > "${SMB_CONF}" <<EOF
[global]
   server string = Tytosmag Samba NAS
   workgroup = WORKGROUP
   security = user
   server role = standalone server
   map to guest = Bad User

   # SMB3 only
   server min protocol = SMB3
   server max protocol = SMB3

   # Authentication hardening
   ntlm auth = ntlmv2-only
   lanman auth = no
   client lanman auth = no

   # Signing
   server signing = auto
   client signing = auto

   # Charset and logs
   unix charset = UTF-8
   log file = /var/log/samba/log.%m
   max log size = 1000

[${SHARE_NAME}]
   path = ${SHARE_DIR}
   valid users = ${SAMBA_USER}
   read only = no
   writable = yes
   browseable = yes

   force user = ${SAMBA_USER}
   force group = ${SAMBA_USER}

   create mask = 0660
   directory mask = 0770
EOF
}

validate_config() {
  echo "==> Проверяем Samba config через testparm"
  testparm -s "${SMB_CONF}" >/dev/null
}

restart_samba() {
  echo "==> Перезапускаем Samba"
  systemctl restart smbd

  if systemctl list-unit-files | grep -q '^nmbd'; then
    systemctl restart nmbd || true
  fi
}

print_summary() {
  local host
  host="$(hostname -f 2>/dev/null || hostname)"

  echo
  echo "Готово."
  echo "Шара: //${host}/${SHARE_NAME}"
  echo "Каталог: ${SHARE_DIR}"
  echo "Пользователь: ${SAMBA_USER}"
  echo
  echo "Проверка на сервере:"
  echo "  testparm -s"
  echo "  systemctl status smbd --no-pager"
  echo "  smbstatus"
  echo
  echo "Проверка с клиента Linux:"
  echo "  smbclient //SERVER_IP/${SHARE_NAME} -U ${SAMBA_USER} -m SMB3"
}

main() {
  require_root
  ask_password
  install_packages
  create_user
  prepare_share_dir
  create_samba_user
  backup_config
  write_config
  validate_config
  restart_samba
  print_summary
}

main "$@"

Запуск

1
2
chmod +x setup-samba-share.sh
sudo ./setup-samba-share.sh

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

1
sudo SAMBA_USER="samba" SAMBA_PASS="StrongPasswordHere" ./setup-samba-share.sh

Не используй пароль из примера в реальной сети. Лучше сгенерировать уникальный пароль и сохранить его в менеджере паролей.


Проверка конфигурации

На сервере:

1
testparm -s

Проверяем сервис:

1
systemctl status smbd --no-pager

Проверяем открытый порт:

1
ss -ltnp | grep ':445'

Проверяем статус Samba:

1
smbstatus

Проверка подключения с Linux

1
smbclient -L //SERVER_IP -U samba -m SMB3

Подключение к шаре:

1
smbclient //SERVER_IP/share -U samba -m SMB3

Внутри smbclient:

1
2
3
4
smb: \> ls
smb: \> put test.txt
smb: \> ls
smb: \> quit

Проверка подключения с Windows

В проводнике:

1
\\SERVER_IP\share

Или через CMD:

net use S: \\SERVER_IP\share /user:samba

Отключить:

net use S: /delete

Что получилось

После запуска у нас есть:

1
/srv/samba/share

и рабочая SMB-шара:

1
\\nas\share

Свойства:

  • доступ только по логину и паролю;
  • writable;
  • SMB3-only;
  • NTLMv2-only;
  • корректные права 0770;
  • создаваемые файлы получают маску 0660;
  • директории получают маску 0770.

Возможные ошибки

NT_STATUS_LOGON_FAILURE

Причина:

  • неверный пароль;
  • пользователь не добавлен в Samba;
  • пользователь отключён.

Проверка:

1
2
sudo pdbedit -L
sudo smbpasswd -e samba

Сброс пароля:

1
sudo smbpasswd samba

tree connect failed: NT_STATUS_BAD_NETWORK_NAME

Причина:

  • неверное имя шары;
  • блок [share] не попал в smb.conf;
  • Samba не перезапущена.

Проверка:

1
testparm -s | grep -A20 '\[share\]'

Порт 445 не слушается

Проверка:

1
2
3
systemctl status smbd --no-pager
journalctl -u smbd -n 100 --no-pager
ss -ltnp | grep ':445'

Итог

Мы получили базовую рабочую Samba-шару [share].

Это фундамент всей серии. В следующей части добавим отдельную защищённую шару [secure], где включим SMB encryption и подготовим её под аудит.

Авторский пост защищен лицензией CC BY 4.0 .

Популярные теги