HP D2700: схема дисковых массивов и назначение хранилищ
HP D2700: схема дисковых массивов и назначение хранилищ
| Версия | 1.8 |
|---|---|
| Дата | 10.11.2026 |
| Статус | P411 с 512 MB FBWC и firmware 6.64 работает в PCIe Slot 1 как PCIe Gen2 x8. D2700 firmware 0150, все 25 дисков исправны, production RAID-массивы созданы. MAIN-DATA передан в VM 103, production Btrfs смонтирован в /srv/main-data. Созданы 8 функциональных Btrfs subvolume, Snapper, группы и POSIX ACL. Samba введена в эксплуатацию: опубликованы 8 SMB shares, проверена матрица доступа, Windows Previous Versions, Samba recycle и автоматическая очистка корзин. ACL корзин скорректированы для административного доступа через File Browser без раскрытия пользовательских корзин профильным группам. Установлен и проверен File Browser Next v3.0.0-next как отдельный systemd-сервис. Management-маршрутизация переведена на gateway 10.44.100.1 через ens19. DNS-интеграция файлового сервера введена в эксплуатацию: настроен split DNS через systemd-resolved, для пяти OT-сегментов зарегистрированы отдельные FQDN и согласованные A/PTR, создан /usr/local/sbin/ot-ddns-register и включён ot-ddns-register.service.На Windows-клиенте проверена штатная процедура переключения Samba-учётной записи: BAT change_share.bat отключает только SMB-сессии к SMR-SRV-OT-SHARE по всем известным IP/FQDN/коротким именам, очищает связанные сохранённые credentials и не затрагивает сетевые подключения к другим серверам.Добавлена модель read-only доступа для производственных подразделений: shared-ro даёт RO к exchange, software и documentation; профильные группы pivoproduction-ro, rozliv-ro и utilities-ro дают RO только к соответствующему производственному share. Для RO-групп настроены обычные и default POSIX ACL с исключением .snapshots и .recycle. Учётная запись rozliv_read проверена локально: доступ только на чтение соответствует принятой матрице.Введён в эксплуатацию конфигурационный backup файлового сервера: создан /usr/local/sbin/share-config-backup, который формирует обычный архив конфигурации и инвентаризации, отдельный зашифрованный AES-256 архив Samba/File Browser credential/state DB и файл SHA256. Первый recovery-набор сформирован и вынесен с сервера. |
| Проект | Расширение памяти сервера |
1. Назначение документа
Документ фиксирует production-архитектуру хранения HP ProLiant DL380 G7 с внешней дисковой полкой HP StorageWorks D2700, контроллером Smart Array P411, аппаратными RAID, виртуальной машиной Ubuntu Server, Btrfs, Snapper, POSIX ACL и Samba.
Здесь рассматриваются основной файловый массив MAIN-DATA, локальный массив CRITICAL-BACKUP, служебный RECOVERY, общий горячий резерв, передача MAIN-DATA в VM 103 и публикация функциональных ресурсов по SMB. TFTP/PXE/Cisco recovery для массива RECOVERY должен оформляться отдельной статьёй.
Начиная с версии 1.3 документ также фиксирует DNS-интеграцию многосетевого файлового сервера: маршрутизацию DNS-запросов по OT-интерфейсам через systemd-resolved, сегментные FQDN, RFC 2136/DDNS через nsupdate и правила коротких имён для клиентов.
2. Состав оборудования
| Сервер | HP ProLiant DL380 G7 |
|---|---|
| Гипервизор | Proxmox VE 9.1.9 |
| Внутренний RAID | HP Smart Array P410i, firmware 6.64, 512 MB cache |
| Внешний RAID | HP Smart Array P411, PCIe Slot 1, firmware 6.64, 512 MB FBWC |
| Полка | HP StorageWorks D2700, 25 × 2.5" SFF SAS |
| Firmware D2700 | 0150 |
| Подключение | P411 port 1E → SFF-8088 → D2700 I/O Module A, P1 |
| Режим | Single Domain |
3. Физическая раскладка дисков D2700
| Отсеки | Диски | Роль | Имя |
|---|---|---|---|
| 1–12 | 12 × 600 GB SAS 10K | Основной RAID50 | MAIN-DATA |
| 13–14 | 2 × 146 GB SAS 15K | RAID1 | RECOVERY |
| 15 | 1 × 600 GB SAS 10K | Shared online spare | GLOBAL-SPARE |
| 16–25 | 10 × 500 GB SAS 7.2K | Резервный RAID50 | CRITICAL-BACKUP |
HP D2700 — bays 01–25
01–12 600 GB MAIN-DATA
13–14 146 GB RECOVERY
15 600 GB GLOBAL-SPARE
16–25 500 GB CRITICAL-BACKUP
4. Production RAID-массивы
4.1. MAIN-DATA
| RAID | RAID50 |
|---|---|
| Состав | 12 × 600 GB SAS 10K |
| Parity groups | 2 группы: bays 1–6 и 7–12 |
| Strip size | 256 KiB |
| Полезная ёмкость | 5.46 TiB / 6.00 TB |
| Назначение | рабочие данные, SMB/NFS, Clonezilla |
4.2. RECOVERY
RAID1 из bays 13–14, около 136 GiB. Зарезервирован под отдельный TFTP/PXE/Cisco recovery-проект.
4.3. GLOBAL-SPARE
Bay 15, 600 GB SAS 10K. P411 отображает диск как shared spare. При отказе активного диска контроллер автоматически использует spare для rebuild. После установки замены в штатный bay контроллер может выполнить copy-back, после чего bay 15 снова становится свободным spare.
4.4. CRITICAL-BACKUP
RAID50 из 10 × 500 GB SAS 7.2K, две parity group по пять дисков, полезная ёмкость около 3.64 TiB. Используется для локальных копий выбранных критичных данных и не публикуется как обычная пользовательская шара.
CRITICAL-BACKUP не является независимым backup: MAIN-DATA и CRITICAL-BACKUP находятся в одной D2700 и зависят от одного P411, сервера и общей инфраструктуры питания.
5. Логика использования хранилищ
MAIN-DATA
├── рабочие документы
├── SMB shares
├── NFS при необходимости
└── Clonezilla
│
└── выбранные критичные копии
↓
CRITICAL-BACKUP
RECOVERY
└── отдельный TFTP/PXE/Cisco recovery проект
6. Имена объектов
| Объект | Имя | Статус |
|---|---|---|
| Основной RAID50 | MAIN-DATA |
Создан |
| Служебный RAID1 | RECOVERY |
Создан |
| Общий spare | GLOBAL-SPARE |
Назначен |
| Резервный RAID50 | CRITICAL-BACKUP |
Создан |
7. Ввод P411 и D2700 в эксплуатацию
Первоначальный 256 MB cache-модуль P411 оказался неисправным и приводил к ошибке self-test. После установки исправного 512 MB FBWC и обновления firmware до 6.64 P411 корректно заработал с SAS-expander D2700. D2700 и оба I/O-модуля работают на firmware 0150.
7.1. Диагностика PCIe/IOCK
При размещении P411 в прежнем PCIe Slot 5 воспроизводились IOCK, reset и controller lockup. Перевод драйвера hpsa в simple mode не устранил проблему. После переноса P411 в PCIe Slot 1 контроллер согласовал PCIe Gen2 5 GT/s ×8; повторных IOCK/lockup в контрольном периоде не зафиксировано.
7.2. Контроль через ssacli
ssacli ctrl all show status
ssacli ctrl slot=1 show detail
ssacli ctrl slot=1 show config
ssacli ctrl slot=1 ld all show detail
ssacli ctrl slot=1 pd all show status
Production checkpoint P411: Controller/Cache/Capacitor Status = OK; firmware 6.64; cache ratio 25% read / 75% write.
7.3. Parity initialization
MAIN-DATA и CRITICAL-BACKUP сохраняют Parity Initialization Status: Queued, при этом logical drive имеют Status: OK. Это не блокирует эксплуатацию, но статус продолжает контролироваться.
8. Виртуальная машина файлового сервера
| VM ID | 103 |
|---|---|
| Имя | SMR-SRV-OT-SHARE |
| Hostname | smr-srv-ot-share |
| ОС | Ubuntu Server 24.04.4 LTS |
| CPU | 4 vCPU, type host |
| RAM | 8 GiB |
| Системный диск | 100 GiB, ext4/LVM |
| Production data | MAIN-DATA через отдельный SCSI device |
| DNS-зона OT | ot-samara.baltika.ru |
| DNS-модель | Multi-homed: отдельный FQDN на каждый OT-сегмент; автоматическая регистрация A/PTR через RFC 2136 |
9. Системный диск VM
Системный диск 100 GiB размещён на внутреннем хранилище Proxmox/P410i. Корневая файловая система Ubuntu — ext4 поверх LVM; production-данные на системном диске не хранятся.
10. Сетевые интерфейсы VM
| Ubuntu | Сегмент | Адрес | Маршрутизация |
|---|---|---|---|
ens18 |
временная сеть настройки | 192.168.1.229/24 |
без default gateway |
ens19 |
Prod management VLAN2100 | 10.44.100.229/24 |
default gateway 10.44.100.1 |
ens20 |
Rozliv VLAN2002 | 172.16.68.229/23 |
connected route |
ens21 |
Pivoproduction VLAN2030 | целевой 172.16.66.229/23 |
целевой интерфейс; route 172.16.66.0/23 пока остаётся на ens23 |
ens22 |
Utilities VLAN2040 | 172.16.70.229/23 |
connected route |
ens23 |
Legacy VLAN1 | 10.255.0.229/16 + переходный 172.16.66.229/23 |
connected: 10.255.0.0/16 и переходный 172.16.66.0/23 |
enp2s1 |
АСТУЭ VLAN2006 | 172.17.14.229/24 |
connected route |
Адрес
172.16.66.229не должен одновременно находиться на legacy-интерфейсе и VLAN2030. После миграции он переносится на целевой интерфейс VLAN2030.
Основной маршрут по умолчанию для VM:
default via 10.44.100.1 dev ens19. Наens18адрес192.168.1.229/24сохранён для локального сервисного доступа, но default gateway через192.168.1.1удалён. Это исключает два конкурирующих default route и обеспечивает обратный трафик к корпоративной сети через management VLAN2100.
Проверенная таблица маршрутизации после netplan try:
default via 10.44.100.1 dev ens19 proto static
10.44.100.0/24 dev ens19 proto kernel scope link src 10.44.100.229
10.255.0.0/16 dev ens23 proto kernel scope link src 10.255.0.229
172.16.66.0/23 dev ens23 proto kernel scope link src 172.16.66.229
172.16.68.0/23 dev ens20 proto kernel scope link src 172.16.68.229
172.16.70.0/23 dev ens22 proto kernel scope link src 172.16.70.229
172.17.14.0/24 dev enp2s1 proto kernel scope link src 172.17.14.229
192.168.1.0/24 dev ens18 proto kernel scope link src 192.168.1.229
10.1. Split DNS через systemd-resolved
Файловый сервер подключён одновременно к нескольким изолированным OT-сегментам. Для корректного обращения к локальному BIND9 каждому OT-интерфейсу назначается DNS-адрес своего сегмента. Маршрутизация запросов выполняется systemd-resolved через route-only domains с префиксом ~.
Важно:
~ot-samara.baltika.ru— это не search suffix. Он определяет, на какой DNS отправлять запрос. Расширение короткого имени выполняется на клиенте через DNS suffix search list и описано в разделе 20.14.
| Интерфейс | Сегмент | DNS | Route-only domains |
|---|---|---|---|
ens18 |
временная сеть настройки | 192.168.1.1 |
общий/внешний resolver; без OT route-only domain |
ens20 |
Rozliv | 172.16.68.53 |
~ot-samara.baltika.ru, ~68.16.172.in-addr.arpa, ~69.16.172.in-addr.arpa |
ens22 |
Utilities | 172.16.70.53 |
~ot-samara.baltika.ru, ~70.16.172.in-addr.arpa, ~71.16.172.in-addr.arpa |
ens23 |
Legacy + временно Pivo | 10.255.0.53, 172.16.66.53 |
~ot-samara.baltika.ru, ~255.10.in-addr.arpa, ~66.16.172.in-addr.arpa, ~67.16.172.in-addr.arpa |
enp2s1 |
АСТУЭ | 172.17.14.53 |
~ot-samara.baltika.ru, ~14.17.172.in-addr.arpa |
ens21 |
Pivoproduction VLAN2030, целевой | пока не назначен | после миграции сюда переносятся DNS 172.16.66.53 и route-only domains ~ot-samara.baltika.ru, ~66.16.172.in-addr.arpa, ~67.16.172.in-addr.arpa |
Почему для /23 указаны две reverse-зоны. Сеть
172.16.66.0/23включает две стандартные reverse-зоны:66.16.172.in-addr.arpaдля адресов172.16.66.xи67.16.172.in-addr.arpaдля адресов172.16.67.x. Обе route-only зоны нужны, чтобы файловый сервер мог разрешать PTR любого узла во всей /23.Это не означает, что собственный IP SHARE должен иметь PTR в обеих зонах. Например,
172.16.66.229имеет PTR только в66.16.172.in-addr.arpa. Запись с owner229в зоне67.16.172.in-addr.arpaозначала бы другой адрес —172.16.67.229.
Management-интерфейс ens19 не использует management-IP DNS-ВМ как DNS: BIND9 намеренно не слушает DNS на management-сети.
Фрагменты DNS-настроек в Netplan; существующие адреса и маршруты интерфейсов при этом сохраняются:
ens18:
nameservers:
addresses:
- 192.168.1.1
ens20:
nameservers:
addresses:
- 172.16.68.53
search:
- "~ot-samara.baltika.ru"
- "~68.16.172.in-addr.arpa"
- "~69.16.172.in-addr.arpa"
ens22:
nameservers:
addresses:
- 172.16.70.53
search:
- "~ot-samara.baltika.ru"
- "~70.16.172.in-addr.arpa"
- "~71.16.172.in-addr.arpa"
ens23:
nameservers:
addresses:
- 10.255.0.53
- 172.16.66.53
search:
- "~ot-samara.baltika.ru"
- "~255.10.in-addr.arpa"
- "~66.16.172.in-addr.arpa"
- "~67.16.172.in-addr.arpa"
enp2s1:
nameservers:
addresses:
- 172.17.14.53
search:
- "~ot-samara.baltika.ru"
- "~14.17.172.in-addr.arpa"
10.2. Применение и проверка DNS-маршрутизации
sudo netplan generate
sudo netplan try --timeout 120
resolvectl status
Подтверждённая маршрутизация:
172.16.68.53PTR — черезens20;172.16.70.53PTR — черезens22;10.255.0.53и172.16.66.53PTR — черезens23;172.17.14.53PTR — черезenp2s1;- прямая зона
ot-samara.baltika.ruможет обслуживаться любым равнозначным OT-link, поскольку все локальные BIND-адреса авторитетны для одной и той же зоны; - обычные внешние имена при текущей переходной конфигурации разрешаются через
ens18 → 192.168.1.1, а не через OT BIND.
11. Ubuntu Server
Ubuntu Server 24.04.4 LTS установлен с OpenSSH. Hostname: smr-srv-ot-share. Временная сеть установки — 192.168.1.229/24.
12. Базовые пакеты
sudo apt install -y ca-certificates curl nano openssl iputils-ping tcpdump arping bash-completion lsof qemu-guest-agent systemd-timesyncd ufw ethtool rsync acl attr btrfs-progs snapper
13. QEMU Guest Agent
sudo systemctl enable --now qemu-guest-agent
systemctl status qemu-guest-agent --no-pager
Сервис подтверждён как active (running).
14. Время
sudo timedatectl set-timezone Europe/Samara
sudo timedatectl set-local-rtc 0
sudo timedatectl set-ntp true
15. Запрет маршрутизации между OT-сегментами
net.ipv4.ip_forward = 0
net.ipv6.conf.all.forwarding = 0
VM является многосетевым файловым сервером, но не маршрутизатором. Для reverse path filtering используется loose mode rp_filter=2.
16. Production MAIN-DATA в VM 103
Logical drive MAIN-DATA передан в VM по стабильному идентификатору /dev/disk/by-id/scsi-3600508b1001c2abf1f734aef851f07c9. Имена /dev/sdX не считаются постоянными.
qm set 103 -scsi2 /dev/disk/by-id/scsi-3600508b1001c2abf1f734aef851f07c9,cache=none,iothread=1,backup=0
16.1. Production Btrfs
| Label | MAIN-DATA |
|---|---|
| UUID | 98e5188a-407c-4d4a-adc1-24d8c90afb32 |
| Размер | 5.46 TiB |
| Data | single |
| Metadata/System | DUP |
| Mount | /srv/main-data |
UUID=98e5188a-407c-4d4a-adc1-24d8c90afb32 /srv/main-data btrfs defaults,nofail,x-systemd.device-timeout=10s 0 0
17. Логическая структура MAIN-DATA
/srv/main-data
└── baltikashare
├── clonezilla
├── exchange
├── pivoproduction
├── rozliv
├── utilities
├── software
├── documentation
└── ot-admin
| Ресурс | Назначение |
|---|---|
clonezilla |
образы рабочих станций и технологических ПК |
exchange |
общий обмен инженеров |
pivoproduction |
рабочие данные пивопроизводства |
rozliv |
рабочие данные розлива |
utilities |
инженерные и энергетические системы |
software |
дистрибутивы, драйверы, firmware, утилиты |
documentation |
инструкции, схемы, ТЗ и паспорта |
ot-admin |
административные OT-материалы |
18. Snapper
Для каждого из 8 функциональных Btrfs subvolume создана отдельная Snapper-конфигурация: clonezilla, exchange, pivoproduction, rozliv, utilities, software, documentation, ot-admin.
BACKGROUND_COMPARISON=no
TIMELINE_CREATE=yes
TIMELINE_CLEANUP=yes
TIMELINE_MIN_AGE=1800
| Ресурс | Hourly | Daily | Weekly | Monthly | Yearly |
|---|---|---|---|---|---|
| clonezilla | 24 | 30 | 12 | 12 | 1 |
| exchange | 24 | 7 | 2 | 0 | 0 |
| pivoproduction | 72 | 30 | 12 | 12 | 0 |
| rozliv | 72 | 30 | 12 | 12 | 0 |
| utilities | 72 | 30 | 12 | 12 | 0 |
| software | 0 | 14 | 8 | 6 | 0 |
| documentation | 72 | 60 | 26 | 24 | 3 |
| ot-admin | 72 | 90 | 26 | 24 | 5 |
systemctl is-active snapper-timeline.timer snapper-cleanup.timer
Оба таймера подтверждены как active.
19. Модель доступа: группы и POSIX ACL
19.1. Группы
| Группа | Назначение |
|---|---|
admins |
полный доступ ко всем ресурсам |
engineers |
exchange RW; software/documentation RO |
clonezilla-rw |
RW clonezilla |
pivoproduction-rw |
RW pivoproduction |
rozliv-rw |
RW rozliv |
utilities-rw |
RW utilities |
software-rw |
RW software |
documentation-rw |
RW documentation |
shared-ro |
RO exchange, software, documentation |
pivoproduction-ro |
RO pivoproduction |
rozliv-ro |
RO rozliv |
utilities-ro |
RO utilities |
Создание RO-групп:
sudo groupadd shared-ro
sudo groupadd pivoproduction-ro
sudo groupadd rozliv-ro
sudo groupadd utilities-ro
getent group shared-ro
getent group pivoproduction-ro
getent group rozliv-ro
getent group utilities-ro
19.2. Матрица доступа
| Ресурс | admins | engineers | Профильная RW-группа | Профильная RO-группа | shared-ro |
|---|---|---|---|---|---|
| clonezilla | RW | DENY | clonezilla-rw → RW | — | DENY |
| exchange | RW | RW | — | — | RO |
| pivoproduction | RW | DENY | pivoproduction-rw → RW | pivoproduction-ro → RO | DENY |
| rozliv | RW | DENY | rozliv-rw → RW | rozliv-ro → RO | DENY |
| utilities | RW | DENY | utilities-rw → RW | utilities-ro → RO | DENY |
| software | RW | RO | software-rw → RW | — | RO |
| documentation | RW | RO | documentation-rw → RW | — | RO |
| ot-admin | RW | DENY | только admins | — | DENY |
Для производственных учётных записей с правом записи используется составная RW-модель: пользователь одновременно входит в engineers и свою профильную группу *-rw.
| Тип учётной записи | Группы | Итоговые права |
|---|---|---|
| Пивопроизводство — RW | engineers + pivoproduction-rw |
pivoproduction RW; exchange RW; software RO; documentation RO |
| Розлив — RW | engineers + rozliv-rw |
rozliv RW; exchange RW; software RO; documentation RO |
| Утилиты — RW | engineers + utilities-rw |
utilities RW; exchange RW; software RO; documentation RO |
Для пользователей только для чтения используется отдельная составная RO-модель: shared-ro + одна профильная группа *-ro.
| Тип учётной записи | Группы | Итоговые права |
|---|---|---|
| Пивопроизводство — RO | shared-ro + pivoproduction-ro |
pivoproduction RO; exchange RO; software RO; documentation RO; остальные профильные shares DENY |
| Розлив — RO | shared-ro + rozliv-ro |
rozliv RO; exchange RO; software RO; documentation RO; остальные профильные shares DENY |
| Утилиты — RO | shared-ro + utilities-ro |
utilities RO; exchange RO; software RO; documentation RO; остальные профильные shares DENY |
Важно: RO-пользователей нельзя добавлять в
engineers, профильные*-rwилиadmins, иначе они могут получить права записи. Доступ кclonezillaиot-adminдля RO-модели не предоставляется.
19.3. Универсальные учётные записи
| Учётная запись | Группы доступа |
|---|---|
baltikashare |
admins |
engineer |
engineers |
clonezilla |
clonezilla-rw |
pivo |
engineers + pivoproduction-rw |
rozliv |
engineers + rozliv-rw |
utilities |
engineers + utilities-rw |
software |
software-rw |
documents |
documentation-rw |
Актуализация существующих производственных учётных записей:
sudo usermod -aG engineers pivo
sudo usermod -aG engineers rozliv
sudo usermod -aG engineers utilities
id pivo
id rozliv
id utilities
getent group engineers
После изменения групп на Windows-клиенте необходимо завершить старую SMB-сессию. Для этого используется проверенный change_share.bat из раздела 20.15, после чего выполняется новое подключение к SHARE.
19.3.1. Персонифицированные учётные записи
Помимо универсальных технологических учётных записей допускается создавать персонифицированные Samba-учётные записи для конкретных сотрудников. В документации реальные логины не фиксируются; ниже используются условные user1 и user2.
Права персональной учётной записи формируются теми же Linux-группами, что и права универсальной учётки соответствующего подразделения. Например, для прав Розлива:
engineers
rozliv-rw
Создание двух новых персональных учётных записей с правами Розлива:
sudo useradd -M -U -s /usr/sbin/nologin -G engineers,rozliv-rw user1
sudo useradd -M -U -s /usr/sbin/nologin -G engineers,rozliv-rw user2
id user1
id user2
sudo smbpasswd -a user1
sudo smbpasswd -a user2
sudo pdbedit -L | grep -E 'user1|user2'
Итоговые права для такого пользователя:
| Share | Доступ |
|---|---|
rozliv |
RW |
exchange |
RW |
software |
RO |
documentation |
RO |
pivoproduction |
DENY |
utilities |
DENY |
clonezilla |
DENY |
ot-admin |
DENY |
Для другого подразделения меняется только профильная группа: pivoproduction-rw для Пивопроизводства или utilities-rw для Утилит. Членство в engineers сохраняется, если пользователю требуются exchange RW и software/documentation RO.
Важно: Samba-пользователь должен существовать как локальный Linux-пользователь. Пароль Samba задаётся отдельно через
smbpasswd -a. Пароли в документации не хранятся.
19.3.2. Учётные записи только для чтения
Для производственных подразделений введены отдельные RO-роли. Пользователь состоит в shared-ro и в одной профильной *-ro группе. Такой пользователь может читать свой производственный каталог и общие ресурсы exchange, software, documentation, но не может создавать, изменять, переименовывать или удалять данные.
| Учётная запись | Группы | Назначение |
|---|---|---|
rozliv_read |
shared-ro + rozliv-ro |
RO Розлив + общие RO-ресурсы |
pivo_read |
shared-ro + pivoproduction-ro |
RO Пивопроизводство + общие RO-ресурсы |
utilities_read |
shared-ro + utilities-ro |
RO Утилиты + общие RO-ресурсы |
Пример создания пользователя Розлива только для чтения:
sudo useradd -M -U -s /usr/sbin/nologin -G shared-ro,rozliv-ro rozliv_read
id rozliv_read
sudo smbpasswd -a rozliv_read
sudo pdbedit -L | grep '^rozliv_read:'
Для Пивопроизводства:
sudo useradd -M -U -s /usr/sbin/nologin -G shared-ro,pivoproduction-ro pivo_read
sudo smbpasswd -a pivo_read
Для Утилит:
sudo useradd -M -U -s /usr/sbin/nologin -G shared-ro,utilities-ro utilities_read
sudo smbpasswd -a utilities_read
Пароли в документации не хранятся. После создания пользователя или изменения групп перед проверкой с Windows необходимо сбросить существующие SMB-сессии через change_share.bat.
19.4. POSIX ACL
Для профильного RW-ресурса используется следующая базовая модель:
user::rwx
group::rwx
group:admins:rwx
mask::rwx
other::---
default:user::rwx
default:group::rwx
default:group:admins:rwx
default:mask::rwx
default:other::---
Для software и documentation дополнительно задан RO для engineers:
group:engineers:r-x
default:group:engineers:r-x
19.4.1. POSIX ACL для read-only групп
Для RO-доступа используется r-X: чтение файлов и право прохода по каталогам без предоставления записи. Для новых объектов на каталогах задаётся такой же default ACL.
exchange → shared-ro = r-x
software → shared-ro = r-x
documentation → shared-ro = r-x
pivoproduction → pivoproduction-ro = r-x
rozliv → rozliv-ro = r-x
utilities → utilities-ro = r-x
Важно: не использовать простой
setfacl -Rпо корню share. В дереве находятся Snapper.snapshotsи Samba.recycle. Попытка менять ACL внутри read-only Btrfs snapshots приводит кOperation not supported, а распространение RO-группы на.recycleраскроет служебные корзины. Production-команды ниже намеренно исключают оба каталога.
19.4.2. Общая группа shared-ro
for dir in exchange software documentation
do
BASE="/srv/main-data/baltikashare/$dir"
sudo find "$BASE" -path "$BASE/.snapshots" -prune -o -path "$BASE/.recycle" -prune -o -exec setfacl -m g:shared-ro:r-X {} +
sudo find "$BASE" -path "$BASE/.snapshots" -prune -o -path "$BASE/.recycle" -prune -o -type d -exec setfacl -m d:g:shared-ro:r-X {} +
done
Проверка:
getfacl -p /srv/main-data/baltikashare/exchange
getfacl -p /srv/main-data/baltikashare/software
getfacl -p /srv/main-data/baltikashare/documentation
В корне каждого ресурса должны присутствовать:
group:shared-ro:r-x
default:group:shared-ro:r-x
19.4.3. Профильные RO-группы
Розлив:
BASE="/srv/main-data/baltikashare/rozliv"
sudo find "$BASE" -path "$BASE/.snapshots" -prune -o -path "$BASE/.recycle" -prune -o -exec setfacl -m g:rozliv-ro:r-X {} +
sudo find "$BASE" -path "$BASE/.snapshots" -prune -o -path "$BASE/.recycle" -prune -o -type d -exec setfacl -m d:g:rozliv-ro:r-X {} +
Пивопроизводство:
BASE="/srv/main-data/baltikashare/pivoproduction"
sudo find "$BASE" -path "$BASE/.snapshots" -prune -o -path "$BASE/.recycle" -prune -o -exec setfacl -m g:pivoproduction-ro:r-X {} +
sudo find "$BASE" -path "$BASE/.snapshots" -prune -o -path "$BASE/.recycle" -prune -o -type d -exec setfacl -m d:g:pivoproduction-ro:r-X {} +
Утилиты:
BASE="/srv/main-data/baltikashare/utilities"
sudo find "$BASE" -path "$BASE/.snapshots" -prune -o -path "$BASE/.recycle" -prune -o -exec setfacl -m g:utilities-ro:r-X {} +
sudo find "$BASE" -path "$BASE/.snapshots" -prune -o -path "$BASE/.recycle" -prune -o -type d -exec setfacl -m d:g:utilities-ro:r-X {} +
Контроль корней:
getfacl -p /srv/main-data/baltikashare/rozliv
getfacl -p /srv/main-data/baltikashare/pivoproduction
getfacl -p /srv/main-data/baltikashare/utilities
Контроль отсутствия RO-групп в корзинах:
getfacl -p /srv/main-data/baltikashare/rozliv/.recycle | grep rozliv-ro
getfacl -p /srv/main-data/baltikashare/pivoproduction/.recycle | grep pivoproduction-ro
getfacl -p /srv/main-data/baltikashare/utilities/.recycle | grep utilities-ro
Правильный результат последних трёх команд — пустой вывод.
19.4.4. Очистка ошибочно добавленного shared-ro из .recycle
Если ранее был выполнен рекурсивный setfacl -R и shared-ro попал в служебные корзины, удалить только эту ACL-запись:
for dir in exchange software documentation
do
REC="/srv/main-data/baltikashare/$dir/.recycle"
if [ -d "$REC" ]; then
sudo find "$REC" \( -type d -o -type f \) -exec setfacl -n -x g:shared-ro {} +
fi
done
Ключ -n запрещает автоматический пересчёт ACL mask; остальные настроенные права корзины не изменяются.
20. Samba — production-конфигурация
20.1. Состояние
| Версия Samba | 4.19.5-Ubuntu |
|---|---|
| Роль | standalone server |
| NetBIOS name | SMR-OT-SHARE |
| Security | user |
| Минимальный протокол | SMB2_02; SMB1 отключён |
| Конфигурация | /etc/samba/smb.conf |
| Сервис | smbd.service — active |
Проверка конфигурации:
sudo testparm
sudo systemctl restart smbd
sudo systemctl is-active smbd
sudo smbstatus
20.2. Опубликованные shares
\\SMR-OT-SHARE\exchange
\\SMR-OT-SHARE\clonezilla
\\SMR-OT-SHARE\pivoproduction
\\SMR-OT-SHARE\rozliv
\\SMR-OT-SHARE\utilities
\\SMR-OT-SHARE\software
\\SMR-OT-SHARE\documentation
\\SMR-OT-SHARE\ot-admin
20.3. Исправление ACL-маски при создании файлов через SMB
Первоначальная комбинация inherit acls = yes + inherit permissions = yes привела к тому, что новый файл через SMB получил эффективную маску mask::r--. Именованная ACL для admins присутствовала, но фактическая запись была запрещена.
-rwxr-----+
user::rwx
group::rwx #effective:r--
group:admins:rwx #effective:r--
mask::r--
other::---
Production-схема изменена: default ACL наследуются Linux/Btrfs, а Samba создаёт файлы и каталоги с фиксированной базовой маской:
create mask = 0660
force create mode = 0660
directory mask = 0770
force directory mode = 0770
inherit acls = no
inherit permissions = no
После исправления новый файл через SMB:
-rw-rw----+
user::rw-
group::rwx #effective:rw-
group:admins:rwx #effective:rw-
mask::rw-
other::---
Контрольная запись от пользователя baltikashare через ACL группы admins выполнена успешно.
20.4. DOS/Windows attributes
Чтобы DOS Archive/Hidden/System не превращались в UNIX execute-биты, Windows-атрибуты хранятся в xattr:
store dos attributes = yes
map archive = no
map hidden = no
map system = no
20.5. Актуальный smb.conf
# ============================================================
# Samba configuration
# Server: SMR-SRV-OT-SHARE
# Role: standalone OT file server
# Data root: /srv/main-data/baltikashare
# ============================================================
[global]
# Рабочая группа Windows.
# Используется для standalone Samba без Active Directory.
workgroup = WORKGROUP
# Сервер работает автономно и не является контроллером домена.
server role = standalone server
# Аутентификация пользователей по логину и паролю.
security = user
# Локальная база Samba-пользователей.
# В неё пользователи добавляются командой smbpasswd -a.
passdb backend = tdbsam
# Короткое NetBIOS-имя Samba-сервера.
# Ограничение NetBIOS — максимум 15 символов.
# Linux hostname при этом остаётся smr-srv-ot-share.
netbios name = SMR-OT-SHARE
# Описание сервера, которое могут видеть SMB-клиенты.
server string = SMR OT File Server
# Никогда не преобразовывать неизвестного пользователя в guest.
map to guest = never
# Запрещаем usershare и guest usershare.
usershare max shares = 0
usershare allow guests = no
# Samba не используется как print server.
load printers = no
disable spoolss = yes
printcap name = /dev/null
# Минимально разрешённая версия SMB — SMB2.
# SMB1/CIFS не разрешаем.
server min protocol = SMB2_02
# Логирование.
log file = /var/log/samba/log.%m
logging = file
max log size = 1000
# PAM.
obey pam restrictions = yes
unix password sync = no
pam password change = no
# =========================================================
# Права создаваемых файлов и каталогов
# =========================================================
# Обычные файлы:
# владелец = RW, группа = RW, остальные = NO ACCESS.
create mask = 0660
force create mode = 0660
# Каталоги:
# владелец = RWX, группа = RWX, остальные = NO ACCESS.
directory mask = 0770
force directory mode = 0770
# Специальное наследование Samba не используем.
# Default POSIX ACL наследуются файловой системой Linux.
#
# inherit permissions = yes переопределяет create/directory mask
# и в данной схеме использоваться не должен.
inherit acls = no
inherit permissions = no
# =========================================================
# DOS / Windows attributes
# =========================================================
# DOS/Windows-атрибуты храним в extended attributes,
# а не кодируем UNIX execute-битами.
store dos attributes = yes
map archive = no
map hidden = no
map system = no
# ============================================================
# EXCHANGE
# admins = RW
# engineers = RW
# shared-ro = RO
# ============================================================
[exchange]
path = /srv/main-data/baltikashare/exchange
browseable = yes
guest ok = no
read only = no
valid users = @admins @engineers @shared-ro
# shared-ro принудительно работает только на чтение.
read list = @shared-ro
# =========================================================
# Служебные каталоги
# =========================================================
# Каталог Snapper полностью скрываем от обычного SMB-доступа.
# Пользователь работает со snapshots через Windows
# «Свойства» -> «Предыдущие версии».
veto files = /.snapshots/
# Сетевую корзину скрываем из обычного списка файлов,
# но оставляем доступной по прямому SMB-пути.
hide files = /.recycle/
# Snapper = Windows Previous Versions.
# Recycle = сетевая корзина Samba.
vfs objects = snapper recycle
# Для каждого SMB-пользователя создаётся отдельная корзина.
recycle:repository = .recycle/%U
recycle:keeptree = yes
recycle:versions = yes
recycle:touch_mtime = yes
recycle:directory_mode = 0770
recycle:subdir_mode = 0770
recycle:exclude_dir = .recycle
# ============================================================
# CLONEZILLA
# admins = RW
# clonezilla-rw = RW
# ============================================================
[clonezilla]
path = /srv/main-data/baltikashare/clonezilla
browseable = yes
guest ok = no
read only = no
valid users = @admins @clonezilla-rw
# =========================================================
# Служебные каталоги
# =========================================================
# Каталог Snapper полностью скрываем от обычного SMB-доступа.
# Previous Versions продолжает работать через vfs_snapper.
veto files = /.snapshots/
# Только Snapper.
# vfs_recycle намеренно не включён: большие образы могут
# одновременно удерживаться корзиной и Btrfs snapshots.
vfs objects = snapper
# ============================================================
# PIVOPRODUCTION
# admins = RW
# pivoproduction-rw = RW
# pivoproduction-ro = RO
# ============================================================
[pivoproduction]
path = /srv/main-data/baltikashare/pivoproduction
browseable = yes
guest ok = no
read only = no
valid users = @admins @pivoproduction-rw @pivoproduction-ro
read list = @pivoproduction-ro
# Служебные каталоги.
veto files = /.snapshots/
hide files = /.recycle/
vfs objects = snapper recycle
recycle:repository = .recycle/%U
recycle:keeptree = yes
recycle:versions = yes
recycle:touch_mtime = yes
recycle:directory_mode = 0770
recycle:subdir_mode = 0770
recycle:exclude_dir = .recycle
# ============================================================
# ROZLIV
# admins = RW
# rozliv-rw = RW
# rozliv-ro = RO
# ============================================================
[rozliv]
path = /srv/main-data/baltikashare/rozliv
browseable = yes
guest ok = no
read only = no
valid users = @admins @rozliv-rw @rozliv-ro
read list = @rozliv-ro
# Служебные каталоги.
veto files = /.snapshots/
hide files = /.recycle/
vfs objects = snapper recycle
recycle:repository = .recycle/%U
recycle:keeptree = yes
recycle:versions = yes
recycle:touch_mtime = yes
recycle:directory_mode = 0770
recycle:subdir_mode = 0770
recycle:exclude_dir = .recycle
# ============================================================
# UTILITIES
# admins = RW
# utilities-rw = RW
# utilities-ro = RO
# ============================================================
[utilities]
path = /srv/main-data/baltikashare/utilities
browseable = yes
guest ok = no
read only = no
valid users = @admins @utilities-rw @utilities-ro
read list = @utilities-ro
# Служебные каталоги.
veto files = /.snapshots/
hide files = /.recycle/
vfs objects = snapper recycle
recycle:repository = .recycle/%U
recycle:keeptree = yes
recycle:versions = yes
recycle:touch_mtime = yes
recycle:directory_mode = 0770
recycle:subdir_mode = 0770
recycle:exclude_dir = .recycle
# ============================================================
# SOFTWARE
# admins = RW
# software-rw = RW
# engineers = RO
# shared-ro = RO
# ============================================================
[software]
path = /srv/main-data/baltikashare/software
browseable = yes
guest ok = no
# По умолчанию только чтение.
read only = yes
valid users = @admins @engineers @software-rw @shared-ro
# Запись только для admins и software-rw.
# shared-ro намеренно отсутствует в write list.
write list = @admins @software-rw
# Служебные каталоги.
veto files = /.snapshots/
hide files = /.recycle/
vfs objects = snapper recycle
recycle:repository = .recycle/%U
recycle:keeptree = yes
recycle:versions = yes
recycle:touch_mtime = yes
recycle:directory_mode = 0770
recycle:subdir_mode = 0770
recycle:exclude_dir = .recycle
# ============================================================
# DOCUMENTATION
# admins = RW
# documentation-rw = RW
# engineers = RO
# shared-ro = RO
# ============================================================
[documentation]
path = /srv/main-data/baltikashare/documentation
browseable = yes
guest ok = no
# По умолчанию только чтение.
read only = yes
valid users = @admins @engineers @documentation-rw @shared-ro
# Запись только для admins и documentation-rw.
# shared-ro намеренно отсутствует в write list.
write list = @admins @documentation-rw
# Служебные каталоги.
veto files = /.snapshots/
hide files = /.recycle/
vfs objects = snapper recycle
recycle:repository = .recycle/%U
recycle:keeptree = yes
recycle:versions = yes
recycle:touch_mtime = yes
recycle:directory_mode = 0770
recycle:subdir_mode = 0770
recycle:exclude_dir = .recycle
# ============================================================
# OT-ADMIN
# admins = RW
# Все остальные = NO ACCESS
# ============================================================
[ot-admin]
path = /srv/main-data/baltikashare/ot-admin
browseable = yes
guest ok = no
read only = no
valid users = @admins
# Служебные каталоги.
veto files = /.snapshots/
hide files = /.recycle/
vfs objects = snapper recycle
recycle:repository = .recycle/%U
recycle:keeptree = yes
recycle:versions = yes
recycle:touch_mtime = yes
recycle:directory_mode = 0770
recycle:subdir_mode = 0770
recycle:exclude_dir = .recycle
20.6. Проверка матрицы доступа через smbclient
Пользователь engineer проверен фактическими SMB-операциями:
| Share | Ожидаемо | Факт |
|---|---|---|
| exchange | RW | OK: put/del |
| software | RO | OK: ls; put → ACCESS_DENIED |
| documentation | RO | OK: ls; put → ACCESS_DENIED |
| clonezilla | DENY | ACCESS_DENIED |
| pivoproduction | DENY | ACCESS_DENIED |
| rozliv | DENY | ACCESS_DENIED |
| utilities | DENY | ACCESS_DENIED |
| ot-admin | DENY | ACCESS_DENIED |
Изначально производственные универсальные учётные записи входили только в свои профильные *-rw группы. В результате, например, пользователь rozliv имел RW к rozliv, но не мог открыть exchange, software и documentation.
После добавления pivo, rozliv и utilities в группу engineers применяется следующая целевая модель:
| Тип пользователя | Свой профильный share | exchange | software | documentation | Чужие профильные shares / ot-admin |
|---|---|---|---|---|---|
| Пивопроизводство | RW | RW | RO | RO | DENY |
| Розлив | RW | RW | RO | RO | DENY |
| Утилиты | RW | RW | RO | RO | DENY |
На Windows-клиенте модель проверена для пользователя Розлива после сброса старой SMB-сессии через change_share.bat: профильный ресурс доступен на чтение и запись, exchange — на чтение и запись, software/documentation — только на чтение. Для Пивопроизводства и Утилит права формируются тем же сочетанием engineers + профильная *-rw.
Специализированные учётные записи остаются без членства в engineers:
| Учётка | Share | Результат |
|---|---|---|
| clonezilla | clonezilla | RW |
| software | software | RW |
| documents | documentation | RW |
Администратор baltikashare имеет полный доступ ко всем восьми shares, включая software и documentation, где запись разрешена через write list.
20.6.1. Проверка read-only модели
После создания RO-групп и применения POSIX ACL конфигурация Samba проверена через testparm -s. В конфигурации подтверждены read list/valid users для профильных RO-групп и отсутствие shared-ro в write list ресурсов software и documentation.
После изменения /etc/samba/smb.conf выполнен sudo systemctl reload smbd. Сервис остался в состоянии active (running); reload завершён status=0/SUCCESS.
Для rozliv_read выполнена локальная проверка Linux/POSIX ACL:
| Share | READ | WRITE |
|---|---|---|
rozliv |
OK | DENY |
exchange |
OK | DENY |
software |
OK | DENY |
documentation |
OK | DENY |
pivoproduction |
DENY | DENY |
utilities |
DENY | DENY |
clonezilla |
DENY | DENY |
ot-admin |
DENY | DENY |
Учётные записи pivo_read и utilities_read созданы с группами shared-ro + pivoproduction-ro и shared-ro + utilities-ro соответственно. Окончательную проверку RO-ролей через Windows SMB выполнить после сброса старых сессий с помощью change_share.bat.
Шаблон локальной проверки:
sudo -u rozliv_read bash -c '
for dir in rozliv exchange software documentation pivoproduction utilities clonezilla ot-admin
do
echo "===== $dir ====="
test -r "/srv/main-data/baltikashare/$dir" && echo "READ : OK" || echo "READ : DENY"
test -w "/srv/main-data/baltikashare/$dir" && echo "WRITE : OK" || echo "WRITE : DENY"
done
'
20.7. Samba recycle
vfs_recycle включён на: exchange, pivoproduction, rozliv, utilities, software, documentation, ot-admin.
Для clonezilla recycle намеренно отключён: крупные образы могут одновременно удерживаться корзиной и Btrfs snapshots, что создаёт риск чрезмерного расхода MAIN-DATA. Clonezilla защищается Snapper; критичные образы дополнительно должны копироваться на CRITICAL-BACKUP.
20.7.1. Структура корзины
.recycle/%U
Пример для Pivoproduction:
/srv/main-data/baltikashare/pivoproduction/.recycle/pivo/recycle-test-dir/recycle-test.txt
Проверенный файл в корзине сохранил корректные ACL:
-rw-rw----+ pivo pivoproduction-rw
user::rw-
group::rwx #effective:rw-
group:admins:rwx #effective:rw-
mask::rw-
other::---
20.7.1.1. Production ACL для корзин
Изначально recycle:directory_mode = 0700 и recycle:subdir_mode = 0700 приводили к созданию каталогов с ACL group:admins:rwx, но с mask::---. В результате группа admins фактически не имела доступа, и сервисный пользователь filebrowser не мог открыть большинство каталогов .recycle.
recycle:directory_mode = 0770
recycle:subdir_mode = 0770
Корень .recycle имеет следующую модель:
user::rwx
group::rwx
group:admins:rwx
mask::rwx
other::---
default:user::rwx
default:group::---
default:group:admins:rwx
default:mask::rwx
default:other::---
На корне .recycle установлен sticky bit. Типовой режим отображается как drwxrws--T+. Основная группа ресурса может войти в корень и создать свой .recycle/%U, но sticky bit не позволяет пользователю удалить чужой каталог верхнего уровня.
Персональный каталог .recycle/<user> имеет более строгую модель:
user::rwx
group::---
group:admins:rwx
mask::rwx
other::---
default:user::rwx
default:group::---
default:group:admins:rwx
default:mask::rwx
default:other::---
Таким образом, владелец видит собственную корзину, группа admins получает полный административный доступ, а остальные участники профильной группы ресурса не получают доступ к содержимому чужой корзины. Для software и documentation ACL engineers внутри .recycle удалены, чтобы RO-доступ к рабочим данным не распространялся на удалённые файлы.
Для ot-admin отдельная именованная запись group:admins не требуется, поскольку admins является основной группой каталога.
Схема проверена не только на существующих каталогах: .recycle/pivo был полностью удалён, после чего Samba повторно создала его при удалении файла. Новый каталог автоматически получил правильные default ACL, а filebrowser сохранил доступ к содержимому.
20.7.2. Сохранение структуры
recycle:keeptree = yes проверен удалением файла из вложенного каталога: исходная структура каталога появилась внутри персональной корзины.
20.7.3. Несколько версий
recycle:versions = yes проверен двойным удалением файла с одинаковым именем. В корзине появились:
version-test.txt
Copy #1 of version-test.txt
20.7.4. Удаление из самой корзины
recycle:exclude_dir = .recycle проверен удалением файла непосредственно из .recycle через SMB. Файл исчез окончательно и не был повторно перемещён во вложенную корзину.
20.7.5. Скрытие служебных каталогов
veto files = /.snapshots/
hide files = /.recycle/
veto files делает .snapshots недоступным по обычному SMB-пути, но не мешает vfs_snapper публиковать snapshots через Windows «Предыдущие версии». hide files присваивает .recycle атрибут Hidden; при необходимости корзину можно открыть напрямую, например \\SMR-OT-SHARE\exchange\.recycle.
На clonezilla используется только veto files = /.snapshots/, так как vfs_recycle для этого ресурса отключён.
20.8. Snapper и Windows «Предыдущие версии»
Цепочка Btrfs snapshot → Snapper → vfs_snapper → Samba → Windows Previous Versions проверена на реальном Windows-клиенте.
20.8.1. Контрольный тест
Для exchange были созданы две ручные точки Snapper с разными версиями одного файла, после чего текущая версия файла была изменена ещё раз. Windows отобразил обе сохранённые версии в свойствах файла и позволил восстановить более раннюю версию. После восстановления содержимое файла фактически вернулось к исходному варианту.
Отдельный тест выполнен на documentation: snapshot появился в «Свойства → Предыдущие версии», его содержимое успешно открывалось из Windows. Это подтвердило работу настройки не только на exchange, но и после её распространения на остальные shares.
20.8.2. Проверка автоматических timeline snapshots
Snapper создаёт timeline snapshots ежечасно. Контрольный вывод для exchange 28.10.2026 показывал последовательные snapshots с 05:00 до 14:00. Если Windows Explorer не сразу показывает последние точки, достаточно повторно открыть каталог или окно свойств: серверные snapshots при этом продолжают создаваться корректно.
20.9. Автоматическая очистка Samba recycle
Так как одновременно используется Snapper, корзина Samba предназначена для быстрого возврата случайно удалённых файлов и не должна хранить данные месяцами без ограничения. Для каждого ресурса задан отдельный срок хранения.
| Ресурс | Срок хранения .recycle |
|---|---|
exchange |
7 дней |
pivoproduction |
14 дней |
rozliv |
14 дней |
utilities |
14 дней |
software |
14 дней |
documentation |
30 дней |
ot-admin |
30 дней |
clonezilla |
recycle отключён |
В smb.conf используется recycle:touch_mtime = yes, поэтому при перемещении файла в корзину обновляется его mtime, и очистка может ориентироваться на время удаления через Samba.
20.9.1. Скрипт /usr/local/sbin/samba-recycle-cleanup
#!/usr/bin/env bash
# ============================================================
# Samba recycle cleanup
# Server: SMR-SRV-OT-SHARE
#
# Автоматическая очистка файлов из Samba .recycle
# по времени их нахождения в корзине.
#
# Режимы:
# --dry-run только показать, что было бы удалено
# --delete реально удалить просроченные файлы
# ============================================================
set -u
set -o pipefail
BASE="/srv/main-data/baltikashare"
MODE="${1:---dry-run}"
case "$MODE" in
--dry-run)
DELETE=false
;;
--delete)
DELETE=true
;;
*)
echo "Usage: $0 [--dry-run|--delete]"
exit 2
;;
esac
# Не допускаем работу по каталогу на root FS,
# если production MAIN-DATA не смонтирован.
if ! mountpoint -q /srv/main-data; then
echo "ERROR: /srv/main-data is not mounted."
echo "Cleanup aborted."
exit 1
fi
FS_TYPE="$(findmnt -n -o FSTYPE /srv/main-data 2>/dev/null || true)"
if [[ "$FS_TYPE" != "btrfs" ]]; then
echo "ERROR: /srv/main-data filesystem is '$FS_TYPE', expected 'btrfs'."
echo "Cleanup aborted."
exit 1
fi
POLICY=(
"exchange:7"
"pivoproduction:14"
"rozliv:14"
"utilities:14"
"software:14"
"documentation:30"
"ot-admin:30"
)
echo "============================================================"
echo "Samba recycle cleanup"
echo "Date: $(date '+%Y-%m-%d %H:%M:%S %z')"
echo "Mode: $MODE"
echo "============================================================"
TOTAL_FILES=0
TOTAL_BYTES=0
for ITEM in "${POLICY[@]}"; do
SHARE="${ITEM%%:*}"
DAYS="${ITEM##*:}"
RECYCLE="${BASE}/${SHARE}/.recycle"
echo
echo "------------------------------------------------------------"
echo "Share: $SHARE"
echo "Recycle: $RECYCLE"
echo "Retention: $DAYS days"
echo "------------------------------------------------------------"
if [[ ! -d "$RECYCLE" ]]; then
echo "INFO: recycle directory does not exist, skipping."
continue
fi
AGE_MINUTES=$((DAYS * 24 * 60))
while IFS= read -r -d '' FILE; do
SIZE="$(stat -c '%s' "$FILE" 2>/dev/null || echo 0)"
TOTAL_FILES=$((TOTAL_FILES + 1))
TOTAL_BYTES=$((TOTAL_BYTES + SIZE))
if [[ "$DELETE" == true ]]; then
echo "DELETE: $FILE"
rm -f -- "$FILE"
else
echo "WOULD DELETE: $FILE"
fi
done < <(
find "$RECYCLE" \
-xdev \
-type f \
-mmin "+${AGE_MINUTES}" \
-print0
)
if [[ "$DELETE" == true ]]; then
find "$RECYCLE" \
-xdev \
-depth \
-mindepth 1 \
-type d \
-empty \
-delete
fi
done
echo
echo "============================================================"
echo "Summary"
echo "============================================================"
echo "Matched files: $TOTAL_FILES"
echo "Matched bytes: $TOTAL_BYTES"
if command -v numfmt >/dev/null 2>&1; then
echo "Matched size: $(numfmt --to=iec-i --suffix=B "$TOTAL_BYTES")"
fi
if [[ "$DELETE" == true ]]; then
echo "Result: expired files deleted."
else
echo "Result: DRY-RUN only. Nothing was deleted."
fi
echo "Finished: $(date '+%Y-%m-%d %H:%M:%S %z')"
Права и контроль синтаксиса:
sudo chmod 0755 /usr/local/sbin/samba-recycle-cleanup
sudo bash -n /usr/local/sbin/samba-recycle-cleanup
20.9.2. Проверка dry-run и удаления
Сначала скрипт был запущен с --dry-run: при отсутствии просроченных файлов он вернул Matched files: 0. Затем в корзине exchange был создан искусственно состаренный на 8 дней файл. Dry-run обнаружил его как WOULD DELETE, но не удалил. Запуск с --delete удалил только этот файл и вернул успешный результат.
20.9.3. systemd service
/etc/systemd/system/samba-recycle-cleanup.service:
[Unit]
Description=Cleanup expired Samba recycle files
Documentation=man:find(1)
RequiresMountsFor=/srv/main-data
[Service]
Type=oneshot
ExecStart=/usr/local/sbin/samba-recycle-cleanup --delete
PrivateTmp=yes
NoNewPrivileges=yes
StandardOutput=journal
StandardError=journal
20.9.4. systemd timer
/etc/systemd/system/samba-recycle-cleanup.timer:
[Unit]
Description=Daily Samba recycle cleanup
[Timer]
OnCalendar=*-*-* 03:30:00
Persistent=true
RandomizedDelaySec=10m
Unit=samba-recycle-cleanup.service
[Install]
WantedBy=timers.target
Активация:
sudo systemctl daemon-reload
sudo systemctl enable --now samba-recycle-cleanup.timer
systemctl status samba-recycle-cleanup.timer --no-pager
systemctl list-timers samba-recycle-cleanup.timer --all
sudo journalctl \
-u samba-recycle-cleanup.service \
-n 100 \
--no-pager
Контрольный статус: timer active (waiting). После включения 28.10.2026 следующий запуск был назначен на 29.10.2026 03:36:04 +04, что соответствует 03:30 плюс RandomizedDelaySec=10m.
20.10. Защита smbd от запуска без MAIN-DATA
Если D2700 или MAIN-DATA недоступны, каталог /srv/main-data всё равно может существовать на системном root filesystem. Без дополнительной защиты Samba могла бы запуститься и начать принимать данные в этот обычный каталог, заполняя системный диск.
Для smbd.service создан systemd drop-in: /etc/systemd/system/smbd.service.d/main-data.conf.
# ============================================================
# SMR-SRV-OT-SHARE
# Защита Samba от запуска без MAIN-DATA
#
# Не позволять smbd стартовать, если production-хранилище
# /srv/main-data не смонтировано.
# ============================================================
[Unit]
# systemd должен поднять все mount units, необходимые
# для доступа к /srv/main-data, до запуска smbd.
RequiresMountsFor=/srv/main-data
[Service]
# /srv/main-data должен быть именно mountpoint.
# Если MAIN-DATA не смонтирован, ExecStartPre завершится
# неуспешно и smbd не запустится.
ExecStartPre=/usr/bin/mountpoint -q /srv/main-data
Применение и проверка:
sudo systemctl daemon-reload
sudo systemctl cat smbd
mountpoint /srv/main-data
findmnt /srv/main-data
sudo systemctl restart smbd
sudo systemctl status smbd --no-pager
Фактически подтверждено:
/srv/main-data is a mountpoint
TARGET SOURCE FSTYPE OPTIONS
/srv/main-data /dev/sdb1 btrfs rw,relatime,space_cache=v2,subvolid=5,subvol=/
ExecStartPre=/usr/bin/mountpoint -q /srv/main-data
(code=exited, status=0/SUCCESS)
Status: "smbd: ready to serve connections..."
Проверка UUID в ExecStartPre намеренно не добавлялась: для текущей схемы принято оставить защиту простой — systemd dependency плюс проверка факта монтирования.
20.11. NFS
NFS на текущем этапе не установлен и не публикуется. Решение отложено до появления реальной необходимости со стороны Clonezilla или другого клиента. При последующем внедрении необходимо отдельно определить разрешённые сети/клиенты, UID/GID-модель и root squashing.
20.12. Access Based Enumeration
Access Based Enumeration намеренно не включается. Недоступные SMB shares могут отображаться в списке ресурсов сервера, но попытка подключения к ним блокируется через valid users и файловые ACL. Для текущей эксплуатации такое поведение принято как штатное.
20.13. File Browser Next — административный web-доступ
Для административного web-доступа к MAIN-DATA установлен File Browser Next v3.0.0-next. Сервис предназначен для работы из management-сети и не заменяет SMB. Через web-интерфейс администратор видит все восемь функциональных каталогов, включая служебные .snapshots и .recycle.
Для web-интерфейса намеренно не включается скрытие dot-files: административная задача File Browser включает просмотр и обслуживание
.snapshotsи.recycle.
20.13.1. Версия и бинарный файл
File Browser Next v3.0.0-next
/usr/local/bin/filebrowser
Проверенная SHA-256 загруженного архива filebrowser-linux-amd64.tar.gz:
17a51c2b8fe2eaf88ca4f7a80bd2f2b2e7fe968961bbeb8569a86942696e08b0
20.13.2. Системная учётная запись
user: filebrowser
shell: /usr/sbin/nologin
supplementary group: admins
Сервис не запускается от root. Доступ к файловым ресурсам он получает через существующую POSIX ACL-модель и членство в admins.
id filebrowser
# uid=999(filebrowser) gid=987(filebrowser) groups=987(filebrowser),1001(admins)
20.13.3. Каталоги и база
/etc/filebrowser root:root 0755
/var/lib/filebrowser filebrowser:filebrowser 0750
/var/lib/filebrowser/filebrowser.db
Основные параметры хранятся в BoltDB. Отдельный конфигурационный файл на текущем этапе не используется.
20.13.4. Основные параметры File Browser
| Параметр | Значение |
|---|---|
| Root | /srv/main-data/baltikashare |
| Management address | 10.44.100.229 |
| TCP port | 28443 |
| Authentication | json |
| Locale | ru |
| File mode | 0660 |
| Directory mode | 0770 |
| Minimum password length | 12 |
| Execute | disabled |
| Share | disabled |
| External symlinks | disabled |
| Hide dotfiles | false |
Первичная проверка выполнялась на 127.0.0.1:28443. После локальной проверки сервис предназначен для bind только на management-адрес 10.44.100.229:28443, а не на 0.0.0.0.
20.13.5. Web-учётная запись
login: baltikafile
scope: /
admin: true
execute: false
share: false
Пароль в документации не хранится.
20.13.6. systemd unit
Файл: /etc/systemd/system/filebrowser.service
# ============================================================
# SMR-SRV-OT-SHARE
# File Browser Next
#
# Web-доступ к данным MAIN-DATA.
# Сервис работает от отдельной системной учётной записи
# filebrowser и получает права через группу admins / POSIX ACL.
# ============================================================
[Unit]
Description=File Browser Next
After=network.target
RequiresMountsFor=/srv/main-data
[Service]
Type=simple
User=filebrowser
Group=filebrowser
SupplementaryGroups=admins
WorkingDirectory=/var/lib/filebrowser
# Не допускаем запуск на пустом каталоге /srv/main-data,
# если production Btrfs по какой-либо причине не смонтирован.
ExecStartPre=/usr/bin/mountpoint -q /srv/main-data
ExecStart=/usr/local/bin/filebrowser \
-d /var/lib/filebrowser/filebrowser.db
Restart=on-failure
RestartSec=5s
NoNewPrivileges=yes
PrivateTmp=yes
[Install]
WantedBy=multi-user.target
Проверка:
sudo systemctl daemon-reload
sudo systemctl start filebrowser
sudo systemctl status filebrowser --no-pager
sudo ss -ltnp | grep ':28443'
curl -s -o /dev/null -w '%{http_code}\n' http://10.44.100.229:28443/
Ожидаемый HTTP-код: 200.
После окончательной проверки для включения автозапуска:
sudo systemctl enable filebrowser
systemctl is-enabled filebrowser
systemctl is-active filebrowser
20.13.7. Проверенные права
От имени Linux-пользователя filebrowser проверены чтение и запись в рабочий ресурс, доступ ко всем восьми верхнеуровневым каталогам и административный проход в .recycle. Для корзин итоговая проверка дала ACCESS OK на всех семи ресурсах, где используется vfs_recycle.
Удаление файлов через File Browser выполняется непосредственно на файловой системе и не проходит через Samba vfs_recycle. Основной механизм защиты от ошибочных административных изменений в этом случае — Btrfs/Snapper snapshots.
20.13.8. Ограничение management-сети
Management-интерфейс VM: ens19 = 10.44.100.229/24, gateway 10.44.100.1. Целевая модель — публиковать на этом интерфейсе только необходимые административные web-сервисы, в первую очередь File Browser на 28443/tcp. Ограничение firewall выполняется отдельным этапом после инвентаризации текущих слушающих портов, чтобы не потерять административный доступ.
20.14. DNS-имена и DDNS многосетевого файлового сервера
Центральная конфигурация BIND9 описана в отдельной статье «Установка DNS сервера BIND9 на Ubuntu Server 24.04 с Webmin в Proxmox». Здесь фиксируется только конфигурация самого SMR-SRV-OT-SHARE и правила его использования клиентами.
20.14.1. Модель имён
Один multi-homed сервер не публикуется одной A-записью со всеми интерфейсами. Каждый OT-интерфейс получает собственный сегментный FQDN:
| Сегмент | IP | FQDN |
|---|---|---|
| Legacy | 10.255.0.229 |
smr-srv-ot-share.legacy.ot-samara.baltika.ru |
| Пивопроизводство | 172.16.66.229 |
smr-srv-ot-share.pivo.ot-samara.baltika.ru |
| Розлив | 172.16.68.229 |
smr-srv-ot-share.rozliv.ot-samara.baltika.ru |
| Утилиты | 172.16.70.229 |
smr-srv-ot-share.utilities.ot-samara.baltika.ru |
| АСТУЭ | 172.17.14.229 |
smr-srv-ot-share.astue.ot-samara.baltika.ru |
PTR каждого адреса указывает на соответствующий сегментный FQDN.
20.14.2. Как клиенты используют короткое имя
Для обычного одноинтерфейсного Windows-клиента основной connection-specific suffix остаётся ot-samara.baltika.ru, а глобальный список поиска содержит два элемента:
| Сегмент клиента | 1-й suffix | 2-й suffix |
|---|---|---|
| Legacy | legacy.ot-samara.baltika.ru |
ot-samara.baltika.ru |
| Pivo | pivo.ot-samara.baltika.ru |
ot-samara.baltika.ru |
| Rozliv | rozliv.ot-samara.baltika.ru |
ot-samara.baltika.ru |
| Utilities | utilities.ot-samara.baltika.ru |
ot-samara.baltika.ru |
| АСТУЭ | astue.ot-samara.baltika.ru |
ot-samara.baltika.ru |
Например, клиент Розлива при обращении к \\SMR-SRV-OT-SHARE\exchange сначала проверит SMR-SRV-OT-SHARE.rozliv.ot-samara.baltika.ru и получит 172.16.68.229.
Не добавлять на обычный клиент suffix всех сегментов. Первым должен быть только suffix его локального сегмента, вторым — общая зона.
20.14.3. Установка DNS-утилит
sudo apt update
sudo apt install -y dnsutils
command -v nsupdate
command -v dig
20.14.4. Скрипт /usr/local/sbin/ot-ddns-register
sudo tee /usr/local/sbin/ot-ddns-register >/dev/null <<'SCRIPT_EOF'
#!/usr/bin/env bash
# ============================================================
# SMR-SRV-OT-SHARE
# Регистрация интерфейсных DNS-имён многосетевого сервера
# в авторитетном BIND9 через RFC 2136 / nsupdate.
# ============================================================
set -euo pipefail
TTL=3600
ZONE="ot-samara.baltika.ru."
register_dns()
{
local iface="$1"
local ip="$2"
local dns="$3"
local fqdn="$4"
local ptr="$5"
echo
echo "============================================================"
echo "Interface : $iface"
echo "IP : $ip"
echo "DNS : $dns"
echo "FQDN : $fqdn"
echo "============================================================"
if ! ip -4 addr show dev "$iface" | grep -qw "$ip"; then
echo "ERROR: IP $ip отсутствует на интерфейсе $iface"
return 1
fi
route_info="$(ip route get "$dns" | head -n1)"
echo "Route : $route_info"
if ! grep -qw "src $ip" <<< "$route_info"; then
echo "ERROR: запрос к $dns пойдёт не с source IP $ip"
return 1
fi
nsupdate <<EOF
server $dns
zone $ZONE
update delete $fqdn A
update add $fqdn $TTL A $ip
send
EOF
nsupdate <<EOF
server $dns
update delete $ptr PTR
update add $ptr $TTL PTR $fqdn
send
EOF
result_a="$(dig +short +norecurse @"$dns" "$fqdn" A | head -n1)"
if [[ "$result_a" != "$ip" ]]; then
echo "ERROR: A verification failed: '$result_a'"
return 1
fi
result_ptr="$(dig +short +norecurse @"$dns" -x "$ip" | head -n1)"
if [[ "$result_ptr" != "$fqdn" ]]; then
echo "ERROR: PTR verification failed: '$result_ptr'"
return 1
fi
echo "OK: A $fqdn -> $ip"
echo "OK: PTR $ip -> $fqdn"
}
# Legacy OT / VLAN 1.
register_dns \
"ens23" \
"10.255.0.229" \
"10.255.0.53" \
"smr-srv-ot-share.legacy.ot-samara.baltika.ru." \
"229.0.255.10.in-addr.arpa."
# Пивопроизводство. Пока 172.16.66.229 находится на ens23.
# После миграции VLAN2030 заменить ens23 на ens21.
register_dns \
"ens23" \
"172.16.66.229" \
"172.16.66.53" \
"smr-srv-ot-share.pivo.ot-samara.baltika.ru." \
"229.66.16.172.in-addr.arpa."
# Розлив / VLAN2002.
register_dns \
"ens20" \
"172.16.68.229" \
"172.16.68.53" \
"smr-srv-ot-share.rozliv.ot-samara.baltika.ru." \
"229.68.16.172.in-addr.arpa."
# Утилиты / VLAN2040.
register_dns \
"ens22" \
"172.16.70.229" \
"172.16.70.53" \
"smr-srv-ot-share.utilities.ot-samara.baltika.ru." \
"229.70.16.172.in-addr.arpa."
# АСТУЭ / VLAN2006.
register_dns \
"enp2s1" \
"172.17.14.229" \
"172.17.14.53" \
"smr-srv-ot-share.astue.ot-samara.baltika.ru." \
"229.14.17.172.in-addr.arpa."
echo
echo "============================================================"
echo "OT DDNS registration completed successfully."
echo "============================================================"
SCRIPT_EOF
sudo chown root:root /usr/local/sbin/ot-ddns-register
sudo chmod 0755 /usr/local/sbin/ot-ddns-register
Перед включением автозапуска скрипт проверяется вручную:
sudo /usr/local/sbin/ot-ddns-register
Успешный результат содержит по всем пяти интерфейсам строки OK: A и OK: PTR.
20.14.5. systemd unit
sudo tee /etc/systemd/system/ot-ddns-register.service >/dev/null <<'UNIT_EOF'
[Unit]
Description=Register SMR-SRV-OT-SHARE DNS records in OT BIND9
Wants=network-online.target
After=network-online.target
[Service]
Type=oneshot
ExecStart=/usr/local/sbin/ot-ddns-register
[Install]
WantedBy=multi-user.target
UNIT_EOF
sudo chown root:root /etc/systemd/system/ot-ddns-register.service
sudo chmod 0644 /etc/systemd/system/ot-ddns-register.service
sudo systemctl daemon-reload
sudo systemctl enable ot-ddns-register.service
sudo systemctl start ot-ddns-register.service
sudo systemctl status ot-ddns-register.service --no-pager
sudo journalctl -u ot-ddns-register.service -n 100 --no-pager
Для Type=oneshot состояние inactive (dead) после выполнения является нормальным. Критерий успеха: code=exited, status=0/SUCCESS и успешные проверки A/PTR.
20.14.6. Фактически зарегистрированные A/PTR
| FQDN | A | PTR |
|---|---|---|
smr-srv-ot-share.legacy.ot-samara.baltika.ru |
10.255.0.229 |
на это же FQDN |
smr-srv-ot-share.pivo.ot-samara.baltika.ru |
172.16.66.229 |
на это же FQDN |
smr-srv-ot-share.rozliv.ot-samara.baltika.ru |
172.16.68.229 |
на это же FQDN |
smr-srv-ot-share.utilities.ot-samara.baltika.ru |
172.16.70.229 |
на это же FQDN |
smr-srv-ot-share.astue.ot-samara.baltika.ru |
172.17.14.229 |
на это же FQDN |
PTR для сетей /23. У SHARE адреса Пивопроизводства, Розлива и Утилит находятся в первых половинах соответствующих /23:
172.16.66.229,172.16.68.229и172.16.70.229. Поэтому их PTR находятся соответственно только в reverse-зонах66.16.172.in-addr.arpa,68.16.172.in-addr.arpaи70.16.172.in-addr.arpa.Парные зоны
67.16.172.in-addr.arpa,69.16.172.in-addr.arpaи71.16.172.in-addr.arpaсуществуют и обслуживаются тем же BIND9, но используются для узлов с адресами172.16.67.x,172.16.69.xи172.16.71.x. Дублировать в них PTR адресов SHARE нельзя.
05.11.2026 ручной запуск и запуск через systemd завершились успешно для всех пяти пар A/PTR.
20.14.7. Миграция Пивопроизводства на VLAN2030
При переносе 172.16.66.229/23 с ens23 на ens21 одновременно:
- перенести IP в Netplan; один IP не должен одновременно присутствовать на двух интерфейсах;
- перенести DNS
172.16.66.53и route-only domains~ot-samara.baltika.ru,~66.16.172.in-addr.arpaи~67.16.172.in-addr.arpaнаens21; наens23оставить только Legacy DNS/домены; - в
/usr/local/sbin/ot-ddns-registerдля Pivo заменитьens23наens21; - запустить
sudo systemctl start ot-ddns-register.serviceи проверить журнал.
20.15. Переключение Samba-учётной записи на Windows-клиенте
Windows не позволяет одновременно использовать разные наборы SMB-учётных данных для одного и того же сервера в рамках одной пользовательской сессии. Типичный сценарий: пользователь сначала открыл \\SMR-SRV-OT-SHARE\clonezilla под clonezilla, а затем попытался открыть ot-admin под baltikashare. Windows может вернуть ошибку о невозможности множественных подключений к одному серверу с использованием разных имён пользователя.
Закрытие окна Проводника не гарантирует немедленного завершения SMB-сессии: могут оставаться mapping, скрытое соединение IPC$ и сохранённые Windows credentials. Для штатного переключения пользователя используется проверенный клиентский BAT change_share.bat.
Назначение BAT: отключить только SMB-подключения к
SMR-SRV-OT-SHAREнезависимо от того, через какой его IP, короткое имя или сегментный FQDN было открыто подключение. Другие сетевые серверы и сетевые диски не затрагиваются.
20.15.1. Какие адреса и имена учитывает скрипт
| Тип | Значения |
|---|---|
| Сервисные и management IP | 192.168.1.22910.44.100.22910.255.0.229172.16.66.229172.16.68.229172.16.70.229172.17.14.229 |
| Короткие имена | SMR-SRV-OT-SHARESMR-OT-SHARE |
| Сегментные FQDN | smr-srv-ot-share.legacy.ot-samara.baltika.rusmr-srv-ot-share.pivo.ot-samara.baltika.rusmr-srv-ot-share.rozliv.ot-samara.baltika.rusmr-srv-ot-share.utilities.ot-samara.baltika.rusmr-srv-ot-share.astue.ot-samara.baltika.ru |
20.15.2. Какие SMB-ресурсы очищаются
Скрипт учитывает все восемь опубликованных shares:
exchange
clonezilla
pivoproduction
rozliv
utilities
software
documentation
ot-admin
Дополнительно удаляется скрытое соединение IPC$, поскольку оно может сохранять старый SMB-контекст даже после закрытия окон Проводника.
20.15.3. Пользовательские учётные записи
| Учётная запись | Основное назначение |
|---|---|
baltikashare |
административный доступ, включая ot-admin и остальные ресурсы |
engineer |
RW exchange; RO software и documentation |
clonezilla |
RW clonezilla |
pivo |
RW pivoproduction |
rozliv |
RW rozliv |
utilities |
RW utilities |
software |
RW software |
documents |
RW documentation |
rozliv_read |
RO rozliv + RO exchange/software/documentation |
pivo_read |
RO pivoproduction + RO exchange/software/documentation |
utilities_read |
RO utilities + RO exchange/software/documentation |
BAT не хранит пароли и не выбирает новую учётную запись автоматически. Он только удаляет текущие SMB-подключения и сохранённые credentials, относящиеся к SHARE. После этого пользователь заново открывает нужный ресурс и вводит требуемый логин/пароль.
20.15.4. Полный проверенный BAT change_share.bat
@echo off
chcp 65001 >nul
title Смена пользователя SMR-SRV-OT-SHARE
echo ============================================================
echo SMR-SRV-OT-SHARE - отключение текущих SMB-сессий
echo ============================================================
echo.
echo Будут отключены ТОЛЬКО подключения к файловому серверу SHARE.
echo Подключения к другим серверам и сетевым ресурсам не трогаются.
echo.
powershell.exe -NoProfile -ExecutionPolicy Bypass -Command ^
"$targets = @(" ^
"'192.168.1.229'," ^
"'10.44.100.229'," ^
"'10.255.0.229'," ^
"'172.16.66.229'," ^
"'172.16.68.229'," ^
"'172.16.70.229'," ^
"'172.17.14.229'," ^
"'SMR-SRV-OT-SHARE'," ^
"'SMR-OT-SHARE'," ^
"'smr-srv-ot-share.legacy.ot-samara.baltika.ru'," ^
"'smr-srv-ot-share.pivo.ot-samara.baltika.ru'," ^
"'smr-srv-ot-share.rozliv.ot-samara.baltika.ru'," ^
"'smr-srv-ot-share.utilities.ot-samara.baltika.ru'," ^
"'smr-srv-ot-share.astue.ot-samara.baltika.ru'" ^
");" ^
"$mappings = Get-SmbMapping -ErrorAction SilentlyContinue | Where-Object {" ^
" $remote = $_.RemotePath;" ^
" $targets | Where-Object { $remote -like ('\\' + $_ + '\*') }" ^
"};" ^
"if ($mappings) {" ^
" $mappings | Sort-Object RemotePath -Unique | ForEach-Object {" ^
" Write-Host ('Отключение: ' + $_.RemotePath);" ^
" Remove-SmbMapping -RemotePath $_.RemotePath -Force -UpdateProfile -ErrorAction SilentlyContinue" ^
" }" ^
"} else {" ^
" Write-Host 'Явных SMB mappings к SHARE не найдено.'" ^
"}"
echo.
echo Очистка скрытых IPC$ и известных SMB-ресурсов...
echo.
for %%S in (
192.168.1.229
10.44.100.229
10.255.0.229
172.16.66.229
172.16.68.229
172.16.70.229
172.17.14.229
SMR-SRV-OT-SHARE
SMR-OT-SHARE
smr-srv-ot-share.legacy.ot-samara.baltika.ru
smr-srv-ot-share.pivo.ot-samara.baltika.ru
smr-srv-ot-share.rozliv.ot-samara.baltika.ru
smr-srv-ot-share.utilities.ot-samara.baltika.ru
smr-srv-ot-share.astue.ot-samara.baltika.ru
) do (
net use \\%%S\IPC$ /delete /y >nul 2>&1
net use \\%%S\exchange /delete /y >nul 2>&1
net use \\%%S\clonezilla /delete /y >nul 2>&1
net use \\%%S\pivoproduction /delete /y >nul 2>&1
net use \\%%S\rozliv /delete /y >nul 2>&1
net use \\%%S\utilities /delete /y >nul 2>&1
net use \\%%S\software /delete /y >nul 2>&1
net use \\%%S\documentation /delete /y >nul 2>&1
net use \\%%S\ot-admin /delete /y >nul 2>&1
)
echo.
echo Удаление сохраненных учетных данных SHARE...
echo.
for %%S in (
192.168.1.229
10.44.100.229
10.255.0.229
172.16.66.229
172.16.68.229
172.16.70.229
172.17.14.229
SMR-SRV-OT-SHARE
SMR-OT-SHARE
smr-srv-ot-share.legacy.ot-samara.baltika.ru
smr-srv-ot-share.pivo.ot-samara.baltika.ru
smr-srv-ot-share.rozliv.ot-samara.baltika.ru
smr-srv-ot-share.utilities.ot-samara.baltika.ru
smr-srv-ot-share.astue.ot-samara.baltika.ru
) do (
cmdkey /delete:%%S >nul 2>&1
)
echo.
echo ============================================================
echo Готово.
echo.
echo SMB-сессии к SMR-SRV-OT-SHARE сброшены.
echo Остальные серверы и сетевые подключения не затронуты.
echo.
echo Теперь заново открой нужный ресурс и введи другую учетку.
echo ============================================================
echo.
pause
20.15.5. Порядок использования
- Завершить активное копирование/изменение файлов на SHARE.
- Желательно закрыть окна Проводника, открытые на ресурсах SHARE.
- Запустить
change_share.batот того же Windows-пользователя, который работал с SMB. - Дождаться сообщения, что SMB-сессии к
SMR-SRV-OT-SHAREсброшены. - Снова открыть требуемый ресурс, например
\\SMR-SRV-OT-SHARE\ot-admin. - Ввести новую Samba-учётную запись и пароль.
Пример переключения:
Было:
\\SMR-SRV-OT-SHARE\clonezilla
user: clonezilla
↓ запустить change_share.bat
Стало:
\\SMR-SRV-OT-SHARE\ot-admin
user: baltikashare
Важно: скрипт использует принудительное отключение SMB mappings. Не запускать его во время копирования, сохранения или изменения файлов на SHARE: активная файловая операция может быть оборвана.
20.15.6. Что именно выполняет скрипт
Get-SmbMappingнаходит явные SMB mappings только к известным адресам/именам SHARE.Remove-SmbMapping -Force -UpdateProfileудаляет найденные mappings.net use ... /deleteдополнительно очищает известные shares и скрытыйIPC$.cmdkey /deleteудаляет сохранённые Windows credentials только для известных targets SHARE.- Подключения к другим серверам не очищаются; команда
net use * /deleteне используется.
20.15.7. Сопровождение BAT
Список targets и shares внутри BAT является частью production-конфигурации клиента. При изменении сетевой схемы SHARE его необходимо актуализировать.
Обновить BAT требуется при:
- добавлении или удалении IP-адреса файлового сервера;
- добавлении нового DNS/FQDN/короткого имени, используемого для SMB;
- добавлении или переименовании Samba share;
- окончательном удалении временного адреса
192.168.1.229; - изменении общей схемы доступа к файловому серверу.
Изменение Samba-паролей или состава групп само по себе не требует изменения BAT, поскольку пароли в скрипте не хранятся.
20.16. Резервное копирование критической конфигурации сервера
Backup не заменяет резервирование пользовательских данных MAIN-DATA и CRITICAL-BACKUP. Он предназначен именно для конфигурации и служебного состояния.
20.16.1. Скрипт /usr/local/sbin/share-config-backup
Production-скрипт:
#!/usr/bin/env bash
# ============================================================
# SMR-SRV-OT-SHARE
# Backup critical server configuration
#
# Output:
# CONFIG archive - ordinary configuration and inventory
# SECRETS archive - Samba/File Browser databases, encrypted
# SHA256SUMS - archive integrity
#
# Destination:
# /srv/main-data/baltikashare/ot-admin/server-backups
# ============================================================
set -Eeuo pipefail
umask 077
HOST="$(hostname -s)"
STAMP="$(date '+%Y%m%d-%H%M%S')"
DEST="/srv/main-data/baltikashare/ot-admin/server-backups"
WORK="$(mktemp -d "/var/tmp/${HOST}-config-backup.XXXXXX")"
CONFIG_ROOT="${WORK}/config"
SECRET_ROOT="${WORK}/secrets"
INVENTORY="${CONFIG_ROOT}/inventory"
CONFIG_ARCHIVE="${DEST}/${HOST}-config-${STAMP}.tar.gz"
SECRET_PLAIN="${WORK}/${HOST}-secrets-${STAMP}.tar.gz"
SECRET_ARCHIVE="${DEST}/${HOST}-secrets-${STAMP}.tar.gz.enc"
SUMS="${DEST}/SHA256SUMS-${STAMP}.txt"
STOPPED_SERVICES=()
cleanup()
{
for svc in "${STOPPED_SERVICES[@]:-}"
do
systemctl start "$svc" >/dev/null 2>&1 || true
done
rm -rf "$WORK"
}
trap cleanup EXIT
echo "============================================================"
echo "SMR-SRV-OT-SHARE configuration backup"
echo "Host: $HOST"
echo "Timestamp: $STAMP"
echo "Destination: $DEST"
echo "============================================================"
echo
if ! mountpoint -q /srv/main-data
then
echo "ERROR: /srv/main-data is not mounted."
exit 1
fi
FS_TYPE="$(findmnt -n -o FSTYPE /srv/main-data 2>/dev/null || true)"
if [[ "$FS_TYPE" != "btrfs" ]]
then
echo "ERROR: /srv/main-data is '$FS_TYPE', expected btrfs."
exit 1
fi
install -d \
-o root \
-g admins \
-m 0770 \
"$DEST"
mkdir -p "$CONFIG_ROOT" "$SECRET_ROOT" "$INVENTORY"
copy_path()
{
local SRC="$1"
if [[ -e "$SRC" || -L "$SRC" ]]
then
echo "COPY: $SRC"
cp -a --parents "$SRC" "$CONFIG_ROOT"
else
echo "SKIP: $SRC does not exist"
fi
}
echo
echo "=== Static configuration ==="
copy_path /etc/samba
copy_path /etc/netplan
copy_path /etc/hostname
copy_path /etc/hosts
copy_path /etc/nsswitch.conf
copy_path /etc/fstab
copy_path /etc/systemd/resolved.conf
copy_path /etc/systemd/timesyncd.conf
copy_path /etc/sysctl.conf
copy_path /etc/sysctl.d
copy_path /etc/ufw
copy_path /etc/snapper
copy_path /etc/default/snapper
copy_path /etc/systemd/system/smbd.service.d
copy_path /usr/local/sbin/samba-recycle-cleanup
copy_path /etc/systemd/system/samba-recycle-cleanup.service
copy_path /etc/systemd/system/samba-recycle-cleanup.timer
copy_path /usr/local/sbin/ot-ddns-register
copy_path /etc/systemd/system/ot-ddns-register.service
copy_path /etc/filebrowser
copy_path /etc/systemd/system/filebrowser.service
copy_path /usr/local/bin/filebrowser
copy_path /usr/local/sbin/share-config-backup
copy_path /etc/passwd
copy_path /etc/group
copy_path /etc/ssh/sshd_config
copy_path /etc/ssh/sshd_config.d
copy_path /etc/apt/sources.list
copy_path /etc/apt/sources.list.d
echo
echo "=== Collecting inventory ==="
hostnamectl > "${INVENTORY}/hostnamectl.txt" 2>&1 || true
ip -br link \
> "${INVENTORY}/ip-link.txt" 2>&1 || true
ip -br address \
> "${INVENTORY}/ip-address.txt" 2>&1 || true
ip route show table all \
> "${INVENTORY}/ip-route-all.txt" 2>&1 || true
ip rule show \
> "${INVENTORY}/ip-rule.txt" 2>&1 || true
resolvectl status \
> "${INVENTORY}/resolvectl-status.txt" 2>&1 || true
timedatectl \
> "${INVENTORY}/timedatectl.txt" 2>&1 || true
lsblk -o \
NAME,PATH,SIZE,TYPE,FSTYPE,LABEL,UUID,PARTUUID,MOUNTPOINTS \
> "${INVENTORY}/lsblk.txt" 2>&1 || true
blkid \
> "${INVENTORY}/blkid.txt" 2>&1 || true
findmnt \
> "${INVENTORY}/findmnt.txt" 2>&1 || true
findmnt /srv/main-data \
> "${INVENTORY}/findmnt-main-data.txt" 2>&1 || true
btrfs filesystem show /srv/main-data \
> "${INVENTORY}/btrfs-filesystem-show.txt" 2>&1 || true
btrfs filesystem usage /srv/main-data \
> "${INVENTORY}/btrfs-filesystem-usage.txt" 2>&1 || true
btrfs subvolume list -t /srv/main-data \
> "${INVENTORY}/btrfs-subvolumes.txt" 2>&1 || true
snapper list-configs \
> "${INVENTORY}/snapper-list-configs.txt" 2>&1 || true
testparm -s \
> "${INVENTORY}/samba-testparm.txt" 2>&1 || true
pdbedit -L -v \
> "${INVENTORY}/samba-users.txt" 2>&1 || true
getent passwd \
> "${INVENTORY}/passwd-getent.txt"
getent group \
> "${INVENTORY}/group-getent.txt"
dpkg-query -W \
-f='${binary:Package}\t${Version}\n' \
> "${INVENTORY}/packages.txt" 2>&1 || true
apt-mark showmanual \
> "${INVENTORY}/packages-manual.txt" 2>&1 || true
systemctl is-enabled \
smbd \
filebrowser \
samba-recycle-cleanup.timer \
ot-ddns-register.service \
> "${INVENTORY}/services-enabled.txt" 2>&1 || true
systemctl is-active \
smbd \
filebrowser \
samba-recycle-cleanup.timer \
> "${INVENTORY}/services-active.txt" 2>&1 || true
systemctl list-timers --all \
> "${INVENTORY}/systemd-timers.txt" 2>&1 || true
ss -lntup \
> "${INVENTORY}/listening-ports.txt" 2>&1 || true
ufw status verbose \
> "${INVENTORY}/ufw-status.txt" 2>&1 || true
echo
echo "=== Collecting ACL state ==="
ACL="${INVENTORY}/acl-important.txt"
BASE="/srv/main-data/baltikashare"
: > "$ACL"
for share in \
clonezilla \
exchange \
pivoproduction \
rozliv \
utilities \
software \
documentation \
ot-admin
do
DIR="${BASE}/${share}"
if [[ -d "$DIR" ]]
then
echo >> "$ACL"
echo "==================================================" >> "$ACL"
echo "SHARE: $share" >> "$ACL"
echo "==================================================" >> "$ACL"
getfacl -p "$DIR" >> "$ACL" 2>&1 || true
if [[ -d "${DIR}/.recycle" ]]
then
echo >> "$ACL"
echo "--- .recycle ---" >> "$ACL"
getfacl -p "${DIR}/.recycle" \
>> "$ACL" 2>&1 || true
find "${DIR}/.recycle" \
-mindepth 1 \
-maxdepth 1 \
-type d \
-exec getfacl -p {} + \
>> "$ACL" 2>&1 || true
fi
fi
done
cat > "${CONFIG_ROOT}/RESTORE_ORDER.txt" <<'EOF'
SMR-SRV-OT-SHARE
Recommended restore order
=========================
1. Install Ubuntu Server and required packages.
2. Recreate local users/groups while preserving required UID/GID
where existing MAIN-DATA files are retained.
3. Restore:
/etc/netplan
/etc/fstab
/etc/hostname
/etc/hosts
relevant sysctl/systemd configuration.
4. Mount MAIN-DATA and verify:
mountpoint /srv/main-data
findmnt /srv/main-data
5. Restore Snapper configuration.
6. Restore scripts:
/usr/local/sbin/samba-recycle-cleanup
/usr/local/sbin/ot-ddns-register
7. Restore systemd units:
samba-recycle-cleanup.service/timer
smbd.service.d/main-data.conf
filebrowser.service
ot-ddns-register.service
8. Restore /etc/samba/smb.conf.
9. Restore Samba private database from encrypted SECRETS archive
ONLY with Samba stopped.
10. Restore File Browser database from encrypted SECRETS archive
ONLY with File Browser stopped.
11. Run:
systemctl daemon-reload
testparm -s
netplan generate
12. Verify POSIX ACL against:
inventory/acl-important.txt
13. Start and verify services.
14. Check:
Samba RW/RO matrix
Snapper Previous Versions
recycle
File Browser
DDNS A/PTR
split DNS
EOF
echo
echo "=== Creating configuration archive ==="
tar \
--acls \
--xattrs \
--numeric-owner \
-C "$CONFIG_ROOT" \
-czf "$CONFIG_ARCHIVE" \
.
chown root:admins "$CONFIG_ARCHIVE"
chmod 0640 "$CONFIG_ARCHIVE"
echo
echo "============================================================"
echo "Sensitive database backup"
echo
echo "Samba/File Browser will be stopped briefly."
echo "Do not run this script during active file transfers."
echo "============================================================"
echo
for svc in smbd nmbd winbind filebrowser
do
if systemctl is-active --quiet "$svc"
then
echo "STOP: $svc"
systemctl stop "$svc"
STOPPED_SERVICES+=("$svc")
fi
done
if [[ -d /var/lib/samba ]]
then
cp -a --parents /var/lib/samba "$SECRET_ROOT"
fi
if [[ -f /var/lib/filebrowser/filebrowser.db ]]
then
cp -a --parents \
/var/lib/filebrowser/filebrowser.db \
"$SECRET_ROOT"
fi
sync
for svc in "${STOPPED_SERVICES[@]:-}"
do
echo "START: $svc"
systemctl start "$svc"
done
STOPPED_SERVICES=()
tar \
--acls \
--xattrs \
--numeric-owner \
-C "$SECRET_ROOT" \
-czf "$SECRET_PLAIN" \
.
echo
echo "============================================================"
echo "Enter a password for the encrypted SECRETS archive."
echo "IMPORTANT: without this password the archive cannot be restored."
echo "============================================================"
echo
openssl enc \
-aes-256-cbc \
-salt \
-pbkdf2 \
-iter 200000 \
-in "$SECRET_PLAIN" \
-out "$SECRET_ARCHIVE"
rm -f "$SECRET_PLAIN"
chown root:admins "$SECRET_ARCHIVE"
chmod 0640 "$SECRET_ARCHIVE"
(
cd "$DEST"
sha256sum \
"$(basename "$CONFIG_ARCHIVE")" \
"$(basename "$SECRET_ARCHIVE")"
) > "$SUMS"
chown root:admins "$SUMS"
chmod 0640 "$SUMS"
echo
echo "============================================================"
echo "BACKUP COMPLETED"
echo "============================================================"
echo
echo "CONFIG:"
echo " $CONFIG_ARCHIVE"
echo
echo "SECRETS:"
echo " $SECRET_ARCHIVE"
echo
echo "CHECKSUMS:"
echo " $SUMS"
echo
echo "Copy all three files to an external PC/storage."
echo "============================================================"
Права скрипта:
sudo chown root:root /usr/local/sbin/share-config-backup
sudo chmod 0750 /usr/local/sbin/share-config-backup
sudo bash -n /usr/local/sbin/share-config-backup
При успешной синтаксической проверке bash -n не выводит ничего.
20.16.2. Что входит в CONFIG-архив
Обычный архив не содержит Samba password DB и не предназначен для хранения секретов. В него входят критичные конфиги и снимок состояния сервера:
| Категория | Содержимое |
|---|---|
| Samba | /etc/samba, эффективный testparm -s, список Samba-пользователей без паролей |
| Сеть | /etc/netplan, hostname/hosts, fstab, IP/route/rule, resolvectl |
| Snapper/Btrfs | /etc/snapper, Btrfs filesystem/subvolume/usage, UUID и mount-инвентаризация |
| systemd | unit-файлы Samba protection, recycle cleanup, File Browser, DDNS |
| Скрипты | samba-recycle-cleanup, ot-ddns-register, сам share-config-backup |
| File Browser | конфигурация, unit, бинарный файл; рабочая DB хранится отдельно в SECRETS |
| Linux users/groups | /etc/passwd, /etc/group, getent для фиксации UID/GID |
| ACL | ACL корней восьми shares и служебных .recycle |
| Пакеты/сервисы | установленные/manual packages, активные/enabled службы, systemd timers, listening ports |
| Recovery | RESTORE_ORDER.txt с рекомендуемым порядком восстановления |
20.16.3. Что входит в SECRETS-архив
Секретная часть резервируется отдельно и перед записью на MAIN-DATA шифруется. В неё входят:
/var/lib/samba/
/var/lib/filebrowser/filebrowser.db
Для получения согласованной копии база снимается при кратковременно остановленных smbd и filebrowser. После копирования скрипт запускает ранее активные службы обратно до начала шифрования.
Шифрование:
openssl enc \
-aes-256-cbc \
-salt \
-pbkdf2 \
-iter 200000
Пароль шифрования не должен храниться вместе с SECRETS-архивом. Его необходимо хранить отдельно, например в менеджере паролей или в другом защищённом хранилище. В текст инструкции пароль не заносится.
20.16.4. Запуск backup
Перед запуском необходимо убедиться, что в этот момент нет активного копирования или изменения файлов по SMB, поскольку Samba на короткое время останавливается.
sudo /usr/local/sbin/share-config-backup
В процессе будет запрошен пароль для шифрования SECRETS. Готовые файлы создаются в:
/srv/main-data/baltikashare/ot-admin/server-backups/
Формат имён:
smr-srv-ot-share-config-YYYYMMDD-HHMMSS.tar.gz
smr-srv-ot-share-secrets-YYYYMMDD-HHMMSS.tar.gz.enc
SHA256SUMS-YYYYMMDD-HHMMSS.txt
20.16.5. Проверка SHA256
cd /srv/main-data/baltikashare/ot-admin/server-backups
sha256sum -c SHA256SUMS-YYYYMMDD-HHMMSS.txt
Ожидается:
smr-srv-ot-share-config-...tar.gz: OK
smr-srv-ot-share-secrets-...tar.gz.enc: OK
20.16.6. Вынос backup на Windows-компьютер
Перед подключением под административной учётной записью рекомендуется запустить проверенный change_share.bat, чтобы убрать старый SMB credential context.
Ресурс:
\\SMR-OT-SHARE\ot-admin\server-backups
Допустим также доступ по сегментному IP, например:
\\10.255.0.229\ot-admin\server-backups
На внешнее хранилище необходимо копировать комплект целиком:
*-config-*.tar.gz
*-secrets-*.tar.gz.enc
SHA256SUMS-*.txt
После копирования на ПК рекомендуется повторно проверить SHA256 (например через certutil -hashfile или другой проверенный инструмент) и хранить как минимум ещё одну независимую копию recovery-набора.
20.16.7. Первый сформированный recovery-набор
10.11.2026 сформирован первый recovery-набор с timestamp 20261110-154701:
smr-srv-ot-share-config-20261110-154701.tar.gz
smr-srv-ot-share-secrets-20261110-154701.tar.gz.enc
SHA256SUMS-20261110-154701.txt
Наличие этих файлов подтверждает фактический запуск backup-процедуры. Recovery-набор необходимо хранить вне самой VM/MAIN-DATA, поскольку backup, лежащий только на том же сервере, не защищает от полного отказа сервера или массива.
20.16.8. Расшифровка SECRETS при восстановлении
На recovery-системе зашифрованный архив можно преобразовать обратно во временный tar.gz:
openssl enc -d \
-aes-256-cbc \
-pbkdf2 \
-iter 200000 \
-in smr-srv-ot-share-secrets-YYYYMMDD-HHMMSS.tar.gz.enc \
-out smr-srv-ot-share-secrets-YYYYMMDD-HHMMSS.tar.gz
После проверки содержимого временный незашифрованный архив должен быть удалён или храниться только на защищённом носителе.
20.16.9. Рекомендуемый порядок восстановления
- Установить Ubuntu Server и необходимые пакеты.
- Восстановить пользователей/группы с учётом UID/GID из inventory.
- Восстановить сеть, hostname/hosts, fstab и системные настройки.
- Смонтировать MAIN-DATA и проверить
mountpoint/findmnt. - Восстановить конфигурацию Snapper.
- Восстановить локальные скрипты и systemd unit/drop-in.
- Восстановить
/etc/samba/smb.confи проверитьtestparm -s. - Остановить Samba и только после этого восстановить
/var/lib/sambaиз SECRETS. - Остановить File Browser и восстановить его DB из SECRETS.
- Выполнить
systemctl daemon-reloadи проверить конфигурацию сети. - Сверить POSIX ACL с
inventory/acl-important.txt. - Запустить сервисы и проверить RW/RO-матрицу Samba.
- Проверить Snapper Previous Versions, recycle, File Browser, DDNS A/PTR и split DNS.
При восстановлении Samba private DB желательно использовать ту же major/minor ветку Samba, на которой backup был создан. Перед заменой рабочего
/var/lib/sambaвсегда необходимо сохранить его текущую копию.
20.16.10. Что backup не заменяет
- backup пользовательских файлов MAIN-DATA;
- копирование критичных данных на CRITICAL-BACKUP;
- резервную копию самой VM/системного диска;
- внешнюю/offline-копию recovery-набора;
- документированную проверку восстановления.
Production-подход: конфигурационный recovery-набор + резервные копии данных + актуальная BookStack-инструкция должны храниться раздельно и позволять восстановить сервис без зависимости от единственного экземпляра VM.
21. Текущая контрольная точка
| Этап | Состояние |
|---|---|
| P411 | Slot 1, firmware 6.64, 512 MB FBWC, PCIe Gen2 x8, Status OK |
| D2700 | firmware 0150, 25/25 дисков OK |
| MAIN-DATA | RAID50, 5.46 TiB, production Btrfs, VM 103 |
| RECOVERY | RAID1, около 136 GiB |
| CRITICAL-BACKUP | RAID50, около 3.64 TiB |
| GLOBAL-SPARE | bay 15, shared spare, OK |
| Parity RAID50 | Queued; эксплуатацию не блокирует, контролируется |
| Production Btrfs | LABEL MAIN-DATA, mount /srv/main-data |
| Subvolume | 8 functional Btrfs subvolume |
| Snapper | 8 configs; timeline/cleanup timers active |
| POSIX ACL | SGID/default ACL настроены; корзины переведены на приватную модель .recycle/<user> + административный доступ admins; добавлены shared-ro и профильные *-ro ACL с исключением .snapshots/.recycle |
| Samba | введена в эксплуатацию; 8 shares; RW-модель: engineers + профильная *-rw; RO-модель: shared-ro + профильная *-ro; testparm OK, конфигурация перечитана через systemctl reload smbd |
| vfs_recycle | 7 shares; directory_mode/subdir_mode = 0770; sticky bit и ACL проверены; clonezilla исключён намеренно |
| Очистка .recycle | production-скрипт + systemd timer; dry-run/delete проверены |
| vfs_snapper | Windows Previous Versions: просмотр и восстановление проверены |
| Служебные каталоги | .snapshots veto; .recycle hidden |
| Защита smbd | RequiresMountsFor + mountpoint ExecStartPre работают |
| File Browser Next | v3.0.0-next; отдельный user filebrowser; web-admin baltikafile; root MAIN-DATA; port 28443 |
| Management route | default via 10.44.100.1 dev ens19; 192.168.1.229/24 без default gateway |
| File Browser / recycle | доступ к .recycle на всех 7 recycle-shares проверен; повторное создание .recycle/pivo проверено |
| ABE | не используется по принятому решению |
| NFS | не установлен; внедрение отложено до реальной необходимости |
| Split DNS | systemd-resolved: per-link OT DNS и route-only domains для прямой и reverse-зон; проверено |
| DNS-имена SHARE | 5 сегментных FQDN; A/PTR зарегистрированы и проверены. Для сетей /23 PTR находится только в reverse-зоне /24, соответствующей фактическому IP; дублирования в парную зону нет. |
| Linux DDNS | ot-ddns-register + ot-ddns-register.service; systemd запуск завершён status=0/SUCCESS |
| Переключение SMB credentials | change_share.bat проверен на Windows-клиенте; очищает SMB mappings, IPC$ и сохранённые credentials только для адресов/имён SHARE, не затрагивая подключения к другим серверам. |
| Персонифицированные Samba-учётки | создаются как локальные Linux-пользователи без shell; права задаются членством в engineers + профильной *-rw; в документации реальные логины не фиксируются |
| Read-only Samba-учётки | rozliv_read, pivo_read, utilities_read созданы; rozliv_read локально проверен: свой профильный share + exchange/software/documentation только RO, остальные DENY. Windows SMB-проверка RO-ролей остаётся отдельным контрольным шагом. |
| Recovery backup конфигурации | /usr/local/sbin/share-config-backup; CONFIG + зашифрованный SECRETS + SHA256; destination ot-admin/server-backups; первый набор 20261110-154701 сформирован и подготовлен для внешнего хранения. |
21.1. Следующие этапы
После существенных изменений сети, Samba, ACL, Snapper, File Browser или systemd повторно запускать /usr/local/sbin/share-config-backup, выносить новый комплект с сервера и проверять SHA256. Отдельно провести тестовое восстановление recovery-набора в изолированной VM.
Проверить RO-роли через Windows SMB после запуска change_share.bat: rozliv_read, pivo_read, utilities_read. Для каждого подтвердить чтение своего профильного share и exchange/software/documentation, запрет записи и DENY к чужим профильным ресурсам, clonezilla и ot-admin.
После следующей плановой перезагрузки один раз проверить boot-журнал ot-ddns-register.service.
При переводе Пивопроизводства на VLAN2030 выполнить DNS-миграцию ens23 → ens21 по разделу 20.14.7.
При вводе клиентов новых сегментов стандартизировать двухэлементный DNS suffix search list: локальный сегментный suffix + ot-samara.baltika.ru.
- Провести инвентаризацию слушающих портов и настроить firewall для management-интерфейса
10.44.100.229; оставить только сознательно необходимые административные сервисы. - Настроить копирование выбранных критичных данных на
CRITICAL-BACKUP. - Добавить мониторинг P410i/P411, D2700, physical disks, Btrfs usage, Snapper, mount, Samba и File Browser.
- NFS внедрять только при появлении реальной необходимости; первым потенциальным потребителем остаётся Clonezilla.
- Отдельно решить вопрос постоянного использования
hpsa_simple_mode=1. - Отдельно оценить необходимость Dual Domain через второй порт P411 и I/O Module B.
22. Порядок включения и выключения D2700
22.1. Включение
- Подать питание на оба БП D2700.
- Включить полку и дождаться инициализации.
- Включить DL380 G7.
- Проверить POST P411 и доступность logical drive.
22.2. Выключение
- Корректно остановить VM.
- Корректно остановить Proxmox/DL380.
- Дождаться полного выключения сервера.
- Перевести D2700 в Standby.
- При необходимости снять AC с БП полки.
22.3. Восстановление питания
Желаемая последовательность: сначала D2700 и её инициализация, затем запуск DL380 G7 с задержкой. Поведение после полного снятия и возврата AC требуется отдельно проверить в production-конфигурации.
23. Справочные материалы
- Btrfs documentation
- Snapper documentation
- Samba
vfs_snapper/vfs_recycle - HPE Smart Array / D2700 documentation
- File Browser Next documentation / release v3.0.0-next
BookStack page: HP D2700: схема дисковых массивов и назначение хранилищ
Обновление 1.0: фактическая конфигурация Samba и результаты тестов добавлены 28.10.2026.
Обновление 1.1: проверены Windows Previous Versions, скрытие служебных каталогов, автоматическая очистка Samba recycle и защита smbd от запуска без MAIN-DATA; ABE оставлен отключённым.
Обновление 1.2: добавлены File Browser Next, management gateway 10.44.100.1, production ACL для Samba recycle, проверка повторного создания персональной корзины и актуальная контрольная точка на 30.10.2026.
BookStack: Установка DNS сервера BIND9 на Ubuntu Server 24.04 с Webmin в Proxmox
Обновление 1.3: добавлены split DNS через systemd-resolved, сегментные FQDN файлового сервера, RFC 2136/DDNS через nsupdate, ot-ddns-register.service, клиентская модель DNS suffix search list и процедура миграции Pivo на ens21. 05.11.2026.
Обновление 1.4: уточнена логика reverse DNS для сетей /23. Обе половины /23 обслуживаются отдельными reverse-зонами /24, но PTR конкретного адреса SHARE создаётся только в той зоне, которой принадлежит его фактический IP. Для 172.16.66.229, 172.16.68.229 и 172.16.70.229 это зоны 66, 68 и 70.16.172.in-addr.arpa; зоны 67, 69 и 71 предназначены для других адресов второй половины соответствующих /23. 06.11.2026.
Обновление 1.5: добавлена проверенная Windows-процедура переключения Samba-учётной записи. BAT change_share.bat обрабатывает все текущие IP, короткие имена и сегментные FQDN SMR-SRV-OT-SHARE, очищает явные SMB mappings, IPC$ и сохранённые credentials только для SHARE, после чего пользователь может повторно открыть ресурс под другой Samba-учётной записью. Остальные сетевые серверы и mappings не затрагиваются. 06.11.2026.
Обновление 1.6: скорректирована эксплуатационная модель доступа производственных пользователей. Учётные записи Пивопроизводства, Розлива и Утилит теперь одновременно состоят в engineers и своей профильной *-rw группе, благодаря чему получают RW к своему производственному ресурсу и exchange, RO к software/documentation и не получают доступ к чужим профильным shares. Добавлен шаблон создания персонифицированных учётных записей на примере user1/user2; реальные персональные логины в документации не хранятся. Обновлённая модель проверена на Windows-клиенте для профиля Розлива. 10.11.2026.
Обновление 1.7: добавлена read-only модель доступа для производственных подразделений. Созданы группы shared-ro, pivoproduction-ro, rozliv-ro, utilities-ro; shared-ro предоставляет RO к exchange/software/documentation, профильная *-ro — RO только к своему производственному share. Обновлён /etc/samba/smb.conf с использованием read list и valid users. Для POSIX ACL зафиксирован безопасный способ применения через find ... -prune без обхода .snapshots и .recycle. Созданы тестовые ролевые учётки rozliv_read, pivo_read, utilities_read; локальная матрица прав rozliv_read проверена успешно. 10.11.2026.
Обновление 1.8: введён recovery-backup критической конфигурации SMR-SRV-OT-SHARE. Добавлен production-скрипт /usr/local/sbin/share-config-backup, формирующий обычный CONFIG-архив с конфигурацией и инвентаризацией, отдельный зашифрованный AES-256-CBC/PBKDF2 SECRETS-архив с Samba/File Browser state DB и файл SHA256. Описаны состав архивов, запуск, проверка SHA256, вынос на Windows-компьютер, расшифровка и рекомендуемый порядок восстановления. Первый recovery-набор 20261110-154701 сформирован 10.11.2026.