mirror of
https://codeberg.org/postscriptum/gemlog.git
synced 2026-03-11 03:52:40 +00:00
add rust-crates-mirroring-with-kellnr.gmi
This commit is contained in:
parent
4a96b5febb
commit
d730d37f49
5 changed files with 209 additions and 0 deletions
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
### Нотатки
|
||||
|
||||
=> rust-crates-mirroring-with-kellnr.gmi 2026-02-25 Організація локального дзеркала залежностей Cargo з Kellnr
|
||||
=> radicle-p2p-traffic-leak-prevention.gmi 2026-02-24 Radicle: обмеження витоків пірингового трафіку
|
||||
=> flarum-v2-fof-redis-extension-setup.gmi 2026-02-22 Flarum v2: активація драйвера Redis (FoF/redis)
|
||||
=> flarum-v2-fof-upload-extension-setup.gmi 2026-02-22 Flarum v2: встановлення модуля локальних вкладень для повідомлень FoF/upload
|
||||
|
|
|
|||
208
public/uk/rust-crates-mirroring-with-kellnr.gmi
Normal file
208
public/uk/rust-crates-mirroring-with-kellnr.gmi
Normal file
|
|
@ -0,0 +1,208 @@
|
|||
# Організація локального дзеркала залежностей Cargo з Kellnr
|
||||
|
||||
Давно задумуюсь про організацію локального дзеркала залежностей crates.io, щоб не ходити за ними в Інтернет. При чому, я не маю достатньо простору для хостингу повної копії репозиторію, утім готовий ділитися тими крейтами, якими користуюся сам.
|
||||
|
||||
Трішки прозондувавши тему, віднайшов проєкт Kellnr:
|
||||
=> https://kellnr.io
|
||||
|
||||
Це рішення позиціонується як Self Hosted Solution для хостингу крейтів, та головне - має фічу вбудованого кешуючого проксі, що власне під мої задачі підходить.
|
||||
|
||||
Дане рішення постачається з Веб-інтерфейсом для адміністрування: зокрема, керування правами доступу.
|
||||
|
||||
=> rust-crates-mirroring-with-kellnr/index-page.png Головна сторінка каталогу (скріншот)
|
||||
|
||||
Сторінка пошуку містить відповідну перемичку фільтрації:
|
||||
|
||||
=> rust-crates-mirroring-with-kellnr/proxy-filter.png Фільтрація кешованих пакунків в Kellnr (скріншот)
|
||||
|
||||
Отже, має бути зручно, особливо для візуалізації результатів CLI-експериментів. Нижче занотую процес встановлення і налаштування публічної ноди (бо варіант з Docker мені не підходить як і автоматичне встановлення скриптом `.sh` - якщо пускатиму в контейнері, то робитиму це руками в LXC)
|
||||
|
||||
## Встановлення
|
||||
|
||||
``` bash
|
||||
git clone https://github.com/kellnr/kellnr.git
|
||||
cd kellnr
|
||||
```
|
||||
|
||||
Якщо планується компіляція кореневого `Cargo.toml` то потрібно спочатку зібрати компонент `ui`, інакше буде помилка на етапі `crates/embedded-resources`:
|
||||
|
||||
``` bash
|
||||
cd ui
|
||||
npm install
|
||||
npm run build
|
||||
```
|
||||
|
||||
На цьому етапі, важливо зкопіювати результат білду до теки `crates/embedded-resources/static`, вміст якої статично додається до бінарного пакету `kellnr`:
|
||||
|
||||
``` bash
|
||||
cp -r ui/dist/. crates/embedded-resources/static/
|
||||
```
|
||||
|
||||
Тепер збираємо корінь .rs:
|
||||
|
||||
``` bash
|
||||
cd ..
|
||||
cargo build --release
|
||||
```
|
||||
|
||||
## Запуск
|
||||
|
||||
Перш, як почепити налаштований демон на systemd, службу можна запустити на локалхост:
|
||||
|
||||
``` bash
|
||||
target/release/kellnr start --registry-data-dir /path/to/kellnr \
|
||||
--proxy-enabled true --local-ip 127.0.0.1 -l debug
|
||||
```
|
||||
|
||||
Після запуску, зайшов до адмінки, вказавши логін `admin` і пароль `admin`:
|
||||
=> http://127.0.0.1:8000/login?redirect=settings
|
||||
|
||||
* на віддаленому сервері потрібно цей пароль змінити (в моїй версії була помилка не співпадіння - проігноруйте її, бо пароль насправді змінюється)
|
||||
|
||||
База даних тут стандартно SQLite, вона буде розташована за вказаним шляхом `/path/to/kellnr`.
|
||||
|
||||
## Підключення клієнта
|
||||
|
||||
Щоб почати наповнення індексу запланованим мною способом (тобто через кешування проксі) додаю наступні рядки до клієнтського файлу `~/.cargo/config.toml`:
|
||||
|
||||
``` ~/.cargo/config.toml
|
||||
# Оголошуємо параметри підключення до сервера
|
||||
[registries.kellnr]
|
||||
index = "sparse+http://127.0.0.1:8000/api/v1/crates/"
|
||||
|
||||
# Вказуємо Cargo замінити стандартне джерело crates.io на Kellnr
|
||||
[source.crates-io]
|
||||
replace-with = "kellnr"
|
||||
```
|
||||
|
||||
Тепер, якщо відкрити будь який проєкт Rust і виконати в ньому оновлення індексу, то отримаємо наступне:
|
||||
|
||||
``` bash
|
||||
$ cargo update
|
||||
Updating `kellnr` index
|
||||
error: no matching package named `libadwaita` found
|
||||
```
|
||||
|
||||
Ця помилка відбувається тому, що ми "залінкувались" на статичне сховище, яке наразі порожнє. Тому в даному випадку, повертаємось до `~/.cargo/config.toml` і змінюємо `index` на URL з суфіксом `cratesio`:
|
||||
|
||||
``` bash
|
||||
index = "sparse+http://127.0.0.1:8000/api/v1/cratesio/"
|
||||
```
|
||||
|
||||
Повторюємо оновлення і бачимо, що залежності почали відбудовуватись, а кеш - наповнюватись:
|
||||
|
||||
=> rust-crates-mirroring-with-kellnr/proxy-index-update.png Оновлення кешованого індексу проксі на головній сторінці Kellnr (скріншот)
|
||||
|
||||
Інші способи глобального і локального оголошення джерела пакунків описані в документації, зупинятись окремо на кожному не будемо:
|
||||
=> https://kellnr.io/documentation#configure-cargo
|
||||
|
||||
## Спільний сервер
|
||||
|
||||
За схожою логікою, можна розгорнути суспільний сервіс, замінивши хост з `127.0.0.1` на `0.0.0.0` або `::`.
|
||||
|
||||
Такий сервіс буде зручно запускати від окремого користувача `kellnr` через systemd:
|
||||
|
||||
``` bash
|
||||
useradd -mr kellnr
|
||||
```
|
||||
* в домашній теці - будуть зберігатись журнали і власне дані сервера
|
||||
|
||||
Системний сервіс у мене виглядає наступним чином:
|
||||
|
||||
``` /etc/systemd/system/kellnr.service
|
||||
[Unit]
|
||||
After=network.target
|
||||
Wants=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
|
||||
User=kellnr
|
||||
Group=kellnr
|
||||
|
||||
ExecStart=/usr/local/bin/kellnr start --registry-data-dir /home/kellnr \
|
||||
--proxy-enabled true \
|
||||
--local-ip :: \
|
||||
--local-port 8180 \
|
||||
-l warn
|
||||
|
||||
Environment="NO_COLOR=1"
|
||||
StandardOutput=file:///home/kellnr/debug.log
|
||||
StandardError=file:///home/kellnr/error.log
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
* для Tor і I2P достатньо лише перекинути на будь-який IP "прихований сервіс" або "тунель"
|
||||
* теоретично, можна оголоситись на `::1` і перекинути проксі Nginx, але не знаю чи це працюватиме в контексті `sparse`
|
||||
|
||||
Після цього відкривається порт:
|
||||
|
||||
``` bash
|
||||
ufw allow from 0200::/7 to 202:68d0:f0d5:b88d:1d1a:555e:2f6b:3148 port 8180 proto tcp
|
||||
ufw allow from 0400::/7 to 505:6847:c778:61a1:5c6d:e802:d291:8191 port 8180 proto tcp
|
||||
```
|
||||
* у прикладі використовуються дозволи для мереж Yggdrasil і Mycelium
|
||||
|
||||
Керування сервісом відбувається за класикою:
|
||||
|
||||
* `systemctl restart kellnr` - (пере) запуск
|
||||
* `systemctl enable kellnr` - авто-старт з системою
|
||||
* `systemctl status kellnr` - перевірка статусу
|
||||
|
||||
---
|
||||
|
||||
Варто враховувати, що простір може швидко заповнитись, якщо проксі-сервер активно використовується.
|
||||
|
||||
Стосовно перманентного хостингу проєктів - як правило, використовуються облікові записи і згенеровані для них токени, утім це вже інша тема.
|
||||
|
||||
### Налаштування вихідного проксі
|
||||
|
||||
На моєму сервері немає Інтернет-інтерфейсу, тому я не можу забрати пакунки з crates.io напряму. Схоже, що Kellnr також поки не підтримує таку функціональність, тому я створив відповідний тікет #1096 і згодом знайшов тимчасове рішення у зв'язці з Nginx - засобами якого я "підставляю" потрібні заголовки згідно до URI:
|
||||
|
||||
``` /etc/nginx/sites-available/default
|
||||
server {
|
||||
listen [::1]:8200;
|
||||
|
||||
access_log /var/log/nginx/kellnr.outproxy.access.log;
|
||||
|
||||
location / {
|
||||
proxy_pass http://[::1]:8118;
|
||||
proxy_set_header X-Forwarded-Proto "https";
|
||||
proxy_set_header Host "index.crates.io";
|
||||
}
|
||||
location /crates {
|
||||
proxy_pass http://[::1]:8118;
|
||||
proxy_set_header X-Forwarded-Proto "https";
|
||||
proxy_set_header Host "static.crates.io";
|
||||
}
|
||||
}
|
||||
```
|
||||
* `[::1]:8118` - це будь-який локальний проксі (типу privoxy або gost) який вміє обробляти HTTP
|
||||
* теоретично, можна пускати трафік через Tor, без проксі-посередника, але в моїй редакції Arti підтримується тільки SOCKS, а той - не підтримується Nginx
|
||||
|
||||
Відповідно до нашого прикладу Nginx, при запуску сервера Kellnr, потрібно додати два аргументи:
|
||||
|
||||
``` bash
|
||||
kellnr start .. \
|
||||
--proxy-index=http://[::1]:8200/ \
|
||||
--proxy-url=http://[::1]:8200/crates/
|
||||
```
|
||||
* тут я також пробував різні аналоги proxychains і "магічні" URL типу `http://[::1]:8118/index.crates.io/` - але цей фокус не пройшов, тому ось такий костиль з Nginx, який працює.
|
||||
|
||||
## Зауваження щодо безпеки
|
||||
|
||||
Хоча в Cargo передбачається декілька рівнів перевірки цілісності пакетів, буде не зайвим переконатись в наявності оригінального файлу `Cargo.lock` для вашого проєкту, що містить хеші залежностей. Ці хеш-суми стандартно не доступні в реєстрах crates.io, утім вони звичайно зберігаються в репозиторіях Git.
|
||||
|
||||
При використанні будь яких проксі, рекомендую збиратись з використанням аргументу `--locked`:
|
||||
|
||||
``` bash
|
||||
cargo build --locked
|
||||
```
|
||||
|
||||
## Посилання
|
||||
|
||||
Наш експериментальний вузол в мережах Yggdrasil і Mycelium, побачимо що з того вийде:
|
||||
|
||||
* `http://[202:68d0:f0d5:b88d:1d1a:555e:2f6b:3148]:8180` | http://ygg.ua.srv:8180
|
||||
* `http://[505:6847:c778:61a1:5c6d:e802:d291:8191]:8180` | http://myc.ua.srv:8180
|
||||
BIN
public/uk/rust-crates-mirroring-with-kellnr/index-page.png
Normal file
BIN
public/uk/rust-crates-mirroring-with-kellnr/index-page.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 128 KiB |
BIN
public/uk/rust-crates-mirroring-with-kellnr/proxy-filter.png
Normal file
BIN
public/uk/rust-crates-mirroring-with-kellnr/proxy-filter.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 36 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 204 KiB |
Loading…
Add table
Add a link
Reference in a new issue