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

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

Останнім часом я почав "зловживати" торентами:
=> gta3-on-linux-using-re3-engine.gmi GTA3 в Linux на базі рушія re3
=> gta3-on-linux-using-openrw-engine.gmi Запустив 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 з профілем:

``` bash
sudo useradd -m rust
```

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

``` bash
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
```

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

``` bash
sudo su rust

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

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

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

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

``` ~/.bash_profile
. "/opt/cargo/env"
```

``` ~/.profile
. "/opt/cargo/env"
```

``` ~/.bashrc
. "/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.
```
* технічно, можна додати шляхи CARGO_HOME і RUSTUP_HOME до `/opt/cargo/env`

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

### VSCode / rust-analyzer

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

``` settings.json
{
    "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"
    }
}
```
=> https://github.com/rust-lang/rust-analyzer/releases бінарні збірки сервера rust-analyzer

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

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

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

=> install-latest-rust-version-on-linux.gmi Встановлення останньої версії Rust в Linux