RISH 2.9.0: зашифрованные бэкапы, Composer и Laravel
«Вы просили нас добавить шифрование бэкапов и архивов в RISH? Нет? А мы добавили!»
В прошлой версии мы укрепляли сервер изнутри. Теперь защищаем то, что неизбежно покидает его пределы.

В RISH 2.8.0 мы усилили защиту внутри сервера: изолировали сайты разных пользователей, ограничили возможности PHP-FPM, забрали управление CRON, SFTP-ключами и служебными учётными данными из-под контроля процессов сайта. Тот релиз отвечал на вопрос: что произойдёт, если один сайт взломан и через него попытаются добраться до соседних сайтов или закрепиться на сервере?
RISH 2.9.0 продолжает эту работу, но переносит границу защиты дальше. Теперь вопрос звучит иначе: что произойдёт с данными после того, как резервная копия покинет сервер?
Хранить бэкап отдельно от рабочего сервера — правильно. Иначе поломка диска, потеря сервера или серьёзная компрометация могут уничтожить одновременно и сайт, и копию. Поэтому RISH отправляет архивы через rclone в S3, WebDAV, Яндекс Диск, SFTP и другие внешние хранилища.
Но права Linux, отдельные PHP-FPM pools, ограничения SFTP и защита CRON не уезжают в облако вместе с архивом. С этого момента доступ к копии зависит от другого аккаунта, другого сервиса, API-токена, подключённых компьютеров и людей, которые когда-либо скачивали файл.
В версии 2.9.0 появляется возможность шифровать архив до передачи на внешнее хранилище. Внешнее хранилище получает уже закрытые данные, а одного доступа к облаку недостаточно, чтобы получить файлы сайта и содержимое базы. Для расшифрования нужен приватный ключ, который следует хранить отдельно от сервера и хранилища.
Кроме шифрования, в релиз вошли управление Composer 2 для отдельных сайтов и операции обслуживания Laravel: безопасная генерация APP_KEY и запуск миграций.
Защита сервера заканчивается там, где начинается внешний бэкап
За пределами сервера мы уже не контролируем всю цепочку. Можно выбрать надёжного провайдера, включить двухфакторную авторизацию, ограничить права API-токена и внимательно настроить доступы. Всё это необходимо, но не делает утечку невозможной.
Аккаунт хранилища могут взломать, а токен может попасть в чужие руки. Архив могут скачать на компьютер и забыть в каталоге загрузок, скопировать на старый диск или передать специалисту, который давно не работает с проектом. Наконец, ошибка или инцидент могут произойти на стороне самого внешнего сервиса.
Шифрование меняет требования к этой цепочке. Облако по-прежнему должно защищать аккаунт и файлы, но ему больше не приходится быть единственной преградой между посторонним и содержимым базы. Даже получив архив, нужно отдельно получить подходящий приватный ключ.
Это не защита от всего. Тот, кто получил полный доступ к хранилищу, может удалить зашифрованные копии, поэтому нужны история версий, несколько мест хранения и контроль успешности бэкапов. Шифрование решает другую задачу: не позволяет прочитать украденную копию. Безопасность хранения и шифрование дополняют друг друга, а не заменяют.
152-ФЗ: бэкап это персональные данные
После выгрузки в облако база клиентов не перестаёт содержать персональные данные. Меняется место хранения, но не характер информации и не обязанность её защищать.
Согласно статье 19 закона «О персональных данных», оператор должен принимать необходимые правовые, организационные и технические меры для защиты персональных данных от неправомерного или случайного доступа, уничтожения, изменения, блокирования, копирования, предоставления, распространения и других неправомерных действий.
Шифрование резервных копий — одна из технических мер в таком комплексе. Оно не заменяет разграничение доступа, журналирование, обновления, регламенты и защиту учётных записей. Но если архив неправомерно скопировали из облака, с внешнего диска или с компьютера вебмастера, шифрование препятствует превращению самого факта копирования в утечку читаемых данных.
Поэтому смысл новой функции не в формальной галочке около 152-ФЗ. Мы уменьшаем последствия ситуации, которую нельзя исключить полностью: файл оказался не у того человека, но содержащиеся в нём данные остались закрыты.
Как RISH шифрует резервные копии
Для шифрования RISH использует утилиту age. На сервере хранится только публичный ключ: с его помощью можно создавать зашифрованные копии, но нельзя их открыть. Приватный ключ остаётся у владельца и понадобится только при восстановлении.
Шифрование выполняется потоком. Для файлов сайта цепочка выглядит так:
файлы → tar + gzip → age → части архива → облако
Для базы данных:
MariaDB → dump → gzip → age → части архива → облако
Полный открытый архив рядом не создаётся. В хранилище отправляются уже зашифрованные данные, а имена файлов получают окончание .age: например, .tar.gz.age или .sql.gz.age.
Что именно теперь можно зашифровать
Шифрование встроено и в автоматическое резервное копирование через backup2.sh, и в ручное создание архивов из меню Midnight Commander.
Во время установки и обновления RISH пытается установить age как необязательный пакет. Если пакет недоступен в используемых репозиториях, остальные шаги продолжаются, но действия с шифрованием не показываются. После установки age настройку можно продолжить.
Зашифровать можно:
- сайт вместе с его базой данных;
- только файлы сайта или обычную папку;
- только базу данных;
- папку с выбранными исключениями;
- отдельный файл.
Настройка привязана к объекту из списка резервного копирования. Если для сайта назначены ключи, ручное меню показывает рядом с обычными действиями варианты с пометкой (шифр). Администратор по-прежнему может создать и незашифрованный архив, когда он действительно нужен.
Один набор публичных ключей можно назначить отдельному объекту, всем объектам пользователя или всем включённым объектам сервера. Его также можно скопировать с уже настроенного сайта. Так один проверенный набор применяется ко всем нужным копиям без повторного ввода ключей и без отдельного приватного файла для каждого проекта.
Один архив — два владельца ключа
Для каждого объекта можно указать до двух публичных ключей: основной и запасной. Это два независимых получателя, а не две части одного секрета и не пороговая схема «2 из 2». Для восстановления достаточно любого из соответствующих приватных ключей, если его публичный ключ был назначен в момент создания копии.
Один ключ может храниться у владельца сайта, второй — у вебмастера или системного администратора. Владелец не зависит от доступности подрядчика, а вебмастер может начать аварийное восстановление, не разыскивая владельца и его ключ.
Та же схема помогает при плановой ротации: сначала новый ключ добавляется как запасной, затем создаётся и проверяется свежий бэкап, и только после этого старый ключ убирается из настройки будущих копий.
Уже созданные архивы при изменении списка получателей не перешифровываются. Если копия была создана до добавления второго ключа, открыть её новым ключом нельзя.
Слишком сложно? Включите шифрование одной кнопкой
Если всё сказанное про отдельные ключи пока кажется слишком сложным — не откладывайте шифрование. RISH позволяет включить его буквально одной кнопкой, используя SSH-ключ, с которым вы уже входите на сервер.
Ничего нового создавать, скачивать и пристраивать на хранение не нужно. Публичная часть ключа уже находится в /root/.ssh/authorized_keys, а приватная — на вашем компьютере. RISH покажет подходящие ключи ssh-ed25519 и ssh-rsa: выбираете нужный, и следующие резервные копии отправляются в облако уже зашифрованными. Мы специально предусмотрели этот вариант для тех, кому нужна защита прямо сейчас, без предварительного погружения в криптографию.
Но простота запуска не отменяет ответственности за ключ. Теперь он нужен не только для входа на сервер, но и для расшифрования резервных копий. Если позднее вы замените SSH-ключ и удалите его старую приватную часть, новый ключ позволит войти на сервер, но не откроет прежние архивы. Более того, RISH продолжит шифровать новые копии на сохранённый старый публичный ключ, пока вы явно не измените настройку. Поэтому при замене SSH-ключа сначала обновите ключ шифрования, создайте и проверьте новый бэкап — и только потом удаляйте старый приватный ключ. Если доступ к серверу и резервным копиям должны контролировать разные люди, лучше создать отдельный ключ age.
Где начинается боль: ключи нельзя терять
У хорошего шифрования есть неприятное, но честное свойство: кнопки «мы тут забыли пароль, откройте как-нибудь» у него нет.
При создании отдельного ключа age RISH просит защитить приватную часть паролем. Затем предлагает скопировать защищённый ключ через буфер обмена или временно сохранить его в /root для скачивания. Перед включением шифрования программа создаёт тестовые данные, шифрует их и просит открыть сохранённым ключом. Настройка применяется только после успешной проверки.
RISH не хранит пароль и не держит приватный ключ в настройках бэкапа. Файл, оставленный в /root, нужно скачать, проверить и удалить с сервера. Команда rish check отдельно предупреждает о защищённых ключах age и приватных SSH-ключах, забытых в /root.
Новый ключ используется только для будущих бэкапов. Старые архивы остаются зашифрованными на тот набор, который действовал в момент их создания. Поэтому старый приватный ключ нельзя удалять, пока соответствующие копии не вышли из срока хранения.
С SSH-ключами легко пропустить эту зависимость: заменить ключ доступа к серверу и удалить старую приватную часть. Вход по SSH заработает с новым ключом, но старые бэкапы на него не переключатся. Более того, RISH продолжит шифровать новые копии на сохранённый старый публичный ключ, пока его явно не заменят в настройках.
Приватный ключ следует хранить минимум в двух защищённых местах, пароль — отдельно, а перед удалением или ротацией проверять восстановление. Если приватный ключ утрачен, данные потеряны для всех — в том числе для законного владельца архива.
Как восстанавливаются зашифрованные копии
Меню восстановления понимает новые расширения, собирает части архива после скачивания и, если у сайта есть отдельный дамп базы, загружает пару файлов вместе.
Приватный ключ можно выбрать из файлов в /root либо вставить из буфера обмена. Поддерживаются защищённый ключ age и приватный SSH-ключ. Если ключ защищён паролем, RISH запрашивает его один раз для всей операции, а не отдельно для архива сайта и базы данных.
Дальше доступны два варианта:
- сразу проверить и восстановить содержимое без создания рядом обычного расшифрованного архива;
- расшифровать копию в привычный
.tar.gz,.sql.gzили.gzдля самостоятельной работы.
Перед изменением файлов сайта или базы RISH проверяет формат архива и соответствие приватного ключа. Если ключ не подходит, архив повреждён или пара файлов не прошла проверку, восстановление останавливается до внесения изменений.
Что означают .end и [ok]
Большой бэкап разбивается на части. Таких файлов может быть много, и наличие первых десяти частей ещё не означает, что в облако попал весь архив.
В RISH 2.9.0 завершающая часть получает отметку .end. Сначала программа переносит в облако все обычные части и только после их успешной передачи отдельно загружает последнюю часть с этой отметкой. Поэтому .end служит признаком того, что передача дошла до конца и в хранилище находится полный комплект частей архива.
В меню восстановления такие снимки получают понятную отметку [ok]. Незавершённую загрузку теперь проще отличить от полноценной копии ещё до скачивания.
Это проверка комплектности и завершённости передачи, а не криптографическая контрольная сумма каждого байта. Старые бэкапы, созданные до появления .end, не объявляются испорченными и остаются доступными: RISH сохраняет совместимость с прежней схемой хранения.
Composer теперь живёт в меню RISH
Установить Composer на сервер несложно. Сложнее каждый раз запускать его в правильном каталоге, с PHP-версией конкретного сайта и с правами его владельца — особенно когда на одном сервере работают проекты разных пользователей и на разных версиях PHP.
Эту часть RISH 2.9.0 берёт на себя. Управление Composer включается отдельно в разделе управления сервером. Оттуда можно установить актуальную ветку Composer 2, проверить версию, переустановить бинарник, отключить интеграцию или удалить сам Composer, не затрагивая composer.json, composer.lock и vendor внутри проектов.
RISH скачивает официальный установщик и до запуска сверяет его контрольную сумму SHA-384. Готовый файл размещается в /usr/local/bin/composer с владельцем root и безопасными правами. Существующий файл, ссылка или объект с небезопасными владельцем и правами автоматически не заменяются.
После включения в меню Midnight Commander появляется пункт «Composer для сайта». RISH проверяет выбранную папку, DocumentRoot, владельца, версию PHP и наличие composer.json. Для Composer 2 требуется PHP 7.2.5 или новее; для сайта на более старой версии сначала придётся сменить PHP.
В меню проекта доступны:
- информация и диагностика Composer;
- проверка
composer.jsonиcomposer.lock; - установка зависимостей;
- обновление зависимостей и lock-файла там, где это разрешено;
- пересборка autoload;
- проверка устаревших прямых зависимостей.
Все команды выполняются от системного пользователя сайта и в очищенном окружении. Это принципиально: Composer plugins и scripts проекта могут исполнять код. Для работы с зависимостями сайту не нужны права root.
Local и production ведут себя по-разному
Набор действий зависит от режима сервера. Разработка и production решают разные задачи, поэтому одинаковое меню для них было бы опасным упрощением.
На локальном сервере Composer может подобрать версии зависимостей, создать composer.lock, установить dev-зависимости и выполнить composer update. Изменённый lock-файл затем проверяется и попадает в систему контроля версий вместе с проектом.
На production установка доступна только при наличии готового composer.lock. Dev-зависимости исключаются, autoload оптимизируется, а действия, способные подобрать новые версии пакетов или переписать lock-файл, не предлагаются.
Таким образом, боевой сервер устанавливает заранее зафиксированный набор зависимостей, а не формирует его заново во время развёртывания.
Laravel: APP_KEY и миграции без ручной сборки команд
Если в Composer-проекте найден обычный файл artisan, RISH определяет Laravel и проверяет, установлены ли зависимости, найден ли .env и задан ли APP_KEY.
Предложение сгенерировать ключ появляется только при точной пустой строке:
APP_KEY=
Существующий ключ RISH не перезаписывает. Если строка отсутствует, повторяется или имеет непонятный формат, действие блокируется. Случайная замена APP_KEY может сделать недоступными уже зашифрованные Laravel данные, поэтому здесь безопаснее остановиться, чем пытаться автоматически «исправить» файл.
В том же меню запускаются новые миграции Laravel. До выполнения RISH предупреждает, что команда может изменить структуру и содержимое базы. И генерация ключа, и миграции выполняются из каталога проекта, от владельца сайта и с его версией PHP.
Это две операции, при ручном запуске которых особенно легко выбрать не тот каталог, PHP-бинарник или пользователя. RISH не заменяет знание Laravel, а убирает ошибки в серверном окружении команды.
Другие изменения RISH 2.9.0
RISH больше не вызывает rclone about вслепую. Сначала программа определяет, поддерживает ли выбранное подключение сведения об общей квоте. Если провайдер их не отдаёт, это показывается как особенность хранилища, а не как ошибка. Размер каталога с бэкапами запрашивается отдельно.
При чистой установке Certbot теперь не только регистрирует аккаунт Let’s Encrypt, но и сразу включает и запускает certbot-renew.timer. Ошибка регистрации или запуска таймера останавливает шаг: установщик не сообщает о готовности Certbot, пока автоматическое продление фактически не включено.
Менеджер сертификатов перенесён из корня RISH в /root/rish/scripts/certs.sh. Меню MC и клонирование локальных сайтов используют новый путь, а старая копия удаляется только после проверки нового файла.
postupdate.sh также удаляет устаревший /root/rish/index.html, когда новый шаблон Apache-заглушки уже установлен. Эти изменения не добавляют новых пунктов меню, но убирают дубли и устаревшие пути, которые со временем превращаются в источник ошибок при обновлении.
Что сделать после обновления
Шифрование не включается для существующих объектов само по себе: сначала нужно решить, кто именно должен иметь возможность восстановить копию. После обновления рекомендуем пройти несколько шагов:
- Откройте управление резервным копированием и выберите объект, для которого нужно шифрование.
- Создайте отдельный ключ
ageлибо выберите подходящий SSH-ключ. - Если восстановление должно быть доступно владельцу и вебмастеру, добавьте второй публичный ключ до запуска следующего бэкапа.
- Сохраните приватные ключи вне сервера, пароль держите отдельно и удалите временные копии из
/root. - Создайте тестовый зашифрованный бэкап и пройдите проверку восстановления. Сам факт наличия файлов в облаке ещё не доказывает, что у вас сохранился правильный приватный ключ.
- Запустите
rish checkи разберите предупреждения о забытых приватных ключах.
Если проект использует Composer, включите интеграцию в управлении сервером и сначала откройте пункт диагностики для одного сайта. Для Laravel отдельно проверьте состояние .env, APP_KEY и резервную копию базы перед запуском миграций.
Итог
В RISH 2.8.0 мы провели границы между сайтами и забрали критичные настройки из-под контроля процессов сайта. В версии 2.9.0 защита следует за данными дальше: архив шифруется до выхода с сервера и остаётся закрытым в облаке, на внешнем диске и на компьютере, куда его скачали.
Для копии можно назначить два независимых ключа — владельца и вебмастера — либо использовать существующий SSH-ключ. Завершающая часть .end показывает, что в хранилище перенесён полный комплект частей архива, а меню восстановления умеет собрать, проверить и открыть зашифрованную копию.
Composer и Laravel продолжают ту же линию: серверная операция должна выполняться в контексте конкретного сайта, с его PHP и правами его владельца, а потенциально опасные действия на production не должны появляться по умолчанию.
Шифрование добавляет владельцу новую ответственность. Старые ключи нужно хранить не меньше старых бэкапов, а возможность восстановления — проверять до аварии. Если это правило соблюдается, утечка файла из внешнего хранилища уже не означает автоматическую утечку содержимого сайта и базы данных.
Обновляйтесь до RISH 2.9.0, сначала настройте шифрование на тестовом объекте и рассказывайте в нашем чате, какие сценарии Composer, Laravel и резервного копирования стоит автоматизировать дальше.




