понедельник, 6 декабря 2021 г.

Debian 11: настройка VirtualBox

При настройке VirtualBox под Debian 11 столкнулся с загадочной проблемой. По заветам официального сайта скачал и развернул дистрибутив, всё выглядит привычно и работоспособно, виртуальная машина создалась, но вот запускаться категорически не захотела:

vboxdrv.sh: failed: modprobe vboxdrv failed. Please use 'dmesg' to find out why.
There were problems setting up VirtualBox.  To re-start the set-up process, run
  /sbin/vboxconfig
as root.  If your system is using EFI Secure Boot you may need to sign the
kernel modules (vboxdrv, vboxnetflt, vboxnetadp, vboxpci) before you can load
them. Please see your Linux system's documentation for more information.

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

С учетом этого требуются следующие дополнительные шаги:

1. генерируем модули, требующиеся VirtualBox-у (впрочем, пока у меня дело дошло до вышеописанной ошибки, модули уже были созданы)

sudo /sbin/vboxconfig

2. создаём так называемый ключ владельца (machine owner key)

openssl req -new -x509 -newkey rsa:2048 -keyout MOK.priv -outform DER -out MOK.der -days 36500 -subj "/CN=huhmuh/" -nodes

3. подсовываем созданный ключ в систему:

sudo mokutil --import MOK.der

4. перезагружаем компьютер. Тут потребуется пароль, заданный на этапе 2.

5. подписываем ключом владельца модули, сгенерированные VirtualBox-ом:

sudo /usr/src/linux-kbuild-5.10/scripts/sign-file sha256 ./MOK.priv ./MOK.der /lib/modules/$(uname -r)/misc/vboxdrv.ko
sudo /usr/src/linux-kbuild-5.10/scripts/sign-file sha256 ./MOK.priv ./MOK.der /lib/modules/$(uname -r)/misc/vboxnetadp.ko
sudo /usr/src/linux-kbuild-5.10/scripts/sign-file sha256 ./MOK.priv ./MOK.der /lib/modules/$(uname -r)/misc/vboxnetflt.ko

6. наконец, добавляем модули в ядро:

sudo modprobe vboxdrv
sudo modprobe vboxnetadp
sudo modprobe vboxnetflt

По завершении этой процедуры VirtualBox запустилась без ошибок.

Литература:

пятница, 3 декабря 2021 г.

Маленькая заметочка про сервисы в debian дистрибутивах

Понадобилось расшарить папку для общего доступа. Задача знакомая: добавляем пару строк в файл конфигурации, включаем пользователя, перезапускаем сервис. Последний пункт вызвал некоторые затруднения. Если раньше делал просто /etc/init.d/smbd restart, то теперь захотелось по-модному, через systemctl. Однако выполнение соответствующей команды слегка озадачило:

# systemctl status samba
● samba.service
   Loaded: masked (/dev/null)
   Active: inactive (dead)

# systemctl start samba
Failed to start samba.service: Unit samba.service is masked.

Что за чудеса? Оказывается, в моём случае статус masked означает, что сервис отключён:

$ ls -l /lib/systemd/system/samba.service
lrwxrwxrwx 1 root root /lib/systemd/system/samba.service -> /dev/null

Пришлось покопаться в памяти и вспомнить, что нужный мне сервис называется по-другому, smbd. А этот сервис перезапустить не составило труда:

# systemctl status smbd
# systemctl restart smbd

Ну, и на будущее: посмотреть сервисы можно командой:

# systemctl list-units

Посмотреть файлы - командой:

# systemctl list-units

Посмотреть зависимости - командой:

# systemctl list-dependencies smbd

и так далее...

Литература:

  1. Почему некоторые системные сервисы находятся в «маскированном» состоянии?

пятница, 26 марта 2021 г.

Windows 10: установка .NET Framework 3.5

Время идёт, когда-то разбирался, как поставить Microsoft NET Framework 3.5 на Windows 8, теперь вот подошел черёд Windows 10. Для неё, насколько я знаю, отдельного установщика нет, всё делается через включение-отключение компонентов. Однако попытка сделать это штатным образом через "Панель управления" -> "Добавление компонентов Windows" привела к ошибке "0x80244022". Помогла правка реестра: найти параметр HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU\UseWUServer, сменить значение с 1 на 0 и перезапустить Центр обновления Windows командами:

net stop wuauserv
net start wuauserv

После этой правки команда установки фреймворка тяжко задумалась на полчаса, но в конце концов отработала штатно:

DISM /Online /Enable-Feature /FeatureName:NetFx3 /All


Правда, стоит отметить, что ситуация была не очень стандартная: компьютер в локальной сети, у которой нет прямого выхода в большой Интернет, поэтому всё общение с внешним миром идёт через прокси. Чтобы Центр обновления этот самый прокси увидел, нужно его прописать:

netsh winhttp set proxy proxy-server="http=12.34.56.78:90"

или:

netsh winhttp set proxy proxy-server="socks=12.34.56.78:90"

или просто взять настройки прокси интернет эксплорера:

netsh winhttp import proxy source =ie

Когда прокси будет не нужен, его можно убрать командой:

netsh winhttp reset proxy


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

Узнаём PID (идентификатор) процесса командой:

sc queryex wuauserv

Прибиваем процесс командой:

taskkill /PID 123456 /F


Вообще, команды tasklist и taskkill оказались довольно интересными. Например, при помощи tasklist можно решить обратную задачу - найти по PID имя процесса:

tasklist /FI "pid eq 123456"

или отфильтровать вывод по имени образа:

tasklist /FI "imagename eq iexplore.exe"

или получить информацию о службе:

tasklist /FI "services eq wuauserv"

или посмотреть все зависшие процессы:

tasklist /FI "status eq not responding"

короче, масса полезных свойств.


Литература:

Deploy .NET Framework 3.5 by using Deployment Image Servicing and Management (DISM)
Killing a Windows Service that Hangs on Stopping or Not Responding
https://winitpro.ru/index.php/2017/08/10/oshibka-0x80244022-i-problema-ostanovki-wsuspool/
Исправление ошибки обновлений с кодом 80244022 в Windows 7
Как клиент Windows Update определяет, какой прокси-сервер использовать для подключения к веб-узлу Windows Update

UPD 2023-01-25: При ошибке 0x800f0954 помогло прописывание параметра в реестре:

[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU]
"UseWUServer"=dword:00000000

воскресенье, 7 марта 2021 г.

Ubuntu: как настроить OpenVPN

С недавних пор заинтересовал меня вопрос, как можно попадать в свою домашнюю сеть из большого Интернета. Нет, конечно, проброшенные ssh и rdp-порты выручают, но всё-таки это как-то неизящно. Есть, правда, ещё pptp, он он, говорят, небезопасный... В общем, захотелось что-нибудь посолиднее, и выбор пал на OpenVPN.

Сама установка трудностей не представляет:

sudo apt install openvpn
Основная интрига - как этот самый openvpn-сервер сконфигурировать. В сети полно инструкций, как это сделать с использованием easy-rsa, но на поверку оказалось, что этот самый easy-rsa - просто набор bash-скриптов для работы с openssl, так что особого смысла в использовании этой дополнительной прослойки я не увидел и насоздавал ключи и сертификаты прямо с использованием openssl.

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

Удостоверяющий центр:
-- приватный ключ УЦ (бережно хранится и никому не показывается)
-- сертификат УЦ (раздаётся всем кому попало)
эта пара используется для подписи сертификатов сервера и клиента

Сервер OpenVPN:
-- сертификат УЦ
-- приватный ключ сервера (бережно хранится и никому не показывается)
-- сертификат сервера, подписанный УЦ (передаётся клиентам при установлении подключения)

Клиент, подключающийся к серверу:
-- сертификат УЦ
-- приватный ключ клиента (бережно хранится и никому не показывается)
-- сертификат клиента, подписанный УЦ (передаётся серверу при установлении подключения)
При подключении клиент и сервер обмениваются своими сертификатами. Сервер проверяет, что сертификат клиента подписан тем же УЦ, что и его собственный, а клиент делает такую же проверку с сертификатом сервера. Если оба сертификата прошли проверку, соединение устанавливается, сервер вытаскивает из сертификата клиента ComnmonName и использует его для идентификации клиента.

Создание удостоверяющего центра (УЦ)

Можно, конечно, использовать сторонние УЦ, но там, как правило, за работу требуют денежку. Поэтому логично поднять свой УЦ. Фактически, весь УЦ - это пара файлов, ключ и самоподписанный сертификат. Единственная тонкость - из соображений безопасности эту пару файлов желательно запрятать поглубже: вынести в docker, на отдельную машину, отправить на Луну... Так или иначе, создаются эти файлы следующим образом.

1. Создаём приватный ключ УЦ:

openssl genrsa    -des3   -out huhmuh-CA.key    2048

Поскольку тут фигурирует опция "-des3", то ключ будет зашифрован, поэтому потребуется ввести пароль. В дальнейшем этот пароль потребуется вводить при использовании этого ключа, например, при подписывании сертификатов, так что пароль лучше сделать помудрёнее и не забыть.

2. Создаём самоподписанный сертификат УЦ:

openssl req \
    -x509 \
    -days 3650 \
    -key huhmuh-CA.key \
    -out huhmuh-CA.crt \
    -subj "/emailAddress=huhmuh@example.com/C=RU/ST=Oblastnaya oblast/L=Default City/O=Home/OU=Living room/CN=example.com" \
    -addext "subjectAltName = DNS:example.com"

Можно "-subj" и не указывать, тогда при создании сертификата потребуется ответить на кучку вопросов, кто вы и откуда. Ну, и, поскольку используется huhmuh-CA.key, программа спросит для него пароль.

В результате этих манипуляций у нас на руках окажутся два файла, huhmuh-CA.key и huhmuh-CA.crt - это и будет наш удостоверяющий центр.

Создание сертификата сервера

1. Создаём приватный ключ сервера:

openssl genrsa    -out huhmuh-openvpn.key    2048

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

2. Создаём запрос сертификата для сервера:

openssl req \
    -new \
    -key huhmuh-openvpn.key \
    -out huhmuh-openvpn.csr \
    -subj "/emailAddress=huhmuh@example.com/C=RU/ST=Oblastnaya oblast/L=Default City/O=Home/OU=Living room/CN=server"

Тут стоит обратить внимание на поле /CN=server. Его значение отличается от соответствующего поля, использовавшегося при создании сертификата УЦ. Если эти поля совпадают, то клиенты почему-то считают сертификат сервера самоподписанным, насколько я понял. Поэтому лучше CommonName сертификатов УЦ и сервера сделать различными, во избежание недоразумений.

3. Подписываем сертификат в удостоверяющем центре:

Как выяснилось в процессе эксплуатации, некоторые клиенты openvpn, в частности, 2.3, требуют, чтобы сертификат содержал расширения x509v3, в которых было бы явно указано, для чего его можно использовать. Делается это при помощи следующих расширений: keyUsage и extendedKeyUsage. Можно было бы их указывать на этапе создания запроса сертификата, но почему-то на этапе подписания они теряются. Но есть положительный момент: при подписании можно добавить нужные расширения. И момент отрицательный: соответствующий параметр командной строки "-addext" срабатывает только в openssl начиная с версии 1.1.1а.

Поэтому создадим на УЦ два файла с расширениями для серверных и клиентских сертификатов.

Файл server-extensions.txt:

[default]
keyUsage = digitalSignature,keyAgreement
extendedKeyUsage = serverAuth

Файл client-extensions.txt:

[default]
keyUsage = digitalSignature,keyAgreement
extendedKeyUsage = clientAuth

И будем их использовать при подписании.

Сам процесс подписания прост: передаём на Луну файл *.csr, подписываем его в УЦ командой:

openssl x509 \
    -req \
    -days 3650 \
    -in    huhmuh-openvpn.csr \
    -out   huhmuh-openvpn.crt \
    -CA    huhmuh-CA.crt \
    -CAkey huhmuh-CA.key \
    -CAcreateserial \
    -extfile server-extensions.txt

И возвращаем готовый сертификат huhmuh-openvpn.crt с Луны обратно на сервер, где будет жить OpenVPN.

4. Дальше потребуется сгенерировать ещё два файла, они нужны при настройке сервера. Эти файлы создаются так:

Создаём файл с параметрами для протокола Диффи-Хеллмана:

openssl dhparam    -out dh.pem     2048

Создаём приватный ключ для tls-аутентификации:

openvpn --genkey --secret ta.key

Тут интересно, что используется не команда openssl, а сама программа openvpn. У этой самой openvpn оказалось вообще много всяких параметров командной строки, посмотреть их можно командой openvpn --help. Программа живёт в каталоге /sbin или /usr/sbin, эти каталоги в $PATH простых смертных не прописаны, так что если вызывать её из-под непривилегированного пользователя, возможно потребуется указать полный путь: /sbin/openvpn.

Итак, по завершении этого этапа, в нашем распоряжении будут файлы:

huhmuh-CA.crt
huhmuh-openvpn.key
huhmuh-openvpn.crt
dh.pem
ta.key

Эти файлы потребуется сгрузить в каталог /etc/openvpn, туда же скопировать из /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz образец конфигурации, распаковать его командой

gunzip server.conf.gz

При этом получится файл server.conf, и этот файл уже можно править под свои нужды.

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

# тут можно указать, какой адрес использовать,
# но, поскольку мой сервер находится "в глубине" сети,
# то у него один адрес, поэтому я оставил эту настройку закомментированной
;local a.b.c.d

# порт по умолчанию 1194, но можно и сменить
port 32194

# протокол рекомендуют udp, но пусть уж так
proto tcp

dev tun

# наши ключи и сертификаты
ca       huhmuh-CA.crt
cert     huhmuh-openvpn.crt
key      huhmuh-openvpn.key  # This file should be kept secret
dh       dh.pem
tls-auth ta.key     0

topology subnet

# задаём, какой диапазон адресов будет использоваться клиентскими подключениями
# первый адрес, 10.8.0.1, сервер openvpn заберёт себе
server 10.8.0.0 255.255.255.0

# логи и прочая полезная информация.
# в частности, в ipp.txt показываются сопоставления CN клиентских сертификатов и выделенные для них адреса
ifconfig-pool-persist /var/log/openvpn/ipp.txt
status                /var/log/openvpn/openvpn-status.log
log-append            /var/log/openvpn/openvpn.log

# насколько подробным будет лог
verb 6

# с этой опцией клиент будет вынужден весь свой трафик завернуть через openvpn
push "redirect-gateway def1 bypass-dhcp"

keepalive 10 120

# версия 2.3 знает лишь AES-256-CBC, с версии 2.4 лучше применять AES-256-GCM, он надёжнее, говорят
;cipher AES-256-CBC
cipher AES-256-GCM

comp-lzo

# чтобы сервер не работал под рутом - для пущей безопасности
user nobody
group nogroup

persist-key
persist-tun

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

systemctl start openvpn@server

Вот это дополнение, @server, задаёт имя файла конфигурации, который будет использован, т.е., server.conf. Если же взлететь с первого раза не получилось, может выручить запуск сервера командой:

openvpn --config /etc/openvpn/server.conf

И медитация над логами из /var/log/openvpn/ в попытке разобраться, что же пошло не так...

Создание файла подключения клиента

Если сервер, наконец, удалось каким-то чудом запустить, пришло время для клиента. Все настройки клиента - и конфигурация, и ключ, и сертификаты - удобно сливаются в единый файл *.ovpn.

1. Создаём приватный ключ клиента:

openssl genrsa    -des3    -out huhmuh-alice.key    2048

Ключ шифруем (опция "-des3") - пусть клиент при установлении подключения вводит пароль.

2. Создаём запрос сертификата для клиента:

openssl req \
    -new \
    -key huhmuh-alice.key \
    -out huhmuh-alice.csr \
    -subj "/emailAddress=alice@example.com/C=RU/ST=Oblastnaya oblast/L=Default City/O=Home/OU=Kitchen/CN=alice"

3. Подписываем сертификат клиента в удостоверяющем центре:

openssl x509 \
    -req \
    -days 3650 \
    -in    huhmuh-alice.csr \
    -out   huhmuh-alice.crt \
    -CA    huhmuh-CA.crt \
    -CAkey huhmuh-CA.key \
    -CAcreateserial \
    -extfile client-extensions.txt

В итоге для клиентского подключения мы приготовили файлы:

huhmuh-CA.crt
huhmuh-alice.key
huhmuh-alice.crt

Из этих файлов и файла /etc/openvpn/ta.key можно собрать файл подключения. Проще всего это сделать примерно таким скриптом:

#!/bin/sh

FNAME=huhmuh-alice.ovpn

echo "client
dev tun
proto tcp
remote example.com 32194
resolv-retry infinite
remote-cert-tls server
auth SHA1
cipher AES-256-GCM
tls-client
key-direction 1
persist-key
persist-tun
resolv-retry infinite
nobind
comp-lzo
verb 3"				>  $FNAME

echo "<ca>"			>> $FNAME
cat ./huhmuh-CA.crt		>> $FNAME
echo "</ca>"			>> $FNAME

echo "<cert>"			>> $FNAME
cat ./huhmuh-alice.crt		>> $FNAME
echo "</cert>"			>> $FNAME

echo "<key>"			>> $FNAME
cat ./huhmuh-alice.key		>> $FNAME
echo "</key>"			>> $FNAME

echo "<tls-auth>"		>> $FNAME
cat /etc/openvpn/ta.key		>> $FNAME
echo "</tls-auth>"		>> $FNAME

Тут надо помнить пару моментов. Во-первых, /etc/openvpn/ta.key - секретный (хотя как секретный, клиенту же передаётся?), поэтому доступен лишь под рутом. И, во-вторых, соответствующие настройки должны совпадать с настройками сервера. Например, если в конфиге сервера стоит "cipher AES-256-CBC", то и у клиента должно быть то же самое, "cipher AES-256-CBC". Про "remote example.com 32194", думаю, упоминать смысла нет - и так понятно, что это адрес сервера и открытый на нем порт.

Если всё прошло нормально, то в нашем распоряжении оказывается файл huhmuh-alice.ovpn, который можно отдавать клиенту, чтобы он с ним подключался к нашему серверу. Клиентов для OpenVPN хватает, даже под андроидом есть некий OpenVPN Connect, так что тип операционной системы использование этого инструмента не лимитирует.

(NB: для WindowsXP, как оказалось, последняя версия клиента: 2.3.18. При её настройке из скопированного в C:\Program Files\OpenVPN\config файла .ovpn пришлось удалить строку set CLIENT_CERT 0. Также эта версия начала кочевряжиться при отсутствии Key Usage в расширениях серверного сертификата, о чем было упомянуто выше. Помогает либо добавление требуемого расширения, либо убирание строки remote-cert-tls server в файле *.ovpn)

Настройка netfilter на сервере

В случае успеха клиенты, подключенные к серверу, смогут добраться лишь до этого самого сервера. Попытка попасть на какие-то другие хосты в локальной сети окажется неудачной. Для того, чтобы клиенты получили возможность пройти дальше сервера, требуется использовать nat. В принципе, можно сконфигурировать openvpn так, чтобы он позволил своим клиентам получать адреса из диапазона локальной сети. Но, поскольку в вышеприведенной конфигурации клиенты получают адреса из диапазона 10.8.0.0/24, а остальная сеть живёт в диапазоне 192.168.0.0/24, то в данном случае придётся воспользоваться iptables. Минимальная конфигурация, позволяющая это осуществить, выглядит так:

#!/bin/sh

# подключаем nf_conntrack и разрешаем проброс пакетов
modprobe nf_conntrack
sysctl net.ipv4.ip_forward=1


# очищаем таблицы nat и filter
iptables -F -t nat
iptables -F -t filter

iptables -X -t nat
iptables -X -t filter


# разрешаем работать исходящим и уже установленным подключениям
iptables -t filter -A INPUT   -m conntrack --ctstate     ESTABLISHED,RELATED -j ACCEPT
iptables -t filter -A FORWARD -m conntrack --ctstate     ESTABLISHED,RELATED -j ACCEPT
iptables -t filter -A OUTPUT  -m conntrack --ctstate NEW,ESTABLISHED,RELATED -j ACCEPT


# разрешаем доступ к серверу по перечисленным портам (не один же openvpn у нас тут крутится)
iptables -t filter -A INPUT -p tcp -m multiport --dports 22,67,68,80,443,32194 -j ACCEPT
iptables -t filter -A INPUT -p udp -m multiport --dports 67,68                 -j ACCEPT
# 22 -ssh, 67 - dhcp, 80,443 - https, 32194 - openvpn


# в трафик из подсети 10.8.0.0/24 подставляем адрес сервера в локальной сети, 192.168.0.2, в качестве источника
iptables -t filter -A FORWARD     -s 10.8.0.0/24  -j ACCEPT
iptables -t nat    -A POSTROUTING -s 10.8.0.0/24  -j SNAT    --to-source 192.168.0.2


# остальные пакеты, не прошедшие правила, отбрасываем (кроме исходящих)
iptables -t filter -P INPUT   DROP
iptables -t filter -P FORWARD DROP
iptables -t filter -P OUTPUT  ACCEPT

Настройка клиента на ubuntu

Подключение к серверу с использованием имеющегося файла huhmuh-alice.ovpn выглядит так:

sudo openvpn --config ./huhmuh-alice.ovpn

При этом, если на сервере прописана опция redirect-gateway, весь трафик пойдёт через этот vpn-канал. Иногда это не очень удобно - например, мы сидим в большом инете и хотим подцепться к корпоративной сети, но при этом не желаем, чтобы развлекательные сайты заворачивались через служебную прокси. Это решается следующим образом.

Оказывается, в openvpn есть две внутренние константы, vpn_gateway и net_gateway. Они содержат адрес vpn-шлюза и шлюза локальной сети соответственно, и с их помощью можно задавать нужные маршруты. В файл *.ovpn добавляем строку:

route 192.168.0.0 255.255.255.0 vpn_gateway

Клиента запускаем командой:

sudo openvpn --pull-filter ignore redirect-gateway --config ./huhmuh-alice.ovpn

И весь трафик будет ходить по-старому, за исключением сети 192.168.0.0/24 - общение с ней пойдёт через vpn.

Литература

Установка и настройка OpenVPN-сервера в Debian
Конспект по установке OpenVPN
Установка и настройка сервера OpenVPN в Ubuntu 20.04
OpenSSL Quick Reference Guide
Create SSL certificate non-interactively
Генерирование сертификатов для OpenVPN с помощью Easy-RSA 3
x509v3_config
OpenVPN Certificate does not have key usage extension
OpenSSL CA keyUsage extension
IX509ExtensionEnhancedKeyUsage interface (certenroll.h)
Class ExtendedKeyUsage
Connecting to Access Server with Linux
Ignoring redirect-gateway

воскресенье, 7 февраля 2021 г.

Ubuntu: установка на программный raid+uefi

До недавнего времени мне верой и правдой служил компьютер под управлением убунты, купленный в 2010 году и с тех пор не обновлявшийся (только HDD добавил, и память дополнительную вставил, с 2Гб до 6Гб, когда началась эта чехарда с коронавирусом и zoom-ом на удалёнке). Но время не стоит на месте, программы становятся всё требовательнее, да и менеджер пакетов убунты пару лет назад стал сбоить, в общем, пришла пора подумать о замене.

В прожорливые игры я не играю, фильмы в высоком качестве не смотрю, единственное из ресурсоёмких задач - это докер и виртуальные машины. Ну, и квартира маленькая, так что живём мы с этим оборудованием, что называется, бок о бок. Поэтому основными критериями выбора стали такие:
1) отказоустойчивость
2) малошумность
3) сносное быстродействие

Первый критерий привёл к мысли, что нужна материнская плата с RAID на борту, второй - что нужен процессор с низким тепловыделением, а третий - что диски будут SSD. Тут надо признать, что в железе я не разбираюсь совершенно. Поэтому сборка работоспособной машины превратилась в увлекательный квест.

Покопался на сайте одного известного магазина, повыбирал комплектующие на свой вкус, купил, собрал - не работает. Выяснилось, что в современном мире слова "DDR4" и "AM4" гарантируют только, что память и процессор удастся запихнуть в соответствующие слоты, а их работоспособность с данной конкретной материнской платой никто не обещал. К счастью, недостаток знаний удалось отчасти скомпенсировать финансовыми вливаниями, но изучать списки совместимости, искать и докупать на замену пришлось чуть ли не всё.

В итоге я стал счастливым обладателем материнской платы ASRock B450 Pro4, процессора Athlon 200GE, двух плашек ОЗУ A-Data XPG Gammix D10 [AX4U266638G16-SBG] (8+8 ГБ) и двух M.2 SSD A-Data XPG SX6000 Lite [ASX6000LNP-128GT-C] (128+128 ГБ) - для RAID-а. На процессор повесил здоровенный кулер DEEPCOOL REDHAT, вентилятор прицеплять не стал, машина получилась достаточно тихой, с одним вентилятором в блоке питания и непривычно пустым системным блоком в корпусе DEXP DC-101B - ни тебе дисководов, ни сидиромов, ни жестких дисков... Прогресс, однако. Осталось дело за малым - поднять RAID и установить операционную систему.

Первым делом включил raid, покопавшись в настройках материнской платы. К сожалению мануал, рассказывающий о том, как это делается, попался под руку не сразу. А всё оказалось просто - заходим в UEFI Setup Utility и там включаем пару опций:

Boot -> CSM (Compatibility Support Module) -> Disabled
Advanced -> AMD PBS -> NVMe RAID mode -> Enabled
Advanced -> Storage Configuration -> SATA Mode -> RAID
После перезагрузки в UEFI Setup Utility появится дополнительный пункт "RAIDXpert2 Configuration Utility", и там уже можно объединить два диска в массив. Правда, оказалось, что не любые два диска в этом пункте меню видны, и не зря на одном из слотов материнки была наклейка "Ultra M.2". Выяснилось, что и M.2 диски бывают разные, и в слот с этой наклейкой следует пихать тот, у которого есть опция NVMe. Второму M.2 разъёму, правда, не важно, что за диск в него подсунут, с NVMe или без, а вот первый в этом плане привередлив. Так или иначе, с этой проблемой удалось справиться, вот только это не сильно помогло: при установке убунта упорно продолжала видеть мой RAID-массив как два отдельных диска.

Пришлось изучать вопрос дальше, пока в одном из обсуждений попалась ссылка на статью, рассказывающую о разных вариантах реализации RAID. Есть Hardware RAID - когда одновременность чтения-записи на диски обеспечивается на аппаратном уровне, есть Software RAID - когда вся кухня реализована на уровне драйверов операционной системы, и есть Fake RAID - когда операционка вроде бы видит RAID, а на самом деле он реализовывается при помощи программного обеспечения, зашитого в материнскую плату. И, судя по цене материнки, мой случай именено такой. В то же время куча форумов пестрит утверждениями, что под линуксом все эти низкоуровневые RAID не нужны, а пользуйтесь лучше программными RAID-ами, граждане. Поэтому я, скрепя сердце, свой с трудом созданный массив размонтировал:

Boot -> CSM (Compatibility Support Module) -> Disabled
Advanced -> AMD PBS -> NVMe RAID mode -> Disabled
Advanced -> Storage Configuration -> SATA Mode -> AHCI
и приступил к третьей части - установке операционной системы.

Установка операционной системы меня тоже не порадовала. Выяснилось, что установщик моей любимой XUbuntu из коробки RAID не поддерживает, поэтому - либо качайте и ставьте сервер, либо делайте пару дополнительных пассов руками. Кроме того, наступило будущее, и на смену BIOS+MBR пришел UEFI+GPT. В моём случае будущее выразилось в том, что все 128 Гб превратить в RAID-1 не удастся: вышеупомянутая опция "Boot -> CSM (Compatibility Support Module) -> Disabled" приводит к тому, что при загрузке UEFI ищет не MBR, а раздел, носящий имя ESP. Этот раздел размечен fat32 и помечен флагом efi, на нём, собственно, и хранятся инструкции по дальнейшей загрузке операционной системы. При этом обнаружился приятный бонус - оказывается, современные версии линуксового загрузчика GRUB умеют поддерживать в идентичном состоянии несколько ESP, причудливо разбросанных по разным дискам. Поэтому моё первоначальное стремление сделать так:

Disk1: [RAID-1: [ESP...] [всё остальное............] ]
Disk2: [ -"- ........................................]
превратилось в:
Disk1: [ESP...] [RAID-1: [всё остальное............] ]
Disk2: [ESP...] [ -"- ...............................]
И про это самое "всё остальное" следует сказать особо.

В принципе, если массив поднят, можно запускать инсталлятор убунты, разбивать им свободное место на разделы и вообще двигаться дальше. Но под линуксом есть ещё одна полезная прослойка, которая называется LVM. Штука эта, Logical Volume Manager, очень интересная. Результат её действия таков, что логические тома, т.е., "разделы", видимые в файловой системе, на самом деле не являются привычными разделами, в виде единого целого хранящимися на диске, а являются мозаикой, элементы которой собираются из кусочков, раскиданных по разным дискам и прочим устройствам. Эти логические тома допускают, по слухам, большую гибкость в настройке, в частности, их размер можно менять как угодно, расширять за счет добавления в машину новых дисков и т.п. Поэтому итоговая структура дисков моего нового компьютера выглядит так:

Disk1: [ESP...] [RAID-1: [LVM: (Том: /.......) (Том: swap.......) (Том: /home.......) ] ]
Disk2: [ESP...] [ -"- ..................................................................]
ну, или в виде вывода команды lsblk -a:
$ lsblk -a

nvme0n1          259:0    0 119,2G  0 disk         (первый SSD A-Data XPG SX6000 Lite)
├─nvme0n1p1      259:2    0   128M  0 part             (efi раздел)
└─nvme0n1p2      259:3    0 119,1G  0 part             (раздел под всё остальное)
  └─md0            9:0    0 119,1G  0 raid1                (raid массив)
    ├─myVG-rootv 253:0    0    40G  0 lvm   /                  (логический том)
    ├─myVG-swapv 253:1    0    16G  0 lvm   [SWAP]             (логический том)
    └─myVG-homev 253:2    0  63,1G  0 lvm   /home              (логический том)

nvme1n1          259:1    0 119,2G  0 disk         (второй SSD A-Data XPG SX6000 Lite)
├─nvme1n1p1      259:4    0   128M  0 part             (efi раздел)
└─nvme1n1p2      259:5    0 119,1G  0 part             (раздел под всё остальное)
  └─md0            9:0    0 119,1G  0 raid1                (raid массив)
    ├─myVG-rootv 253:0    0    40G  0 lvm   /                  (логический том)
    ├─myVG-swapv 253:1    0    16G  0 lvm   [SWAP]             (логический том)
    └─myVG-homev 253:2    0  63,1G  0 lvm   /home              (логический том)

Теперь, наконец, опишу последовательность шагов, приведших к такому результату.

0. Создание инсталляционной флэшки

Берём понравившийся образ, например, отсюда https://mirror.yandex.ru/ubuntu-cdimage/xubuntu/releases/20.10/release/, подключаем флэшку - будем считать, что она села на /dev/sdh - и заливаем:

sudo dd if=xubuntu-20.10-desktop-amd64.iso of=/dev/sdh bs=1M

1. Подготовка к установке

Загружаемся с полученной флэшки, выбираем работать без установки и попадаем на рабочий стол. Там запускаем терминал, устанавливаем boot-repair (на всякий случай, мне, помнится, так и не понадобился):

sudo add-apt-repository -y ppa:yannubuntu/boot-repair
sudo apt update
apt install boot-repair
Устанавливаем средство для управления программными RAID массивами:
sudo apt install mdadm
Размечаем диски:
sudo fdisk /dev/nvme0n1
sudo fdisk /dev/nvme1n1
так, чтобы lsblk -a рисовал примерно такую картинку:
$ lsblk -a

nvme0n1          259:0    0 119,2G  0 disk
├─nvme0n1p1      259:2    0   128M  0 part
└─nvme0n1p2      259:3    0 119,1G  0 part
nvme1n1          259:1    0 119,2G  0 disk
├─nvme1n1p1      259:4    0   128M  0 part
└─nvme1n1p2      259:5    0 119,1G  0 part
Размечаем ESP под fat:
sudo mkfs -t fat -F 32 /dev/nvme0n1p1
sudo mkfs -t fat -F 32 /dev/nvme1n1p1
Создаём RAID:
mdadm --create /dev/md0 --metadata=0.90 --level 1 --raid-disks 2 /dev/nvme0n1p2 /dev/nvme1n1p2
этот процесс небыстрый, нужно подождать, пока диски синхронизируются, текущий статус массива можно глянуть командой cat /proc/mdstat. Когда всё закончится, настраиваем LVM. Передаём под его отвественность наш свежесозданный раздел /dev/md0:
pvcreate /dev/md0
Создаём группу томов, в которую включаем /dev/md0:
vgcreate myVG /dev/md0
Создаём логические тома:
lvcreate -L 40G myVG -n rootv
lvcreate -L 16G myVG -n swapv
lvcreate -l +100%FREE myVG -n homev
После этого конфигурация приобретёт законченный вид, и можно приступать к собственно процессу установки.

2. Процесс установки

Сама установка сложностей не представляет - запускаем процесс по ярлыку на рабочем столе, аккуратно указываем соответствие точек монтирования /, /home логическим устройствам и расположение раздела подкачки. По окончании процесса установки на перезагрузку, однако, не соглашаемся - надо на свежепоставленную систему взгромоздить mdadm, использующийся для программного RAID. Поэтому выбираем опцию "Продолжить работу" и возвращаемся в терминал.

3. Дополнительная настройка

Монтируем корень нашей новой системы и подготавливаемся к тому, чтобы в эту новую систему переключиться:

sudo mount /dev/myVG/rootv /mnt
mount -o bind /dev /mnt/dev
mount -o bind /dev/pts /mnt/dev/pts
mount -o bind /sys /mnt/sys
mount -o bind /proc /mnt/proc
cat /etc/resolv.conf >> /mnt/etc/resolv.conf
Переключаемся:
chroot /mnt
Доустанавливаем в свежеустановленную систему необходимые пакеты:
apt install mdadm
apt install grub-efi-amd64
apt remove grub-efi-amd64-signed
Включаем показ меню GRUB при запуске системы:
vi /etc/grub.d/10_linux # изменить значение quick_boot на 0
И, наконец, перезагружаемся.

4. Настройка GRUB для работы с двумя копиями ESP

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

dpkg-reconfigure grub-efi-amd64
там в какой-то момент конфигуратор выведет список найденных ESP и предложит отметить галочками, какие из них синхронизировать. Правда, говорят, эта опция доступна только с недавних пор - дистрибутивы, выпущенные ранее 2019 года, такой возможности не имеют. Я поставил обе галочки напротив nvme0n1p1 и nvme1n1p1. Буду надеяться, GRUB не подведёт.

Литература:

Установка Linux на software raid
Install Ubuntu 18.04 desktop with RAID 1 and LVM on machine with UEFI BIOS
How to install Ubuntu server with UEFI and RAID1 + LVM
Как установить Ubuntu на программный RAID-1
Лабораторная работа: настраиваем lvm, raid на linux

четверг, 28 января 2021 г.

Ubuntu: при подключении через rdp ошибка CredSSP required

С незапамятных времён пользовался rdesktop для подключения к windows-машинам:

rdesktop -g 1280x972 -r disk:shared=~/shared host:port

Но с windows 10 возникает проблема: Failed to connect, CredSSP required by server (check if server has disabled old TLS versions, if yes use -V option). В принципе, можно это поправить: Панель управления -> Система и безопасность -> Система -> Защита системы -> вкладка "Удаленный доступ" -> снять галочку с "Разрешить подключения только с компьютеров, на которых работает удаленный рабочий стол с проверкой подлинности на уровне сети (рекомендуется)", но получается как-то неизящно.

Оказывается, есть вариант использовать другой клиент, xfreerdp. В убунте устанавливается из репозитория командой sudo apt-get install freerdp2-x11. Ну, и параметры командной строки немного другие:

xfreerdp /w:1280 /h:972 /u:"domain\\username" /drive:shared /v:host:port

Не без багов (например, не работает /drive:name,shared позволяющее присвоить шаре нужное имя), но работает.

четверг, 21 января 2021 г.

Антивирус Касперского и внедрение скриптов

Оказывается, KIS перехватывает веб-трафик и внедряет на страницы свой скрипт примерно такого вида (см. ниже), отчего иногда другие скрипты, написанные альтернативно одарёнными разработчиками, перестают нормально функционировать:

<script type="text/javascript" src="https://gc.kis.v2.scr.kaspersky-labs.com/01234567-8901-2345-6789-012345678901/main.js?attr=abcdefghijklmnopqrstuvwxyz" charset="UTF-8"></script>

Чтобы KIS отучить от этого нехорошего поведения, нужно покопаться в настройках - снять галочку вот тут:

Settings -> Additional -> Network -> Inject scripts into web traffic to interact with web pages

Литература:
How to disable Kaspersky Antivirus javascript injection?