慣性聚合 高效追讀感興趣之博客、新聞、科技資訊
閱原文 以慣性聚合開啟

推薦訂閱源

博客园 - 司徒正美
V
V2EX
T
Tailwind CSS Blog
有赞技术团队
有赞技术团队
aimingoo的专栏
aimingoo的专栏
Apple Machine Learning Research
Apple Machine Learning Research
IT之家
IT之家
Blog — PlanetScale
Blog — PlanetScale
A
About on SuperTechFans
月光博客
月光博客
T
The Blog of Author Tim Ferriss
宝玉的分享
宝玉的分享
Martin Fowler
Martin Fowler
博客园 - 聂微东
The GitHub Blog
The GitHub Blog
V
Visual Studio Blog
WordPress大学
WordPress大学
酷 壳 – CoolShell
酷 壳 – CoolShell
Engineering at Meta
Engineering at Meta
GbyAI
GbyAI

Все публикации подряд на Хабре

Ловим музу за клавиатуру: как айтишнику стать автором Что умеет Midjourney в 2026? Мой немного грустный разбор этого шикарного инструмента Никто не любит писать тесты, но ИИ может исправить это IPv8 выглядит как мечта. Поэтому почти наверняка не взлетит Производители вернули в продажу материнки с DDR3. Что происходит? Управление агентом с телефона через Telegram теперь в KodaCode От координации к лидерству: как меняется роль руководителя разработки Я сделала родителям бизнес вместо пенсии: зарабатываем 70 тысяч, мама не даёт продать В три раза быстрее приемка товара и оптимизация трудозатрат на 73%: как «РСТ-Инвент» помог Gulliver Group ИИ-шечный мир победил? О влиянии искусственного интеллекта на игропром Кремль снижает давление на Телеграмм пока Европа строит интернет по паспорту Как CEO, CTO и CIO за 8 часов собрали ИИ-директора, который умеет держать позицию под давлением Как (не) потерять домен за выходные Вместо 8 разных VPS: как я организовал практику студентам на одном сервере Почему твой Open Source проект не замечают? R&D: искусство управления неопределенностью в разработке AI-дефляция: вакансий для разработчиков больше, а рост зарплат — худший за 15 лет Мы отдали управление роботами OpenClaw. Что из этого вышло Галактический ID: система идентификации для всех форм разумной жизни Кто решает судьбу вашего проекта? Разбираем заинтересованные стороны. BABOK #1 Код-ревью, в котором дело не в коде Данные переехали. Команда — нет Системной подход к сдаче OSWE в 2025 Почему комната управления реактором покрашена в цвет морской пены 4 YAML-файла вместо PySpark: как аналитикам строить пайплайны без разработчиков LLM-агент для поиска свободных доменов: автоматизируем подбор Когда, зачем и как правильно начинать новую сессию в Claude Code? Как я заставил нейросеть писать макросы для FreeCAD Анатомия ИИ‑агента для подбора персонала. От тысячи резюме к топ‑10 за минуты Опыт разработчика как экономика внимания Автономность как точка невозврата: кто будет субъектом в цифровом будущем Обучение ИИ в «диких» условиях: как рутинные действия превращаются в датасеты Как измерить LLM для задач кибербеза: обзор открытых бенчмарков Где хранить код? Сравнение GitHub, GitLab и Bitbucket Математика объясняет, почему нормальное распределение встречается повсюду Почему ваш FinOps не работает: 12 тезисов от практиков Как подписать проектную документацию УКЭП с использованием бесплатных лицензий Pilot Адаптивное администрирование Sigla Vision Я грузил уран в бочки, а потом 20 лет строил ИТ в атомной отрасли Чем позвонить с Эвереста? История и обзор спутниковой связи. Часть 2 Как языковая модель помогает контролировать качество инструктажей по охране труда в металлургии Как не передать на desktop свой IP в РКН Анатомия SAP Privileges: как устроено управление правами в macOS MoneyDev: Сказка про три главных слова Обновлённый токенизатор видео K-VAE 2.0 от Сбера Как сделать диспетчеризацию дома на 1284 квартиры почти бесплатно Как мы разогнали железную дорогу Мы дали агентам рутину. Теперь надо решить — что делать с освободившимся временем Токсичный контент, промпт-хакинг и защита ИИ — всё о Guardrails для LLM Умный город начинается с точного взгляда: как Фалькон Тех меняет пространство к лучшему
RustDesk Pro 不可得于俄罗斯。经年累月,吾辈终得己之诚解。
arturwise · 2026-05-24 · via Все публикации подряд на Хабре

难度等级中等

阅读时长十分钟

传播与读者八十三

案例

一文人,十载管他人之机,今乃行己所欲为之事.

取官方版 RustDesk (AGPLv3),吾等不立分支,每建客户端,即于 GitHub Actions 中实时补丁之。其上,乃俄罗刹之基设:服务器在俄,付账依法人账单,企业 SSO 经 Active Directory 与 Яндекс ID,且御 Android 诈伪之患。

吾名阿尔图尔·瓦利耶夫。非为采购而作「进口替代认证之解决方案」。唯一可用之产品,吾昔居客户支持之位,十年前欲用之,今犹自用也。

吾何故为此

十载间,吾为黑客,后为系统管理员,复为IT外包之支持工程师。尝用TeamViewer、AnyDesk、LiteManager、AeroAdmin、Ammyy,凡目之所及,皆历之也。 之列。人各有其烦:

  • AnyDesk谓汝为商用者,若助母调 printer 二度

  • LiteManager -尝试之,然界面乃二千零八年纪之旧物,且许可按件计,甚不便

  • RuDesktop -其详别述于下

论 AGPLv3 之诚(及何以吾非「如 RuDesktop」)

吾初启之时,观俄罗斯之竞者。其显者有RuDesktop。其网站有丽徽曰「Реестр росПО」,曰「Сертификация ФСТЭК」,复有公开之辞,言「自出之制」。然此实为RustDesk之分支,而未公之于源码,是何故耶? 直违AGPLv3.

AGPL非「可阅而忘」之谓也。用之则改之而公之,布之若网,亦公之。人知其用,则皆可索其本源。

吾不欲如是。此虽暂利(竞标时无人察之),然久则如悬刃。待RustDesk警觉而讼,此等徽章皆将湮灭。

是故吾择 「不分支」之道。之注解在后者.

要旨于技术:于运行时补上游源

为开源产品立基之常法:

  1. 分叉其库

  2. 直于码中易之

  3. 永护其分叉:每上游之更新,必手合之,解其纷争

此法可行,然岁余,上游将远去,维护分支实为苦。RustDesk之提交,日日而至。

吾行殊途。 工作流组件仓库甚简 上载于上游,以 sed 修之 方集客户之时

- name: Checkout RustDesk source (master)
  uses: actions/checkout@v4
  with:
    repository: rustdesk/rustdesk
    ref: master
    submodules: recursive

- name: Aggressive rebrand
  if: ${{ inputs.rebrand_strings == 'true' }}
  run: |
    find ./flutter/lib -name "*.dart" -type f \
      -exec sed -i "s|RustDesk|${APP_NAME}|g" {} +

    sed -i "s|hbb_common::config::APP_NAME.read().unwrap().clone()|\"${APP_NAME}\".to_string()|g" \
      ./src/common.rs

    sed -i "s|android:scheme=\"rustdesk\"|android:scheme=\"${BRAND_LOWER}\"|g" \
      ./flutter/android/app/src/main/AndroidManifest.xml

每建版本,必引新源(或特定标签,客户所请),施吾之补丁,成之,去之。其果为 .exe.apk.dmg.deb 以奉客户。

Создание клиента

立客户

此何益

  • 吾不必布分叉之枝 - 盖因无分支。有下游补丁,公之于众(于吾工作流仓库),且兼容AGPL。

  • 上游自动更新 - 欲集 RustDesk 1.4.5乎?示之 version: 1.4.5 - 工作流自会牵引。

  • 公司之每一客户,皆独立之集合也 持己之品牌,有己之铭文(tenant slug),具己之功能。

何等困厄

首頁 上游破名吾昔尝加 sed-патч 于锚下 PopupMenuButton<String>上游者于次版本更名此小件。塞德默然未得此式。continue-on-error: true), 装配已毕,然 功能未增启客户所集,无“求助”之钮。久寻其故。

法:书 御侮多锚补丁 ,察补丁实施:

sed -i "s|buildTip(context),|buildTip(context),\n  Padding(...)|" desktop_home_page.dart
echo "Verification:"
grep -c "showSupportRequestDialog" desktop_home_page.dart || \
  echo "⚠️ Patch did not apply!"

今诸补丁皆验——若grep返零,则于构建日志见弊,可速正正则。

御诈:去Android来者之术。

此乃Google Play、RuStore及安全认证者所欣然接纳吾之 сборка 之由也。

Часть окна сборки клиента Android

Android客户端构建窗口之一隅

俄罗斯诈骗之剧本:

  1. 银行来电,诈称“老人家”

  2. 下载应用/AnyDesk/RustDesk

  3. 老人家授其ID

  4. 诈者入内,转款于Сбербанк Онлайн

吾以物理之法,自安卓之包中剜除入模式。 若以 outgoing_only=true之旗而筑之:

# 1. На уровне Rust: is_outgoing_only() всегда true
sed -i -E 's|SyncReturn\(config::is_outgoing_only\(\)\)|SyncReturn(true)|g' \
  src/flutter_ffi.rs

# 2. На уровне Dart: насильно скрываем Server tab
sed -i 's|if (isAndroid && !bind.isOutgoingOnly())|if (false)|' \
  flutter/lib/mobile/pages/home_page.dart

# 3. Из AndroidManifest удаляем опасные permissions
sed -i '/<uses-permission[^>]*FOREGROUND_SERVICE_MEDIA_PROJECTION[^>]*/d' "$MANIFEST"
sed -i '/<uses-permission[^>]*RECORD_AUDIO[^>]*/d' "$MANIFEST"
sed -i '/<uses-permission[^>]*SYSTEM_ALERT_WINDOW[^>]*/d' "$MANIFEST"

则于所成之APK 中,实无 取接之UI,亦无摄屏/摄声/overlay之许。既下既置既启,唯一可为者:书ID而接于PC。欲取接之 ,则不可得。自非全然.

此乃:

  • 护祖母辈;)

  • 得于Google Play / RuStore布文无阻(理应然——Kaspersky犹有微词,详下文)

  • 可呈于俄罗软件之录,号曰「安全之远程管理器」

然Kaspersky何如?

吾将APK投诸RuStore,卡巴斯基乃觉之。 not-a-virus:HEUR:RemoteAdmin.AndroidOS.RustDesk.a前缀 not-a-virus 此谓PUA(潜在不受欢迎应用),与AnyDesk/TeamViewer同属一类。

启发式之法应于其迹 librustdesk.so 在APK中。其解法,乃临时更易本生之库名:

NATIVE_NAME="evertydesk"
# Файл .so копируется в jniLibs под новым именем
cp ./target/release/liblibrustdesk.so \
   ./flutter/android/app/src/main/jniLibs/arm64-v8a/lib${NATIVE_NAME}.so

# И Kotlin загружает по новому имени
sed -i "s|System.loadLibrary(\"rustdesk\")|System.loadLibrary(\"${NATIVE_NAME}\")|" \
  ./flutter/android/app/src/main/kotlin/com/.../ffi.kt

复诉于RuStore,释此乃PUA,吾客户唯出而不入,且"非病毒"者,实非病毒也。当决之。候之。

智代理——同事间点对点之助

此功能,非TeamViewer、非AnyDesk、非RustDesk之所有也

Окно собранного клиента

已集之客户之窗

于定制客户中,吾注入别之Dart服务(agent_service.dart者,于RustDesk之进程中隐运不息。其功有三:

  1. 脉动 ,每分钟叩吾之伺,以陈机之在否;

  2. 箱候 ,三十秒一探,以纳入之讯,若管者之推;

  3. 求援 ,客按UI之钮,择司者,彼得弹窗,列钮以待。 [Принять] [Через 10 мин] [Через час] [Отклонить]

此乃 RustDesk 协议之上构建之架构, 别设一通道,不假 relay。经吾 HTTP API.

class AgentService {
  static const Duration kInboxInterval = Duration(seconds: 30);
  static const Duration kHeartbeatInterval = Duration(minutes: 1);

  Future<void> _checkInbox() async {
    final resp = await http.get(
      Uri.parse('$_apiServer/admin/agent/inbox').replace(queryParameters: {
        'machine_id': _machineId,
        'service_key': _serviceKey,
      }),
    ).timeout(kHttpTimeout);

    if (resp.statusCode != 200) {
      _inboxFailures++;
      return;
    }
    _inboxFailures = 0;

    final items = jsonDecode(resp.body)['items'] as List;
    for (final item in items) {
      if (item['type'] == 'support_ping') {
        showSupportPingDialog(ctx, item); // Popup сдействиями
      }
      // ... друге типы: banner, poll, config_update
    }
  }
}

此处有一趣事:初时,吾仅将 target_machine_id 存为字符串于 target_ids AgentNotification 之域。然服务器之收件过滤程序,视此为 JSON 数组。Json.Unmarshal 遂败 → continue → 通知失。 默然无应。症候若「按之求援,寂然无动」。诊之需时二刻:

// Было:
TargetIds: resolvedTarget,  // ← "abc123"

// Стало:
targetIdsJson, _ := json.Marshal([]string{resolvedTarget})
TargetIds: string(targetIdsJson),  // ← `["abc123"]`

训曰:若汝之解析严苛,而具 continue-on-error,则谬误隐匿。故吾今于往昔之 silent-fail 处,皆增计数器(_inboxFailures++)而录之.

级二:器物附于租户,乃于接续之际。者,乃 RustDesk 之原生,于租户之事一无所知。吾甚异之:RustDesk 之客户端 (/api/heartbeat) 所发心跳,不载租户 ID 之信息,惟有 {id, uuid, conns}而已。是故,十公司皆将心跳发于同一之默认账号.

。解此困,赖 Smart Agent 之力。此物知其 service_key (公司之 slug,于构建时已嵌入),每六十息,即将其发往。 /admin/agent/heartbeat:服务器

//        на каждом агентском heartbeat:
if saId > 0 {
  // Находим Device с тем же rustdesk_id и перепривязывем к правильному тенанту
  c.Db.Where("rustdesk_id = ?", machineId).
    Cols("service_account_id", "is_pending").
    Update(&model.Device{
      ServiceAccountId: saId,
      IsPending:        false,
    })
}

者,即设备初入"待处理池"(隐于众目),继而Smart Agent"取"之,归其所属之租户。自客户端安顿后,三十至六十息间,机显于该公司之厅堂。

复有:待处理池犹若"审察"——若代理缘何未起,主人于管理界面见"纳机"之钮,可手缚于客户端。此 以AnyDesk风格进行入会 于极简之境.

企业级SSO:Active Directory + Яндекс ID

Часть страницы для настройки AD

AD配置之页

LDAP/AD 其实现之术 不须补丁于客户端者, RustDesk之用户,按“登录”钮,入域名之登录/密码。服务器察其租户有LDAP,遂试bind。若成,则立用户,返以令牌。Klein之客户端不知其与LDAP语,但取之而已。

// В service/ldap.go:
func LdapAuthenticate(cfg *model.LdapConfig, username, password string) (*LdapAuthResult, error) {
    conn, _ := ldap.DialURL(cfg.ServerUrl)
    defer conn.Close()

    // 1 Bind как сервисный  аккаунт для поиска
    conn.Bind(cfg.BindDn, cfg.BindPassword)

    // 2 Найти пользователя по фильтру
    filter := strings.ReplaceAll(cfg.UserFilter, "{username}",
                                 ldap.EscapeFilter(username))
    res, _ := conn.Search(...)

    // 3 Bind КАК этот пользователь это и есть проверка пароля
    if err := conn.Bind(res.Entries[0].DN, password); err != nil {
        return nil, fmt.Errorf("invalid_credentials")
    }

    // 4 Опционально проверить вхождение в разрешёную группу
    return &LdapAuthResult{...}, nil
}

。复于标准 /api/login

if !get {
    // Пользователь не существует локально
    res, accId, err := LdapTryAllAccounts(db, username, password)
    if err == nil && res != nil {
        // LDAP принял! Создаём User под нужным тенантом
        user = autoProvisionFromLdap(res, accId)
    }
}

结果:公司客户将LDAP纳入其办公室,所有员工皆可无额外注册,以域账号登录RustDesk客户端。员工若遭解雇(于AD中停用),其下次登录RustDesk 将直接无法通过

雅虎ID 乃依標準OAuth 2.0加設備授權之賦值(RFC 8628)以實現。於網頁控制台,設「通過雅黑登入」之按鈕,引導至回呼。至桌面客戶端,則行設備碼流:客戶端得碼,示對話「啟yandex.com/device,入ABCD-EFGH」,用戶入之,客戶端得憑證。此乃CLI工具之標準(gh auth loginaws sso login)。

俄羅斯法人之賬務與支付。

此乃西土SaaS之初创公司,假Stripe以省时之地也。然Stripe于俄境不兴。

吾之用者:

  • 优客萨(YooKassa) 于自然人,直纳其API入柜中。

  • 法人偿款,别设其程。 其法若此:

    1. 客于柜中击“偿据”,入其税号/商号/款目而毕。

    2. 服务器生成 InvoiceRequest 唯一编号 2026-0042

    3. 吾于管理界面见申请,于银行开具PDF(吾有网点),上传于系统

    4. 客户得电子邮件,附下载账单之链接

    5. 付款→资金入账户

    6. 吾于管理界面标注「已付」→订阅自动激活

非谓此乃商业之新创,然 俄境嵌入式B2B计费无成法 实无。众皆以木偶支撑。

铁骨,数字,虚言。

构件。

术法。

后端API。

Go + Iris MVC。

根基。

PostgreSQL 16。

前端(厅堂,门面)。

Vue 3 + Naive UI + Vite。

客(案)

RustDesk官版+补丁

智策(内于客)

Flutter/Dart

构作

GitHub Actions

布署

Docker Compose

独客构作需二刻至四刻(其大半为Rust编译)。四平台(Win/Linux/macOS/Android)并行构作。

至二零二六年五月末,吾将:

  • 稳定之SaaS发布

  • 安卓于Google Play及RuStore(RuStore现正申诉,因 HEUR:RustDesk 检测问题)

定价尚待测试,

异于RuDesktop,吾不与投资者立公司,无埃勒圆圈之商业计划,亦无首季获ФСТЭК认证为KPI。

吾但解此困,其扰吾久矣:『予我正法俄式远程桌面,其许可之清白,安于终端者,且可依俄式之制偿之』。况吾素贪读《哈勃》之 RustDesk 文,今已得四『试客』,姑且继之。

至若要者,自置版之设:为不适云者谋之。

非每公司皆可强令远程支持寄于他方云海。官署、银行、医坊、国防工业之域,及有自设信息安全之企业——其政策明文昭示,不容置疑。 数据处之域内,点也此无益之争也。

故与SaaS并行,吾亦为之。 自托管版本 同此产品。同此代码基础,同此功能,然皆于客户之铁器或其私有云中启动。

何所含

# docker-compose.yml у клиента после установки
services:
  everty-desk-api:        # Go backend + Vue cabinet
    image: everty-desk/api:1.0
  everty-desk-postgres:   # PostgreSQL
    image: postgres:16-alpine
  everty-desk-hbbs:       # RustDesk ID server
    image: rustdesk/rustdesk-server:latest
  everty-desk-hbbr:       # RustDesk relay
    image: rustdesk/rustdesk-server:latest

一 docker compose up -d,脚本安装器Pro证书Let's Encrypt(或下载自备),数据库迁移——毕矣。 无外部之鸣于我等之服务器。 全然隔绝。

何以許可之

許可證 - 年度,通過簽名之JWT鑰線下啟動。無需「線上檢查」,若網絡中斷,則不至使伺服器停運。現有簡略文獻此處

許可權繫於域名(JWT內白名單之主機名),以防複製至他之實例。及期,則漸降:一月前示警,既滿,新接連者阻絕,然 既存之機器與址簿, 仍存至續期時。無「盡毀」之患。

自托管者,凡物皆可纳,然诸般设置、授权、令牌,皆须尔自为。

其状:尚在试炼,其时:六月之末。

今即自托管之版 方在试炼中。 吾已别设一机,并行安装,察其迁移、授权、隔离、更新之事。与试炼者,诚有难处,若尔等有志,可致信info@everty.ru,注明事由。

至二零二六年六月末——稳定版一零发布 含

  • 完整安装脚本(curl install.everty.ru/selfhost.sh | sh

  • 详尽文档(自docker compose至nginx反向代理及Let's Encrypt)

  • 通过吾之管理面板实现许可证生命周期管理

  • 首年漏洞修复SLA

  • 更新渠道: stable / beta / edge

谢君卒读,若欲论技之详,吾乐于答于注中.

info@everty.ru
desk.everty.ru