Эта статья довольно долго не могла увидеть свет, по ряду причин, от проблем со здоровьем после COVID (я отупел), до отсутствия времени. Время шло, импортозамещение набирало обороты, пилоты становились продакш-средами, и все катилось под откос шло к светлому будущему.

Какое-то время назад мы с командой тоже приступили к пилотированию миграции на «отечественное» ПО. И вот, что из этого вышло.

Началось все с разговоров. А куда без них?

С чего начинается миграция? С выбора ПО? Нет, с планирования и анализа.

- Чего мы хотим достичь?

- Заместить импортные программные продукты отечественными аналогами.

- Полностью?

- Да.

- А если аналогов нет?

- Тогда в максимально возможном объеме.

И тут у нас встала дилемма. Потому что сотрудники Компании в работе помимо прочего используют CAD и PLM софт, который просто не умеет работать на Linux. Вернее, умеет, но через костыли wine’а, что вызывает недовольство пользователей в плане быстродействия. Так же мы используем VDI Horizon, который умеет работать только с AD. А аналогов у Horizon нет. И не говорите про всякие там надстройки для ProxMox и вот это вот все. Ни одна из других существующих VDI-систем не умеет работать с Instant Clones. Максимум, что предлагает OpenSource (и импортозамещение, которое построено на OpenSource) - это Linked Clones. А у нас на IC построены как Windows пулы, так и Linux. И администрировать VDI-рабочие столы как полноценные машины — это смерти подобно, и стоимость владения вырастает за счет необходимости держать огромный штат техподдержки. Поэтому мы не сможем полностью уйти от Windows, как бы нам этого ни хотелось. И из этого вытекает следующее:

  • Мы не сможем уйти от домена на базе Windows.

  • Для обеспечения работоспособности инфраструктуры нужны также сервисы DNS, DHCP, WSUS, CA and etc, которые нет смысла (или невозможно) переносить на Linux.

А раз мы не сможем полностью импортозаместиться, то и проект не имеет особого смысла. На этом можно было бы и закончить, но мы решили, что раз уж инфраструктуру импортозаместить не выйдет — займемся хотя бы пользовательской средой. А со стороны инфры сделаем все, что сможем. Zabbix перевезем на отечественную ОСь.. еще чего-нибудь.. Потому что проблема, например, почтового сервера заключается в том, что Exchange у нас есть, и он работает.. А чтобы его заменить на условный Communigate Pro нам нужно потратить кучу денег. А кто же любит тратить деньги, если и так все работает?.. И так с большинством развернутых в проде систем.

На том и порешали.

0. Ansible

Как поднять Ansible я писать не буду, информации об этом в интернетах более, чем достаточно, не вижу смысла загромождать статью лишней информацией. Главное, что там нужно сделать — это сформировать ssh-ключ, с которым Ansible будет ходить к клиентам, и продумать доставку этого ключа на клиентов.

И еще один нюанс – динамическое inventory. Клиентские ПК – дело непостоянное: кто-то уволился, кто-то пришел, какие-то ПК выключены, какие-то больше не существуют. И как это поддерживать в актуальном состоянии – целая задача. Особенно, когда речь идет не о десятках, и даже не о сотнях, а о тысячах машин. Мы пошли по более-менее простому пути – использование плагина nmap в связке с плагином constructed для Ansible. При запуске он опрашивает указанные подсети и формирует список хостов для применения плейбуков или ролей, а потом делает свои грязные делишки на отобранные по правилам хосты.

0.1. Муки выбора дистрибутива

Из представленных на рынке «отечественных» ОС по факту выбор-то и не велик, благо, 99% наших рабочих мест не нужно закрывать сертифицированными ОСями. DEB или RPM, Gentoo-подобные поделки для централизованного администрирования даже не рассматривались, спасибо. Астра\Альт\РедОС\ROSA. Проблема в том, что все они платные. Но. У Альта есть форк - Simply Linux, который бесплатен для коммерческого использования. Думаю, дальше не стоит объяснять, почему мы выбрали Simply Linux.

Ниже есть глава про преобразование ISO-образа.

1. Локальный репозиторий

В нашем случае все даже проще, чем обычно. БазАльт сделал веб-интерфейс, который в пару кликов позволяет настроить репликацию их репозитория (выбранных веток).

Выглядит вот так:

Чтобы попасть на эту страничку, нужно доустановить пакеты ahttpd, alterator-fbi и alterator-mirror, и запустить-активировать ahttpd:

systemctl start ahttpd
systemctl enable ahttpd

В целом в этой админке довольно много функций помимо зеркалирования репозитория, доступ к которым открывается с доустановкой нужных пакетов альтератора.

Дальше мы столкнулись с тем, что нельзя выбрать, куда будут зеркалироваться пакеты. В Вике Альта пишут про то, что надо лезть в fstab, и там монтировать желаемое расположение к /srv/public/mirror*. Но нам это показалось странным. В итоге нашли файлик /usr/lib/alterator/backend3/mirror, в котором указаны пути для alterato-mirror. Поменяли dest_dir=/repos/alt_main-repo и все поехало.

*(Статью в Вике Альта правил я по результатам наших изысканий)

Дальше мы подумали о том, что нам нужен будет кастомный репозиторий, в который мы будем сваливать пакеты того же Каспера и 1С.. да и прочие, которых нет в репозах Альта (Simply). Список доп.софта у нас получился примерно такой:

  • 1С толстый и тонкий клиент

  • Google Chrome

  • Касперский агент и клиент

  • OnlyOffice (ну не Libre же офисным работникам отдавать..)

  • VNC-Viewer

  • VMWare Horizon Client (про него отдельная история, как Windows-админ (я) пытался RPM собрать)

Чтобы создать кастомный репозиторий, нужно прочитать это и это, создать нужную структуру каталогов, наполнить нужное место RPM-пакетами, создать gpg-ключ, создать и подписать индексы, подключить репозиторий клиентам, и можно радоваться.

В целом – ничего сложного, если не накосячить с деревом каталогов, как я по началу.

После заполнения каталога с RPM-пакетами, в моем случае это /repos/alt_custom-repo/x86_64/RPMS.alt_custom_repo/, нужно создать и подписать индексы:

genbasedir --create --progress --sign --default-key=[gpg-key без скобок] --topdir=/repos/alt_custom-repo x86_64 alt_custom_repo

*genbasedir является командой из пакета apt-utils.

Основные сложности у меня вызвали 2 пакета – OnlyOffice и VMWare Horizon Client. Первый не может удовлетворить зависимости, второй просто не существует.

1.3. Пакеты

Тут я вынужден сделать лирическое отступление - я и моя команда - чистый SRE, парни, которые про эти ваши CI\CD и DevOps практики знают только из интернетов и разговоров с коллегами. Это я к тому, что пересобрать RPM-пакет для сисадмина - это тёмный лес. Но мы не отступаем перед сложностями. Самое сложное было разобраться в скриплетах и найти инфу о том, в какой последовательности они применяются при обновлении пакета. И тут мне помогла вот эта дока.

1.3.1. OnlyOffice

Тут все просто – пересобрать RPM без отсутствующих зависимостей. Но стоит сразу уточнить, что Альт (Simply) по дефолту не даст руту собрать RPM-пакет, для этого предлагается использовать непривилегированного пользователя. Делаем:

cd /tmp
wget https://download.onlyoffice.com/install/desktop/editors/linux/onlyoffice-desktopeditors.x86_64.rpm?_ga=2.238710784.1633530263.1666265796-724860256.1666265796
sudo apt-get install wget
wget https://download.onlyoffice.com/install/desktop/editors/linux/onlyoffice-desktopeditors.x86_64.rpm?_ga=2.238710784.1633530263.1666265796-724860256.1666265796
rpmrebuild -enp onlyoffice-desktopeditors.x86_64.rpm\?_ga\=2.238710784.1633530263.1666265796-724860256.1666265796
sudo apt-get install rpmrebuild
rpmrebuild -enp onlyoffice-desktopeditors.x86_64.rpm\?_ga\=2.238710784.1633530263.1666265796-724860256.1666265796

И в открывшейся спеке комментируем пакеты, которых нет в репозиториях Р10. Приводим к виду:

Requires:      /bin/sh
Requires:      /bin/sh
Requires:      /bin/sh
Requires:      /bin/sh
Requires:      /bin/sh
Requires:      atk
Requires:      boost-filesystem
Requires:      curl
#Requires:      dejavu-sans-fonts
#Requires:      dejavu-sans-mono-fonts
#Requires:      dejavu-serif-fonts
Requires:      gtk3
Requires:      libX11
Requires:      libXScrnSaver
Requires:      liberation-mono-fonts
Requires:      liberation-narrow-fonts
Requires:      liberation-sans-fonts
Requires:      liberation-serif-fonts
Requires:      libstdc++ >= 4.8.0
Requires:      libxcb
#Requires:      rpmlib(CompressedFileNames) <= 3.0.4-1
#Requires:      rpmlib(FileDigests) <= 4.6.0-1
#Requires:      rpmlib(PayloadFilesHavePrefix) <= 4.0-1
#Requires:      rpmlib(PayloadIsXz) <= 5.2-1
#Requires:      xcb-util-image
#Requires:      xcb-util-keysyms
#Requires:      xcb-util-renderutil
#Requires:      xcb-util-wm
#Requires:      xdg-utils

И сохраняем. На выходе получается RPM-пакет без неудовлетворенных зависимостей. Да, так делать неправильно. Но, на Вике Альта так и написано – игнорируй зависимости, и "спина болеть не будет".

Более правильным решением, конечно же, было бы собрать пакет из исходников. Но мы же SRE.. И поэтому это мы записали в планы. На потом.

1.3.2. VMWare Horizon Client

Собрать из исходников проприетарное ПО не получится, даже если вы - не я. Horizon можно скачать в виде tarball-архива с бинарниками, и писать спеку под них. Но я пошел по более простому пути. Я скачал bundle, написал spec-файл для его установки, и запаковал это все в RPM-пакет.

А потом я решил автоматизировать это дело. И написал скриптик, который, получая на вход ссылку на скачивание bundle'а Horizon Client'а, создает структуру каталогов для сборки, меняет в спеке "хххххх" на "версию", и запускает сборку.

Spec-файл Horizon Agent for Linux выглядит так:

Name:           vmware-horizon-client
Version:        xxxxxx
Release:        1
Summary:        custom rpm package vmware-horizon-client

License:        GPL
Source0:        %{name}-%{version}.tar.gz

Requires:       bash
Requires:       python3-modules-sqlite3
Requires:       python3-modules-curses
Requires:       python3-module-pexpect
Requires:       python-modules-json
Requires:       python-module-pygtk
Requires:       python-module-jinja2
Requires:       python-module-yaml
Requires:       python-module-distutils-extra

%description
VMware Horizon Client for LAB.RU team custom repo

%prep
%setup -q

%install
install -d -m 0755 $RPM_BUILD_ROOT/opt/vdi/
install -m 0755 %{name}-%{version} $RPM_BUILD_ROOT/opt/vdi/%{name}-%{version}

%pretrans
if !([ -z "$(pgrep vmware-view)" ]); then
        pkill -f vmware-view
fi

%preun
if !([ -z "$(pgrep vmware-view)" ]); then
        pkill -f vmware-view
fi
file=(`ls /opt/vdi/`)
if !([ -z $file ]); then
        env VMWARE_KEEP_CONFIG=no /opt/vdi/$file -u vmware-horizon-client --console
        rm -f /opt/vdi/$file
fi
if test -f "/etc/skel/Рабочий стол/vmware-view.desktop"; then
        rm -f "/etc/skel/Рабочий стол/vmware-view.desktop"
fi

%posttrans
env TERM=dumb VMWARE_EULAS_AGREED=yes /opt/vdi/%{name}-%{version} --console --set-setting vmware-horizon-integrated-printing vmipEnable yes --set-setting vmware-horizon-html5mmr html5mmrEnable yes --set-setting vmware-horizon-usb usbEnable yes --set-setting vmware-horizon-smartcard smartcardEnable yes --set-setting vmware-horizon-rtav rtavEnable yes --set-setting vmware-horizon-tsdr tsdrEnable yes --set-setting vmware-horizon-scannerclient scannerEnable yes --set-setting vmware-horizon-serialportclient serialportEnable yes --set-setting vmware-horizon-mmr mmrEnable yes --set-setting vmware-horizon-media-provider mediaproviderEnable yes --set-setting vmware-horizon-teams-optimization teamsOptimizationEnable no
echo "view.defaultBroker = 'uag.lab.ru'" > /etc/vmware/view-mandatory-config
echo "view.defaultDomain = 'lab'" >> /etc/vmware/view-mandatory-config
echo "view.defaultProtocol = 'BLAST'" >> /etc/vmware/view-mandatory-config
echo "view.autoHideToolbar = 'TRUE'" >> /etc/vmware/view-mandatory-config
echo "view.autoConnectBroker = 'uag.lab.ru'" >> /etc/vmware/view-mandatory-config
echo "view.enableMMR = 'TRUE'" >> /etc/vmware/view-mandatory-config
chmod +x /usr/share/applications/vmware-view.desktop
if !([[ -f "/etc/skel/Рабочий\ стол/vmware-view.desktop" ]]); then
ln -sf /usr/share/applications/vmware-view.desktop /etc/skel/Рабочий\ стол/vmware-view.desktop
chmod 755 /etc/skel/Рабочий\ стол/vmware-view.desktop
fi
if [[ -d /home/LAB.RU/ ]]; then
        for dir in $(ls /home/LAB.RU/ | grep -v _); do
                if !([[ -f "/home/LAB.RU/$dir/Рабочий\ стол/vmware-view.desktop" ]]); then
                        ln -sf /usr/share/applications/vmware-view.desktop /home/LAB.RU/$dir/Рабочий\ стол/vmware-view.desktop
                        chmod 755 /home/LAB.RU/$dir/Рабочий\ стол/vmware-view.desktop
                fi
        done
fi

%files
/opt/vdi/%{name}-%{version}

%changelog
* August 2022 ANSysoev
-

Скрипт для выглядит так:

#!/bin/bash
if [ -z "$@" ]; then
echo "run script with link to download Horizon Client as argument at run"
else
        cd /home/user/rpmbuild/
        rm -rf /home/user/rpmbuild/*
        mkdir BUILD BUILDROOT SOURCES SPECS SRPMS
        cd /home/user/rpmbuild/SOURCES
        wget "$@"
        version=$(ls | sed -e "s/VMware-Horizon-Client-//" -e "s/.bundle//" -e "s/-/./g")
        name="vmware-horizon-client"
        fullname=$(echo $name-$version)
        mkdir $fullname
        mv $(find /home/user/rpmbuild/SOURCES/  -maxdepth 1 -type f) /home/user/rpmbuild/SOURCES/$fullname/$fullname
        tar -czvf $fullname.tar.gz $fullname
        cp /home/user/vmware-horizon-client.spec /home/user/rpmbuild/SPECS/vmware-horizon-client.spec
        sed -i "s/xxxxxx/$version/" /home/user/rpmbuild/SPECS/vmware-horizon-client.spec
        cd /home/user/rpmbuild/
        rpmbuild -bb SPECS/vmware-horizon-client.spec
fi

Для запуска надо сделать вот такую магию:

horizon-client-RPM-1.sh https://download3.vmware.com/software/CART23FQ3_LIN64_2209/VMware-Horizon-Client-2209-8.7.0-20616018.x64.bundle

И На выходе получится собранный пакетик:

tree
rpmbuild
├── BUILD
│   └── vmware-horizon-client-2209.8.7.0.20616018.x64
│       └── vmware-horizon-client-2209.8.7.0.20616018.x64
├── BUILDROOT
├── RPMS
│   └── x86_64
│       └── vmware-horizon-client-2209.8.7.0.20616018.x64-1.x86_64.rpm
├── SOURCES
│   ├── vmware-horizon-client-2209.8.7.0.20616018.x64
│   │   └── vmware-horizon-client-2209.8.7.0.20616018.x64
│   └── vmware-horizon-client-2209.8.7.0.20616018.x64.tar.gz
├── SPECS
│   └── vmware-horizon-client.spec
└── SRPMS

1.3.3. Google Chrome and etc.

Тут вообще проблем нет, просто скачивается RPM-пакет с официального сайта, копируется в каталог, и все. Все пакеты с удовлетворенными зависимостями ставятся так. И это хорошо.

2. Преобразование ISO-образа

Мы выбрали Simply, потому что он бесплатный.

Но. Отдавать офисным работникам Linux с xfce на борту — это парализовать работу офиса на неопределенный срок. Если более-менее привычные к ПК ребята освоятся достаточно быстро, но тоже не сразу, то тётушки-бухгалтеры — скорее никогда, чем быстро. Поэтому что? Правильно, надо поставить KDE! Это тоже не решит все проблемы, но порог вхождения существенно снизится.

Но. Если выпилить xfce и поставить сверху KDE — получится не кошерно. Останутся лишние пакеты от DM и DE, поэтому надо лезть в ISO и понять, как же происходит установка Linux, чтобы вмешаться в этот процесс и вместо одной DE поставить другую.

На самом деле ничего сложного в этом нет (если разобраться), но все по порядку.

Прочитав Вику Альта Модификация установочного ISO образа, Создание образов устройств, Autoinstall, и ничего в ней не поняв, я решил отвязаться от дистрибутива, и полез в теорию. Хотя последняя ссылка мне помогла во многом.

Что есть дистрибутив Linux? Дистрибутив – это, сильно упрощая, ядро Linux + набор пакетов. Всё. Набор пакетов ПО – суть «встроенный в ISO репозиторий». У Simply пакеты лежат в \ISOroot\ALTLinux\RPMS.main\. Чтобы собрать дистрибутив, нужно набрать выбранные пакеты, удовлетворить их зависимости, и положить в ISO, описать «группы ПО», пересчитать и подписать индексы. . В директории Metadata\pkg-groups.tar\lists\ лежит файл .base, содержащий в себе список пакетов, которые накатываются в любом случае, а так же директория slinux, содержащая в себе описание этих самых групп ПО (имя и состав пакетов каждой группы).

Для того, чтобы избавиться от xfce и добавить вместо него KDE есть 2 пути: сложный и очень сложный.

Очень сложный предполагает скачивание из репозитория нужных пакетов (KDE и его зависимости). Но мне было лень. Наверное, есть какой-то специальный софт, который умеет считывать зависимости из метадаты указанного пакета, и выкачивать эти зависимости.. Но я такого не нашел, поэтому пошел по сложному пути, а именно — скачал Альт Workstation 10 K (у которого та же пакетная база, что и у Simply, только с KDE искаропке), и подменил пакеты в ISO-репозитории и файл .base, собрал, установил… … … … ..ииииии.. получил свежеустановленный Альт 10 K. Удивился. Много думал. В основном о том, что моих теоретических познаний явно недостаточно для реализации поставленной мной же задачи. (Как же сложно и неприятно быть тупым! Проклятый COVID!)

После пролитых слез, покрасневших глаз, вырванных волос и обгрызенных ногтей поиска причин, я понял, что в списке пакетов есть RPM’ки со словом branding в имени, и понял, что именно их установка в целевую систему отвечает за то, какой дистрибутив получится на выходе. Например, один из пакетов правит файлик/etc/system-release, другой накидывает нескучные обои и т.д.

Словом, после нехитрых, но скучных и утомительных правок файлика .base и закидывания в репозиторий недостающих пакетов (у меня на это ушло примерно 10 попыток установки системы), я получил на выходе Simply Linux 10 K. Потом я решил, что этого недостаточно, и отсобрал еще один ISO уже без DE.. Simply Linux Server. А то на чем мне Ansible и локальный репозиторий разворачивать?

Список команд чуть ниже.

Далее — доставка на свежеустановленную систему ключей Ansible и установка hostname. Если в ОСи будут установлены ключи от Ansible, то дальше можно все сделать через сам Ansible. Тут нам поможет пакет alterator-postinstall и простейший скрипт, который доставит в /root/.ssh/authorized_keys нужные ключи. У меня 2 Ansible, 1 в головном офисе, и 1 в филиале, канал с которым, мягко говоря, оставляет желать лучшего. Поэтому 2 ключа. Так же нужно позаботиться об инженерах техподдержки, и закинуть в свежую систему скрипт, который на основе существующих в AD записей для компьютеров, будет подбирать подходящий hostname для нового ПК перед вводом в домен. Эти скрипты тоже нужно будет доставить в целевую систему. Скрипт назовем 87-set-ansbls-keys.sh, и напишем в нем следующее (ну почти так, ключи я вам не покажу =Ъ):

#!/bin/sh

. install2-init-functions

echo "ssh-rsa бла-бла-бла-набор-символов root@ansible-filial-hostname" > $destdir/root/.ssh/authorized_keys
echo "ssh-rsa бла-бла-бла-набор-символов root@ansible-hostname" >> $destdir/root/.ssh/authorized_keys

cp /var/ChangeHostName.py $destdir/var/

Тут одна тонкость — таргет указывается с преффиксом $destdir, иначе установщик, выполняя директиву postinstall, запишет ключи в свой /root, а не в устанавливаемую ОС.

Скрипт поиска подходящего hostname прост, как 5 копеек (которых никто не видел уже черт знает сколько лет). Я создал в AD бесправную учетку, чтобы Python мог сходить в AD и считать уже существующие в определенной OU учетки компьютеров, и выбрать следующий по списку.

#!/usr/bin/python3
# -*- coding: utf-8 -*-
import os
import sys
from getpass import getpass
from ldap3 import Server, Connection, SUBTREE, LEVEL
import time

username="lab.ru\linux_to_domain"
password="Passw0rd!"

server = Server("dc-1.lab.ru", port=389, use_ssl=False, get_info='ALL')
connection = Connection(server, user=username, password=password,
               fast_decoder=True, auto_bind=True, auto_referrals=True, check_names=False, read_only=True,
               lazy=False, raise_exceptions=False)

hostnamedigit=1
hostname = "ARM-"+'{:0>4}'.format(hostnamedigit)

def get_all_ad_hosts(connection):

    results = list()
    elements = connection.extend.standard.paged_search(
        search_base='OU=LINUX,OU=Computers,dc=lab,dc=ru',
        search_filter='(&(objectCategory=computer)(!(userAccountControl:1.2.840.113556.1.4.803:=2)))',
        search_scope=SUBTREE,
        attributes=['name'],
        paged_size=100)
    for element in elements:
        host = dict()
        if 'dn' in element:
            host['dn'] = element['dn']
            host['name'] = element['attributes'][u'name'][0]
            results.append(host)
    return(results)
    connection.unbind()

def search_for_duplicatename(hostname,list_of_computers):
    for computer in list_of_computers:
        if computer['name'].casefold() == hostname.casefold():
            print(hostname+" already exists")
            return 1
    return 0

computers = get_all_ad_hosts(connection)
while search_for_duplicatename(hostname, computers) != 0:
    hostnamedigit += 1
    hostname = "ARM-"+'{:0>4}'.format(hostnamedigit)
print(hostname)
os.system("hostnamectl set-hostname "+hostname)
print("Your system is gonna reboot in 10 seconds....")
time.sleep(10)
os.system("reboot now")

Теперь о том, куда же эти скрипты поместить. Целевая директория — архив altinst, находящийся в корне ISO. В архиве скрипт нужно расположить в директории /usr/share/install2/postinstall.d/ и не забыть сделать его исполняемым, иначе чуда не произойдет. Скрипт подбора hostname я положил в /var, хотя это не играет особой роли.

Но. Прежде, чем все это сделать, нужно смонтировать скачанный ISO, скопировать куда-то его содержимое, распаковать архив с помощью squashfs-tools (пакет нужно поставить), скопировать скрипты, поменять файлик .base.. Словом, сделать все свои грязные делишки, и потом запаковать архив и собрать ISO. Итого (перед выполнением genbasedir нужно скопировать необходимые пакеты, удалить лишние, и привести в порядок файлы, отвечающие за установку групп ПО, как было описано выше):

apt-get install apt-utils squashfs-tools
mkdir /home/user/slinux_iso /home/user/altinst
cd /home/user/altinst
sudo mount /home/user/slinux.iso /mnt
cp -r /mnt/* /home/user/slinux_iso/
unsquashfs /home/user/slinux_iso/altinst
cp /path_to_script_ansible_keys.sh /home/user/altinst/squashfs-root/usr/share/install2/postinstall.d/87-set-ansbls-keys.sh
chmod +x /home/user/altinst/squashfs-root/usr/share/install2/postinstall.d/87-set-ansbls-keys.sh
cp /path_to_script_hostname /home/user/altinst/squashfs-root/var/ChangeHostName.py
chmod +x /home/user/altinst/squashfs-root/var/ChangeHostName.py
mksquashfs /home/user/altinst/squashfs-root/ /home/user/slinux_iso/altinst
genbasedir --create --topdir=/home/user/slinux_iso/ ALTLinux main
sudo xorriso \
-as mkisofs \
-joliet \
-partition_cyl_align "off" \
-partition_offset 16 \
-iso-level 3 \
-full-iso9660-filenames \
-sysid "LINUX" \
-volid "Simply Linux 10.1 x86_64" \
-volset "ALT" \
-publisher "BASEALT LTD" \
-appid "SIMPLY LINUX 10.1 X86_64 2022-06-28" \
-copyright "LICENSE_ALL_HTML" \
-eltorito-boot syslinux/isolinux.cfg \
-eltorito-catalog syslinux/boot.cat \
-no-emul-boot \
-boot-load-size 4 \
-boot-info-table \
-isohybrid-mbr syslinux/isohdpfx.bin \
-eltorito-alt-boot \
-e EFI/.efiboot.img \
-no-emul-boot \
-isohybrid-gpt-basdat \
-output ../SimplyLinux10_KDE.iso

И ждем.

В целом, можно было заскриптовать и еще какие-то штуки, которые делаются при первом запуске системы, как то – установка доменных сертификатов, прописывание локального репозитория и т.д. Но мы предпочли делать это через Ansible. Так это проще контролировать, и проще что-то изменить, если это потребуется.

3. Ansible playbooks

Дальше мы приступили к написанию плейбуков для доставки на клиенты нужных настроек:

  • ssh

  • sssd

  • samba

  • kerberos

  • pam

  • cups

  • ввод в домен

  • … etc.

Я довольно долго думал о том, нужно ли приводить листинг плейбуков. И, посоветовавшись с командой, мы решили, что не все стоит выкладывать. По ряду причин.

Спойлер

Да, мы знаем, что в нижеследующем можно сделать все иначе. Использовать роли, переменные и т.д. Хранить все в гите, отслеживать там изменения и прочее, прочее, прочее. Мы знаем, спасибо. Но читать это в рамках статьи будет невозможно. Поэтому плейбуки. Поэтому разбито так, как разбито.

 Итак, требования следующие:

  1. Доставить внутренние сертификаты, импортировать их

  2. Добавить локальные репозитории

  3. Установить в систему весь требуемый софт, закинуть конфиги для установленного софта, настроить skel, чтобы при первом входе в систему, пользователь получил нужные линки и каталоги, предусмотреть подключение для пользователей сетевых шар, живущих на Windows-сервере, предусмотреть подключение пользователям списка баз 1С, как это описано здесь (ну это просто удобно)

  4. Сформировать конфиги для подключения ПК к домену, предусмотреть запуск логон-скриптов, обойти проблему авторизации на proxy-сервере (в нашем случае это скрипт, который стучится в proxy-сервер с Kerberos-тикетом, посредством curl’а, и получает на проксе тикет на 8 часов). Да, WSA – она такая..

  5. Настроить ssh согласно требованиям от ИБ, в том числе ограничить доступ для определенных групп AD

  6. Настроить доступ к sudo для определенной группы AD

  7. Соблюсти прочие требования ИБ (мне запретили это показывать. ИБ – те еще параноики)

  8. Ввести ПК в домен

  9. Предусмотреть механизм «брендирования» - обои рабочего стола, загрузчика и прочее (это мне тоже запретили вам показывать)

  10. Предусмотреть возможность массового обновления

В плейбуках все понятно по названиям тасков. Поэтому в проде мы вообще не делали комментариев. Для статьи я добавил немного комментов там, где посчитал необходимым.

«Кто в теме и так поймет, кто не в теме – тот все равно листинг читать не будет».

Оговорюсь лишь о том, что для доставки файлов, открытых ключей и прочего, мы опубликовали их рядом с репозиториями. Там все равно web-сервер поднят, почему бы его не использовать?

3.1. Доставить внутренние сертификаты, импортировать их

- name: Install local CA certs
  gather_facts: false
  hosts: simply
  tasks:
    - name: Execute script
      shell: |
        mkdir /tmp/certs
        cd /tmp/certs
        wget --no-check-certificate https://local-repo-srv.lab.ru/alt_custom-repo/certs/root.crt
        wget --no-check-certificate https://local-repo-srv.lab.ru/alt_custom-repo/certs/subca.crt
        cp ./rootca.crt /etc/pki/ca-trust/source/anchors/
        cp ./subca.crt /etc/pki/ca-trust/source/anchors/
        chmod a-x /etc/pki/ca-trust/source/anchors/*
        update-ca-trust extract

3.2. Добавить локальные репозитории

- name: add repositories
  gather_facts: false
  hosts: simply
  tasks:
    - name: delete all /etc/apt/sources.list.d/
      shell: rm -f /etc/apt/sources.list.d/*

    - name: create lab.list
      copy:
        dest: /etc/apt/sources.list.d/lab.list
        content: |
          rpm [p10] http:// local-repo-srv.lab.ru /alt_main-repo p10/branch/x86_64 classic
          rpm [p10] http:// local-repo-srv.lab.ru /alt_main-repo p10/branch/noarch classic
          rpm [alt_custom_repo] http:// local-repo-srv.lab.ru /alt_custom-repo x86_64 alt_custom_repo

    - name: add custom gpg key
      shell: curl http:// local-repo-srv.lab.ru /alt_custom-repo/x86_64/base/custom_repo.pgp >> /etc/apt/custom_repo.pgp && gpg --no-default-keyring --keyring /usr/lib/alt-gpgkeys/pubring.gpg --import /etc/apt/custom_repo.pgp

    - name: add /etc/apt/vendors.list.d/lab.list
      copy:
        dest: /etc/apt/vendors.list.d/lab.list
        content: |
          simple-key "alt_custom_repo" {
          Fingerprint "бла-бла-бла-буквы-и-цЫфры";
          Name "Vasily <Vasya@lab.ru>";
          }

    - name: apt-get update
      shell: |
apt-get update
	apt-get dist-upgrade -y

3.3. Установить в систему весь требуемый софт, …

- name: soft installation
  gather_facts: false
  hosts: simply
  tasks:

    - name: update
      shell: apt-get update -y

    - name: install packages
      apt_rpm:
        name:
          - sudo
          - apt-scripts
          - openssh
          - task-auth-ad-sssd
          - sssd-ad
          - samba-client
          - 1c-preinstall-full
          - vmware-view-preinstall
          - onlyoffice-desktopeditors
          - nano
          - firefox
          - libinput
          - libinput-devel
          - xorg-drv-libinput
          - xorg-drv-libinput-devel
          - x11vnc
          - x11vnc-service
          - 1c-enterprise-8.3.18.1483-thin-client
          - vlc
          - google-chrome-stable
          - autofs
          - vmware-horizon-client
          - system-config-printer
          - kde5-spectacle
          - evolution
          - evolution-ews
          - conky
          - remmina
          - remmina-plugins
          - cups
        state: present

    - name: remove Libre, stop cups
      shell: |
            apt-get remove libreoffice5 -y && apt-get clean -y && apt-get autoremove -y
            systemctl stop cups

#для VNC есть еще таска для установки пароля, но я вам ее не покажу.
#Там тривиально
    - name: x11vnc config
      copy:
        dest: /usr/sbin/x11vnc-start-daemon
        content: |
          #!/bin/bash
          AUTH=`ps aux | grep "\-auth " | head -n 1`
          AUTH=${AUTH/*\-auth /}
          AUTH=${AUTH/ */}
          /usr/bin/x11vnc -auth $AUTH -dontdisconnect -usepw -shared -forever -rfbport 5900 -rfbauth /etc/vncpasswd -display :0 -repeat

    - name: catalogs and files
      file:
        path: "{{ item.path }}"
        state: "{{ item.state }}"
      with_items:
        - { path: /etc/skel/Рабочий стол/, state: directory } #каталог для создания ярлыков
        - { path: /mnt/share/, state: directory } #каталог для монтирования «сетевых дисков»
        - { path: /var/ChangeHostName.py, state: absent } #удаление скрипта подбора hostname
        - { path: /opt/1cv8/x86_64/8.3.18.1483/libstdc++.so.6, state: absent } #для работы 1С этот файл надо удалить. Не спрашивайте, это не баг, это фича.
        - { path: /etc/skel/.1C/1cestart/, state: directory } #каталог для монтирования шары со списком баз для 1С

    - name: create links
      file:
        src: "{{ item.src }}"
        dest: "{{ item.dest }}"
        state: "{{ item.state }}"
        mode: "{{ item.mode }}"
        force: yes
      with_items:
        - { src: /mnt/share/, dest: /etc/skel/Рабочий стол/Сетевые_Папки, state: link, mode: '755' }
        - { src: /usr/share/applications/firefox.desktop, dest: /etc/skel/Рабочий стол/firefox.desktop, state: link, mode: '755' }
        - { src: /usr/share/applications/google-chrome.desktop, dest: /etc/skel/Рабочий стол/google-chrome.desktop, state: link, mode: '755' }
        - { src: /usr/share/applications/1cestart-8.3.18-1483.desktop, dest: /etc/skel/Рабочий стол/1C.desktop, state: link, mode: '755' }
        - { src: /usr/share/kf5/applications/kf5/org.kde.dolphin.desktop, dest: /etc/skel/Рабочий стол/Dolphin.desktop, state: link, mode: '755' }
        - { src: /usr/share/applications/onlyoffice-desktopeditors.desktop, dest: /etc/skel/Рабочий стол/onlyoffice-desktopeditors.desktop, state: link, mode: '755' }
        - { src: /usr/share/applications/vmware-view.desktop, dest: /etc/skel/Рабочий стол/vmware-view.desktop, state: link, mode: '755' }
        - { src: /mnt/.services/1CBases/1cestart_alt.cfg, dest: /etc/skel/.1C/1cestart/1cestart.cfg, state: link, mode: '755' }

    - name: copy files
      copy:
        src: "{{ item.src }}"
        dest: "{{ item.dest }}"
        owner: "{{ item.owner }}"
        group: "{{ item.group }}"
        mode: "{{ item.mode }}"
      with_items:
#блок копирования настроек cups. Они для всех одинаковы, подключается очередь
#печати на принтер MyQ
        - { src: /etc/ansible/playbooks/files/cups/cupsd.conf, dest: /etc/cups/cupsd.conf, owner: root, group: lp, mode: '640' }
        - { src: /etc/ansible/playbooks/files/cups/cups-files.conf, dest: /etc/cups/cups-files.conf, owner: root, group: root, mode: '644' }
        - { src: /etc/ansible/playbooks/files/cups/printers.conf, dest: /etc/cups/printers.conf, owner: root, group: lp, mode: '600' }

    - name: enable services
      service:
        name: "{{ item }}"
        enabled: yes
        state: restarted
      with_items:
        - x11vnc
        - cups

    - name: firefox set krb enable
      copy:
        dest: /usr/lib64/firefox/browser/defaults/preferences/myprefs.js
        content: |
          pref("network.negotiate-auth.trusted-uris",".lab.ru");
          pref("network.automatic-ntlm-auth.trusted-uris",".lab.ru");
          pref("network.automatic-ntlm-auth.allow-non-fqdn","true");
          pref("network.negotiate-auth.allow-non-fqdn","true");
          pref("network.negotiate-auth.delegation-uris",".lab.ru");

    - name: chrome set krb enable
      copy:
        dest: /etc/opt/chrome/policies/managed/krb.json
        content: |
          {
            "AuthServerAllowlist": "*.lab.ru",
            "AuthNegotiateDelegateAllowlist": "*.lab.ru"
          }

    - name: apt dedup, enable cups
      shell: |
             apt-get dedup -y
             systemctl start cups

3.4. Сформировать конфиги для подключения ПК к домену, ..

- name:  pre-domain config
  gather_facts: false
  hosts: simply
  tasks:
          - name: krb config
            copy:
              dest: /etc/krb5.conf
              content: |
                [logging]
                # default = FILE:/var/log/krb5libs.log

                [libdefaults]
                 default_realm = LAB.RU
                 dns_lookup_realm = true
                 dns_lookup_kdc = true
                 ticket_lifetime = 24h
                 renew_lifetime = 7d
                 rdns = false
                 forwardable = yes
                 default_ccache_name = FILE:/tmp/krb5cc_%{uid}

          - name: samba config
            copy:
              dest: /etc/samba/smb.conf
              content: |
                [global]
                security = ads
                realm = LAB.RU
                workgroup = LAB
                netbios name = {{inventory_hostname}}
                template shell = /bin/bash
                kerberos method = system keytab
                wins support = no
                idmap config * : range = 10000-20000000
                idmap config * : backend = tdb

          - name: sssd config
            copy:
              dest: /etc/sssd/sssd.conf
              content: |
                [sssd]
                config_file_version = 2
                user = root
                domains = LAB.RU
                services = pam,nss,autofs

                [nss]

                [pam]

                [domain/LAB.RU]
                id_provider = ad
                auth_provider = ad
                chpass_provider = ad
                default_shell = /bin/bash
                fallback_homedir = /home/%d/%u
                ad_server = dc-1.lab.ru,dc-2.lab.ru
                ad_backup_server = _srv_
                cache_credentials = true
                debug_level = 2
#монтирование сетевых дисков. Через pam mount ничего не вышло. Он либо багованый,
#либо фича у него такая, но мы перешли на смб, который монтирует шары при
#обращении к ним пользователя 
          - name: autofs config
            copy:
              dest: /etc/auto.master
              content: |
                /mnt/share        /etc/auto.samba --ghost
                /mnt/.services    /etc/auto2.samba --ghost --timeout 60


          - name: autofs config 1
            copy:
              dest: /etc/auto.samba
              content: |
                disk_1  -fstype=cifs,multiuser,cruid=$UID,sec=krb5,domain=LAB.RU      ://dfs-server.lab.ru/Share
                disk_2  -fstype=cifs,multiuser,cruid=$UID,sec=krb5,domain=LAB.RU      ://file-server.lab.ru/Share2
                disk_3  -fstype=cifs,multiuser,cruid=$UID,sec=krb5,domain=LAB.RU      ://file-server.lab.ru/Share3

          - name: autofs config 2
            copy:
              dest: /etc/auto2.samba
              content: |
                1CBases      -fstype=cifs,multiuser,cruid=$UID,sec=krb5,domain=LAB.RU      ://file-server.lab.ru /1CBases
                background   -fstype=cifs,multiuser,cruid=$UID,sec=krb5,domain=LAB.RU      ://file-server.lab.ru/background


          - name: enable autofs
            service:
              name: autofs
              enabled: yes
              state: restarted

          - name: configure nsswitch and cronyd
            lineinfile:
              path: "{{ item.path }}"
              regexp: "{{ item.regexp }}"
              line: "{{ item.line }}"
            loop:
              - { path: /etc/nsswitch.conf, regexp: '^passwd', line: 'passwd:     files sss' }
              - { path: /etc/nsswitch.conf, regexp: '^shadow', line: 'shadow:     tcb files sss' }
              - { path: /etc/nsswitch.conf, regexp: '^group', line: 'group:      files sss' }
              - { path: /etc/chrony.conf, regexp: '^pool', line: 'pool dc-1.lab.ru iburst' }

          - name: set control policy and system-auth
            shell: |
                  control sudo public
                  control system-auth sss

#Cisco WSA – довольно «интересный» proxy-сервер..
#И так как далеко не все Linux’овые приложения умеют использовать krb-тикеты
#для авторизации на прокси, приходится использовать костыль. Нет, можно было
#заставить пользователя сначала запустить браузер, авторизоваться на проксе,
#и только после этого получить доступ в интернет, скажем, с мессенджера..
#но мы посчитали это издевательством.

          - name: proxy auth script
            copy:
              dest: /var/proxy_auth.sh
              content: |
                #!/bin/bash
                ip=$(echo `ifconfig eth0 2>/dev/null|awk '/inet addr:/ {print $2}'|sed 's/addr://'`)
                echo "curl -isL --negotiate -u : https://proxy-server.lab.ru/same_text/$ip/http://lab.ru/ > /dev/null" > /tmp/proxy_auth.sh
                /bin/bash /tmp/proxy_auth.sh
                rm -f /tmp/proxy_auth.sh
              mode: "755"

          - name: create logon script fpr proxy auth
            copy:
              dest: /etc/profile.d/proxy_auth.sh
              content: |
                #!/bin/bash
                /var/proxy_auth.sh
              mode: "755"

3.5. Настроить ssh согласно требованиям от ИБ, в том числе ограничить доступ для определенных групп AD

- name: ssh
  gather_facts: false
  hosts: simply
  tasks:
          - name: edit sshd config
            lineinfile:
                    path: /etc/openssh/sshd_config
                    regex: "^(#)?{{item.key}}"
                    line: "{{item.key}} {{item.value}}"
                    state: present
            loop:
                            - { key: "LogLevel", value: "VERBOSE" }
                            - { key: "PermitRootLogin", value: "prohibit-password" }
                            - { key: "MaxAuthTries", value: "3" }
                            - { key: "MaxSessions", value: "2" }
                            - { key: "PermitEmptyPasswords", value: "no" }
                            - { key: "UsePAM", value: "yes" }
                            - { key: "AllowGroups", value: "domain?users root wheel linux-sudoers" }
#да, да, именно в таком формате тут нужно указывать доменные группы с пробелами
#в названиях
            notify:
                    - restart sshd
                    - enable sshd

  handlers:
          - name: restart sshd
            service:
                    name: sshd
                    state: restarted

          - name: enable sshd
            service:
                    name: sshd
                    enabled: yes

3.6. Настроить доступ к sudo для определенной группы AD

- name: sudoers
  gather_facts: false
  hosts: simply
  tasks:
          - name: edit sudoers file
            blockinfile:
                    path: /etc/sudoers
                    backup: yes
                    block: |
                            %Linux-Sudoers ALL=(ALL) ALL
                            %Linux-Users ALL=/usr/bin/apt-cache
                            %Linux-Users ALL=/usr/sbin/poweroff
                            %Linux-Users ALL=/usr/sbin/NetworkManager
                    validate: /usr/sbin/visudo -cf %s

          - name: replace line
            lineinfile:
                    path: /etc/sudoers
                    regexp: '^@includedir /etc/sudoers.d'
                    line: '#@includedir /etc/sudoers.d'
                    validate: /usr/sbin/visudo -cf %s

3.8. Ввести ПК в домен

#При запуске спрашивает логин и пароль (в «приватном» виде).
#После чего получает керберос-тикет и подключает ОС к домену
- name: domain join
  gather_facts: false
  hosts: simply

  vars_prompt:
    - name: "adlogin"
      prompt: "Enter AD Login"
      private: no

    - name: "password"
      prompt: "Enter password"
      private: yes

  tasks:
    - name: domain check
      shell: timeout 6s net ads testjoin
      register: domain_state
      failed_when: domain_state.rc == 0

    - name: Clear the sssd cache
      shell: rm -f /var/lib/sss/db/* /var/lib/sss/mc/*

    - name: get krb ticket
      shell: echo '{{ password }}'| kinit "{{ adlogin }}"

    - name: join domain
      command: net ads join -U "{{ adlogin }}"%"{{ password }}" createcomputer="/Computers/Linux"

    - name: sssd enable
      service:
        name: sssd
        enabled: yes
        state: restarted

    - name: reboot
      reboot:
        reboot_timeout: 120

3.10. Предусмотреть возможность массового обновления

Тут пришлось сделать отдельный playbook для обновления, и отдельный playbook для брендирования, так как мы пошли по простому пути – не стали пилить тему для кедов, а просто поменяли интересующие нас картинки. И поэтому при обновлении пакетов картинки затираются. Поэтому сразу после обновления происходит брендирование.

Playbook апдейта:

- name: update and upgrade
  hosts: simply
  gather_facts: false
  tasks:

  - name: update & upgrade
    shell: |
      apt-get update -y && apt-get dist-upgrade -y
      apt-get dedup -y

Брендинг у нас уже был (но я вам его не покажу, мне запретили). И поэтому playbook обновления выглядят так:

- import_playbook: update.yml
- import_playbook: branding.yml

4. Server-side

Следующий этап импортозамещения – перенос инфраструктурных сервисов на «отечественные» программные продукты. Об этом мы долго думали, рассматривали варианты, поднимали стенды (но стенд и боевые тесты – это совсем не одно и то же). Словом, перекинуть на Альт или Астру, или какую-то еще ОС, например, Zabbix, dhcp, dns, proxy-сервер – не проблема. Это все есть и работает. Но заменить VMWare Hypervisor просто нечем. OpenNebula? Ну да, ну да. KVM? ProxMox? VDI – отсутствует. Проблема «отечественного» софта осталась той же – это пересобранное OpenSource ПО, которое стоит денег. И как весь OpenSource, его стоимость заключается не в «коробка + 2 инженера», а в «десяток инженеров с зарплатами сильно выше, чем у «коробочного» (в зависимости от размера инфраструктуры).

По итогу мы перекинули на Simply Linux продуктовый Zabbix, и подняли Ansible, jitsi и локальный репозиторий. Дальше по плану перенос Nextcloud, Kaspersky Security Center, Certification Authority. Но все это.. такое.. Фикция и профанация.

5. Выводы

В целом, со слов тестовой группы, работать на Linux «можно». Да, недостает привычных виндовых удобств, типа SSO для Outlook, предпросмотра документов в 1С (над этим работает наш центр компетенций 1С), «адок с банк-клиентами и криптопрой» (с) техподдержка.

«Работать можно». Базовый функционал есть. Да, не искаропке, его приходится допиливать, ибо парадигма Linux такова, что каждый каждый делает «это» так, как хочет. Если вы понимаете, о чем я. А допиливать функционал приходится в основном силами админов и ТП.

В итоге: используя данный инструментарий, сотрудник сможет выполнять свои обязанности.

Но. Шаг влево\шаг вправо вызывает жуткий butthurt как у пользователя, так у техпода, привыкшего к Windows. У нас же как заведено? Логи начинают читать только тогда, когда google ничего не подсказал. И перестроить мышление довольно трудно, потому что «ну там же так работает! И это удобно! Так зачем уходить от удобного и привычного к сложному и непонятному?». Но это уже политика, это на другом ресурсе обсуждается.

«Мыши плакали и кололись..» А, стоп, где-то я это уже писал..

Комментарии (7)


  1. nikweter
    28.10.2022 11:55

    Вопрос немного не по теме, но все же... Судя по всему организация у вас довольно масштабная, не проще организовать получение лицензий альтернативным способом?


    1. Snow_Bars Автор
      28.10.2022 12:03

      В целом, проще, конечно, но есть ряд "но".

      Проблема альтернативных лицензий в том, что они "не обеспечивают гарантированную работоспособность", а непрерывность бизнеса - постулат.
      Плюс никто не отменял правительственную программу по импортозамещению, и вот это все.

      Для малого бизнеса "иранский офис" будет допустимым выходом, наверное. Для крупного - под большим вопросом.


    1. BeLord
      28.10.2022 13:59

      Стратегически это может привести к остановке бизнеса, гайки закручиваются и будут закручиваться, в один прекрасный момент софт Х может оказаться вне закона и не важно какая там лицензия, хоть марсианская. Поэтому, замещать софт стоит.


  1. edo1h
    29.10.2022 17:07

    Ни одна из других существующих VDI-систем не умеет работать с Instant Clones

    можно в двух словах что это и зачем?


    Отдавать офисным работникам Linux с xfce на борту — это парализовать работу офиса на неопределенный срок. Если более-менее привычные к ПК ребята освоятся достаточно быстро, но тоже не сразу, то тётушки-бухгалтеры — скорее никогда, чем быстро

    честно говоря не понял, если у вас активно используется VDI, то какая разница что за DE на рабочем месте?


    1. Snow_Bars Автор
      31.10.2022 09:36

      можно в двух словах что это и зачем?

      В двух словах. Или можно попробовать LMGTFU.

      честно говоря не понял, если у вас активно используется VDI, то какая разница что за DE на рабочем месте?

      Потому, что на тонких клиентах сидят далеко не все. И кому-то удобно сидеть на толстом клиенте, потому что им "религия не позволяет". Например, разработчики терпеть не могут VDI, потому что всем известный Kaspersky и его менее известный продукт agentless, режет скорость по сети в 42 раза. И они об этом знают, но не могут в своих темплейтах аплаенсов поменять e1000 на vmxnet3. И разрабы не хотят ждать, пока у них пересчитываются индексы по 30с вместо 0.5с, и сборка проекта занимает до получаса вместо 2 минут.

      Есть еще множество причин, но и этого хватит для ответа на поставленный вопрос.


  1. teelledro
    31.10.2022 09:40

    Тема моего дипломного проекта "Применение свободного программного обеспечения, при организации автоматического рабочего места медицинского работника". АРМы - моноблоки от поганого Леново. ОСь - чистый дебиан 9 с четвёртым гномом (АРМы поставились министерством здравоохранения с приказом не менять ОСь и его версию!). По итогу имеем: ВЕСЬ необходимый медикам софт для их работы + личные хотелки в виде месседжеров, просмотрщика DICOM-снимков и др . Гном вырезан под корень, вместо него накатана XFCE с самописаными темой оформления и набором иконок. Для работы софта написанного only for windows заюзал wine в режиме multiuser (экономим место на HDD, при работе не одного десятка юзеров на одном моноблоке), остальное заменено опенсурсными аналогами. Для разворота преднастроенного сеанса пользователя (панели, иконки, меню, нескучные обои ;), mimсы типов файлов), написал генератор сеансов. Для того, чтобы не линуксовые админы загоняли свежие тачки, после прошивки в домен AD, так же написал скрипт и с выборкой действий под разные ситуации - новая дефолтная тачка для стационара, тачка для гинекологов и акушеров отделений гинекологии, роддома и женских консультаций или работников мед.статистики - у них свой софт, который никто больше не юзает - изменение набора софта и преднастроенного сеанса юзера.

    Сам деб поставлялся с предустановленными касперским, криптопро, випнетом и поделием под название сикретнет. КриптоПро норм работает, випнет без эл.почты, а значит - не нужен. Касперский с локального сервера поставил - требование ФСБ с их ежегодными проверками. Сикретнет - становил демоны и грохнул из авторана, если нужен будет, то он настроен не вредить системе и поднимается так же скриптом с последующей разблокировкой ОСи ибо что курил разраб, я не знаю почему он сразу блокирует тачку, при его активации либо остановке(((

    Все скрипты писал на bash, вайн нафарширован и запакован в тарбол. Устанавливается нужная версия нафаршированного вайна так же скриптом загона тачки в домен. Сам образ нафаршированной ОСи и его новые релизы (хотелки врачей практически каждый месяц первого года внедрения линуха приходили, та и сами скрипты модернизирую время от времени и пишу новые) делаю клонзиллой и разворачиваются через PXE той же клонзиллой виртуальным сервером.

    Принтеры в больнице и её филиалах я ногами обошёл и нашёл, установил, и проверил драйвера. Работают ;) До сканеров пока дело не дошло, т.к. мало используются медиками.

    В общем, тачки активно используются. На сегодняшний день поставлено в эксплуатацию 98 машин из 178. Кому нужно было работать в современных реалиях тяжёловесности софта и заменить старые компы 20летней давности, те спокойно работают под линухом. Кто ругался по началу, те - привыкли. Кто поумнее, просит сразу помочь с литературой или практической помощью в обучении работы с новым софтом и ОСью, в чём не отказываю ибо сам натыкался так же на повсеместный RTFM 17 лет назад, когда перешёл на линух с мастдая. Ну, а отвечать тем же своей семье, которая так же работает/играет на компах и ноутах, работающим на линухе - как-то стрёмно ;)

    В чём был посыл моего комента? Не так страшен и плох линух на десктопе. Просто его нужно уметь приготовить и забэкапить ;) Ну и, естесствено, обучить пользователя, если он конечно желает того...


    1. rader90
      31.10.2022 10:11

      Сам использую linux soft, многое перешло на web. Интересно было обменятся опытом с коллегами реализации внедрений в медицине.