cd ~кейси/remote-office.md

кейс 03LIVE · ПРАЦЮЄ У КЛІЄНТА

Віддалений офіс на 19 робочих місць

За два тижні повністю дистанційно розгорнув для компанії термінальний сервер під ключ. 19 працівників працюють в обліковій програмі через власний VPN, сервер закритий з інтернету, а щоночі робиться резервна копія з перевіреним відновленням.

Термін
жовтень 2026 · ~2 тижні · повністю віддалено
Стек
Windows Server 2022 · Hyper-V · Remote Desktop Services · WireGuard · PowerShell · SQL Server Express · AppLocker
Виконавець
Forge Logic
19робочих місць, кожне з власним VPN-ключем
0відкритих портів ззовні за зовнішнім скануванням
7нічних копій сервера з автоперевіркою цілісності
2 хввідновлення з копії, перевірено на практиці
~2 тиж.від порожнього сервера до роботи офісу
0виїздів на місце — усе дистанційно
Віддалений офіс на 19 робочих місць0:29

Що боліло

Офіс залишився без сервера і без адміністратора одночасно. Клієнт раніше звертався до мене з друком через RDP, тож прийшов знову. Але цього разу все горіло.

  • Сервер ліг разом з акаунтом. Великий європейський хостинг закрив акаунт клієнта після перевірки даних, апеляцію відхилили. Разом із сервером зупинилась робота офісу.
  • Попередній адміністратор перестав відповідати. Документації і передачі справ не було.
  • Приїхати в офіс я не міг. Усе, від першого входу на сервер до друку чеків, треба було зробити дистанційно.

Вимоги клієнта

  • В офісі працюють тонкі клієнти, решта людей підключається з дому через VPN.
  • Усі працюють в одній обліковій системі на SQL-базі.
  • Друк рахунків на A4 і чеків в іншому офісі, на принтери працівників.
  • «Щоб вірус не зніс усе»: збій чи зараження не має зачепити копії.
  • Архівні копії, з яких можна швидко піднятись.
  • Ліцензії RDS не купувати наперед, а брати помісячно.
  • Не робити нічого, про що клієнт не просив: спершу запитувати, потім робити.

Рішення

Робоче середовище живе в окремій віртуальній машині. Фізичний сервер лише керує нею і зберігає її копії.

Схема: фізичний сервер, віртуальна машина і хто та як до них доступається

Працівники й адмін заходять кожен через свій VPN. З інтернету до сервера не достукатись, а копії лежать і на хості, і в хмарі.

Чому саме так:

  • Вірус не знесе все. Якщо щось потрапить у віртуалку, хост і нічні копії лишаться цілими. Повернення до вчорашнього стану займає 2 хвилини.
  • Два окремих VPN. Доступ працівника веде лише до робочого стола. До керування сервером йому дороги немає.
  • Друк через сам RDP. Принтер вдома чи в офісі працює без жодного драйвера на сервері.

Історія розробки

Етапи йдуть у тому порядку, як усе було: що сталось і як вирішили. Усі зміни робились скриптами PowerShell, кожен — з резервною копією стану і окремим скриптом відкату.

ops(infra)#01

Новий сервер і фундамент

Орендували фізичний сервер у дата-центрі в Нідерландах з помісячною орендою ліцензій. Диски зібрали в дзеркало RAID-1 і синхронізували завантажувальний розділ, щоб сервер стартував навіть після смерті одного диска. На залізі працює лише Hyper-V, а вся робота людей живе у віртуальній машині.

fix(network)#02

Адреса, яка вже була чиєю

Що сталось: віртуальний сервер не виходив у мережу з виданої провайдером адреси. Виявилось, що цю IP уже займав сервер іншого клієнта.

Як вирішили: зібрали докази скриптом, написали в підтримку, отримали нову адресу і перенесли на неї сервер.

sec(firewall)#03

Windows сам відчинив двері

Що сталось: після встановлення Hyper-V система відкрила служби керування для всього інтернету. Правила віддаленого робочого стола і ліцензування теж стояли «дозволено звідусіль».

Як вирішили: адмін-доступ — тільки через окремий VPN, робочий стіл — тільки через VPN працівників. Зверху — аварійні блокуючі правила на випадок, якщо хтось помилково відкриє порт. Зовнішнє сканування: жодного відкритого порту.

sec(host)#04

Сторонні програми на хості

Що сталось: через кілька днів на фізичному сервері з’явились дві програми віддаленого доступу, встановлені без погодження. Це були двері в обхід усього VPN.

Як вирішили: зберегли журнали, з’ясували, хто і навіщо їх ставив, видалили до останнього файлу. Пояснили простими словами, чому на хості не має бути нічого, крім віртуалізації.

feat(monitoring)#05

Сторож і стан сервера в один клік

Щоб наступний такий випадок не залежав від везіння, поставив щогодинного сторожа на хост і віртуалку. Він звіряє з еталоном адміністраторів, служби, задачі, правила брандмауера і входи. На робочому столі адміна — ярлик «SRV status»: диски, бекапи, VPN, тривоги і чужі входи на одному екрані.

feat(onboarding)#06

Підключення працівників без дзвінків адміну

Рішення: генератор одним запуском створює користувача і пакує йому архів: VPN-ключ, інсталятор в один клік, ярлик та інструкція. Людина розпаковує, запускає і працює.

Підводний камінь: свіже оновлення Windows почало лякати попередженням про «невідоме віддалене підключення» і за замовчуванням вимикати буфер обміну та принтери. Замість того щоб вимикати цей захист, я підписав ярлики власним сертифікатом, а інсталятор додає йому довіру. У працівників — жодного попередження.

feat(print)#07

Друк без драйверів

Принтер працівника прокидається на сервер через сам віддалений робочий стіл і працює як локальний. На сервер не ставиться жодного драйвера, і чековий принтер в іншому офісі друкує так само.

feat(backup)#08

Резервні копії, які справді відновлюються

Рішення: щоночі — експорт цілої віртуальної машини: 7 копій, перевірка цілісності дисків, захист від переповнення диска. Усередині сервера — тіньові копії файлів тричі на день, щоб витягти видалений документ за хвилину. AppLocker запущений у режимі аудиту, щоб зібрати картину запусків перед блокуванням.

Підводний камінь: копію мало зробити — її треба відновити. Тестове відновлення показало, що експорт зберігає стан пам’яті машини, а друга копія не вміщається в пам’ять хоста. Підібрали процедуру, і відновлення тепер займає 2 хвилини.

fix(app)#09

«Сервер уже працює» в обліковій програмі

Що сталось: працівники не бачили базу, яку створив менеджер, або отримували «сервер уже працює». Причина: серверна частина програми запускалась від імені того, хто зайшов першим, і кожен сеанс бачив свій окремий екземпляр.

Як вирішили: окремий службовий обліковий запис для сервера програми і правильні дозволи на запуск. Механіку пояснили менеджеру клієнта простими словами, і він застосував її сам.

fix(perms)#10

З восьмого користувача — «Access denied»

Що сталось: нові працівники отримували помилку при старті програми. Виявилось, що файл налаштувань першим створив інший користувач, і решта не могла в нього писати.

Як вирішили: права на цю одну папку видали групі працівників, а не людям по одному. Усі наступні нові користувачі отримують їх автоматично, а файли самої програми лишились закритими на запис.

fix(dpi)#11

Масштаб, рамка і друк рахунків

Що сталось: на ноутбуках із масштабом 125–150% рахунки друкувались дрібно. Перша версія фіксу примусово ставила 100%, і друк став нормальним. Але вилізли два нові болі: сервер відкривався вікном зі смугами прокрутки, а люди з поганим зором не могли збільшити картинку.

Як вирішили: перестали лікувати всіх і вилікували одну програму: для облікової системи на сервері увімкнено режим сумісності DPI. Ярлики повернули до масштабу ПК: сервер відкривається на весь екран, кожен бачить свій масштаб, а друк лишився точним. Перевірка — порівнянням PDF до і після, без жодного принтера під рукою.

sec(audit)#12

Аудит після чужих налаштувань

Що сталось: коли замовник доналаштував базу, сторож видав десятки змін. Серед них три небезпечні: працівник з правами адміністратора; копії всієї бази, доступні всім 19 людям; папка системної служби, куди будь-хто міг підкласти файл і стати адміном. Правила брандмауера програми стояли «звідусіль».

Як вирішили: спершу аудит без жодних змін, потім погодження із замовником по кожному пункту. Усе закрили одним скриптом з бекапом прав і відкатом, а відразу після — перевірили, що програма і друк працюють.

fix(backup)#13

Хмарний бекап бази, який лише прикидався зеленим

Що сталось: скрипт замовника для копії бази в хмару формально працював, а сервіс моніторингу показував зелене. Насправді задача запускалась лише тоді, коли адмін сидів на сервері. Шлях до хмарного клієнта був хибним, а на вхід у хмару скрипт чекав 15 секунд замість 2–3 хвилин. Ще й хмарний клієнт захоплював файл логу, і наступний бекап впав би.

Як вирішили: задача працює в режимі без входу користувача і без збереженого пароля. Хмарний клієнт стартує окремо, а скрипт чекає входу до 4 хвилин. Скрипт замовника правився точково, з копією оригіналу. Тест: архів створено, синхронізація йде, моніторинг зелений уже не дарма.

Уроки

Головне, що я виніс із цього проєкту: перевіряти треба кінець ланцюжка, а не зелену галочку.

  • Хост — не робоча машина. На фізичному сервері лише віртуалізація, бекапи і сторож. Будь-яка зайва програма там — це двері повз усі замки.
  • Кожна зміна — з бекапом і відкатом. На чужому живому сервері дистанційно це єдиний спосіб спати спокійно.
  • Відновлення треба перевірити, а не припустити. Перший же тест знайшов проблему, яка під час аварії коштувала б години.
  • Права видаються групам, а не людям. Тоді двадцятий працівник працює так само, як перший.
  • Лікувати треба програму, а не людей. Примусовий масштаб для всіх прибрав одну проблему і створив дві нові.
  • Не вимикати захист, а робити правильно. Замість вимкнення попереджень Windows — підписані ярлики, замість чужого пароля — режим задачі без пароля.
  • Не робити того, про що не просили. Пропонувати — так, але вирішує клієнт. Це зберігає довіру.

Результат

Офіс працює на новому сервері: 19 людей заходять одним значком з дому чи з офісу, принтери друкують, а ззовні сервер не видно.

  • Резервні копії є на трьох рівнях: цілий сервер щоночі, файли тричі на день, база щодня в хмару.
  • Додати нового працівника — один запуск скрипта і готовий архів.
  • Адмін бачить стан усього одним кліком, а сторож повідомляє про будь-які несподівані зміни.