[{"data":1,"prerenderedAt":327},["ShallowReactive",2],{"docs-navigation-ru":3,"docs-search-ru":22,"i-lucide:search":95,"i-lucide:sun":100,"i-lucide:menu":102,"i-lucide:chevron-down":104,"docs-ru-/docs/architecture":106,"i-lucide:link":325},[4,15],{"section":5,"items":6},"Начало работы",[7,11],{"title":8,"path":9,"order":10},"Введение","/docs",1,{"title":12,"path":13,"order":14},"Установка","/docs/installation",2,{"section":16,"items":17},"Как это работает",[18],{"title":19,"path":20,"order":21},"Как это устроено","/docs/architecture",3,[23,27,32,37,42,47,52,56,61,66,71,75,80,85,90],{"id":24,"title":19,"titles":25,"content":26,"level":10},"/ru/docs/architecture",[],"Три процесса на сервере с Maran, контракт между ними и правила, которые решают, что корневому демону вообще позволено делать. На сервере с Maran работают ровно три процесса. Разделение между ними — главное проектное решение\nпродукта, и большинство правил ниже следуют из него.",{"id":28,"title":29,"titles":30,"content":31,"level":14},"/ru/docs/architecture#три-процесса","Три процесса",[19],"ПроцессРаботает отДержитmaran-apiнепривилегированного системного пользователявсю бизнес-логику и единственное подключение к базеmaran-agentrootничего — он без состояния, без базы и без собственной конфигурацииPostgreSQLсобственного пользователяданные панели, на unix-сокете, вообще без TCP-порта Панель никогда не трогает систему. Агент ничего не решает. В этом вся форма: процесс, который знает,\nчто должно произойти, не имеет привилегий, а процесс с привилегиями знает только, как выполнить\nфиксированный список вещей.",{"id":33,"title":34,"titles":35,"content":36,"level":14},"/ru/docs/architecture#контракт-между-ними","Контракт между ними",[19],"Они говорят через unix-сокет, и передаётся именованная операция с типизированными и проверенными\nаргументами. Отсюда три свойства, и каждое — правило, а не привычка: Нет операции, которая запускает переданную вызывающей стороной программу. Ни ограниченной, ни\nиз белого списка — никакой. Поэтому множество того, что можно заставить сделать корневой процесс,\nконечно, записано и поддаётся ревью.Нигде в обмене нет shell-строки. Домен не экранируется перед попаданием в конфигурационный\nфайл; он проверяется как домен — буквы, цифры, дефисы и точки, — и в нём неоткуда взяться\nпереводу строки, который завершит одну директиву и начнёт другую, выбранную вызывающим.Агент проверяет, кто спрашивает. Учётные данные пира на сокете читаются до рассмотрения\nоперации, так что демон знает, какой процесс на другом конце, а не верит тому, что ему сказали.",{"id":38,"title":39,"titles":40,"content":41,"level":14},"/ru/docs/architecture#запись-конфигурационного-файла","Запись конфигурационного файла",[19],"Каждая привилегированная запись идёт в одном и том же порядке, и порядок — это и есть суть: отрендерить во временный файл;fsync;атомарно переименовать на место;дать проверить результат самой службе — nginx -t, а не нашему регулярному выражению;перезагрузить;откатить файл, если проверка или перезагрузка отказали. Один плохой рендер не может уронить остальные сайты сервера, потому что о качестве рендера судит\nсобственный парсер сервера.",{"id":43,"title":44,"titles":45,"content":46,"level":14},"/ru/docs/architecture#изоляция-между-аккаунтами","Изоляция между аккаунтами",[19],"Аккаунт — настоящий пользователь Linux, со своим домашним каталогом и правами файловой\nсистемы.Его PHP работает в собственном пуле php-fpm под собственным uid, и файловые операции идут от\nэтого пользователя — никогда от root.Таблицы арендаторов ограничены аккаунтом на уровне базы, фильтрами запросов, которые\nавтоматический тест проверяет, обходя всю модель.Запрос чужого ресурса отвечает 404, а не 403, поэтому ошибка никогда не подтверждает, что\nстрока существует.",{"id":48,"title":49,"titles":50,"content":51,"level":14},"/ru/docs/architecture#чего-сознательно-нет","Чего сознательно нет",[19],"Ни брокера сообщений, ни сайдкара, ни второго демона. Фоновая работа идёт по надёжным очередям в\nPostgreSQL, и установка Maran не добавляет на сервер ничего, чего нет в таблице выше, — кроме одного\nисключения, которое оператор включает сам: службы FTPS. Платные модули этого тоже не меняют: это модули на C#, которые управляют операциями, уже собранными\nв открытом агенте. Агент никогда не загружает внешний код — поэтому лицензия не может добавить\nновую привилегированную возможность.",{"id":53,"title":8,"titles":54,"content":55,"level":10},"/ru/docs",[],"Что такое Maran, из каких трёх процессов состоит сервер и что корневой демон делать не станет — включая то, почему он не принимает shell-команд. Maran — панель управления веб-хостингом для серверов Linux. Установите её на сервер и управляйте\nсайтами, версиями PHP, SSL-сертификатами, базами данных, файлами, резервными копиями и брандмауэром\nиз браузера, с отдельным кабинетом для каждого клиента хостинга и API, которым биллинговая система\nсоздаёт аккаунты сама.",{"id":57,"title":58,"titles":59,"content":60,"level":14},"/ru/docs#три-процесса-и-root-есть-только-у-одного","Три процесса, и root есть только у одного",[8],"На сервере с Maran работают ровно три процесса, и разделение между ними — главное решение продукта: maran-api — сама панель. В ней вся бизнес-логика, и только она обращается к базе данных.\nРаботает от непривилегированного системного пользователя.maran-agent — единственный процесс с root. Он не хранит состояние, у него нет базы и своих\nконфигурационных файлов, и только он трогает веб-сервер, php-fpm, сервер баз данных, SSH и\nпередачу файлов, планировщик, брандмауэр и сертификаты.PostgreSQL — доступен только из maran-api, через unix-сокет, вообще без TCP-порта. Панель просит у агента именованные операции через unix-сокет, с типизированными и проверенными\nаргументами. Нет операции, которая запускает переданную вызывающей стороной программу, и между ними\nнигде нет shell-строки: множество того, что можно заставить сделать корневой процесс, конечно,\nзаписано и поддаётся ревью.",{"id":62,"title":63,"titles":64,"content":65,"level":14},"/ru/docs#что-такое-аккаунт-хостинга","Что такое аккаунт хостинга",[8],"Настоящий пользователь Linux со своим домашним каталогом и правами файловой системы. Его PHP\nработает в собственном пуле под собственным uid, и файловые операции идут от этого же uid — никогда\nот root. Каждая таблица, принадлежащая арендатору, ограничена аккаунтом на уровне базы, а запрос\nчужого ресурса отвечает 404, а не 403 — ошибка никогда не подтверждает, что строка существует.",{"id":67,"title":68,"titles":69,"content":70,"level":14},"/ru/docs#ни-брокеров-ни-сайдкаров","Ни брокеров, ни сайдкаров",[8],"Фоновая работа идёт по надёжным очередям, хранящимся в PostgreSQL. Установка Maran не добавляет на\nсервер ни брокера сообщений, ни сайдкар, ни второй демон.",{"id":72,"title":12,"titles":73,"content":74,"level":10},"/ru/docs/installation",[],"Установка Maran на чистый сервер, что установщик проверяет первым делом и как создаётся первый администратор. Устанавливайте на сервер, которым управляете сами, с доступом root и одной из\nподдерживаемых платформ.",{"id":76,"title":77,"titles":78,"content":79,"level":14},"/ru/docs/installation#запустить-установщик","Запустить установщик",[12],"curl -sSL https://get.maran.innovayse.com | bash Установщик проверяет систему до того, как что-то изменить: дистрибутив и его версию по матрице\nподдержки, пороги по памяти и диску, нужные порты и свободное место на файловой системе резервных\nкопий. Он собирает все отказы и выходит один раз, так что список исправляется целиком, а не по\nодной проблеме за запуск. Если проверки пройдены, он ставит подписанные артефакты релиза, ужесточает systemd-юниты и\nразворачивает то, что нужно хостинговому серверу: веб-сервер, PostgreSQL для данных самой панели,\nсервер баз данных для аккаунтов, передачу файлов, брандмауэр и планировщик.",{"id":81,"title":82,"titles":83,"content":84,"level":14},"/ru/docs/installation#первый-администратор","Первый администратор",[12],"По завершении установщик печатает одноразовую ссылку. Открыть её в браузере — единственный способ\nсоздать первого администратора: больше его не создать ничем, и ссылка сгорает при использовании.",{"id":86,"title":87,"titles":88,"content":89,"level":14},"/ru/docs/installation#после-первого-входа","После первого входа",[12],"Включите двухфакторную аутентификацию и создайте первый аккаунт хостинга. Аккаунт — настоящий\nпользователь Linux со своим домашним каталогом, своим пулом php-fpm и квотой по тарифу; создание\nчерез панель и есть то, что разворачивает его на хосте.",{"id":91,"title":92,"titles":93,"content":94,"level":14},"/ru/docs/installation#обновления-и-откат","Обновления и откат",[12],"Обновления подписаны и ставятся из панели или утилитой maran. Перед подменой чего-либо обновление\nделает дамп базы, а maran rollback возвращает предыдущую версию, используя этот дамп как страховку.\nПатчи безопасности по умолчанию ставятся автоматически; это можно выключить. 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);}",{"left":96,"top":96,"width":97,"height":97,"rotate":96,"vFlip":98,"hFlip":98,"body":99},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":96,"top":96,"width":97,"height":97,"rotate":96,"vFlip":98,"hFlip":98,"body":101},"\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":96,"top":96,"width":97,"height":97,"rotate":96,"vFlip":98,"hFlip":98,"body":103},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M4 5h16M4 12h16M4 19h16\"/>",{"left":96,"top":96,"width":97,"height":97,"rotate":96,"vFlip":98,"hFlip":98,"body":105},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"m6 9l6 6l6-6\"/>",{"doc":107,"isFallback":98},{"id":108,"title":19,"body":109,"description":317,"extension":318,"meta":319,"navigation":320,"order":21,"path":24,"section":16,"seo":321,"seoTitle":322,"stem":323,"__hash__":324},"docsRu/ru/docs/architecture.md",{"type":110,"value":111,"toc":309},"minimark",[112,116,120,181,193,196,204,226,229,232,260,263,266,296,299,302],[113,114,115],"p",{},"На сервере с Maran работают ровно три процесса. Разделение между ними — главное проектное решение\nпродукта, и большинство правил ниже следуют из него.",[117,118,29],"h2",{"id":119},"три-процесса",[121,122,123,139],"table",{},[124,125,126],"thead",{},[127,128,129,133,136],"tr",{},[130,131,132],"th",{},"Процесс",[130,134,135],{},"Работает от",[130,137,138],{},"Держит",[140,141,142,157,170],"tbody",{},[127,143,144,151,154],{},[145,146,147],"td",{},[148,149,150],"code",{},"maran-api",[145,152,153],{},"непривилегированного системного пользователя",[145,155,156],{},"всю бизнес-логику и единственное подключение к базе",[127,158,159,164,167],{},[145,160,161],{},[148,162,163],{},"maran-agent",[145,165,166],{},"root",[145,168,169],{},"ничего — он без состояния, без базы и без собственной конфигурации",[127,171,172,175,178],{},[145,173,174],{},"PostgreSQL",[145,176,177],{},"собственного пользователя",[145,179,180],{},"данные панели, на unix-сокете, вообще без TCP-порта",[113,182,183,184,188,189,192],{},"Панель никогда не трогает систему. Агент ничего не решает. В этом вся форма: процесс, который знает,\n",[185,186,187],"em",{},"что"," должно произойти, не имеет привилегий, а процесс с привилегиями знает только, ",[185,190,191],{},"как"," выполнить\nфиксированный список вещей.",[117,194,34],{"id":195},"контракт-между-ними",[113,197,198,199,203],{},"Они говорят через unix-сокет, и передаётся ",[200,201,202],"strong",{},"именованная операция с типизированными и проверенными\nаргументами",". Отсюда три свойства, и каждое — правило, а не привычка:",[205,206,207,214,220],"ul",{},[208,209,210,213],"li",{},[200,211,212],{},"Нет операции, которая запускает переданную вызывающей стороной программу."," Ни ограниченной, ни\nиз белого списка — никакой. Поэтому множество того, что можно заставить сделать корневой процесс,\nконечно, записано и поддаётся ревью.",[208,215,216,219],{},[200,217,218],{},"Нигде в обмене нет shell-строки."," Домен не экранируется перед попаданием в конфигурационный\nфайл; он проверяется как домен — буквы, цифры, дефисы и точки, — и в нём неоткуда взяться\nпереводу строки, который завершит одну директиву и начнёт другую, выбранную вызывающим.",[208,221,222,225],{},[200,223,224],{},"Агент проверяет, кто спрашивает."," Учётные данные пира на сокете читаются до рассмотрения\nоперации, так что демон знает, какой процесс на другом конце, а не верит тому, что ему сказали.",[117,227,39],{"id":228},"запись-конфигурационного-файла",[113,230,231],{},"Каждая привилегированная запись идёт в одном и том же порядке, и порядок — это и есть суть:",[233,234,235,238,244,247,254,257],"ol",{},[208,236,237],{},"отрендерить во временный файл;",[208,239,240,243],{},[148,241,242],{},"fsync",";",[208,245,246],{},"атомарно переименовать на место;",[208,248,249,250,253],{},"дать проверить результат самой службе — ",[148,251,252],{},"nginx -t",", а не нашему регулярному выражению;",[208,255,256],{},"перезагрузить;",[208,258,259],{},"откатить файл, если проверка или перезагрузка отказали.",[113,261,262],{},"Один плохой рендер не может уронить остальные сайты сервера, потому что о качестве рендера судит\nсобственный парсер сервера.",[117,264,44],{"id":265},"изоляция-между-аккаунтами",[205,267,268,275,282,289],{},[208,269,270,271,274],{},"Аккаунт — ",[200,272,273],{},"настоящий пользователь Linux",", со своим домашним каталогом и правами файловой\nсистемы.",[208,276,277,278,281],{},"Его PHP работает ",[200,279,280],{},"в собственном пуле php-fpm под собственным uid",", и файловые операции идут от\nэтого пользователя — никогда от root.",[208,283,284,285,288],{},"Таблицы арендаторов ограничены аккаунтом ",[200,286,287],{},"на уровне базы",", фильтрами запросов, которые\nавтоматический тест проверяет, обходя всю модель.",[208,290,291,292,295],{},"Запрос чужого ресурса отвечает ",[200,293,294],{},"404, а не 403",", поэтому ошибка никогда не подтверждает, что\nстрока существует.",[117,297,49],{"id":298},"чего-сознательно-нет",[113,300,301],{},"Ни брокера сообщений, ни сайдкара, ни второго демона. Фоновая работа идёт по надёжным очередям в\nPostgreSQL, и установка Maran не добавляет на сервер ничего, чего нет в таблице выше, — кроме одного\nисключения, которое оператор включает сам: службы FTPS.",[113,303,304,305,308],{},"Платные модули этого тоже не меняют: это модули на C#, которые управляют операциями, уже собранными\nв открытом агенте. ",[200,306,307],{},"Агент никогда не загружает внешний код"," — поэтому лицензия не может добавить\nновую привилегированную возможность.",{"title":310,"searchDepth":14,"depth":14,"links":311},"",[312,313,314,315,316],{"id":119,"depth":14,"text":29},{"id":195,"depth":14,"text":34},{"id":228,"depth":14,"text":39},{"id":265,"depth":14,"text":44},{"id":298,"depth":14,"text":49},"Три процесса на сервере с Maran, контракт между ними и правила, которые решают, что корневому демону вообще позволено делать.","md",{},true,{"title":19,"description":317},"Архитектура — три процесса, root у одного","ru/docs/architecture","cGiNNklPXEFVP9i4wzLUEVQn470w0qAeG7SFYP43_JI",{"left":96,"top":96,"width":97,"height":97,"rotate":96,"vFlip":98,"hFlip":98,"body":326},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71\"/>\u003Cpath d=\"M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71\"/>\u003C/g>",1790166392848]