Satont.
299 subscribers
321 photos
52 videos
1 file
201 links
Download Telegram
Satont. pinned «Переписал Twir на Bun вместо Node Bun это альтернативный js рантайм, который имеет кучу built-in апишек, написаных на языке zig. Апишки эти работают на порядок быстрее, чем в ноде, и их просто больше. Для примера, из встроенного и написанного на zig есть:…»
Планирую расширять ресурсы твира, и перекинуть всё на hetzner. Напоминаю, сейчас меня хостят бесплатно, один сервак всего. Докинуть ресурсов не могу. А ресурсы порой кончаются, например сейчас в пике может 12гб оперативки потребляться из 16ти. В какой-то скорый момент они кончатся.

Буду брать серваки на hetzner, горизонтальное масштабирование, в целом быстрее cpu, и вот это всё.
Буду признателен вам за подписки, или донаты копеечкой.
Если хотите чтобы я вас в ответ тоже отблагодарил, можете в лс писать. Могу предоставить vpn, какие-то фишки в твире, которые вы хотите (в силу возможностей). Жопу не покажу.

https://boosty.to/yakui
USDT TRC20: TVTagN51Wtykm8nXVthTJXStbNAAgYCmgp
USDC Polygon PoS: 0xbdde3a059458468371b613d113c15a97499950fb
Ethereum ERC20: 0xbdde3a059458468371b613d113c15a97499950fb
Bybit UID: 424720268
CARD RUB: 2202 2061 3958 1651
9👍1🔥1
Satont. pinned «Планирую расширять ресурсы твира, и перекинуть всё на hetzner. Напоминаю, сейчас меня хостят бесплатно, один сервак всего. Докинуть ресурсов не могу. А ресурсы порой кончаются, например сейчас в пике может 12гб оперативки потребляться из 16ти. В какой-то скорый…»
Satont.
Планирую расширять ресурсы твира, и перекинуть всё на hetzner. Напоминаю, сейчас меня хостят бесплатно, один сервак всего. Докинуть ресурсов не могу. А ресурсы порой кончаются, например сейчас в пике может 12гб оперативки потребляться из 16ти. В какой-то скорый…
Перенёс.

Взял 3 сервера, 2 под сервисы, 1 под бдшки, чтобы они отдельно крутились.

Процы на hetzner сразу видно лучше, вот avg load с сервера с базами: 0.09, 0.10, 0.09. Я так понимаю это потому что они быстрее и лучше справляются с поставленными вещами, плюсом не надо делить процессорное время уже с самими сервисами.

Поставил traefik, который за cloudflared тоннелем. Что это значит?
Вы запускаете агент cloudflared, создаёте докер сеть под него, и потом прикрепляете эту докер сеть к вашему сервису.
services:
cloudflared:
image: cloudflare/cloudflared
command: tunnel run
networks:
- cloudflared
environment:
- TUNNEL_TOKEN=${TUNNEL_TOKEN}


networks:
cloudflared:
external: true


И второй файлик:
services:
image: nginx
networks:
- cloudflared

networks:
cloudflared:
external: true


Запустили, и можно через панельку cloudflare открыть nginx по домену в сеть! (см. скриншот №1)

Там поддерживается как http, так и ssh, tcp. Можно почти любой сервис так открыть за доменом через эти тонели.

Ещё из апгрейда инфры я сделал zero-access до своих панелек. Например adminer закрыл, и логиниться могу только я туда. Не нужно настраивать traefik мидлвары, кастомные плагины, парится об env всяких. Просто настроил и работает. Можно даже сделать доступ за warp (впн клиент такой), если надо. Чем меньше env, тем лучше.

Брал кстати сервера в америке, и твич стал сильно быстрее отвечать за счёт этого. Но у этого минус есть - фронт у европейцев будет на 150мс медленее грузить.
🔥5👍3🏆1
Фига чё гитлаб придумали.

Если вы потеряли своё 2fa приложение, и у вас привязан ssh ключ — то вы можете перегенерить рекавери коды использовав ssh [email protected] 2fa_recovery_codes.
👍6🤯6
Ребят, если зарегаетесь по моей рефке на хетзнере — получите 20 евро на баланс клауда.
А когда потратите свои закинутые 10 евро — их получу я.
Потому, если кто задумывался и имеет возможность — дерзайте.

https://hetzner.cloud/?ref=CLdub3cH5y9p

П.С россияне не могут.
🗿8
Добавил в twir автоопределение играющей музыки на стриме, без необходимости подключать сторонний сервис по типу spotify, last.fm. Бот просто получает отрезочек стрима, отправляет его на определение.
Пока использую только shazam reverse-engineered api, потом подключу acrcloud, который уже будет платным для меня.
Но acrcloud имеет более лучшее определение, потому сделать придётся. Сейчас много мисов в определении, но уже хоть что-то, и бесплатно для меня и вас.
🔥15👍42🆒1
This media is not supported in your browser
VIEW IN TELEGRAM
🗿72💅2
Какой вариант вам нравится больше?
Думаю может взять старый дизайн, и осовременить его чутка, а конкретно взять блок features с нового.

👍https://twir.app
❤️https://web.archive.org/web/20230721100427/https://twir.app/
👍297
8
Может кому полезно будет: https://github.com/orval-labs/orval

Либа из openapi спеки генерит вам tanstack квери и мутации. Сам не пользовал, но выглядит интересно.
🔥6
Чутка поработал над безопасностью исполняемого пользовательского кода в Twir.

В Twir есть фича, называется scripts variable, позволяющая пользователям писать код на javascript, для расширения функционала. К примеру сходить на какое-то стороннее апи, распарсить ответ старндартными средствами js.

Конечно, это порождает дыры в безопасности, хоть это и вынесено в отдельный сервис, который занимается выполонением, но всё же, можно:
- забить эти сервисы оперативкой
- сильно забить CPU, сделав какой-то while (true) {}
- сбежать из сандбокса node:vm, и получить доступ к вайловой системе контейнера, с целью абуза, или с целью последующего взлома, попыток сбежать из докера
- повесить сервис каким-то долго выплняющимся скриптом

Половину из этих проблем я пытался решить с помощью vm2 пакета. В нём есть таймауты, вроде ограничения по RAM. Но работало там это через раз, например while (true) {} не таймаутился.

Что я решил делать с этим?

А давайте я буду запускать контейнер при каждом запросе на выполнение скрипта!

Было решено написать небольшое апи на Go, которое будет заниматься оркестрацией контейнеров (почти).
На каждый запрос на выполнение скрипта, я спавню контейнер через docker api, задавая ему лимиты по cpu, ram, времени жизни. Ограничиваю контейнеру системые capabilities, доступ к вайловой системе, а именно делаю её read-only. Пользовательский скрипт я чучуть оборачиваю:
wrapperContent := `
import { readFileSync } from 'fs';
import vm from 'node:vm'
import _ from 'lodash';

const consoleRegex = /console\.(log|debug|info|warn|error|table|trace|group|groupEnd|time|timeEnd)\s*\([^;]*\);?/g;

try {
const code = readFileSync('/code/user_code.mjs', 'utf8').replace(consoleRegex, '');
const result = await eval('(async () => { ' + code + ' })()');
console.log(JSON.stringify({ result: result.toString() }));
} catch (e) {
console.log(JSON.stringify({ error: e.message }));
}

Так я добавляю в контекст выполнения lodash, для более удобной работы с некоторыми вещами для пользователей.
Скрипт выполняется, и через докеровское апи я читаю результат выполнения из консоли.

Почему именно так? Сделано так, чтобы упростить написание скрипта для пользователя, условно чтобы он в скрипте мог сделать return 1, и без каких-либо дополнительных вещей.

Вчера ещё бился с проблемой, что пользователь можно легко узнать IP сервера, где это всё выполняется каким нибудь запросом на сайт, например https://ifconfig.me/ip. Плясал вокруг cloudflare, думал пойти вообще в сторону workers, а не докера, но в итоге получилось довольно интересно.
Оказывается, докер контейнеру можно задать network_mode другого контейнера. Что это нам даёт? Мы можем поднять рядом vpn, в лице которого я использую wrap, и пустить весь трафик контейнера через него: network_mode: "service:cloudflare-warp".
networkMode := container.NetworkMode(network.DefaultNetwork)
if os.Getenv("APP_ENV") == "production" {
networkMode = container.NetworkMode("container:executron-warp")
}

pidsLimit := int64(100)
hostConfig := &container.HostConfig{
Mounts: containerCtx.mounts,
Resources: container.Resources{
Memory: 128 * 1024 * 1024, // 128 MB
NanoCPUs: 1000000000, // 1 CPU
PidsLimit: &pidsLimit, // Limit to 100 PIDs
},
NetworkMode: networkMode,
ReadonlyRootfs: true,
AutoRemove: true,
SecurityOpt: []string{"no-new-privileges"},
CapDrop: []string{"ALL"}, // Drop all capabilities
//Runtime: "runsc",
}


На всякий случай ещё сделал, чтобы сервис не мог запустить более чем N контейнеров одновременно, через некую очередь ожидания на исполнение через атомики:
for c.runedContainers.Load() >= c.maxRunedContainers {
time.Sleep(100 * time.Millisecond)
}

c.runedContainers.Add(1)
defer c.runedContainers.Add(-1)


Всё просто, и вроде как (я надеюсь) безопасно. Я ещё пробовал дополнительный слой безопасности в виде https://gvisor.dev, но к сожалению это добавляет неплохую такую задержку при исполнении.

Буду рад любому фидбеку.

https://github.com/twirapp/ExecuTron
14🏆6🔥4
Channel photo updated
🤡6😁5🌚2
Satont.
Здравствуйте, днб слушатели. Вот вам микс на послушать под рабочий процесс: https://youtu.be/4XpCKnLJbU8
Так же напоминаю, что я веду ютуб плей-лист c днб, который регулярно пополняю. Там нет чёткой структуризации, потому можно наткнутся как на чиловые сэты, так и на нейрофанк.

Ссылка: https://www.youtube.com/watch?v=yUa_hwhGlmg&list=PL3qfVPfMnrn6y30FoOe_Whw_eJZRo9EE6
5🆒2🤯1
💯83🤗1
This media is not supported in your browser
VIEW IN TELEGRAM
2❤‍🔥21