Bash-скрипты, которые настраивают чистую Debian 12/13 под VPS, хост AmneziaVPN, мини-ПК Intel N5095 и WSL2 и обновляют Debian 11/12 до 13. Каждый скрипт — один файл: его запускают от root на целевой машине одной командой, а что именно он меняет, описано в руководстве.
Какой скрипт выбрать · Быстрый старт · Как работает скрипт · Возможности · Безопасность · Версии и выпуски · Документация · Решение частых проблем · Участие в разработке · Лицензия
| Скрипт | Для чего | Debian | Версия скрипта | Руководство |
|---|---|---|---|---|
optimize_vps.sh |
VPN-сервер на VPS с 1–4 GB RAM: ядро Debian Backports, sysctl под 10 Гбит/с, Fish + Starship, Go, Node.js/fnm, Docker, закалка SSH, Fail2Ban, UFW | 12, 13 | 3.0.0 | руководство |
optimize_amnezia_host.sh |
Хост под AmneziaVPN self-hosted: только база для приложения Amnezia, параметры флагами, firewall в две фазы | 12, 13 | 0.3.0 | руководство |
optimize_mini_pc.sh |
Домашний и медиасервер на Intel N5095: ядро Debian Backports, Intel QuickSync, Samba, Docker, Fish + Starship | 12, 13 | 2.0.0 | руководство |
optimize_wsl2.sh |
WSL2 для разработки и ML: systemd в wsl.conf, Fish + Starship, Go, Node.js/fnm, Docker, NVIDIA Container Toolkit и CUDA |
12, 13 | 4.1.0 | руководство |
upgrade-to-debian13.sh |
Обновление серверной Debian до 13 с бэкапом и проверкой SSH после каждого шага; не для WSL2 | 11, 12 | 2.0.3 | руководство |
Версия скрипта — значение SCRIPT_VERSION в его коде; bash <скрипт> --help печатает ее без root. Четыре optimize_*.sh при запуске проверяют версию Debian и на любой другой завершаются сразу.
Все optimize_*.sh при настройке локалей генерируют en_US.UTF-8 и ru_RU.UTF-8, чтобы SSH-сессии с английским или русским окружением работали без предупреждений setlocale. Amnezia-профиль делает это автоматически, сохраняя системный язык; в Mini PC и WSL2 шаг можно отключить. Выбор языка в VPS, Mini PC и WSL2 задает значение по умолчанию через update-locale, без постоянного LC_ALL. Для уже настроенного сервера см. исправление ошибки локали.
Warning
Скрипты меняют ядро, пользователей, sudoers, SSH, firewall и sysctl. Запускайте их только на целевой машине от root; на рабочей станции не запускайте ни от root, ни через sudo. Перед запуском сделайте снимок VM или бэкап. bash <скрипт> --help печатает справку без root и ничего не меняет.
Команды ниже запускают текущую версию из main. curl -fsSL останавливается на ошибке HTTP, а шаги optimize_vps.sh, optimize_mini_pc.sh и optimize_wsl2.sh начинаются только после того, как скрипт загружен целиком: оборванная загрузка ничего не меняет.
Tip
Чтобы запустить закрепленный выпуск, замените в адресе main на его тег (см. Версии и выпуски).
# Быстрый запуск (bash + curl)
bash <(curl -fsSL https://raw.githubusercontent.com/snaplyze/optimize-debian/main/optimize_vps.sh)
# Или скачайте и запустите
wget https://raw.githubusercontent.com/snaplyze/optimize-debian/main/optimize_vps.sh
chmod +x optimize_vps.sh
sudo ./optimize_vps.sh# Целевой пользователь: без --user это пользователь, запустивший sudo (SUDO_USER);
# от root без sudo --user обязателен (root как целевой пользователь не допускается).
# Задайте имя оператора один раз (замените ops на свое):
OPERATOR=ops
# Быстрый запуск (bash + curl, под root)
bash <(curl -fsSL https://raw.githubusercontent.com/snaplyze/optimize-debian/main/optimize_amnezia_host.sh) --user "$OPERATOR" --yes
# Или скачайте и запустите минимальный host baseline
wget https://raw.githubusercontent.com/snaplyze/optimize-debian/main/optimize_amnezia_host.sh
chmod +x optimize_amnezia_host.sh
# Рекомендуемый путь: подготовить host и сразу поставить vanilla Docker CE
sudo ./optimize_amnezia_host.sh --yes
# Если пользователя нет, его можно создать сразу
sudo ./optimize_amnezia_host.sh --user "$OPERATOR" --create-user \
--ssh-public-key 'ssh-ed25519 AAAA... your-key' --yes
# Если swap уже настроен отдельно, можно пропустить его создание
sudo ./optimize_amnezia_host.sh --skip-swap --yes
# Альтернатива: оставить установку Docker самому приложению Amnezia
sudo ./optimize_amnezia_host.sh --skip-docker --yes
# После того как AmneziaWG закреплен на 8443/udp, можно ужесточить firewall
sudo ./optimize_amnezia_host.sh --firewall-phase locked --yes# Быстрый запуск (bash + curl)
bash <(curl -fsSL https://raw.githubusercontent.com/snaplyze/optimize-debian/main/optimize_mini_pc.sh)
# Или скачайте и запустите
wget https://raw.githubusercontent.com/snaplyze/optimize-debian/main/optimize_mini_pc.sh
chmod +x optimize_mini_pc.sh
sudo ./optimize_mini_pc.sh# Только Debian 12 или Debian 13 под WSL2
# Подготовка в Windows PowerShell
wsl --update
wsl --set-default-version 2
# Быстрый запуск (bash + curl)
bash <(curl -fsSL https://raw.githubusercontent.com/snaplyze/optimize-debian/main/optimize_wsl2.sh)
# Или скачайте и запустите в WSL2
wget https://raw.githubusercontent.com/snaplyze/optimize-debian/main/optimize_wsl2.sh
chmod +x optimize_wsl2.sh
sudo ./optimize_wsl2.sh# Быстрый запуск (bash + curl)
bash <(curl -fsSL https://raw.githubusercontent.com/snaplyze/optimize-debian/main/upgrade-to-debian13.sh)
# Или скачайте и запустите интерактивный апгрейд
wget https://raw.githubusercontent.com/snaplyze/optimize-debian/main/upgrade-to-debian13.sh
chmod +x upgrade-to-debian13.sh
sudo ./upgrade-to-debian13.sh
# Или без интерактивных подтверждений.
# Для Debian 11 скрипт остановится после 11 -> 12, чтобы дать сделать reboot.
sudo ./upgrade-to-debian13.sh --yes
# Только для лабораторных стендов: разрешить 11 -> 12 -> 13 без промежуточного reboot
sudo ./upgrade-to-debian13.sh --yes --allow-two-hop-no-rebootflowchart TD
A["Загрузка целиком,<br>затем optimize_main"] --> C["Проверка: root,<br>Debian 12/13"]
C -->|иначе| X["Выход без изменений"]
C --> D["Меню компонентов"]
D --> E["Шаги: пользователь,<br>Fish, ядро, Docker,<br>sysctl, UFW, SSH"]
E --> F["Проверки шага:<br>sshd -t, sshd -T,<br>visudo -cf, SHA-256"]
F -->|расхождение| R["Откат шага"]
F -->|сошлось| G["Итог, лог,<br>предложение reboot"]
Так работают optimize_mini_pc.sh и optimize_wsl2.sh (WSL2 дополнительно проверяет, что это WSL; ядра, swap, UFW, Fail2Ban и закалки SSH у него нет — какие шаги есть у каждого скрипта, см. Возможности). optimize_vps.sh меню компонентов не показывает: он спрашивает имя пользователя, ключ SSH, имя хоста, локаль и часовой пояс, ждет Enter после проверки входа по SSH, остальные шаги идут все. optimize_amnezia_host.sh берет параметры из флагов, подтверждает запуск (без --yes) и выполняет один фиксированный проход main. upgrade-to-debian13.sh идет своим маршрутом: проверки, бэкап в /root/upgrade-backup-<TS>/, шаги 11 -> 12 и 12 -> 13 с проверкой sshd -t и портов SSH после каждого, лог в /var/log/debian-upgrade/.
TUI: основной backend — Charmbracelet gum; если его нет, он скачивается с проверкой SHA-256, а при неудаче используется plain Bash prompt. dialog и whiptail не выбираются автоматически и доступны только через явный TUI_BACKEND=dialog|whiptail.
| Возможность | VPS | Amnezia | Mini PC | WSL2 |
|---|---|---|---|---|
| Ядро Debian Backports на Debian 12 | ✅ | ✅ --kernel-backports |
✅ | — |
Fish + Starship (nerd-font-symbols), /bin/bash остается login shell |
✅ | ✅ | ✅ | ✅ |
sysctl: BBR + fq, Loose rp_filter = 2 |
✅ | ✅ | ✅ | ✅ |
Буферы rmem_max/wmem_max |
до 64 MB | 32–64 MB | 32 MB | 64 MB |
| Docker CE + Compose plugin | ✅ | ✅ vanilla | ✅ | ✅ |
Закалка SSH: drop-in 00-*.conf, проверка sshd -T |
✅ | ✅ | ✅ | — |
Fail2Ban (backend = systemd, python3-systemd) |
✅ | ✅ | ✅ | — |
| UFW | ✅ | ✅ две фазы | ✅ | — |
UFW: DEFAULT_FORWARD_POLICY="ACCEPT" для VPN |
✅ | ✅ | — | — |
| Swap-файл | по RAM | 2 GB | 4 GB при 12 GB+ RAM | — |
Синхронизация времени (существующий NTP или systemd-timesyncd) |
✅ | ✅ | ✅ | — |
Локали en_US.UTF-8 + ru_RU.UTF-8 |
✅ | ✅ | ✅ | ✅ |
Автообновления безопасности (unattended-upgrades) |
✅ | — | ✅ | ✅ |
CPU governor schedutil |
✅ | — | ✅ | — |
| Go (закрепленная версия, SHA-256) | ✅ | — | ✅ | ✅ |
| Node.js LTS через fnm | ✅ | — | ✅ | ✅ |
NVIDIA Container Toolkit + CUDA (cuda-keyring) |
— | — | — | ✅ |
Intel QuickSync (intel-media-va-driver-non-free, vainfo) |
— | — | ✅ | — |
Samba (server min protocol = SMB2) |
— | — | ✅ по выбору | — |
| Служебные скрипты (monitor, cleanup; info — VPS и Mini PC, backup — WSL2) | ✅ | — | ✅ | ✅ |
Что ставит и настраивает каждый шаг, какие файлы пишет и как это откатить — в руководствах из раздела Документация.
- Закалка SSH пишется в drop-in
/etc/ssh/sshd_config.d/00-*.conf: sshd берет первое прочитанное значение, поэтому50-cloud-init.confсPasswordAuthentication yesее не отменяет. Послеsshd -tдействующие значения сверяются черезsshd -T; при расхождении drop-in снимается и sshd не перезапускается. - Файлы
/etc/sudoers.d/*пишутся через временный файл с проверкойvisudo -cf; при ошибке прежний файл остается без изменений. - Starship 1.27.0 (на Debian 13 — пакет
starshipиз Debian), fnm 1.39.0, Go 1.27.3, gum 0.17.0 иcuda-keyring1.1-1 закреплены по версии и SHA-256, записанной в скрипте; при несовпадении установка отклоняется. Исключение — Node.js: текущий LTS ставит fnm с nodejs.org по HTTPS, версия и сумма в репозитории не закреплены. - Ключи репозиториев Docker и NVIDIA Container Toolkit принимаются только с закрепленным отпечатком основного ключа.
- Загрузки идут только по HTTPS (и при редиректах): каждая попытка — не дольше 15 минут (gum — 5), повторы начинаются только в пределах этого же времени, так что загрузка завершается не позже чем примерно через 30 минут (gum — 10). Временные файлы — в уникальных каталогах
mktemp -d, которые удаляются после установки, при ошибке и при выходе скрипта, в том числе по сигналу. upgrade-to-debian13.shсохраняет/etc/ssh,authorized_keysи состояние firewall в/root/upgrade-backup-<TS>/, защищает пакеты удаленного доступа отautoremoveи после каждого шага проверяетsshdи прослушивание прежних портов.
Об уязвимости сообщайте приватно, как описано в SECURITY.md, а не через публичный issue.
main— текущая версия. В него попадают только PR, прошедшие проверкуchecks, и команды этого README запускают именно его.- Выпуск — снимок всех скриптов с тегом
vГГГГ.ММ.ДД(второй выпуск за день —vГГГГ.ММ.ДД.1) и списком изменений на странице Releases. Выпуски неизменяемы, а тегиv*нельзя перенести или удалить, поэтому команда с тегом всегда запускает один и тот же код. - Если версия из
mainповела себя не так, запустите предыдущий выпуск: заменитеmainв адресе на его тег.
TAG=v2026.10.21.1 # последний выпуск: https://github.com/snaplyze/optimize-debian/releases/latest
bash <(curl -fsSL "https://raw.githubusercontent.com/snaplyze/optimize-debian/$TAG/optimize_vps.sh")Версии в заголовках скриптов (например, WSL2 4.1.0) относятся к отдельному скрипту, а тег выпуска — ко всему репозиторию. История изменений — в CHANGELOG.md.
# Текущая версия из main; чтобы скачать выпуск, замените main на его тег
curl -fsSLO https://raw.githubusercontent.com/snaplyze/optimize-debian/main/optimize_amnezia_host.sh
curl -fsSLO https://raw.githubusercontent.com/snaplyze/optimize-debian/main/optimize_vps.sh
curl -fsSLO https://raw.githubusercontent.com/snaplyze/optimize-debian/main/optimize_mini_pc.sh
curl -fsSLO https://raw.githubusercontent.com/snaplyze/optimize-debian/main/optimize_wsl2.sh
curl -fsSLO https://raw.githubusercontent.com/snaplyze/optimize-debian/main/upgrade-to-debian13.sh- docs/README.md — оглавление документации.
- docs/README_VPS.md — VPS:
optimize_vps.sh. - docs/README_AMNEZIA_HOST.md — хост AmneziaVPN:
optimize_amnezia_host.sh. - docs/README_MINI_PC.md — мини-ПК Intel N5095:
optimize_mini_pc.sh. - docs/README_WSL2.md — WSL2:
optimize_wsl2.sh. - docs/README_UPGRADE.md — обновление Debian 11/12 до 13:
upgrade-to-debian13.sh. - docs/ARCHITECTURE.md — устройство репозитория: встроенные копии
lib/,optimize_main, тесты, CI, выпуски. - CHANGELOG.md — выпуски и история версий скриптов.
Ошибка терминала VSCode Remote: __vsc_update_env
При использовании VSCode Remote (WSL/SSH/Tunnels) может появиться ошибка:
__vsc_update_env:6: key: attempt to set associative array to scalar
Скрипты решают это сами: переход на Fish shell и чистый .bashrc устраняет конфликты __vsc_update_env. Если ошибка осталась, закройте все старые терминалы в VSCode и откройте новый (Ctrl + ~).
npm EACCES при установке глобальных пакетов
Скрипты ставят fnm в каталог пользователя, поэтому права доступа остаются корректными. Реализация рассчитана на чистую ОС и не переносит уже существующие конфигурации NVM.
Ручное исправление, если нужно:
sudo chown -R $(whoami):$(whoami) ~/.npm
sudo chown -R $(whoami):$(whoami) ~/.local/share/fnm
sudo chown -R $(whoami):$(whoami) ~/.configWSL2: CUDA, contrib и вывод сведений о системе
optimize_wsl2.sh работает только на Debian 12 и 13 под WSL2. Путь репозитория CUDA выбирается по VERSION_ID: debian12 или debian13. Пакет cuda-keyring ставится официальным методом NVIDIA, а его SHA-256 сверяется с суммой, закрепленной в скрипте; широкий метапакет cuda в WSL не используется. Go и Node.js/fnm включаются отдельными пунктами меню; apt-transport-https не требуется.
Что делает скрипт для CUDA, по шагам:
# Включение contrib (обязательно для Debian)
add-apt-repository contrib
# Установка keyring пакета (рекомендовано NVIDIA); скрипт сверяет его SHA-256
# с суммой, закрепленной для debian12 или debian13, и только затем устанавливает
curl -fsSL -o cuda-keyring_1.1-1_all.deb https://developer.download.nvidia.com/compute/cuda/repos/debian${VERSION_ID}/x86_64/cuda-keyring_1.1-1_all.deb
dpkg -i cuda-keyring_1.1-1_all.deb
# Установка CUDA
apt update
apt install cuda-toolkitСведения о системе: скрипт сначала пытается использовать fastfetch, затем neofetch, а если ни один пакет недоступен — пропускает этот шаг без ошибки. fastfetch предпочтителен: написан на C, активно поддерживается, гибче настраивается и официально доступен в Debian 13.
Обновление до Debian 13 на облачной VM
upgrade-to-debian13.sh не переписывает настройку сети под конкретный cloud image. Ошибки вида networking.service failed после перезагрузки могут быть особенностью образа или VM, а не самого обновления; разбор идет на уровне VM (serial console, восстановление из /root/upgrade-backup-*). Подробнее — в docs/README_UPGRADE.md.
Вопросы и ошибки — через issues, уязвимости — по SECURITY.md. Правила изменений, коммитов и PR — в CONTRIBUTING.md, устройство репозитория — в docs/ARCHITECTURE.md. Проверка перед PR, из корня репозитория и не от root:
for f in *.sh lib/*.sh tests/*.sh; do bash -n "$f" || echo "FAIL: $f"; done
shellcheck -- *.sh lib/*.sh tests/*.sh
for test in tests/*.sh; do bash "$test" || echo "FAIL: $test"; donebash -n проверяет только первый переданный файл, поэтому синтаксис проверяется по одному файлу. Те же проверки выполняет CI (.github/workflows/ci.yml) на self-hosted раннере для push в main и PR владельца из этого же репозитория; для других источников проверка checks падает на GitHub-hosted раннере, не исполняя их код. Запуски из форков требуют одобрения владельца — не одобряйте их: PR из форка исполняет свой вариант workflow. Вклад из форка владелец проверяет, перенеся его в ветку этого репозитория.
Каждый optimize_*.sh работает одним файлом: lib/common.sh и lib/tui.sh подключаются, только если лежат рядом, иначе работают встроенные копии нужных функций. Изменение функции в lib/ повторяется в копиях каждого скрипта; совпадение проверяет tests/test_embedded_copies.sh.
MIT, см. LICENSE.