release: prepare agent 0.6.8 publication

This commit is contained in:
2026-07-30 20:57:40 +03:00
parent c7aa286dde
commit 91388f7266
14 changed files with 570 additions and 111 deletions
+28 -32
View File
@@ -184,66 +184,62 @@ jobs:
while IFS= read -r file; do
artifact="$(basename "$(dirname "$file")")"
cp "$file" "legacy-publish/${artifact}-$(basename "$file")"
done < <(find legacy-artifacts -type f ! -name 'SHA256SUMS' -print | sort)
done < <(find legacy-artifacts -type f \( -name '*.ipk' -o -name '*.apk' \) -print | sort)
find legacy-publish -type f -print -quit | grep -q .
- name: Attest legacy release assets
uses: actions/attest-build-provenance@v2
with:
subject-path: legacy-publish/*
- name: Combine and reconstruct all release package artifacts
- name: Download current release build artifacts
env:
AGENT_TAG: ${{ inputs.agent_tag }}
GH_TOKEN: ${{ github.token }}
shell: bash
run: |
set -euo pipefail
mkdir release-assets
gh release download "$AGENT_TAG" \
release_run_id="$(
gh run list \
--repo "$GITHUB_REPOSITORY" \
--workflow build.yml \
--branch "$AGENT_TAG" \
--event push \
--status success \
--limit 20 \
--json databaseId \
--jq '.[0].databaseId'
)"
test -n "$release_run_id"
gh run download "$release_run_id" \
--repo "$GITHUB_REPOSITORY" \
--pattern 'openwrt-*' \
--dir release-assets
cp legacy-publish/* release-assets/
bash scripts/unpack-release-package-assets.sh \
release-assets \
.github/openwrt-sdk-lock.tsv \
combined-artifacts
--dir current-artifacts
- name: Prepare combined signed package repository
env:
AGENT_TAG: ${{ inputs.agent_tag }}
shell: bash
run: |
set -euo pipefail
mkdir combined-artifacts
cp -a current-artifacts/openwrt-* combined-artifacts/
cp -a legacy-artifacts/openwrt-* combined-artifacts/
bash scripts/prepare-package-repository.sh \
combined-artifacts \
package-repository \
"${AGENT_TAG#agent-v}"
- uses: sigstore/cosign-installer@v3
- name: Prepare combined release checksums
shell: bash
run: |
set -euo pipefail
(
cd release-assets
sha256sum ./openwrt-* > SHA256SUMS
)
- name: Attest combined release checksums
uses: actions/attest-build-provenance@v2
with:
subject-path: release-assets/SHA256SUMS
- name: Sign and upload combined release checksums
- name: Upload legacy packages
env:
AGENT_TAG: ${{ inputs.agent_tag }}
GH_TOKEN: ${{ github.token }}
shell: bash
run: |
set -euo pipefail
cosign sign-blob --yes \
--bundle release-assets/SHA256SUMS.sigstore.json \
release-assets/SHA256SUMS
mapfile -t legacy_files < <(find legacy-publish -type f -print | sort)
gh release upload "$AGENT_TAG" \
"${legacy_files[@]}" \
release-assets/SHA256SUMS \
release-assets/SHA256SUMS.sigstore.json \
--repo "$GITHUB_REPOSITORY" \
--clobber
+16 -14
View File
@@ -208,7 +208,7 @@ jobs:
name: openwrt-${{ matrix.release }}-${{ matrix.label }}
path: artifacts/*
if-no-files-found: error
retention-days: 30
retention-days: 90
release:
name: Publish agent GitHub release assets
@@ -233,8 +233,17 @@ jobs:
while IFS= read -r file; do
artifact="$(basename "$(dirname "$file")")"
cp "$file" "publish/${artifact}-$(basename "$file")"
done < <(find release-assets -type f ! -name 'SHA256SUMS' -print | sort)
(cd publish && sha256sum ./* > SHA256SUMS)
done < <(find release-assets -type f \( -name '*.ipk' -o -name '*.apk' \) -print | sort)
find publish -type f -print -quit | grep -q .
- name: Prepare release notes
shell: bash
run: |
set -euo pipefail
bash scripts/extract-release-notes.sh \
"$GITHUB_REF_NAME" \
CHANGELOG.md \
release-notes.md
- name: Prepare signed package repository
shell: bash
@@ -257,16 +266,6 @@ jobs:
with:
subject-path: publish/*
- uses: sigstore/cosign-installer@v3
- name: Sign release checksums with GitHub OIDC
shell: bash
run: |
set -euo pipefail
cosign sign-blob --yes \
--bundle publish/SHA256SUMS.sigstore.json \
publish/SHA256SUMS
- name: Create release and upload packages
env:
GH_TOKEN: ${{ github.token }}
@@ -278,10 +277,13 @@ jobs:
gh release upload "${GITHUB_REF_NAME}" "${files[@]}" \
--repo "${GITHUB_REPOSITORY}" \
--clobber
gh release edit "${GITHUB_REF_NAME}" \
--repo "${GITHUB_REPOSITORY}" \
--notes-file release-notes.md
else
gh release create "${GITHUB_REF_NAME}" "${files[@]}" \
--repo "${GITHUB_REPOSITORY}" \
--generate-notes \
--notes-file release-notes.md \
--title "OpenWrt RMM Agent ${GITHUB_REF_NAME#agent-v}"
fi
+10 -2
View File
@@ -132,9 +132,17 @@ jobs:
shell: bash
run: |
set -euo pipefail
if ! gh release view "$GITHUB_REF_NAME" --repo "$GITHUB_REPOSITORY" >/dev/null 2>&1; then
bash scripts/extract-release-notes.sh \
"$GITHUB_REF_NAME" \
CHANGELOG.md \
release-notes.md
if gh release view "$GITHUB_REF_NAME" --repo "$GITHUB_REPOSITORY" >/dev/null 2>&1; then
gh release edit "$GITHUB_REF_NAME" \
--repo "$GITHUB_REPOSITORY" \
--notes-file release-notes.md
else
gh release create "$GITHUB_REF_NAME" \
--repo "$GITHUB_REPOSITORY" \
--generate-notes \
--notes-file release-notes.md \
--title "OpenWrt RMM Server ${GITHUB_REF_NAME#server-v}"
fi
+57
View File
@@ -0,0 +1,57 @@
# Changelog
This file contains user-facing release notes. Every section must match its Git tag;
the release workflow fails when notes for a new tag have not been prepared.
## agent-v0.6.8
Stable agent release with more reliable LAN client presence detection.
### Added
- The agent safely probes private IPv4 addresses found in DHCP leases and reports the
results with its heartbeat.
- Probing is capped at 32 addresses, six concurrent requests, and a short timeout to
avoid noticeable load on the router or LAN.
- The server stores `first_seen`, `last_seen`, and the most recent probe time for each
client.
- The LuCI application keeps English as its default language and provides Russian through
the separate `luci-i18n-rmm-agent-ru` package.
### Fixed
- A static DHCP reservation is no longer treated as proof that a client is currently
connected.
- Clients are separated into Online, Recently online, and Unconfirmed states.
- DHCP, Wi-Fi, neighbor-table, and active-probe data are merged without duplicate
clients.
### Compatibility
- The API protocol remains `v1`; the server and agent can still be upgraded
independently.
- Existing agent configuration remains compatible without changes.
- The primary workflow builds OpenWrt 24.10 and 25.12 packages. OpenWrt 21.02, 22.03,
and 23.05 packages are added by the separate legacy workflow.
### Installation
Download the `.ipk` or `.apk` matching the OpenWrt release and target architecture.
Install `luci-app-rmm-agent` as well to configure the agent through LuCI. Install
`luci-i18n-rmm-agent-ru` for the Russian interface.
## server-v0.8.1
Corrective server release for cloud SSH and LuCI tunnels.
### Fixed
- The server validates SSH and LuCI ports issued to agents and rejects invalid
endpoints.
- Reverse-tunnel parameters are validated before they are exposed to an operator.
- Boundary-value and malformed tunnel-service response tests were added.
### Compatibility
- No database migration is required.
- The agent protocol remains `v1`.
+139
View File
@@ -0,0 +1,139 @@
<p align="center">
<img src="web/web-app-192.png" width="112" alt="OpenWrt RMM logo">
</p>
# OpenWrt RMM
[Русская версия](README_RU.md) · [Releases](https://github.com/Benya9669/openwrt-rmm/releases) · [Changelog](CHANGELOG.md) · [Security](docs/security.md)
OpenWrt RMM is a self-hosted remote monitoring and management platform for OpenWrt
routers. It combines a Go cloud server, a lightweight outbound agent, a responsive web
dashboard, temporary SSH/LuCI access, notifications, and signed OpenWrt package feeds.
The agent does not require an inbound port on the router. It connects to the server over
HTTPS and opens a restricted reverse tunnel only when an authorized operator requests
remote access.
## Highlights
- Separate user accounts and router ownership.
- One-time router enrollment grants.
- Live inventory, health metrics, connectivity checks, and LAN client presence.
- Safe allowlisted diagnostics and package/UCI operations.
- Temporary SSH and LuCI access through an isolated cloud tunnel.
- Built-in notification center, e-mail, Telegram, and signed webhooks.
- Quiet hours, maintenance pauses, and per-router alert preferences.
- Responsive web UI and a LuCI application for agent configuration.
- Signed IPK/APK repositories for supported OpenWrt releases.
## Components
```text
Browser ──HTTPS──> RMM server ──SQLite
│
├── notification workers
└── isolated SSH tunnel service
▲
OpenWrt router ──outbound HTTPS/SSH───┘
├── rmm-agent-go-production
├── luci-app-rmm-agent
└── luci-i18n-rmm-agent-ru (optional)
```
| Component | Purpose | License |
| --- | --- | --- |
| `server/`, `web/` | API, persistence, dashboard, notifications | AGPL-3.0-only |
| `deploy/tunnel/` | Restricted reverse SSH tunnel service | AGPL-3.0-only |
| `agent/` | Go agent, LuCI app, and OpenWrt packages | MIT |
## Deployment
Requirements:
- Docker Engine with Compose v2;
- an HTTPS reverse proxy such as NPMplus;
- a wildcard DNS record and certificate for cloud LuCI access;
- an SSH key dedicated to router tunnels.
Copy the example configuration and follow the production deployment guide:
```sh
cp .env.example .env
docker compose -f compose.yaml -f compose.release.yaml pull
docker compose -f compose.yaml -f compose.release.yaml up -d
docker compose -f compose.yaml -f compose.release.yaml ps
```
Do not start production with the example secrets. Generate the tunnel key and configure
the required environment values first.
- [Docker Compose deployment](docs/docker-compose.md)
- [NPMplus configuration](docs/npmplus.md)
- [KeenDNS-like wildcard router access](docs/keendns.md)
- [Architecture](docs/architecture.md)
## Installing the OpenWrt agent
The recommended method is the signed package feed:
- OpenWrt 24.10 and older: IPK/opkg;
- OpenWrt 25.12 and newer: APK;
- OpenWrt 21.02, 22.03, and 23.05: legacy support tier.
Install the runtime and LuCI application:
```sh
opkg install rmm-agent-go-production luci-app-rmm-agent
# or
apk add rmm-agent-go-production luci-app-rmm-agent
```
English is the default LuCI language. Install the optional Russian translation:
```sh
opkg install luci-i18n-rmm-agent-ru
# or
apk add luci-i18n-rmm-agent-ru
```
See [Signed OpenWrt package repository](docs/package-repository.md) for feed URLs,
verification keys, and architecture-specific instructions.
## Development
```sh
go test ./...
go vet ./...
node --check web/app.js
docker compose config
```
Run the server in explicit local development mode:
```sh
RMM_INSECURE_DEV_MODE=true \
RMM_OPERATOR_PASSWORD='replace-with-a-long-development-password' \
go run ./server/cmd/rmm-server
```
Never enable insecure development mode on an internet-facing deployment.
## Releases
The server and agent use independent version lines:
- `server-v*` publishes the server and tunnel container images;
- `agent-v*` publishes installable IPK/APK packages;
- release descriptions are maintained in English in [CHANGELOG.md](CHANGELOG.md).
GitHub Releases contain only installable packages. Signed repository indexes and public
keys are published through GitHub Pages, while provenance is kept in GitHub attestations.
See [Release policy](RELEASES.md).
## Security and license
Review [the security model](docs/security.md) before exposing the service publicly.
Back up the SQLite volume before every server upgrade.
The cloud application is licensed under `AGPL-3.0-only`; the OpenWrt agent and LuCI
packages are licensed under MIT. See [LICENSE.md](LICENSE.md) and [NOTICE.md](NOTICE.md).
+140
View File
@@ -0,0 +1,140 @@
<p align="center">
<img src="web/web-app-192.png" width="112" alt="Логотип OpenWrt RMM">
</p>
# OpenWrt RMM
[English](README.md) · [Релизы](https://github.com/Benya9669/openwrt-rmm/releases) · [Changelog](CHANGELOG.md) · [Безопасность](docs/security.md)
OpenWrt RMM — самостоятельная платформа удалённого мониторинга и управления роутерами
OpenWrt. В неё входят облачный сервер на Go, компактный исходящий агент, адаптивный
веб-интерфейс, временный доступ по SSH и LuCI, уведомления и подписанные репозитории
пакетов OpenWrt.
На роутере не требуется открывать входящий порт. Агент подключается к серверу по HTTPS,
а ограниченный обратный туннель создаётся только по запросу авторизованного оператора.
## Возможности
- Отдельные аккаунты пользователей и привязка роутеров к владельцу.
- Одноразовые коды подключения роутеров.
- Инвентаризация, метрики, проверки соединения и определение присутствия LAN-клиентов.
- Безопасный ограниченный набор диагностических, пакетных и UCI-команд.
- Временный доступ к SSH и LuCI через изолированный облачный туннель.
- Центр уведомлений, e-mail, Telegram и подписанные webhook-запросы.
- Тихие часы, режим обслуживания и настройки алертов для каждого роутера.
- Адаптивный веб-интерфейс и LuCI-приложение для настройки агента.
- Подписанные IPK/APK-репозитории для поддерживаемых версий OpenWrt.
## Компоненты
```text
Браузер ──HTTPS──> RMM-сервер ──SQLite
│
├── обработчики уведомлений
└── изолированный SSH tunnel-сервис
▲
OpenWrt-роутер ──исходящие HTTPS/SSH─────┘
├── rmm-agent-go-production
├── luci-app-rmm-agent
└── luci-i18n-rmm-agent-ru (необязательно)
```
| Компонент | Назначение | Лицензия |
| --- | --- | --- |
| `server/`, `web/` | API, база данных, интерфейс и уведомления | AGPL-3.0-only |
| `deploy/tunnel/` | Ограниченный обратный SSH-туннель | AGPL-3.0-only |
| `agent/` | Go-агент, LuCI и пакеты OpenWrt | MIT |
## Развёртывание
Потребуются:
- Docker Engine и Compose v2;
- HTTPS reverse proxy, например NPMplus;
- wildcard DNS-запись и сертификат для облачного доступа к LuCI;
- отдельный SSH-ключ для туннелей роутеров.
Скопируйте пример конфигурации и следуйте инструкции по развёртыванию:
```sh
cp .env.example .env
docker compose -f compose.yaml -f compose.release.yaml pull
docker compose -f compose.yaml -f compose.release.yaml up -d
docker compose -f compose.yaml -f compose.release.yaml ps
```
Не запускайте прод с примерными секретами. Сначала создайте ключ туннеля и заполните
обязательные переменные окружения.
- [Развёртывание через Docker Compose](docs/docker-compose.md)
- [Настройка NPMplus](docs/npmplus.md)
- [Wildcard-доступ к роутерам в стиле KeenDNS](docs/keendns.md)
- [Архитектура](docs/architecture.md)
## Установка агента OpenWrt
Рекомендуемый способ — подписанный пакетный репозиторий:
- OpenWrt 24.10 и старше: IPK/opkg;
- OpenWrt 25.12 и новее: APK;
- OpenWrt 21.02, 22.03 и 23.05: уровень legacy-поддержки.
Установите агент и LuCI-приложение:
```sh
opkg install rmm-agent-go-production luci-app-rmm-agent
# или
apk add rmm-agent-go-production luci-app-rmm-agent
```
По умолчанию интерфейс LuCI остаётся английским. Русский язык устанавливается отдельным
стандартным пакетом:
```sh
opkg install luci-i18n-rmm-agent-ru
# или
apk add luci-i18n-rmm-agent-ru
```
Адреса репозиториев, ключи проверки и инструкции для архитектур находятся в документе
[Подписанный репозиторий OpenWrt](docs/package-repository.md).
## Разработка и проверки
```sh
go test ./...
go vet ./...
node --check web/app.js
docker compose config
```
Запуск сервера в явно включённом локальном режиме разработки:
```sh
RMM_INSECURE_DEV_MODE=true \
RMM_OPERATOR_PASSWORD='replace-with-a-long-development-password' \
go run ./server/cmd/rmm-server
```
Небезопасный режим разработки нельзя использовать на публичном сервере.
## Релизы
Сервер и агент версионируются независимо:
- `server-v*` публикует контейнеры сервера и tunnel-сервиса;
- `agent-v*` публикует устанавливаемые IPK/APK-пакеты;
- подробные описания релизов ведутся на английском в [CHANGELOG.md](CHANGELOG.md).
В GitHub Release загружаются только устанавливаемые пакеты. Подписанные индексы и
публичные ключи публикуются через GitHub Pages, а provenance хранится в GitHub
attestations. Подробнее: [политика релизов](RELEASES.md).
## Безопасность и лицензирование
Перед публикацией сервиса изучите [модель безопасности](docs/security.md). Перед каждым
обновлением серверной части создавайте резервную копию SQLite volume.
Облачная часть распространяется по `AGPL-3.0-only`, агент и LuCI-пакеты — по MIT.
Подробнее: [LICENSE.md](LICENSE.md) и [NOTICE.md](NOTICE.md).
+14 -9
View File
@@ -62,22 +62,27 @@ transition period; it should not silently reuse `v1`.
## Release commands
Before creating a tag, add an English `## <tag>` section to `CHANGELOG.md`. The release
workflow uses that section verbatim and fails instead of publishing empty autogenerated
notes.
```sh
git tag -a server-v0.8.1 -m "OpenWrt RMM Server 0.8.1"
git tag -s server-v0.8.1 -m "OpenWrt RMM Server 0.8.1"
git push origin server-v0.8.1
git tag -a agent-v0.6.8 -m "OpenWrt RMM Agent 0.6.8"
git tag -s agent-v0.6.8 -m "OpenWrt RMM Agent 0.6.8"
git push origin agent-v0.6.8
```
Pushing a server tag publishes the container image and creates a GitHub Release. Pushing
an agent tag builds the full OpenWrt matrix and creates a GitHub Release with packages and
checksums. It also publishes signed package feeds through GitHub Pages. Repository setup,
key generation and router configuration are documented in
an agent tag builds the full OpenWrt matrix and creates a GitHub Release containing only
installable `.ipk` and `.apk` packages. Repository indexes, public signing keys and
provenance metadata stay in the signed GitHub Pages package feed and GitHub attestations.
Repository setup, key generation and router configuration are documented in
[`docs/package-repository.md`](docs/package-repository.md). `workflow_dispatch` can test
either workflow without creating a release.
Server and tunnel images are published with SBOM/provenance attestations and keyless
Sigstore signatures bound to the release workflow identity. Agent checksums receive the
same GitHub OIDC-backed signature. IPK and APK feeds additionally use their native OpenWrt
repository signatures so `opkg` and `apk` can enforce trust on the router.
Server and tunnel images are published with SBOM/provenance attestations bound to the
release workflow identity. Agent packages receive GitHub build-provenance attestations.
IPK and APK feeds additionally use their native OpenWrt repository signatures so `opkg`
and `apk` can enforce trust on the router.
+4
View File
@@ -7,6 +7,10 @@ Production package upgrades restart an already running agent so the new binary t
Production Go agent for OpenWrt, with the shell implementation retained as a fallback runtime.
The LuCI application uses English by default. Russian is distributed as the standard
optional `luci-i18n-rmm-agent-ru` package so the router can select either language
through its normal LuCI language settings.
The agent, LuCI application and OpenWrt packaging under `agent/` are licensed under the
MIT License. Binary OpenWrt packages install a copy of the license under
`/usr/share/licenses/<package>/LICENSE`.
+7 -35
View File
@@ -1,44 +1,16 @@
# SPDX-License-Identifier: MIT
include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-rmm-agent
PKG_VERSION:=0.2.1
PKG_RELEASE:=2
PKG_VERSION:=0.2.2
PKG_RELEASE:=1
PKG_MAINTAINER:=RMM OpenWrt
PKG_LICENSE:=MIT
PKG_LICENSE_FILES:=LICENSE
include $(INCLUDE_DIR)/package.mk
LUCI_TITLE:=OpenWrt RMM agent configuration
LUCI_DESCRIPTION:=Configure and control the OpenWrt RMM agent.
LUCI_DEPENDS:=+luci-base
LUCI_PKGARCH:=all
define Package/luci-app-rmm-agent
SECTION:=luci
CATEGORY:=LuCI
SUBMENU:=3. Applications
TITLE:=LuCI support for the OpenWrt RMM agent
DEPENDS:=+luci-base
PKGARCH:=all
endef
define Package/luci-app-rmm-agent/description
LuCI application for configuring and controlling the OpenWrt RMM agent.
endef
define Build/Compile
endef
define Package/luci-app-rmm-agent/install
$(INSTALL_DIR) $(1)/www/luci-static/resources/view/services
$(INSTALL_DATA) ./htdocs/luci-static/resources/view/services/rmm-agent.js \
$(1)/www/luci-static/resources/view/services/rmm-agent.js
$(INSTALL_DIR) $(1)/usr/share/luci/menu.d
$(INSTALL_DATA) ./root/usr/share/luci/menu.d/luci-app-rmm-agent.json \
$(1)/usr/share/luci/menu.d/luci-app-rmm-agent.json
$(INSTALL_DIR) $(1)/usr/share/rpcd/acl.d
$(INSTALL_DATA) ./root/usr/share/rpcd/acl.d/luci-app-rmm-agent.json \
$(1)/usr/share/rpcd/acl.d/luci-app-rmm-agent.json
$(INSTALL_DIR) $(1)/usr/share/licenses/luci-app-rmm-agent
$(INSTALL_DATA) ./LICENSE $(1)/usr/share/licenses/luci-app-rmm-agent/LICENSE
endef
$(eval $(call BuildPackage,luci-app-rmm-agent))
include $(TOPDIR)/feeds/luci/luci.mk
@@ -27,6 +27,16 @@ opkg install rmm-agent_*.ipk luci-app-rmm-agent_*.ipk
On apk-based OpenWrt releases, install the generated `.apk` packages instead.
English remains the built-in default language. The same build produces the standard
optional Russian translation package:
```text
luci-i18n-rmm-agent-ru
```
After it is installed, LuCI selects Russian according to the router's configured
interface language.
## Reproducible Docker build
The repository includes a containerized OpenWrt SDK build. By default it uses the
@@ -0,0 +1,81 @@
msgid ""
msgstr ""
"Project-Id-Version: luci-app-rmm-agent\n"
"Language: ru\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : "
"n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
msgid "RMM agent"
msgstr "RMM Агент"
msgid "Command failed with code %d"
msgstr "Команда завершилась с кодом %d"
msgid "RMM agent action completed."
msgstr "Действие RMM Агента выполнено."
msgid "Unable to control RMM agent: %s"
msgstr "Не удалось управлять RMM Агентом: %s"
msgid "Connect this router to your RMM account. Create a one-time enrollment grant in the RMM control panel, paste it below, save and restart the agent."
msgstr "Подключите этот роутер к своей учётной записи RMM. Создайте одноразовый код подключения в панели RMM, вставьте его ниже, сохраните настройки и перезапустите агент."
msgid "Connection"
msgstr "Подключение"
msgid "Enable agent"
msgstr "Включить агент"
msgid "RMM server URL"
msgstr "Адрес сервера RMM"
msgid "Use an HTTPS URL, or explicitly allow insecure HTTP in advanced settings."
msgstr "Используйте адрес HTTPS или явно разрешите небезопасный HTTP в дополнительных настройках."
msgid "One-time enrollment grant"
msgstr "Одноразовый код подключения"
msgid "The grant is consumed once and removed from the router after successful enrollment."
msgstr "Код используется один раз и удаляется с роутера после успешного подключения."
msgid "Polling interval"
msgstr "Интервал опроса"
msgid "Connectivity check targets"
msgstr "Адреса для проверки соединения"
msgid "Advanced settings"
msgstr "Дополнительные настройки"
msgid "Tunnel identity file"
msgstr "Файл ключа туннеля"
msgid "Allow insecure HTTP"
msgstr "Разрешить небезопасный HTTP"
msgid "Use only in an isolated lab. Agent credentials can otherwise be intercepted."
msgstr "Используйте только в изолированной тестовой сети. Иначе учётные данные агента могут быть перехвачены."
msgid "Re-enroll on next restart"
msgstr "Подключить заново при следующем запуске"
msgid "Deletes the current device identity. Create and enter a fresh one-time grant first."
msgstr "Удаляет текущую идентификацию устройства. Сначала создайте и введите новый одноразовый код подключения."
msgid "Service status"
msgstr "Состояние службы"
msgid "The RMM agent is running."
msgstr "RMM Агент запущен."
msgid "The RMM agent is stopped."
msgstr "RMM Агент остановлен."
msgid "Restart agent"
msgstr "Перезапустить агент"
msgid "Start agent"
msgstr "Запустить агент"
+10 -3
View File
@@ -141,10 +141,13 @@ RUN rm -rf tmp/info \
tmp/.packagedeps \
tmp/.packageinfo
RUN printf '%s\n' 'CONFIG_PACKAGE_luci-app-rmm-agent=m' >> .config \
RUN printf '%s\n' \
'CONFIG_PACKAGE_luci-app-rmm-agent=m' \
'CONFIG_PACKAGE_luci-i18n-rmm-agent-ru=m' \
>> .config \
&& make defconfig \
&& awk ' \
/^CONFIG_PACKAGE_(ca-bundle|ip-tiny|iwinfo|libopenssl|luci-app-rmm-agent|openssh-client|openssh-keygen|rmm-agent-go-production|zlib)=m$/ { \
/^CONFIG_PACKAGE_(ca-bundle|ip-tiny|iwinfo|libopenssl|luci-app-rmm-agent|luci-i18n-rmm-agent-ru|openssh-client|openssh-keygen|rmm-agent-go-production|zlib)=m$/ { \
print; \
next; \
} \
@@ -156,7 +159,8 @@ RUN printf '%s\n' 'CONFIG_PACKAGE_luci-app-rmm-agent=m' >> .config \
{ print; } \
' .config > .config.packages-pruned \
&& mv .config.packages-pruned .config \
&& grep -q '^CONFIG_PACKAGE_luci-app-rmm-agent=m$' .config
&& grep -q '^CONFIG_PACKAGE_luci-app-rmm-agent=m$' .config \
&& grep -q '^CONFIG_PACKAGE_luci-i18n-rmm-agent-ru=m$' .config
RUN make -j1 package/luci-app-rmm-agent/compile V=s
@@ -171,10 +175,13 @@ RUN --mount=type=secret,id=openwrt_usign_secret_b64,uid=1000,required=false \
find bin -type f \
\( -name 'luci-app-rmm-agent*.apk' \
-o -name 'luci-app-rmm-agent*.ipk' \
-o -name 'luci-i18n-rmm-agent-ru*.apk' \
-o -name 'luci-i18n-rmm-agent-ru*.ipk' \
-o -name 'rmm-agent*.apk' \
-o -name 'rmm-agent*.ipk' \) \
-exec cp '{}' /home/builder/artifacts/ \;; \
test -n "$(find /home/builder/artifacts -maxdepth 1 -type f \( -name '*.apk' -o -name '*.ipk' \) -print -quit)"; \
test -n "$(find /home/builder/artifacts -maxdepth 1 -type f \( -name 'luci-i18n-rmm-agent-ru*.apk' -o -name 'luci-i18n-rmm-agent-ru*.ipk' \) -print -quit)"; \
cd /home/builder/artifacts; \
if find . -maxdepth 1 -type f -name '*.ipk' -print -quit | grep -q .; then \
MKHASH=/home/builder/sdk/staging_dir/host/bin/mkhash \
+15 -16
View File
@@ -86,10 +86,14 @@ Run it only after the main agent release has completed. The legacy workflow:
1. checks out and builds the exact agent tag;
2. signs the IPK repositories with the configured `usign` key;
3. combines them with the current release and reconstructs the complete repository;
4. refreshes signed checksums and uploads the legacy files to the existing GitHub Release;
3. downloads retained artifacts from the original tagged workflow and reconstructs the
complete repository;
4. uploads only installable legacy packages to the existing GitHub Release;
5. redeploys the complete current plus legacy repository to GitHub Pages.
Run the legacy workflow within 90 days of the tagged build while its internal artifacts
are retained.
The workflow refuses an older agent tag because publishing it would roll the `stable`
feed back from the latest agent version.
@@ -112,6 +116,8 @@ wget -O "/etc/opkg/keys/${key_id}" "${key_base}/${key_id}"
printf 'src/gz rmm %s\n' "$feed" > /etc/opkg/customfeeds.conf.d/rmm.conf
opkg update
opkg install rmm-agent-go-production luci-app-rmm-agent
# Optional Russian LuCI translation:
opkg install luci-i18n-rmm-agent-ru
```
The workflow creates `Packages`, `Packages.gz` and `Packages.sig`. `opkg` verifies the
@@ -130,6 +136,8 @@ wget -O /etc/apk/keys/rmm-openwrt.pem "${base}/keys/apk/rmm-openwrt.pem"
printf '%s\n' "$repo" > /etc/apk/repositories.d/rmm.list
apk update
apk add rmm-agent-go-production luci-app-rmm-agent
# Optional Russian LuCI translation:
apk add luci-i18n-rmm-agent-ru
```
APK verifies the signed `packages.adb` index. Installation should not require
@@ -138,17 +146,8 @@ not configured correctly.
## Release verification
Release assets also include a keyless Sigstore bundle for the combined checksums:
```sh
cosign verify-blob \
--bundle SHA256SUMS.sigstore.json \
--certificate-identity-regexp \
'^https://github.com/Benya9669/openwrt-rmm/.github/workflows/(build\.yml@refs/tags/agent-v.*|build-legacy\.yml@refs/heads/main)$' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
SHA256SUMS
sha256sum --check SHA256SUMS
```
This Sigstore verification complements native package-manager trust; it does not replace
the `usign` or APK repository signature.
GitHub Releases contain only installable `.ipk` and `.apk` files. GitHub build-provenance
attestations remain available through the repository attestations page and GitHub CLI.
Package-manager installations rely on the signed feed: `opkg` verifies `Packages.sig`,
while APK verifies `packages.adb`. Public verification keys are served through GitHub
Pages and are not duplicated as release assets.
+39
View File
@@ -0,0 +1,39 @@
#!/usr/bin/env bash
set -euo pipefail
if [ "$#" -ne 3 ]; then
echo "usage: $0 <tag> <changelog> <output>" >&2
exit 2
fi
tag="$1"
changelog="$2"
output="$3"
if [ ! -f "$changelog" ]; then
echo "changelog does not exist: $changelog" >&2
exit 1
fi
mkdir -p "$(dirname "$output")"
if ! awk -v heading="## ${tag}" '
$0 == heading { found = 1; next }
found && /^## / { exit }
found { print }
END {
if (!found) {
exit 3
}
}
' "$changelog" > "$output"; then
rm -f "$output"
echo "release notes section is missing: ## ${tag}" >&2
exit 1
fi
if ! grep -q '[^[:space:]]' "$output"; then
rm -f "$output"
echo "release notes section is empty: ## ${tag}" >&2
exit 1
fi