[{"content":" 🚧 Будьте внимательны! Невнимательные действия могу привести к блокировки системы\u0026hellip; и тогда придется серьезно запарится. У меня YubiKey, openSUSE, SDDM, DMS Quickshell, я покажу на этом примере.\nУстановка pam_u2f:\nsudo zypper install pam_u2f Как работает файл с ключами Все ключи хранятся в одном общем файле /etc/Yubico/u2f_keys. В формате одна строка на пользователя, а все ключи этого пользователя идут в той же строке через двоеточие (упрощенно):\n1 2 user:key1:key2:key3 root:key1:key2:key3 Регистрация не привязана к имени юзера, а указывается юзеру, поэтому отдельно регистрировать ключ для root не нужно.\nА так же в ~/.config/Yubico/u2f_keys \u0026ndash; только строка юзера. Его использует например DMS, KDE и тд., то что работает от вашего пользователя, а не от root.\nТо есть:\n/etc/Yubico/u2f_keys \u0026ndash; sudo, su, su-l, в общем система. ~/.config/Yubico/u2f_keys \u0026ndash; кастомные юзерские сервисы, лок скрины, и тп. Добавляем ключи Создаем скрипт и даем права на выполнение 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 sudo tee /usr/local/bin/u2f-add-key \u0026gt; /dev/null \u0026lt;\u0026lt; \u0026#39;EOF\u0026#39; #!/bin/bash set -euo pipefail f=/etc/Yubico/u2f_keys uf=$HOME/.config/Yubico/u2f_keys me=$(id -un) put() { local run=$1 file=$2 u=$3 if $run awk -F: -v u=\u0026#34;$u\u0026#34; -v add=\u0026#34;$add\u0026#34; \u0026#39;$1 == u \u0026amp;\u0026amp; index($0, add) { found = 1 } END { exit !found }\u0026#39; \u0026#34;$file\u0026#34;; then return fi $run awk -v u=\u0026#34;$u\u0026#34; -v add=\u0026#34;$add\u0026#34; \u0026#39; BEGIN { FS = OFS = \u0026#34;:\u0026#34; } $1 == u { $0 = $0 \u0026#34;:\u0026#34; add; found = 1 } { print } END { if (!found) print u \u0026#34;:\u0026#34; add } \u0026#39; \u0026#34;$file\u0026#34; | $run tee \u0026#34;$file.new\u0026#34; \u0026gt; /dev/null $run mv \u0026#34;$file.new\u0026#34; \u0026#34;$file\u0026#34; } sudo mkdir -p \u0026#34;$(dirname \u0026#34;$f\u0026#34;)\u0026#34; sudo touch \u0026#34;$f\u0026#34; echo \u0026#34;Make sure your key is plugged in, then touch it when it blinks (or when a bush catches fire)...\u0026#34; reg=$(pamu2fcfg -u \u0026#34;$me\u0026#34;) add=${reg#*:} if [ -z \u0026#34;$reg\u0026#34; ] || [ \u0026#34;$add\u0026#34; = \u0026#34;$reg\u0026#34; ]; then echo \u0026#34;Registration failed\u0026#34; \u0026gt;\u0026amp;2 exit 1 fi put sudo \u0026#34;$f\u0026#34; \u0026#34;$me\u0026#34; if [ \u0026#34;$me\u0026#34; != root ]; then put sudo \u0026#34;$f\u0026#34; root fi sudo chown root:root \u0026#34;$f\u0026#34; sudo chmod 600 \u0026#34;$f\u0026#34; if [ \u0026#34;$me\u0026#34; != root ]; then mkdir -p \u0026#34;$(dirname \u0026#34;$uf\u0026#34;)\u0026#34; touch \u0026#34;$uf\u0026#34; put command \u0026#34;$uf\u0026#34; \u0026#34;$me\u0026#34; chmod 600 \u0026#34;$uf\u0026#34; fi echo \u0026#34;Done. Keys per user in $f:\u0026#34; sudo awk -F: \u0026#39;{ print \u0026#34; \u0026#34; $1 \u0026#34;: \u0026#34; NF-1 }\u0026#39; \u0026#34;$f\u0026#34; if [ \u0026#34;$me\u0026#34; != root ]; then echo \u0026#34;Keys in $uf:\u0026#34; awk -F: \u0026#39;{ print \u0026#34; \u0026#34; $1 \u0026#34;: \u0026#34; NF-1 }\u0026#39; \u0026#34;$uf\u0026#34; fi EOF sudo chmod +x /usr/local/bin/u2f-add-key Запускаем от обычного пользователя (без sudo):\nu2f-add-key и касаемся ключа.\nЕсли нужны доп. ключи, то втыкаете следующий и снова запускаете скрипт.\nПроверяем:\nsudo cat /etc/Yubico/u2f_keys \u0026amp;\u0026amp; echo \u0026amp;\u0026amp; cat ~/.config/Yubico/u2f_keys Должно быть две строки (ваш юзер и root), а так же один ключ вашего юзера. Выходим из системы и заходим снова (необязательно, но желательно).\n💡 Если нужно убрать ключ, откройте файлы /etc/Yubico/u2f_keys/~/.config/Yubico/u2f_keys и удалите его фрагмент между двоеточиями в строке/обеих строках.\nЧтобы убрать все ключи, просто удалите файлы:\nsudo rm -rf /etc/Yubico/u2f_keys ~/.config/Yubico/u2f_keys Далее настройка сервисов.\nsudo cp /usr/lib/pam.d/su /etc/pam.d/su sudo nano /etc/pam.d/su Добавить:\n1 auth sufficient pam_u2f.so cue authfile=/etc/Yubico/u2f_keys Выше common-auth, но ниже самого первого auth (если есть). Пара примеров:\n1 2 3 4 5 6 7 8 9 10 auth sufficient pam_rootok.so auth sufficient pam_u2f.so cue authfile=/etc/Yubico/u2f_keys auth include common-auth # --- # auth sufficient pam_u2f.so cue authfile=/etc/Yubico/u2f_keys auth include common-auth # --- # auth requisite pam_nologin.so auth sufficient pam_u2f.so cue authfile=/etc/Yubico/u2f_keys auth substack common-auth Нужно, чтобы аппаратный ключ был sufficient и стоял выше common-auth. Иначе оно будет требовать пароль + ключ.\n💡 Если вы хотите секьюрно \u0026ndash; пароль + ключ, то строка должна быть после common-auth и иметь required. Но в таком случае лучше иметь пару ключей, и оба их нужно добавить в систему, иначе если потеряете/сломаете, то все\u0026hellip; Проверить:\nsu Если ключ подключен, то попросит коснуться ключа (подойдет любой из добавленных). Если же нет, то попросит ввести пароль: или-или.\nПовторяете то же самое для:\nsu-l sudo sddm (ваш Display Manager) В случае чего вернуть назад можно, просто удалив файлы, что были скопированы:\nsudo sh -c \u0026#39;cd /etc/pam.d \u0026amp;\u0026amp; rm su su-l sudo sddm \u0026amp;\u0026amp; ls\u0026#39; Так же после обновления ОС оригинальные файлы могут поменяться (обычно очень не часто). Проверить:\n1 2 3 4 ARGS=(/usr/lib/pam.d/su /etc/pam.d/su); command -v kompare \u0026gt; /dev/null \u0026amp;\u0026amp; kompare \u0026#34;${ARGS[@]}\u0026#34; || { echo -e \u0026#34;\\n- su\u0026#34;; diff \u0026#34;${ARGS[@]}\u0026#34;; } ARGS=(/usr/lib/pam.d/su-l /etc/pam.d/su-l); command -v kompare \u0026gt; /dev/null \u0026amp;\u0026amp; kompare \u0026#34;${ARGS[@]}\u0026#34; || { echo -e \u0026#34;\\n- su-l\u0026#34;; diff \u0026#34;${ARGS[@]}\u0026#34;; } ARGS=(/usr/lib/pam.d/sudo /etc/pam.d/sudo); command -v kompare \u0026gt; /dev/null \u0026amp;\u0026amp; kompare \u0026#34;${ARGS[@]}\u0026#34; || { echo -e \u0026#34;\\n- sudo\u0026#34;; diff \u0026#34;${ARGS[@]}\u0026#34;; } ARGS=(/usr/lib/pam.d/sddm /etc/pam.d/sddm); command -v kompare \u0026gt; /dev/null \u0026amp;\u0026amp; kompare \u0026#34;${ARGS[@]}\u0026#34; || { echo -e \u0026#34;\\n- sddm\u0026#34;; diff \u0026#34;${ARGS[@]}\u0026#34;; } 📝 В SDDM, чтобы использовать ключ \u0026ndash; нужно нажать Enter. После входа в систему по ключу вас может ожидать неприятность на некотором софте:\nAuthentication required - The login keyring did not get unlocked when you logged into your computer\nДва самых безопасных решения с точки зрения буквально безопасности:\nВводить пароль, это все равно один раз после входа в систему Отключить аппаратный ключ для DM и вводить пароль как обычно, это все равно один раз на вход в систему На sudo это никак не повлияет.\nДругой вариант, это отключение шифрования keyring, не делайте так.\nDMS В настройках Lock Screen включаем Enable security key authentication, откроется терминал с выбором аутентификации, выберите что-то, я предпочитаю sudo и ввести пароль (он же ключ если уже настроили). Подробнее здесь и тут.\n‎ ","permalink":"https://hv8.pages.dev/blog/yubikey-hardware-key-as-password-alternative-on-linux/","summary":"Настройка YubiKey на openSUSE для sudo, а также входа в систему.","title":"Замена пароля аппаратным ключом YubiKey на Linux"},{"content":"📜 Изменения 01 нояб. 2026: Добавлено: Больше бенчмарков 2026 Октябрь 28 окт. 2026 Обновлено: Доп. информация про Зависание при выключение/перезагрузки VM и 100% CPU Добавлено: Проблема X в Windows из-за Y 15 окт. 2026 Обновлено: Периферия \u0026ndash; Звук 2026 Июль-Август 21 авг. 2026 Добавлено: Проброс дополнительных устройств в VM 20 июл. 2026 Обновлено: Доп. информация про TPM Добавлено: Как обновлять QEMU/KVM udev симлинки (объединение устройств в одно) 📝 Дисклеймеры / Информация 🧠 Про ИИ.\nДа, я использовал ИИ, и нет, ИИ не писал этот текст.\nТекст написан от и до \u0026mdash; мной.\nИИ использовался для поиска и проверки информации, а также написания скриптов. Но с одним ключевым нюансом \u0026ndash; я понимаю что я делаю (ну, почти), а не бездумно копирую и вставляю.\nЭто НЕ компиляция информации, это ровно то, что я сделал у себя.\n👀 Это довольно сложная тема, и сделать так, чтобы работало у всех\u0026hellip; я не знаю, как.\nТо, что вы тут прочитаете это одна конкретная тропинка, одна, но я их прошел десятки, перепробовал ОЧЕНЬ много всего. Поэтому вам нужны хотя бы базовые знания.\nЭто длинный текст, тут полно команд и скриптов. Я все это делал и одновременно писал и описывал это, и далеко не один день.\nЕсли вы найдете тут ошибку, у вас что-то не будет работать хотя ТОЧНО должно работать \u0026ndash; свяжитесь со мной.\nЕсли у вас возникнут проблемы с XML, то вот мой полный XML файл.\nДругое железо (не описанное здесь), другой дистрибутив, другое окружение/WM, что-то еще другое \u0026mdash; не повод писать. Хотя\u0026hellip; я возможно посмотрю.\nПредисловие Если вы тут оказались, то:\nВас сюда послали (не завидую вам) Вы знаете, о чем речь Но если вдруг ни то ни другое, для тех, кто не знает, что такое VFIO, поясню.\nVFIO (Virtual Function I/O) \u0026mdash; это фреймворк/драйвер ядра Linux, обеспечивающий безопасный прямой доступ к аппаратному обеспечению из пространства пользователя. Если простыми словами, это способ передать деталь ПК напрямую внутрь виртуальной машины, то есть PCI-passthrough. Ну что такое PCI-то объяснять не надо, так?\nИ о чем же речь? Скажем, вот у вас Windows, на Windows вы например играете в игры. Windows использует ваше железо, пусть будет видеокарта. И использует хорошо, потому что работает с видеокартой напрямую. Но что если вы не хотите использовать Windows, а хотите Linux, и по какой-то причине, не хотите запускать игры на Linux или хотите запускать игры на Windows; или вам нужен Adobe, CAD и др.\nОчевидное решение dual-boot! Штоб его черт побрал. Это не круто, это не интересно, это медленно.\nДругое очевидное решение \u0026ndash; виртуализация. Установить виртуальную машину с Windows в Linux. Но тогда проблема, виртуализация:\nHOST (Linux) [железка] ↓ гипервизор/паравиртуализация (VirtIO) ↓ GUEST (Windows) [вирт. железка] Это такой них*евый слой жира между железкой и ОС (с VirtIO слой потоньше), I/O (Input/Output) в дерьме, мы в дерьме, все лагает. Не хорошо.\nДля этого и существует VFIO, но оно мутировало из какой-то там технологии в уже пацанское понятие категорию/топик, что может затрагивать не только сам по себе VFIO по определению, а нечто большее, о чем и будет тут речь. Вот и получается:\nHOST (Linux) [железка (была тут)] ↓ GUEST (Windows) [железка (стала тут)] Круто, да?\nВ этом тексте я покажу, как я настроил KVM на Linux openSUSE Tumbleweed от и до + доп. фичи (Quality-of-Life). Из главного это разумеется проброс и/или эффективное использование:\nSSD GPU CPU RAM В самом начале, имейте в виду, у меня есть iGPU и dGPU и текст писался именно под такой сценарий. Если у вас нет двух GPU, iGPU + dGPU или dGPU + dGPU, вам этот текст не подойдет. И читать его стоит в таком случае, разве что ради общего развития и скриптов.\nНу и важно упомянуть, если вы это читаете с четким намерением и хотением сделать это, то вероятно вы морально готовы к этому, и у вас есть железо. Разумеется слабое железо будет не очень, но чисто технически чтобы сделать, конкретно в данном случае, решает не мощь, а количество \u0026ndash; много ОЗУ, ядер и в идеале отдельный диск.\nНЕ наличие второй GPU в данном тексте не обсуждается, там совершенно другой подход, потому что с ОДНОЙ GPU вы \u0026ldquo;используете\u0026rdquo; ЛИБО хост, ЛИБО гость, а в данном тексте расчет на и то, и другое, одновременно.\n🚧 В тексте описывается AMD CPU + NVIDIA GPU, если у вас процессор Intel \u0026ndash; проблем не возникнет, там мало отличий и я их указал. Но если у вас AMD GPU, то вам придется думать, думать и гуглить, потому что у меня нету AMD GPU чтобы проверить, что и как, чтобы сказать точно, как надо. Итак. Я выбрал openSUSE Tumbleweed + KDE Plasma. Почему? Нам нужны самые новые релизы всего и вся \u0026ndash; rolling-release схема, чтобы сделать этот трюк с виртуалкой с производительностью 1:1 к голому железу. Debian и прочие LTS дистрибутивы не очень подходят.\nОчевидный вариант \u0026ndash; это Arch. Разработчик выкатил апдейт софта \u0026ndash; вы его установили, то что надо. Но из-за этого Arch часто ломается, и приходится мониторить новостную ленту обновлений на предмет \u0026ldquo;а не сломается ли моя система после апдейта и что я должен сделать руками\u0026rdquo;, не круто.\nЕсть Void, это как Arch, только обновления автоматически тестируются, вероятность, что система ляжет после обновления сильно меньше. Но Void использует runit вместо systemd, для кого-то это плюс, но systemd мегапопулярен, все делается под него, вам оно надо учитывая сложность темы? Ну и еще я слышал там в основном старье/скудные репозитории, все новое нужно собирать ручками.\nИ третий вариант \u0026mdash; openSUSE Tumbleweed, это как Void, но с systemd и новейшим софтом, а также встроенным GUI приложением YaST через которое можно настроить систему и установить KVM буквально в один клик.\nНу, а KDE Plasma, потому что она самая навороченная и простая. На первое время + тестов \u0026ndash; самое оно. На момент написания этого текста только в KDE Plasma нормально работает 4K HDR 320 Hz, или типа того, возможно кому-то это важно.\nИ все-все будет описано, сказано и показано в контексте Tumbleweed и KDE Plasma. Потому если у вас другие distro/DE/WM и вы вообще не шарите за Linux и ни разу с этим чудом не еб*лись \u0026ndash; не делайте этого, по крайней мере на своей рабочей ОС.\nЕсли же вы шарите, и у вас НЕ KDE Plasma ИЛИ вас интересует исключительно холодный проброс dGPU \u0026ndash; прочтите это.\nВведение Про мониторы Подумайте о том, как будете смотреть на Windows. Есть конечно Looking Glass, и я даже покажу, как его настроить, но для игр, особенно экшен игр, это ужасно + оверхед dGPU. В моем случае 2 монитора (оба FULLHD):\nХост:\nОсновной \u0026ndash; HDMI 1.4 Второй \u0026ndash; DP Гость:\nОсновной \u0026ndash; DP Второй \u0026ndash; HDMI 1.4 То есть перекрестное подключение, а такое оно из-за недостатка входов как на мониторах так и на материнки, будь моя воля, я бы все втыкнул в DP.\nВерсию HDMI я написал не просто так, у меня 1.4, а это максимум 120 Hz (хоть и программно), в то время как у моего основного монитора 144 Hz.\nЛогика #1, максимально проста и логична: Делаем основной монитор хоста в DP, в работе я увижу все 144 Hz, а вот то, что в играх будет 144 FPS, я очень сомневаюсь, и поэтому для гостя HDMI на 120 Hz.\nИменно так я изначально и сделал, забыв, что NVIDIA не работает с FreeSync, G-Sync и прочими Sync с HDMI \u0026lt;2.1 и то криво, насколько мне известно.\nПоэтому, Логика #2: Наоборот, хост не такой гладкий, да, но разница 120 vs 144 не особо заметна, как например 60 vs 75, но при этом все Sync работают с NVIDIA через DP.\nВ BIOS, он же UEFI Firmware нужно, разумеется, включить аппаратную виртуализацию вашего процессора и IOMMU. Как это сделать гуглите для своего процессора и для своего производителя мат. платы, тут у каждого по-своему.\nТакже включение IOMMU в ОС (не заменяет настройки BIOS):\nYaST \u0026ndash;\u0026gt; System \u0026ndash;\u0026gt; Boot Loader в конец добавить: amd_iommu=force_isolation iommu=pt. Если у вас Intel, то вместо amd_iommu=force_isolation \u0026ndash;\u0026gt; intel_iommu=on.\nПерезагрузиться.\nПроверить параметры и включен ли IOMMU:\nsudo sh -c \u0026#39;dmesg | grep -i iommu \u0026amp;\u0026amp; echo \u0026amp;\u0026amp; dmesg | grep -E \u0026#34;Intel-IOMMU|AMD-Vi\u0026#34;\u0026#39; Узнать, выиграли ли вы в лотерею, можно:\nsh -c \u0026#39;for g in $(find /sys/kernel/iommu_groups/* -maxdepth 0 -type d | sort -V); do echo \u0026#34;IOMMU Group ${g##*/}:\u0026#34;; for d in $(ls -1 $g/devices); do lspci -nns $d; done; echo; done\u0026#39; Если каждая железка, ну или только те железки, что вам нужны для проброса в отдельной IOMMU группе \u0026ndash; вам повезло. А именно, это нужный SSD и нужная GPU, ну и другое по желанию, что вам нужно. Если нет, то придется применить ACS patch (я опишу это, когда у меня будет достаточно информации).\nПро SSD может быть такое, что у вас скажем 3 слота SSD, но 2 из них в одной группе, а 1 в отдельной, уже знаете, что делать, ведь так?\nВиртуализация YaST \u0026ndash;\u0026gt; Virtualization \u0026ndash;\u0026gt; Install Hypervisor and Tools - KVM server и KVM tools.\nЕсли при установке YaST предложит создать мост, соглашайтесь, если ошибка \u0026ndash; значения не имеет.\nПосле установки проверьте:\nsudo systemctl status virtqemud А также добавляемся в группы:\nsudo usermod -aG libvirt,kvm $(whoami) Это нужно, чтобы потом иметь возможность пробросить PCI устройства, а также запинить ядра процессора, сделать hugepages, ну и другое.\nПерезагружаемся, проверить, что вы в группе, можно:\ngroups \u0026amp;\u0026amp; grep -E \u0026#39;libvirt|kvm\u0026#39; /etc/group А также для W11:\nls /usr/share/qemu/ovmf* Должен быть /usr/share/qemu/ovmf-x86_64-smm-ms-code.bin, это SMM + Secure Boot.\nСоздание виртуальной машины Открываем Virtual Machine Manager и создаем новую виртуалку, Local install media (ISO), да, у вас должен быть образ Windows. RAM/CPU что угодно, сейчас неважно. Storage - тут важно, убрать галочку с Enable storage for this VM. И ВАЖНО поставить галочку Customize configuration before install.\nЕсли \u0026ldquo;Virtual Network is not active\u0026rdquo; \u0026ndash; sudo virsh net-autostart default и нажмите \u0026ldquo;Yes\u0026rdquo;.\nOverview:\nChipset: Q35 Firmware: /usr/share/qemu/ovmf-x86_64-smm-ms-code.bin CPU:\nCopy host CPU configuration (host-passthrough) Add Hardware \u0026ndash;\u0026gt; TPM. Вот тут притормозим. У вас есть два варианта, либо passthrough, либо нет. Есть ли какие-то минусы-плюсы пробрасывать TPM? Ну, в жизни обычного человека \u0026ndash; нету.\nPassthrough это синоним эксклюзивного доступа, а TPM один. Из-за чего могут появляться ошибки, ну например, запускаете виртуалку, все работает, выключаете виртуалку, запускаете снова, и тут как повезет:\nЗапустится '/dev/fdset/0' is not a TPM device \u0026ndash; лечится перезагрузкой хоста, не круто Проверить используется ли TPM хостом можно так:\nsudo journalctl -k -b 0 | grep -i \u0026#34;ima\\|tpm\u0026#34; Если наблюдаете некоторую активность (больше пары строк после загрузки ОС и некоторой работы), то оно используется хостом.\nЕсли вы хотите пойти на риск или TPM не используется хостом, то почему бы и нет:\nType: Passthrough Model: CRB (только 2.0) / TIS Version: CRB - 2.0 / TIS - 2.0/1.2 Если же нет, то лучше эмулировать:\nType: Emulated Model: если есть поддержка TPM 2.0 - CRB, иначе - TIS Version: CRB - 2.0 / TIS - 2.0/1.2 Если у вас два TPM в списке, удалите тот, что вы не создавали.\nПроброс диска Есть два способа пробросить диск. Универсальный и если вам повезло с IOMMU группами \u0026ndash; VFIO.\nПроверьте IOMMU группы:\nsh -c \u0026#39;for g in $(find /sys/kernel/iommu_groups/* -maxdepth 0 -type d | sort -V); do echo \u0026#34;IOMMU Group ${g##*/}:\u0026#34;; for d in $(ls -1 $g/devices); do lspci -nns $d; done; echo; done\u0026#39; Если видите что-то такое:\n1 2 3 IOMMU Group 24: 04:08.0 PCI bridge [0604]: Advanced Micro Devices, Inc. [AMD] 600 Series Chipset PCIe Switch Downstream Port [1022:43f5] (rev 01) 0d:00.0 Non-Volatile memory controller [0108]: Kingston Technology Company, Inc. KC3000/FURY Renegade NVMe SSD [E18] [2646:5013] (rev 01) Или такое:\n1 2 IOMMU Group 27: 10:00.0 Non-Volatile memory controller [0108]: Samsung Electronics Co Ltd NVMe SSD Controller SM981/PM981/PM983 [144d:a808] И все, если в этой группе больше НИЧЕГО нету, вам очень повезло, вы можете пробросить диск самым прямым способом.\nВ первом случае в группе вместе с диском находится и его мост, такое можно смело пробрасывать, но если там скажем парочка USB, еще один диск, сетевая карта или еще что, то нет, не надо так делать.\nУниверсальный это через VirtIO драйвер, он не плохой, но задержки больше, потеряете около 3-5% линейной скорости (запись/перемещение файлов), и чуть больше потерь на рандомной записи/чтения (видеомонтаж, рендер, игры и тп.) в сравнении с голым железом.\nТакже вы можете попробовать сначала одно, потом другое, без пересоздания виртуалки и переустановки Windows, все будет работать.\nДелаем:\nlsblk -o NAME,SIZE,TYPE,MOUNTPOINT,MODEL Вывод:\n1 2 3 4 5 NAME SIZE TYPE MOUNTPOINT MODEL nvme1n1 1.9T disk KINGSTON SKC3000D2048G ├─nvme1n1p1 16M part └─nvme1n1p2 1.9T part ... Проверяем наличие нужного диска и отсутствие точек монтирования.\nДалее:\nls -la /dev/disk/by-id/ | grep nvme1n1 Нам нужно типа такого nvme-KINGSTON_SKC3000D2048G_xxxx, без _x или -x. Записываем это.\nТак мы узнали серийник диска, он нужен, чтобы привязать диск по серийнику (VirtIO), а не по имени. В Linux какой первый диск инициализируется, тот первым и будет. Это значит, то, что вы укажите в настройках виртуалки, после перезагрузки хоста может поменяться, по серийнику не поменяется.\nVirtIO (универсально) Качаем virtio-win драйвер. Он нужен, чтобы Windows могла увидеть этот ваш диск.\nТыкаем Add Hardware \u0026ndash;\u0026gt; Storage:\nSelect or create custom storage Device type: Disk device Bus type: VirtIO Manage \u0026ndash;\u0026gt; /dev/disk/by-id/nvme-KINGSTON_SKC3000D2048G_xxxx (см. выше) Advanced options: Cache mode: none Discard mode: unmap Снова Add Hardware \u0026ndash;\u0026gt; Storage:\nDevice type: CDROM virtio-win.iso VFIO Если вы еще не устанавливали Windows, то пропускаем этот шаг, если уже установили, но хотите VFIO, то загружайтесь в Windows, открываете терминал от имени админа:\nbcdedit /set {current} safeboot minimal Выключаете виртуалку и удаляете текущий VirtIO диск.\nAdd Hardware \u0026ndash;\u0026gt; PCI Host Device, тут надо найти нужный SSD, да это будет чуточку проблематично, но как найдете, тыкаете на него и Finish. Отныне он будет отображаться не как диск, а как \u0026ldquo;PCI ID\u0026rdquo; в левой панели, не теряйте.\n🚧 ВНИМАНИЕ! Это НЕ ID диска, НЕ его серийник, это ID слота PCI.\nЕсли вы переставите диск в другой слот, то нужно будет снова его добавлять.\nНо что более ВАЖНО, если вы на его место поставите другой диск, он автоматически пробросится (если не делали изоляцию \u0026ndash; то автоматически не пробросится, только при запуске виртуалки). То есть, если вы поменяете его местами, скажем, с системным диском хоста, будет грустно.\nПеред такими делами удалите диск из виртуалки, а потом добавьте снова!\nИдем в Boot Options и там выбираем тот самый \u0026ldquo;PCI ID\u0026rdquo;. Все. Было просто, да?\nWindows должна загрузиться в безопасный режим, В безопасный режим желательно входить, когда меняется системный диск, диск тот же, но для Windows был Red Hat, стал не Red Hat \u0026ndash; смена диска. выходим из безопасного режима:\nbcdedit /deletevalue {current} safeboot Теперь в диспетчере задач в Performance вы увидите не Red Hat че-то там, а прям свой диск.\nТак как изоляцию мы не делали, проброс динамический, когда виртуалка выключена \u0026ndash; хост видит диск, когда включена \u0026ndash; хост не видит диск. Делать изоляцию смысла особо нету, это ничего не прибавит. Но если вдруг система решит что-то сделать с диском в момент запуска виртуалки, то в худшем случае будет kernel panic :D\nНо это не так важно, ничего не сломается. Самое главное, чтобы диск не был примонтирован во время запуска виртуалки, иначе ФС может быть разрушена :)\nКогда диск УЖЕ будет в виртуалке, хост ничего с ним не сделает (только если вы не балуйтесь вкл/выкл виртуалкой как светом в комнате). Если вы все-таки хотите его изолировать, то см. Про проброс VFIO.\nВот небольшое сравнение скоростей:\nГолый метал: 6500/6300 VirtIO: 6300/6100 VFIO: 6420/6330 Установка Windows Если вы делали VirtIO диск, то на этапе установки Windows, конкретно выбора диска, вас постигнет ужас, но вы не бойтесь, тыкайте на Load Driver \u0026ndash;\u0026gt; \u0026ldquo;virtio-win\\viostor\\w11\\amd64\u0026rdquo; и установите это. Ну, а дальше как обычно.\n📝 Во время установки, когда снова будет просить белым по черному что-то нажать \u0026ndash; ничего не нажимайте, а то снова уйдете в установщик Windows. После установки ОС, VirtIO \u0026amp; Windows ISO можно удалить из девайсов, они больше не нужны.\nА еще небольшой спойлер, хоть это и не по теме, все равно проверьте Проблема X в Windows из-за Y!\nПериферия \u0026ndash; Клавиатура и мышь Рано или поздно это нужно было бы решить, и по-уму \u0026ndash; evdev passthrough.\nИщем нужные устройства (нужны mouse и kbd):\nls /dev/input/by-id/ | grep event В моем случае usb-COMPANY_USB_Device-if01-event-mouse и usb-I-CHIP_MMD_KM40_Receiver_1234-event-kbd.\nПроверить что устройство нужное можно так:\nsudo evtest /dev/input/by-id/usb-COMPANY_USB_Device-if01-event-mouse И так же для клавиатуры. По нажимать кнопки/клавиши/поводить мышью, если видите тонну лога то это оно.\nДобавляем устройства в cgroup_device_acl (придется поискать и изменить, или просто добавить свое \u0026ndash; обычно оно все закомментировано по умолчанию):\nsudo nano /etc/libvirt/qemu.conf 1 2 3 4 5 6 7 cgroup_device_acl = [ \u0026#34;/dev/null\u0026#34;, \u0026#34;/dev/full\u0026#34;, \u0026#34;/dev/zero\u0026#34;, \u0026#34;/dev/random\u0026#34;, \u0026#34;/dev/urandom\u0026#34;, \u0026#34;/dev/ptmx\u0026#34;, \u0026#34;/dev/kvm\u0026#34;, \u0026#34;/dev/rtc\u0026#34;, \u0026#34;/dev/hpet\u0026#34;, \u0026#34;/dev/input/by-id/usb-COMPANY_USB_Device-if01-event-mouse\u0026#34;, \u0026#34;/dev/input/by-id/usb-I-CHIP_MMD_KM40_Receiver_1234-event-kbd\u0026#34; ] sudo sh -c \u0026#39;systemctl restart virtqemud \u0026amp;\u0026amp; systemctl status virtqemud\u0026#39; В Virtual Machine Manager \u0026ndash;\u0026gt; Edit \u0026ndash;\u0026gt; Preferences: Enable XML editing.\nОткрываем настройки виртуалки, в Overview переходим на XML, в конце ищем \u0026lt;/devices\u0026gt; и внутрь тега добавляем:\n1 2 3 4 5 6 \u0026lt;input type=\u0026#39;evdev\u0026#39;\u0026gt; \u0026lt;source dev=\u0026#39;/dev/input/by-id/usb-COMPANY_USB_Device-if01-event-mouse\u0026#39;/\u0026gt; \u0026lt;/input\u0026gt; \u0026lt;input type=\u0026#39;evdev\u0026#39;\u0026gt; \u0026lt;source dev=\u0026#39;/dev/input/by-id/usb-I-CHIP_MMD_KM40_Receiver_1234-event-kbd\u0026#39; grab=\u0026#39;all\u0026#39; repeat=\u0026#39;on\u0026#39;/\u0026gt; \u0026lt;/input\u0026gt; Применяем, текст \u0026ldquo;пропадет\u0026rdquo;, но он не пропал, он просто переместился повыше. При запуске виртуалки ввод с хоста сразу же пропадет и уйдет в виртуалку. Переключение LCtrl + RCtrl .\n📝 Медиа клавиши в госте работать не будут, чтобы они работали их тоже надо добавить, например у меня они if01, но я не рекомендую этого делать, потому что далее по настройке звука мы сделаем красиво.\nТак же обратите внимание, что донгл и USB провод разные вещи, если вы добавите только что-то одно, то при другом работать не будет (зависит от поведения девайса).\nНа примере клавиатуры, вы добавили только донгл:\nВключен только донгл \u0026ndash; работает Включен донгл и провод, но клавиатура принципиально начинает работать через провод \u0026ndash; не работает Включен донгл и провод, но клавиатура просто заряжается, но работает через донгл \u0026ndash; работает Если решите добавить и то, и то \u0026ndash; работать не будет, если что-то из этого отключено \u0026ndash; виртуалка откажется запускаться. Решается через симлинки udev, про что \u0026ndash; ниже.\nudev симлинки (объединение устройств в одно) Покажу на примере клавиатуры. Подключаем клавиатуру всеми способами, что нужно объединить, или если при использование одного способа \u0026ndash; другой \u0026ldquo;отлетает\u0026rdquo; и наоборот, то просто делайте описанное ниже по очереди.\nСнова проверяем список устройств:\nls /dev/input/by-id/ | grep event 📝 Если вы не уверены в устройстве, то проверьте его:\nsudo evtest /dev/input/by-id/usb-SmartCloud_MMD_KM40-event-kbd При нажатие на обычные клавиши у меня ничего не пишет в лог, а:\nsudo evtest /dev/input/by-id/usb-SmartCloud_MMD_KM40-if02-event-kbd Пишет. Значит, нужное устройство \u0026ndash; usb-SmartCloud_MMD_KM40-if02-event-kbd.\nВ моем случае получается:\nusb-I-CHIP_MMD_KM40_Receiver_1234-event-kbd \u0026ndash; донгл usb-SmartCloud_MMD_KM40-if02-event-kbd \u0026ndash; провод Далее делаем с ними такое:\nDEV=/dev/input/by-id/usb-I-CHIP_MMD_KM40_Receiver_1234-event-kbd \u0026amp;\u0026amp; echo \u0026#34;- Properties:\u0026#34; \u0026amp;\u0026amp; udevadm info -q property -n \u0026#34;$DEV\u0026#34; | grep -E \u0026#34;ID_VENDOR_ID|ID_MODEL_ID|ID_SERIAL|ID_USB_INTERFACE_NUM|ID_INPUT\u0026#34; \u0026amp;\u0026amp; echo \u0026#34;- Name:\u0026#34; \u0026amp;\u0026amp; udevadm info -a -n \u0026#34;$DEV\u0026#34; | grep -m1 \u0026#39;ATTRS{name}\u0026#39; DEV=/dev/input/by-id/usb-SmartCloud_MMD_KM40-if02-event-kbd \u0026amp;\u0026amp; echo \u0026#34;- Properties:\u0026#34; \u0026amp;\u0026amp; udevadm info -q property -n \u0026#34;$DEV\u0026#34; | grep -E \u0026#34;ID_VENDOR_ID|ID_MODEL_ID|ID_SERIAL|ID_USB_INTERFACE_NUM|ID_INPUT\u0026#34; \u0026amp;\u0026amp; echo \u0026#34;- Name:\u0026#34; \u0026amp;\u0026amp; udevadm info -a -n \u0026#34;$DEV\u0026#34; | grep -m1 \u0026#39;ATTRS{name}\u0026#39; Подставляем свои значения в DEV, разумеется.\nНас интересуют:\nID_VENDOR_ID ID_MODEL_ID ID_USB_INTERFACE_NUM ATTRS{name} \u0026ndash; нужно во избежание коллизий Далее:\nsudo nano /etc/udev/rules.d/99-vm-keyboard.rules 1 2 3 4 5 # /dev/input/by-id/usb-I-CHIP_MMD_KM40_Receiver_1234-event-kbd SUBSYSTEM==\u0026#34;input\u0026#34;, KERNEL==\u0026#34;event*\u0026#34;, ENV{ID_VENDOR_ID}==\u0026#34;\u0026lt;ID_VENDOR_ID\u0026gt;\u0026#34;, ENV{ID_MODEL_ID}==\u0026#34;\u0026lt;ID_MODEL_ID\u0026gt;\u0026#34;, ENV{ID_USB_INTERFACE_NUM}==\u0026#34;\u0026lt;ID_USB_INTERFACE_NUM\u0026gt;\u0026#34;, ATTRS{name}==\u0026#34;\u0026lt;NAME\u0026gt;\u0026#34;, OPTIONS+=\u0026#34;link_priority=-10\u0026#34;, SYMLINK+=\u0026#34;input/by-id/vm-keyboard-event-kbd\u0026#34; # /dev/input/by-id/usb-SmartCloud_MMD_KM40-if02-event-kbd SUBSYSTEM==\u0026#34;input\u0026#34;, KERNEL==\u0026#34;event*\u0026#34;, ENV{ID_VENDOR_ID}==\u0026#34;\u0026lt;ID_VENDOR_ID\u0026gt;\u0026#34;, ENV{ID_MODEL_ID}==\u0026#34;\u0026lt;ID_MODEL_ID\u0026gt;\u0026#34;, ENV{ID_USB_INTERFACE_NUM}==\u0026#34;\u0026lt;ID_USB_INTERFACE_NUM\u0026gt;\u0026#34;, ATTRS{name}==\u0026#34;\u0026lt;NAME\u0026gt;\u0026#34;, OPTIONS+=\u0026#34;link_priority=10\u0026#34;, SYMLINK+=\u0026#34;input/by-id/vm-keyboard-event-kbd\u0026#34; Данные в \u0026lt;...\u0026gt; меняем на свои. Советую так же сделать комментарии аналогичные, чтобы не путаться и знать что есть что.\n📝 Обратите внимание на link_priority, это приоритет. Когда я подключаю клавиатуру для зарядки, я разумеется донгл не вытыкаю из USB.\nНо клавиатура у меня не дура и начинает работать по проводу, а не по донглу, но в системе по прежнему донгл то имеется.\nКак итог, udev использует донгл, который\u0026hellip; не работает, потому что подключен провод. Потому у донгла приоритет ниже, а у провода выше.\nПрименяем правила:\nsudo sh -c \u0026#39;udevadm control --reload-rules \u0026amp;\u0026amp; udevadm trigger\u0026#39; Проверяем:\nls -l /dev/input/by-id/vm-keyboard-event-kbd И так же:\nsudo evtest /dev/input/by-id/vm-keyboard-event-kbd И по нажимайте клавиши, попробуйте только донгл, только провод, и то и то, все должно работать.\nДалее везде добавляем/заменяем клавиатуру на /dev/input/by-id/vm-keyboard-event-kbd как было показано в начале раздела.\n🚧 К сожалению, на момент написания этого текста, оно не работает на горячую. То есть если после запуска виртуалки вы \u0026ldquo;переключите\u0026rdquo; устройства, провод втыкнете или вытокните, то QEMU потеряет устройство и нужно будет перезагрузить виртуалку. Это не баг, это поведение системы. Pinning CPU ядер \u0026amp; HugePages Самое интересное и простое. Но для начала предисловие. У дох*я ядерников Intel не совсем дох*я ядер. Есть P-ядра \u0026ndash; производительные, и E-ядра \u0026ndash; энергоэффективные, производительные мощные, энергоэффективные так \u0026ldquo;на подсосе\u0026rdquo;. Ну скажем легенда i5-14600K, у него 14 ядер, верно? Но\u0026hellip;\n6 P-ядер и 8 E-ядер, то есть 6 реально крутых ядер, и 8 таких себе ядер. Но (еще раз), в разгоне энергоэффективные ядра бустятся с 2.6 ГГц до 4.0 ГГц, не то чтобы сильно много, но уже не на подсосе. Производительные же с 3.5 ГГц до 5.3 ГГц. Независимо от того в разгоне у вас или нет, кидайте мощные ядра + их потоки в виртуалку, а хосту оставляйте все энергоэффективные. Вот и все.\nС AMD все проще, у них нету понятия энергоэффективные ядра. Не придется детектить P и E ядра, нужно будет только связать ядра с потоками, но с AMD особенно с Zen 4 (AM5 сокет) понять какой поток к какому ядру как два пальца. Но (снова), есть исключения, у дох*я ядерников AMD, 12-16 ядер типа R 9, там ядра разделены на два чиплета, и ну\u0026hellip; вот лучше не надо в виртуалку кидать кучку ядер с одного чиплета и кучку с другого, лучше только с одного.\nlscpu -e=CORE,CPU,CLUSTER,SOCKET,MINMHZ,MAXMHZ,MHZ CORE \u0026ndash; ядро CPU \u0026ndash; поток CLUSTER \u0026ndash; чиплет У меня не R 9, поэтому точнее показать и сказать, как делать не смогу, у меня просто Ryzen на AM5:\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 CORE CPU CLUSTER SOCKET MINMHZ MAXMHZ MHZ 0 0 - 0 422.3340 5392.8721 3021.3081 1 1 - 0 422.3340 5392.8721 4339.9531 2 2 - 0 422.3340 5392.8721 3021.3081 3 3 - 0 422.3340 5392.8721 4341.2192 4 4 - 0 422.3340 5392.8721 3470.1899 5 5 - 0 422.3340 5392.8721 3021.3081 6 6 - 0 422.3340 5392.8721 4333.1089 7 7 - 0 422.3340 5392.8721 3021.3081 0 8 - 0 422.3340 5392.8721 3021.3081 1 9 - 0 422.3340 5392.8721 4339.2979 2 10 - 0 422.3340 5392.8721 3021.3081 3 11 - 0 422.3340 5392.8721 3021.3081 4 12 - 0 422.3340 5392.8721 3021.3081 5 13 - 0 422.3340 5392.8721 3021.3081 6 14 - 0 422.3340 5392.8721 3021.3081 7 15 - 0 422.3340 5392.8721 4001.2991 От 0 до 7, у меня 8 ядер, но как обычно оно бывает в таких делах \u0026ndash; счет идет не с 1, а с нуля, то есть 0-7 = 1-8 ядер = 8 ядер.\nНужно найти совпадения, ну например CORE 0, мы видим, что в правой колонке напротив 0 есть 0 и 8, это близнецы, то есть это одно целое ядро с двумя потоками (потому что SMT/HT). Далее второе ядро (которое помечено как 1), имеет 1 и 9. То есть вот я нашел 2 ядра и их 2 потока, что суммарно 4 потока, которые я отдам хосту:\n0,8 1,9 Остальные (12 штук) уйдут виртуалке:\n2,10 3,11 4,12 5,13 6,14 7,15 Видите? С AMD с одним чиплетом все просто!\nБоже, благослови QEMU диспетчер.\nСоздаем диспетчер, очень удобная и универсальная штука, так же может пригодиться потом для хуков других виртуалок:\nsudo nano /etc/libvirt/hooks/qemu dispatcher.sh Loading file... vfio/qemu-hooks/dispatcher.sh Создаем директории с хуками:\nVM=\u0026#34;win11\u0026#34;; sudo mkdir -p /etc/libvirt/hooks/qemu.d/\u0026#34;$VM\u0026#34;/prepare/begin/ /etc/libvirt/hooks/qemu.d/\u0026#34;$VM\u0026#34;/release/end/ Где win11 название вашей виртуальной машины, узнать можно sudo virsh list --all.\nХук при старте виртуалки:\nsudo nano /etc/libvirt/hooks/qemu.d/win11/prepare/begin/50-cpu-pinning-and-hugepages.sh 50-cpu-pinning-and-hugepages.sh Loading file... vfio/qemu-hooks/start/50-cpu-pinning-and-hugepages.sh Хук при выключении виртуалки:\nsudo nano /etc/libvirt/hooks/qemu.d/win11/release/end/50-cpu-pinning-and-hugepages.sh 50-cpu-pinning-and-hugepages.sh Loading file... vfio/qemu-hooks/stop/50-cpu-pinning-and-hugepages.sh Не забудьте в скриптах поменять потоки ядер и настроить hugepages сколько вам надо. Про hugepages так же будет доп. информация далее, и так же таблица с примерами.\nДаем права на исполнение:\nsudo chmod +x /etc/libvirt/hooks/qemu И для хуков:\nVM=\u0026#34;win11\u0026#34;; sudo find /etc/libvirt/hooks/qemu.d/\u0026#34;$VM\u0026#34; -type f -name \u0026#39;*.sh\u0026#39; \\( -path \u0026#39;*/prepare/begin/*\u0026#39; -o -path \u0026#39;*/prepare/end/*\u0026#39; -o -path \u0026#39;*/release/begin/*\u0026#39; -o -path \u0026#39;*/release/end/*\u0026#39; \\) -exec chmod +x {} + Перезапускаем сервис, чтобы обновить хуки:\nsudo sh -c \u0026#39;systemctl restart virtqemud \u0026amp;\u0026amp; systemctl status virtqemud\u0026#39; В моем случае 6 ядер с SMT, то есть 12 потоков. В настройках виртуалки \u0026ndash;\u0026gt; CPUs, Cores ставим кол-во ядер (в моем случае 6), а в Threads кол-во потоков на ядро (в моем случае 2) и применяем. Sockets это кол-во процессоров, ставьте 1.\nВ настройках виртуалки Overview - XML ищем \u0026lt;vcpu placement=\u0026quot;static\u0026quot;\u0026gt;X\u0026lt;/vcpu\u0026gt;, где X какое-то общее кол-во потоков. Вписываем нужное значение:\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 \u0026lt;vcpu placement=\u0026#34;static\u0026#34;\u0026gt;12\u0026lt;/vcpu\u0026gt; \u0026lt;cputune\u0026gt; \u0026lt;vcpupin vcpu=\u0026#34;0\u0026#34; cpuset=\u0026#34;2\u0026#34;/\u0026gt; \u0026lt;vcpupin vcpu=\u0026#34;1\u0026#34; cpuset=\u0026#34;10\u0026#34;/\u0026gt; \u0026lt;vcpupin vcpu=\u0026#34;2\u0026#34; cpuset=\u0026#34;3\u0026#34;/\u0026gt; \u0026lt;vcpupin vcpu=\u0026#34;3\u0026#34; cpuset=\u0026#34;11\u0026#34;/\u0026gt; \u0026lt;vcpupin vcpu=\u0026#34;4\u0026#34; cpuset=\u0026#34;4\u0026#34;/\u0026gt; \u0026lt;vcpupin vcpu=\u0026#34;5\u0026#34; cpuset=\u0026#34;12\u0026#34;/\u0026gt; \u0026lt;vcpupin vcpu=\u0026#34;6\u0026#34; cpuset=\u0026#34;5\u0026#34;/\u0026gt; \u0026lt;vcpupin vcpu=\u0026#34;7\u0026#34; cpuset=\u0026#34;13\u0026#34;/\u0026gt; \u0026lt;vcpupin vcpu=\u0026#34;8\u0026#34; cpuset=\u0026#34;6\u0026#34;/\u0026gt; \u0026lt;vcpupin vcpu=\u0026#34;9\u0026#34; cpuset=\u0026#34;14\u0026#34;/\u0026gt; \u0026lt;vcpupin vcpu=\u0026#34;10\u0026#34; cpuset=\u0026#34;7\u0026#34;/\u0026gt; \u0026lt;vcpupin vcpu=\u0026#34;11\u0026#34; cpuset=\u0026#34;15\u0026#34;/\u0026gt; \u0026lt;emulatorpin cpuset=\u0026#34;0-1,8-9\u0026#34;/\u0026gt; \u0026lt;/cputune\u0026gt; Здесь cpuset это ядро вашего процессора, а vcpu это поток внутри VM, 12 виртуальных потоков это от 0 до 11, справа я назначаю им РЕАЛЬНЫЕ потоки с хоста. Нужно назначить виртуальной паре \u0026ndash; реальную пару (см. выше).\nemulatorpin говорит хосту использовать для \u0026ldquo;поддержания\u0026rdquo; жизни KVM вот эти ядра, то есть в моем случае указаны ядра, что я оставил хосту \u0026ndash; первые 2 ядра (4 потока), то есть чтобы виртуалка не лезла на ядра, что выделены гостю.\nЕсли вы пробрасывали диск через VirtIO, а не VFIO, то после \u0026lt;emulatorpin/\u0026gt; добавьте:\n1 \u0026lt;iothreadpin iothread=\u0026#34;1\u0026#34; cpuset=\u0026#34;0-1,8-9\u0026#34;/\u0026gt; HugePages в XML нужно добавить сразу после тега \u0026lt;currentMemory\u0026gt;:\n1 2 3 4 5 \u0026lt;memoryBacking\u0026gt; \u0026lt;hugepages\u0026gt; \u0026lt;page size=\u0026#34;2\u0026#34; unit=\u0026#34;M\u0026#34;/\u0026gt; \u0026lt;/hugepages\u0026gt; \u0026lt;/memoryBacking\u0026gt; А также изменить:\n1 2 \u0026lt;memory unit=\u0026#34;KiB\u0026#34;\u0026gt;X\u0026lt;/memory\u0026gt; \u0026lt;currentMemory unit=\u0026#34;KiB\u0026#34;\u0026gt;X\u0026lt;/currentMemory\u0026gt; Где X \u0026ndash; GB * 1048576 , например 42 GB * 1048576 = 44040192 KiB. Указывать это надо очень точно.\nПримеры:\nGB TARGET (хук) KiB (XML) 8 4096 8388608 16 8192 16777216 24 12288 25165824 32 16384 33554432 42 21504 44040192 48 24576 50331648 Про memoryBacking (size=\u0026quot;2\u0026quot;) и hugepages-2048kB, размер страницы решает, самый такой крутой вариант это 1024 и hugepages-1048576kB \u0026mdash; 1gb, но это как фрагментация диска. Хосту будет (вероятно очень) проблематично найти нужный объем памяти по 1 непрерывному гигабайту, потому что ОЗУ нелинейна. Но задержки станут еще меньше. 2mb это компромисс. Важно, меньше нельзя, больше нельзя, работает только 4kb (дефолт системы), 2mb, 1024mb (1gb) и все.\nТакже проверить, что hugepages выделены (после запуска VM) можно так:\ncat /proc/meminfo | grep Huge Проброс dGPU Варианта два. Топорный, но 100%, требует перезагрузки для \u0026ldquo;переключения режима\u0026rdquo;. И изящный, но может не сработать. Изящный вариант, это переключение на горячую, запустили виртуалку \u0026ndash; dGPU улетела в виртуалку, выключили виртуалку \u0026ndash; dGPU вернулась хосту, ах*ено шо пизд*ц. Но это сложно. Может работать сейчас, но перестать потом. Если изящный способ перестанет работать у меня, я обязательно обновлю текст, если у вас\u0026hellip; ну тут как бы, я не вы, я не знаю, что у вас.\nВ начале ПЕРВЫМ делом! Включите ssh сервер, если что-то пойдет не так, пропадет изображение, или еще что \u0026ndash; вы могли зайти с телефона и исправить проблему:\nsudo sh -c \u0026#39;systemctl enable --now sshd \u0026amp;\u0026amp; firewall-cmd --permanent --add-service=ssh \u0026amp;\u0026amp; firewall-cmd --reload \u0026amp;\u0026amp; systemctl status sshd\u0026#39; Когда закончите все делать, ssh сервер можно (и лучше, если не нужен он вам) отключить:\nsudo sh -c \u0026#39;systemctl disable --now sshd \u0026amp;\u0026amp; firewall-cmd --permanent --remove-service=ssh \u0026amp;\u0026amp; firewall-cmd --reload \u0026amp;\u0026amp; systemctl status sshd\u0026#39; Разлогиньтесь и на экране входа выберите Wayland.\nТеперь заставим Wayland работать с iGPU, иначе после проброса dGPU может пропасть изображение.\n📝 Описанное ниже нужно делать, если вы не делали этого, и у вас уже пропало изображение; поэтому делаем это заранее, считайте это \u0026ldquo;превентивным фиксом\u0026rdquo;. Узнаем PCI iGPU в десятичной системе (hex to decimal):\nlspci -D | grep -E \u0026#34;VGA|3D|Display\u0026#34; | grep -v \u0026#34;NVIDIA\u0026#34; | awk -F\u0026#39;[:. ]\u0026#39; \u0026#39;{printf \u0026#34;\\n%s:%s:%s.%s (hex) =\u0026gt; PCI:%d:%d:%d (decimal)\\n\\n\u0026#34;, $1, $2, $3, $4, strtonum(\u0026#34;0x\u0026#34;$2), strtonum(\u0026#34;0x\u0026#34;$3), strtonum(\u0026#34;0x\u0026#34;$4)}\u0026#39; Вывод:\n0000:11:00.0 (hex) =\u0026gt; PCI:17:0:0 (decimal) Для AMD:\n1 2 3 4 5 6 7 sudo tee /etc/X11/xorg.conf \u0026lt;\u0026lt; \u0026#39;EOF\u0026#39; Section \u0026#34;Device\u0026#34; Identifier \u0026#34;iGPU\u0026#34; Driver \u0026#34;amdgpu\u0026#34; BusID \u0026#34;PCI:17:0:0\u0026#34; EndSection EOF sudo zypper install xf86-video-amdgpu Для Intel:\n1 2 3 4 5 6 7 sudo tee /etc/X11/xorg.conf \u0026lt;\u0026lt; \u0026#39;EOF\u0026#39; Section \u0026#34;Device\u0026#34; Identifier \u0026#34;iGPU\u0026#34; Driver \u0026#34;modesetting\u0026#34; # или intel BusID \u0026#34;PCI:17:0:0\u0026#34; EndSection EOF Если Driver \u0026ldquo;modesetting\u0026rdquo; не сработал, и вы используете \u0026ldquo;intel\u0026rdquo;, то:\nsudo zypper install xf86-video-intel Учтите, что \u0026ldquo;xf86-video-intel\u0026rdquo; не обновляется и так себе работает на intel \u0026gt;=11 поколения, и в любом случае \u0026ndash; в приоритете использовать Driver \u0026ldquo;modesetting\u0026rdquo; для Intel.\nЕсли забыли PCI:\nlspci | grep -E \u0026#34;VGA|3D|Display\u0026#34; Вывод:\n01:00.0 VGA compatible controller: NVIDIA Corporation AD104 [GeForce RTX 4070] (rev a1) 11:00.0 VGA compatible controller: Advanced Micro Devices, Inc. [AMD/ATI] Raphael (rev c5) На этот раз нужно просто 11:00.0. Далее находим DRM устройство по PCI:\nls -la /dev/dri/by-path/ | grep \u0026#34;11:00.0\u0026#34; Вывод:\nlrwxrwxrwx. 1 root root 8 Jun 15 13:11 pci-0000:11:00.0-card -\u0026gt; ../card0 lrwxrwxrwx. 1 root root 13 Jun 15 13:11 pci-0000:11:00.0-render -\u0026gt; ../renderD128 Передаем устройство в KWin \u0026ndash; pci-0000:11:00.0-card :\nmkdir -p ~/.config/systemd/user/plasma-kwin_wayland.service.d 1 2 3 4 tee ~/.config/systemd/user/plasma-kwin_wayland.service.d/override.conf \u0026lt;\u0026lt; \u0026#39;EOF\u0026#39; [Service] ExecStartPre=/bin/sh -c \u0026#39;systemctl --user set-environment KWIN_DRM_DEVICES=$(readlink -f /dev/dri/by-path/pci-0000:11:00.0-card)\u0026#39; EOF sudo nano /etc/environment 1 KWIN_DRM_DEVICES=\u0026#34;/dev/dri/by-path/pci-0000\\:11\\:00.0-card\u0026#34; Обратите внимание на \\, это экранирование :, так надо.\nsystemctl --user daemon-reload Если вы собираетесь делать горячий проброс \u0026ndash; рекомендую прочитать про холодный проброс, знание поможет вам.\nNVIDIA (Холодный проброс; VFIO со старта) sudo nano /etc/modprobe.d/vfio.conf Там:\ninstall vfio-pci /sbin/vfio-pci-override.sh Далее:\nlspci -nnk | grep -A3 -i nvidia 1 2 3 4 5 6 7 8 01:00.0 VGA compatible controller [0300]: NVIDIA Corporation AD104 [GeForce RTX 4070] [10de:2786] (rev a1) Subsystem: Micro-Star International Co., Ltd. [MSI] Device [1462:5137] Kernel driver in use: nvidia Kernel modules: nouveau, nvidia_drm, nvidia 01:00.1 Audio device [0403]: NVIDIA Corporation AD104 High Definition Audio Controller [10de:22bc] (rev a1) Subsystem: Micro-Star International Co., Ltd. [MSI] Device [1462:5137] Kernel driver in use: snd_hda_intel Kernel modules: snd_hda_intel Записываем 01:00.0 и 01:00.1.\nsudo nano /sbin/vfio-pci-override.sh 1 2 3 4 5 6 7 8 9 #!/bin/sh DEVS=\u0026#34;0000:01:00.0 0000:01:00.1\u0026#34; for DEV in $DEVS; do echo \u0026#34;vfio-pci\u0026#34; \u0026gt; /sys/bus/pci/devices/$DEV/driver_override done modprobe -i vfio-pci К тому, что записали ранее, добавляем 0000: \u0026ndash; 0000:\u0026lt;ваше_значение\u0026gt; (как в скрипте). Делаем скрипт исполняемым:\nsudo chmod +x /sbin/vfio-pci-override.sh Далее:\nsudo nano /etc/dracut.conf.d/vfio.conf 1 2 force_drivers+=\u0026#34; vfio vfio_pci vfio_iommu_type1 \u0026#34; install_items+=\u0026#34; /sbin/vfio-pci-override.sh \u0026#34; Пересобираем initramfs:\nsudo sdbootutil --no-reuse-initrd add-all-kernels YaST \u0026ndash;\u0026gt; System \u0026ndash;\u0026gt; Boot Loader \u0026ndash;\u0026gt; Kernel Parameters в конце:\n1 rd.driver.pre=vfio-pci Перезагружаемся. Проверяем:\nlspci -nnk | grep -A3 -i nvidia Должно быть Kernel driver in use: vfio-pci:\n1 2 3 4 5 6 7 8 01:00.0 VGA compatible controller [0300]: NVIDIA Corporation AD104 [GeForce RTX 4070] [10de:2786] (rev a1) Subsystem: Micro-Star International Co., Ltd. [MSI] Device [1462:5137] Kernel driver in use: vfio-pci Kernel modules: nouveau, nvidia_drm, nvidia 01:00.1 Audio device [0403]: NVIDIA Corporation AD104 High Definition Audio Controller [10de:22bc] (rev a1) Subsystem: Micro-Star International Co., Ltd. [MSI] Device [1462:5137] Kernel driver in use: vfio-pci Kernel modules: snd_hda_intel В настройках виртуалки добавляем новое PCI Host Device устройство (dGPU и ее Audio) (как с VFIO диском), и там же удаляем Display Spice и затем Video \u0026lt;X\u0026gt; (например Video Virtio или Video QXL).\nИначе \u0026ldquo;этот\u0026rdquo; дисплей определится Windows и будет как второй/третий\u0026hellip; дисплей, ну вы поняли, мешаться будет крч.\nNVIDIA (Горячий проброс) Я делал это с проприетарным драйвером NVIDIA, для НЕ проприетарного драйвера нужно немного поменять скрипты. Как по мне видеокарта NVIDIA без проприетарных драйверов \u0026ndash; бесполезна. Поэтому вот так.\nЗаставляем KWin работать с iGPU, чтобы в будущем отпустил dGPU.\nmkdir -p ~/.config/environment.d Указываем PCI iGPU (lspci | grep -E \u0026quot;VGA|3D|Display\u0026quot;):\n1 2 3 4 tee ~/.config/environment.d/kwin-gpu.conf \u0026lt;\u0026lt; \u0026#39;EOF\u0026#39; KWIN_DRM_DEVICES=\u0026#34;/dev/dri/by-path/pci-0000:11:00.0-card\u0026#34; __EGL_VENDOR_LIBRARY_FILENAMES=/usr/share/glvnd/egl_vendor.d/50_mesa.json EOF systemctl --user daemon-reload Перезагружаемся.\nПроверить можно командой с PCI iGPU:\nsudo lsof /dev/dri/by-path/pci-0000:11:00.0-card | grep kwin Что-то будет. И с PCI dGPU:\nsudo lsof /dev/dri/by-path/pci-0000:01:00.0-card | grep kwin Должно быть пусто. WARNING\u0026rsquo;и не в счет.\nТак же доп. проверка если у вас NVIDIA:\nsudo lsof /dev/nvidia* /dev/dri/by-path/pci-0000:01:00.0* Вот тут вообще должно быть пусто. Но если там что-то есть, и это не что-то системное типа KWin, то нестрашно, хук или ваши руки просто могут убить процесс и все. А вот если это KWin, то так не получится.\nСтруктуру хуков и диспетчер мы настраивали выше в Pinning CPU ядер \u0026amp; HugePages, если вы это пропустили, метнитесь туда, сделайте и вернитесь сюда.\nНе забудьте в скриптах поменять PCI на свои.\nsudo nano /etc/libvirt/hooks/qemu.d/win11/prepare/begin/10-dgpu-nvidia-detach.sh detach.sh Loading file... vfio/qemu-hooks/dgpu/nvidia/detach.sh sudo nano /etc/libvirt/hooks/qemu.d/win11/release/end/90-dgpu-nvidia-attach.sh attach.sh Loading file... vfio/qemu-hooks/dgpu/nvidia/attach.sh Сделать хуки исполняемыми:\nVM=\u0026#34;win11\u0026#34;; sudo find /etc/libvirt/hooks/qemu.d/\u0026#34;$VM\u0026#34; -type f -name \u0026#39;*.sh\u0026#39; \\( -path \u0026#39;*/prepare/begin/*\u0026#39; -o -path \u0026#39;*/prepare/end/*\u0026#39; -o -path \u0026#39;*/release/begin/*\u0026#39; -o -path \u0026#39;*/release/end/*\u0026#39; \\) -exec chmod +x {} + Где win11 имя вашей VM.\n📝 Если у вас НЕ KDE Plasma, но при этом KDE Plasma в системе имеется \u0026ndash; закомментируйте строки с (KDE), в случае если у вас нету KDE просто ничего не будет. Если KDE есть, но вы не используете KDE то, что-то будет, что-то, что вам вероятно не нужно. Перезапускаем сервис, чтобы обновить хуки:\nsudo sh -c \u0026#39;systemctl restart virtqemud \u0026amp;\u0026amp; systemctl status virtqemud\u0026#39; Тут есть неочевидная проблемка. Если вырубят свет или вы решите пнуть кнопку выключения ПК, пока виртуалка запущена, скрипт на выключение не выполнится. А повторный запуск виртуалки не увенчается успехом, потому что выгружать будет нечего. В таком случае нужно будет выполнить скрипт \u0026ldquo;при выключении\u0026rdquo; вручную, ничего особенного.\nПоследний шаг \u0026ndash; посмотреть самый конец главы выше (про добавление PCI dGPU и удаление других устройств).\nПериферия \u0026ndash; Звук Все работает, а звука нет, ща исправим. Это также будет работать и с микрофоном.\nБудет на примере \u0026ldquo;PulseAudio (on PipeWire 1.6.7)\u0026rdquo; \u0026ndash; это означает, что реально PipeWire, PulseAudio для совместимости. Узнать что у вас можно pactl info.\nsudo zypper in -y qemu-audio-pa qemu-audio-pipewire Проверить можно:\nqemu-system-x86_64 -audiodev help Должны были появиться pa и pipewire.\nЕсли все ок, перезапускаем сервис:\nsudo sh -c \u0026#39;systemctl restart virtqemud \u0026amp;\u0026amp; systemctl status virtqemud\u0026#39; Создаем конфигурацию:\nmkdir -p ~/.config/pipewire/pipewire-pulse.conf.d 1 2 3 4 5 6 7 8 cat \u0026gt; ~/.config/pipewire/pipewire-pulse.conf.d/10-tcp.conf \u0026lt;\u0026lt; \u0026#39;EOF\u0026#39; pulse.properties = { server.address = [ \u0026#34;unix:native\u0026#34; \u0026#34;tcp:4713\u0026#34; ] } EOF Рестартим pipewire сервис:\nsystemctl --user restart pipewire-pulse Проверка:\nss -tlnp | grep 4713 \u0026amp;\u0026amp; pactl --server=127.0.0.1:4713 info Должно быть так:\n1 2 3 LISTEN 0 32 0.0.0.0:4713 0.0.0.0:* users:((\u0026#34;pipewire-pulse\u0026#34;,pid=2735,fd=17)) LISTEN 0 32 [::]:4713 [::]:* users:((\u0026#34;pipewire-pulse\u0026#34;,pid=2735,fd=18)) Server String: 127.0.0.1:4713 В настройках виртуалки удаляем существующий \u0026ldquo;Sound X\u0026rdquo; и создаем новый - ICH9. Далее Overview и там в XML внутри \u0026lt;devices\u0026gt;:\n1 \u0026lt;audio id=\u0026#34;1\u0026#34; type=\u0026#34;pulseaudio\u0026#34; serverName=\u0026#34;127.0.0.1:4713\u0026#34;/\u0026gt; И добавить \u0026lt;audio id=\u0026quot;1\u0026quot;/\u0026gt; внутрь тега \u0026lt;sound\u0026gt;.\nДо запуска виртуалки проверить можно командой:\nsudo virsh dumpxml win11 | grep -A3 audio Это микширование звука, настройте под себя звук внутри VM, а также в микшере хоста. И если помните, я советовал не пробрасывать медиа клавиши клавиатуры, благодаря этому если выровнять звук гостя под хост, чтобы они были примерно одинаковыми, то находясь в госте с захватом клавиш и тыкая на медиа клавиши \u0026ndash; вы будете менять сразу и гостя и хост, прям как на \u0026ldquo;просто одной системе\u0026rdquo;.\n💡 Выровнять звук довольно просто, в госте на 100%, в микшере хоста тоже, а общую громкость хоста уже настраиваете как обычно. 🚧 При старте VM сразу после старта системы может выбить ошибку:\npulseaudio: Wrong context state Reason: Connection refused это нормально. Оно так потому что сервис еще не запустился и соответственно сокет не работает.\nЗапустится либо со второго раза, либо дайте звук перед запуском VM. Альтернатива:\nsystemctl --user enable pipewire-pulse.service Скрытие и ускорение виртуалки Это базовое скрытие, полное KVM скрытие \u0026ndash; это целая наука и конечно же патчинг QEMU и ядра Linux, что уже труднее и описано здесь не будет, но возможно когда-нибудь я про это напишу. А ускорение это так называемое \u0026ldquo;Hyper-V Enlightenments\u0026rdquo; (что тесно связано с базовым, но современным скрытием), чтобы для каких-то вещей не происходил тяжелый VM Exit в хост, а инструкции шли как для Hyper-V (родная среда виртуализации Windows).\nДа, казалось бы небольшое противоречие, скрыть факт виртуализации, но при этом прямо сказать системе, что она виртуалка, кажется таким себе решением, но это типа окей.\nВсе делается в XML, я думаю, вы к этому времени там уже много раз побывали.\nВ \u0026lt;cpu\u0026gt; у вас уже должно быть типа такого:\n1 2 3 \u0026lt;cpu mode=\u0026#34;host-passthrough\u0026#34; check=\u0026#34;none\u0026#34; migratable=\u0026#34;on\u0026#34;\u0026gt; \u0026lt;topology sockets=\u0026#34;1\u0026#34; dies=\u0026#34;1\u0026#34; cores=\u0026#34;6\u0026#34; threads=\u0026#34;2\u0026#34;/\u0026gt; \u0026lt;/cpu\u0026gt; Туда же внутрь \u0026lt;cpu\u0026gt; нужно добавить:\n1 2 \u0026lt;cache mode=\u0026#34;passthrough\u0026#34;/\u0026gt; \u0026lt;feature policy=\u0026#34;require\u0026#34; name=\u0026#34;invtsc\u0026#34;/\u0026gt; А также заменить migratable=\u0026quot;on\u0026quot; на migratable=\u0026quot;off\u0026quot;.\nЕсли у вас AMD (с SMT, а я надеюсь, что с SMT) то также добавить \u0026lt;feature policy=\u0026quot;require\u0026quot; name=\u0026quot;topoext\u0026quot;/\u0026gt;.\nБлок \u0026lt;features\u0026gt; должен выглядеть так:\nfeatures.xml xml Loading file... vfio/qemu-xml/features.xml А блок \u0026lt;clock\u0026gt; должен выглядеть так:\nclock.xml xml Loading file... vfio/qemu-xml/clock.xml Найдите в самом верху тег \u0026ldquo;uuid\u0026rdquo; и скопируйте значение, также выполните:\nsudo dmidecode -s baseboard-serial-number И скопируйте полученное значение тоже, даже если там \u0026ldquo;Default string\u0026rdquo; :D\nВставьте в XML после \u0026lt;/cputune\u0026gt;:\nsysinfo.xml xml Loading file... vfio/qemu-xml/sysinfo.xml Не забудьте поменять серийник и UUID.\nНайдите \u0026lt;os\u0026gt; и добавьте внутрь:\n1 \u0026lt;smbios mode=\u0026#34;sysinfo\u0026#34;/\u0026gt; Также ищем \u0026lt;interface type=\u0026quot;network\u0026quot;\u0026gt;, там меняем MAC адрес на 00:15:5D:xx:xx:xx, где X\u0026rsquo;ы любое значение, но не 00 и FF. После в госте проверить можно ipconfig /all. 00:15:5D это MAC hyper-v, а 52:54:00 \u0026ndash; qemu.\nИ уберите из \u0026lt;devices\u0026gt;:\n1 2 3 \u0026lt;input type=\u0026#34;tablet\u0026#34; bus=\u0026#34;usb\u0026#34;\u0026gt; \u0026lt;address type=\u0026#34;usb\u0026#34; bus=\u0026#34;0\u0026#34; port=\u0026#34;1\u0026#34;/\u0026gt; \u0026lt;/input\u0026gt; Также в самом конце найдите memballoon, и сделайте так (выключите):\n1 2 3 4 5 \u0026lt;memballoon model=\u0026#34;virtio\u0026#34;\u0026gt; \u0026lt;address type=\u0026#34;pci\u0026#34; domain=\u0026#34;0x0000\u0026#34; bus=\u0026#34;0x05\u0026#34; slot=\u0026#34;0x00\u0026#34; function=\u0026#34;0x0\u0026#34;/\u0026gt; \u0026lt;/memballoon\u0026gt; ↓ \u0026lt;memballoon model=\u0026#34;none\u0026#34;/\u0026gt; memballoon по сути не используется, но существует и делает вызовы, зачем ему делать вызовы и потенциально вызывать фризы, если он не работает, правильно? Также в Windows если заметили процесс \u0026ldquo;blnsvr.exe\u0026rdquo; в диспетчере, можно отключить BallonService в сервисах, иначе он так же будет работать вхолостую.\nВ диспетчере задач \u0026ldquo;Virtual Machine: Yes\u0026rdquo;, никуда не пропадет, цель сделать современно и не потерять в производительности, а значит не прям скрыть-скрыть факт виртуализации, а сделать вид, что это \u0026ldquo;легальная\u0026rdquo; виртуализация. В терминале \u0026ndash; systeminfo, если в самом низу \u0026ldquo;A hypervisor has been detected. Features required for Hyper-V will not be displayed.\u0026rdquo; \u0026ndash; значит все работает.\nЭтот статус появляется, если вы включаете в системе Core Isolation или WSL, то бишь это абсолютно легальные функции которые тригерят этот статус. А производительность лучше, потому что Windows не эмулирует вызовы, а использует быстрые \u0026ldquo;родные\u0026rdquo; Hyper-V.\nБлагодаря этим манипуляциям мой средний FPS в бенчмарке Cyberpunk 2077 стал 140 \u0026ndash;\u0026gt; 162, в то время как на голом железе он 163. Уровень погрешности. Удивительно, неправда ли?\nНастройка сети Просто небольшая правка, чтобы закрепить IP адрес за виртуалкой (чтобы он не менялся).\nВ настройках виртуалки \u0026ndash;\u0026gt; NIC и там скопируйте MAC адрес.\nДалее в главном окне со списком виртуалок \u0026ndash;\u0026gt; тык на виртуалку \u0026ndash;\u0026gt; Edit \u0026ndash;\u0026gt; Connection Details \u0026ndash;\u0026gt; Virtual Networks \u0026ndash;\u0026gt; XML, в блок dhcp добавить:\n1 \u0026lt;host mac=\u0026#34;MAC\u0026#34; ip=\u0026#39;192.168.122.5\u0026#39;/\u0026gt; Применить, и в том же окне нажать на кнопку Stop Network, затем Start Network.\nПроверить можно введя ipconfig в терминале Windows.\nГостевые дополнения В Windows можно в любом случае или нет установить \u0026ldquo;гостевые дополнения\u0026rdquo;, вы можете сделать это сразу, или не делать если оно вам не нужно.\nЭтот раздел в основном нужен, чтобы ссылаться на него, когда это нужно установить, поэтому в любом случае если это будет нужно, вы об этом узнаете.\nПерейти на https://www.spice-space.org/download.html и в разделе \u0026ldquo;Windows binaries\u0026rdquo; скачать и установить \u0026ldquo;spice-guest-tools\u0026rdquo;.\nА также переходим на https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/stable-virtio/ качаем и устанавливаем \u0026ldquo;virtio-win-guest-tools.exe\u0026rdquo;.\nПерезагружаем Windows, разумеется.\nОбщий буфер обмена и общие папки (Samba) Самое удобное удобство. Если вкратце, что мы сделаем:\nОбщий буфер обмена включая текст и пикчи (только если MIME тип изображения \u0026ndash; скриншоты). Шара Samba. Скрипт для удобного \u0026ldquo;копирования\u0026rdquo; файлов на шару без траты TBW (ну чтоб наверняка). Буфер обмена Мини предисловие. Я пробовал нативно, много пробовал. Конкретно через полу-spice, как spice только не spice, без графики. Но Wayland не дает читать буфер обмена пока окно не в фокусе, то есть:\nкопировать \u0026ndash;\u0026gt; ткнуть окно spice \u0026ndash;\u0026gt; вставить. Неудобно, но конечно же есть костыль с GDK_BACKEND=x11.\nНо это не все мины подводные, text/plain работает в обе стороны, но без русского текста. text/plain\\;charset=utf=8 работает только из гостя в хост, из хоста в гостя см. воркфлоу выше. Ну и конечно же постоянно ломающееся окружение (полностью нерабочая панель задач и \u0026ldquo;пуск\u0026rdquo;) из-за GDK_BACKEND=x11. И еще пара десятков проблем, а потому\u0026hellip;\nClipCascade ClipCascade это такая софтина для (барабанная дробь) шеринга буфером обмена по сети, и все, только для этого. Прям то что надо. С этим способом будет небольшая задержка передачи данных буфера обмена между системами, но пока вы переключаете ввод, чтобы вставить оно уже передаст. Без докера будет тяжко.\nsudo zypper in docker-compose docker-compose-switch wl-clipboard sudo systemctl enable --now docker sudo usermod -G docker -a $USER newgrp docker sudo systemctl restart docker mkdir -p ClipCascade \u0026amp;\u0026amp; cd ClipCascade \u0026amp;\u0026amp; nano docker-compose.yaml 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 services: clipcascade: image: sathvikrao/clipcascade:latest container_name: clipcascade # user: \u0026#34;1000:1000\u0026#34; ports: - \u0026#34;127.0.0.1:8080:8080\u0026#34; - \u0026#34;192.168.122.1:8080:8080\u0026#34; # restart: always # Обратите внимание, выключено т.к. далее создадим юнит volumes: - ./cc_users:/database:z environment: - CC_MAX_MESSAGE_SIZE_IN_MiB=10 - CC_P2P_ENABLED=false # - CC_SIGNUP_ENABLED=true mkdir cc_users docker compose up -d \u0026amp;\u0026amp; docker compose logs -f Далее клиент, качаем архив с репозитория GitHub и распаковываем куда удобно.\npython3 -m venv venv source venv/bin/activate pip install -r requirements.txt python main.py --gui false --xmode false --xmode false \u0026ndash; это для Wayland.\nПопросит войти, логин:пароль \u0026ndash; admin:admin123 , остальное тыкайте Enter (или сначала прочитайте текст ниже).\nНа Windows качаем .exe (portable) или .msi (установщик) отсюда https://github.com/Sathvik-Rao/ClipCascade/releases, если .exe то создаем папку и кидаем туда .exe. Авторизация по тем же данным, но Server URL: http://192.168.122.1:8080.\n📝 Крутейшие данные для авторизации в этом случае менять не обязательно (ТОЛЬКО В ЭТОМ СЛУЧАЕ), потому что мы гоняем данные по сети хоста, ничего за пределы вашего ПК не уходит.\nСоответственно шифрование тоже можно не использовать, будет работать быстрее и стабильнее.\nА также в доп. настройках можно сделать, чтобы пароль сохранялся в файл, тогда не придется каждый раз авторизоваться после перезапуска докер контейнера (а это значит после перезагрузки хоста).\nЕсли все работает то круто. Надо только это автоматизировать, ClipCascade создает DATA файл, там уже все есть, нужно просто запускать приложения в фоне.\nДля начала докер, формально уже все есть, но докер стартует раньше libvirt, как итог \u0026ndash; он не стартует, потому что нет сети. Варианта два, глобальный для ВСЕХ контейнеров и разовый юнит, предлагаю юнит:\nsudo nano /etc/systemd/system/clipcascade-server-docker.service 1 2 3 4 5 6 7 8 9 10 11 12 13 14 [Unit] Description=ClipCascade Docker Compose After=docker.service virtnetworkd.service Requires=docker.service virtnetworkd.service [Service] Type=oneshot RemainAfterExit=yes WorkingDirectory=/home/\u0026lt;USERNAME\u0026gt;/Software/InDocker/ClipCascade ExecStart=/usr/bin/docker compose up -d ExecStop=/usr/bin/docker compose down [Install] WantedBy=multi-user.target Не забудьте указать свои пути.\nsudo systemctl daemon-reload sudo sh -c \u0026#39;systemctl enable --now clipcascade-server-docker.service \u0026amp;\u0026amp; systemctl status clipcascade-server-docker.service\u0026#39; Далее демон клиента ClipCascade:\nnano ~/.config/systemd/user/clipcascade.service 1 2 3 4 5 6 7 8 9 10 11 12 13 [Unit] Description=ClipCascade Client After=graphical-session.target [Service] Type=simple WorkingDirectory=%h/Software/ClipCascade/ ExecStart=/usr/bin/bash -c \u0026#34;tail -f /dev/null | %h/Software/ClipCascade/venv/bin/python3 -u main.py --gui false --xmode false\u0026#34; Restart=always RestartSec=3 [Install] WantedBy=graphical-session.target %h/ = /home/username/ (работает только в юзерских сервисах).\nsystemctl --user daemon-reload systemctl --user enable --now clipcascade.service \u0026amp;\u0026amp; systemctl --user status clipcascade.service Логи можно так поглядеть:\njournalctl --user -u clipcascade.service -f Далее Windows.\nЕсли portable:\nПросто сделайте ярлык с ALT и киньте его в WIN + R \u0026ndash;\u0026gt; shell:startup.\nЕсли установщик:\nНичего не делать.\nОбщее:\nВ параметрах в поиске Firewall \u0026ndash;\u0026gt; Windows Defender Firewall \u0026ndash;\u0026gt; Allow an app or feature\u0026hellip; \u0026ndash;\u0026gt; сюда добавить ClipCascade.exe. Чисто на всякий случай.\nWIN + R \u0026ndash;\u0026gt; intl.cpl \u0026ndash;\u0026gt; Administrative \u0026ndash;\u0026gt; Change system locale \u0026ndash; Use Unicode UTF-8\u0026hellip;, и перезагрузить, иначе без этого возможно не сможете копировать и вставлять не английский текст.\nДругая автоматизация:\nЕсли вас не устраивает постоянная работа ClipCascade в фоне на хосте, все-таки это Java которая отжирает в среднем 400-900мб ОЗУ просто потому что это Java, можно запуск и выключение запихнуть в хуки.\nДалее нужно переключить docker на тот же бэкенд, который использует libvirt в вашей системе, в случае openSUSE это nftables.\n🚧 Далее где virbr0 \u0026ndash; ваш бридж KVM, по дефолту (сеть \u0026ldquo;default\u0026rdquo;) это именно \u0026ldquo;virbr0\u0026rdquo;. Если запускать докер до VM/при старте ОС, а потом саму VM, то все будет окей. Но если запускать сначала VM, а потом докер, то ломается сеть KVM (1, 2). Это из-за конфликта с другими \u0026ldquo;владельцами\u0026rdquo; правил сети.\nТо что описано ниже это экспериментальная фича в новом docker (\u0026gt;=29) (на момент написания этого текста), и с ней работает не все фичи docker, если у вас домашний ПК, а не сервер где нужен SLA 100% и вы не используете Swarm \u0026ndash; то почему бы и нет.\nМеняем бэкенд:\nsudo nano /etc/docker/daemon.json Туда добавляем \u0026quot;firewall-backend\u0026quot;: \u0026quot;nftables\u0026quot;.\nВключаем ip forwarding вручную, потому что это так-то делает сам docker, но в моем случае с nftables \u0026ndash; не делает, поэтому:\necho \u0026#34;net.ipv4.ip_forward = 1\u0026#34; | sudo tee /etc/sysctl.d/99-ip-forward.conf \u0026amp;\u0026amp; sudo sysctl --system sudo systemctl restart docker \u0026amp;\u0026amp; docker ps \u0026amp;\u0026amp; systemctl --user restart clipcascade.service \u0026amp;\u0026amp; systemctl --user status clipcascade.service Проверяем, что оно сменилось:\nsudo nft list tables Там должно быть ip docker-bridges/ip6 docker-bridges.\nДалее выключаем сервис/клиент и их автозапуск (если вы это включали ранее):\nsudo systemctl disable --now clipcascade-server-docker.service \u0026amp;\u0026amp; systemctl --user disable --now clipcascade.service И делаем хуки:\nsudo nano /etc/libvirt/hooks/qemu.d/win11/prepare/begin/95-clipcascade.sh 95-clipcascade.sh Loading file... vfio/qemu-hooks/start/95-clipcascade.sh sudo nano /etc/libvirt/hooks/qemu.d/win11/release/end/95-clipcascade.sh 95-clipcascade.sh Loading file... vfio/qemu-hooks/stop/95-clipcascade.sh Сделать хуки исполняемыми:\nVM=\u0026#34;win11\u0026#34;; sudo find /etc/libvirt/hooks/qemu.d/\u0026#34;$VM\u0026#34; -type f -name \u0026#39;*.sh\u0026#39; \\( -path \u0026#39;*/prepare/begin/*\u0026#39; -o -path \u0026#39;*/prepare/end/*\u0026#39; -o -path \u0026#39;*/release/begin/*\u0026#39; -o -path \u0026#39;*/release/end/*\u0026#39; \\) -exec chmod +x {} + Где win11 имя вашей VM.\nПерезагружаем хост, чтоб прям наверняка все проверить, запускаем виртуалку, проверяем буфер обмена, затем выключаем виртуалку.\ndocker ps \u0026amp;\u0026amp; echo \u0026amp;\u0026amp; systemctl --user status clipcascade.service Альтернативы Если вдруг вам не нравится ClipCascade, то можно попробовать UniClipboard или вовсе KDE Connect, но возможно там не будет работать буфер изображений, только текста (насчет UniClipboard \u0026ndash; не уверен, насчет KDE Connect \u0026ndash; вероятно не будет).\nОбщие папки Разумеется Samba, как же иначе?\nСоздайте или морально выберите \u0026ldquo;shared\u0026rdquo; папку, в моем случае ~/Public/KVM. У папки должны быть права 755 а.к.а drwxr-xr-x, именно с такими правами вы по умолчанию создаете папки от своего имени юзера (не root).\nОткрываем YaST \u0026ndash;\u0026gt; Network Services \u0026ndash;\u0026gt; Samba Server. Да можно было и руками, но YaST все сделает за вас, почему бы и нет.\nWORKGROUP оставьте WORKGROUP, это неважно.\nStart-Up:\nAfter writing configuration: Start After reboot: Start on boot Shares:\nAdd\u0026hellip; \u0026ndash;\u0026gt; Добавьте свою папку Share Name: Что-нибудь связанное с темой (у меня одноименно с названием папки), это вам еще понадобится Share Description: Если надо Share Type: Directory, а не Printer Share Path: выберите свою папку что создали ранее Read-Only: ❌ Inherit ACLs: ❌ Expose Snapshots: ❌ Utilize Btrfs Features: ❌ (это про снапшоты, вроде как) Allow Users to Share Their Directories: ❌ Identity, Trusted Domain и LDAP Settings трогать не надо. Жмите ОК.\nДалее чутка изменим конфиг:\nsudo nano /etc/samba/smb.conf В [global]:\nunix extensions = no И там же smb3 directory leases = Yes заменить на No.\nДалее найти [kvm] (ваш Share Name) и туда в блок добавить:\n1 2 3 4 5 6 force user = username force group = username create mask = 0664 directory mask = 0775 follow symlinks = yes wide links = yes Где username ваш юзернейм. Это чтобы Windows делала файлы с правильными правами и вы могли свободно с ними работать на хосте.\ntestparm если все ok, то все ок.\nПерезапускаем сервис:\nsudo sh -c \u0026#39;systemctl restart smb nmb \u0026amp;\u0026amp; systemctl status smb nmb\u0026#39; Установить пароль для юзера samba:\nsudo smbpasswd -a username Где username опять же ваш юзернейм.\nЭто нужно потому что иначе Windows вас за*ебет, если есть желание покопаться в реестре и групповых политиках, то можете не ставить пароль, но тогда еще придется включить Guest mode для вашей папки в samba (можно сделать в YaST).\nПроверка:\nsmbclient -L 127.0.0.1 -N \u0026amp;\u0026amp; smbclient -L 192.168.122.1 -N Должно быть что-то типа:\n1 2 3 4 5 6 7 8 9 Sharename Type Comment --------- ---- ------- profiles Disk Network Profiles Service users Disk All users print$ Disk Printer Drivers KVM Disk For KVM IPC$ IPC IPC Service (Samba 4.24.3-git.475.629de6765b9SUSE-oS16.9-x86_64) nobody Disk Home Directories SMB1 disabled -- no workgroup available На обе команды. И контрольная проверка:\nsmbclient //192.168.122.1/KVM -N Где KVM это ваш Share Name.\nПравила фаервола, просто на всякий случай:\nsudo sh -c \u0026#39;firewall-cmd --zone=libvirt --add-service=samba --permanent \u0026amp;\u0026amp; firewall-cmd --reload \u0026amp;\u0026amp; firewall-cmd --zone=libvirt --list-services\u0026#39; И если выполните:\nsudo ss -tlnp | grep 445 То увидите, что samba слушает все адреса, то есть доступна для других ПК в локальной сети, или в интернете (если у вас белый IP и не закрыты порты на роутере). Если вам samba не нужна для других сценариев использования, то лучше сделать так, чтобы она слушала только localhost и сеть KVM соответственно:\nsudo nano /etc/samba/smb.conf В [global]:\n1 2 interfaces = lo virbr0 bind interfaces only = yes lo \u0026ndash; localhost virbr0 \u0026ndash; дефолтная (буквально \u0026ldquo;default\u0026rdquo;) сеть KVM testparm sudo sh -c \u0026#39;systemctl restart smb nmb \u0026amp;\u0026amp; systemctl status smb \u0026amp;\u0026amp; systemctl status nmb \u0026amp;\u0026amp; sudo ss -tlnp | grep 445\u0026#39; Если вы сделали interfaces = lo virbr0 При настройке общего буфера обмена мы делали так если он должен был запускаться вместе с системой.\nНужно поменять сервисы samba чутка:\nsudo systemctl edit smb.service sudo systemctl edit nmb.service В оба сервиса добавить:\n1 2 3 4 5 6 7 8 9 10 ... ### Anything between here and the comment below will become the contents of the drop-in file [Unit] After=virtnetworkd.service Requires=virtnetworkd.service ### Edits below this comment will be discarded ... Это нужно чтобы samba стартовала строго после kvm сети, иначе она упадет потому что сети еще не будет.\nДля справки, в чем прикол, если сделать это только для сервиса буфера обмена и запускать его вместе с системой, он будет тригерить запуск kvm сети, из-за чего samba будет работать с interfaces = lo virbr0, но если не запускать сервис буфера обмена вместе с системой то samba не будет работать без этих правок. Но так или иначе лучше это добавить в любом случае если вы используете interfaces = lo virbr0, независимо от того как вы запускаете сервис буфера обмена, так банально надежнее.\nВ Windows, ПКМ по This PC \u0026ndash;\u0026gt; Map network drive \u0026ndash;\u0026gt; Folder \u0026ndash; \\\\192.168.122.1\\KVM. Connect using different credentials, там ваш username и пароль, и галочка на Remember my credentials. И не забудьте про галочку \u0026ldquo;Reconnect at sign-in\u0026rdquo;, чтобы он автоматом подключался.\nИ проверьте, что все работает, посоздавайте файлы, и проверьте права на хосте ls -l.\nСкрипт для симлинков (если надо).\nrl.sh Loading file... vfio/scripts/host/rl.sh nano ~/Scripts/rl.sh chmod +x ~/Scripts/rl.sh ln -s ~/Scripts/rl.sh ~/.local/bin/rl В начале скрипта укажите пути до папок/симлинков на шаре.\nЧтобы использовать просто введите rl это help.\nrl file \u0026ndash; сделать симлинк на файл rl dir/ \u0026ndash; сделать симлинк на директорию rl file1 file2 dir1 dir2 \u0026ndash; сделать 4 симлинка. Скрипт сам детектит диск, если вы делаете симлинк на файл/директорию которые находятся на \u0026ldquo;Disk 1\u0026rdquo;, то и симлинк он кинет в \u0026ldquo;Disk 1\u0026rdquo; на шаре, аналогично с \u0026ldquo;Disk 2\u0026rdquo; и тд. и тп.\nПро симлинки на директории, Windows удаляет папки рекурсивно, поэтому при удалении симлинков директорий на Windows, Windows заходит внутрь (так как не знает что это симлинк) и удаляет содержимое. У Windows такого страшного дела сделать не получается и папка не удаляется. Короче говоря, симлинки на папки можно удалять только с хоста.\nЕсли шарите второй диск (для системного диска так лучше не делать!), а он просто не работает (DENIED) и у вас SELinux (на момент написания текста у openSUSE по дефолту SELinux), не забудьте про:\nsudo semanage fcontext -a -t samba_share_t \u0026#34;/mnt/second(/.*)?\u0026#34; sudo restorecon -R -v /mnt/second Проверить можно так:\nsudo semanage fcontext -l | grep second Где second ваша точка монтирования. Должно вывести samba_share_t.\nДополнительно Аппаратные штуки По умолчанию аппаратные фичи отключены по юридическим причинам. Так то темы виртуализации это особо не касается, а скорее про настройку ОС. Но может быть такое, что виртуалка не сможет использовать эти фичи, если их нету на хосте, поэтому я это и добавил, а оно так потому что host-passthrough \u0026ndash; дает виртуалки юзать аппаратные фичи процессора.\nАппаратные фичи можно проверить:\ngrep -E \u0026#34;aes|sha\u0026#34; /proc/cpuinfo Будет полотно текста, ищите наличие aes и sha. А также:\nsudo zypper in libva-utils vainfo Если в списке отсутствует H.264 и H.265, то они отключены и их бы включить.\nsudo zypper in opi opi codecs И со всем соглашайтесь в процессе. Если в процессе все встало и вы видите 403 ошибку, расчехляйте ВПН друзья и попробуйте снова (то что уже установило оно устанавливать не будет).\nНа будущее, при обновлении системы zypper dup, если будут ошибки с пакетами, так как в openSUSE могли их обновить, а в packman еще нет, выбирайте вариант в стиле \u0026ldquo;оставить старые версии\u0026rdquo; и просто попробуйте еще раз через пару дней, иначе лишитесь кодеков.\nСнова проверяем:\nvainfo И наблюдаем новые кодеки.\nПроверить в Windows это тоже можно.\nДля CPU:\nПроверить можно через CPU-Z, а конкретно \u0026ldquo;Instructions\u0026rdquo;.\nДля dGPU (NVIDIA):\nnvidia-smi Должно вывести таблицу. В диспетчере задач в Performance \u0026ndash;\u0026gt; GPU должны быть Video Encode и Decode.\nLooking Glass (альтернатива переключению на мониторе) LookingGlass \u0026ndash; альтернатива физическому переключению видеовыхода на мониторе, дает больше задержек, и сильнее нагружает систему, но удобно для работы или легких игр типа Kenshi или Sims. Ну, точнее, вам ничего не мешает использовать LG для чего угодно, но нативная картинка прямиком из GPU всегда будет лучше.\nОчевидный плюс это окошко, что существует в хосте, а значит вам по-прежнему будут доступны монитор(ы) хоста и при этом вы сможете свободно крутить, вертеть, перемещать, \u0026ldquo;сворачивать Windows\u0026rdquo;, удобно.\nВсе же однажды мечтали \u0026ldquo;свернуть\u0026rdquo; Windows?\nLooking Glass также умеет пробрасывать клавиатуру, мышь, буфер обмена и звук, что довольно удобно. Но работать это будет через spice, что довольно неудобно, ну на Wayland. Поэтому учитывая что я показывал как все это настроить по отдельности \u0026ndash; мы настроим LG чтобы только на Windows глазами глядеть, не более.\nДля гостя нужны virtio драйвера см. здесь.\nНужно установить пакеты, но из-за того, что один из пакетов \u0026ndash; это kmp, в идеале сначала обновить всю систему sudo zypper dup и перезагрузить ПК. Иначе оно может в качестве зависимости обновить ядро Linux без обновления всего остального, что не есть хорошо.\nПакеты:\nsudo zypper install looking-glass-client looking-glass-kvmfr-kmp-default Looking Glass не умеет в больше 1-го монитора, и Looking Glass захватит тот, что в госте ОСНОВНОЙ. То есть, размер надо рассчитывать исходя из монитора который будет захватываться.\nМатематика такая: $$ ((width \\times height) \\times (pixel\\_size \\times 2) \\div 1024 \\div 1024) + 10 $$\nЭто размер кадра в МиБ + оверхед в 10 МиБ для служебных данных, это нужно округлить до ближайшей степени двойки.\nУ SDR (32-бит) pixel_size = 4, у HDR (64-бит) = 8.\nНу например FULLHD SDR:\n$$ ((1920 \\times 1080) \\times (4 \\times 2) \\div 1024 \\div 1024) + 10 = 25.8 \\approx 32 \\ МиБ $$\nПо порядку $\\ 1920 \\times 1080 = 2073600$ $\\ 2073600 \\times 8 = 16588800$ $\\ 16588800 \\div 1024 = 16200$ $\\ 16200 \\div 1024 = 15.8203125$ $\\ 15.8203125 + 10 = 25.8203125$ $\\ 25.8203125 \\to 2^{\\lceil \\log_2 25.8203125 \\rceil} = 32$ Примеры:\nРазрешение Кадр + 10 МиБ Округление до степени 2 1920×1080 15.8 МиБ 25.8 МиБ 32 МиБ 2560×1440 28.1 МиБ 38.1 МиБ 64 МиБ 3440×1440 (ultrawide) 37.8 МиБ 47.8 МиБ 64 МиБ 3840×2160 (4K) 63.3 МиБ 73.3 МиБ 128 МиБ Если вы не минималист, у вас не супер-дупер 32к телевизор и вы не хотите париться \u0026ndash; просто делайте 256 МиБ.\nНастройка модуля:\necho \u0026#34;options kvmfr static_size_mb=32\u0026#34; | sudo tee /etc/modprobe.d/kvmfr.conf Где 32 \u0026ndash; тот самый размер в МиБ.\necho kvmfr | sudo tee /etc/modules-load.d/kvmfr.conf sudo modprobe kvmfr Проверка:\nls -la /dev/kvmfr0 udev (права доступа):\nsudo nano /etc/udev/rules.d/71-kvmfr.rules SUBSYSTEM==\u0026#34;kvmfr\u0026#34;, GROUP=\u0026#34;kvm\u0026#34;, MODE=\u0026#34;0660\u0026#34; sudo sh -c \u0026#39;udevadm control --reload-rules \u0026amp;\u0026amp; udevadm trigger\u0026#39; В /etc/libvirt/qemu.conf добавить \u0026quot;/dev/kvmfr0\u0026quot; в cgroup_device_acl.\nПерезапустить сервис:\nsudo sh -c \u0026#39;systemctl restart virtqemud \u0026amp;\u0026amp; systemctl status virtqemud\u0026#39; Далее:\nsudo EDITOR=nano virsh edit \u0026lt;имя_вашей_vm\u0026gt; Там в самом начале:\n1 2 3 \u0026lt;domain type=\u0026#39;kvm\u0026#39;\u0026gt; 🡓 \u0026lt;domain type=\u0026#39;kvm\u0026#39; xmlns:qemu=\u0026#39;http://libvirt.org/schemas/domain/qemu/1.0\u0026#39;\u0026gt; И в самом конце, после закрывающегося \u0026lt;/devices\u0026gt;, но до закрывающегося \u0026lt;/domain\u0026gt; добавить:\n1 2 3 4 5 6 \u0026lt;qemu:commandline\u0026gt; \u0026lt;qemu:arg value=\u0026#34;-device\u0026#34;/\u0026gt; \u0026lt;qemu:arg value=\u0026#39;{\u0026#34;driver\u0026#34;:\u0026#34;ivshmem-plain\u0026#34;,\u0026#34;id\u0026#34;:\u0026#34;shmem0\u0026#34;,\u0026#34;memdev\u0026#34;:\u0026#34;looking-glass\u0026#34;}\u0026#39;/\u0026gt; \u0026lt;qemu:arg value=\u0026#34;-object\u0026#34;/\u0026gt; \u0026lt;qemu:arg value=\u0026#39;{\u0026#34;qom-type\u0026#34;:\u0026#34;memory-backend-file\u0026#34;,\u0026#34;id\u0026#34;:\u0026#34;looking-glass\u0026#34;,\u0026#34;mem-path\u0026#34;:\u0026#34;/dev/kvmfr0\u0026#34;,\u0026#34;size\u0026#34;:33554432,\u0026#34;share\u0026#34;:true}\u0026#39;/\u0026gt; \u0026lt;/qemu:commandline\u0026gt; 33554432 \u0026ndash; это 32 МиБ, но в байтах, $32 \\times 1024 \\times 1024$ .\nПроверка:\nsudo virsh dumpxml \u0026lt;имя_вашей_vm\u0026gt; | grep -A6 \u0026#34;qemu:commandline\u0026#34; 📝 Поясняю \u0026ldquo;а че так\u0026rdquo;. Virtual Machine Manager (GUI) просто не дает отредачить/добавить эти параметры, они просто удалятся при сохранении.\nНо, если добавить через virsh edit, а потом менять какой-то XML через Virtual Machine Manager \u0026ndash; оно уже не будет удаляться.\nДалее конфиг:\nmkdir -p ~/.config/looking-glass \u0026amp;\u0026amp; nano ~/.config/looking-glass/client.ini 1 2 3 4 5 [app] shmFile=/dev/kvmfr0 [spice] enable=no Также рекомендую:\n1 2 3 [input] hideCursor=no escapeKey=KEY_ESC Самое главное, это escapeKey, курсор по желанию. У вас есть клавиша Scroll Lock? А вы о ней хоть раз слышали? Ну вот в LG эта клавиша модификатор по умолчанию, настройка выше ее меняет, зажимаете и видите меню + можете еще тут глянуть.\nЕсли щас запустите LG то получите ошибку о том что Host приложение (на госте) не работает, если так, то хорошо.\nНа Windows качаем Windows Host Binary вот тут https://looking-glass.io/downloads и устанавливаем.\nPermission denied Если при запуске виртуалки получаете ...can't open backing store /dev/kvmfr0 for guest RAM: Permission denied, то вероятно это SELinux, так как он включен по умолчанию на openSUSE.\nОтключать я это не рекомендую, но чтоб наверняка:\nsudo getenforce Или глобально проверить параметр grep '^SELINUX=' /etc/selinux/config.\nЕсли Enforcing \u0026ndash; значит включено. Выполните:\nsudo setenforce 0 Это переключит в permissive, попробуйте снова запустить виртуалку. Если сработало это из-за SELinux.\nЕсли так. Для начала переключаем обратно:\nsudo setenforce 1 Далее:\nsudo sh -c \u0026#39;semanage fcontext -a -t svirt_image_t \u0026#39;/dev/kvmfr0\u0026#39; \u0026amp;\u0026amp; restorecon -v /dev/kvmfr0\u0026#39; Проверка:\nls -Z /dev/kvmfr0 Должно быть svirt_image_t.\nА также:\nsudo nano /etc/udev/rules.d/71-kvmfr.rules Туда в конец добавить:\n...MODE=\u0026#34;0660\u0026#34;, RUN+=\u0026#34;/usr/sbin/restorecon %E{DEVNAME}\u0026#34; sudo sh -c \u0026#39;udevadm control --reload-rules \u0026amp;\u0026amp; sudo rmmod kvmfr \u0026amp;\u0026amp; sudo modprobe kvmfr \u0026amp;\u0026amp; ls -Z /dev/kvmfr0\u0026#39; 📝 Сходу в Looking Glass у вас вероятно будет мыло, чтобы его не было окно LG надо открыть fullscreen, прям вот полный-полный экран, как игры например обычно открываются.\nЛибо же, если вы хотите ощутить нереальный дзен на WM, ну например Niri, выполняете niri msg windows, ищите там размер окна LG, и через NVIDIA, AMD, Intel создаете кастомное разрешение монитора. Уф! Как же это стильно выглядит :D\nСкрипт переключения VFIO (Холодный проброс) Положите куда-нибудь скрипт и конфиги, ну например:\nmkdir -p /home/$USER/Scripts/vfiopt Создайте скрипт и конфиги с нужным содержимым (см. Проброс dGPU):\ntouch /home/$USER/Scripts/vfiopt/vfiopt.sh /home/$USER/Scripts/vfiopt/modprobe-vfio.conf /home/$USER/Scripts/vfiopt/dracut-vfio.conf /home/$USER/Scripts/vfiopt/vfiopt.conf (echo; head -n -0 /etc/{modprobe,dracut.conf}.d/vfio.conf; echo) Так же в nano /home/$USER/Scripts/vfiopt/vfiopt.conf укажите PCI адрес dGPU и ее аудио:\n1 2 # PCI dGPU \u0026amp; Audio (0000:XX:XX.X) DGPU_DEVS=\u0026#34;0000:01:00.0 0000:01:00.1\u0026#34; Сам скрипт:\nsudo nano /home/$USER/Scripts/vfiopt/vfiopt.sh vfiopt.sh Loading file... vfio/scripts/host/vfiopt.sh sudo chmod 755 /home/$USER/Scripts/vfiopt/vfiopt.sh Сделайте симлинк:\nsudo ln -s /home/$USER/Scripts/vfiopt/vfiopt.sh /usr/local/bin/vfiopt Перезапустите терминал. И запускать скрипт из любого места:\nvfiopt Про проброс VFIO Как вы могли заметить в /sbin/vfio-pci-override.sh:\n1 DEVS=\u0026#34;0000:01:00.0 0000:01:00.1\u0026#34; Есть такая запись, в нее можно добавить не только видеокарту, а что угодно, типа:\n1 DEVS=\u0026#34;0000:01:00.0 0000:01:00.1 0000:X 0000:X 0000:X\u0026#34; И все это будет проброшено vfio.\nПроброс температур GPU с гостя на хост Для гостя нужны virtio драйвера см. здесь.\nВам это может вовсе и не нужно, но кому нужно покажу, так же учтите, что главный сценарий проброса температур нужен, если у вас горячий проброс, если у вас холодный проброс, то данный мной python скрипт можно сильно упростить.\nЛично мне не хватает встроенного «Smart Fan» в биосе, потому я предпочитаю контролировать кулера процессора и корпуса, ориентируясь на температуру процессора и видеокарты по \u0026ldquo;MAX\u0026rdquo;. То есть, если греется проц, то такая кривая, если карта, то такая кривая.\nСоответственно, когда карта проброшена в гостя ее температуры в хосте не доступны, а гость не имеет доступа к корпусным кулерам. Также после, я покажу свой пример, как с CoolerControl.\n🚧 Текст ниже ИСКЛЮЧИТЕЛЬНО для NVIDIA GPU.\nОбязательно нужны проприетарные драйвера NVIDIA как на хосте так и госте, так как мы будем использовать nvidia-smi \u0026ndash;\u0026gt; NVML.\nnvidia-smi это оф. утилита обертка для NVML, которая входит в проприетарный драйвер NVIDIA, и мы будем использовать NVML напрямую.\nИтак, начнем.\nВ настройках виртуалки Add hardware \u0026ndash;\u0026gt; Channel:\nName: org.local.gpu-temp Device Type: UNIX socket (unix) Auto socket: ✅ Запустите виртуалку. На хосте:\nsudo virsh dumpxml win11 | grep -B2 -A2 \u0026#34;org.local.gpu-temp\u0026#34; Где win11 имя вашей виртуалки. Вывод:\n1 2 3 4 5 \u0026lt;channel type=\u0026#39;unix\u0026#39;\u0026gt; \u0026lt;source mode=\u0026#39;bind\u0026#39; path=\u0026#39;/run/libvirt/qemu/channel/2-win11/org.local.gpu-temp\u0026#39;/\u0026gt; \u0026lt;target type=\u0026#39;virtio\u0026#39; name=\u0026#39;org.local.gpu-temp\u0026#39; state=\u0026#39;disconnected\u0026#39;/\u0026gt; \u0026lt;alias name=\u0026#39;channel0\u0026#39;/\u0026gt; \u0026lt;address type=\u0026#39;virtio-serial\u0026#39; controller=\u0026#39;0\u0026#39; bus=\u0026#39;0\u0026#39; port=\u0026#39;1\u0026#39;/\u0026gt; Тут нужен path \u0026ndash; /run/libvirt/qemu/channel/2-win11/org.local.gpu-temp \u0026ndash; запомните путь, может понадобиться в Python скрипте. Теперь виртуалку можно выключить для дальнейших тестов.\nДобавляемся в группу sudo usermod -aG qemu $USER (на всякий случай) и перезагружаемся.\nСоздаем python скрипт:\nsudo mkdir -p /usr/local/sbin/gpu-temp-bridge sudo nano /usr/local/sbin/gpu-temp-bridge/gpu-temp-bridge.py gpu-temp-bridge.py Loading file... vfio/scripts/host/gpu-temp-bridge.py Не забудьте поменять имя виртуалки, путь сокета (если отличается) и PCI dGPU на свои.\n📝 В будущем (вероятно очень далеком), файл библиотеки \u0026ldquo;libnvidia-ml.so\u0026rdquo; (название) может поменяться мажорная версия .so-1 \u0026ndash;\u0026gt; .so-2, имейте это в виду. Python скрипт берет температуру с хоста, но если датчик недоступен, то берет температуру из сокета гостя. В случае чего если ничего недоступно ставится температура из FALLBACK_TEMP, Это не так важно \u0026ndash; 50 это ни много ни мало, но лучше конечно поставить индивидуальное значение \u0026ndash; ваша температура карты в простое. но это может показаться небезопасно. И оно так и есть, но не совсем.\n📝 Про небезопасно, небезопасно для GPU только если вы хотите контролить кулера GPU. Но если вы хотите контролить кулера GPU, то пробрасывать температуру на хост не нужно, хост уже имеет полный доступ к dGPU, когда виртуалка не запущена.\nРовно так же, как и гость имеет полный доступ к dGPU, когда виртуалка запущена. То есть контролить кулера GPU следует на той ОС, где карта сейчас используется. Это же все чисто ради того, чтобы контролить любые другие кулера, опираясь на температуру GPU.\nИными словами, и хост, и гость могут контролировать кулера GPU, когда GPU используется ими, но все остальные кулера может контролировать только хост.\nБыстрая проверка, просто запустите скрипт\npython3 /usr/local/sbin/gpu-temp-bridge/gpu-temp-bridge.py И в соседнем терминале:\nwatch -n 1 cat /dev/shm/gpu-temp Вы должны увидеть температуру. Нагрузите как-нибудь видеокарту, ну например:\nsudo zypper in glmark2 Это такой легчайший бенчмарк, далее запустите его через dGPU:\n__NV_PRIME_RENDER_OFFLOAD=1 __GLX_VENDOR_LIBRARY_NAME=nvidia glmark2 Температура меняется? Если да, то круто.\nДалее стартуем виртуалку.\n💡 При запуске виртуалки будет ошибка/упадет скрипт (его убьет хук), это нормально, просто запустите его снова. Далее в автоматизации мы сделаем, чтобы было все четко. В Windows запустите powershell от имени админа:\n1 Set-ExecutionPolicy RemoteSigned -Scope CurrentUser И согласитесь (Y). Это чтобы можно было запускать скрипты от имени админа.\nДалее создаем скрипт \u0026ldquo;gpu-temp-bridge.ps1\u0026rdquo;:\ngpu-temp-bridge.ps1 powershell Loading file... vfio/scripts/guest/windows/gpu-temp-bridge.ps1 Запускаем, и с гостя чем-нибудь нагружаем видеокарту, если в хосте циферки побежали, то все работает, температура проброшена.\ngpu-temp-bridge.ps1 лучше положить куда-нибудь, а не просто на \u0026ldquo;рабочем столе\u0026rdquo; оставить, так как далее мы сделаем задачу автозапуска.\nВыключаем виртуалку и автоматизируем, сделаем демона и автозапуск.\nСоздаем демона:\nsudo nano /etc/systemd/system/gpu-temp-bridge.service 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 [Unit] Description=GPU temperature bridge (host NVML / guest virtio-serial -\u0026gt; /dev/shm) After=virtqemud.service [Service] Type=simple ExecStart=/usr/bin/python3 /usr/local/sbin/gpu-temp-bridge/gpu-temp-bridge.py Restart=on-failure RestartSec=5 User=root [Install] WantedBy=multi-user.target sudo rm -rf /dev/shm/gpu-temp sudo systemctl daemon-reload sudo sh -c \u0026#39;systemctl enable --now gpu-temp-bridge.service \u0026amp;\u0026amp; systemctl status gpu-temp-bridge.service\u0026#39; Посмотреть логи:\nsudo journalctl -u gpu-temp-bridge.service -f Далее создаем хуки, до выдергивания dGPU и после:\nsudo nano /etc/libvirt/hooks/qemu.d/win11/prepare/begin/09-dgpu-bridge-stop.sh 09-dgpu-bridge-stop.sh Loading file... vfio/qemu-hooks/start/09-dgpu-bridge-stop.sh sudo nano /etc/libvirt/hooks/qemu.d/win11/prepare/begin/11-dgpu-bridge-start.sh 11-dgpu-bridge-start.sh Loading file... vfio/qemu-hooks/start/11-dgpu-bridge-start.sh И на всякий случай (чтобы наверняка):\nsudo nano /etc/libvirt/hooks/qemu.d/win11/release/end/11-dgpu-bridge-restart.sh 91-dgpu-bridge-restart.sh Loading file... vfio/qemu-hooks/stop/91-dgpu-bridge-restart.sh Проверяйте, запускайте виртуалку, далее автоматизируем powershell.\nСоздайте временный .ps1 скрипт (он создаст задачу):\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 $action = New-ScheduledTaskAction -Execute \u0026#34;powershell.exe\u0026#34; ` -Argument \u0026#34;-NoProfile -WindowStyle Hidden -ExecutionPolicy Bypass -File C:\\Scripts\\gpu-temp-bridge.ps1\u0026#34; $trigger = New-ScheduledTaskTrigger -AtStartup $principal = New-ScheduledTaskPrincipal -UserId \u0026#34;SYSTEM\u0026#34; -LogonType ServiceAccount -RunLevel Highest $settings = New-ScheduledTaskSettingsSet ` -AllowStartIfOnBatteries ` -DontStopIfGoingOnBatteries ` -StartWhenAvailable ` -RestartCount 999 ` -RestartInterval (New-TimeSpan -Minutes 1) ` -ExecutionTimeLimit ([TimeSpan]::Zero) Register-ScheduledTask -TaskName \u0026#34;GpuTempBridge\u0026#34; -Action $action -Trigger $trigger ` -Principal $principal -Settings $settings -Force C:\\Scripts\\gpu-temp-bridge.ps1 \u0026ndash; не забудьте указать свой путь до мейн скрипта.\nЗапускаем powershell от имени админа и стартует этот скрипт, выключаем все, включаем все, если все работает без ваших рук, поздравляю, вы извращенец.\nИтак, CoolerControl. Если нажать на \u0026ldquo;+\u0026rdquo; и там \u0026ldquo;Custom Sensor\u0026rdquo; в открывшемся окне можно выбрать Sensor Type: File, и просто указать путь до /dev/shm/gpu-temp. И еще надо отключить обычные сенсоры dGPU там же.\nНо CoolerControl все равно дох*я принципиальный и все равно будет использовать dGPU, из-за чего трагически погибнет от рук хука. Можно, конечно и его демона в хук засунуть, но это уже будет неэлегантным решением, а костылем, да это другое.\nsudo systemctl edit coolercontrold Там добавить:\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 ### Editing /etc/systemd/system/coolercontrold.service.d/override.conf ### Anything between here and the comment below will become the contents of the drop-in file [Service] Environment=\u0026#34;CUDA_VISIBLE_DEVICES=\u0026#34; DevicePolicy=closed DeviceDeny=/dev/nvidiactl DeviceDeny=/dev/nvidia0 DeviceDeny=/dev/nvidia-uvm DeviceDeny=/dev/nvidia-modeset ### Edits below this comment will be discarded ### /usr/lib/systemd/system/coolercontrold.service # [Unit] # Description=CoolerControl Daemon ... Далее:\nsudo sh -c \u0026#39;sudo systemctl daemon-reload \u0026amp;\u0026amp; systemctl restart coolercontrold.service\u0026#39; Также в CoolerControl надо отключить сенсоры dGPU и запускать сам GUI на iGPU (читать ниже \u0026ndash; FATAL: Module X is in use).\nДалее нужно заставить появиться кулера, если их нет.\nsudo sensors-detect Везде Enter кроме последнего \u0026ldquo;Lastly, we can probe the I2C/SMBus adapters for connected hardware\u0026hellip;\u0026rdquo;.\nИ если в конце вы получили:\n1 2 3 4 5 Sorry, no sensors were detected. Either your system has no sensors, or they are not supported, or they are connected to an I2C or SMBus adapter that is not supported. If you find out what chips are on your board, check https://hwmon.wiki.kernel.org/device_support_status for driver status. Всему виной gigabyte. Так как у меня именно gigabyte я покажу, как это исправить. Если у вас не gigabyte \u0026ndash; смотрите это.\ngit clone https://github.com/frankcrawford/it87 \u0026amp;\u0026amp; cd it87/ sudo zypper in dkms sudo ./dkms-install.sh Дальше либо все ок, либо:\n1 2 3 4 5 ... Running depmod... done. modprobe: ERROR: could not insert \u0026#39;it87\u0026#39;: Key was rejected by service make: *** [Makefile:110: dkms] Error 1 Finished running dkms install steps. Это из-за Secure Boot:\nsudo mokutil --import /var/lib/dkms/mok.pub Придумайте какой-нибудь простой пароль, и перезагрузитесь. На этапе загрузки будет MOK экран, где нужно enroll key и ввести придуманный пароль. Аналогично у вас было с драйверами NVIDIA и вероятно root паролем, если у вас Secure Boot.\nПроверяем, загрузились ли драйвера:\nlsmod | grep it87 Если нет, то делаем все описанное ниже\nsudo modprobe it87 Если не сработало, то:\nsudo modprobe it87 ignore_resource_conflict=1 И добавить модуль в автозагрузку:\necho \u0026#34;it87\u0026#34; | sudo tee /etc/modules-load.d/it87.conf И это если на предыдущем шаге не сработало без ignore_resource_conflict=1:\necho \u0026#34;options it87 ignore_resource_conflict=1\u0026#34; | sudo tee /etc/modprobe.d/it87.conf Проверяем:\nsensors Видите это?\n1 2 3 4 5 6 7 8 9 10 11 fan1: 858 RPM (min = 0 RPM) fan2: 764 RPM (min = 0 RPM) fan3: 732 RPM (min = 0 RPM) fan4: 0 RPM (min = 0 RPM) fan5: 855 RPM (min = 0 RPM) pwm1: 25% (freq = 23437 Hz) pwm2: 20% (freq = 23437 Hz) pwm3: 24% (freq = 23437 Hz) pwm4: 25% (freq = 23437 Hz) pwm5: 25% (freq = 23437 Hz) ... Значит все круто.\nИ обязательно прочтите readme чтобы знать, как обновлять, это важно.\nЕсли кулера не управляются вручную или через CoolerControl и прочие, то нужно зайти в биос и там в Smart Fan, чтобы \u0026ldquo;сбросить\u0026rdquo; кривые, а конкретно сделать ОДНУ точку, потому что Smart Fan как бы переопределяет это. То есть сделать типа такого:\n1 2 3 4 5 6 7 PWM(%) 25 25 25 25 25 25 100 Temp(C) 0 80 80 80 80 80 80 Где 25 минимальная скорость, которую вы хотите (разумно, не надо делать 0) на случай отвала CoolerControl, чтобы не было перегрева. Где 100, просто 100. Где Temp первое всегда 0, остальные макс. возможное, у меня это 80. Например, если я поставлю 90, перезагружусь снова в биос, то оно сбросится на 80.\n🚧 После обновления ОС (в основном ядра) кулера могут пропасть, а могут работать в \u0026ldquo;read-only\u0026rdquo;, фиксится переустановкой (в моем случае) it87:\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 $ sudo dkms status | grep it87 it87/v1.0-232-g20f2f2f.20260416, 7.1.2-1-default, x86_64: installed (Original modules exist) $ sudo dkms remove it87/v1.0-232-g20f2f2f.20260416 --all Module it87/v1.0-232-g20f2f2f.20260416 for kernel 7.1.2-1-default (x86_64): Before uninstall, this module version was ACTIVE on this kernel. Deleting /lib/modules/7.1.2-1-default/updates/it87.ko.zst Restoring archived original module /lib/modules/7.1.2-1-default/kernel/drivers/hwmon/it87.ko.zst Running depmod... done. $ sudo modprobe -r it87 $ sudo ./dkms-install.sh About to run dkms install steps... Creating symlink /var/lib/dkms/it87/v1.0-232-g20f2f2f.20260416/source -\u0026gt; /usr/src/it87-v1.0-232-g20f2f2f.20260416 Sign command: /lib/modules/7.1.3-1-default/build/scripts/sign-file Signing key: /var/lib/dkms/mok.key Public certificate (MOK): /var/lib/dkms/mok.pub Building module(s)... done. Signing module /var/lib/dkms/it87/v1.0-232-g20f2f2f.20260416/build/it87.ko Found pre-existing /lib/modules/7.1.3-1-default/kernel/drivers/hwmon/it87.ko.zst, archiving for uninstallation Installing /lib/modules/7.1.3-1-default/updates/it87.ko.zst Running depmod... done. Finished running dkms install steps. $ sudo systemctl restart coolercontrold.service $ sudo mokutil --import /var/lib/dkms/mok.pub # на всякий случай проверить Проброс дополнительных устройств в VM Два главных способа:\nпробросить само устройство и только его пробросить целиком USB \u0026ldquo;порт\u0026rdquo; (контроллер), то есть это VFIO Первый максимально простой, универсальный и сработает в любом случае (вопрос только как хорошо).\nНо второй только при крутых IOMMU группах и есть нюанс \u0026ndash; обычно USB порты на одном контроллере, вероятность того что получится пробросить только 1 порт, а не всю пачку, крайне мала, я бы даже сказал невозможно, потому что порт не пробрасывается \u0026ndash; пробрасывается контроллер. Ну например отдельная PCI USB карта, с ней этого нюанса не будет.\nОчевидный плюс такого проброса это производительность, это как проброс dGPU, тоже самое, полностью отдаем гостю. В первом же способе оно все равно идет через хост, что вызывает задержки, и может вызвать приличные \u0026ldquo;нюансы\u0026rdquo; на USB флешках/дисках, веб-камерах и тп. С устройствами ввода \u0026ndash; геймпады, мыши, клавиатуры, \u0026ldquo;нюансы\u0026rdquo; не заметны хоть и есть если вы киберкотлета.\nЯ буду показывать на примере китайского геймпада GameSir с подключением через донгл.\nПроброс конкретного устройства Тут все очень просто. Подключаем устройство. В моем случае оно определяется как DualShock 4 (китайцы любят эмулировать DualShock/XBOX геймпады для совместимости).\nДалее в параметрах виртуалки, Add Hardware \u0026ndash;\u0026gt; USB Host Device, и ваше устройство, все. Готово.\nНо, я рекомендую еще поменять Startup Policy на Optional, это нужно чтобы если устройство не подключено физически, виртуалка запустилась, а не кинула ошибку.\nОтвечаю на очевидные вопросы:\nНадо ли подключать устройство ДО запуска виртуалки или можно после? Нужно ДО, иначе не пробросится, но, смотрите след. вопрос, не суть важно.\nЧто если во время работы виртуалки, устройство отключится по какой-то причине, нужно будет перезапускать виртуалку? Да, но на самом деле не обязательно, можно просто удалить устройство и добавить его снова пока виртуалка работает.\nПроброс USB порта (контроллера; VFIO) Нативный натив. И разумеется у вас должны быть четкие IOMMU группы, чтобы пробрасываемый PCI был в отдельной группе, об этом уже было в гайде.\nПодключаем устройство, далее:\nlsusb В моем случае Bus 001 Device 008: ID 054c:09cc Sony Corp. DualShock 4 [CUH-ZCT2x] (почему DualShock если GameSir \u0026ndash; смотреть выше).\nЧто мы видим, \u0026ldquo;Bus 001\u0026rdquo; и \u0026ldquo;Dev (Device) 008\u0026rdquo;, далее:\nlsusb -t Смотрим на \u0026ldquo;Bus 001\u0026rdquo;, в моем случае это вся нах*й задняя панель материнской платы. То есть для меня это не вариант.\nНо\u0026hellip; у меня есть type-c на передней панели и на задней панели материнской платы, и вот для них типично находится на отдельных контроллерах, потому что требуют огромных скоростей. Втыкаем туда что-нибудь, и проверяем:\n1 2 3 4 5 6 7 8 lsusb Bus 003 Device 015: ID 214b:7000 Huasheng Electronics 4-port hub [Maxxter ACT-HUB2-4P, HS8836, iSoul ultra-slim] Bus 003 Device 018: ID 054c:09cc Sony Corp. DualShock 4 [CUH-ZCT2x] lsusb -t /: Bus 003.Port 001: Dev 001, Class=root_hub, Driver=xhci_hcd/2p, 480M |__ Port 001: Dev 015, If 0, Class=Hub, Driver=hub/4p, 480M |__ Port 004: Dev 018, If 0, Class=Human Interface Device, Driver=usbhid, 12M Huasheng это USB хаб, а в него втыкнут донгл геймпада.\nИ все, под Bus 003 больше ничего нету, и точно такая же ситуация с type-c на задней панели. И вот с этим уже можно работать, а остальное дело техники, переходники, хабы и все такое, как у меня уже сделано :D\nУзнаем PCI:\nreadlink -f /sys/bus/usb/devices/usb3 Bus 003 = usb3 соответственно. Получаем что-то вроде:\n1 /sys/devices/pci0000:00/0000:00:08.1/0000:11:00.3/usb3 Нужен 0000:11:00.3.\nДалее, если вы используете Virtual Machine Manager, а не запускаете виртуалку напрямую через QEMU из терминала (а в этом гайде про это ничего не говорилось, так что расчет на то что вы запускаете через Virtual Machine Manager), libvirt будет делать всю магию под капотом, так как драйвера USB не такие наглые как драйвера GPU, оно само отвяжет устройство от хоста при запуске виртуалки.\nТо есть, Add Hardware \u0026ndash;\u0026gt; PCI Host Device \u0026ndash;\u0026gt; этот самый PCI, прям как добавляли PCI dGPU. Готово.\nТа-да \u0026mdash; подключаемые устройства работают нативно и абсолютно минуют хост систему, когда включена виртуалка, что еще и безопасно (для всяких проверок).\nПроблемы FATAL: Module X is in use sudo lsof /dev/nvidia* /dev/dri/by-path/pci-0000:01:00.0* Тут разумеется ваш dGPU PCI \u0026ndash; lspci | grep -E \u0026quot;VGA|3D|Display\u0026quot;.\nПроверьте, что использует карту, ну например в моем случае частенько такая штука:\n1 2 3 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME code 5485 user 28u CHR 195,255 0t0 1348 /dev/nvidiactl code 5485 user 29u CHR 226,129 0t0 1325 /dev/dri/by-path/../renderD129 code это VSCode, который слегка прих*ел использовать dGPU, нужно просто закрыть/убить процесс и все. Если там что-то системное, то смотреть ниже про KDE Plasma.\nЧто если вы не хотите, чтобы приложение убивалось, можно сразу запускать его на iGPU. Но в случае VS Code это не сработает, так как там то, что вы запускаете это обертка, запустив ее с нужными параметрами, сам VSCode не запустится на iGPU, а изменив обертку \u0026ndash; обновление VS Code, в случае VS Code проще отключить аппаратное ускорение.\nДля остальных приложений, для .desktop:\n1 Exec=env __EGL_VENDOR_LIBRARY_FILENAMES=/usr/share/glvnd/egl_vendor.d/50_mesa.json VK_ICD_FILENAMES=/usr/share/vulkan/icd.d/radeon_icd.x86_64.json /path/to/bin Для терминала просто:\n1 __EGL_VENDOR_LIBRARY_FILENAMES=/usr/share/glvnd/egl_vendor.d/50_mesa.json VK_ICD_FILENAMES=/usr/share/vulkan/icd.d/radeon_icd.x86_64.json /path/to/bin Обратите внимание __EGL_VENDOR_LIBRARY_FILENAMES и VK_ICD_FILENAMES отличаются в зависимости от вендора Intel/AMD/NVIDIA/что-то другое? Китайцы?\nМигает экран и не запускается VM после обновления ОС (KDE Plasma) Проверьте PCI dGPU:\nsudo lsof /dev/nvidia* /dev/dri/by-path/pci-0000:01:00.0* Тут разумеется ваш dGPU PCI \u0026ndash; lspci | grep -E \u0026quot;VGA|3D|Display\u0026quot;.\nТам наверняка будет куча всего, куча всего, что юзает вашу dGPU, а не должно, и вероятно это что-то, что отвечает за окружение, вероятно это KWin. А использует он не прям вашу карту (cardX), а только рендеринг EGL/OpenGL, хотя фактически саму карту он не использует (не выводит через нее картинку на экран), из-за чего кажется, что все как бы окей.\nКак следствие хук убивает KWin чтоб отвязать карту, а заодно и сам себя (KVM). Из-за трагичной смерти, KWin экстренно возрождается, потому-то экран и мигает.\nПоздравляю, дообновлялись :D\nЭто KWin, познакомьтесь. Вероятно он время от времени будет ломаться из-за обновлений, которые меняют его поведение (логику инициализации GPU), и решение (возможно) искать вам, к слову во время написания текста (до первой публикации), я обновил систему, и в первый раз с этим столкнулся, решением было (что уже описано в главе проброса dGPU) __EGL_VENDOR_LIBRARY_FILENAMES.\nWelcome to the «VFIO» club buddy, как говори-ца! Как сделать так, чтобы не ломалось? Просто сделать нельзя, можно мониторить и отслеживать changelog. Или более радикальный способ \u0026ndash; не использовать KWin, то есть не использовать KDE Plasma. Ну или не пробрасывать на горячую, только холодный проброс, но если вы зачем-то хотите именно на горячую, то и смысла на холодную нету.\nДа я понимаю тут явное противоречие, я говорил вот это будем использовать, а сейчас наоборот. Но для первого раза, с учетом того, что текст рассчитан на аудиторию, что \u0026ldquo;шарит, но как бы и не очень, но опыт есть\u0026rdquo;, мое мнение, и правда лучше использовать rich-GUI штуку для наглядности, если так можно выразиться.\nБольшинство описанных тут вещей и так сработают без KDE Plasma, просто игнорируете все, где фигурирует KWin (возможно еще X11, зависит от вас) и KDE Plasma соответственно, но придется найти альтернативу для вашей DE/WM \u0026ndash; \u0026ldquo;пересадить\u0026rdquo; все на iGPU, это почти все, что надо, и не исключено, что \u0026ldquo;там\u0026rdquo; в этом плане, будет даже проще (так например на Niri \u0026ndash; очень просто).\nЯ же со своей стороны, даже если буду использовать другую DE/WM, постараюсь быть в курсе и применять фиксы. Но добавлять я их буду бесшовно, то есть как будто бы так надо было с самого начала, но лог обновления оставлю.\nЗависание при выключение/перезагрузки VM и 100% CPU Это баг NVIDIA/AMD связанный с FLR. Для NVIDIA фикса нет. А у меня нету AMD, но для AMD возможно поможет это.\nПросто делайте \u0026ldquo;двойной\u0026rdquo; shutdown через Virtual Machine Manager. Если это не force off, а именно shutdown, то это безопасно. Либо выключайте из Windows + Shutdown из Virtual Machine Manager, либо два раза shutdown из Virtual Machine Manager.\nИли типа такая автоматизация:\n1 2 3 4 5 6 7 8 9 10 11 #!/bin/bash if [[ $EUID -ne 0 ]]; then exec sudo \u0026#34;$0\u0026#34; \u0026#34;$@\u0026#34; fi VM=\u0026#34;$1\u0026#34; virsh shutdown \u0026#34;$VM\u0026#34; sleep 16 virsh shutdown \u0026#34;$VM\u0026#34; Разумеется это костыль.\nА так же виной может быть X софтина, с ядерным драйвером. Проверить это просто, выключите Windows из Windows смотря на Windows через монитор напрямую, а не через LG, если там BSOD с ошибкой типа \u0026ldquo;VIDEO_DXGKRNL_FATAL_ERROR\u0026rdquo; \u0026ndash; то это ваш случай. Для справки: LG не показывает BSOD экран.\nНапример в моем случае это MSI Afterburner. Даже если его закрыть перед выключением, его драйвер остается загруженным. После того как я убрал его из автозагрузки и запустил VM, она начала выключаться абсолютно нормально.\n2 способа это исправить:\nНе использовать MSI Afterburner вообще Выгрузить драйвер / Не загружать драйвер Не загружать драйвер: General \u0026ndash;\u0026gt; Enable low-level IO driver - выкл. Применится только после перезагрузки VM.\nВ чем минусы отключения этого драйвера? В основном датчики. Андервольт/оверклокинг работает через драйвер NVIDIA (это просто удобный интерфейс, не более), так что там все будет работать. А для датчиков есть HWiNFO, GPU-Z, Aida64, что угодно.\nПроблема X в Windows из-за Y В этом тексте разбирался VirtIO/VFIO диск, в обоих случаях Windows физически устанавливается на диске, без вирт. дисков. Если что-то не обноляется, что-то конкретно сломалось, еще какой-то п*здец мировых масштабов \u0026ndash; вы всегда можете просто \u0026ldquo;дуалбутнутся\u0026rdquo; в Windows.\nДва момента, СЛЕДИТЕ за BitLocker. Я не знаю почему, но после одной такой загрузки Windows, эта дура решила самолично врубить шифрование диска спустя месяцев работы в VM, и хорошо что я это заметил.\nЕсли шифрование включиться, то ключа у вас не будет как и вменяемого способа разблокировки если вы не вошли в свой Microsoft аккаунт ранее. И при разницы в TPM, а она будет если вы его эмулировали или еще какой-нибудь еб*нины в стиле Windows \u0026ndash; диск заблокируется, и потребует пароль, которого вы физически знать не можете.\nПроверить статус BitLocker можно так (powershell от имени админа):\nmanage-bde -status Отключить можно так:\nmanage-bde -off После отключения, вводите первую команду на проверку время от времени и ждете пока не будет Fully Decrypted (проценты будут уменьшаться), и только потом перезагружайтесь в Linux (если вы были на Windows на голом железе).\nА еще ВЫКЛЮЧАЙТЕ Fast Startup и гибернацию, если они будут включены, и вы будите прыгать между KVM и дуалбутом \u0026ndash; файловая система скажет «кря». Для отключения в терминале от имени админа:\npowercfg /h off Проверить включено ли оно:\npowercfg /a Так же мой совет, отключайте обновления Windows, и включайте только когда вам это нужно. Отключить можно как угодно, главное железно и при этом не навсегда (с возможностью включить обратно).\nКак обновлять QEMU/KVM На время всех этих действий, виртуалка, разумеется, должна быть выключена.\nПомимо само разумеющегося zypper dup \u0026ndash; обновление всей системы, в XML есть такое:\n1 2 3 \u0026lt;os firmware=\u0026#34;efi\u0026#34;\u0026gt; \u0026lt;type arch=\u0026#34;x86_64\u0026#34; machine=\u0026#34;pc-q35-10.2\u0026#34;\u0026gt;hvm\u0026lt;/type\u0026gt; ... pc-q35-10.2 \u0026lt;\u0026ndash; тоже надо обновлять. После обновления QEMU, выполняете:\nqemu-system-x86_64 -machine help | grep q35 Это покажет все версии. Берете самую новую и вручную меняете в XML.\nНо сначала рекомендую сделать бэкап. Бэкап XML:\nsudo virsh dumpxml win11 \u0026gt; ~/win11.xml Бэкап NVRAM файла (если \u0026lt;os firmware=\u0026quot;efi\u0026quot;\u0026gt;):\nsudo virsh dumpxml win11 | grep nvram В выводе:\n1 \u0026lt;nvram template=\u0026#39;/usr/share/qemu/ovmf-x86_64-smm-ms-vars.bin\u0026#39; templateFormat=\u0026#39;raw\u0026#39; format=\u0026#39;raw\u0026#39;\u0026gt;/var/lib/libvirt/qemu/nvram/win11_VARS.fd\u0026lt;/nvram\u0026gt; Нужен /var/lib/libvirt/qemu/nvram/win11_VARS.fd:\nsudo cp /var/lib/libvirt/qemu/nvram/win11_VARS.fd ~/ Восстановить бэкап:\nsudo virsh define ~/win11.xml Проверить:\nsudo virsh dumpxml win11 | diff - ~/win11.xml И NVRAM:\nsudo cp ~/win11_VARS.fd /var/lib/libvirt/qemu/nvram/win11_VARS.fd Итоги \u0026amp; Бенчмарки Я за*бался. Мне лень качать бенчмарки и прогонять тесты, поэтому вот вам скриншоты из бенчмарков Cyberpunk 2077 и Forza Horizon 6, других игр со встроенным бенчмарком у меня нету, а эти я все равно переносил.\nCP2077 \u0026amp; Forza Horizon 6; Bare 158 / 111, KVM 160 / 111 Итак, 4 месяца спустя 01.11.2026 использования Linux хоста и Windows в KVM. Куча обновлений хоста, чуть поменьше гостя, разный софт и игры. Все работает ах*ено, всем советую.\nЯ сделал новые и более полные бенчмарки, на этот раз на поюзанной, а не чистой Windows, и с кучей софта, в том же Cyberpunk 2077, а также в Black Myth: Wukong Benchmark Tool, Bright Memory: Infinite Ray Tracing Benchmark и 3DMark (Time Spy, Steel Nomad, CPU Profile).\nКратко поясню:\nCyberpunk 2077, Black Myth: Wukong \u0026ndash; generic бенчмарк, с RTX и без. Bright Memory: Infinite \u0026ndash; RTX бенчмарк. Time Spy \u0026ndash; бенчмарк GPU + CPU Steel Nomad \u0026ndash; non-RTX, но тяжелый бенчмарк GPU-only. CPU Profile \u0026ndash; CPU-only, бенчмарк многопоточности. Как и в прошлых двух тестах (CP2077 \u0026amp; Forza Horizon), хоть я про это не писал, было 3 прохода каждого бенчмарка, и вы видите средние значения.\nБенчмарки на Windows VM были без стрима LG, а напрямую в монитор.\nТакже любезно напоминаю, что на голом железе 8 ядер 16 потоков, а в VM 6 ядер 12 потоков ($\\text{потеря} \\ 25\\% \\to \\ \\approx 23\\%:\\ \\downarrow N \\Rightarrow \\downarrow \\text{TDP}$), это важная информация для понимания разницы в Time Spy и CPU Profile бенчмарках, а также немного в Cyberpunk 2077 тестах (потому что упор в CPU).\n$\\Delta = \\left|\\frac{\\text{Bare Metal} - \\text{KVM}}{\\text{Bare Metal}}\\right| \\times 100$\n3DMark KVM Bare Metal $|\\Delta|$ Time Spy Extreme 7 418 7 842 5.41% GPU 8 224 8 192 0.39% CPU 4 771 6 317 24.47% Steel Nomad (DX12) 3 865 3 853 0.31% CPU Profile 6 550 8 439 22.38% 16 threads 6 375 8 422 24.31% 8 threads 5 540 6 706 17.39% 4 threads 3 919 3 931 0.31% 2 threads 2 009 2 043 1.66% 1 thread 1 017 1 023 0.59% Знакомые цифры потерь в CPU тестах? Это 1:1. Потери контролируемые из-за \u0026lt; кол-ва ядер, а не просто потому что \u0026ldquo;это виртуализация\u0026rdquo;.\nGames CP2077 CP2077 (RTX+DLSS+FG) Wukong (Very High) Wukong (Cinematic+RTX) Bright Memory (NO DLSS) KVM 125 157 56 32 62 95 139 46 26 \u0026mdash; 163 175 65 40 \u0026mdash; Bare Metal 128 162 56 33 62 105 144 45 26 \u0026mdash; 165 181 65 40 \u0026mdash; Картинки большие, поэтому открывайте в браузере/качайте и зумьте.\nCP2077 / Black Myth: Wukong / Bright Memory: Infinite 3DMark: Time Spy / Steel Nomad / CPU Profile Источники My notes/tutorial to achieve KVM with passthrough on OpenSUSE and Ryzen/Threadripper system \u0026ndash; Level1Techs Fedora 33: Ultimiate VFIO Guide for 2020/2021 [WIP] \u0026ndash; Level1Techs openSUSE - Docker \u0026ndash; openSUSE libvirt/QEMU Installation \u0026ndash; Looking Glass Docs Много-много рандомного интернета и ИИ ","permalink":"https://hv8.pages.dev/blog/windows-but-on-linux-hardware-passthrough/","summary":"Зачем выбирать между Windows и Linux? Когда можно и то и другое.","title":"Windows, но... в Linux: Hardware Passthrough"},{"content":" 📝 Суть этой заметки аналогична этой заметки про Pangolin, но с использованием другого инструмента. Если VPS новый и нету Docker:\napt update \u0026amp;\u0026amp; apt upgrade -y apt install -y curl wget sudo git curl -fsSL https://get.docker.com -o get-docker.sh \u0026amp;\u0026amp; sudo sh ./get-docker.sh 🚧 Если у вас есть firewall разрешите порты 80/tcp и 443/tcp для получения SSL. Установка скриптом Это автоматический скрипт установки и настройки домена панели, а так же других доменов (если надо) и SSL для них. Но NGINX конфиг будет полностью настроен только для панели.\ngit clone https://github.com/nozsh/home-server-vps-ztnet-init ztnet \u0026amp;\u0026amp; cd ztnet \u0026amp;\u0026amp; bash init/init.sh Далее в админке создать сеть. Подключиться к сети на домашнем сервере по инструкции. И на VPS выполнить:\nNET_ID=\u0026#34;XYZ\u0026#34;; docker exec ztnet sh -c \u0026#34;cd /var/lib/zerotier-one \u0026amp;\u0026amp; mkdir networks.d \u0026amp;\u0026amp; cd networks.d \u0026amp;\u0026amp; touch $NET_ID.conf\u0026#34; Где XYZ \u0026ndash; ID сети.\nЕсли добавляли другие домены помимо панели нужно отредактировать NGINX конфиги \u0026ndash; изменить proxy_pass. Можно не добавлять доп. домены сразу. Потом просто использовать скрипт. Где \u0026lt;ZeroTier_IP\u0026gt; IP домашнего сервера в ZeroTier сети, APP_PORT порт на котором работает сервис на домашнем сервере.\ndocker compose down \u0026amp;\u0026amp; docker compose up -d \u0026amp;\u0026amp; docker compose logs -f И если с домашним сервером потерялся коннект:\nsudo systemctl restart zerotier-one Вручную mkdir ztnet \u0026amp;\u0026amp; cd ztnet \u0026amp;\u0026amp; wget -O docker-compose.yml https://raw.githubusercontent.com/sinamics/ztnet/main/docker-compose.yml nano docker-compose.yml Меняйте все как вам нужно согласно документации.\nReverse proxy (NGINX) nano docker-compose.yml Должно быть вот так:\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 services: zerotier: ports: - \u0026#34;9993:9993/udp\u0026#34; - \u0026#34;80:80\u0026#34; - \u0026#34;443:443\u0026#34; nginx: image: nginx:alpine container_name: nginx restart: unless-stopped volumes: - ./nginx/conf.d:/etc/nginx/conf.d - /etc/letsencrypt:/etc/letsencrypt:ro network_mode: \u0026#34;service:zerotier\u0026#34; depends_on: - zerotier Пример полного docker-compose.yml 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 services: postgres: image: postgres:15.2-alpine container_name: postgres restart: unless-stopped environment: POSTGRES_USER: postgres POSTGRES_PASSWORD: database_password POSTGRES_DB: ztnet volumes: - postgres-data:/var/lib/postgresql/data networks: - app-network zerotier: image: zyclonite/zerotier:1.14.2 hostname: zerotier container_name: zerotier restart: unless-stopped volumes: - zerotier:/var/lib/zerotier-one cap_add: - NET_ADMIN - SYS_ADMIN devices: - /dev/net/tun:/dev/net/tun networks: - app-network ports: - \u0026#34;9993:9993/udp\u0026#34; - \u0026#34;80:80\u0026#34; - \u0026#34;443:443\u0026#34; environment: - ZT_OVERRIDE_LOCAL_CONF=true - ZT_ALLOW_MANAGEMENT_FROM=172.31.255.0/29 ztnet: image: sinamics/ztnet:latest container_name: ztnet working_dir: /app volumes: - zerotier:/var/lib/zerotier-one restart: unless-stopped ports: - 3000:3000 environment: POSTGRES_HOST: postgres POSTGRES_PORT: 5432 POSTGRES_USER: postgres POSTGRES_PASSWORD: database_password POSTGRES_DB: ztnet NEXTAUTH_URL: \u0026#34;https://ztnet-panel.domain.org\u0026#34; NEXTAUTH_SECRET: \u0026#34;something_random\u0026#34; NEXTAUTH_URL_INTERNAL: \u0026#34;http://ztnet:3000\u0026#34; networks: - app-network links: - postgres depends_on: - postgres - zerotier nginx: image: nginx:alpine container_name: nginx restart: unless-stopped volumes: - ./nginx/conf.d:/etc/nginx/conf.d - /etc/letsencrypt:/etc/letsencrypt:ro network_mode: \u0026#34;service:zerotier\u0026#34; depends_on: - zerotier volumes: zerotier: postgres-data: networks: app-network: driver: bridge ipam: driver: default config: - subnet: 172.31.255.0/29 NGINX конфиги mkdir -p nginx/conf.d nano nginx/conf.d/panel-ztnet.domain.org.conf Конфиг для панели 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 server { listen 80; server_name ztnet-panel.domain.org; location /.well-known/acme-challenge/ { root /var/www/certbot; } location / { return 301 https://$host$request_uri; } } server { listen 443 ssl; server_name ztnet-panel.domain.org; ssl_certificate /etc/letsencrypt/live/ztnet-panel.domain.org/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/ztnet-panel.domain.org/privkey.pem; ssl_session_cache shared:le_nginx_SSL:10m; ssl_session_timeout 1440m; ssl_protocols TLSv1.2 TLSv1.3; ssl_prefer_server_ciphers on; location / { proxy_pass http://ztnet:3000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } } nano nginx/conf.d/your-app.domain.org.conf Конфиг для каких-то сервисов 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 server { listen 80; server_name your-app.domain.org; location /.well-known/acme-challenge/ { root /var/www/certbot; } location / { return 301 https://$host$request_uri; } } server { listen 443 ssl; server_name your-app.domain.org; ssl_certificate /etc/letsencrypt/live/your-app.domain.org/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/your-app.domain.org/privkey.pem; ssl_session_cache shared:le_nginx_SSL:10m; ssl_session_timeout 1440m; ssl_protocols TLSv1.2 TLSv1.3; ssl_prefer_server_ciphers on; location / { proxy_pass http://\u0026lt;ZeroTier_IP\u0026gt;:APP_PORT; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } } Поменять там где выделено. Где \u0026lt;ZeroTier_IP\u0026gt; IP домашнего сервера в ZeroTier сети, APP_PORT порт на котором работает сервис на домашнем сервере.\nSSL SSL можно получить через тот же Docker, но проще будет через хост.\napt install certbot certbot certonly --standalone --non-interactive --agree-tos --email cert@domain.org -d ztnet-panel.domain.org ls /etc/letsencrypt/live/ 💡 SSL не получится получить/обновить, если запущен контейнер zerotier, из-за конфликта портов. Запуск docker compose up -d \u0026amp;\u0026amp; docker compose logs -f В админке создать сеть. Подключиться к сети на домашнем сервере по инструкции. Далее нужно добавить VPS на котором работает ZTNet в сеть с домашнем сервером:\ndocker exec -it ztnet sh cd /var/lib/zerotier-one mkdir networks.d cd networks.d touch \u0026lt;network\u0026gt;.conf Где \u0026lt;network\u0026gt; \u0026ndash; ID сети.\nexit docker compose down \u0026amp;\u0026amp; docker compose up -d \u0026amp;\u0026amp; docker compose logs -f И если с домашним сервером потерялся коннект:\nsudo systemctl restart zerotier-one Добавление/Настройка сервисов (NGINX) Чтобы добавить новый сервис, скопируйте существующую конфигурацию NGINX, и поменяйте домен и proxy_pass. И запросите SSL сертификат.\ndocker compose down \u0026amp;\u0026amp; docker compose up -d \u0026amp;\u0026amp; docker compose logs -f Или если вы использовали скрипт автоматической настройки, из директории где docker-compose.yml выполнить:\nbash init/add_new.sh Скрипт остановит контейнеры, создаст NGINX конфиг, запросит SSL и запустит контейнеры. Если ошибок не было \u0026ndash; руками ничего делать не требуется.\nПолезные команды Docker Проверить что соединение доходит до вашего домашнего сервера через контейнер NGINX, можно командой:\ndocker exec nginx wget -O- http://\u0026lt;ZeroTier_IP\u0026gt;:APP_PORT --timeout=5 Если что-то не запустилось, и/или работает не правильно после:\ndocker compose restart \u0026amp;\u0026amp; docker compose logs -f Выполните:\ndocker compose down \u0026amp;\u0026amp; docker compose up -d \u0026amp;\u0026amp; docker compose logs -f ZeroTier sudo zerotier-cli join \u0026lt;network\u0026gt; sudo zerotier-cli leave \u0026lt;network\u0026gt; sudo zerotier-cli listnetworks Скрипты VPS \u0026ldquo;certbot_renew.sh\u0026rdquo;:\n1 2 3 4 5 6 7 8 9 10 #!/bin/bash cd /root/ztnet docker compose down certbot renew --quiet #certbot renew bash start_nologs.sh #bash restart_nologs.sh Там же где docker-compose.yml:\n\u0026ldquo;start.sh\u0026rdquo;:\n1 2 3 #!/bin/bash docker compose up -d \u0026amp;\u0026amp; docker compose logs -f \u0026ldquo;start_nologs.sh\u0026rdquo;:\n1 2 3 #!/bin/bash docker compose up -d \u0026ldquo;restart.sh\u0026rdquo;:\n1 2 3 4 #!/bin/bash docker compose down docker compose up -d \u0026amp;\u0026amp; docker compose logs -f \u0026ldquo;restart_nologs.sh\u0026rdquo;:\n1 2 3 4 #!/bin/bash docker compose down docker compose up -d Cron sudo crontab -e VPS:\n0 4 1 * * /bin/bash /root/certbot_renew.sh Домашний сервер:\n2 4 1 * * systemctl restart zerotier-one ","permalink":"https://hv8.pages.dev/blog/tunnel-between-home-server-and-vps-via-zerotier/","summary":"Очередная борьба с NAT!","title":"Туннель между домашним сервером и VPS через ZeroTier"},{"content":" 🚧 Прежде чем что-то делать, прочтите главу \u0026ldquo;Как вернуть все обратно?\u0026rdquo;! 📝 Заметка написана с расчетом того что вы уже включили в BIOS/UEFI виртуализацию и настроили виртуальную машину в VirtualBox. 💡 Если у вас заблокированы обновления, например софтом по типу «Windows Update Blocker» (WUP), то нужно разблокировать обновления, иначе что-то может не сработать. Если вы видите это:\nА должно быть что-то типо такого:\nЗначит ваша виртуальная машина работает медленно, потому что не использует аппаратную виртуализацию вашего процессора.\nМедленная работа виртуальной машины на VirtualBox, это проблема виртуализации Windows и конкретно из-за Device Guard and Credential Guard на Windows 11.\nВ случае Windows 11, даже при отключенной виртуализации везде, где только можно, оно не отключается, пока не отключено Device Guard and Credential Guard, а это к сожалению про безопасность.\nWindows как бы \u0026ldquo;отнимает\u0026rdquo; виртуализацию, и поэтому ее не может использовать другой софт.\nWindows 10 \u0026amp; 11 Нужно отключить все что связано с виртуализацией, WIN + R \u0026ndash;\u0026gt; \u0026ldquo;optionalfeatures\u0026rdquo;:\nHyper-V Virtual Machine Platform Windows Hypervision Platform WSL и др. если есть 📝 Обратите внимание, что описанное в главе \u0026ldquo;Windows 11\u0026rdquo;, может быть применимо и необходимо и для Windows 10, но не в полной мере, а лишь частично. В случае если у вас Windows 10, применяете и перезагружаетесь, должно все работать. Если же Windows 11, нажимаете перезагрузиться потом и продолжаем.\nWindows 11 Параметры \u0026ndash;\u0026gt; Приватность и безопасность (Privacy \u0026amp; security) \u0026ndash;\u0026gt; Безопасность Windows (Windows Security) \u0026ndash;\u0026gt; Безопасность устройства (Device security) \u0026ndash;\u0026gt; Изоляция ядра (Core Isolation), отключить:\nMemory Integrity Kernel-mode Hardware-enforced Stack Protection Скрины Далее, скачать эту утилиту с официального сайта. Открыть PowerShell от имени администратора:\n1 cd \u0026lt;путь_до_утилиты\u0026gt; 1 ./DG_Readiness_Tool_vX.X.ps1 -Disable Обратите внимания на X.X, там должна быть версия, которую вы скачали.\nПерезагружаемся и следуем инструкции по отключению (там все просто).\nКак вернуть все обратно? Как написано выше, только наоборот.\nВ случае только Windows 11.\n1 ./DG_Readiness_Tool_vX.X.ps1 -Enable И перезагрузиться.\n🚧 Прежде чем делать описанное ниже, прочитайте полностью! WIN + R \u0026ndash;\u0026gt; \u0026ldquo;msinfo32\u0026rdquo;, если \u0026ldquo;Secure Boot State\u0026rdquo; - \u0026ldquo;on\u0026rdquo; то промотайте вниз до проверки. Если \u0026ldquo;off\u0026rdquo;, то идем дальше.\nЗаходим в BIOS/UEFI:\nВыключить Secure Boot если он включен Если стоит \u0026ldquo;Standard\u0026rdquo; то поменять на \u0026ldquo;Custom\u0026rdquo; Поменять с \u0026ldquo;Custom\u0026rdquo; на \u0026ldquo;Standard\u0026rdquo; и согласится с заводскими настройками Включить Secure Boot Обратите внимание, что прежде чем включать Secure Boot, вы должны отключить CSM. Учитывая тот факт что вы это читаете, потому что хотите включить это обратно, а это не работает без Secure Boot, вероятно у вас уже отключен CSM, но все равно проверьте.\nИ еще если у вас Windows 11 Pro можно \u0026ldquo;gpedit.msc\u0026rdquo; поковырять, если что-то не заработало: Computer Configuration \u0026ndash;\u0026gt; Administrative Templates \u0026ndash;\u0026gt; System \u0026ndash;\u0026gt; Device Guard \u0026ndash;\u0026gt; Turn On Virtualization Based Security.\nПроверка Как проверить что все работает. В \u0026ldquo;msinfo32\u0026rdquo; будет \u0026ldquo;Secure Boot State\u0026rdquo; = on, \u0026ldquo;Virtualization-based security\u0026rdquo; (VBS) = Running.\n1 ./DG_Readiness_Tool_vX.X.ps1 -Ready Покажет что-то вроде:\n1 2 3 4 Credential-Guard is not running. HVCI is enabled and running. Config-CI is enabled and running. (Enforced mode) Not all services are running. А не:\n1 2 3 4 Credential-Guard is not running. HVCI is not running. Config-CI is enabled and running. (Enforced mode) Not all services are running. \u0026ldquo;Credential-Guard is not running.\u0026rdquo; зависит от железа, поддержки и все такое. Если оно у вас не работает, то ничего такого. Штука крутая, но увы, заточена под enterprise.\nЕще проверить можно командой:\n1 Get-CimInstance -ClassName Win32_DeviceGuard -Namespace root\\Microsoft\\Windows\\DeviceGuard | Select-Object SecurityServicesRunning Больше логов (by AI) Тут объяснения от ИИ, для общего развития решил добавить.\nБолее подробно:\n1 Get-CimInstance -ClassName Win32_DeviceGuard -Namespace root\\Microsoft\\Windows\\DeviceGuard | Format-List * AvailableSecurityProperties - список функций, которые железо поддерживает 1 - BaseVirtualizationSupport (процессор поддерживает виртуализацию) 2 - SecureBoot (UEFI поддерживает Secure Boot) 3 - DMAProtection (чипсет поддерживает IOMMU) 4 - SecureMemoryOverwrite \u0026hellip; RequiredSecurityProperties - обязательные функции VBS 1 - виртуализация 2 - Secure Boot 3 - DMA Protection SecurityServicesConfigured - настроенные VBS-службы (настроенные не значит запущенные) 1 - Credential Guard 2 - HVCI 3 - Secure Launch 5 - Kernel Stack Protection SecurityServicesRunning - VBS-службы которые работают 1 - Credential Guard 2 - HVCI (Hypervisor-enforced Code Integrity); Memory Integrity 3 - System Guard Secure Launch; Firmware Protection 4 - не используется 5 - Kernel-mode Hardware-enforced Stack Protection (KernelShadowStacks) VirtualizationBasedSecurityStatus - статус VBS 0 - VBS выключен 1 - VBS включен, но не запущен 2 - VBS запущен и работает И команда для красивого вывода (by AI):\n1 2 3 4 5 6 7 8 9 10 11 $dg = Get-CimInstance -ClassName Win32_DeviceGuard -Namespace root\\Microsoft\\Windows\\DeviceGuard $props = $dg.RequiredSecurityProperties Write-Host \u0026#34;`n=== Security ===\u0026#34; -ForegroundColor Cyan Write-Host \u0026#34;VBS Running: \u0026#34; -NoNewline; if($dg.VirtualizationBasedSecurityStatus -eq 2){\u0026#34;✅\u0026#34;}else{\u0026#34;❌\u0026#34;} Write-Host \u0026#34;Secure Boot: \u0026#34; -NoNewline; if($props -contains 2){\u0026#34;✅\u0026#34;}else{\u0026#34;❌\u0026#34;} Write-Host \u0026#34;DMA Protection: \u0026#34; -NoNewline; if($props -contains 3){\u0026#34;✅\u0026#34;}else{\u0026#34;❌\u0026#34;} Write-Host \u0026#34;Memory Integrity (HVCI): \u0026#34; -NoNewline; if($dg.SecurityServicesRunning -contains 2){\u0026#34;✅\u0026#34;}else{\u0026#34;❌\u0026#34;} Write-Host \u0026#34;Kernel Stack Protection: \u0026#34; -NoNewline; if($dg.SecurityServicesRunning -contains 5){\u0026#34;✅\u0026#34;}else{\u0026#34;❌\u0026#34;} Write-Host \u0026#34;Firmware Protection: \u0026#34; -NoNewline; if($dg.SecurityServicesRunning -contains 3){\u0026#34;✅\u0026#34;}else{\u0026#34;❌\u0026#34;} Write-Host \u0026#34;Credential Guard: \u0026#34; -NoNewline; if($dg.SecurityServicesRunning -contains 1){\u0026#34;✅\u0026#34;}else{\u0026#34;❌\u0026#34;} Что если? (Windows 11) Что если вы все отключили, попользовались виртуальной машиной, включили все обратно, но решили снова попользоваться виртуальной машиной, и так по кругу, но:\nВы не можете изменить настройки. В таком случае просто пропускаете шаг с отключением параметров в изоляции ядра (Core Isolation) и идете дальше.\nИсточники How to Disable Hyper-V in Windows 11 24H2 \u0026ndash; Broadcom VM using native API instead of AMD-V \u0026ndash; VirtualBox Forum Win11 build 22581 broke VB by enabling Credential Guard \u0026ndash; VirtualBox Forum How to Remove Green Turtle icon in virtual box Windows 11 24h2 \u0026ndash; YouTube I always get the turtle \u0026ndash; Reddit Secure boot enabled but not active for windows 11 \u0026ndash; Reddit ","permalink":"https://hv8.pages.dev/blog/how-to-fix-slow-virtualbox-run-windows-10-11/","summary":"Как же убрать эту чертову черепаху?","title":"Исправление медленной работы VirtualBox на Windows 10\u002611"},{"content":" 📝 В самом начале уведомляю что root права НЕ требуются. И так, у меня есть блог, как вы могли заметить. И я подумал, было бы круто что-то писать/менять с телефона, смотреть превью и пушить изменения. А не как обычно я это делал через приложения для заметок в качестве черновика и без превью.\nЧто понадобится:\nAndroid Termux Markdown редактор или просто редактор текста У меня Android 15. Termux скачан из F-Droid. Markdown редактор нужен что умеет работать с файлами, то есть не только внутреннее хранилище приложения. А так же легкий и который не будет особо мусорить своими файлами, то есть не Obsidian, а например Zettel Notes.\nTermux В Termux как и на любом linux для начала выполним:\n1 pkg update \u0026amp;\u0026amp; pkg upgrade -y Чтобы все обновить. Далее:\n1 termux-setup-storage Это команда Termux, после выполнения, приложение запросит разрешение на доступ к файлам. И в ls ~/storage/shared должны будут появиться привычные вам директории, как в проводнике. А это значит что доступ к файлам есть.\n📝 pkg, это команда Termux, обертка для apt которая делает дополнительные проверки. Поэтому в контексте установки пакетов лучше использовать pkg для лучшей совместимости. Дальше все завист от вашего \u0026ldquo;хочу\u0026rdquo;. В случае моего \u0026ldquo;хочу\u0026rdquo; мне нужен go и hugo для генерации сайта (превью, live server) и git для клонирования/обновления репозитория сайта, поэтому именно этот сценарий я и опишу далее.\nУстановка git:\n1 pkg install git -y Установка ssh:\n1 pkg install openssh -y 📝 SSH нужен для работы с вашим сервером через git (вы \u0026lt;-\u0026gt; сервер), то есть если вы не используете ничего типа GitHub. Если вы используете такой сервис и не используете ssh ключи для авторизации, устанавливать не обязательно. Авторизация git чтобы пушить изменения:\n1 git config --global user.name \u0026#34;\u0026lt;username\u0026gt;\u0026#34; 1 git config --global user.email \u0026lt;email@example.com\u0026gt; 1 git config --global credential.helper store store \u0026ndash; не самый безопасный способ хранения, но в контексте Android (sandbox) и ограничений Termux (отсутствие полноценной поддержки libsecret) пойдет.\nУстановка go:\n1 pkg install golang Проверка: go version.\nСборка hugo:\nУстановка clang:\n1 pkg install clang И сборка hugo:\n1 CGO_ENABLED=1 go install -tags extended github.com/gohugoio/hugo@latest В момент установки зависимостей показалось что оно зависло, даже лог не шел, но оказалось что это не так. Когда завершится, выполнить команду:\n1 ls ~/go/bin/ Там должен быть \u0026ldquo;hugo\u0026rdquo;, если так, значит оно скомпилировалось.\nТеперь добавим это в переменные среды, чтобы не писать путь до бинарника каждый раз:\n1 touch ~/.bashrc 1 echo \u0026#39;export PATH=\u0026#34;$HOME/go/bin:$PATH\u0026#34;\u0026#39; \u0026gt;\u0026gt; ~/.bashrc \u0026amp;\u0026amp; source ~/.bashrc Проверка: hugo version.\nА еще при запуске сервера например hugo server -D, нужно использоваться флаг noBuildLock из-за особенности файловой системы Android блокировки файлов.\nТо есть:\n1 hugo server -D --noBuildLock Markdown редактор Markdown редактор на ваш вкус, цвет и настроение. Можно и вовсе не markdown редактор, а какой-нибудь обычный текстовый редактор. Я выбрал Zettel Notes из-за легкости и кастомизации.\nПослесловие Я пробовал устанавливать go и hugo вручную как это делаю обычно (но arm64 версии, uname -m = \u0026ldquo;aarch\u0026rdquo; ).\nGo работал, hugo просто не работал. Тогда я попытался собрать hugo по официальной документации, но go сыпался при работе с сетью (скачивание зависимостей). Устанавливать hugo через пакетный менеджер не вариант, потому что старая + не extended версия.\nЯ попробовал установить go через pkg, go все так же работал, но исправился краш компилятора при скачивание зависимостей, тогда я попробовал снова собрать hugo, и о чудо.\n","permalink":"https://hv8.pages.dev/blog/ssg-on-android-via-termux-hugo/","summary":"Настраиваем Termux и компилируем hugo на Android.","title":"SSG на Android через Termux на примере hugo"},{"content":"Изменения 30 янв. 2026\nДобавлено: Настройка и интеграция SSO 27 янв. 2026\nДобавлено: Как сделать красивые юзернеймы Добавлено: Настройка и включение федерации Дополнение: Исправление для PostgreSQL v18+ 13 авг. 2025\nДобавлено: Установка TURN сервера (Coturn) Введение Это именно то о чем вы думаете. Вам не придется покупать дорогой VPS для хостинга Matrix. Достаточно простого VPS и средне-мощного ПК прямо у вас дома.\n📝 Обратите внимание статья написана с инструкциями на примере Linux (Debian) и с использованием Docker. О Matrix Matrix \u0026ndash; это открытый протокол для обмена сообщениями в реальном времени. Проект был запущен в 2014 году командой из компании Amdocs 1 . Протокол определяет модель событий, формат данных и API для обмена сообщениями между клиентами и серверами, а также для их федерации, то есть взаимодействия между собой.\nДля передачи данных Matrix использует стандартные транспорты, такие как HTTP/HTTPS, WebSockets и WebRTC. События и сообщения представлены в формате JSON и передаются через REST-подобные интерфейсы.\nГлавная особенность Matrix \u0026ndash; это его федеративная и децентрализованная архитектура 1 . Множество серверов могут объединяться в единую открытую федерацию, что устраняет зависимость от одного центрального узла и обеспечивает гибкость развертывания.\nMatrix поддерживает передачу текста, файлов и медиа, а также интеграции с другими системами 2 . Это позволяет пользователям общаться, независимо от используемого клиента или провайдера.\nДля защиты данных Matrix использует сквозное шифрование (E2E). При включенном шифровании содержимое сообщений хранится на серверах в зашифрованном виде, и только участники чата с соответствующими ключами могут его расшифровать. При этом серверы видят служебную информацию, такую как метаданные и состав комнат.\nMatrix используется как частными лицами, так и организациями, включая корпоративный и государственный сектор. Например, решения на базе Matrix применяются в вооруженных силах 3 и системе здравоохранения Германии 4 .\nMatrix это Synapse? Matrix это не программа, это протокол, набор правил, экосистема. Фактически чат работает на Synapse, но есть и другие, например Dendrite.\nПодобно тому как электронная почта работает на основе протоколов IMAP/SMTP, Matrix определяет, как клиенты и сервера должны обмениваться данными. Это позволяет разным серверам и клиентам работать вместе.\nЧто будем делать? Захостим Matrix мессенджер на домашнем ПК с динамическим IP, который будет доступен в интернете через VPS.\nSynapse довольно требователен к железу (зависит от кол-ва юзеров), особенно в контексте дискового пространства (медиа файлы), и подходящий VPS/VDS будет не дешевым. Поэтому я покажу как поднять Matrix именно на домашнем ПК/сервере с конфигурацией заточенной под Pangolin.\nЧто понадобится:\nДомашний сервер, \u0026gt;2 CPU \u0026amp; RAM, и побольше дискового пространства Дешевый VPS, \u0026gt;=1 CPU \u0026amp; RAM, желательно с каналом пошире (\u0026gt;=1 Gbit) Доменное имя Ну и в идеале базовые знания Linux, Docker, настройки DNS и знание Pangolin.\nПодразумевается что вы уже установили, настроили Pangolin и проверили что все работает, но если нет:\nУстановка Pangolin Хотели мощный VPS/VDS, но нету денег? Проблемы с NAT? Есть решение! 𝙓 В данной статье я покажу как поднять и Synapse и Element. Element нужен чтобы была некая страница (frontend, клиент) где юзеры прямо в браузере могли бы зарегистрировать аккаунт и/или войти в аккаунт, а так же чтобы была совместимость с клиентами Element и в целом Matrix можно было бы пользоваться прямо в браузере без программ.\nДва отдельных сервиса, Synapse и Element. Их можно повесить на два разных домена/поддомена, но могут возникнуть проблемы, Element в некоторых сценариях будет обращаться к домену на котором он работает, но на нем НЕ работает Synapse, поэтому будет куча ошибок, и учитывая что в этой статье рассматривается хостинг Synapse и Element на одной машине, мы не будет парится, и сделаем как проще.\nЧтобы элегантно это решить, мы будем использовать сеть внутри Docker, и использовать Nginx чтобы сделать reverse proxy на localhost, который уже будет пробрасываться через Pangolin.\nТипо такого:\nservices: synapse and etc: networks: m_network: ipv4_address: 10.10.10.X reverse-proxy: ports: - \u0026#34;4100:80\u0026#34; networks: m_network: ipv4_address: 10.10.10.X networks: m_network: ipam: driver: default config: - subnet: \u0026#34;10.10.10.0/24\u0026#34; # Synapse API location ~ ^(/_matrix|/_synapse/client) { ... } # Element location / { ... } Контейнеры общаются между собой в своей Docker сети, весь внешний трафик входит через nginx, который работает на 4100 порту и хост которого пробрасывается через Pangolin.\n💡 Фактически если вы немного в теме, это универсальная инструкция, которую можно использовать как для хостинга Matrix прямо на VPS, так и на домашнем сервере используя на VPS не только Pangolin, а что-нибудь другое. Установка Matrix 📝 Synapse по умолчанию использует sqlite, (личное мнение) это совсем не очень хороший выбор базы данных, поэтому будем использовать PostgreSQL. 💡 Я подготовил все конфиги необходимые для базового старта Matrix. Если вы будете что-то менять, что не описано в тексте ниже, делайте это внимательно. Установка Docker:\n1 sudo sh -c \u0026#39;curl -fsSL https://get.docker.com -o get-docker.sh \u0026amp;\u0026amp; sh ./get-docker.sh \u0026amp;\u0026amp; rm -f get-docker.sh\u0026#39; Клонирование репозитория с приготовленными конфигами:\n1 git clone https://github.com/nozsh/matrix-element-pangolin-conf matrix \u0026amp;\u0026amp; cd matrix Создание конфигурации Synapse (homeserver.yaml):\n1 sudo docker compose run --rm -e SYNAPSE_SERVER_NAME=domain.org -e SYNAPSE_REPORT_STATS=no synapse generate Где domain.org ваш домен или поддомен, на него должно/будет указывать DNS запись на ваш VPS сервер на котором установлен Pangolin.\nРедактирование конфига, например через nano 5 :\n1 nano synapse/homeserver.yaml В самый конец нужно добавить:\n1 2 enable_registration: true enable_registration_without_verification: true enable_registration - включает регистрацию. enable_registration_without_verification - отключает предупреждения если нету никакой защиты типа капчи. Установить пароль для базы данных:\n1 cp example.env .env \u0026amp;\u0026amp; nano .env Если строка содержит спец. символы убедитесь что все нормально:\n1 sudo docker compose config Переменная POSTGRES_PASSWORD должна содержать ту же строку что вы туда и положили (в \u0026ldquo;.env\u0026rdquo;).\nДальше нужно поменять базу данных на PostgreSQL. Из \u0026ldquo;homeserver.yaml.example\u0026rdquo; скопируйте конфигурацию database и замените в вашем \u0026ldquo;homeserver.yaml\u0026rdquo;:\n1 2 database: ... Не забудьте установить \u0026ldquo;password\u0026rdquo; такой же, какой вы установили в \u0026ldquo;.env\u0026rdquo;.\nРедактирование конфига Element:\n1 nano element-config.json В base_url ваш домен с протоколом и без \u0026ldquo;/\u0026rdquo; в конце. Используйте \u0026ldquo;https\u0026rdquo;, Pangolin сам работает с SSL сертификатами.\n\u0026quot;disable_custom_urls\u0026quot;: true - запрещает использовать НЕ ваш Matrix сервер, иначе можно будет использовать другой Matrix сервер через ваш Element instance.\nАналогично:\n1 nano wellknown/matrix/client И так же:\n1 nano nginx/default.conf Поменяйте server_name domain.org на ваш домен.\nДалее нужно раскомментировать две строки в \u0026ldquo;docker-compose.yaml\u0026rdquo;:\n1 nano docker-compose.yaml 1 2 3 4 5 # depends_on: # - synapse_db ⇓ depends_on: - synapse_db ВАЖНО: О PostgreSQL \u0026gt;=18 В новой версии PostgreSQL изменены пути, поэтому если вы не используете версию \u0026lt;18 то необходимо их изменить в вашем docker-compose.yaml.\nЕсли установка новая (данных еще нету или есть, но их не жалко), то\n1 sudo docker compose down -v Далее:\n1 sudo docker exec matrix-1-synapse_db-1 env | grep PGDATA 📝 Название вашего matrix-1-synapse_db-1 можно посмотреть через sudo docker ps. Например вывело PGDATA=/var/lib/postgresql/18/docker, значит в docker-compose.yaml изменить:\n1 2 3 4 5 volumes: - ...:/var/lib/postgresql/data ⇓ volumes: - ...:/var/lib/postgresql/18/docker 💡 Некоторые вещи из \u0026ldquo;Дополнительно\u0026rdquo; желательно сделать до запуска.\n🚀 - лучше сделать до первого запуска\n🧩 - значения не имеет\nЗапуск:\n1 sudo sh -c \u0026#39;docker compose down \u0026amp;\u0026amp; docker compose up -d --force-recreate \u0026amp;\u0026amp; docker compose logs -f\u0026#39; Element должен открываться по ip:port (в конфиге 4100) и домену если вы уже настроили Pangolin.\nДополнительно 🚧 Это доп. инструкции для людей которые чего-то хотят и понимают что именно и как именно хотят. Если вы не знаете надо ли оно вам, или не понимаете о чем речь \u0026ndash; не делайте этого. 🚧 \u0026ldquo;Красивые юзернеймы\u0026rdquo; и \u0026ldquo;Включение/Настройка федерации\u0026rdquo; вероятно не получится сделать с Pangolin, потому что нужно писать/править конфиги руками. А на момент написания этой статьи в Pangolin нельзя вручную менять конфиги. 🚀 Красивые юзернеймы Если вы используете поддомен, и везде укажите поддомен \u0026ldquo;sub.domain.org\u0026rdquo; (потому что там у вас synapse/element), то юзернемы будут такими \u0026ldquo;user:sub.domain.org\u0026rdquo;. Я покажу как сделать чтобы они были такими \u0026ndash; \u0026ldquo;user:domain.org\u0026rdquo;.\nЕсли вы уже все настроили, все запустили, и все уже давно работает \u0026ndash; то ничего не делайте, чтобы это сделать нужно очистить базу данных. Ну, а если вы еще ничего не запускали то смело делайте. А если запускали, но хотите переделать выполните:\n1 sudo docker compose down -v 1 rm -rf /path/to/location/where/db/* Это для очистки БД. Ну или можете вручную попробовать править базу.\nДомашний сервер\n1 nano synapse/homeserver.yaml 1 server_name: \u0026#34;sub.domain.org\u0026#34; ==\u0026gt; \u0026#34;domain.org\u0026#34; Вот element-config.json менять чисто для общей эстетики, не обязательно.\n1 nano element-config.json 1 2 3 4 5 6 7 8 9 { \u0026#34;default_server_config\u0026#34;: { \u0026#34;m.homeserver\u0026#34;: { \u0026#34;base_url\u0026#34;: \u0026#34;https://sub.domain.org\u0026#34;, \u0026#34;server_name\u0026#34;: \u0026#34;domain.org\u0026#34; } }, \u0026#34;disable_custom_urls\u0026#34;: true } 1 nano nginx/default.conf Убрать:\n1 2 3 4 5 location /.well-known/matrix/ { root /usr/share/nginx/html; default_type application/json; add_header Access-Control-Allow-Origin *; } VPS\nВ корне сайта domain.org:\n1 mkdir -p .well-known/matrix/ \u0026amp;\u0026amp; touch .well-known/matrix/client \u0026amp;\u0026amp; touch .well-known/matrix/server \u0026amp;\u0026amp; ls .well-known/matrix/ client:\n1 2 3 4 5 { \u0026#34;m.homeserver\u0026#34;: { \u0026#34;base_url\u0026#34;: \u0026#34;https://sub.domain.org\u0026#34; } } server:\n1 2 3 { \u0026#34;m.server\u0026#34;: \u0026#34;sub.domain.org:443\u0026#34; } NGINX для \u0026ldquo;domain.org\u0026rdquo; (НЕ \u0026ldquo;sub.domain.org\u0026rdquo;):\n1 2 3 4 5 6 7 8 9 10 server { listen 443 ssl; ... location /.well-known/matrix/ { default_type application/json; add_header Access-Control-Allow-Origin *; } location / { ... Если вы используете федерацию, проверьте что она работает здесь.\nУ \u0026ldquo;sub.domain.org\u0026rdquo; вероятно будет ошибка \u0026ldquo;MatchingServerName\u0026rdquo;, это нормально. Но у \u0026ldquo;domain.org\u0026rdquo; \u0026ndash; ошибок быть не должно, то есть проверять нужно то что указано в server_name в homeserver.yaml.\n🧩 Включение/Настройка федерации Домашний сервер\ndocker-compose.yaml:\n1 2 3 4 reverse-proxy: ports: - \u0026#34;4100:80\u0026#34; - \u0026#34;4101:8448\u0026#34; NGINX default.conf:\n1 2 3 4 5 6 7 ... server { listen 80; listen [::]:80; listen 8448; listen [::]:8448; ... VPS\nОткрыть порт 8448 в firewall и указать его в Docker если вы используете Docker, на примере ufw и ZT:\n1 ufw allow 8448/tcp 1 2 3 4 5 6 zerotier: ports: - \u0026#34;9993:9993/udp\u0026#34; - \u0026#34;80:80\u0026#34; - \u0026#34;443:443\u0026#34; - \u0026#34;8448:8448\u0026#34; NGINX, в конце добавить еще один server блок:\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 server { listen 8448 ssl; http2 on; server_name domain.org; client_max_body_size 100M; ssl_certificate /etc/letsencrypt/live/domain.org/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/domain.org/privkey.pem; ssl_session_cache shared:le_nginx_SSL:10m; ssl_session_timeout 1440m; ssl_protocols TLSv1.2 TLSv1.3; ssl_prefer_server_ciphers on; location / { proxy_pass http://ip:4101; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto https; proxy_http_version 1.1; } } Проверить работоспособность федерации можно здесь.\n🧩 Отключение федерации homeserver.yaml:\n1 federation_domain_whitelist: [] Или отключить федерацию со всеми, кроме некоторых:\n1 2 3 federation_domain_whitelist: - server.org - server.com Разницы форматирования между этими двумя нету, это просто разный синтаксис, но если перечислять \u0026ndash; так просто удобнее, чем в строку.\n🧩 Подключение Google reCaptcha Создать ключи тут (v2, \u0026ldquo;I\u0026rsquo;m not a robot\u0026rdquo;).\nhomeserver.yaml:\n1 2 3 4 5 enable_registration_without_verification: false recaptcha_public_key: \u0026#34;x\u0026#34; recaptcha_private_key: \u0026#34;x\u0026#34; enable_registration_captcha: true Обратите внимание, капча будет работать только на домене. При доступе через ip:port капча работать не будет и вы не сможете зарегистрировать аккаунт соответственно.\n🚀 Разделение хранилища 📝 Если у вас уже есть файлы \u0026ndash; их можно просто перенести после изменений (когда разметите пространство) и перед запуском контейнера. На примере LVM дисков.\nЕсть SSD и HDD, оба LVM, нужно сделать так, чтобы был отдельный логический том SSD диска для БД Synapse и отдельный логический том HDD для медиа файлов, а сам Docker контейнер работал в home/root.\nЭто рабочий пример, где \u0026ldquo;vg0\u0026rdquo; ваш Volume Group, где sda1 и nvme0n1 ваши диски:\n1 2 3 4 5 6 7 sudo lvcreate -L 10G -n synapse-1-media vg0 /dev/sda1 sudo mkfs.ext4 /dev/vg0/synapse-1-media sudo mkdir -p /mnt/synapse-1-media sudo mount /dev/vg0/synapse-1-media /mnt/synapse-1-media sudo su echo \u0026#34;/dev/vg0/synapse-1-media /mnt/synapse-1-media ext4 defaults 0 2\u0026#34; \u0026gt;\u0026gt; /etc/fstab exit 1 2 3 4 5 6 7 sudo lvcreate -L 10G -n synapse-1-db vg0 /dev/nvme0n1p3 sudo mkfs.ext4 /dev/vg0/synapse-1-db sudo mkdir -p /mnt/synapse-1-db sudo mount /dev/vg0/synapse-1-db /mnt/synapse-1-db sudo su echo \u0026#34;/dev/vg0/synapse-1-db /mnt/synapse-1-db ext4 defaults 0 2\u0026#34; \u0026gt;\u0026gt; /etc/fstab exit 1 sudo sh -c \u0026#39;mkdir -p /mnt/synapse-1-media/data \u0026amp;\u0026amp; mkdir -p /mnt/synapse-1-db/data\u0026#39; Права:\n1 chown -R 1000:1000 /mnt/synapse-1-media Потому что docker-compose.yaml:\n1 2 3 4 synapse: environment: - UID=1000 - GID=1000 На \u0026ldquo;synapse-1-db\u0026rdquo; тоже нужно будет установить владельца и группу, если:\n1 sudo docker run --rm postgres id покажет не:\n1 uid=0(root) gid=0(root) groups=0(root) docker-compose.yaml:\n1 2 3 4 5 6 7 8 synapse: volumes: - ./synapse:/data - /mnt/synapse-1-media/data:/media synapse_db: volumes: - /mnt/synapse-1-db/data:/var/lib/postgresql/data homeserver.yaml:\n1 2 media_store_path: /media/data uploads_path: /media/data/uploads Путь получится \u0026ldquo;/data/data/\u0026rdquo;, в корень файлы лучше не записывать, потому что корень зачастую не пустой из-за \u0026ldquo;lost+found\u0026rdquo; (зависит от файловой системы). А программа может требовать чтобы директория была пуста, так например требует PostgreSQL, к тому же зачем смешивать файлы.\nНе красиво, но точно будет работать.\n🧩 Максимальный размер загружаемых файлов (Max Upload Size) homeserver.yaml:\n1 max_upload_size: 500M nginx:\n1 client_max_body_size 500M; 🧩 Другие размеры миниатюр Может работать некорректно, или не работать вовсе. Лично у меня не работало и сломало аватарки.\nhomeserver.yaml:\n1 2 3 4 thumbnail_sizes: - width: 320 height: 240 method: scale # OR crop В любом случае миниатюры обычно создаются сами.\nПодробнее.\n🧩 Мосты Telegram В существующем docker-compose.yaml:\n1 2 3 4 5 6 7 8 9 10 11 mautrix-telegram: image: dock.mau.dev/mautrix/telegram:latest container_name: mautrix-telegram restart: unless-stopped volumes: - ./mautrix-telegram:/data networks: m_network: ipv4_address: 10.10.10.6 depends_on: - synapse 1 mkdir mautrix-telegram 1 sudo docker compose run --rm mautrix-telegram 1 sudo nano mautrix-telegram/config.yaml 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 address: http://synapse:8008 domain: domain.org verify_ssl: false appservice: address: http://mautrix-telegram:29317 database: postgres://synapse:password@synapse_db/mautrix_telegram # postgres://username:password@hostname/dbname ... telegram: # Get your own API keys at https://my.telegram.org/apps api_id: xyz api_hash: xyz bridge: permissions: \u0026#39;*\u0026#39;: relaybot domain.org: puppeting # domain.org: full \u0026#39;@admin:domain.org\u0026#39;: admin 1 sudo docker compose exec synapse_db psql -U synapse -c \u0026#34;CREATE DATABASE mautrix_telegram WITH ENCODING=\u0026#39;UTF8\u0026#39;;\u0026#34; 1 sudo docker compose run --rm mautrix-telegram 1 cp mautrix-telegram/registration.yaml synapse/mautrix-telegram-registration.yaml 1 nano synapse/homeserver.yaml 1 2 app_service_config_files: - /data/mautrix-telegram-registration.yaml 1 sudo sh -c \u0026#39;docker compose down \u0026amp;\u0026amp; docker compose up -d --force-recreate \u0026amp;\u0026amp; docker compose logs -f\u0026#39; Подробнее.\n🧩 Настройка и интеграция SSO Зачем это нужно? Помимо общих применений SSO, так же для авторизации в matrix через стороние сервисы типа Google, GitHub и др. (но об этом тут не будет), и/или для улучшения защиты аккаунтов пользователей посредством 2FA. Потому что synapse/element сами по себе не поддерживают 2FA.\nТо есть, чтобы войти в аккаунт matrix нужно будет не только ввести логин, пароль и ключ восстановления или подтвердить авторизацию с другого устройства, а вести логин, пароль, 2FA или использовать аппаратный ключ и только потом ключ восстановления или подтвердить вход с другого устройства чтобы расшифровать сообщения.\nСвоего рода «Defense in Depth». По факту просто круто + может пригодится если у вас будет очень много selfhosted сервисов с поддержкой SSO, чтобы был один вход на все сервисы вместо огромной кучи пар логин и пароль.\nМожно поднять в том же docker-compose.yaml файле где synapse и element, или в отдельном \u0026ndash; разницы нет. Что использовать в качестве сервиса SSO и как это поднять я не покажу, это вы решайте сами. Я же покажу только как настроить на примере Authentik.\n📝 Последующие употребление \u0026ldquo;SSO\u0026rdquo; расценивайте не как аббревиатуру «Single Sign-On», а как некую неопределенную платформу (Authentik, Keycloak, Authelia, Zitadel, и тд). Applications ==\u0026gt; Providers ==\u0026gt; Create ==\u0026gt; \u0026ldquo;OAuth2/OpenID Provider\u0026rdquo;. Provider Name - что-нибудь связанное с matrix. Authorization flow - на ваш вкус, но если не знаете что это, выбирайте \u0026ldquo;explicit\u0026rdquo;. Client type - Confidential. Redirect URIs/Origins (RegEx) - указать ваш URL Synapse (в этой статье писалось про Synapse и Element на одном домене поэтому), например https://element.domain.org/_synapse/client/oidc/callback, без / в конце. Путь должен быть точно таким, как указано. Applications ==\u0026gt; Applications ==\u0026gt; Create, ввести имя и slug, в Provider выбрать созданный ранее провайдер. В homeserver.yaml:\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 public_baseurl: \u0026#34;https://element.domain.org\u0026#34; # url на котором synapse oidc_providers: - idp_id: authentik idp_name: \u0026#34;SSO\u0026#34; discover: true issuer: \u0026#34;https://sso.domain.org/application/o/my-matrix-slug/\u0026#34; client_id: \u0026#34;xxx\u0026#34; client_secret: \u0026#34;xxx\u0026#34; scopes: - \u0026#34;openid\u0026#34; - \u0026#34;profile\u0026#34; # - \u0026#34;email\u0026#34; allow_existing_users: true # после миграции юзеров отключить enable_registration: true user_mapping_provider: config: localpart_template: \u0026#34;{{ user.preferred_username }}\u0026#34; display_name_template: \u0026#34;{{ user.name }}\u0026#34; Моя конфигурация OIDC 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 oidc_providers: - idp_id: authentik idp_name: \u0026#34;SSO\u0026#34; discover: true issuer: \u0026#34;https://sso.domain.org/application/o/matrix-nexus/\u0026#34; client_id: \u0026#34;xxx\u0026#34; client_secret: \u0026#34;xxx\u0026#34; scopes: - \u0026#34;openid\u0026#34; - \u0026#34;profile\u0026#34; allow_existing_users: false enable_registration: true backchannel_logout_enabled: true # Provider - Logout URI: https://element.domain.org/_synapse/client/oidc/backchannel_logout user_mapping_provider: config: localpart_template: \u0026#34;{{ user.preferred_username }}\u0026#34; display_name_template: \u0026#34;{{ user.name }}\u0026#34; NGINX:\n1 2 3 proxy_set_header X-Forwarded-Proto $backend_proto; ⇓⇓⇓ proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto; allow_existing_users: true \u0026ndash; нужен для миграции текущих юзеров, если таковы есть. Для миграции нужно создать юзера с тем же username что и в matrix, если \u0026ldquo;john:domain.org\u0026rdquo; то \u0026ldquo;john\u0026rdquo;, и когда Джон залогинится, к аккаунту SSO автоматически привяжется аккаунт Synapse.\n🚧 allow_existing_users: true опция ОЧЕНЬ НЕ безопасная, если у вас будет включена публичная регистрация на SSO платформе любой сможет украсть аккаунт просто зарегистрировав существующий юзернейм. enable_registration: true \u0026ndash; если у вас приватный сервер и вы делаете аккаунты вручную, то вам нужно будет создать аккаунт в Synapse и SSO, но если true, то только в SSO, аккаунт Synapse будет создан и привязан к SSO автоматически при первом входе. По умолчанию \u0026ldquo;true\u0026rdquo;.\nЧтобы отключить вход по логину и паролю, оставив только SSO, в homeserver.yaml:\n1 2 password_config: enabled: false Группы (Authentik) Группы нужны если вы например хотите иметь 100 юзеров, но что бы лишь 20 из них могли залогинится в matrix.\nМожно сделать через homeserver.yaml, искать пример attribute_requirements тут.\nНо есть так же как по мне лучший вариант сделать это чисто на стороне Authentik: Applications ==\u0026gt; Applications ==\u0026gt; ваше приложение ==\u0026gt; Policy / Group / User Bindings ==\u0026gt; Bind existing Policy / Group / User ==\u0026gt; Group ==\u0026gt; выбрать нужную ранее созданную группу.\nКапча (Authentik) Если вы не задумались \u0026ldquo;а как же капча?\u0026rdquo; \u0026ndash; задумайтесь. Капча есть и ее можно настроить. Нужно создать \u0026ldquo;stage\u0026rdquo; в \u0026ldquo;stages\u0026rdquo; с типом \u0026ldquo;Captcha Stage\u0026rdquo;, выбрать провайдера и вписать ключи, тут все просто.\nДалее зайти в Flows and Stages ==\u0026gt; Flows, выбрать нужный Flow куда нужно добавить капчу \u0026ndash; \u0026ldquo;default-authentication-flow\u0026rdquo; ==\u0026gt; Stage Bindings ==\u0026gt; Bind existing stage ==\u0026gt; Выбрать ту капчу что вы создали ранее, order нужно установить между \u0026ldquo;identification\u0026rdquo; и \u0026ldquo;password\u0026rdquo; \u0026ndash; обычно это 15.\n🧩 Установка TURN сервера (Coturn) TURN сервер лучше установить на VPS с публичным IP, можно рядом с Pangolin, все будет работать. В Pangolin для TURN сервера ничего добавлять и настраивать не нужно.\n1 git clone https://github.com/nozsh/matrix-element-pangolin-conf coturn \u0026amp;\u0026amp; cd coturn \u0026amp;\u0026amp; mv extra/coturn . \u0026amp;\u0026amp; find . -maxdepth 1 -not -name \u0026#39;coturn\u0026#39; -not -name \u0026#39;.\u0026#39; -exec rm -rf {} + \u0026amp;\u0026amp; mv coturn/* . \u0026amp;\u0026amp; rm -rf coturn/ Открыть порты UFW (на всякий случай):\n1 sudo sh -c \u0026#39;ufw allow 3478/tcp \u0026amp;\u0026amp; ufw allow 3478/udp \u0026amp;\u0026amp; ufw allow 5349/tcp \u0026amp;\u0026amp; ufw allow 5349/udp \u0026amp;\u0026amp; ufw allow 59000:60100/udp \u0026amp;\u0026amp; ufw status\u0026#39; 1 nano coturn.conf Поменять external-ip, realm и server-name. А также данные user=test:test - логин:пароль.\nСертификаты можно получить через certbot, или в другом месте, например Cloudflare:\n\u0026ldquo;cert.pem\u0026rdquo; - публичный ключ \u0026ldquo;private.key\u0026rdquo; - приватный ключ 1 touch certs/cert.pem certs/private.key Если вы создали сертификаты с помощью \u0026ldquo;certbot\u0026rdquo; то нужно использовать \u0026ldquo;fullchain.pem\u0026rdquo; и \u0026ldquo;privkey.pem\u0026rdquo;:\n/etc/letsencrypt/live/turn.domain.org/fullchain.pem /etc/letsencrypt/live/turn.domain.org/privkey.pem 1 docker compose up -d \u0026amp;\u0026amp; docker compose logs -f --tail=200 Если при запуске все виснет \u0026ndash; уберите порты и используйте:\n1 2 3 services: coturn: network_mode: host Более того, так лучше сделать в любом случае, потому что Docker будет открывать все эти порты с 59000 до 60100, это довольно много, и может быть плохо.\nhomeserver.yaml:\n1 2 3 4 5 6 7 8 9 turn_uris: - \u0026#34;turns:turn.domain.org:5349?transport=tcp\u0026#34; - \u0026#34;turns:turn.domain.org:5349?transport=udp\u0026#34; - \u0026#34;turn:turn.domain.org:3478?transport=tcp\u0026#34; - \u0026#34;turn:turn.domain.org:3478?transport=udp\u0026#34; turn_username: \u0026#34;test\u0026#34; turn_password: \u0026#34;test\u0026#34; turn_allow_guests: true Протестировать turn сервер независимо от matrix можно здесь, но если у вас в браузере отключен WebRTC \u0026ndash; временно включите его.\nУдаление \u0026ldquo;старых\u0026rdquo; медиа файлов Это может не работать:\nhomeserver.yaml:\n1 2 3 media_retention: local_media_lifetime: 90d # медиа от пользователей remote_media_lifetime: 14d # медиа с других серверов (федерация) 100% рабочий вариант через API:\nСоздать админ аккаунт \u0026ndash; см. Synapse Admin.\nПолучить токен:\n1 URL=\u0026#34;http://10.10.10.2:8008\u0026#34;; USER=\u0026#34;@admin:domain.org\u0026#34;; PASS=\u0026#39;abrakadabra\u0026#39;; curl -X POST \u0026#34;$URL/_matrix/client/v3/login\u0026#34; -H \u0026#34;Content-Type: application/json\u0026#34; -d \u0026#34;{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;m.login.password\\\u0026#34;,\\\u0026#34;user\\\u0026#34;:\\\u0026#34;$USER\\\u0026#34;,\\\u0026#34;password\\\u0026#34;:\\\u0026#34;$PASS\\\u0026#34;}\u0026#34; Удалить все что старше 1 минуты (60000 в мс):\n1 BEFORE_TS=$(($(date +%s%3N) - 60000)); URL=\u0026#34;http://10.10.10.2:8008\u0026#34;; TOKEN=\u0026#34;token\u0026#34;; curl -X POST -H \u0026#34;Authorization: Bearer $TOKEN\u0026#34; \u0026#34;$URL/_synapse/admin/v1/media/delete?before_ts=$BEFORE_TS\u0026#34; Или в одну команду, получить токен, выполнить удаление, отозвать токен:\n1 URL=\u0026#34;http://10.10.10.2:8008\u0026#34;; USER=\u0026#34;@admin:domain.org\u0026#34;; PASS=\u0026#39;abrakadabra\u0026#39;; DELAFTERMS=60000; LOGIN_RESP=$(curl -s -X POST \u0026#34;$URL/_matrix/client/v3/login\u0026#34; -H \u0026#34;Content-Type: application/json\u0026#34; -d \u0026#34;{\\\u0026#34;type\\\u0026#34;:\\\u0026#34;m.login.password\\\u0026#34;,\\\u0026#34;user\\\u0026#34;:\\\u0026#34;$USER\\\u0026#34;,\\\u0026#34;password\\\u0026#34;:\\\u0026#34;$PASS\\\u0026#34;}\u0026#34;); echo \u0026#34;Login response: $LOGIN_RESP\u0026#34;; TOKEN=$(echo \u0026#34;$LOGIN_RESP\u0026#34; | grep -oP \u0026#39;\u0026#34;access_token\u0026#34;:\u0026#34;\\K[^\u0026#34;]+\u0026#39;); BEFORE_TS=$(($(date +%s%3N) - DELAFTERMS)); curl -X POST -H \u0026#34;Authorization: Bearer $TOKEN\u0026#34; \u0026#34;$URL/_synapse/admin/v1/media/delete?before_ts=$BEFORE_TS\u0026#34;; curl -X POST \u0026#34;$URL/_matrix/client/v3/logout\u0026#34; -H \u0026#34;Authorization: Bearer $TOKEN\u0026#34; Или скриптом. И сделать cron задачу, типо такого:\n1 2 crontab -e 0 0 1 * * \u0026gt;.../matrix/utilities/media-cleanup.log; bash .../matrix/utilities/media-cleanup.sh \u0026gt;\u0026gt; .../matrix/utilities/media-cleanup.log 2\u0026gt;\u0026amp;1 Будет запускать скрипт каждые 30 дней в 00:00.\n📝 Обратите внимание, способ через API не удаляет аватарки, только любой загруженный пользователями контент в чатах - фото, видео, архивы и прочие файлы. Synapse Admin (админка) Админку можно запускать где угодно, необязательно пробрасывать в Pangolin, более того, лично я не рекомендую этого делать для безопасности (и это невозможно с конфигурацией из этой статьи (из-за конфигурации nginx)).\nАдминка от Awesome-Technologies:\n1 2 3 4 5 6 7 8 services: synapse-admin: container_name: synapse-admin hostname: synapse-admin image: awesometechnologies/synapse-admin:latest ports: - \u0026#34;4200:80\u0026#34; restart: unless-stopped Админка от etkecc:\n1 image: ghcr.io/etkecc/synapse-admin:latest Создать админ аккаунт:\n1 sudo docker exec matrix-synapse-1 register_new_matrix_user -u admin -p \u0026#39;abrakadabra\u0026#39; -a -c /data/homeserver.yaml http://localhost:8008 SSH туннель:\n1 ssh -p 22 -N -L 127.0.0.1:8008:10.10.10.2:8008 user@ip \u0026ldquo;10.10.10.2\u0026rdquo; ip Synapse:\n1 2 3 4 synapse: networks: m_network: ipv4_address: 10.10.10.2 Порт 8008 - это порт Synapse по умолчанию.\nWhat\u0026rsquo;s the Matrix protocol? And how will it change modern messaging?\u0026#160;\u0026#x21a9;\u0026#xfe0e;\u0026#160;\u0026#x21a9;\u0026#xfe0e;\nMatrix: a decentralized open-source messaging platform for the future\u0026#160;\u0026#x21a9;\u0026#xfe0e;\nA secure messaging app for the German Armed Forces\u0026#160;\u0026#x21a9;\u0026#xfe0e;\nGermany\u0026rsquo;s national healthcare system adopts Matrix!\u0026#160;\u0026#x21a9;\u0026#xfe0e;\nТекстовый редактор nano: CTRL + X, y, Enter \u0026ndash; сохранить и выйти.\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n","permalink":"https://hv8.pages.dev/blog/how-to-set-up-matrix-chat-with-pangolin/","summary":"Расскажу как развернуть Matrix на домашнем сервере за NAT и сделать его доступным в интернете.","title":"Разворачиваем Matrix-чат дома и выбрасываем в интернет. Self-hosted мессенджер"},{"content":"Смотрите так же:\nТуннель между домашним сервером и VPS через ZeroTier Очередная борьба с NAT! 𝙓 Это короткая заметка о том как установить Pangolin для туннелирования трафика.\nПонадобится сервер VPS/VDS с публичным IP адресом и доменное имя. Если вы используете Cloudflare и тп. проксирование для админки Pangolin должно быть выключено (DNS only).\n📝 Где domain.org \u0026mdash; ваш домен. Необходимо указать DNS запись на поддомен/домен для админки Pangolin, например \u0026ldquo;pangolin.domain.org\u0026rdquo;. Указывать DNS запись на сам домен \u0026ldquo;domain.org\u0026rdquo; в таком случае \u0026ndash; необязательно.\nЕсли вы используйте фаервол, нужно разрешить следующие порты: \u0026ldquo;80/tcp\u0026rdquo;, \u0026ldquo;443/tcp\u0026rdquo;, \u0026ldquo;51820/udp\u0026rdquo;, \u0026ldquo;21820/udp\u0026rdquo;. На примере ufw:\n1 sudo sh -c \u0026#39;ufw allow 80/tcp \u0026amp;\u0026amp; ufw allow 443/tcp \u0026amp;\u0026amp; ufw allow 51820/udp \u0026amp;\u0026amp; ufw allow 21820/udp\u0026#39; Установка Docker:\n1 sudo sh -c \u0026#39;curl -fsSL https://get.docker.com -o get-docker.sh \u0026amp;\u0026amp; sh ./get-docker.sh \u0026amp;\u0026amp; rm -f get-docker.sh\u0026#39; Далее следуйте установки из документации.\nBase domain: \u0026ldquo;domain.org\u0026rdquo;, в любом случае, даже если вы не будите его использовать Dashboard domain: домен на котором будет админка, например \u0026ldquo;pangolin.domain.org\u0026rdquo;, на него должна указывать DNS запись Email: любой, можно даже несуществующий, например \u0026ldquo;cert@domain.org\u0026rdquo; Если вам не нужны какие-то специфичные настройки, везде где что-то спрашивает и есть \u0026ldquo;(default: X)\u0026rdquo; \u0026ndash; нажимайте Enter.\nЕсли ошибок не было - открываете сайт, входите в аккаунт и настраиваете. Newt советую использовать в Docker compose.\nВ прокси нужно добавлять локальный IP машины, и порт на котором работает приложение. Например, у VPS IP \u0026ldquo;a.a.a.a\u0026rdquo;, у домашнего сервера динамический IP \u0026ldquo;b.b.b.b\u0026rdquo;, а локальный (hostname -I) \u0026ldquo;c.c.c.c\u0026rdquo;. Приложение работает в Docker на \u0026ldquo;8888\u0026rdquo; порту. Нужно указать IP - \u0026ldquo;c.c.c.c\u0026rdquo;, и порт \u0026ldquo;8888\u0026rdquo;.\n","permalink":"https://hv8.pages.dev/blog/installing-pangolin/","summary":"Хотели мощный VPS/VDS, но нету денег? Проблемы с NAT? Есть решение!","title":"Установка Pangolin"},{"content":"Дисклеймер/Ахтунг 🚧 Настоящий материал подготовлен исключительно в образовательных и исследовательских целях. Он не содержит призывов к каким-либо действиям, нарушающим законодательство. Автор(ы) не несут ответственности за последствия использования изложенной информации. Использование/применение представленных сведений осуществляется на ваш страх и риск. Информация предоставляется исключительно для законного изучения и анализа. Любое использование описанных методов для несанкционированного доступа к данным или системам является незаконным и строго запрещено. Любое использование материала в незаконных целях нарушает закон и не одобряется авторами. 🚧 Весь представленный материал носит исключительно юмористический, сатирический и/или пародийный характер. Любые упоминания лиц, организаций, событий и явлений являются вымышленными, гиперболизированными или используются в шутливом контексте. Любое совпадение с реальными событиями или личностями случайно или является частью авторской иронии. Материал не содержит реальных призывов к действию, не отражает реального мнения авторов и не предназначен для восприятия в буквальном смысле. Если в тексте вы нашли что-то, что может показаться оскорбительным, абсурдным или провокационным, помните — это художественное преувеличение, сатира и ирония и не должно восприниматься буквально. Не воспринимайте данный материал всерьез! Лэй Цзюнь - отс*си 🖕\nВступление Что мы имеем:\nPOCO M4 Pro 4G на A13 и HyperOS 1.0.8.0, не китайский.\nКитайскую версию прошивки говорят прошить нельзя, так как невозможно разблокировать загрузчик, но есть какие-то платные способы, но я в этом не разбирался.\nМой путь начался в этом прекрасном треде со списком прошивок на xda, перетек сюда, далее сюда. А так же я побывал здесь, тут, там и вот здесь вот, а закончился мой путь в этом треде.\nВкратце, не берите первые попавшиеся Xiaomi/POCO в надежде что прошьете. А если берете, то сначала посмотрите есть ли актуальные ROM на вашу модель, и если есть и вы взяли, НЕ обновляйте телефон, так шансов провернуть этот финт будет выше.\n📝 Если вы оказались тут не по причине разблокировки и прошивки этого телефона, а еще в процессе решения, еще ничего не приобрели и думаете что взять \u0026ndash; настоятельно рекомендую ознакомиться с этим.\nВ этом списке указаны бренды телефонов у которых сложно разблокировать загрузчик, невозможно, и рекомендуемые бренды у которых это сделать можно и просто.\nИстория Чтобы прошить, нужно разблокировать загрузчик, история стара как мир.\nЧтобы разблокировать загрузчик, мне понадобилось:\nЭл. почта Номер телефона Xiaomi аккаунт Рабочая сим-карта с рабочим моб. интернетом Слить все эти данные китайцам 7 дней терпения Аккаунт должен быть зарегистрирован минимум 30 дней, чтобы появилась возможность \u0026ldquo;запросить\u0026rdquo; разблокировку загрузчика.\n7 дней нужно ждать после запроса на разблокировку.\nНемного забегая вперед, мне повезло, у меня уже был Xiaomi аккаунт, поэтому в моем случае ждать надо было только 7 дней.\nК аккаунту не было привязано номера телефона, так как на многих этапах просило привязать, пришлось привязывать, но мне не приходил код подтверждения.\nСпустя часа попыток код пришел, я радостный пошел в настройки разработчика разблокировать загрузчик. Но появилась ошибка и меня послали нах*й в приложение Xiaomi Community.\nСкачал, залогинился. К слову, единственный способ залогинится в приложение, только дав разрешение на управление вызовами (звонилкой), это разрешение нужно чтобы приложение подхватило ваш Xiaomi аккаунт, по-другому никак :)\nВ приложение, где-то нужно было нажать на \u0026ldquo;Unlock bootloader\u0026rdquo;, но разумеется такой опции не было. Чтобы она появилась нужно сменить регион на Global в приложение, благо это делается за пару тыков.\nНажал на разблокировку, и\u0026hellip; Меня снова послали нах*й на сайт для скачивания Mi Unlock Tool (официально от Xiaomi, только Windows).\nСкачал эту утилиту, в которой после перезапуска нужно каждый раз входить в аккаунт. Появилось сообщение на англ. яз. но с китайскими корнями:\nСообщение вероятно пыталось уведомить о том что вышла новая версия. Я решил обновить, может быть исправился бы кривой user experience. Китайские корни вероятно означали \u0026ldquo;Да\u0026rdquo;. Я нажал и попал на:\nСмешно? Утилиту я так и не обновил. В этом прекрасном приложении я пытался создать Xiaomi аккаунт (до того как обнаружил что он у меня уже есть) и привязать номер телефона.\nАккаунт создать не получилось, не работала капча. Создал на сайте, после входа в утилиту спросило номер телефона, но кривой интерфейс не дал мне выбрать код страны. Окно растянуть нельзя, там где код страны выбирать не скролится, поиск не кликался, чтобы в поиске страну ввести.\nКакой-то список с pointer-events: none; подумал я и решил привяжу на сайте, но не приходил код, думал такая проблема только на сайте (нет).\nПришлось входить в аккаунт и привязывать номер телефона на мобиле, тогда то я и обнаружил что аккаунт у меня уже был, и нужно было только номер привязать, об этом было выше.\nВошел в аккаунт в Mi Unlock Tool через qr code (справа сверху), разрешил разблокировку загрузчика, вернулся в Xiaomi Community и меня послали нах*й показали ошибку, так как квота кончилась.\nВот беда, есть квота\u0026hellip; Квота на запросы разблокировки загрузчика, ах*еть прекрасное решение.\nНа форумах почитал, что это почти нереально, люди пробовали в 00:00 по пекинскому времени отправлять запрос и все равно получали сообщения о квоте.\nКвота на запрос на разблокировку не только для меня, она для всех. Что-то по типу X человек в день по пекинскому времени, а человек много, да и X это сколько никто не знал. Но кто-то предположил что X = 1, 1 человек в день, похоже на правду.\nВидел шутку, что все это скам, чтобы слить кучу данных китайцам, а потом сидеть с вечной ошибкой и угрюмой физиономией.\nПришлось \u0026ldquo;абузить\u0026rdquo;, так как у меня HyperOS, а не MIUI, отлично сработал HyperSploit (xda). Запрос был как-будто бы отправлен, осталось ждать.\n7 дней спустя\u0026hellip;\nПосле нажатия на кнопку \u0026ldquo;Reboot\u0026rdquo;, мобила очень долго стартовала сначала на POCO logo, потом на HyperOS logo, поэтому не бойтесь, вероятно так и должно быть.\nКазалось как бы все, можно шить на кастомный ROM, но я решил не рисковать и сначала прошить стоковый рекомендуемый ROM, как это и было указано в листе с прошивками.\nПрошить на MIUI было просто, я использовал 2й метод с использованием MiFlash, после прошивки загрузчик заблокировался. Но это не проблема, это MIUI и я разблокировал его буквально за 5 секунд.\nНу, а остальное за малым, установить recovery (если нужно) и прошивку - готово.\nУстановить TWRP тоже было просто. Осталось прошить.\nЯ хотел использовать OTG флешку, но она оказалась micro-usb, я пробовал переходник usb - type-c, с новой и старой флешкой (2.0 \u0026amp; 3.0), не сработало.\nПришлось расчехлять SD карту, переходник для SD карты и кард ридер. Оно так потому что я захотел перекинуть ROM на SD карту с ПК через USB. У вас два пути, сделать как я или вставить SD карту туда куда ее можно вставить.\nСделал wipe, прошил, все абсолютно без проблем.\nК сожалению вы наверняка в любом случае увидите не красивое POCO/Mi Logo, но после небольшого ожидания вас встретит красивое лого вашей кастомной прошивки.\nКраткий гайд 📝 Этот гайд краток, потому что рассчитан на людей которые знают что делают + вся информация есть по ссылкам и в архиве (зачем ее дублировать?), здесь не будет мелких деталей и подробностей. Что нужно / Что понадобится USB Android driver Platform tools (ADB \u0026amp; Fastboot) Можно добавить в переменные среды или использовать на месте. Разблокированный загрузчик SD карта/Настоящая OTG флешка Переходники вероятно не сработают. ROM Recovery Советую TWRP. Прошивка MIUI с возможностью прошивки См. требования у нужной вам прошивки. Возможно понадобится:\nАккаунт Xiaomi Эл. почта на доверенном домене (например gmail) Номер телефона Рабочая сим-карта с рабочим моб. интернетом MiFlash Mi Unlock Tool Нехило, да?\nВсе утилиты, текстовые гайды, включая этот, вы можете скачать здесь.\n📝 Не качайте архив без уважительной причины. Если что-то удалено, ссылка не работает, вы не можете найти это в другом надежном месте, у вас какая-то другая причина или очень хочется, качайте.\nВ остальных случаях, это просто не нужно, все есть по ссылкам.\nРазблокировка загрузчика MIUI Качаем \u0026ldquo;BootloaderUnlock\u0026rdquo; здесь.\nУстановить UsbDk_1.0.22_x64.msi или x86 (это драйвер) Запустить \u0026ldquo;UnlockBootloader.bat\u0026rdquo; Выключить телефон Зажать Громкость+ и - Подключить телефон к ПК. Подождать Когда терминал закроется, значит процесс завершился, и загрузчик должен быть разблокирован.\nДа, это работает без какого-либо ожидания и аккаунтов.\nHyperOS Метод для MIUI, формально работает, ошибок нет, но фактически загрузчик не разблокируется.\nНужен Xiaomi аккаунт зарегистрированный мин. 30дн, с подтвержденным номером телефона и рабочая сим-карта с моб. интернетом.\nЕсли все условия выполнены запускаем утилиту (xda) и следуем инструкции в терминале.\nЕсли это не сработает, скачайте Xiaomi Community, смените регион на Global, запросите разблокировку загрузчика и повторите. Если запросить не получилось, попробуйте через Mi Unlock Tool.\nПосле использования утилиты и следованию инструкции в терминале, \u0026ldquo;запрос будет запрошен\u0026rdquo; в обход квоты.\nКак сообщает автор, после этих действий, лучше пользоваться телефоном как обычно, не вынимать сим-карту, не выходить и не входить в Xiaomi аккаунт и не пытаться прошить чтобы не сбить время.\nКак проверить сколько еще ждать Отсчет в 7 дней работает не в телефоне, а привязан к аккаунту к конкретному телефону. Если вы зайдете в \u0026ldquo;этот\u0026rdquo; Xiaomi аккаунт на другом устройстве (телефон, планшет, мб еще что-то), вероятно отсчет сбросится.\nМожно снова запустить Mi Unlock Tool, зайти в аккаунт (это ничего не сбросит) и нажать \u0026ldquo;Unlock\u0026rdquo;, у вас либо будет ошибка и указано кол-во оставшихся часов, либо если 168 часов прошло, вы разблокируете загрузчик с удалением всех данных без подтверждения, имейте это ввиду.\nПрошивка (TWRP) Прошивка прошивается либо через adb, либо recovery.\nЯ прошивал MIUI используя MiFlash, использовал platform-tools для TWRP, и TWRP для установки самой прошивки. Подробный гайд.\nОчень кратко:\nadb reboot bootloader В режиме fastboot (bootloader): fastboot flash boot twrp.img fastboot reboot В TWRP: WIPE =\u0026gt; Format data Install =\u0026gt; прошивка Reboot =\u0026gt; System После прошивки (на ваше усмотрение) можно очистить dalvik, обычно это рекомендуется делать при установки другой прошивки или обновление.\nТак же можно сделать Advanced =\u0026gt; Flash current TWRP, чтобы TWRP остался на телефоне. Это нужно делать каждый раз после wipe =\u0026gt; format data.\n💡 Если вы каждый раз загружаетесь в TWRP, смените \u0026ldquo;Slot\u0026rdquo;. ","permalink":"https://hv8.pages.dev/blog/how-flash-poco-m4-pro-fleur/","summary":"Расскажу как я разблокировал загрузчик HyperOS и MIUI, устанавливал TWRP и прошивал кастомный ROM на POCO M4 Pro a.k.a Fleur.","title":"Как я POCO M4 Pro прошивал"},{"content":" 🔥 В этой статье вы узнаете, как запустить локальную установку для генерации текста на вашем компьютере \u0026ndash; с минимальными техническими знаниями. Введение: О KoboldCPP \u0026amp; SillyTavern, LM Studio KoboldCPP \u0026ndash; это простое в использовании ПО для запуска текстовых моделей в форматах GGML и GGUF, основанное на llama.cpp.\nllama.cpp написан на чистом C/C++ и не имеет внешних зависимостей, что обеспечивает высокую производительность.\nKoboldCPP очень полезный инструмент для запуска локальных LLM если у вас мало видеопамяти, так как KoboldCPP может использовать процессор.\nKoboldCPP будет медленнее других бэкендов которые загружают модели исключительно в VRAM, но зато KoboldCPP позволяет запускать большие LLM на не очень мощных машинах.\nKoboldCPP предоставляет собственный интерфейс (UI), но он не такой гибкий, функциональный и (по мнению автора) удобный как SillyTavern.\nSillyTavern \u0026ndash; это интерфейс (UI) для взаимодействия с текстовыми моделями через API (KoboldAI/CPP, OpenAI, OpenRouter и др.).\nИнтегрируется с генераторами изображений в чате, такими как WebUI от A1111 и ComfyUI, а также поддерживает TTS, может работать либо сам по себе от системы (не AI), либо через API для генерации (AI) голоса.\nSillyTavern обладает сильно настраиваемым интерфейсом, включает крутые функции лорбуков (lorebook и world info), поддерживает автоматический перевод сообщений с помощью сервисов Google, DeepL и других, а также предоставляет множество дополнительных опций и расширений от сообщества пользователей.\nKoboldCPP + SillyTavern универсальное и гибко настраиваемое решение, подходящие для всего в т.ч. сильного RP.\nLM Studio \u0026ndash; очень простой и дружелюбный инструмент, установили, запустили и все работает.\nЕсть поддержка моделей с \u0026ldquo;reasoning\u0026rdquo; из коробки и без настройки.\nLM Studio отлично подходит для теста моделей, технических и простых вопросов, таких как код, ответы на вопросы, написание текста, рерайт и тд. и тп. В качестве бэкенда LM Studio менее гибкий, чем KoboldCPP. И в качестве фронтенда не такой настраиваемый как SillyTavern, но минималистичный и приятный.\n💡 В этой статье описан процесс как для Windows, так и для Linux (Debian/Arch). Установка Git (Bash), NodeJS и Python NodeJS 📝 NodeJS нужен для запуска SillyTavern, если вы не собирайтесь использовать SillyTavern, NodeJS вам не нужен. Windows Для Windows качаем установщик для вашей архитектуры.\nРекомендую использовать LTS версию.\nЗапускаем установщик, жмем «Далее», убираем галочку в конце «Automatically install the necessary tools\u0026hellip;», и устанавливаем.\nLinux Для Linux, можно установить через Volta или другим удобным вам способом.\n📝 В пакетных менеджерах (apt, pacman и др.) версия Node может быть устаревшей. Установка Volta:\n1 curl https://get.volta.sh | bash Установка NodeJS и NPM:\n1 volta install node@x Где \u0026ldquo;x\u0026rdquo; мажорная версия node которую вы хотите установить, можно посмотреть на главной странице NodeJS.\nНапример, Node.js LTS v22.14.0:\n1 volta install node@22 Git 📝 Git нужен для клонирования репозитория SillyTavern и удобного обновления, но репозиторий так же можно скачать вручную. Windows Для Windows нужно скачать git, \u0026ldquo;Standalone\u0026rdquo; - установщик или \u0026ldquo;Portable\u0026rdquo; - портативную версию. Я советую портативную версию, но нужно будет вручную обновить переменные среды, об этом дальше.\nLinux Если вы пользователь Linux, вероятно git у вас уже установлен, проверить можно командой git -v, если нет:\nDebian:\n1 2 apt update apt install git Arch:\n1 2 pacman -Syu pacman -S git Python 📝 Для запуска \u0026ldquo;распакованного\u0026rdquo; KoboldCPP требуется Python.\nЯ рекомендую установить Python и использовать \u0026ldquo;распакованный\u0026rdquo; KoboldCPP \u0026ndash; это улучшит производительность.\nПодробнее об этом будет позже.\n📝 На момент написания этой статьи я использую Python 3.11.9. 💡 Если вы используете последнюю версию Python и что-то не работает, понижайте минорную версию \u0026ndash; x.x.x. Windows Для Windows нужно скачать и установить Python.\nСкачайте «Windows Installer» нужной версии Python для вашей архитектуры из столбца «Stable Releases». Если вам не нужна конкретная версия, просто качайте последнюю.\nВо время установки Python, нажмите «Customize installation» и поставьте галочки на «pip», «tcl/tk» и «Add Python to environment variables»:\nМесто установки на ваше усмотрение.\nLinux Так же как и в случае с git, Python обычно уже установлен в дистрибутив Linux, но возможно старая версии, проверить можно командой:\n1 2 3 4 5 python -V # ИЛИ python2 -V # ИЛИ python3 -V Python 2 \u0026ndash; старая версия. Если Python нету, или версия не та, то:\nDebian:\n1 2 3 apt update apt install python3 apt install python3-pip # Возможно понадобится Arch:\n1 2 3 pacman -Syu pacman -S python pacman -S python-pip # Возможно понадобится Настройка переменных среды После установки Git, NodeJS и Python нужно добавить их в переменные среды (если требуется). Это позволит запускать их без указания полного пути к бинарным файлам. Программы тоже смогут использовать их по простым командам, таким как python, node и git.\nОбычно установщики Python и NodeJS автоматически обновляют переменные среды, если вы не отключали эту опцию. То же самое касается Git, если вы устанавливали его через установщик, а не использовали portable-версию.\nWindows 💡 Если вы установили Python и NodeJS через установщик, как описано в статье, а Git скачали в портативной версии, в переменные среды нужно добавить только Git. Win + R systempropertiesadvanced Environment Variables (Переменные среды) User variables (Переменные среды пользователя) Path New (Создать) Git: path\\to\\git\\bin\\ и path\\to\\git\\cmd\\ NodeJS: path\\to\\nodejs\\ Python: path\\to\\python\\ и path\\to\\python\\Scripts\\ Одна строка - один путь!\nLinux Если вы устанавливали Git и Python через пакетный менеджер (apt, pacman и др.) или они уже были в системе, а NodeJS устанавливали способом с официального сайта (в т.ч через Volta), то все должно быть в порядке.\nНо, если это не так:\nОткрыть .bashrc в редакторе nano:\n1 nano ~/.bashrc В конце файла добавить:\n1 export PATH=$PATH:/path/to Обновить .bashrc:\n1 source ~/.bashrc Обычно пути такие:\nGit: /usr/bin/git NodeJS: /usr/bin/node Python: /usr/bin/python или /usr/bin/python3 Но могут оказаться другими.\nМожно попробовать выполнить команду, чтобы узнать где находится программа:\n1 which \u0026lt;...\u0026gt; Пример .bashrc файла:\n1 2 3 4 5 ... export PATH=$PATH:/usr/bin/git export PATH=$PATH:/usr/bin/node export PATH=$PATH:/usr/bin/python3 Проверка Введите в терминале:\n1 2 3 4 5 6 7 8 9 10 11 $ git -v git version 2.48.1.windows.1 $ node -v v22.14.0 $ npm -v 10.9.2 $ python -V Python 3.11.9 Если вы получаете версию, а не ошибку по типу:\n1 2 \u0026#39;x\u0026#39; is not recognized as an internal or external command, operable program or batch file. 1 -bash: x: command not found Значит все работает.\nУстановка и запуск KoboldCPP + SillyTavern \u0026amp; LM Studio Для начала советую задуматься над директориями, что куда ложить, и сделать что-то типо этого:\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 | - AI \u0026lt;== Корень | | - - Backend \u0026lt;== Бэкенд | - - - LM Studio \u0026lt;== Тут установка LM Studio | - - - KoboldCPP \u0026lt;== Директория с KoboldCPP | - - - - Loose \u0026lt;== Распакованный KoboldCPP | - - - - Settings \u0026lt;== Конфиги KoboldCPP (.kcpps) | - - - - .exe \u0026lt;== Бинарный файл KoboldCPP | | - - UI \u0026lt;== Фронтенд | - - - SillyTavern \u0026lt;== Директория с SillyTavern | | - - Models \u0026lt;== Директория с моделями | - - - Text \u0026lt;== Текстовые модели KoboldCPP Переходим на страницу релизов на GitHub страницы репозитория KoboldCPP.\nКачаем бинарный файл для вашей системы, что качать выбираем исходя из описания релиза, перевод:\nОписания релиза 🚧 Обратите внимание, оригинальный текст может быть изменен в будущих релизах, и перевод может быть не актуален. Если вам не нужно CUDA, вы можете использовать koboldcpp_nocuda.exe, который значительно меньше.\nЕсли у вас есть видеокарта Nvidia, но старый процессор, и koboldcpp.exe не работает, попробуйте koboldcpp_oldcpu.exe.\nЕсли у вас современная видеокарта Nvidia, вы можете использовать версию CUDA 12 - koboldcpp_cu12.exe (она значительно больше, но немного быстрее).\nЕсли вы используете Linux, выберите соответствующий бинарный файл для Linux (не .exe).\nЕсли у вас современный MacOS (M1, M2, M3), вы можете попробовать koboldcpp-mac-arm64, бинарный файл для MacOS.\nЕсли вы используете AMD, мы рекомендуем сначала попробовать вариант с Vulkan (доступен во всех версиях) для лучшей совместимости. В качестве альтернативы вы можете попробовать koboldcpp_rocm в форке YellowRoseCx.\nЗапускаем бинарный файл:\nТут можно смотреть логи KoboldCPP - GUI Запуск не быстрый, так как это упакованные python файлы (код), интерпретатор python и другие файлы в один файл.\nС бинарным файлом можно так же взаимодействовать через терминал, например:\n1 koboldcpp_cu12.exe --help Чтобы распаковать KoboldCPP переходим в «Extra» =\u0026gt; «Unpack KoboldCpp To Folder», выбираем пустую директорию куда распаковать.\nТеперь можно запускать KoboldCPP уже в разы быстрее используя python:\n1 python koboldcpp.py --help Но в таком случае GUI работать не будет, GUI работает только если запускать бинарный файл.\nНо если вы не хотите заморачиваться с терминалом и писать кучу флагов, то есть вариант настройки через GUI.\nСтартуем бинарный файл и настраиваем все через GUI, после сохраняем конфиг (кнопка - «Save»).\nИ в будущем уже используем такую команду:\n1 python koboldcpp.py --config \u0026#34;/path/to/myconfig.kcpps\u0026#34; Чтобы запустить KoboldCPP с созданным ранее конфигом.\nЕсли конфиг необходимо изменить, можно сделать это точно так же через GUI (загрузив его, кнопка - «Load», а потом сохранив после изменений), или просто открыть конфиг через блокнот, например чтобы заменить одну модель на другую или поменять размер контекста.\nSillyTavern Качаем исходный код с GitHub репозитория вручную, либо используем git:\n1 git clone https://github.com/SillyTavern/SillyTavern -b release Эта команда клонирует репозиторий в папку \u0026ldquo;SillyTavern\u0026rdquo; в той же директории, откуда была запущена команда.\nЗапуск на Windows:\nДвойной клик на «Start.bat» или в терминале:\n1 Start.bat Запуск на Linux:\nСделать файл исполняемым:\n1 chmod +x start.sh Запустить:\n1 ./start.sh Базовая настройка Откройте вкладку «API Connections» (сверху):\nAPI: Text Completion API Type: KoboldCpp API URL: API URL KoboldCPP «API URL» - можно посмотреть в терминале после запуска KoboldCPP, но обычно это :5001, если этот порт был свободен.\nКрайне рекомендую включить «Derive context size from backend», чтобы значение «Context (tokens)» автоматически подтягивалось с бэкенда, то есть из параметра KoboldCPP где вы установили размер контекста.\n«Auto-connect to Last Server» - тоже полезная опция, чтобы при запуске SillyTavern, не нужно было вручную нажимать на «Connect», и оно само подключалось к последнему бэкенд серверу.\nSillyTavern - вкладка с настройкой API бэкенда Нажимайте «Connect», если вы видите 🟢 и название модель, значит все работает.\nLM Studio Переходим на сайт LM Studio, выбираем ОС, архитектуру, качаем и устанавливаем.\n📝 «Enable Local LLM Service» рекомендую отключить, если вы не хотите чтобы сервис работал когда LM Studio закрыта. Переходим в настройки:\nLM Studio - Настройки приложения «User Interface Complexity Level» - «Power User» «Show side button labels» - Включить (для понятности) «Model loading guardrails», на ваше усмотрение, лично я использую «Relaxed» «Use LM Studio\u0026rsquo;s Hugging Face Proxy», помогает с доступом к HF через LM Studio, если прямое соединение не работает Остальные настройки на ваше усмотрение Нажимаем на «Discover» в сайдбаре:\nLM Studio - Обзор моделей для скачивания 💡 При поиске моделей не забудьте поставить галочку на «GGUF». Переходим в «Runtime»:\nLM Studio - Обзор Runtime компонентов Обновляем «CPU llama.cpp», и второй пакет CUDA для видеокарт Nvidia. Vulkan или ROCm для видеокарт AMD.\nНа странице «My Models» (в сайдбаре), можно посмотреть и настроить параметры по умолчанию для каждой модели:\nLM Studio - Управление скачанными моделями Если вы скачиваете модели вручную, а не через LM Studio, они должны быть расположены так:\n1 2 3 4 | - Text \u0026lt;== «Models Directory» в LM Studio | - - dir1 \u0026lt;== Какая-то директория (автор) | - - - dir2 \u0026lt;== Какая-то директория (название модели) | - - - - .gguf \u0026lt;== Модель dir1 и dir2, не обязательно должный быть названы в честь автора и модели, главное чтобы просто была такая иерархия, иначе LM Studio их не увидит.\nМодели загружаются и выгружаются сверху:\nLM Studio - GUI Советы KoboldCPP \u0026amp; SillyTavern KoboldCPP 📝 Советы даны для KoboldCPP \u0026amp; llama.cpp, в другом ПО работа технологий может отличаться. CuBLAS обычно работает быстрее чем CLBlast для видеокарт Nvidia.\nДля видеокарт AMD следует использовать Vulkan, а еще лучше ROCm.\nВозможно использование «MMQ», «MMAP», «MLOCK», «ContextShift», «FastForwarding» и «FlashAttention», поможет ускорить скорость генерации, выясняется путем экспериментов.\nПояснение: MMQ, MMAP, MLOCK, ContextShift, FastForwarding, FlashAttention MMQ (Quantized Matrix Multiplication)\nMMQ режим, при котором для prompt processing вместо стандартных операций cuBLAS используются квантованные матричные умножения. Это позволяет экономить VRAM и может давать прирост производительности для некоторых квантованных форматов (например, Q4_0), хотя для других форматов эффект может быть менее заметен.\nПредставьте, что у вас есть два способа выполнения матричных вычислений при генерации нового токена в языковой модели. Один способ использует стандартный алгоритм cuBLAS, который уже поддерживает низкую точность, а другой \u0026ndash; режим MMQ, оптимизированный для квантованных данных. При включении MMQ система выбирает именно оптимизированный алгоритм для prompt processing, что позволяет быстрее обрабатывать запросы и снижать потребление видеопамяти, если модель заквантована до нужного уровня. Это не означает, что cuBLAS перестает использоваться \u0026ndash; режим MMQ работает в составе инфраструктуры cuBLAS, изменяя лишь способ обработки данных для определенных квантованных форматов.\nMMAP (Memory Mapping)\nMMAP \u0026ndash; это способ работы с весами и слоями модели, когда они загружаются в оперативную память, но не полностью. Система подгружает нужные части по требованию.\nПри запуске LLM, MMAP позволяет \u0026ldquo;подключить\u0026rdquo; модель к оперативной памяти так, как будто она уже загружена, но реально считывать только те блоки, которые требуются для текущего запроса.\nMLOCK (Memory Lock)\nОпция MLOCK заставляет операционную систему \u0026ldquo;закреплять\u0026rdquo; загруженные данные модели в оперативной памяти, не позволяя им выгружаться на диск (swap). Это предотвращает задержки, связанные с обращением к медленной виртуальной памяти.\nПри использовании LLM важно, чтобы ключевые веса модели оставались в быстрой памяти (VRAM или RAM). MLOCK фиксирует данные в RAM, если часть модели загружена туда, предотвращая свопинг и снижая задержки.\nСвопинг (Swapping) \u0026ndash; перемещение процессов или их частей из RAM на диск (в файл подкачки).\nContextShift\nContextShift \u0026ndash; позволяет эффективно работать с большим контекстом. Вместо того чтобы пересчитывать всю информацию (весь контекст), система \u0026ldquo;сдвигает\u0026rdquo; KV-кэш, старые данные удаляются, а новые переносятся в начало нового окна.\nНапример, если чат-бот участвует в длительном диалоге, при генерации нового ответа модель не начинает обработку с нуля всего контекста. Вместо того чтобы пересчитывать весь контекст, модель сохраняет промежуточные вычисленные представления (скрытые состояния) уже обработанных сообщений. При генерации нового ответа используются эти сохраненные данные, чтобы быстрее использовать новую информацию из последних сообщений. Это похоже на инкрементную генерацию в трансформерах, когда модель продолжает вычисления, опираясь на уже обработанную часть текста.\nТакой подход значительно ускоряет обработку, так как модель фокусируется только на новой информации.\nFastForwarding (KV-caching)\nFastForwarding позволяет модели пропускать повторную обработку токенов, для которых уже были вычислены скрытые состояния (KV-кэш), и выполнять генерацию новых токенов только для изменений в последовательности. Эта функция особенно полезна, когда используется «ContextShift».\nПредставьте процесс инкрементной генерации в трансформерах: при генерации нового токена модель не пересчитывает полностью все предыдущие токены, а использует сохраненный KV-кэш для уже обработанных частей. FastForwarding в KoboldCPP действует аналогично – если модель продолжает генерировать текст в длинном диалоге или документе, она «перематывает» уже вычисленные участки и обновляет только последние, неизменные части последовательности, что значительно ускоряет обработку.\nПример, есть история из 1000 токенов, FastForwarding создает KV-кэш этих 1000 токенов за один проход, и при следующей генерации используется кэш, а не пересчитывается все с нуля.\nFlashAttention\nFlashAttention \u0026ndash; использует более эффективное распределение данных и работу с кэш-памятью GPU, что позволяет ускорить вычисления и снизить потребление VRAM.\nВ трансформерных моделях вычисление внимания обычно требует квадратичного количества операций при увеличении длины последовательности. FlashAttention оптимизирует этот процесс, позволяя быстрее обрабатывать большие последовательности, что особенно важно при работе с высоконагруженными серверными приложениями ИИ.\nДля контекста тоже требуется VRAM и не мало, не следует загружать всю VRAM только слоями если вы используйте большой контекст 8-12К+.\nСтарайтесь поместить как можно больше слоев в VRAM, но при этом оставить место для контекста. Если в VRAM не влезает всего 1 слой, лучше оставить не загруженным больше 1 слоя, 2-3 слоя.\nЕсли VRAM не хватает для загрузки большинства слоев, используйте другие кванты. Не влезает Q6, используйте Q5. Не влезает Q5, используйте Q4.\nЭто ухудшит качество генерации, но это будет работать. Если критически важна точность и качество, возможно не следует запускать локально если не хватает железа.\nВ крайнем случае если у вас много RAM, можно сильно пожертвовать скоростью, загрузив в RAM большее кол-во слоев чем в VRAM.\nПроверьте скорость генерации с «BLAS Batch Size» \u0026ndash; 512, после поменяйте на 2048 и снова проверьте. Если 2048 медленнее 512, возможно подойдет 1024.\nВ идеале чем больше «BLAS Batch Size» тем лучше, но большое значение «BLAS Batch Size» может замедлить скорость генерации.\nЧто касается «Threads», значение \u0026ldquo;-1\u0026rdquo; означает \u0026ldquo;авто\u0026rdquo;.\nЕсли вы вручную не установите какое-то значение для каждого параметра «Threads», оно будет использоваться из главного параметра «Threads».\nПример: у вас 6 ядер, 12 потока, если вы укажете для «Threads» все 12 потока, а у «BLAS threads» значения не будет, то «BLAS threads» тоже будет использовать 12 потока. В итоге 24 потока, но у вас всего 12, а так же ОС тоже нужны ресурсы.\nОбычно KoboldCPP сам устанавливает оптимальное кол-во потоков, но стоит проверить, какие значения выставлены автоматически и убедиться что все окей. Посмотреть это можно рядом с параметром «Threads» (после \u0026ldquo;запуска\u0026rdquo; модели) через GUI или после запуска в логах в терминале.\nЕсли система работает медленно или нестабильно, попробуйте уменьшить количество потоков вручную.\nСледите чтобы KoboldCPP не использовал потоков больше чем у вас есть, и чтобы у системы оставались ресурсы (2-4+ потока).\nЧтобы поменять модель, нужно перезапустить KoboldCPP.\nSillyTavern На YouTube я так и не смог найти гайд по всем настройкам SillyTavern где все бы объяснялось и все такое.\nПоэтому, если вы решите остаться, вам придется экспериментировать и гуглить\u0026hellip; А если вы совсем новичок, то придется очень много гуглить.\nВот два ваших новых лучших друга - SillyTavern Documentation \u0026amp; r/SillyTavernAI, где вы возможно найдете нужную вам информацию.\nМодели не создаются в GGUF формате, GGUF это формат для хранения квантов модели. Поэтому там где вы качаете GGUF модель (зачастую это HF) должна быть указана ссылка на \u0026ldquo;оригинал\u0026rdquo; или предоставлены соответствующие инструкции.\nНа странице оригинала обычно можно найти не только описание модели, а еще настройки, в некоторых случаях даже пресеты для ST1.\nНапример модель которую я использую на момент написания этой статьи «NemoMix Unleashed 12B» (GGUF).\nТам все описано, даны настройки и пресеты ST.\nНа самом деле правильные настройки не обязательны. Но правильные настройки «Context Template» (очень важно), «Instruct Template» (если есть), «System Prompt» (не так важно) и настройки семплеров для тонкой настройки вывода, могут ОЧЕНЬ сильно повысить качество генерации.\nЗаключение KoboldCPP в сочетании с SillyTavern \u0026ndash; это мощный инструмент для энтузиастов, которым важна гибкость, кастомизация и возможность детальной настройки. Это идеальный выбор для экспериментов и RP. Однако из-за большого количества параметров и тонких настроек это может потребовать времени.\nLM Studio, напротив, предлагает простоту и удобство. Это отличный вариант для тех, кто хочет сразу приступить к использованию локальных моделей с минимальными настройками. Если ваша цель \u0026ndash; генерирование текста, кода или ответов на вопросы без необходимости тонкой настройки, то LM Studio станет оптимальным выбором.\nЧитайте также:\nЛокальная AI генерация изображений. Stability Matrix Простой способ запустить локальную установку AI для генерации изображений. 𝙓 ST - сокращение SillyTavern.\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n","permalink":"https://hv8.pages.dev/blog/local-ai-text-generation-koboldcpp-sillytavern-lm-studio/","summary":"Как запустить установку AI для генерации текста у себя на ПК.","title":"Локальная AI генерация текста. KoboldCPP \u0026 SillyTavern. LM Studio"},{"content":"У вас не запускается Tails с флешки или например внешнего SSD диска, вы получаете что-то вроде:\n1 (initramfs) Unable to find a medium containing a live file system Это из-за того, что вы используете диск, или \u0026ldquo;неправильную\u0026rdquo; флешку, которая \u0026ldquo;является\u0026rdquo; диском.\nTails требует, чтобы запуск был именно со съемного накопителя.\nНекоторые USB-накопители (флешки) распознаются не как съемные накопители, а как фиксированные диски. А диски, соответственно это диски, а не съемные накопители, даже если они подключаются через USB.\nЛучше не пытаться изменить такое поведение накопителя, так как это связано с особенностями производства.\nЧаще всего такая проблема возникает с флешками SanDisk и с любыми дисками, в т.ч. «внешними».\nРешение На экране выбора загрузки нажмите TAB, откроются параметры загрузки, удалите:\n1 live-media=removable Нажмите ENTER, чтобы загрузиться.\nДелать это нужно при каждом запуске Tails.\n","permalink":"https://hv8.pages.dev/blog/ne-zapuskayetsya-tails-s-fleshki-diska/","summary":"Что делать если не запускается Tails с USB-флешки или диска.","title":"Не запускается Tails с флешки или диска"},{"content":"Вы начали использовать Obsidian на Android, синхронизировали хранилище и вдруг поняли, что куча изображений из Obsidian разбросаны по всей галереи. Не круто.\nВсе просто, нужно создать файл .nomedia в корне вашего хранилища Obsidian.\n📝 Файл .nomedia используется для указания операционной системе Android не выполнять поиск мультимедийных файлов в директориях, где он находится. 1 2 3 4 5 - .obsidian - .space - .trash - ... - .nomedia \u0026lt;== файл Total Commander Файл .nomedia можно создать как через USB, так и прямо на телефоне с помощью текстового редактора, например, «Editor» (F-Droid / GitHub).\nСкорее всего, вы не увидите файл .nomedia в \u0026ldquo;классическом проводнике\u0026rdquo;, потому что такие файлы скрытые (dotfiles).\nНо после создания файла .nomedia в корне хранилища Obsidian, все изображения должны исчезнуть из галереи.\n💡 То же самое произойдет в тех приложениях, которые умеют обрабатывать файл .nomedia. Если вдруг это не сработает, есть еще один вариант - создать файл .nomedia в каждой директории, где хранятся изображения. Но если у вас много таких директорий, то возможно оно того не стоит.\n","permalink":"https://hv8.pages.dev/blog/skryt-izobrazheniya-mediafayly-obsidian-galerei-android/","summary":"Как убрать изображения Obsidian из галереи на Android.","title":"Как скрыть изображения Obsidian из галереи Android"},{"content":" 🚀 В этой статье вы узнаете, как легко запустить локальную установку для генерации изображений на вашем компьютере \u0026ndash; без каких-либо технических знаний. ✨ Введение: О Stability Matrix Мы будем использовать Stability Matrix. Это многоплатформенный менеджер пакетов для Stable Diffusion, который работает на Windows, Linux и macOS. Кроме того, Stability Matrix поддерживает установку различных панелей для управления генерацией изображений, включая те, которые работают с Flux моделями.\nStability Matrix делает все за вас, и вам не нужно устанавливать множество зависимостей отдельно и вручную. Это удобно, потому что все необходимые зависимости будут в одном месте и не повлияют на вашу операционную систему.\nНапример, если у вас уже установлен Python определенной версии, Stability Matrix все равно установит нужную версию и будет использовать только ее, не меняя вашу. Если Python у вас нет, после установки панели через Stability Matrix он также не появится в системе - версия, которую установит Stability Matrix, будет использоваться только через Stability Matrix.\n🖼️ Пикчи Изображения сгенерированы моделью flux1-dev-bnb-nf4-v2.\n⚙️ Установка Stability Matrix Переходим на страницу GitHub репозитория Stability Matrix, качаем либо со страницы релизов:\nЛибо ниже с кнопок в README:\nStability Matrix можно установить или запустить без установки (portable). Я рекомендую второй вариант. Для этого нужно создать папку для Stability Matrix и запустить исполняемый файл из этой папки.\nРазумеется, соглашаемся с лицензионным соглашением, даже не читая его:\nУстановка Stability Matrix Далее выбираем путь куда установить или используем Portable Mode:\nО Portable Mode В Portable Mode все данные и настройки будут храниться в той же директории, что и приложение. Вы сможете перенести приложение с папкой \u0026ldquo;Data\u0026rdquo; в другое место или на другой компьютер.\nВ конце установки Stability Matrix предложит сразу же установить какую-нибудь панель.\nЕсли вы не знаете что вам нужно, нажимайте Skip first-time setup:\n🚀 Установка и запуск первой панели Панели устанавливаются на вкладке Packages:\nНажимаем на Add Package:\nЗдесь перечислен список панелей для скачивания и установки. У каждой панели указано с чем она может работать: CPU, NVIDIA, DirectML, AMD (Linux), macOS и др.\nЕсли это ваш первый раз, рекомендую «Stable Diffusion WebUI» от AUTOMATIC1111 или «Stable Diffusion WebUI Forge» от lllyasviel.\nВ плане интерфейса «Stable Diffusion WebUI» и «Stable Diffusion WebUI Forge» очень похожи.\nНо Forge версия, имеет больше фич и может работать не только с SD (Stable Diffusion) моделями, а еще и с Flux.\nЗапуск Flux моделей локально You do not have CLIP state dict! 𝙓 Когда выбрали нужную панель, нажимаете Install:\nDownload MP4 Your browser does not support video. Установка может занять приличное кол-во времени, в зависимости от панели.\nПосле установки, нажимаем 🚀 Launch, запуск панели тоже может занять некоторое время.\nЕсли все запустилось и критических ошибок нет, то в выводе вы увидите что-то вроде этого:\n1 local URL: http://127.0.0.1:7860 Если этот URL не открылся в браузере автоматически, перейдите по URL или скопируйте вручную.\nWebUI by AUTOMATIC1111 Узнать как пользоваться WebUI от AUTOMATIC1111 можно в статье про Stable Diffusion.\nИли в видео на YouTube:\n💡 WebUI и WebUI Forge похожи. Поэтому узнав одно вы узнаете другое.\nЗа исключением некоторых фич, которые есть только в Forge.\nLow VRAM Warning 1 2 3 4 5 6 [Low VRAM Warning] You just set Forge to use 100% GPU memory (**** MB) to load model weights. [Low VRAM Warning] This means you will have 0% GPU memory (0.00 MB) to do matrix computation. Computations may fallback to CPU or go Out of Memory. [Low VRAM Warning] In many cases, image generation will be 10x slower. [Low VRAM Warning] To solve the problem, you can set the \u0026#39;GPU Weights\u0026#39; (on the top of page) to a lower value. [Low VRAM Warning] If you cannot find \u0026#39;GPU Weights\u0026#39;, you can click the \u0026#39;all\u0026#39; option in the \u0026#39;UI\u0026#39; area on the left-top corner of the webpage. [Low VRAM Warning] Make sure that you know what you are testing. В некоторых случаях вы можете получать предупреждение Low VRAM Warning.\nЭто предупреждение сообщает о том, что вы выделили слишком много видеопамяти для панели, и скорость генерации может ухудшаться с каждым разом.\nРешение: уменьшите выделенную память на 500-1500 МБ. Например, если у вас 12 ГБ VRAM, выделите панели 11 ГБ VRAM.\nКак это сделать зависит от панели, но вот как это делается в WebUI Forge:\n🔍 Обзор Stability Matrix Как устанавливать модели Модели, LoRA, энкодеры, VAE и все остальное для всех панелей, находятся в /Data/Models, основное:\n/StableDiffusion/ - модели (любые, не только SD) /Lora/ - LoRA /CLIP/ - экнодеры /VAE/ - VAE. Packages Вкладка Packages, как вы, наверное, уже поняли, существует исключительно для управления пакетами (панелями). Установка, обновление, удаление, запуск и пр.\nПодвкладка Inference (в Add Package) предназначена для установки панелей, в первую очередь для обычного запуска моделей.\nПодвкладка Training (в Add Package) нужна для установки панелей, ориентированных на обучение моделей.\nInference Inference - обновленный интерфейс для Stable Diffusion, встроенный в Stability Matrix.\nИз репозитория Stability Matrix Из репозитория Stability Matrix:\nМощное автозаполнение и подсветка синтаксиса с использованием формальной грамматики языка Рабочие области открываются во вкладках, которые сохраняются и загружаются из файлов проекта .smproj Настраиваемые прикрепляемые и плавающие панели Генерируемые изображения содержат метаданные Inference Project, ComfyUI Nodes и A1111-совместимые метаданные Перетаскивание изображений галереи или файлов для загрузки состояний Возможно кому-то будет полезно, но лично я предпочитаю использовать стоковый интерфейс установленной панели.\nCheckpoint Manager Если Packages это менеджер пакетами, то Checkpoint Manager это менеджер всех ваших установленных моделей, лора, экнодеров и тд.\nModel Browser В Model Browser вы можете просматривать модели и сразу же скачивать их с Hugging Face.\nКроме того, вы можете привязать аккаунт Civitai (Settings - Accounts), чтобы просматривать и скачивать модели, Lora и другие ресурсы с сайта Civitai прямо из Stability Matrix.\nOutput Browser В Output Browser вы можете увидеть все сгенерированные изображения.\nWorkflows Workflow готовые процессы и сценарии, для упрощения выполнения некоторых задач.\n📦 Где брать модели Наверное самый лучший сайт где можно брать модели, это Civitai.\nCivitai предлагает не только огромный выбор моделей, но и возможность для авторов публиковать изображения. Пользователи также могут загружать изображения, сгенерированные с помощью этих моделей, что позволяет сразу увидеть, что вы получите.\nТак же вы можете найти модели на Hugging Face.\nИ конечно же вы можете найти модели на просторах интернета.\n🚧 Будьте осторожны с запуском моделей в формате ckpt, особенно из непроверенных источников!\nЗапуск моделей в формате ckpt так же рискован, как запуск исполняемого файла.\nПредпочтительнее использовать формат safetensors.\nПодробнее о safetensors можно почитать здесь.\n","permalink":"https://hv8.pages.dev/blog/local-ai-image-generation-stability-matrix/","summary":"Простой способ запустить локальную установку AI для генерации изображений.","title":"Локальная AI генерация изображений. Stability Matrix"},{"content":"Вероятней всего вы получаете шум или пустоту, вместо красивой картинки, при попытки генерации используя Flux модель на том же Stable Diffusion web UI by AUTOMATIC1111.\nИли ошибку You do not have CLIP state dict! используя Flux модель на другой панели.\nИ видимо именно поэтому вы это читаете.\n🚧 Это заметка о том как запустить Flux модель.\nА не о том как запустить локальную установку для генерации пикч. Локальная AI генерация изображений. Stability Matrix Простой способ запустить локальную установку AI для генерации изображений. 𝙓 Если вы получаете шум или пустоту, значит панель не поддерживает Flux модели.\nНа момент написания этой заметки Flux работает в WebUI Forge и ComfyUI, которые так же имеются в Stability Matrix. И еще, на текущий момент с Flux идеально работают только видеокарты NVIDIA.\n📝 Оптимизированная версия оригинальной модели Flux отсюда, может работать сразу на WebUI Forge.\nТак как все необходимые энкодеры и VAE уже встроены в панель.\nМодели Оригинальные модели можно скачать отсюда или отсюда.\nGGUF версии можно скачать отсюда или отсюда.\nПри запуске Flux моделей (и соответственно других моделей на основе Flux), возникает ошибка:\n1 You do not have CLIP state dict! Она возникает из-за отсутствия text encoder, так же это называют CLIP, хотя это немного разные вещи.\nЧтобы, все таки запустить Flux модель, нужно скачать энкодеры и VAE.\nКачаем энкодеры, clip-l* и t5* здесь.\n📝 Что использовать fp8 или fp16 зависит от вашего железа.\nЕсли у вас мало VRAM 4-8Gb и немного оперативной памяти 8-16Gb, используйте fp8.\nЕсли у вас средне VRAM 11-12Gb, и много оперативной памяти 32Gb+, можно использовать fp16.\nЕсли у вас всего много, особенно VRAM 20Gb+, то смело используйте fp16.\nКачаем VAE, vae/diffusion_pytorch_model.safetensors и ae.safetensors здесь или здесь.\nVAE помещаем в models\\VAE, энкодеры в models\\text_encoder или models\\CLIP (если вы используете Stability Matrix).\nОсталось только загрузить VAE и энкодеры в соответствующем списке.\nЗагружать их можно в любом порядке.\nПодробнее так же можно почитать от разработчика WebUI Forge.\n","permalink":"https://hv8.pages.dev/blog/start-flux-model-local/","summary":"You do not have CLIP state dict!","title":"Запуск Flux моделей локально"},{"content":" 🚧 Git НЕ равно GitHub.\nАвторизация будет описана на примере GitHub.\nДля других платформ получение данных для авторизации может отличаться!\nGit Bash Для начала нужно установить Git. Для Windows нужно скачать Git Bash.\nПроверить установлен ли git можно командой:\n1 git --version Настройка конфигов 📝 Конфиги настраиваются независимо от вашего аккаунта на GitHub. То есть, вы можете настроить это даже не имея аккаунта на GitHub. Для настройки конфигов вводим данные команды:\n1 git config --global user.name \u0026#34;\u0026lt;username\u0026gt;\u0026#34; 1 git config --global user.email \u0026lt;email@example.com\u0026gt; Имя и почту можно ввести любую, но я обычно использую username с GitHub, и для почты \u0026ldquo;GitHub почту\u0026rdquo; - \u0026lt;...\u0026gt;@users.noreply.github.com. Посмотреть ее можно в настройках, на странице Emails.\nОпция --global значит, что имя и почта будут использоваться для всех действий в Git.\nЕсли не использовать --global, то вводимые данные будут применяться только к текущему репозиторию.\nЗачем это? Эти команды используются для настройки глобальных параметров пользователя в Git. Эти параметры определяют, как ваше имя и email будут ассоциироваться с вашими коммитами в репозиториях.\nЗачем это нужно:\nИдентификация автора коммитов: Когда вы делаете коммит в Git, он сохраняет информацию о том, кто его создал. Это помогает другим участникам проекта понять, кто внес изменения и кто может ответить на вопросы, связанные с этими изменениями. Соответствие стандартам: Многие проекты требуют, чтобы коммиты были подписаны корректными данными автора. Это помогает поддерживать прозрачность и ответственность в развитии проекта. Автоматизация и интеграция: Некоторые инструменты и сервисы, такие как GitHub, GitLab и другие, используют информацию о пользователе для автоматической генерации статистики, уведомлений и других функций. Проверить текущие настройки можно используя команду:\n1 git config --global --list Генерация токена В правом верхнем углу страницы нажмите на иконку вашего профиля и выберите \u0026ldquo;Settings\u0026rdquo; (Настройки). В левой панели навигации прокрутите вниз и выберите \u0026ldquo;Developer settings\u0026rdquo;.\nВ разделе \u0026ldquo;Developer settings\u0026rdquo; выберите \u0026ldquo;Personal access tokens\u0026rdquo;. Нажмите на кнопку \u0026ldquo;Generate new token\u0026rdquo; (Создать новый токен) и выберите \u0026ldquo;Generate new token (classic)\u0026rdquo;.\nВведите описание токена (например, \u0026ldquo;Git Bash Windows\u0026rdquo;), выберите срок действия токена (можно выбрать \u0026ldquo;No expiration\u0026rdquo; для токена без истечения срока действия) и установите необходимые разрешения (scopes) для токена (например, repo для полного доступа к репозиториям).\nПрокрутите вниз и нажмите на кнопку \u0026ldquo;Generate token\u0026rdquo;. После создания токена GitHub покажет вам токен. Скопируйте его, так как вы больше не сможете увидеть его в открытом виде.\n📝 В случае чего, там же можно будет перегенерировать токен. Авторизация Вводим команду:\n1 git config --global credential.helper wincred Эта команда настраивает Git для использования Windows Credential Manager, который является встроенным менеджером учетных данных в Windows. Credential Manager обеспечивает более безопасное хранение учетных данных, так как они шифруются и хранятся в защищенном хранилище.\nДалее понадобится какой-нибудь репозиторий. В директории с репозиторием выполняем команду:\n1 git push Это нужно чтобы открылось окно ввода учетных данных. В этом окне нужно ввести ранее полученный токен.\nЕсли все сделано правильно, либо вы запушите новые изменения в репозиторий, либо получите сообщение что все актуально (обновлять нечего).\n","permalink":"https://hv8.pages.dev/blog/avtorizatsiia-git-na-windows/","summary":"Как запушить этот код?","title":"Авторизация Git на Windows"},{"content":"Windows Директория 1 mklink /J \u0026#34;C:\\CustomDir\u0026#34; \u0026#34;D:\\SomeDir\u0026#34; Где \u0026quot;C:\\CustomDir\u0026quot; путь до символической ссылки. Где \u0026quot;D:\\SomeDir\u0026quot; путь где находится существующая директория, к которой делается символическая ссылка.\nЭто точно будет работать на одном диске. Создание символической ссылки МЕЖДУ дисками (как в примере) будет работать только если оба диска в одной файловой системе.\nЕсли диски в разных файловых системах, то в таком случае следует использовать параметр /D вместо /J.\n1 mklink /D \u0026#34;C:\\CustomDir\u0026#34; \u0026#34;D:\\SomeDir\u0026#34; Файл Все так же как и для директории, но без параметров:\n1 mklink \u0026#34;C:\\CustomDir\\myfile.txt\u0026#34; \u0026#34;D:\\SomeDir\\somefile.txt\u0026#34; Linux Тут все просто, для файлов и директорий:\n1 ln -s /opt/foo /opt/bar Где /opt/foo целевая директория, то есть директория которая существует. Где /opt/bar, символическая ссылка с именем bar.\nТо есть если перейти в /opt/bar вы фактически окажетесь в /opt/foo.\n","permalink":"https://hv8.pages.dev/blog/symlink-windows-linux/","summary":"О том как сделать символическую ссылку в Windows и Linux","title":"Symlink - Windows и Linux"},{"content":"Подготовка накопителя Для начала нужно подготовить флешку/диск, если ваш накопитель имеет несколько разделов, и это так не потому что вы так захотели, то их нужно удалить. Что-то по типу этого:\nЕсли же вы хотите сделать несколько разделов, на одном из которых будет 2k10 Live, то его нужно делать первым:\nМой внешний SSD диск, с 2k10 Live на разделе \u0026ldquo;zboot\u0026rdquo;, в NTFS Я буду использовать флешку. Но вы можете использовать как внешний SDD, так и внешний HDD.\nВ идеале отформатировать флешку в FAT32, но вы не сможете этого сделать (законным путем на Windows) если у вас флешка объемом более 32гб. Так же из-за ограничений FAT32, вы не сможете копировать на флешку файлы больше 4гб. А копировать файлы весом больше 4гб нужно, если вы планируете устанавливать большие дистрибутивы ОС с флешки.\nФорматировать флешку в FAT32 нужно из-за огромной совместимости со старым железом. Но это можно упустить и отформатировать в NTFS. Можно было бы отформатировать в exFAT, это тот же FAT32, но без ограничений. Но с exFAT большинство старого железа не совместима, в отличии от NTFS.\nЗапись 2k10 Live на флешку И так, я буду показывать на 2k10 Live 7.37 Unofficial. У меня есть флешка на 16гб отформатированная в NTFS которую я отформатирую в FAT32.\n🚧 Так же, касается только флешек. В конце \u0026ldquo;пути\u0026rdquo; вы можете столкнуться с проблемой, 2k10 Live не будет загружаться, так как система не сможет найти с чего загружаться.\nПоэтому лучше все же использовать FAT32 и отформатировать флешку используя RMPrepUSB.\nЭто можно пропустить если у вас SSD/HDD в NTFS.\nRMPrepUSB Распаковываем образ 2k10 Live с помощью 7z. И запускаем утилиту RMPrepUSB из \\2k10\\Programs-2k10\\Flash-Utilites\\RMPrepUSB\\.\nПроверяем чтобы флешка была выбрана верно, загрузочный сектор и файловая система была как на скриншоте выше.\nНажимаем Подготовить диск.\nЕсли вы получаете ошибку \u0026ldquo;Отказано в доступе\u0026rdquo;, сначала вручную отформатируйте флешку через проводник.\nДожидаемся окончания, закрываем программу, извлекаем флешку и подключаем снова.\nЗапускаем утилиту UTmake, которая идет в комплекте с 2k10 Live. Если по какой-то причине UTMake не была скачена с ISO образом, запускаем ее из распакованного образа - \\2k10\\Programs-2k10\\Flash-Utilites\\UTmake\\.\nЭто старый скриншот с файловой системой NTFS, я делаю на FAT32 Выбираете другой накопитель, если программа выбрала его не правильно.\nЕсли вы используете не флешку, а SSD/HDD диск, выбирайте USB-Hdd.\nДалее нажимаем Copy, чтобы скопировать содержимое ISO образа на флешку.\n💡 Если кнопка Copy недоступна - переключите UFD/USB-Hdd туда и обратно. После завершения копирования, выбираем загрузчик в секции Select loader и нажимаем на Setup, если кнопки доступны. Я советую поставить Syslinux или оставить по умолчанию - Bootmgr.\nЕсли кнопки недоступны, то просто пропускаем это и идем дальше. Но если, все же это так, то вероятней всего ничего работать не будет и стоит отформатировать флешку с помощью RMPrepUSB.\nВы можете нажать на Test Disk, чтобы посмотреть работает или нет. Если вы не устанавливали загрузчик то вы особо ничего не увидите, а если устанавливали, то что-то произойдет:\nВ моем случае работал только режим UEFI, то есть EFIx64 и EFIx32. Режим Legacy не работал.\nUTMake можно закрыть.\nУстановка загрузчика Загрузчик можно не устанавливать, если у вас уже все работает, но лучше в любом случае это сделать, независимо от предыдущего шага.\nДалее ВАЖНО! Не перепутайте, вы должны в корне вашего накопителя открыть SetLDR-2k10 из \\2k10\\. То есть это нужно делать НА накопители, а не из папки откуда вы изначально запускали UTMake и где лежит образ!\nСкриншот старый, я делаю на FAT32 Выбираем загрузчик который вам больше нравится, но я опять таки советую Syslinux, с ним будет большая совместимость со старым железом. Нажимаем Setup. Если Syslinux недоступен, то ставьте Grub4Dos.\nМожно снова запустить UTMake и нажать на \u0026ldquo;Test Disk\u0026rdquo;, чтобы проверить как работает. После того как я установил загрузчик Grub4Dos, у меня заработал Legacy режим.\nЕсли вы хотите быть точно уверены, что все работает, перезагрузитесь с этой флешки, или одолжите ПК у друга.\n📝 Так же, если вы все делали в файловой системе NTFS, то вероятней всего загрузка UEFI работать не будет. Но это не столь критично, так как обычно новые материнские платы поддерживают Legacy, но иногда это нужно включить в настройках. Дополнения Содержимое архивов 2k10 Addons.zip и 2k10 PMAGIC.zip нужно распаковать в корень флешки.\nСвои дистрибутивы систем Дистрибутивы Linux должны находиться в \\2k10\\User.Image\\*, а Windows в \\2k10\\User.WindS\\*.\n","permalink":"https://hv8.pages.dev/blog/kak-sdelat-multibut-2k10-live/","summary":"Инструкция как сделать мультизагрузочную флешку/диск c 2k10 Live.","title":"Мультибут 2k10 Live. Windows"},{"content":" 🚧 Настоящий материал подготовлен исключительно в образовательных и исследовательских целях. Он не содержит призывов к каким-либо действиям, нарушающим законодательство. Автор(ы) не несут ответственности за последствия использования изложенной информации. Использование/применение представленных сведений осуществляется на ваш страх и риск. Информация предоставляется исключительно для законного изучения и анализа. Любое использование описанных методов для несанкционированного доступа к данным или системам является незаконным и строго запрещено. Любое использование материала в незаконных целях нарушает закон и не одобряется авторами. Для начала, разберемся как работает распаковка через терминал и что мы будем использовать при написании скрипта.\n1 \u0026#34;path\\to\\7-Zip\\7z.exe\u0026#34; x -pPASSWORD \u0026#34;path\\to\\someWinRARArchive.rar\u0026#34; -o\u0026#34;path\\to\\output\u0026#34; -y path\\to\\7-Zip\\7z.exe - это путь до 7z.exe x - распаковать архив -p - использовать пароль при распаковки path\\to\\someWinRARArchive.rar - путь до WinRAR архива -o - указать куда будет распакован архив path\\to\\output - путь куда будет распакован архив -y - Yes/Да подтвердить замену файлов, если они уже существуют. 📝 Указывать параметры после флагов -p и -o нужно без пробелов. Итак, у нас есть архив с паролем: qwerty.\nЕсли мы введем данную команду в терминал с неправильным паролем:\n1 \u0026#34;path\\to\\7-Zip\\7z.exe\u0026#34; x -p123 \u0026#34;path\\to\\someWinRARArchive.rar\u0026#34; -o\u0026#34;path\\to\\output\u0026#34; -y То мы получим ошибку:\n1 2 3 4 5 6 Can not open encrypted archive. Wrong password? Can\u0026#39;t open as archive: 1 Files: 0 Size: 0 Compressed: 0 После выполнения этой команды, мы можем использовать:\n1 2 echo %errorlevel% 2 И в ответ мы получим 2. Это означает что команда была выполнена с ошибкой. Если мы снова введем команду, но уже с верным паролем, а потом проверим errorlevel, то мы получим 0.\n1 2 3 4 5 6 7 8 9 10 11 \u0026#34;path\\to\\7-Zip\\7z.exe\u0026#34; x -pqwerty \u0026#34;path\\to\\someWinRARArchive.rar\u0026#34; -o\u0026#34;path\\to\\output\u0026#34; -y Everything is Ok Folders: 1 Files: 1 Size: 12 Compressed: 334 echo %errorlevel% 0 Из этого следует, что мы можем использовать errorlevel в скрипте, для проверки был ли пароль верен, или же нет, и подбирать пароль дальше, пока errorlevel не будет равен 0.\nСоздаем файл с расширением .bat или .cmd. Начинаем скрипт с:\n1 @echo off Чтобы скрыть лишний вывод.\nПросим пользователя ввести путь до каталога с 7z:\n1 echo - Path to 7z dir: Записываем это в переменную z7dir:\n1 set /p z7dir=\u0026#34;#: \u0026#34; Проверяем существует ли каталог 7z, если нет, то выводим ошибку:\n1 2 3 4 5 6 7 8 if not exist \u0026#34;%z7dir%\u0026#34; ( echo. echo ERROR! echo 7z dir - \u0026#34;%z7dir%\u0026#34; echo Not be found... pause exit ) Аналогично делаем с архивом:\n1 2 3 4 5 6 7 8 9 10 11 echo - Path to archive: set /p archive=\u0026#34;#: \u0026#34; if not exist \u0026#34;%archive%\u0026#34; ( echo. echo ERROR! echo Archive \u0026#34;%archive%\u0026#34; echo Not be found... pause exit ) Спрашиваем пользователя куда распаковать архив:\n1 2 echo - Path to output: set /p output=\u0026#34;#: \u0026#34; И тоже самое со словарем, где находятся пароли:\n1 2 3 4 5 6 7 8 9 10 11 echo - Path to wordlist.txt: set /p wordlist=\u0026#34;#: \u0026#34; if not exist \u0026#34;%wordlist%\u0026#34; ( echo. echo ERROR! echo Wordlist - \u0026#34;%wordlist%\u0026#34; echo Not be found... pause exit ) Далее пишем цикл, который будет построчно записывать данные из wordlist.txt в переменную, каждую итерацию:\n1 2 3 4 5 6 7 8 for /f \u0026#34;tokens=*\u0026#34; %%a in (\u0026#39;type \u0026#34;%wordlist%\u0026#34;\u0026#39;) do ( set pwd=%%a call :try ) echo. echo Oh-uh... Password not be found... pause exit Шаманим с \u0026quot;tokens=*\u0026quot; и 'type \u0026quot;%wordlist%\u0026quot;' для того, чтобы юзер мог использовать пути с пробелами.\nИ вызываем блок кода (подпрограмму) call: :try, который идет далее:\n1 2 3 4 5 6 7 8 9 10 11 :try \u0026#34;%z7dir%\\7z.exe\u0026#34; x -p%pwd% \u0026#34;%archive%\u0026#34; -o\u0026#34;%output%\u0026#34; -y \u0026gt;nul 2\u0026gt;\u0026amp;1 echo Try: %pwd% if /I %errorlevel% EQU 0 ( echo. echo Archive was successfully unpacked! echo Password is: %pwd% pause exit ) \u0026quot;%z7dir%\\7z.exe\u0026quot; x -p%pwd% \u0026quot;%archive%\u0026quot; -o\u0026quot;%output%\u0026quot; -y - команда для распаковки архива, но с нашими переменными.\n\u0026gt;nul 2\u0026gt;\u0026amp;1 - «выводит вывод» в никуда, дабы не спамить логами 7z.\necho Try: %pwd% - выводит перебираемые пароли.\nif /I %errorlevel% EQU 0 () - если выпоенная команда распаковки архива, errorlevel = 0, значит команда выполнилась успешно.\nИспользуя call :try мы вызываем подпрограмму (или же просто блок кода), который после выполнения возвращается обратно к тому месту в скрипте, где был сделан вызов, и продолжается выполнение следующих команд. В нашем случае:\n1 2 3 4 echo. echo Oh-uh... Password not be found... pause exit Уведомление о том что пароль не был подобран. Но если условие оказывается верным, мы так же видим следующие уведомление:\n1 2 3 4 5 echo. echo Archive was successfully unpacked! echo Password is: %pwd% pause exit Полный код скрипта 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 @echo off :: 7z echo - Path to 7z dir: set /p z7dir=\u0026#34;#: \u0026#34; if not exist \u0026#34;%z7dir%\u0026#34; ( echo. echo ERROR! echo 7z dir - \u0026#34;%z7dir%\u0026#34; echo Not be found... pause exit ) echo Path to 7z: %z7dir% echo OK! echo. :: WinRAR Archive echo - Path to archive: set /p archive=\u0026#34;#: \u0026#34; if not exist \u0026#34;%archive%\u0026#34; ( echo. echo ERROR! echo Archive \u0026#34;%archive%\u0026#34; echo Not be found... pause exit ) echo Path to archive: %archive% echo OK! echo. :: Output echo - Path to output: set /p output=\u0026#34;#: \u0026#34; echo Path to output: %output% echo. :: Wordlist echo - Path to wordlist.txt: set /p wordlist=\u0026#34;#: \u0026#34; if not exist \u0026#34;%wordlist%\u0026#34; ( echo. echo ERROR! echo Wordlist - \u0026#34;%wordlist%\u0026#34; echo Not be found... pause exit ) echo Wordlist: %wordlist% echo OK! echo. echo Starting bruting... echo. :: Wordlist for for /f \u0026#34;tokens=*\u0026#34; %%a in (\u0026#39;type \u0026#34;%wordlist%\u0026#34;\u0026#39;) do ( set pwd=%%a call :try ) echo. echo Oh-uh... Password not be found... pause exit :try \u0026#34;%z7dir%\\7z.exe\u0026#34; x -p%pwd% \u0026#34;%archive%\u0026#34; -o\u0026#34;%output%\u0026#34; -y \u0026gt;nul 2\u0026gt;\u0026amp;1 echo Try: %pwd% if /I %errorlevel% EQU 0 ( echo. echo Archive was successfully unpacked! echo Password is: %pwd% pause exit ) Улучшения Давайте улучшим наш скрипт, и сделаем так, чтобы он в первую очередь брал значения из условного config.txt. А если файла config.txt нет, или он не полный, то скрипт будет запрашивать значения у юзера.\nДля этого придется самую малость переписать скрипт и создать config.txt:\n1 2 3 4 z7dir=path\\to\\ archive=path\\to\\ output=path\\to\\ wordlist=path\\to\\ Добавляем это в самое начало скрипта:\n1 2 3 4 5 if exist \u0026#34;config.txt\u0026#34; ( for /f \u0026#34;tokens=1,* delims==\u0026#34; %%a in (config.txt) do ( set %%a=%%b ) ) if exist \u0026quot;config.txt\u0026quot; проверяет существует ли файл config.txt, если он не существует, то соответственно код внутри блока не выполняется.\nДалее цикл, который перебирает все строки в файле:\n1 2 3 for /f \u0026#34;tokens=1,* delims==\u0026#34; %%a in (config.txt) do ( set %%a=%%b ) tokens=1,* указывает, что нужно разделить каждую строку на два токена: первый токен до знака = и второй токен - все, что после.\ndelims== устанавливает знак = в качестве разделителя.\nДля каждой строки в файле config.txt, %%a = имя переменной, а %%b = значения переменной.\nset %%a=%%b соответственно присваивает значения переменной %%a = %%b.\nТо есть выглядит это так:\n%%a = %%b z7dir = значение archive = значение output = значение wordlist = значение И как можно догадаться, порядок строк в config.txt не имеет значения.\nТеперь проверяем есть ли у переменной значение:\n1 2 3 4 if not defined z7dir ( echo - Path to 7z dir: set /p z7dir=\u0026#34;#: \u0026#34; ) Если переменная отсутствует в файле config.txt, или если нету самого config.txt, то значение у переменной соответственно нету, и скрипт запрашивает данные у юзера.\nЕсли же все в порядке, то скрипт просто выполняется дальше.\nМы получаем, такой немного измененный код:\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 if not defined z7dir ( echo - Path to 7z dir: set /p z7dir=\u0026#34;#: \u0026#34; ) if not exist \u0026#34;%z7dir%\u0026#34; ( echo. echo ERROR! echo 7z dir - \u0026#34;%z7dir%\u0026#34; echo Not be found... pause exit ) echo Path to 7z: %z7dir% echo OK! И тоже самое нужно сделать и с другими переменными.\nИ просто для галочки, сделаем чтобы юзеру нужно было подтвердить начало брута.\nНо сделаем это сразу правильно, чтобы юзер вводя абракадабру, подтверждение выводилось повторно.\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 :yesornot echo Start bruting? (y/n) set /p yesornot=\u0026#34;#: \u0026#34; if /I \u0026#34;%yesornot%\u0026#34;==\u0026#34;y\u0026#34; ( call :startbruting ) else if /I \u0026#34;%yesornot%\u0026#34;==\u0026#34;n\u0026#34; ( echo OK! pause exit ) else ( echo ERROR! echo. call :yesornot ) А перед кодом, где начинается брут пишем: :startbruting.\nКод 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 @echo off :: config.txt if exist \u0026#34;config.txt\u0026#34; ( for /f \u0026#34;tokens=1,* delims==\u0026#34; %%a in (config.txt) do ( set %%a=%%b ) ) :: 7z if not defined z7dir ( echo - Path to 7z dir: set /p z7dir=\u0026#34;#: \u0026#34; ) if not exist \u0026#34;%z7dir%\u0026#34; ( echo. echo ERROR! echo 7z dir - \u0026#34;%z7dir%\u0026#34; echo Not be found... pause exit ) echo Path to 7z: %z7dir% echo OK! echo. :: WinRAR Archive if not defined archive ( echo - Path to archive: set /p archive=\u0026#34;#: \u0026#34; ) if not exist \u0026#34;%archive%\u0026#34; ( echo. echo ERROR! echo Archive - \u0026#34;%archive%\u0026#34; echo Not be found... pause exit ) echo Path to archive: %archive% echo OK! echo. :: Output if not defined output ( echo - Path to output: set /p output=\u0026#34;#: \u0026#34; ) echo Path to output: %output% echo. :: Wordlist if not defined wordlist ( echo - Path to wordlist.txt: set /p wordlist=\u0026#34;#: \u0026#34; ) if not exist \u0026#34;%wordlist%\u0026#34; ( echo. echo ERROR! echo Wordlist - \u0026#34;%wordlist%\u0026#34; echo Not be found... pause exit ) echo Wordlist: %wordlist% echo OK! echo. :: Yes OR Not? :yesornot echo Start bruting? (y/n) set /p yesornot=\u0026#34;#: \u0026#34; if /I \u0026#34;%yesornot%\u0026#34;==\u0026#34;y\u0026#34; ( call :startbruting ) else if /I \u0026#34;%yesornot%\u0026#34;==\u0026#34;n\u0026#34; ( echo OK! pause exit ) else ( echo ERROR! echo. call :yesornot ) :startbruting echo . echo Starting bruting... echo. :: Wordlist for for /f \u0026#34;tokens=*\u0026#34; %%a in (\u0026#39;type \u0026#34;%wordlist%\u0026#34;\u0026#39;) do ( set pwd=%%a call :try ) echo. echo Oh-uh... Password not be found... pause exit :try \u0026#34;%z7dir%\\7z.exe\u0026#34; x -p%pwd% \u0026#34;%archive%\u0026#34; -o\u0026#34;%output%\u0026#34; -y \u0026gt;nul 2\u0026gt;\u0026amp;1 echo Try: %pwd% if /I %errorlevel% EQU 0 ( echo. echo Archive was successfully unpacked! echo Password is: %pwd% pause exit ) Источник ","permalink":"https://hv8.pages.dev/blog/brutfors-arkhiva-winrar/","summary":"Покажу как перебирать пароли от архива WinRAR, используя 7z и Batch.","title":"Брутфорс архива WinRAR на Windows"},{"content":"В этой короткой заметки я расскажу как маскировать ссылки на вашем сайте, и не важно это статика или CMS.\nВсе что нужно, это подключить js скрипт туда где он будет загружаться самым последним.\n1 2 3 4 5 6 7 8 9 10 11 12 llinks_moredetail = document .querySelectorAll(\u0026#34;a[href*=\u0026#39;?nt\u0026#39;]\u0026#34;) .forEach((llinks_moredetail) =\u0026gt; { llinks_moredetail.setAttribute(\u0026#34;target\u0026#34;, \u0026#34;moredetail\u0026#34;); llinks_moredetail.setAttribute(\u0026#34;rel\u0026#34;, \u0026#34;noreferrer nofollow noopener\u0026#34;); let llinks_moredetail_href = llinks_moredetail.href.toString().slice(0, -3); llinks_moredetail.setAttribute( \u0026#34;href\u0026#34;, \u0026#34;https://href.li/?\u0026#34; + llinks_moredetail_href ); }); Атрибуты Разберемся с атрибутами ссылки - rel: noreferrer, nofollow, noopener.\nnoreferrer - делает так, чтобы сайт на который вы ссылаетесь, не знал о вашем сайте.\nnofollow - нужен для того чтобы поисковые роботы, игнорировали эту ссылку.\nnoopener - этот атрибут нужен для безопасности. Предотвращает вмешательство в страницу с которой была открыта ссылка.\nПример использования Я написал этот простой скрипт, чтобы контролировать каждую ссылку, которая должна открываться в новой вкладке.\nПример:\nЯ пишу ссылку так: https://example.com/?nt, а получается это:\n1 2 3 4 5 6 7 8 9 10 11 \u0026lt;a href=\u0026#34;https://example.com/?nt\u0026#34;\u0026gt;ссылка\u0026lt;/a\u0026gt; ==\u0026gt;\u0026gt; \u0026lt;a href=\u0026#34;https://href.li/?https://example.com/\u0026#34; target=\u0026#34;moredetail\u0026#34; rel=\u0026#34;noreferrer nofollow noopener\u0026#34; \u0026gt; ссылка \u0026lt;/a\u0026gt; То есть я пишу ?nt в конце ссылки, если хочу чтобы она открывалась в новой вкладке. Так как я предпочитаю, чтобы в новой вкладке открывались в основном только внешние ссылки, я так же добавил атрибуты.\nВы можете использовать скрипт как есть или немного поменять его:\n1 2 3 4 5 6 7 8 9 10 11 12 llinks_moredetail = document .querySelectorAll(\u0026#34;a\u0026#34;) .forEach((llinks_moredetail) =\u0026gt; { llinks_moredetail.setAttribute(\u0026#34;target\u0026#34;, \u0026#34;moredetail\u0026#34;); llinks_moredetail.setAttribute(\u0026#34;rel\u0026#34;, \u0026#34;noreferrer nofollow noopener\u0026#34;); let llinks_moredetail_href = llinks_moredetail.href; llinks_moredetail.setAttribute( \u0026#34;href\u0026#34;, \u0026#34;https://href.li/?\u0026#34; + llinks_moredetail_href ); }); Данный скрипт, берет все ссылки и добавляет href.li с атрибутами.\nПояснение скрипта 1 document.querySelectorAll(\u0026#34;a[href*=\u0026#39;?nt\u0026#39;]\u0026#34;); Выбирает все ссылки которые содержат ?nt.\n1 llinks_moredetail.setAttribute; Назначает атрибуты.\n1 llinks_moredetail.href; Берет атрибут href (то есть саму ссылку).\n1 toString().slice(0, -3); Обрезает ссылку с конца на 3 символа. Так как предполагается что ?nt будет в конце.\n1 2 3 4 llinks_moredetail.setAttribute( \u0026#34;href\u0026#34;, \u0026#34;https://href.li/?\u0026#34; + llinks_moredetail_href ); Меняет атрибут href, подставляет https://href.li/? перед ссылкой.\nНа месте moredetail может быть _blank или abrakadabra - оно в любом случае откроет ссылку в новой вкладке. Я не использую _blank так как есть проблемы с производительностью и безопасностью. Подробнее.\nТак же вы можете редактировать атрибуты и использовать любого другого провайдера, а не href.li.\nПлюсы использования скрипта, а не редактирования ссылок вручную в том, что фактически ссылки остаются чистыми.\nВы можете быстро поменять атрибуты у всех ссылок, или если href.li сломается - вы сможете быстро все исправить, отредактировав скрипт.\n","permalink":"https://hv8.pages.dev/blog/maskirovka-ssylok-na-saite-cherez-href-li/","summary":"Заметка о том как можно маскировать ссылки на сайте.","title":"Маскировка ссылок на сайте через href.li"},{"content":" 🚧 Настоящий материал подготовлен исключительно в образовательных и исследовательских целях. Он не содержит призывов к каким-либо действиям, нарушающим законодательство. Автор(ы) не несут ответственности за последствия использования изложенной информации. Использование/применение представленных сведений осуществляется на ваш страх и риск. Информация предоставляется исключительно для законного изучения и анализа. Любое использование описанных методов для несанкционированного доступа к данным или системам является незаконным и строго запрещено. Любое использование материала в незаконных целях нарушает закон и не одобряется авторами. 📝 Не обращайте внимание на название статьи, речь пойдет о эмуляции игр для Switch. Чтобы их эмулировать, у вас должна быть консоль и купленная игра ;) Покажу как эмулировать игры свичта на примере Prince of Persia: The Lost Crown. Речь идет о Switch, а не о Wii U, для второго лучше использовать эмулятор Cemu.\nТо есть, когда вы покупаете игру (со 100% скидкой разумеется) обращайте внимание для чего она, Switch или Wii U - это две разные консоли.\n📝 Нет необходимости писать статью на тему эмуляции Wii U, там все просто. Скачать эмулятор, установить игру, готово. Эта статья для тех кто хочет сделать все своими руками, а не скачать уже готовый репак с эмулятором и прочим от жирной девочки.\nМы скачаем эмулятор, настроим эмулятор, скачаем/установим прошивку для свитча, скачаем prod.keys, конвертируем дамп игры в формат для эмулятора, установим DLC для игры и наконец запустим.\nДля начала качаем эмулятор Yuzu (эмулятор прикрыли) или Ryujinx (эмулятор прикрыли), какой значения не имеет. Попробуйте оба если хотите, какой больше понравится тот и используйте. Я буду использовать Ryujinx.\n📝 За эмулятором Ryujinx, пришли Nintendo, так же как и за Yuzu когда-то. Первый запуск Ryujinx Вы уже скачали эмулятор и распаковали его в нужную директорию.\nОткрываем ryujinx, видим это:\nRyujinx ошибка prod.keys Не обращаем внимания, так и должно быть. Нажимаем ОК.\nИнтерфейс Ryujinx Переходим в директорию где хранятся конфиг файлы Ryujinx:\nFile \u0026gt; Open Ryujinx Folder \u0026raquo; System Вы должны оказаться в:\n1 %userprofile%\\AppData\\Roaming\\Ryujinx\\system Отсюда не уходим. Закрываем эмулятор, для установки ключей его нужно было хотя бы раз запустить, чтобы тот создал свои файлы в AppData.\nСкачиваем прошивку и ключи Переходим на сайт и качаем последнюю прошивку и ключи.\n📝 От версии прошивки и ключей зависит кол-во поддерживаемых игр. Поэтому качайте последнюю версию, если нет специальной потребности в старой версии Качать Ryujinx/Yuzu/Switch - значения не имеет, они все одинаковые.\nПрошивка ясное дело это прошивка, думаю мы все знаем что это такое.\nКлючи это буквально ключи, без них игры работать не будут. Ключи нужны для дешифровки, то есть ключи это своего рода DRM.\nИгры требуют определенной прошивки, обратная совместимость как я понимаю есть. Если вы скачаете старую прошивку, новая игра может не работать. Ключи зависимы от прошивки, так как в оригинале ключи идут вместе с прошивкой, но мы пираты.\nЭто информация может быть не совсем верна, это просто мое наблюдение, у меня никогда не было консоли от Nintendo.\nУстановка прошивки и ключей Содержимое архива с ключами кидаем в открытые ранее файлы.\nДолжно быть так:\n- Ryujinx | - system | | - prod.keys | | - Profiles.json | | - title.keys Запускаем Ryujinx, если снова появилась ошибка, значит стоит перечитать текст выше. Если же ошибки нет - ключи установлены, теперь прошивка.\nTools \u0026gt; Install Firmware \u0026gt; \u0026hellip;from XCI or ZIP \u0026raquo; Архив с прошивкой:\nRyujinx - Установка прошивки 📝 Процесс установки прошивки можно посмотреть в консоли. Препарируем дамп игры Где \u0026ldquo;покупать\u0026rdquo; игру решайте сами. Главное помните о Wii U и Switch (см. начало статьи).\nЕсли дамп игры не в .xci, .nsp, .pfs0, .nca, .nro, .nso или не распакованный, то нужно распаковать или конвертировать его. Если же у вас уже есть распакованные файлы игры или дамп в формате выше - пропускайте этот шаг.\nКонвертируем дамп игры Для конвертации будем использовать утилиту nsz, качаем и распаковываем ее. Открываем nsz.exe и видим это:\nNSZ GUI - ERROR ...\\nsz_v4.6.1_win64_portable\\keys.txt or C:\\Users\\%username%\\.switch\\prod.keys not found! Please dump your keys using https://github.com/shchmue/Lockpick_RCM/releases Press Enter to exit... Ошибка гласит что отсутствует prod.keys. Есть два варианта:\nСоздать keys.txt в корне утилиты, с ключами из prod.keys. Создать папку .switch в папке юзера, и кинуть туда prod.keys. Первый вариант будет чище, поэтому создаем текстовый файл в корне утилиты:\n- nsz_v4.6.1_win64_portable | - keys.txt Открываем скачанный prod.keys с помощью любого текстового редактора, копируем содержимое prod.keys в keys.txt. Запускаем снова и ошибки нет:\nNSZ GUI 💡 Открываем настройки Settings [F1] \u0026gt; Tools \u0026gt; Kivy always on top \u0026raquo; Off - перезапускаем утилиту. Таким образом вы выключили функцию \u0026ldquo;всегда поверх всех окон\u0026rdquo; - не благодарите ;) Следуя строке белого цвета жирного шрифта в центре окна, берем файл вашей игры (в моем случае .nsz) и перетаскиваем его в окно утилиты:\nNSZ GUI \u0026amp; Prince of Persia: The Lost Crown Decompress NSZ/XCZ. Ожидаем окончания, новый дамп будет лежать в той же директории что и оригинальный дамп.\nExtract. Если вы хотите распаковать дамп соответственно.\nВ моем случае это \u0026ldquo;Decompress NSZ/XCZ\u0026rdquo; для конвертации .NSZ в .NSP.\nГотово. Осталось самое простое, запустить.\nЗапуск игр Как я понял игры тут не устанавливаются, а просто запускаются из дампа или распакованных файлов.\n📝 Это вопрос беспорядка. Вы можете запускать игру и \u0026ldquo;устанавливать\u0026rdquo; длс откуда угодно. Но если файлы игры или длс будут удалены, они будут удалены. Поэтому в удобном месте создайте папку с играми. Внутри удобной папки с играми, создайте другую папку с конкретной игрой, туда поместите дамп\\файлы игры. Если есть DLC - туда же. Вот как у меня:\n- ryujinx | - games | | - Prince of Persia the Lost Crown | | | - .nsp | | | - DLC | | | | - .nsp | | - Another Game | - ryujinx-1.1.1117 Открываем Ryujinx \u0026gt; Load Application from File\\Unpacked Game \u0026raquo; выбираем дамп\\папку:\nRyujinx - Запуск игры 📝 Если у вас распакованная игра то соответственно выбирайте Load Unpacked Game, у меня же это просто .NSP, поэтому я выбираю Load Application from File. Как только вы загрузите игру, игра начнет (ого) загружаться и запустится.\nДля подключения DLC у вас должен быть каталог игр (см. Настройка Ryujinx \u0026gt; Каталог игр), ПКМ по игре \u0026gt; Manage DLC:\nRyujinx - DLC Нажимаем Add \u0026raquo; .NSP. И так выбираете каждое DLC, возможно можно выбрать сразу все. Проставляете галочки напротив каждого DLC, если те не проставлены.\n📝 Если DLC не в .NSP - то конвертируем в .NSP. На этом все, далее будет настройка эмулятора Ryujinx для наилучшего юзабилити. Можете почитать или полазить по настройкам сами.\nНастройка Ryujinx Настройки находятся тут Options \u0026gt; Settings.\nRyujinx - Настройки Каталог игр Чтобы сделать удобный каталог игр, как у меня на скриншотах выше: General \u0026gt; Game Directories \u0026gt; Add \u0026raquo; Выбираете ту самую удобную папку с играми. НЕ папку с игрой, а папку В которой ДРУГИЕ папки с играми.\n- ryujinx | - games \u0026lt;-- Выбираете это | | - Prince of Persia the Lost Crown | | | - .nsp | | | - DLC | | | | - .nsp | | - Another Game | - ryujinx-1.1.1117 Управление Вкладка Input. Тут вы увидите, таблицу?\nСверху галочки:\nDocked Mode - назовем это \u0026ldquo;геймпад мод\u0026rdquo; Keyboard Access - чтобы играть на клавиатуре Mouse Access - это мышь, аналогично. Но по сути это пресеты для пресетов. Если у геймпада вы биндите только левый и правый стик, то на клавиатуре левый/правый стик - верх, низ, лево, право. Включите - посмотрите.\nRyujinx - Настройки ввода Настраиваем все профили если (уже) собираетесь играть 8-ром, если нет, то только Player 1.\nЧтобы настроить геймпад возможно понадобится софт. Геймпад может работать из коробки, а может и нет. XBOX должен, так как это Microsoft, как и Windows - если у вас Windows.\nС ноунейм китайскими геймпадами ничего не скажу.\nДля геймпада DualShock 4\\5 (PlayStation) можно использовать DS4Windows.\nПроблемы с DS4Windows Из за ситуации с драйвером (vigembus) который использует DS4Windows, второй прекратит обновления. Если вы читаете эту статью из будущего, то возможно придется искать другой софт.\nЕсть второй вариант - Steam. Стим может работать с геймпадами, но он насколько мне известно \u0026ldquo;конвертирует\u0026rdquo; все в клавиатуру. DS4Windows вроде как, \u0026ldquo;конвертирует\u0026rdquo; все в геймпад XBOX. В прочем, через стим я этого не проверял, ни просто, ни эмулятор, только слышал.\nЧтобы забиндить кнопки нужно нажать Configure под профилем. Если открылась панель управления самолетом - вы на верном пути.\nНе забудьте выбрать устройства в Input Device.\nВсе что не кнопки, настраивайте по своему усмотрению. Чтобы забиндить кнопку нажимаем на Unbound \u0026gt; Нажимаем кнопку\\клавишу на которую хотим сделать бинд:\nБиндите на что хотите, но желательно, чтобы бинд совпадал с функцией на которую вы биндите (если это геймпад), как на скриншоте выше.\nС клавиатурой аналогично, только прибавится несколько доп. биндов (верх, низ, лево, право).\nНе забудьте сохранить профиль нажав Add сверху справа.\nГрафика Мои настройки:\nRyujinx - Настройки графики Для начала советую поставить что-то по типу этого:\nRyujinx - Настройки графики Экспериментируйте с настройками. Сглаживание вероятней съедает больше всего производительности.\nЛагают игры Если лагает, не спешите снижать настройки графики и расстраиваться. Лагает, потому что шейдеры компилируются на лету. То есть через сколько-то времени игры, когда все или большинство шейдеров будут скомпилированы, лагать перестанет.\nКак вариант где-то скачать шейдеры и подгрузить их. Шейдеры не универсальны, для каждой игры свои шейдеры. Если вы не понимаете о чем речь, то погуглите.\n","permalink":"https://hv8.pages.dev/blog/piratim-nintendo-switch/","summary":"У вас Denuvo - у нас эмулятор.","title":"Пиратим Nintendo Switch"},{"content":" 📝 Это старая статья и информация о установке возможно устарела! О Stable Diffusion Stable Diffusion это тип ИИ модели для генерации изображений. Так же существует одноименное ПО от automatic1111.\nВы можете использовать любую модель какую вы только захотите на основе SD. Скачать вы их можете например тут Civitai.\nЭто статья рассказывает о Stable Diffusion, а так же объясняет как развернуть Stable Diffusion локально.\nЕсли вы не знаете что такое Stable Diffusion Stable Diffusion - это скрытая модель диффузии текста в изображение, способная генерировать от аниме до фотореалистичных изображений при любом вводе текста, культивирующая автономную свободу для создания невероятных изображений, дающая всем возможность создавать пикчи в течение нескольких секунд.\nВыпуск Stable Diffusion стал важной вехой в этом развитии, поскольку высокопроизводительная модель оказалась доступной широкой публике (производительная с точки зрения качества изображения, скорости и относительно низких требований к ресурсам).\nПикчи Модели:\ndjz Ink Punk V21 djz Dieselpunk City V21 Inkpunk Diffusion Umi AI Mythology and Babes by DutchAlex Техническая часть В этой части я покажу вам как же все таки запустить и опробовать эту шайтан машину. А так же тут будет очень много текста, который поясняет как это работает. Но читать его не обязательно.\nКак работает Stable Diffusion Stable Diffusion гибка, то есть может использоваться множеством разных способов. Давайте сначала рассмотрим генерацию изображений на основе одного текста (text2img). На картинке выше показан пример текстового ввода и получившееся сгенерированное изображение.\nКроме превращения текста в изображение, другим основным способом применения модели является изменение изображений (то есть входными данными становятся текст + изображение).\nДавайте начнем разбираться со внутренностями модели, потому что это поможет нам объяснить ее компоненты, их взаимодействие и значение опций/параметров генерации изображений.\nКомпоненты Stable Diffusion Stable Diffusion - это система, состоящая из множества компонентов и моделей. Это не единая монолитная модель.\nИзучая внутренности, мы первым делом заметим, что в модели есть компонент понимания текста, преобразующий текстовую информацию в цифровой вид, который передает заложенный в текст смысл.\nМы начнем с общего обзора, а позже углубимся в подробности машинного обучения. Однако для начала можно сказать, что этот кодировщик текста - это специальная языковая модель Transformer (технически ее можно описать как текстовый кодировщик модели CLIP). Она получает на входе текст и выдает на выходе список чисел (вектор), описывающий каждое слово/токен в тексте.\nДалее эта информация передается генератору изображений, который состоит из двух компонентов.\nГенератор изображений выполняет два этапа:\n1. Создание информации изображения\nЭтот компонент является секретным ингредиентом Stable Diffusion. Именно благодаря нему возник такой рост качества по сравнению с предыдущими моделями.\nЭтот компонент выполняется в несколько шагов (step), генерируя информацию изображения. Это параметр steps в интерфейсах и библиотеках Stable Diffusion, который часто по умолчанию имеет значение 50 или 100.\nЭтап создания информации изображения действует полностью в пространстве информации изображения (или в скрытом пространстве). Подробнее о том, что это значит, будет ниже. Это свойство ускоряет работу по сравнению с предыдущими моделями диффузии, работавшими в пространстве пикселей. Этот компонент состоит из нейросети UNet и алгоритма планирования.\nСлово «диффузия» (diffusion) описывает происходящее в этом компоненте. Это пошаговая обработка информации, приводящая в конечном итоге к генерации высококачественного изображения (при помощи следующего компонента – декодера изображений).\n2. Декодер изображений\nДекодер изображений рисует картину на основе информации, которую он получил на этапе создания информации. Он выполняется только один раз в конце процесса и создает готовое пиксельное изображение.\nНа изображении выше мы видим три основных компонента (каждый со своей собственной нейросетью), из которых состоит Stable Diffusion:\nClipText для кодирования текста\nВходные данные: текст Выходные данные: 77 векторов эмбеддингов токенов, каждый в 768 измерениях UNet + Scheduler для постепенной обработки/диффузии информации в пространстве информации (скрытом пространстве)\nВходные данные: эмбеддинги текста и исходный многомерный массив (структурированные списки чисел, также называемые тензором), состоящий из шума Выходные данные: массив обработанной информации Декодер автокодировщика (Autoencoder decoder), рисующий готовое изображение при помощи массива обработанной информации\nВходные данные: массив обработанной информации (размеры: (4,64,64)) Выходные данные: готовое изображение (размеры: (3, 512, 512) – (красный/зеленый/синий, ширина, высота)) Что такое диффузия? Диффузия - это процесс, выполняемый внутри розового компонента «image information creator» (этапа создания информации изображения). Имея эмбеддинги токенов, описывающие введенный текст, и случайный начальный массив информации изображения (также они называются latent), процесс создает массив информации, который декодер изображения использует для рисования готового изображения.\nЭто процесс выполняется поэтапно. Каждый шаг добавляет больше релевантной информации. Чтобы представить процесс в целом, мы можем изучить массив случайных latent, и увидеть, что он преобразуется в визуальный шум. В данном случае визуальное изучение – это прохождение данных через декодер изображений.\nДиффузия выполняется в несколько шагов, каждый из которых работает с входным массивом latent и создает еще один массив latent, еще больше напоминающий введенный текст, а вся визуальная информация модели собирается из всех изображений, на которых была обучена модель.\nМы можем визуализировать набор таких latent, чтобы увидеть, какая информация добавляется на каждом из шагов.\nDownload WEBM Your browser does not support video. YouTube: diffusion steps all loop В данном случае нечто особо восхитительное происходит между шагами 2 и 4. Как будто контур возникает из шума.\nDownload WEBM Your browser does not support video. YouTube: stable diffusion steps 2 4 Как работает диффузия Основная идея генерации изображений при помощи диффузионной модели использует тот факт, что у нас есть мощные модели компьютерного зрения. Если им передать достаточно большой массив данных, эти модели могут обучаться сложным операциям. Диффузионные модели подходят к задаче генерации изображений, формулируя задачу следующим образом:\nДопустим, у нас есть изображение, сделаем первый шаг, добавив в него немного шума.\nНазовем «срез» (slice) добавленного нами шума «noise slice 1». Сделаем еще один шаг, добавив к шумному изображению еще шума («noise slice 2»).\nНа этом этапе изображение полностью состоит из шума. Теперь давайте возьмем их в качестве примеров для обучения нейронной сети компьютерного зрения. Имея номер шага и изображение, мы хотим, чтобы она спрогнозировала, сколько шума было добавлено на предыдущем шаге.\nХотя этот пример показывает два шага от изображения к полному шуму, мы можем управлять тем, сколько шума добавляется к изображению, поэтому можно распределить его на десятки шагов, создав десятки примеров для обучения на каждое изображение для всех изображений в обучающем массиве данных.\nКрасота здесь в том, что после того, как эта сеть прогнозирования шума начнет работать правильно, она, по сути, сможет рисовать картины, удаляя шум на протяжении множества шагов.\nПримечание: это небольшое упрощение алгоритма диффузии. На ресурсах по ссылкам в конце статьи представлено более подробное математическое описание.\nРисование изображений устранением шума Обученный предсказатель шума может взять шумное изображение и количество шагов устранения шума, и на основании этого способен спрогнозировать срез шума.\nСрез шума прогнозируется таким образом, что если мы вычтем его из изображения, то получим изображение, которое ближе к изображениям, на которых обучалась модель.\nЕсли обучающий массив данных состоял из эстетически приятных изображений (например, LAION Aesthetics, на котором обучалась Stable Diffusion), то получившееся изображение будет иметь склонность к эстетической приятности.\nВ этом по большей мере и заключается описание генерации изображений диффузионными моделями, представленное в статье Denoising Diffusion Probabilistic Models. Теперь, когда мы понимаем, что такое диффузия, нам понятно, как работают основные компоненты не только Stable Diffusion, но и Dall-E 2 с Google Imagen.\nОбратите внимание, что описанный выше процесс диффузии генерирует изображения без использования текстовых данных. В последующих разделах будет рассказано, как в процесс внедряется текст.\nУвеличение скорости: диффузия сжатых (скрытых) данных, а не пиксельного изображения Для ускорения процесса генерации изображений Stable Diffusion (по информации из исследовательской статьи) выполняет процесс диффузии не с самими пиксельными изображениями, а со сжатой версией изображения. В статье это называется «переходом в скрытое пространство».\nЭто сжатие (и последующая распаковка/рисование) выполняется при помощи автокодировщика. Автокодировщик сжимает изображение в скрытое пространство при помощи своего кодировщика, а затем воссоздает его при помощи декодера на основе только сжатой информации.\nДалее со сжатыми latent выполняется прямой процесс диффузии. Используются срезы шума, применяемые к этим latent, а не к пиксельному изображению. То есть предсказатель шума на самом деле обучается прогнозировать шум в сжатом описании (в скрытом пространстве).\nПри помощи прямого процесса (с использованием кодировщика автокодировщика) мы генерируем данные для обучения предсказателя шума. После его обучения мы можем генерировать изображения, выполняя обратный процесс (при помощи декодера автокодировщика).\nЭти два потока показаны на рисунке статьи про LDM/Stable Diffusion:\nТакже на этом рисунке показаны компоненты «согласования», которые в данном случае являются текстовыми строками, описывающими изображение, которое должна генерировать модель. Поэтому давайте рассмотрим эти текстовые компоненты.\nТекстовый кодировщик: языковая модель Transformer Языковая модель Transformer используется в качестве компонента понимания языка, она получает текстовую строку и создает эмбеддинги токенов. В опубликованной модели Stable Diffusion используется ClipText (модель на основе GPT), а в статье применяется BERT.\nВ статье, посвященной Imagen, показано, что выбор языковой модели важен. Замена на более объемные языковые модели сильнее влияет на качество генерируемого изображения, чем более объемные компоненты генерации изображений.\nУлучшение/увеличение языковых моделей существенно влияет на качество моделей генерации изображений.\nИсточник: Статья про Google Imagen, написанная Saharia и соавторами. В первых моделях Stable Diffusion просто подключалась предварительно обученная модель ClipText, выпущенная OpenAI. Возможно, будущие модели перейдут на новые и гораздо более объемные OpenCLIP-варианты CLIP. В эту новую группу входных векторов включены текстовые модели размерами до 354 миллионов параметров, в отличие от 63 миллионов параметров в ClipText.\nКак обучается CLIP CLIP обучается на массиве изображений и подписей к ним. Массив данных выглядит примерно так, только состоит из 400 миллионов изображений и подписей:\nCLIP - это сочетание кодировщика изображений и кодировщика текста. Обучающий процесс модели можно упрощенно представить как кодирование изображения и его подписи кодировщиками изображений и текста.\nЗатем мы сравниваем получившиеся эмбеддинги при помощи косинусного коэффициента. В начале процесса обучения схожесть будет низкой, даже если тест описывает изображение правильно.\nМы обновляем две модели так, чтобы в следующий раз при создании эмбеддингов получившиеся эмбеддинги были схожими.\nПовторяя этот процесс со всем массивом данных и группами входных векторов большого размера, мы получаем кодировщики, способные создавать эмбеддинги, в которых изображение собаки и предложение «a picture of a dog» схожи. Как и в word2vec, процесс обучения также должен включать в себя отрицательные примеры изображений и подписей, которые не совпадают, а модель должна присваивать им низкую оценку схожести.\nПередача текстовой информации в процесс генерации изображений Чтобы сделать текст частью процесса генерации изображений, нам нужно модифицировать предсказатель шума так, чтобы он использовал в качестве входных данных текст.\nТеперь наш массив данных содержит закодированный текст. Так как мы работаем в скрытом пространстве, то входные изображения и прогнозируемый шум находятся в скрытом пространстве.\nЧтобы лучше понять, как текстовые токены используются в Unet, давайте глубже разберемся с Unet.\nСлои предсказателя шума Unet (без текста) Для начала рассмотрим диффузионную Unet, не использующую текст. Ее входы и выходы выглядят так:\nВнутри мы видим следующее:\nUnet - это последовательность слоев, работающая над преобразованием массива latent. Каждый слой обрабатывает выходные данные предыдущего слоя. Часто выходных данных подается (через остаточные соединения) для обработки на дальнейших этапах сети. Шаг времени преобразуется в вектор эмбеддингов шага времени, который используется в слоях. Слои предсказателя шума Unet с текстом Давайте посмотрим, как изменить эту систему, чтобы уделить внимание тексту.\nОсновное изменение системы, которое необходимо для добавления поддержки текстового ввода (техническое название: text conditioning) – добавление слоя attention между блоками ResNet.\nОбратите внимание, что блок resnet не смотрит непосредственно на текст. Слои attention объединяют эти текстовые описания в latent. И теперь следующий ResNet может использовать эту встроенную текстовую информацию в своей обработке.\nЗаключение Надеюсь, это даст вам поверхностное понимание работы Stable Diffusion. В ней задействовано множество других концепций, но я считаю, что их проще понять, если вы знаете описанные выше строительные блоки. Для дальнейшего изучения можно воспользоваться представленными ниже полезными ресурсами.\nРесурсы Stable Diffusion with 🧨 Diffusers The Annotated Diffusion Model How does Stable Diffusion work? – Latent Diffusion Models EXPLAINED (Видео) Stable Diffusion - What, Why, How? (Видео) High-Resolution Image Synthesis with Latent Diffusion Models (Статья про Stable Diffusion) Более подробное изучение алгоритмов и математики представлено в статье Лилиан Венг (Lilian Weng) What are Diffusion Models? Одноминутный клип на YouTube по использованию Dream Studio для генерации изображений при помощи Stable Diffusion. Хорошие видео о Stable Diffusion от fast.ai Источник - перевод «The Illustrated Stable Diffusion»\nЗапуск Stable Diffusion (Возможно устарело) Что нужно для запуска локально? Мощное железо.\nВ самом деле если вы собрали/купили свой ПК не 20 лет назад, вероятней всего вашего железа хватит.\nКто то пишет что нужно минимум 6Gb VRAM, кто то 10Gb VRAM. А кто то что нужна строго карта от зеленых. Но вот вам правда на момент написания статьи и Stable Diffusion 2.1: нужно минимум 6VRAM, 8RAM и не обязательно иметь карту от Nvidia, а так же серии RTX. Stable Diffusion можно запустить на любой карте будь то AMD, Nvidia или даже Intel.\nНасчет процессора как таковой информации нету. Но при желании Stable Diffusion можно запустить и на 4VRAM. Используя облегченные форки например от basujindal.\nТак же стоит предупредить что официальная установка Stable Diffusion и правда требует минимум 10VRAM и 16RAM.\nКак нынче все что можно запустить в этом мире, моя рекомендация запускать конечно же на SSD.\nМы будем использовать вариант от AUTOMATIC1111, простой, удобный и не слишком требовательный.\nТо есть понадобится примерно 6VRAM и 16RAM. На выходе мы получим удобный веб интерфейс на локальном хосте, и даже плюсом сможем расшарить его и поделится ссылкой с кем то.\nУстановка Stable Diffusion локально Для начало вам нужно будет скачать или обновить или сделать downgrade Python, на текущий момент строго версии 3.10.x, тк Pytorch не поддерживает версию 3.11.x. Посмотреть нужную версию питона можно в репозитории на GitHub. На патч версию можно не обращать внимания (в большинстве случаев).\n🚧 ВАЖНО: Запустите установщик от имени админа, установите ДЛЯ ВСЕХ пользователей и не забудьте поставить галочку на Add path. Качаем или клонируем репозиторий: stable-diffusion-webui (если вы на Linux, лучше клонировать).\nДалее переходим на HuggingFace. Там вам нужно будет скачать саму модель в формате ckpt или safetensors, не имеет значения в каком.\nВ чем отличие: ckpt, safetensors; ema, noema; 512, 768; ckpt от safetensors\nОни одинаковы, но ckpt может содержать вредоносный код, safetensors нет.\nema от nonema\nEMA - можно обучать дальше. NONEMA - нельзя.\n512 от 768\nЭто размеры картинок, на которых обучалась модель. На практике 768 работает лучше.\nСравнение можно посмотреть здесь.\nДалее скачайте v2-inference-v.yaml.\nИ так что мы имеем?\nВы установили Python, и если вы введете в консоль python -V или python3 -V, вы должны увидеть версию питона, указанную выше или в репозитории на GitHub. Вы скачали репозиторий с гитхаба. Вы скачали модель Stable Diffusion, а так же конфиг файл. Если все так, идем дальше.\nОткрываем ../stable-diffusion-webui/models/Stable-diffusion/ – и забрасываем туда модель и конфиг файл.\nДалее копируем название модели, и переименовываем конфиг файл в название модели.\nНапример: v2-1_768-nonema-pruned.safetensors \u0026raquo; v2-1_768-nonema-pruned.yaml.\nДалее в корневой папки откройте с помощью текстового редактора файл - webui-user.bat, и измените аргументы запуска (set COMMANDLINE_ARGS=), но сначала изучите информацию ниже!\n1 2 3 4 5 6 7 8 9 10 11 # Базовые аргументы, нужные для работы --api --cors-allow-origins=https://www.painthua.com --no-half # Можете добавить это, что бы расшарить localhost --share --listen # Так же можно добавить, об этом ниже --xformers # Максимальная оптимизация, позволит вам использовать более высокое разрешение, но повлияет на скорость генерации --xformers --opt-split-attention --opt-sub-quad-attention --medvram --api --cors-allow-origins=https://www.painthua.com --no-half Иногда генерируется сомнительная пикча, потому что разрешение слишком маленькое. Поэтому следует использовать последнюю строку параметров запуска.\nДля запуска нужно использовать webui-user.bat.\nАргументы запуска Xformers Библиотека Xformers - это дополнительный способ ускорить создание изображений. Но это фича доступна только для видеокарт Nvidia.\nДля использования понадобится указать --xformers в параметрах запуска. А так же скачать и установить CUDA 11.3 (какую версию CUDA смотреть здесь), выбрать Custom, а далее выбрать только следующее:\n--force-enable-xformers - Включает xformers, независимо от того, может ли он запустится или нет. Не сообщает об ошибках, которые могут появится, во время выполнения.\nПодробнее здесь.\nSHARE и LISTEN --share - создает публичную ссылку на gradio.\n--listen - должен расшарить локалхост внутри локальной сети, но лично у меня не работает.\nИз-за параметров share и listen могу не работать некоторые расширения, которые скорее всего еще не установлены, но которые вы возможно захотите установить, например ControlNet (у меня так).\nОптимизация Аргумент Пояснение --opt-split-attention Использует черную магию, для снижения памяти почти без затрат. --disable-opt-split-attention Отключает вышеуказанную оптимизацию. --opt-sub-quad-attention Субквадратичное внимание - оптимизация слоя Cross Attention, эффективная для памяти, которая может значительно уменьшить требуемую память, иногда с небольшими затратами производительности. Рекомендуется при низкой производительности или неудачных генерациях с аппаратной/программной конфигурацией, для которой xformers не работает. --opt-split-attention-v1 Использует более старую версию оптимизации, которая не так требовательна к памяти (она будет использовать меньше VRAM, но будет более ограничена в максимальном размере изображений, которые вы можете сделать). --medvram Заставляет модель Stable Diffusion потреблять меньше VRAM, разделяя ее на три части – cond (для преобразования текста в числовое представление), first_stage (для преобразования изображения в латентное пространство и обратно) и unet (для собственно деноизации латентного пространства) и делая так, чтобы только одна из них постоянно находилась в VRAM, отправляя остальные в CPU RAM. Это снижает производительность, но незначительно – за исключением случаев, когда включен предварительный просмотр в реальном времени. --lowvram Еще более тщательная оптимизация вышеописанного, разбиение unet на множество модулей, и только один модуль хранится в VRAM. Разрушительно для производительности. *do-not-batch-cond-uncond Предотвращает пакетную обработку положительных и отрицательных подсказок во время выборки, что позволяет работать с размером партии 0,5, экономя много памяти. Снижает производительность. Не опция командной строки, а оптимизация, неявно включаемая при использовании --medvram или --lowvram. --always-batch-cond-uncond Отключает вышеуказанную оптимизацию. Имеет смысл только вместе с --medvram или --lowvram --opt-channelslast Изменяет тип памяти torch для стабильной диффузии в каналы в последнюю очередь. Эффекты не изучены. Подробнее здесь.\nПромты (Подсказки) Positive - верхнее поле, туда вы вводите чтобы вы хотели.\nNegative - нижние поле, туда вы вводите чтобы вы НЕ хотели.\n() - Так же вы можете использовать \u0026ldquo;приоритет\u0026rdquo; – вес\\акцент промта, который будет применятся, \u0026ldquo;сильнее\u0026rdquo;.\n(1) ((2)) (((3))) ((((4)))) (((((5))))) ((((((6)))))) [] - Меньшей \u0026ldquo;приоритет\u0026rdquo; – уменьшение веса\\акцента промта, который будет применятся, \u0026ldquo;слабее\u0026rdquo;.\n[1] [[2]] [[[3]]] [[[[4]]]] [[[[[5]]]]] [[[[[[6]]]]]] Соотношения - …:1.0, указывает силу\\акцент\\вес в дробях.\nНапример: (Blue hair) будет иметь больший вес, чем [Blue hair] в конечном результате, (Blue hair:1.4) увеличит Blue hair на ~40% больше, чем обычно, (Blue hair:0.6) уменьшит их на ~40%.\nModels, Lora, Textual Inversion, Hypernetwork Checkpoint (Модель) Модель она же «checkpoint». Большая, очень большая или не очень большая уже обученная модель.\nГенерируют txt2img, img2img, etc. с нуля, исходя из больших данных, которыми обучали модель.\nПредоставляется в ckpt и/или safetensors.\nДля установки нужно закинуть ее в ../stable-diffusion-webui/models/Stable-diffusion/.\nLoRA LoRA (Low-Rank Adaptation) - это грубо говоря мини-модель. Суть лоры в том что бы добавить \u0026ldquo;фичу\u0026rdquo; на пикчу сгенерированную полноценной моделью.\nОсновная идея LoRA заключается в том, чтобы адаптировать уже обученные модели к новым задачам или данным, не переобучая всю модель, а добавляя лишь небольшое количество параметров.\nАналогично моделям это ckpt и/или safetensors, но весит очень мало в сравнение с моделью.\nДля установки нужно закинуть в ../stable-diffusion-webui/models/Lora/.\nДля использования в webui нужно нажать на красную кнопку (🎴), выбрать Lora, обновить список, далее выбрать нужную.\nTextual Inversion Textual Inversion ака «embedding» – это почти как Lora. Грубо говоря что-то типа стиля.\nПодробнее **Textual Inversion** - это метод, который позволяет создавать специальные эмбеддинги для определенных концепций или объектов, используя текстовые описания. Этот подход часто применяется в области генеративных моделей, таких как Stable Diffusion, чтобы улучшить качество генерации изображений или текста. Суть метода заключается в том, что вместо того чтобы использовать стандартные текстовые эмбеддинги, мы обучаем модель на конкретных примерах, чтобы она могла ассоциировать определенные слова или фразы с уникальными представлениями (эмбеддингами). Например, если мы хотим, чтобы модель знала, как визуализировать конкретного персонажа или стиль, мы можем предоставить ей набор примеров, и она создаст эмбеддинг, который будет представлять этот концепт. Эмбеддинги, созданные с помощью Textual Inversion, позволяют более точно настраивать результаты генерации, придавая им желаемые характеристики. Это полезно для персонализации контента и улучшения качества генерации в специфических областях. Обычно это pt или bin (первый формат используется автором оригинала, второй – библиотекой диффузоров) с вложением в него.\nДля установки нужно закинуть в ../stable-diffusion-webui/embeddings/.\nИспользование в webui аналогично Lora.\nHypernetwork Hypernetwork - это, грубо говоря, что-то похожее на Textual Inversion. С помощью Textual Inversion вы направляете нейросеть к конкретным целям, тогда как Hypernetwork учитывает прошлые результаты генерации для будущих выходов.\nЧто известно, так это то, что Hypernetwork может восприниматься как некий \u0026ldquo;оригинальный\u0026rdquo; промт для создания изображений. Но на практике для конечного пользователя Lora, Textual Inversion и Hypernetwork часто могут казаться аналогичными инструментами.\nДля установки нужно закинуть в ../stable-diffusion-webui/models/hypernetworks/.\nИспользование в webui аналогично Lora и Textual Inversion.\nСэмплирование Sampling method - это метод обработки входного шума, и разные методы обрабатывают его по-разному.\nРазличные значения Sampling steps значительно влияют на внешний вид результата. Обычно увеличение количества шагов добавляет детали и делает изображение более качественным. Однако это не всегда работает: иногда картинке не нужно столько деталей, особенно если модель рассчитана на арт или абстракцию. В некоторых случаях, из-за слишком большого количества деталей, изображение может стать гиперреалистичным, несмотря на изначальную абстракцию.\nНа практике Sampling steps особенно сильно влияют на генерацию существ (людей, животных и т.д.) и предметов.\nЕсли вам нужен быстрый ответ и не хочется разбираться: Euler и Euler a - это дефолтные методы, которые в 80% случаев дают результат от \u0026ldquo;так себе\u0026rdquo; до \u0026ldquo;сверх круто\u0026rdquo;. DDIM, DPM++ 2M Karras и DPM++ SDE Karras - это самые качественные методы, особенно для генерации персонажей и просторных пейзажей.\nКак пользоваться Stable Diffusion WebUI Интерфейс Sampling method и Sampling steps Про Sampling method и Sampling steps смотреть выше.\nRestore faces Опция восстанолвения лиц. Обычно плохо работает на артах, абстракциях и подобных (даже если там есть лица).\nTiling Tiling - это метод, который делает изображение таким, чтобы его грани не содержали резких или четких элементов, что позволяет размещать несколько таких изображений рядом друг с другом без видимых швов.\nВ общем смысле это можно назвать текстурой, хотя это довольно упрощенное определение. Tiling применяется не только для создания текстур или фонов. Например, вы могли видеть персонажей, вписанных в фон не с помощью света, а через использование частиц, что также может быть достигнуто с помощью этого метода.\nHires. fix Это очень полезная опция, но, как правило, она не так критична для пейзажей. Модель обычно обучается на изображениях размером 512px или 768px.\nЕсли вы сгенерируете лицо человека в разрешении 512px, то результат будет ожидаемым. Однако при генерации в 1K+ вы можете получить неожиданный результат. Скорее всего, сгенерируется \u0026ldquo;мутант\u0026rdquo; с искажённым лицом, или, в лучшем случае, может возникнуть несколько лиц, которые растянутся в ширину или длину в зависимости от размера изображения.\nПоэтому, если вы хотите получить высококачественное изображение лица без искажений, используйте Hires. fix с минимальным значением апскейла, равным 1 (то есть без увеличения). Рекомендуемый шаг - 0.5. И помните, что эта опция использует VRAM.\nBatch count и Batch size Batch count - это количество изображений, которые будут сгенерированы за одно нажатие. Он не влияет на потребление VRAM, так как изображения генерируются по очереди, но влияет на общее время завершения генерации. Вы можете открыть папку output и увидеть уже сгенерированные изображения из этой очереди.\nBatch size - это то же самое, что и Batch count, но в отличие от него, изображения генерируются одновременно. Это влияет на потребление VRAM и требует больше ресурсов.\nНапример, если Batch count равен 3, то сначала будет сгенерировано одно изображение, затем следующее и так далее. В случае Batch size равного 3 будет сгенерировано сразу три изображения.\nCFG Scale Это параметр, который определяет, насколько строго генерация будет следовать вашим промтам. Чем выше значение, тем более точно результат будет соответствовать заданным описаниям, но при этом может снижаться уникальность изображения.\nГрубый пример:\nЕсли вы задаете низкое значение CFG Scale и просите сгенерировать дерево и гору, может получиться изображение с лесом и без горы, только гора или картинка с множеством деталей, где присутствуют дерево и гора, но не в центре внимания.\nНа высоком значении CFG Scale результатом будет более точное соответствие запросу: сгенерируется именно дерево и гора.\nПримерные значения:\n0 - 6: Вы позволяете модели игнорировать ваши промты, что может привести к неожиданным результатам. 6 - 10: Вы хотите, чтобы модель следовала вашим промтам, но допускаете небольшие вариации в результате. 10+: Вы требуете, чтобы модель строго придерживалась ваших промтов, без отклонений. ","permalink":"https://hv8.pages.dev/blog/stable-diffusion/","summary":"Stable Diffusion - Что это? Как работает? Как запустить? И другое.","title":"Stable Diffusion"},{"content":" 📝 Как это работает?\nПриватный ключ хранится у вас (пользователя). А публичный ключ хранится на удаленной машине.\nТо есть, чтобы подключиться к удаленной машине, на ней должен быть публичный ключ, а у вас соответствующий приватный ключ.\nТакже вы можете использовать один и тот же публичный ключ на множестве машин, чтобы подключаться к ним, используя один и тот же приватный ключ. Нужно создать ключ, командой на локальной машине:\n1 ssh-keygen Вас попросит ввести имя ключа.\nЖелательно генерировать ключ со стандартным именем, то есть не давать ему названия (обычно это id_rsa).\nДалее нужно придумать кодовую фразу. Если ее не вводить, вход будет полностью без пароля (не рекомендую).\nВывод:\nGenerating public/private rsa key pair. ... Your identification has been saved in /.ssh/id_rsa Your public key has been saved in /.ssh/id_rsa.pub The key fingerprint is: SHA256:*** ***@*** The key\u0026#39;s randomart image is: +---[RSA 3072]----+ | *************** | +----[SHA256]-----+ Далее нужно скопировать ключ из .pub в authorized_keys, который находится на удаленной машине.\n1 2 3 4 5 # На локальной машине scp ~/.ssh/id_rsa.pub root@ip:/dir/to/.ssh # Скопировать ключ на сервер через SCP # На хосте cat ~/.ssh/id_rsa_pub \u0026gt;\u0026gt; ~/.ssh/authorized_keys # Записать ключ в authorized_keys Либо можете просто открыть .pub скопировать ключ, и вставить его в authorized_keys, через любой текстовый редактор, или просто через sftp.\nЧто получается? Локальная машина:\n1 2 3 ls .ssh id_rsa id_rsa.pub Удаленная машина:\n1 2 3 4 5 ls .ssh authorized_keys cat .ssh/authorized_keys ssh-rsa # много много букв Если вы все сделали правильно, то при следующем подключение у вас либо спросит кодовую фразу, либо произойдет подключение, если вы не указывали кодовую фразу.\nТак же публичный ключ (.pub) можно использовать и на другой машине, для этого его так же нужно будет скопировать в authorized_keys.\n‎ ","permalink":"https://hv8.pages.dev/blog/ssh-bez-parolia/","summary":"Как создать SSH ключ.","title":"SSH без пароля"},{"content":"WIM и ESD ESD это зашифрованный и сжатый формат данных, его нельзя монтировать, изменять и тп. В отличии от WIM.\nТо есть если вы собираетесь модить старую ось, вам понадобится утилита для конвертации esd \u0026gt; wim. Так как старые версии Windows не в wim, а в esd.\nWIM так же удобен если вы модифицируете и поддерживаете свою сборку.\nСистема может аналогично esd установится и из wim. Образ будет занимать больше места, но это удобнее.\nВ файле install.wim\\esd по сути находится система. Все настройки, которые мы видим и которые скрыты, находятся в реестре системы. А файлы реестра находятся в файлах системы.\nЭто означает что все внесенные в систему изменения, после упаковки системы в install.wim останутся.\nИ кншн же про варез офиса не забудем, весь софт установленный на системный диск в тч. с кастомными директориями (путями) - войдет в сборку.\nГде делать сборку? Для создания сборки вам понадобится виртуальная машина или просто машина. Можно использовать любую программу для создания виртуальных машин.\nВозможно не стоит использовать Hyper-V Но, возможно не стоит использовать Hyper-V, тот что встроен в Windows. Hyper-V так идеально работает на системах Windows с установленной системой Windows, потому что обращается к железкам через мейн систему избегая установки драйверов на виртуалку.\nЭто сугубо мое мнение, я это не проверял и не тестировал. Но есть вероятность, что сборка сделанная на Hyper-V будет \u0026ldquo;неполноценной\u0026rdquo;. Вероятность этого такая же, как и вероятность того что сборка сделанная на Hyper-V будет лучше.\nЯ советую использовать Oracle VirtualBox, тк там система будет тянуть минимум не нужного хлама для сборки. Этот \u0026ldquo;хлам\u0026rdquo; очень нужен для наилучшего экспириенса пользователей виртуалки, а не для юзеров что пользуются сборкой сделанной на виртуалке. Таким образом система которую вы будите паковать будет максимально чистая, насколько это возможно.\nНо вам никто не запрещает делать сборку где вы хотите, например на VMware Workstation.\nТак же какую бы вы программу не выбрали, не устанавливайте доп. ПО для виртуалки. Речь идет о разных расширениях, которые позволяют использовать общий буфер обмена и с легкостью передавать файлы между хостом и гостем.\nВместо этого, передавайте файлы используя флешку или внешний диск. Почему? Это все устанавливается в систему, и мусорит ее. Опять же, для юзеров виртуалки - круто, для юзеров сборки - не круто.\nНеобходимое ПО Так же понадобится:\n7-Zip - чтобы распаковать образ. Dism++ - чтобы создать файл install.wim. WinAIO Maker Professional - чтобы создать загрузочный образ (iso). Препарируем образ (Хост) У вас должен быть образ Windows. Распаковываем iso файл с помощью 7z. Распакованные файлы пока что не трогаем.\nДалее создаем виртуальную машину и устанавливаем на нее Windows, как обычно.\n📝 Пользователь созданный при установки Windows сохранится. Поэтому стоит делать пользователя без пароля. Создание install.wim (Гость) Вот вы все настроили, все установили. Ваша сборка готова.\nЗапускаем Dism++ \u0026gt; \u0026ldquo;Файл\u0026rdquo; \u0026gt; \u0026ldquo;Сохранить образ как\u0026rdquo;. Сохраните его например на рабочий стол. После того как он создастся, кидаем его на флешку.\nПодготовка к созданию install.wim Процесс создания install.wim Создание образа (Хост) Вы скопировали install.wim на флешку. Кидаем install.wim в папку с распакованными файлами образа \u0026gt; /sources/. Соглашаемся на замену.\nОткрываем WinAIO Maker. Выбираем \u0026ldquo;Select WIMs\u0026rdquo;. Далее выбираем модифицированный install.wim из папки sources.\nНажимаем \u0026ldquo;Save all into ISO\u0026rdquo;. В \u0026ldquo;Label\u0026rdquo; вводим что-то, в \u0026ldquo;Destination\u0026rdquo; - указываем путь куда сохранить. И жмем \u0026ldquo;Make ISO\u0026rdquo;.\nОжидаем создания образа, обычно это недолго.\nВсе готово, чтобы проверить как работает, можно создать новую виртуальную машину с образом вашей сборки.\n","permalink":"https://hv8.pages.dev/blog/delaem-svoiu-sborku-windows/","summary":"Всегда хотелось сделать сборку как у васи 777? Я покажу как.","title":"Делаем свою сборку Windows"},{"content":" 1 2 3 4 5 6 7 8 9 10 11 diskpart # Запустить diskpart lis dis # list disk # Список дисков sel dis $ # select disk # Выбираем накопитель ($ = цифра, счет начинается с 0) det dis # detail disk # Информация о диске. Убедиться что это тот самый диск. clean # Очищаем cre par pri # create partition primary # Создаём раздел sel par 1 # select partition # Выбираем раздел (счет начинается с 1) active # Делаем раздел активным. Если выдаст ошибку, пропускаем и идем дальше. format fs=$ quick # Форматируем в файловую систему например: fat32, ntfs, опционально label=«name» - имя накопителя. Quick - быстрое форматирование. assign # Назначаем букву, чтобы накопитель появился в проводнике. exit # Выход из diskpart Подробнее об активных разделах.\n","permalink":"https://hv8.pages.dev/blog/udalenie-razdelov-nakopitelia/","summary":"Как удалить разделы флешки, диска, etc.","title":"Удаление разделов накопителя. Windows"}]