[{"data":1,"prerenderedAt":495},["ShallowReactive",2],{"releases-index-ru":3,"i-lucide:search":486,"i-lucide:sun":491,"i-lucide:menu":493},[4,84],{"id":5,"title":6,"body":7,"channel":72,"date":73,"description":74,"extension":75,"meta":76,"navigation":77,"path":78,"seo":79,"seoTitle":80,"stem":81,"version":82,"__hash__":83},"releasesRu/ru/releases/0.1.0.md","Maran 0.1.0 — основание",{"type":8,"value":9,"toc":66},"minimark",[10,14,19,53,57],[11,12,13],"p",{},"Каркас, а не продукт, который вы поставите перед клиентами хостинга. Он всё же опубликован как релиз,\nпотому что всё последующее построено на принятых здесь решениях.",[15,16,18],"h2",{"id":17},"что-входит","Что входит",[20,21,22,30,36,42,48],"ul",{},[23,24,25,29],"li",{},[26,27,28],"strong",{},"Контракт"," между панелью и корневым агентом — типизированные операции, которыми они\nобмениваются через unix-сокет.",[23,31,32,35],{},[26,33,34],{},"Скелет агента на Rust",", включая проверку учётных данных пира на сокете: агент знает, какой\nпроцесс его просит, до того как что-либо сделает.",[23,37,38,41],{},[26,39,40],{},"Модульный монолит на C#",", который стал панелью.",[23,43,44,47],{},[26,45,46],{},"Оболочка на Vue",", в которой построен интерфейс.",[23,49,50],{},[26,51,52],{},"Среда разработки и CI.",[15,54,56],{"id":55},"чего-не-входит","Чего не входит",[11,58,59,60,65],{},"Ни одной возможности хостинга. Аккаунты, сайты, пулы PHP, SSL, базы данных, передача файлов,\nрезервные копии, брандмауэр и мониторинг собраны после этого тега и в него не входят. Они на пути к\nпервому функциональному релизу; что опубликовано — смотрите в ",[61,62,64],"a",{"href":63},"/releases","релизах",".",{"title":67,"searchDepth":68,"depth":68,"links":69},"",2,[70,71],{"id":17,"depth":68,"text":18},{"id":55,"depth":68,"text":56},"stable","2026-08-29","Первая помеченная версия — контракт, скелет агента на Rust, монолит на C#, оболочка на Vue и среда разработки.","md",{},true,"/ru/releases/0.1.0",{"title":6,"description":74},"Maran 0.1.0 — релиз-основание","ru/releases/0.1.0","0.1.0","HWMt0R1wIPNB5ifZm8CdskBZnsuKeTy78zSeUdo74Ug",{"id":85,"title":86,"body":87,"channel":477,"date":478,"description":479,"extension":75,"meta":480,"navigation":77,"path":481,"seo":482,"seoTitle":86,"stem":483,"version":484,"__hash__":485},"releasesRu/ru/releases/1.0.0-beta.1.md","Maran 1.0.0-beta.1 — первый устанавливаемый выпуск",{"type":8,"value":88,"toc":469},[89,95,98,102,138,151,154,158,166,246,273,276,320,332,336,397,401,404,408,411,451,454,458,465],[11,90,91,92],{},"Первый выпуск, который ставится на сервер и проводит хостинг-аккаунт через весь путь. Он опубликован\nкак бета, и слово означает ровно то, что означает: ",[26,93,94],{},"пока не сажайте на него чужих клиентов.",[11,96,97],{},"Софт ставится, работает и делает то, что написано на его экранах. Три вещи, которым платный\nхостинг-продукт обязан быть достоин доверия, проверялись только в контейнерах самого проекта — ни\nодин сертификат не выпущен настоящим удостоверяющим центром, ни одна дисковая квота не проверена\nнастоящей файловой системой, и ни одно восстановление не выполнено на настоящем железе. Это не\nизвестные ошибки, это утверждения, которые пока никто не подтвердил там, где это важно.",[15,99,101],{"id":100},"установка","Установка",[103,104,108],"pre",{"className":105,"code":106,"language":107,"meta":67,"style":67},"language-bash shiki shiki-themes github-light github-dark","curl -sSL https://get.maran.innovayse.com | sudo bash\n","bash",[109,110,111],"code",{"__ignoreMap":67},[112,113,116,120,124,128,132,135],"span",{"class":114,"line":115},"line",1,[112,117,119],{"class":118},"sScJk","curl",[112,121,123],{"class":122},"sj4cs"," -sSL",[112,125,127],{"class":126},"sZZnC"," https://get.maran.innovayse.com",[112,129,131],{"class":130},"szBVR"," |",[112,133,134],{"class":118}," sudo",[112,136,137],{"class":126}," bash\n",[11,139,140,141,144,145,65],{},"Установщик скачивает артефакты, перечисленные в манифесте, подписанном релизным ключом проекта, и\nотказывается принимать всё, чья подпись или контрольная сумма не сходится. Манифест и названные в\nнём артефакты опубликованы на ",[109,142,143],{},"releases.maran.innovayse.com",", а исходники на теге, из которого\nсобран выпуск, — на ",[61,146,150],{"href":147,"rel":148},"https://github.com/innovayse/maran",[149],"nofollow","GitHub",[11,152,153],{},"Посмотрите, что установщик собирается сделать, прежде чем запускать его от root — как с любым\nскриптом, которому вы отдаёте сервер: скачайте, прочитайте, потом запускайте.",[15,155,157],{"id":156},"файлы-и-как-проверить-их-самому","Файлы и как проверить их самому",[11,159,160,161,165],{},"Всё, что скачивает установщик, опубликовано на\n",[61,162,143],{"href":163,"rel":164},"https://releases.maran.innovayse.com",[149]," и перечислено в манифесте,\nподписанном ключом релизов проекта.",[167,168,169,185],"table",{},[170,171,172],"thead",{},[173,174,175,179,182],"tr",{},[176,177,178],"th",{},"Файл",[176,180,181],{},"Размер",[176,183,184],{},"SHA-256",[186,187,188,208,227],"tbody",{},[173,189,190,200,203],{},[191,192,193],"td",{},[61,194,197],{"href":195,"rel":196},"https://releases.maran.innovayse.com/beta/agent-x86_64.tar.gz",[149],[109,198,199],{},"agent-x86_64.tar.gz",[191,201,202],{},"2.9 MB",[191,204,205],{},[109,206,207],{},"f9a57621ef349cb1bfc2df5f7f812685fb3a5a690834b18bd1ae8df2493fbadc",[173,209,210,219,222],{},[191,211,212],{},[61,213,216],{"href":214,"rel":215},"https://releases.maran.innovayse.com/beta/api-x86_64.tar.gz",[149],[109,217,218],{},"api-x86_64.tar.gz",[191,220,221],{},"25.4 MB",[191,223,224],{},[109,225,226],{},"6f367807e265d06bee9db37d692d0748c5fb815967965c0e59675a0b8468c799",[173,228,229,238,241],{},[191,230,231],{},[61,232,235],{"href":233,"rel":234},"https://releases.maran.innovayse.com/beta/frontend-x86_64.tar.gz",[149],[109,236,237],{},"frontend-x86_64.tar.gz",[191,239,240],{},"340 KB",[191,242,243],{},[109,244,245],{},"27879087ddb1a0d1e05e92b9b0b4dec6da21a99263388a74e122681ada828009",[11,247,248,249,256,257,264,265,272],{},"Подписанный список — ",[61,250,253],{"href":251,"rel":252},"https://releases.maran.innovayse.com/beta/manifest.json",[149],[109,254,255],{},"manifest.json",", рядом\nс ним ",[61,258,261],{"href":259,"rel":260},"https://releases.maran.innovayse.com/beta/manifest.json.sig",[149],[109,262,263],{},"manifest.json.sig",", а\n",[61,266,269],{"href":267,"rel":268},"https://releases.maran.innovayse.com/beta/integrity-manifest.json",[149],[109,270,271],{},"integrity-manifest.json","\nзаписывает каждый файл внутри архивов, а не только сами архивы.",[11,274,275],{},"Если не хочется ничего направлять в root-шелл по трубе — та же установка без неё:",[103,277,279],{"className":105,"code":278,"language":107,"meta":67,"style":67},"curl -O https://releases.maran.innovayse.com/installer/maran-installer.tar.gz\ntar -xzf maran-installer.tar.gz\nsudo bash installer/install.sh --channel beta\n",[109,280,281,291,302],{"__ignoreMap":67},[112,282,283,285,288],{"class":114,"line":115},[112,284,119],{"class":118},[112,286,287],{"class":122}," -O",[112,289,290],{"class":126}," https://releases.maran.innovayse.com/installer/maran-installer.tar.gz\n",[112,292,293,296,299],{"class":114,"line":68},[112,294,295],{"class":118},"tar",[112,297,298],{"class":122}," -xzf",[112,300,301],{"class":126}," maran-installer.tar.gz\n",[112,303,305,308,311,314,317],{"class":114,"line":304},3,[112,306,307],{"class":118},"sudo",[112,309,310],{"class":126}," bash",[112,312,313],{"class":126}," installer/install.sh",[112,315,316],{"class":122}," --channel",[112,318,319],{"class":126}," beta\n",[11,321,322,323,326,327,65],{},"Публичный ключ, которым проверяет установщик, едет внутри этого пакета —\n",[109,324,325],{},"installer/keys/release-signing.pub",". Стоит сказать прямо: подпись, проверенная ключом, скачанным с\nтого же хоста, доказывает лишь, что оба пришли из одного места. Чтобы доказать больше, сверьте этот\nключ с ",[61,328,331],{"href":329,"rel":330},"https://github.com/innovayse/maran/blob/main/installer/keys/release-signing.pub",[149],"копией в репозитории",[15,333,335],{"id":334},"что-получает-сервер","Что получает сервер",[20,337,338,344,350,356,362,368,374,391],{},[23,339,340,343],{},[26,341,342],{},"Хостинг-аккаунты — настоящие пользователи Linux."," Создание аккаунта заводит системного\nпользователя, домашний каталог и дисковую квоту тарифа на самом сервере; приостановка,\nвозобновление и удаление тоже доходят до хоста. Сначала действует агент, потом появляется запись\nв базе — поэтому панель никогда не заявляет аккаунт, которого на сервере нет.",[23,345,346,349],{},[26,347,348],{},"Сайты"," — статические, PHP и обратный прокси — с алиасами доменов и корнем внутри домашнего\nкаталога аккаунта. Агент рендерит конфигурацию, заставляет штатный валидатор сервера проверить\nрезультат и откатывает файл, если проверка или перезагрузка отказались, — поэтому плохой рендер\nне может уронить остальные сайты сервера.",[23,351,352,355],{},[26,353,354],{},"Несколько версий PHP одновременно",", у каждого аккаунта свой пул на версию, работающий от его\nже пользователя Linux. Клиент может менять разрешённое подмножество настроек; имя вне списка\nотклоняется, а не отбрасывается молча.",[23,357,358,361],{},[26,359,360],{},"SSL"," по ACME с проверкой HTTP-01, загрузка собственных сертификатов и продление за тридцать\nдней до истечения. Ключи пишутся в хранилище, доступное только root и лежащее вне домашних\nкаталогов, потому что PHP сайта работает от имени клиента.",[23,363,364,367],{},[26,365,366],{},"Базы данных"," с отдельным пользователем на каждую, лимитами тарифа и показом размера. Пароль\nгенерируется, показывается один раз и не хранится — поэтому восстановление это сброс, а не\nизвлечение.",[23,369,370,373],{},[26,371,372],{},"Передача файлов"," — SFTP штатным OpenSSH сервера, каждый вход заперт в jail, внутрь которого\nпримонтирован настоящий домашний каталог аккаунта, с его же uid и без шелла. FTPS поставляется\nустановленным, но выключенным: ничего не слушает, пока администратор его не включит.",[23,375,376,379,380,383,384,387,388,65],{},[26,377,378],{},"Резервные копии",", ",[26,381,382],{},"журнал аудита"," только на дозапись по каждому входу и каждому изменению,\nживой просмотр ",[26,385,386],{},"логов",", брандмауэр, мониторинг и консольная утилита ",[109,389,390],{},"maran",[23,392,393,396],{},[26,394,395],{},"Вход в панель"," с Argon2id, короткоживущими токенами доступа, ротацией refresh-токенов, где\nповторно использованный токен отзывает всё семейство, TOTP с кодами восстановления и сессиями,\nкоторые можно отозвать по одной или все разом.",[15,398,400],{"id":399},"чего-он-намеренно-не-делает","Чего он намеренно не делает",[11,402,403],{},"DNS, почта и веб-менеджер баз данных. Каждое отсутствует по решению, а не по недоделанности:\nменеджер баз данных запланирован отдельным развёртыванием со своим адресом и своей аутентификацией,\nа не наполовину сделанным здесь.",[15,405,407],{"id":406},"прежде-чем-ставить-туда-где-это-важно","Прежде чем ставить туда, где это важно",[11,409,410],{},"Три ограничения стоит знать заранее — иначе оператор узнает о них трудным путём.",[20,412,413,427,433],{},[23,414,415,418,419,422,423,426],{},[26,416,417],{},"Ни один сертификат не выпущен настоящим удостоверяющим центром."," Весь путь при этом\nпроходится целиком — регистрация, заказ, проверка HTTP-01, финализация, скачивание — против\n",[109,420,421],{},"pebble",", тестового сервера самого Let's Encrypt, причём серийный номер выданного сертификата\nсовпадает с прочитанным из PEM. Это упражнение нашло настоящий дефект, которого не видел ни один\nтест: клиент не отправлял ",[109,424,425],{},"User-Agent",", а pebble отклоняет такие запросы, Let's Encrypt же их\nтерпит. Не проверен сам центр: ни его лимиты, ни проверка из публичной сети, ни его цепочка.\nВетка продления не проверялась вовсе — тест каждый раз вынуждает новую проверку. Только HTTP-01,\nбез wildcard-сертификатов: они придут вместе с управлением DNS.",[23,428,429,432],{},[26,430,431],{},"Удаление базы данных окончательно."," Нет ни снимка, ни корзины, ни задержки, и путь удаления\nникак не обращается к модулю резервных копий. База восстановима только из копии, которая уже\nсуществовала.",[23,434,435,438,439,442,443,446,447,450],{},[26,436,437],{},"Конфигурация SSH-демона отслеживается, и у слежения названа граница."," Установщик пишет блок,\nкоторый делает вход для передачи файлов запертым, а мониторинг теперь читает этот блок обратно и\nподнимает тревогу при расхождении — причём все четыре директивы по отдельности, поэтому блок с\nуцелевшим заголовком и опустошённым телом тоже будет пойман. Читается файл конфигурации, а не\nответ демона: ",[109,440,441],{},"sshd -T"," вообще никогда не печатает содержимое блока ",[109,444,445],{},"Match",". Чего слежение не\nделает: не идёт по директивам ",[109,448,449],{},"Include"," и не доказывает, что на разошедшемся хосте действительно\nвыдаётся шелл. Оно сообщает, что конфигурация больше не говорит написанного.",[11,452,453],{},"Заметки об угрозах по привилегированным частям были прочитаны и приняты в день выпуска. Это\nудовлетворяет собственному правилу проекта о втором проверяющем. Это не внешний аудит, и эта\nстраница его не заявляет.",[15,455,457],{"id":456},"обновление-с-010","Обновление с 0.1.0",[11,459,460,461,464],{},"Пути обновления нет, и он не нужен: ",[61,462,82],{"href":463},"/releases/0.1.0"," был каркасом без хостинговых функций,\nи сохранять на нём было нечего.",[466,467,468],"style",{},"html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":67,"searchDepth":68,"depth":68,"links":470},[471,472,473,474,475,476],{"id":100,"depth":68,"text":101},{"id":156,"depth":68,"text":157},{"id":334,"depth":68,"text":335},{"id":399,"depth":68,"text":400},{"id":406,"depth":68,"text":407},{"id":456,"depth":68,"text":457},"beta","2026-09-23","Первый выпуск, который ставится на сервер: аккаунты как настоящие пользователи Linux, сайты, версии PHP, SSL, базы данных, передача файлов и резервные копии — опубликован как бета, с честно очерченной границей.",{},"/ru/releases/0.0-beta.1",{"title":86,"description":479},"ru/releases/1.0.0-beta.1","1.0.0-beta.1","gtSb3_GcJDmwYc67f98G8Ey2aCD3k1DCinQ7xzdocV4",{"left":487,"top":487,"width":488,"height":488,"rotate":487,"vFlip":489,"hFlip":489,"body":490},0,24,false,"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"m21 21l-4.34-4.34\"/>\u003Ccircle cx=\"11\" cy=\"11\" r=\"8\"/>\u003C/g>",{"left":487,"top":487,"width":488,"height":488,"rotate":487,"vFlip":489,"hFlip":489,"body":492},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Ccircle cx=\"12\" cy=\"12\" r=\"4\"/>\u003Cpath d=\"M12 2v2m0 16v2M4.93 4.93l1.41 1.41m11.32 11.32l1.41 1.41M2 12h2m16 0h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41\"/>\u003C/g>",{"left":487,"top":487,"width":488,"height":488,"rotate":487,"vFlip":489,"hFlip":489,"body":494},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M4 5h16M4 12h16M4 19h16\"/>",1790166389881]