Files
digital-garden/dev/snippet/Файловый сервер на Samba.md
Struchkov Mark 1027f5ccb2
All checks were successful
continuous-integration/drone/push Build is passing
Файловый сервер на Samba.md
2026-01-08 01:51:51 +03:00

389 lines
18 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
aliases:
tags:
- maturity/🌱
date: 2024-09-06
zero-link:
- "[[../../meta/zero/00 Snippets|00 Snippets]]"
parents:
- "[[../devops/docker/Полезные Docker образы|Полезные Docker образы]]"
linked:
---
Samba — свободное программное обеспечение для организации файлового сервера на базе протокола SMB/CIFS. С 1992 года обеспечивает безопасный и стабильный обмен файлами между всеми клиентами, использующими SMB/CIFS: Windows, macOS, Linux и другими.
## Особенности образа
- Базовый образ Alpine Linux (минимальный размер)
- Поддержка SMB2/SMB3 (SMB1 отключен по умолчанию)
- Поддержка Time Machine для macOS
- Встроенная корзина для удаленных файлов
- Оптимизированные настройки производительности
- Healthcheck для мониторинга состояния
## Быстрый старт
### Docker Compose
```yaml
services:
samba:
image: docker.struchkov.dev/samba:latest
restart: unless-stopped
container_name: samba
hostname: samba
ports:
- "139:139/tcp"
- "445:445/tcp"
volumes:
- ./data:/cloud
command: '-p -u "user1;pass1" -s "share;/cloud;yes;no;no;user1"'
```
### Docker Compose с NetBIOS
Если требуется обнаружение в сети через NetBIOS, добавьте флаг `-n` и порты 137-138/udp:
```yaml
services:
samba:
image: docker.struchkov.dev/samba:latest
restart: unless-stopped
ports:
- "139:139/tcp"
- "445:445/tcp"
- "137:137/udp"
- "138:138/udp"
volumes:
- ./data:/cloud
command: '-n -p -u "user1;pass1" -s "share;/cloud;yes;no;no;user1"'
```
## Параметры командной строки
| Флаг | Описание |
|------|----------|
| `-h` | Показать справку |
| `-c "<from:to>"` | Настроить маппинг символов для имен файлов/директорий |
| `-g "<параметр>"` | Добавить глобальную опцию в smb.conf |
| `-G "<секция;параметр>"` | Добавить опцию в конкретную секцию smb.conf |
| `-i "<путь>"` | Импортировать файл smbpasswd |
| `-n` | Запустить демон nmbd для объявления шар в сети |
| `-p` | Установить владельца и права на расшаренные директории |
| `-r` | Отключить корзину для шар |
| `-S` | Отключить минимальную версию SMB2 (разрешить SMB1) |
| `-t` | Включить поддержку Time Machine для macOS |
| `-s` | Настроить шару (см. формат ниже) |
| `-u` | Добавить пользователя (см. формат ниже) |
| `-w "<workgroup>"` | Настроить рабочую группу (домен) |
| `-W` | Разрешить широкие символические ссылки |
| `-I "<путь>"` | Добавить include в конец smb.conf |
| `-E` | Включить усиленную безопасность (подпись + шифрование) |
### Формат параметра шары (-s)
```
-s "<name;/path>[;browse;readonly;guest;users;admins;writelist;comment]"
```
| Поле | По умолчанию | Описание |
|------|--------------|----------|
| `name` | обязательно | Имя шары для клиентов |
| `/path` | обязательно | Путь к директории |
| `browse` | yes | Видна при обзоре сети (yes/no) |
| `readonly` | yes | Только чтение (yes/no) |
| `guest` | yes | Разрешить гостевой доступ (yes/no) |
| `users` | all | Список разрешенных пользователей (через запятую) |
| `admins` | none | Список администраторов шары (через запятую) |
| `writelist` | — | Пользователи с правом записи на RO-шаре |
| `comment` | — | Описание шары |
### Формат параметра пользователя (-u)
```
-u "<name;password>[;ID;group;GID]"
```
| Поле | Описание |
|------|----------|
| `name` | Имя пользователя (обязательно) |
| `password` | Пароль (обязательно) |
| `ID` | UID пользователя (опционально) |
| `group` | Группа пользователя (опционально) |
| `GID` | GID группы (опционально) |
## Переменные окружения
Альтернатива параметрам командной строки. Для множественных значений используйте нумерацию: SHARE, SHARE2, SHARE3...
| Переменная | Описание |
|------------|----------|
| `SHARE` | Конфигурация шары (поддерживает SHARE2, SHARE3...) |
| `USER` | Конфигурация пользователя (поддерживает USER2, USER3...) |
| `GLOBAL` | Глобальная опция (поддерживает GLOBAL2, GLOBAL3...) |
| `GENERIC` | Опция для секции (поддерживает GENERIC2, GENERIC3...) |
| `CHARMAP` | Маппинг символов |
| `IMPORT` | Путь к файлу smbpasswd для импорта |
| `NMBD` | Включить демон nmbd |
| `PERMISSIONS` | Установить права на шары |
| `RECYCLE` | Отключить корзину |
| `SMB` | Отключить минимальную версию SMB2 |
| `TIMEMACHINE` | Включить поддержку Time Machine |
| `SECURE` | Включить усиленную безопасность |
| `WORKGROUP` | Рабочая группа |
| `WIDELINKS` | Разрешить широкие символические ссылки |
| `USERID` | UID для пользователя smbuser |
| `GROUPID` | GID для группы smb |
| `INCLUDE` | Путь к дополнительному конфиг-файлу |
| `TZ` | Часовой пояс (например, `Europe/Moscow`) |
| `RECYCLE_AGE` | Автоочистка файлов старше N дней из корзины |
| `RECYCLE_CRON_HOUR` | Час запуска очистки (0-23, по умолчанию: 3) |
| `RECYCLE_CRON_MINUTE` | Минута запуска очистки (0-59, по умолчанию: 0) |
### Пример с переменными окружения
```yaml
services:
samba:
image: docker.struchkov.dev/samba:latest
restart: unless-stopped
environment:
TZ: 'Europe/Moscow'
SHARE: "Documents;/documents;yes;no;no;user1,user2"
SHARE2: "Media;/media;yes;yes;yes"
USER: "user1;${SAMBA_USER1_PASSWORD}"
USER2: "user2;${SAMBA_USER2_PASSWORD}"
PERMISSIONS: "true"
ports:
- "139:139/tcp"
- "445:445/tcp"
volumes:
- /mnt/documents:/documents
- /mnt/media:/media
```
## Порты
| Порт | Протокол | Описание |
|------|----------|----------|
| 137 | UDP | NetBIOS Name Service (только с `-n`) |
| 138 | UDP | NetBIOS Datagram Service (только с `-n`) |
| 139 | TCP | SMB over NetBIOS |
| 445 | TCP | SMB direct |
Порты 137 и 138 нужны только при использовании флага `-n` или переменной `NMBD`.
## Time Machine для macOS
Для резервного копирования macOS через Time Machine:
```bash
docker run -d -p 139:139 -p 445:445 \
-v /mnt/backup:/backup \
docker.struchkov.dev/samba:latest -p -t \
-u "macuser;password" \
-s "TimeMachine;/backup;no;no;no;macuser"
```
## Усиленная безопасность
Для сред, требующих дополнительной защиты, используйте флаг `-E` или переменную `SECURE=true`:
```bash
docker run -d -p 445:445 docker.struchkov.dev/samba:latest -E -p \
-u "user;password" \
-s "secure_share;/data;yes;no;no;user"
```
Это включает:
- **Server signing** (mandatory) — предотвращает подмену пакетов
- **Client signing** (mandatory) — гарантирует подлинность клиента
- **SMB encryption** (desired) — шифрует трафик, если клиент поддерживает
**Примечание**: некоторые старые клиенты могут не поддерживать эти функции.
## Корзина (Recycle Bin)
По умолчанию в образе включена корзина. При удалении файлы перемещаются в папку `.deleted` в корне каждой шары вместо окончательного удаления.
### Как работает
```ini
vfs objects = catia recycle
recycle:keeptree = yes # Сохранять структуру папок
recycle:maxsize = 0 # Без лимита размера (0 = любой файл)
recycle:repository = .deleted # Папка для удалённых файлов
recycle:versions = yes # Сохранять версии при повторном удалении
```
1. При удалении файл перемещается в `.deleted` в корне шары
2. Структура директорий сохраняется: `/share/docs/file.txt``/share/.deleted/docs/file.txt`
3. При повторном удалении файла с тем же именем создаются версии: `file.txt`, `Copy #1 of file.txt` и т.д.
### Автоматическая очистка
**Важно**: без очистки удалённые файлы накапливаются бесконечно и занимают место на диске.
Включите автоматическую очистку через переменную `RECYCLE_AGE`:
```yaml
services:
samba:
image: docker.struchkov.dev/samba:latest
environment:
RECYCLE_AGE: "30" # Удалять файлы старше 30 дней
RECYCLE_CRON_HOUR: "4" # Запуск в 4:00 (опционально, по умолчанию: 3)
RECYCLE_CRON_MINUTE: "30" # Запуск в XX:30 (опционально, по умолчанию: 0)
# ... остальная конфигурация
```
Задача очистки:
- Запускается ежедневно в указанное время (по умолчанию 3:00)
- Активируется только если корзина включена (нет флага `-r`)
- Логи пишутся в `/var/log/recycle-cleanup.log`
### Отключение корзины
Используйте флаг `-r` или `RECYCLE=true` для полного отключения корзины:
```bash
docker run -d docker.struchkov.dev/samba:latest -r -p -s "share;/data"
```
Рекомендуется отключать для:
- Хранения больших медиа-файлов (видео, музыка)
- Ограниченного места на диске
- Временных или кэш-директорий
## Полезные глобальные опции
Через флаг `-g` можно настроить дополнительные параметры smb.conf:
| Опция | Описание |
|-------|----------|
| `workgroup = WORKGROUP` | Рабочая группа Windows |
| `server string = Samba Server` | Описание сервера в сети |
| `netbios name = SAMBA` | Имя сервера в сети NetBIOS |
| `map to guest = Bad User` | Автоматически подключать как гостя при неверном логине |
| `guest account = nobody` | Системный пользователь для гостевых подключений |
| `local master = yes` | Участвовать в выборах мастер-браузера |
| `preferred master = yes` | Предпочтительный мастер-браузер |
| `os level = 20` | Приоритет в выборах мастер-браузера (выше = приоритетнее) |
| `wins support = yes` | Включить WINS-сервер для разрешения имен |
| `name resolve order = bcast host` | Порядок разрешения имен |
## Гостевые шары с принудительным пользователем
Для публичных папок без авторизации используйте комбинацию параметров шары и опций `-G`:
```bash
-s "public;/cloud/share;yes;no;yes" \
-G "public;force user = nobody" \
-G "public;force group = nobody" \
-G "public;guest only = yes"
```
Это гарантирует, что все операции выполняются от имени `nobody`, независимо от того, кто подключился.
## Комплексный пример
Сервер с гостевыми и приватными шарами, обнаружением в сети и ограничением ресурсов:
```yaml
services:
samba:
image: docker.struchkov.dev/samba:latest
restart: always
container_name: samba
hostname: samba
network_mode: host
volumes:
- ./storage/samba/:/cloud:z
command: >
-r -n -p
-g "workgroup = WORKGROUP"
-g "server string = Samba Server"
-g "netbios name = SAMBA"
-g "map to guest = Bad User"
-g "guest account = nobody"
-g "local master = yes"
-g "preferred master = yes"
-g "os level = 20"
-g "wins support = yes"
-g "name resolve order = bcast host"
-u "user1;${SMB_USER1}"
-u "user2;${SMB_USER2}"
-s "shared;/cloud/share;yes;no;yes"
-G "shared;force user = nobody"
-G "shared;force group = nobody"
-G "shared;guest only = yes"
-s "media;/cloud/media;yes;no;yes"
-G "media;force user = nobody"
-G "media;force group = nobody"
-G "media;guest only = yes"
-s "user1;/cloud/user1;yes;no;no;user1"
-s "user2;/cloud/user2;yes;no;no;user1,user2"
healthcheck:
test: ["CMD-SHELL", "smbclient -L localhost -N || exit 1"]
interval: 30s
timeout: 10s
retries: 3
start_period: 10s
mem_limit: 256m
mem_reservation: 64m
cpus: 0.5
```
**Особенности конфигурации:**
- `network_mode: host` — необходим для корректной работы NetBIOS и обнаружения в локальной сети
- `-r` — отключена корзина (для экономии места)
- Гостевые шары (`shared`, `media`) доступны без авторизации
- Приватные шары (`user1`, `user2`) доступны только указанным пользователям
- Пароли вынесены в переменные окружения через `.env` файл
- Ограничение памяти и CPU для предсказуемого потребления ресурсов
## Healthcheck
Для мониторинга состояния контейнера:
```yaml
healthcheck:
test: ["CMD-SHELL", "smbclient -L localhost -N || exit 1"]
interval: 30s
timeout: 10s
retries: 3
start_period: 10s
```
Проверяет доступность SMB-сервера через анонимное подключение.
## Ограничение ресурсов
Samba может потреблять много памяти при большом количестве подключений. Рекомендуется ограничить:
```yaml
mem_limit: 256m # Жесткий лимит памяти
mem_reservation: 64m # Гарантированный минимум
cpus: 0.5 # Лимит CPU (0.5 = половина ядра)
```
## Решение проблем
### Ошибка "Access is denied"
Если в логах `change_to_user_internal: chdir_current_service() failed!`:
```bash
docker run -d -p 139:139 -p 445:445 \
-v /path/to/directory:/mount \
docker.struchkov.dev/samba:latest -p
```
Добавьте флаг `-p` или переменную `PERMISSIONS=true`.
Если изменение прав невозможно, используйте `USERID` и `GROUPID`:
```bash
docker run -d -p 139:139 -p 445:445 \
-e USERID=1000 \
-e GROUPID=1000 \
-v /path/to/directory:/mount \
docker.struchkov.dev/samba:latest
```
### Подключение через smbclient
По умолчанию smbclient пытается использовать SMB1. Используйте флаг `-m SMB3`:
```bash
smbclient -L \\\\localhost -U % -m SMB3
smbclient //localhost/share -U user -m SMB3
```
### Параметры -G не переопределяют глобальные настройки
Убедитесь, что используете актуальную версию образа. В старых версиях `GENERIC` обрабатывался до `SHARE`, поэтому секции шар ещё не существовали.
Корректный пример:
```bash
docker run -d -p 139:139 -p 445:445 docker.struchkov.dev/samba:latest \
-s "public;/cloud/share;yes;no;yes" \
-G "public;force user = nobody" \
-G "public;force group = nogroup"
```
***
## Мета информация
**Область**:: [[../../meta/zero/00 Snippets|00 Snippets]]
**Родитель**:: [[../devops/docker/Полезные Docker образы|Полезные Docker образы]]
**Источник**::
**Автор**::
**Создана**:: [[2024-09-06]]
### Дополнительные материалы
- [Исходный код проекта.](https://git.struchkov.dev/DockerFiles/samba) Форк, который я поддерживаю в актуальном состоянии.
- [Оригинальный репозиторий на GitHub.](https://github.com/dperson/samba) Не поддерживается и не обновляется.
- [Образ проекта в моем Nexus](https://nexus.struchkov.dev/#browse/browse:docker:v2%2Fsamba%2Ftags)
### Дочерние заметки
<!-- QueryToSerialize: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->