diff --git a/public/uk/index.gmi b/public/uk/index.gmi index 7090a71..6d46e14 100644 --- a/public/uk/index.gmi +++ b/public/uk/index.gmi @@ -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 diff --git a/public/uk/rust-crates-mirroring-with-kellnr.gmi b/public/uk/rust-crates-mirroring-with-kellnr.gmi new file mode 100644 index 0000000..a67ae25 --- /dev/null +++ b/public/uk/rust-crates-mirroring-with-kellnr.gmi @@ -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 \ No newline at end of file diff --git a/public/uk/rust-crates-mirroring-with-kellnr/index-page.png b/public/uk/rust-crates-mirroring-with-kellnr/index-page.png new file mode 100644 index 0000000..446b891 Binary files /dev/null and b/public/uk/rust-crates-mirroring-with-kellnr/index-page.png differ diff --git a/public/uk/rust-crates-mirroring-with-kellnr/proxy-filter.png b/public/uk/rust-crates-mirroring-with-kellnr/proxy-filter.png new file mode 100644 index 0000000..3a2a32b Binary files /dev/null and b/public/uk/rust-crates-mirroring-with-kellnr/proxy-filter.png differ diff --git a/public/uk/rust-crates-mirroring-with-kellnr/proxy-index-update.png b/public/uk/rust-crates-mirroring-with-kellnr/proxy-index-update.png new file mode 100644 index 0000000..b951a33 Binary files /dev/null and b/public/uk/rust-crates-mirroring-with-kellnr/proxy-index-update.png differ