Інсталяція Rust за межами користувацького простору


Даний матеріал не є готовим рішенням, а швидше моєю чернеткою, що містить шматки прикладів конфігурації для міркування: як краще ізолювати програми від основного, вразливого користувацького середовища.


Останнім часом я почав "зловживати" торентами:

GTA3 в Linux на базі рушія re3

Запустив GTA3 в Linux на базі рушія openrw

задумався про те, як шкідливий софт буде діяти в екосистемі Linux.


Раніше, при запуску потенційно шкідливої проги, я просто вимикав Інтернет або виконував її від іншого користувача. Утім, цього разу, протупив і почав думати, що такого може бути зараженим. Бо хоч й торент старіший за світ а clamscan мовчить, моя параноя б'є тривогу.


Будучи віднедавна розробником Rust, перше, що прийшло на думку - тулчейни `rustup`, тека `~` з бінарниками (після `cargo install`). Вірус може не викрадати дані коли немає інтернету, а вишукувати файли з правами `+x` і додавати в них шкідливий бінарний або скриптовий код, який зробить погане під час першого виконання зараженого об'єкта напряму або як залежність.


Видалив я значить все з теки поточного користувача і спробував поставити `rustup` з початку, але так і не побачив там вбудованої опції вибору `/usr/local`, `/var/lib` або `/opt` (на таке до речі свариться SELinux, який я вимкнув). Не полінився, вирішив запитати:

https://users.rust-lang.org/t/how-to-install-rust-system-wide/139833


Звідти ж отримав, в принципі, дієвий рецепт на прикладі контейнера:

https://github.com/MusicalNinjas/devcontainers-pyo3/blob/main/Dockerfile#L55C1-L95C15


Тепер мене вже не стільки хвилює мій комп, як вся інфраструктура Rust. Адже якщо розробники мови мотивують ставити бінарний DE в юзерспейс, кожен потенційний крейт в ньому може бути зараженим без відома навіть добросовісних контрибуторів.


Мій новий підхід


Створив окремого системного юзера @rust з профілем:


sudo useradd -m rust

Підготував спільні розташування:


sudo mkdir /opt/rustup
sudo chown rust:rust /opt/rustup

sudo mkdir /opt/cargo
sudo chown rust:rust /opt/cargo

sudo mkdir /opt/cargo/bin
sudo chown rust:rust /opt/cargo/bin

Тепер логінюсь і вказую цільові теки для поточної сесії:


sudo su rust

export RUSTUP_HOME=/opt/rustup
export CARGO_HOME=/opt/cargo
export PATH=/opt/cargo/bin:$PATH

Від цього ж юзера, виконую стандартний інсталятор:


curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

Від основного користувача вказую аналогічний профіль:


. "/opt/cargo/env"

. "/opt/cargo/env"

. "/opt/cargo/env"

Від основного користувача (до речі, як і раніше на сервері - від @root) більше не збираю програми, тому при виклику cargo, повідомлення повинно про це нагадувати:


cargo -V
error: rustup could not choose a version of cargo to run, because one wasn't specified explicitly, and no default is configured.
help: run 'rustup default stable' to download the latest stable release of Rust and set it as your default toolchain.

Зібрані (від користувача @rust) програми - складатимуться в спільну теку, звідки їх (завдяки копіюванню змінних оточення) бачитиме зовнішній інструментарій розробки, а також буде доступний софт, встановлений засобами `cargo install`.


VSCode / rust-analyzer


Це питання для себе я поки не вирішив, але копати потрібно користувацькі (User) налаштування сабжу, бо системні змінні оточення тут не працюють і компонент активно намагатиметься писати сам в себе (тобто туди, куди я не хочу давати доступ)


{
    "rust-analyzer.server.path": "/usr/local/bin/rust-analyzer-x86_64-unknown-linux-gnu",
    "rust-analyzer.rustc.source": "/opt/rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library",
    "rust-analyzer.cargo.extraEnv": {
        "CARGO_HOME": "${userHome}/.cargo-vscode",
        "RUSTUP_HOME": "/opt/rustup",
        "PATH": "/opt/cargo/bin"
    }
}

бінарні збірки сервера rust-analyzer


Тут я все таки бачу рішення в розподіленні середовищ розробки (де поточний користувач контролить свій git) і збірки (де користувач @rust збирає бінарники з ізольованого правами середовища). Хоча це й потягне додатковий дисковий простір але завдання з підвищення безпеки вирішить, без зайвої мороки на апдейтах цього комбайну.


В плані простору: недавно почистив теки зі старими тулчейнами і target проєктів, звільнивши близько 100Гб диску! Тому звертаю увагу, що раст в процесі інтенсивної роботи - сам за собою не прибере, а `cargo cache -a` по суті звільняє тільки "вершки".


Дивіться також


Встановлення останньої версії Rust в Linux



/uk/