diff --git a/DOCS.md b/DOCS.md index c3c306b..a69b9e5 100644 --- a/DOCS.md +++ b/DOCS.md @@ -120,39 +120,60 @@ Save this token — you'll need it to access the Gateway Web UI and for API inte The Gateway Web UI (Control UI) is OpenClaw's main web interface. It opens in a **separate browser tab** because Home Assistant's Ingress proxy has WebSocket limitations. -### Setting up the "Open Gateway Web UI" button +> **Important (v2026.2.21+):** OpenClaw now requires a **secure context** (HTTPS or localhost) for the Control UI. Plain HTTP over LAN is no longer accepted. The add-on's `access_mode` option makes this easy — see below. +> +> **v2026.2.22 note:** The gateway now emits a startup security warning when `dangerouslyDisableDeviceAuth` is active (used by `lan_https` mode). This warning is **expected and safe to ignore** — token authentication is still enforced. -Set `gateway_public_url` in the add-on configuration to the URL where the gateway is reachable from your browser. +### Choosing an access mode -**Examples**: -- LAN: `http://192.168.1.119:18789` -- Public HTTPS: `https://example.duckdns.org:12345` +Set `access_mode` in **Settings → Add-ons → OpenClaw Assistant → Configuration**: -The button opens: `/?token=` +| Mode | Best for | What it does | +|---|---|---| +| **`lan_https`** | Phones, tablets, LAN browsers | Adds a built-in HTTPS proxy inside the add-on. No external setup needed. | +| **`lan_reverse_proxy`** | Users with NPM / Caddy / Traefik | Binds gateway to LAN; your proxy terminates TLS. | +| **`tailnet_https`** | Tailscale users | Binds to Tailscale interface; use Tailscale HTTPS certs. | +| **`local_only`** | Terminal/Ingress only | Loopback — gateway not reachable from other devices. | +| **`custom`** | Advanced / backward compat | Uses the individual `gateway_bind_mode` / `gateway_auth_mode` settings. | -### How to make the Gateway reachable +### Method A — Built-in HTTPS proxy (`lan_https` — recommended) -Choose the method that fits your setup: - -#### Method A — HTTPS via reverse proxy (recommended) - -If you use a reverse proxy (e.g., Nginx Proxy Manager, Caddy, Traefik, Cloudflare Tunnel), configure it to also forward the gateway port (default 18789) with HTTPS. This is the most secure option and avoids browser security warnings. - -> **Note**: Nabu Casa remote access only proxies the Home Assistant UI (port 8123) — it cannot forward custom ports like 18789. The add-on's Ingress page (landing + terminal) works through Nabu Casa, but the Gateway Web UI requires a reverse proxy or LAN access. - -#### Method B — LAN HTTP access (most common) - -Enable LAN access via the add-on configuration: +This is the simplest way to get secure LAN access, especially for phones and tablets. 1. Go to **Settings → Add-ons → OpenClaw Assistant → Configuration** -2. Set: - - `gateway_bind_mode`: **lan** - - `gateway_port`: **18789** (or your preferred port) - - `allow_insecure_auth`: **true** (required for HTTP — see below) - - `gateway_public_url`: `http://:18789` +2. Set `access_mode`: **lan_https** 3. Restart the add-on -#### Method C — SSH port forwarding (secure, no config changes) +**What happens automatically:** +- The add-on generates a local CA certificate and a TLS server certificate +- nginx listens on the gateway port (default 18789) with HTTPS on all interfaces +- The gateway process itself binds to loopback on an internal port (gateway_port + 1) +- The landing page shows a **Download CA Certificate** button + +**Phone/tablet setup (one-time):** +1. Open the add-on page in HA and click **Download CA Certificate** +2. Install the certificate on your device: + - **Android**: Settings → Security → Install certificate → CA certificate → select file + - **iOS**: Open the `.crt` file → Install Profile → Settings → General → About → Certificate Trust Settings → enable the OpenClaw CA +3. After installing the CA, your browser will trust the gateway without warnings + +> **Note**: If you skip CA installation, you can still access the gateway — just accept the browser's certificate warning once. + +### Method B — HTTPS via external reverse proxy + +If you already run a reverse proxy (NPM, Caddy, Traefik): + +1. Set `access_mode`: **lan_reverse_proxy** +2. Set `gateway_trusted_proxies` to your proxy's IP/CIDR (e.g., `127.0.0.1,192.168.88.0/24`) +3. Set `gateway_public_url` to your HTTPS URL +4. Configure your proxy to forward HTTPS to `:18789` +5. Restart the add-on + +See the landing page's **Reverse-proxy recipes** section for copy-paste configs. + +> **Note**: Nabu Casa remote access only proxies port 8123 — it cannot forward custom ports. The Ingress page works through Nabu Casa, but the Gateway UI requires one of the methods above. + +### Method C — SSH port forwarding (secure, no config changes) Forward the gateway port from your HA host to your local machine: @@ -160,18 +181,40 @@ Forward the gateway port from your HA host to your local machine: ssh -L 18789:127.0.0.1:18789 your-user@your-ha-ip ``` -Then open `http://localhost:18789` in your browser. No need to change `gateway_bind_mode` or `allow_insecure_auth`. +Then open `http://localhost:18789` in your browser. `localhost` counts as a secure context. + +> **Limitation**: SSH forwarding doesn't work on phones/tablets. Use `lan_https` for mobile access. + +### Method D — Tailscale HTTPS + +1. Set `access_mode`: **tailnet_https** +2. Enable HTTPS certificates in your Tailnet admin: **DNS → HTTPS Certificates** +3. On the HA host: `tailscale cert .ts.net` +4. Set `gateway_public_url` to `https://.ts.net:18789` +5. Restart the add-on + +### Setting up the "Open Gateway Web UI" button + +Set `gateway_public_url` in the add-on configuration to the URL where the gateway is reachable from your browser. + +**Examples**: +- LAN HTTPS (built-in): `https://192.168.1.119:18789` +- External HTTPS: `https://openclaw.example.com` +- Tailscale: `https://ha-machine.ts.net:18789` + +> **Tip**: In `lan_https` mode, if you leave `gateway_public_url` empty, the add-on auto-constructs it from the detected LAN IP. ### Browser security: "requires HTTPS or localhost" -Modern browsers block certain features on plain HTTP (non-localhost). If you see this error: +If you see: > control ui requires HTTPS or localhost (secure context) +> disconnected (1008): control ui requires device identity -**Solutions** (pick one): -- **Use HTTPS** (Method A above) — best long-term -- **Use SSH port forwarding** (Method C above) — `localhost` counts as secure -- **Enable `allow_insecure_auth`** — quick workaround for LAN HTTP access +This means the browser is connecting over plain HTTP. **Solutions**: +- Set `access_mode` to **lan_https** (easiest — no external setup) +- Set `access_mode` to **lan_reverse_proxy** and use an HTTPS reverse proxy +- Use SSH port forwarding to `localhost` (desktop only) ### Unauthorized error @@ -198,11 +241,15 @@ All options are set via **Settings → Apps/Add-ons → OpenClaw Assistant → C | Option | Type | Default | Description | |---|---|---|---| | `gateway_mode` | `local` / `remote` | `local` | **local**: run gateway in this add-on. **remote**: connect to an external gateway | -| `gateway_bind_mode` | `auto` / `loopback` / `lan` / `tailnet` | `loopback` | **loopback**: 127.0.0.1 only (secure). **lan**: all interfaces (LAN-accessible). **tailnet**: Tailscale interface only. **auto**: let OpenClaw choose bind behavior. Only applies when `gateway_mode` is `local` | +| `gateway_bind_mode` | `loopback` / `lan` / `tailnet` | `loopback` | **loopback**: 127.0.0.1 only (secure). **lan**: all interfaces (LAN-accessible). **tailnet**: Tailscale interface only. Only applies when `gateway_mode` is `local` | | `gateway_port` | int | `18789` | Port for the gateway. Only applies when `gateway_mode` is `local` | -| `gateway_public_url` | string | _(empty)_ | Public URL for the "Open Gateway Web UI" button. Example: `http://192.168.1.119:18789` | +| `access_mode` | `custom` / `local_only` / `lan_https` / `lan_reverse_proxy` / `tailnet_https` | `custom` | **Simplifies secure access setup.** `custom`: use individual settings (backward-compatible). `lan_https`: built-in HTTPS proxy for LAN (recommended for phones). `lan_reverse_proxy`: external reverse proxy. `tailnet_https`: Tailscale. `local_only`: Ingress only. See [Accessing the Gateway Web UI](#4-accessing-the-gateway-web-ui) | +| `gateway_public_url` | string | _(empty)_ | Public URL for the "Open Gateway Web UI" button. Auto-constructed in `lan_https` mode if empty. Example: `https://192.168.1.119:18789` | | `enable_openai_api` | bool | `false` | Enable the OpenAI-compatible `/v1/chat/completions` endpoint. Required for [Assist pipeline integration](#6c-assist-pipeline-integration-openai-api) | -| `allow_insecure_auth` | bool | `false` | Allow HTTP (non-HTTPS) authentication on LAN. **Required** for browser access over plain HTTP | +| `gateway_auth_mode` | `token` / `trusted-proxy` | `token` | Gateway auth mode. Use `trusted-proxy` when terminating HTTPS in a reverse proxy and forwarding trusted auth headers. | +| `gateway_trusted_proxies` | string | _(empty)_ | Comma-separated trusted proxy IP/CIDR list used with `gateway_auth_mode: trusted-proxy`. | + +When `gateway_auth_mode: trusted-proxy` is used, the add-on sets `gateway.auth.trustedProxy.userHeader` to `x-forwarded-user` by default. | `force_ipv4_dns` | bool | `false` | Force IPv4-first DNS ordering for Node network calls. Useful if IPv6 DNS resolves but IPv6 egress is broken (can affect Telegram API polling). | ### Terminal @@ -217,7 +264,7 @@ All options are set via **Settings → Apps/Add-ons → OpenClaw Assistant → C | Option | Type | Default | Description | |---|---|---|---| | `homeassistant_token` | string | _(empty)_ | Optional HA long-lived access token (use at own risk, can be very unsecure but very powerful). Saved to `/config/secrets/homeassistant.token` for use by scripts/skills | -| `http_proxy` | string | _(empty)_ | Optional outbound proxy URL for HTTP/HTTPS requests from OpenClaw and Node tools. Example: `http://192.168.2.1:3128`. When set, the add-on also applies `NO_PROXY/no_proxy` defaults for localhost and private network ranges. | +| `http_proxy` | string | _(empty)_ | Optional outbound proxy URL for HTTP/HTTPS requests from OpenClaw and Node tools. Example: `http://192.168.2.1:3128` | ### Router SSH @@ -244,22 +291,34 @@ To provide the SSH key: place the private key file in the add-on config director ### 6a. LAN Access Setup -This is the most common setup — accessing the Gateway Web UI from a browser on your local network. +This is the most common setup — accessing the Gateway Web UI from a browser on your local network (including phones and tablets). + +> **Since OpenClaw v2026.2.21**, the Control UI requires a secure context (HTTPS or localhost). Use the `access_mode` option for easy setup. + +#### Option 1 — Built-in HTTPS proxy (recommended) + +1. Go to **Settings → Add-ons → OpenClaw Assistant → Configuration** +2. Set `access_mode`: **lan_https** +3. Restart the add-on +4. Click the **Open Gateway Web UI** button — it uses HTTPS automatically + +**Phone/tablet (one-time):** Click **Download CA Certificate** on the landing page, then install it on your device for trusted access without browser warnings. + +#### Option 2 — External reverse proxy 1. Go to **Settings → Add-ons → OpenClaw Assistant → Configuration** 2. Set these options: | Option | Value | |---|---| -| `gateway_bind_mode` | **lan** | -| `gateway_port` | **18789** | -| `allow_insecure_auth` | **true** | -| `gateway_public_url` | `http://:18789` | +| `access_mode` | **lan_reverse_proxy** | +| `gateway_trusted_proxies` | **127.0.0.1,192.168.88.0/24** | +| `gateway_public_url` | `https://` | -3. Restart the add-on -4. Open the **Open Gateway Web UI** button — it should now work from any device on your LAN +3. Configure your reverse proxy to forward HTTPS to `:18789` +4. Restart the add-on -**Security note**: `allow_insecure_auth` allows authentication over plain HTTP. This is fine on a trusted home network but should not be used over the internet. For public access, use HTTPS. +**Security note**: Always use HTTPS for Control UI access. The `lan_https` mode handles this automatically; for reverse proxy setups, ensure your proxy terminates TLS. ### 6b. Remote Gateway Mode @@ -440,6 +499,7 @@ You should see your account listed with the `sheets` service. | Tokens | `/config/secrets/` | Yes | | Homebrew & brew-installed tools | `/config/.linuxbrew/` | Yes (synced on startup) | | gog OAuth credentials | `/config/gogcli/` | Yes | +| TLS certificates (lan_https) | `/config/certs/` | Yes (CA persists; server cert regenerated if IP changes) | | OpenClaw binary | `/usr/lib/node_modules/openclaw/` | **No** — reinstalled from image | ### How built-in skills work @@ -491,6 +551,26 @@ The add-on image includes these tools, available in the terminal: | Homebrew | `brew` | Package manager (optional — may not be available on all CPUs) | | Chromium | `chromium` | Headless browser for automation | | SSH | `ssh` | Remote access | +| oc-cleanup | `oc-cleanup` | Interactive disk space monitor & cache cleanup helper | + +### oc-cleanup + +Run `oc-cleanup` from the add-on terminal to see an overview of disk usage and +selectively clear caches that accumulate over time: + +``` +$ oc-cleanup +``` + +The tool displays: + +- **Disk usage** — total, used, available, and percentage for the overlay filesystem. +- **Cache sizes** — npm global cache, pnpm content store, OpenClaw data, Homebrew cellar, workspace, Python `__pycache__`, and `/tmp`. +- **Cleanup menu** — choose which caches to purge (npm, pnpm, pycache, tmp, all at once). + +> **Note:** The add-on cannot prune Docker images directly. If disk space is +> critically low due to old Docker layers, SSH into the host and run +> `docker image prune -a` or `docker system prune`. --- @@ -574,10 +654,68 @@ Go to **Settings → Add-ons → OpenClaw Assistant → Log** tab. Logs show sta **Checks**: 1. Is the gateway running? In the terminal: `openclaw gateway status` -2. Is the bind mode correct? `openclaw config get gateway.bind` — must be `lan` for LAN access +2. Is the bind mode correct? `openclaw config get gateway.bind` — must be `lan` for direct LAN access, or `loopback` if using `lan_https` mode 3. Is the port correct? `openclaw config get gateway.port` 4. Is the firewall blocking the port? Check your HA host firewall rules +### "disconnected (1008): control ui requires device identity" / "requires HTTPS or localhost" + +**Symptom**: Gateway UI shows error 1008 or "requires secure context / device identity". + +**Cause**: OpenClaw v2026.2.21+ requires HTTPS or localhost. Plain HTTP over LAN is blocked. (v2026.2.22 further hardens this by defaulting remote onboarding to `wss://` and rejecting insecure non-loopback targets.) + +**Fix** (pick one): +1. **Easiest**: Set `access_mode` to **lan_https** in add-on Configuration → restart. This adds a built-in HTTPS proxy with zero external setup. +2. **External proxy**: Set `access_mode` to **lan_reverse_proxy** and configure NPM/Caddy/Traefik with TLS. +3. **SSH tunnel** (desktop only): `ssh -L 18789:127.0.0.1:18789 user@ha-ip` then open `http://localhost:18789`. + +### "disconnected (1008): origin not allowed" + +**Symptom**: Gateway UI shows `origin not allowed (open the Control UI from the gateway host or allow it in gateway.controlUi.allowedOrigins)`. + +**Cause**: OpenClaw v2026.2.21+ checks the browser's `Origin` header against an allow-list. When using the built-in HTTPS proxy (`lan_https`), the origin (`https://:`) must be registered in `gateway.controlUi.allowedOrigins`. + +**Fix**: In **v0.5.78+** this is configured automatically on startup. If you still see the error: +1. Restart the add-on (the startup script detects the LAN IP and sets the origins). +2. If the IP has changed since you last started, restart again — the cert and origins are regenerated. +3. **Manual override** (from the add-on terminal): + ```sh + openclaw config set gateway.controlUi.allowedOrigins '["https://192.168.1.10:18789"]' + ``` + Replace the IP and port with your actual values, then restart the gateway: + ```sh + openclaw gateway restart + ``` + +### "disconnected (1008): pairing required" + +**Symptom**: Gateway UI loads over HTTPS but shows `pairing required` and the status is Offline. + +**Cause**: OpenClaw v2026.2.21+ requires new devices to complete a pairing handshake before the Control UI WebSocket is accepted. Loopback connections are auto-approved (v2026.2.22 further improves this with loopback scope-upgrade auto-approval), but LAN connections (including those through the HTTPS proxy) require explicit approval. + +**Fix**: In **v0.5.80+** the add-on automatically sets `gateway.controlUi.dangerouslyDisableDeviceAuth: true` on startup when using `lan_https` mode. This bypasses per-device pairing — token authentication is still enforced. + +> **v2026.2.22 note:** The gateway now logs a security warning on startup when this flag is active. The warning is expected and harmless — run `openclaw security audit` for details. + +1. **Restart the add-on** — the startup script writes the config before launching the gateway. +2. If the error persists, set it manually: + ```sh + nano /config/.openclaw/openclaw.json + ``` + Ensure `gateway.controlUi` contains: + ```json + "controlUi": { + "dangerouslyDisableDeviceAuth": true, + "allowedOrigins": ["https://YOUR_IP:18789"] + } + ``` + Then restart the gateway: `openclaw gateway restart` +3. Alternatively, approve devices individually without disabling auth: + ```sh + openclaw devices list # show pending pairing requests + openclaw devices approve + ``` + ### Gateway UI shows "Unauthorized" **Fix**: Get the correct token and use it: @@ -616,8 +754,8 @@ If Telegram is configured but polling fails with network fetch errors: 2. Restart the add-on after changing configuration. 3. Check logs for `INFO: Outbound HTTP/HTTPS proxy enabled from add-on configuration.` 4. If you see `WARN: Invalid http_proxy value`, fix the URL format and restart. -5. Local traffic bypass is applied automatically via `NO_PROXY/no_proxy` defaults: - `localhost,127.0.0.1,::1,192.168.0.0/16,10.0.0.0/8,172.16.0.0/12,.local` + +When proxy is enabled, add-on startup also applies default bypass ranges via `NO_PROXY`/`no_proxy` for localhost and private network ranges. ### Skills disappearing after update @@ -660,6 +798,40 @@ rm /config/.openclaw/openclaw.json Restart the add-on — it will generate a fresh config. You'll need to run `openclaw onboard` again. +### Disk space running low / "no space left on device" + +**Symptom**: Build or startup fails, or the landing page shows a red disk-usage indicator. + +**Cause**: Old Docker images and container layers accumulate on the host. Each add-on rebuild (~1–2 GB) keeps the previous image until pruned. + +**Fix (from inside the add-on)**: +1. Open the terminal and run `oc-cleanup` to clear npm/pnpm caches, pycache, and temp files. + +**Fix (from the host)** — you need a **root shell on the HAOS host**, not the `ha` CLI +(the `ha docker` command does **not** support `prune`): + +*Option A — Advanced SSH & Web Terminal add-on (easiest):* +1. Install the **Advanced SSH & Web Terminal** add-on from the HA store. +2. In its Configuration, **disable Protection Mode** (required for host-level access). +3. Open the terminal and run: + ```sh + docker image prune -a # remove all unused images + docker builder prune -a # remove build cache + ``` + +*Option B — HAOS debug console (VirtualBox / physical):* +1. On the HAOS console (keyboard/VirtualBox window), type `login` to get a root shell. +2. Run the same `docker image prune -a` and `docker builder prune -a` commands. + +> **Note:** The `ha docker` CLI (shown by `ha docker --help`) only exposes `info`, +> `options`, and `registries` — it cannot prune images. You must use the raw `docker` +> command from a host root shell. + +**Prevention**: If running HAOS in VirtualBox, resize the VDI to at least 64 GB: +``` +VBoxManage modifymedium disk haos.vdi --resize 64000 +``` + --- ## 11. FAQ @@ -677,7 +849,7 @@ Yes. Set `gateway_mode` to `remote` and configure the remote gateway URL via `op Run `openclaw configure` in the terminal to reconfigure your AI providers, or edit `/config/.openclaw/openclaw.json` directly. You can use OpenAI, Google (Gemini), Anthropic (Claude), local models, and more. **Can other devices on my network use the OpenClaw API?** -Yes, if you set `gateway_bind_mode` to `lan`. Any device on your network can connect to `http://:18789`. Use the gateway token for authentication. This also enables the [Assist pipeline integration](#6c-assist-pipeline-integration-openai-api) from other HA instances. +Yes. Set `access_mode` to `lan_https` (recommended) or `lan_reverse_proxy`. Any device on your network can connect to `https://:18789`. Use the gateway token for authentication. This also enables the [Assist pipeline integration](#6c-assist-pipeline-integration-openai-api) from other HA instances. **Where is my data stored on the host?** The add-on's `/config/` directory maps to `/addon_configs//` on the Home Assistant host. This is included in HA backups automatically. diff --git a/openclaw_assistant/CHANGELOG.md b/openclaw_assistant/CHANGELOG.md index 3ffc263..1c31f36 100644 --- a/openclaw_assistant/CHANGELOG.md +++ b/openclaw_assistant/CHANGELOG.md @@ -2,6 +2,57 @@ All notable changes to the OpenClaw Assistant Home Assistant Add-on will be documented in this file. +## [0.5.50] - 2026-02-23 + +**[!WARNING!]** +This update contains lots of changes. It is adviced to backup before installing! + +### Changed +- **Upgraded OpenClaw to v2026.2.22-2** — includes major gateway/auth/pairing fixes and security hardening. +- Precreate `$OPENCLAW_CONFIG_DIR/identity` on startup to prevent `EACCES` errors on CLI commands that need device identity. +- Gateway token is auto-constructed from detected LAN IP when `lan_https` is active and `gateway_public_url` is empty. +- Config helper now receives the effective internal port (gateway_port + 1 in lan_https mode). + +### Notes — v2026.2.22 impact on this add-on +- **Pairing fixes (loopback)**: v2026.2.22 auto-approves loopback scope-upgrade pairing requests, includes `operator.read`/`operator.write` in default scope bundles, and treats `operator.admin` as satisfying other scopes. This greatly improves `local_only` mode reliability. +- **`dangerouslyDisableDeviceAuth` security warning**: v2026.2.22 now emits a startup warning when this flag is active. The warning is **expected and harmless** for `lan_https` mode — the flag is still required because LAN browser connections through the HTTPS proxy are not considered loopback by the gateway. Token auth remains enforced. +- **Gateway lock improvements**: stale-lock detection now uses port reachability, reducing false "already running" errors after unclean restarts. +- **Log file size cap**: new `logging.maxFileBytes` default (500 MB) prevents disk exhaustion from log storms. +- **`wss://` default for remote onboarding**: validates our HTTPS proxy approach as the correct direction. + +### Added +- **Disk-space monitoring on the landing page** — shows total / used / available with colour-coded indicator (🟢 / 🟡 / 🔴). +- **Low-disk warning banner** appears automatically when usage exceeds 90 %. +- **`oc-cleanup` terminal command** — interactive helper that shows cache sizes (npm, pnpm, OpenClaw, Homebrew, pycache, tmp) and lets users reclaim space with a menu-driven cleanup. +- Startup disk-space check with log warnings when the overlay is above 75 % or 90 %. +- **`access_mode` preset option** — simplifies secure access configuration with one setting: + - `custom` (default, backward-compatible): use individual gateway settings + - `local_only`: loopback + token (Ingress/terminal only) + - `lan_https`: **built-in HTTPS reverse proxy for LAN access** (recommended for phones/tablets) + - `lan_reverse_proxy`: LAN bind + trusted-proxy for external reverse proxy (NPM, Caddy, Traefik) + - `tailnet_https`: Tailscale interface bind + token auth +- **Built-in TLS certificate generation** (`lan_https` mode): + - Auto-generates a local CA + server certificate on first startup + - Server cert is regenerated automatically when LAN IP changes + - CA certificate downloadable from the landing page for one-tap phone trust + - nginx HTTPS server block terminates TLS and proxies to the loopback gateway +- **Overhauled landing page** with: + - Real-time status cards (gateway health, secure context, access mode) + - Access wizard with step-by-step guidance per mode + - Error translation — maps raw errors like `1008: requires device identity` to friendly messages with fixes + - CA certificate download button (lan_https mode) + - Migration banner for users on `custom` mode recommending a preset + - Collapsible reverse-proxy recipes (NPM / Caddy / Traefik / Tailscale) +- Added `openssl` to Docker image for TLS certificate generation. +- Translations for `access_mode` in all 6 languages (EN, BG, DE, ES, PL, PT-BR). + +### Fixed +- **`lan_https` — error 1008 "pairing required"**: auto-set `gateway.controlUi.dangerouslyDisableDeviceAuth: true` to skip interactive device pairing (token auth remains enforced). Replaces the invalid `pairingMode` key that caused `Unrecognized key` config errors. +- Config helper now removes stale/invalid keys (e.g. `pairingMode`) from `controlUi` on startup. +- Landing page error translation now covers "pairing required" and "origin not allowed" errors with correct fix guidance. +- Dropdown translations for `access_mode`, `gateway_mode`, `gateway_bind_mode`, and `gateway_auth_mode` now show human-readable labels in all 6 languages. +- **`lan_https` — error 1008 "origin not allowed"**: auto-configure `gateway.controlUi.allowedOrigins` with the HTTPS proxy origins (LAN IP, `homeassistant.local`, `homeassistant`) so the Control UI WebSocket is accepted. + ## [0.5.49] - 2026-02-22 ### Added diff --git a/openclaw_assistant/Dockerfile b/openclaw_assistant/Dockerfile index 74ee807..9aa2cf3 100644 --- a/openclaw_assistant/Dockerfile +++ b/openclaw_assistant/Dockerfile @@ -29,6 +29,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ rsync \ bat \ less \ + openssl \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* @@ -100,9 +101,9 @@ RUN if [ -x /home/linuxbrew/.linuxbrew/bin/brew ]; then \ fi USER root -# Install OpenClaw globally (official npm release) +# Install OpenClaw globally RUN npm config set fund false && npm config set audit false \ - && npm install -g openclaw@2026.2.21-2 + && npm install -g openclaw@2026.2.22-2 # Shell aliases and color options for interactive use RUN tee -a /etc/bash.bashrc <<'EOF' @@ -124,10 +125,12 @@ fi EOF COPY run.sh /run.sh COPY oc_config_helper.py /oc_config_helper.py +COPY render_nginx.py /render_nginx.py +COPY oc-cleanup.sh /usr/local/bin/oc-cleanup COPY openclaw-proxy-shim.cjs /usr/local/lib/openclaw-proxy-shim.cjs COPY nginx.conf.tpl /etc/nginx/nginx.conf.tpl COPY landing.html.tpl /etc/nginx/landing.html.tpl -RUN chmod +x /run.sh /oc_config_helper.py \ +RUN chmod +x /run.sh /oc_config_helper.py /render_nginx.py /usr/local/bin/oc-cleanup \ && mkdir -p /run/nginx CMD [ "/run.sh" ] diff --git a/openclaw_assistant/config.yaml b/openclaw_assistant/config.yaml index 013b2fc..e43fb0a 100644 --- a/openclaw_assistant/config.yaml +++ b/openclaw_assistant/config.yaml @@ -66,23 +66,34 @@ options: # - loopback: bind to 127.0.0.1 only (local access only, most secure) # - lan: bind to all interfaces (accessible from local network) # - tailnet: bind to Tailscale IP only (accessible only via Tailscale — recommended for remote access) - # - auto: prefer loopback; use tailnet if Tailscale is available # Default is loopback for security. gateway_bind_mode: loopback # Gateway port to listen on gateway_port: 18789 + # Access mode preset — simplifies secure access configuration. + # custom: use individual gateway_bind_mode / auth_mode settings (backward compatible) + # local_only: loopback + token auth (Ingress / terminal only, most secure) + # lan_https: Built-in HTTPS reverse proxy for LAN access (recommended for phones/tablets) + # lan_reverse_proxy: LAN bind + trusted-proxy for an external reverse proxy (NPM, Caddy, …) + # tailnet_https: Tailscale interface bind + token auth + access_mode: custom + + # Gateway authentication mode: + # - token: standard token auth (default) + # - trusted-proxy: trust auth headers from configured reverse proxies + gateway_auth_mode: token + + # Comma-separated trusted proxy IP/CIDR list for trusted-proxy mode. + # Example: "127.0.0.1,192.168.88.0/24" + gateway_trusted_proxies: "" + # Enable OpenAI-compatible Chat Completions API endpoint # When enabled, OpenClaw can be used as a conversation agent in HA Assist pipeline # via Extended OpenAI Conversation (HACS) or any OpenAI-compatible client enable_openai_api: false - # Allow insecure HTTP authentication (required for HTTP gateway access on LAN) - # WARNING: Only enable if you're using HTTP (not HTTPS) for gateway_public_url - # Default is false for security. - allow_insecure_auth: false - # Force IPv4-first DNS result ordering for Node fetch/network calls. # Useful on networks where IPv6 resolution exists but IPv6 egress is broken # (can affect Telegram API polling in some HAOS/VM setups). @@ -104,8 +115,11 @@ schema: clean_session_locks_on_start: bool? clean_session_locks_on_exit: bool? gateway_mode: list(local|remote)? - gateway_bind_mode: list(auto|loopback|lan|tailnet)? + gateway_bind_mode: list(loopback|lan|tailnet)? gateway_port: int(1,65535)? + access_mode: list(custom|local_only|lan_https|lan_reverse_proxy|tailnet_https)? + gateway_auth_mode: list(token|trusted-proxy)? + gateway_trusted_proxies: str? enable_openai_api: bool? - allow_insecure_auth: bool? force_ipv4_dns: bool? + diff --git a/openclaw_assistant/landing.html.tpl b/openclaw_assistant/landing.html.tpl index 4e14023..5ee3357 100644 --- a/openclaw_assistant/landing.html.tpl +++ b/openclaw_assistant/landing.html.tpl @@ -9,36 +9,327 @@ a,button{font:inherit} .card{max-width:1100px;margin:0 auto;background:#111827;border:1px solid #1f2937;border-radius:12px;padding:16px} .row{display:flex;gap:12px;flex-wrap:wrap;align-items:center} - .btn{background:#2563eb;color:white;border:0;border-radius:10px;padding:10px 14px;cursor:pointer;text-decoration:none;display:inline-block} + .btn{background:#2563eb;color:white;border:0;border-radius:10px;padding:10px 14px;cursor:pointer;text-decoration:none;display:inline-block;font-size:14px} .btn.secondary{background:#334155} + .btn.green{background:#059669} + .btn.amber{background:#d97706} + .btn:hover{filter:brightness(1.15)} .muted{color:#9ca3af;font-size:14px} - .term{margin-top:14px;height:70vh;min-height:420px;border:1px solid #1f2937;border-radius:10px;overflow:hidden} + .term{margin-top:14px;height:60vh;min-height:360px;border:1px solid #1f2937;border-radius:10px;overflow:hidden} iframe{width:100%;height:100%;border:0;background:black} - code{background:#0b1220;padding:2px 6px;border-radius:6px} + code{background:#0b1220;padding:2px 6px;border-radius:6px;font-size:13px} + .status-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:10px;margin:12px 0} + .status-item{padding:10px 14px;border-radius:10px;background:#0d1117;border:1px solid #1f2937;font-size:14px;display:flex;align-items:center;gap:8px} + .status-item .icon{font-size:18px;flex-shrink:0} + .banner{padding:12px 16px;border-radius:10px;margin:10px 0;font-size:14px;line-height:1.5} + .banner.info{background:#1e3a5f;border:1px solid #2563eb} + .banner.warn{background:#422006;border:1px solid #d97706} + .banner.error{background:#3b0d0d;border:1px solid #dc2626} + .banner.success{background:#052e16;border:1px solid #059669} + .wizard{background:#0d1117;border:1px solid #1f2937;border-radius:10px;padding:14px;margin:12px 0} + .wizard h3{margin:0 0 8px;font-size:15px} + .wizard ol{margin:6px 0;padding-left:22px;font-size:14px;line-height:1.8} + .wizard code{font-size:12px} + details{margin:8px 0} + details>summary{cursor:pointer;font-size:14px;color:#60a5fa;font-weight:500} + details>summary:hover{text-decoration:underline} + .hidden{display:none} + .badge{display:inline-block;padding:2px 8px;border-radius:6px;font-size:12px;font-weight:600;vertical-align:middle} + .badge.secure{background:#059669;color:#fff} + .badge.insecure{background:#dc2626;color:#fff} + .badge.mode{background:#2563eb;color:#fff}
-

OpenClaw Assistant

+

OpenClaw Assistant

+
+ __ACCESS_MODE__ + +
+ +
+
+ + Gateway: checking… +
+
+ 🔒 + Secure context: checking… +
+
+ 📡 + Access mode: __ACCESS_MODE__ +
+
+ 💾 + Disk: __DISK_USED__ / __DISK_TOTAL__ (__DISK_PCT__) — __DISK_AVAIL__ free +
+
+ + -
- Tip: The gateway UI is intentionally opened outside of Ingress to avoid websocket/proxy issues. - Set gateway_public_url in the add-on options. + + -
- If the Gateway UI says Unauthorized, you need the token. In the terminal run: - openclaw config get gateway.auth.token + + + + + + + + + + + + +
+ Tips & token help +
+ The gateway UI opens in a separate tab to avoid websocket/proxy issues with Ingress. + Set gateway_public_url in add-on options if the button URL is wrong. +
+
+ If the Gateway UI says Unauthorized, get your token in the terminal: + openclaw config get gateway.auth.token +
+
+ + +
+ Reverse-proxy recipes (NPM / Caddy / Traefik / Tailscale) +
+ + Nginx Proxy Manager (NPM) +
Scheme:   https
+Forward:  <HA-IP>:18789
+WS:       ON
+SSL tab:  Request a new SSL certificate (Let's Encrypt or custom)
+ + Caddy +
openclaw.example.com {
+    reverse_proxy <HA-IP>:18789
+}
+ + Traefik (docker labels) +
- "traefik.http.routers.openclaw.rule=Host(`openclaw.example.com`)"
+- "traefik.http.routers.openclaw.tls.certresolver=le"
+- "traefik.http.services.openclaw.loadbalancer.server.port=18789"
+ + Tailscale HTTPS +
# 1. Set access_mode to tailnet_https in add-on configuration
+# 2. Enable Tailscale HTTPS in your Tailnet admin: DNS → HTTPS Certificates
+# 3. On the HA host:  tailscale cert <machine-name>.ts.net
+# 4. Set gateway_public_url to https://<machine-name>.ts.net:18789
+
+
+ +
+ + + diff --git a/openclaw_assistant/nginx.conf.tpl b/openclaw_assistant/nginx.conf.tpl index 36ac288..5ba13eb 100644 --- a/openclaw_assistant/nginx.conf.tpl +++ b/openclaw_assistant/nginx.conf.tpl @@ -59,4 +59,6 @@ http { return 404; } } + + __HTTPS_GATEWAY_BLOCK__ } diff --git a/openclaw_assistant/oc-cleanup.sh b/openclaw_assistant/oc-cleanup.sh new file mode 100644 index 0000000..8d21c28 --- /dev/null +++ b/openclaw_assistant/oc-cleanup.sh @@ -0,0 +1,144 @@ +#!/usr/bin/env bash +# ────────────────────────────────────────────────────────────── +# oc-cleanup — Disk space monitor & cleanup helper for OpenClaw +# Run from the add-on terminal: oc-cleanup +# ────────────────────────────────────────────────────────────── +set -euo pipefail + +BOLD="\033[1m" +RED="\033[91m" +GREEN="\033[92m" +YELLOW="\033[93m" +CYAN="\033[96m" +RESET="\033[0m" + +echo -e "${BOLD}${CYAN}═══════════════════════════════════════════${RESET}" +echo -e "${BOLD}${CYAN} OpenClaw Disk Space Monitor & Cleanup${RESET}" +echo -e "${BOLD}${CYAN}═══════════════════════════════════════════${RESET}" +echo "" + +# ── Disk usage ─────────────────────────────────────────────── +DATA_MOUNT="/config" +if df -h "$DATA_MOUNT" >/dev/null 2>&1; then + DISK_TOTAL=$(df -h "$DATA_MOUNT" | awk 'NR==2{print $2}') + DISK_USED=$(df -h "$DATA_MOUNT" | awk 'NR==2{print $3}') + DISK_AVAIL=$(df -h "$DATA_MOUNT" | awk 'NR==2{print $4}') + DISK_PCT=$(df -h "$DATA_MOUNT" | awk 'NR==2{print $5}') + DISK_PCT_NUM=${DISK_PCT//%/} + + echo -e "${BOLD}Disk usage (data partition):${RESET}" + echo -e " Total: ${DISK_TOTAL}" + echo -e " Used: ${DISK_USED} (${DISK_PCT})" + echo -e " Available: ${DISK_AVAIL}" + echo "" + + if [ "$DISK_PCT_NUM" -ge 90 ]; then + echo -e "${RED}${BOLD}⚠ CRITICAL: Disk is ${DISK_PCT} full!${RESET}" + echo -e "${RED} Add-on updates and Docker builds may fail.${RESET}" + echo "" + elif [ "$DISK_PCT_NUM" -ge 75 ]; then + echo -e "${YELLOW}${BOLD}⚠ WARNING: Disk is ${DISK_PCT} full.${RESET}" + echo -e "${YELLOW} Consider cleaning up to avoid future build failures.${RESET}" + echo "" + else + echo -e "${GREEN}✓ Disk usage looks healthy.${RESET}" + echo "" + fi +fi + +# ── Add-on cache sizes ────────────────────────────────────── +echo -e "${BOLD}Add-on cache sizes:${RESET}" + +show_size() { + local label="$1" path="$2" + if [ -d "$path" ]; then + local size + size=$(du -sh "$path" 2>/dev/null | cut -f1) + printf " %-30s %s\n" "$label" "$size" + fi +} + +show_size "npm cache" "/config/.npm" +show_size "npm global packages" "/config/.node_global" +show_size "pnpm store" "/config/.node_global/pnpm" +show_size "OpenClaw config + skills" "/config/.openclaw" +show_size "Homebrew" "/config/.linuxbrew" +show_size "Agent workspace" "/config/clawd" +show_size "Python __pycache__" "/config/.openclaw/__pycache__" +show_size "Temp files (/tmp)" "/tmp" +echo "" + +# ── Cleanup menu ──────────────────────────────────────────── +echo -e "${BOLD}What can be cleaned from inside the add-on:${RESET}" +echo " 1) npm cache (safe — rebuilds on demand)" +echo " 2) pnpm store cache (safe — rebuilds on demand)" +echo " 3) Python __pycache__ (safe — regenerated automatically)" +echo " 4) /tmp files (safe — transient data)" +echo " 5) All of the above" +echo " 6) Show Docker prune commands (must run from HA host SSH)" +echo " q) Quit" +echo "" +read -r -p "Choose [1-6/q]: " choice + +cleanup_npm() { + echo -e "${CYAN}Cleaning npm cache...${RESET}" + npm cache clean --force 2>/dev/null || true + rm -rf /config/.npm/_cacache 2>/dev/null || true + echo " Done." +} + +cleanup_pnpm() { + echo -e "${CYAN}Cleaning pnpm store...${RESET}" + pnpm store prune 2>/dev/null || true + echo " Done." +} + +cleanup_pycache() { + echo -e "${CYAN}Cleaning Python __pycache__...${RESET}" + find /config -type d -name __pycache__ -exec rm -rf {} + 2>/dev/null || true + echo " Done." +} + +cleanup_tmp() { + echo -e "${CYAN}Cleaning /tmp...${RESET}" + rm -rf /tmp/* 2>/dev/null || true + echo " Done." +} + +show_docker_commands() { + echo "" + echo -e "${BOLD}${YELLOW}Run these from a HOST root shell (not this add-on terminal):${RESET}" + echo "" + echo -e " ${BOLD}Option A — Advanced SSH & Web Terminal add-on:${RESET}" + echo " Install it, disable Protection Mode, then open its terminal." + echo "" + echo -e " ${BOLD}Option B — HAOS console (VirtualBox / keyboard):${RESET}" + echo " Type 'login' at the HAOS prompt to get a root shell." + echo "" + echo -e " ${BOLD}# Then run:${RESET}" + echo " docker image prune -a # remove unused images" + echo " docker builder prune -a # remove build cache" + echo " docker system df # check Docker disk usage" + echo "" + echo -e "${YELLOW}Important: The 'ha docker' CLI does NOT support prune." + echo -e "You must use the raw 'docker' command from a host root shell.${RESET}" +} + +case "${choice:-q}" in + 1) cleanup_npm ;; + 2) cleanup_pnpm ;; + 3) cleanup_pycache ;; + 4) cleanup_tmp ;; + 5) cleanup_npm; cleanup_pnpm; cleanup_pycache; cleanup_tmp ;; + 6) show_docker_commands ;; + q|Q) echo "Bye." ;; + *) echo "Unknown option." ;; +esac + +echo "" +# Show result +if df -h "$DATA_MOUNT" >/dev/null 2>&1; then + DISK_AVAIL_NOW=$(df -h "$DATA_MOUNT" | awk 'NR==2{print $4}') + DISK_PCT_NOW=$(df -h "$DATA_MOUNT" | awk 'NR==2{print $5}') + echo -e "${BOLD}Disk now: ${DISK_PCT_NOW} used, ${DISK_AVAIL_NOW} available${RESET}" +fi diff --git a/openclaw_assistant/oc_config_helper.py b/openclaw_assistant/oc_config_helper.py index d87c0f3..69e557d 100644 --- a/openclaw_assistant/oc_config_helper.py +++ b/openclaw_assistant/oc_config_helper.py @@ -57,16 +57,17 @@ def set_gateway_setting(key, value): return write_config(cfg) -def apply_gateway_settings(mode: str, bind_mode: str, port: int, enable_openai_api: bool, allow_insecure_auth: bool): +def apply_gateway_settings(mode: str, bind_mode: str, port: int, enable_openai_api: bool, auth_mode: str, trusted_proxies_csv: str): """ Apply gateway settings to OpenClaw config. Args: mode: "local" or "remote" - bind_mode: "auto", "loopback", "lan", or "tailnet" + bind_mode: "loopback", "lan", or "tailnet" port: Port number to listen on (must be 1-65535) enable_openai_api: Enable OpenAI-compatible Chat Completions endpoint - allow_insecure_auth: Allow insecure HTTP authentication + auth_mode: Gateway auth mode (token|trusted-proxy) + trusted_proxies_csv: Comma-separated trusted proxy IP/CIDR list """ # Validate gateway mode if mode not in ["local", "remote"]: @@ -74,14 +75,19 @@ def apply_gateway_settings(mode: str, bind_mode: str, port: int, enable_openai_a return False # Validate bind mode - if bind_mode not in ["auto", "loopback", "lan", "tailnet"]: - print(f"ERROR: Invalid bind_mode '{bind_mode}'. Must be 'auto', 'loopback', 'lan', or 'tailnet'") + if bind_mode not in ["loopback", "lan", "tailnet"]: + print(f"ERROR: Invalid bind_mode '{bind_mode}'. Must be 'loopback', 'lan', or 'tailnet'") return False # Validate port range if port < 1 or port > 65535: print(f"ERROR: Invalid port {port}. Must be between 1 and 65535") return False + + # Validate auth mode + if auth_mode not in ["token", "trusted-proxy"]: + print(f"ERROR: Invalid auth_mode '{auth_mode}'. Must be 'token' or 'trusted-proxy'") + return False cfg = read_config() if cfg is None: @@ -92,10 +98,10 @@ def apply_gateway_settings(mode: str, bind_mode: str, port: int, enable_openai_a gateway = cfg["gateway"] - # controlUi should be nested inside gateway - if "controlUi" not in gateway: - gateway["controlUi"] = {} - + # auth should be nested inside gateway + if "auth" not in gateway: + gateway["auth"] = {} + # http.endpoints.chatCompletions should be nested inside gateway if "http" not in gateway: gateway["http"] = {} @@ -104,14 +110,22 @@ def apply_gateway_settings(mode: str, bind_mode: str, port: int, enable_openai_a if "chatCompletions" not in gateway["http"]["endpoints"]: gateway["http"]["endpoints"]["chatCompletions"] = {} - control_ui = gateway["controlUi"] + auth = gateway["auth"] chat_completions = gateway["http"]["endpoints"]["chatCompletions"] - + + trusted_proxies = [p.strip() for p in trusted_proxies_csv.split(",") if p.strip()] + + # OpenClaw trusted-proxy mode requires nested auth.trustedProxy config. + # Use a sane default user header expected from reverse proxies. + trusted_proxy_cfg_default = {"userHeader": "x-forwarded-user"} + current_mode = gateway.get("mode", "") current_bind = gateway.get("bind", "") current_port = gateway.get("port", 18789) current_openai_api = chat_completions.get("enabled", False) - current_insecure = control_ui.get("allowInsecureAuth", False) + current_auth_mode = auth.get("mode", "token") + current_trusted_proxies = gateway.get("trustedProxies", []) + current_trusted_proxy_cfg = auth.get("trustedProxy") changes = [] @@ -131,9 +145,18 @@ def apply_gateway_settings(mode: str, bind_mode: str, port: int, enable_openai_a chat_completions["enabled"] = enable_openai_api changes.append(f"chatCompletions.enabled: {current_openai_api} -> {enable_openai_api}") - if current_insecure != allow_insecure_auth: - control_ui["allowInsecureAuth"] = allow_insecure_auth - changes.append(f"allowInsecureAuth: {current_insecure} -> {allow_insecure_auth}") + if current_auth_mode != auth_mode: + auth["mode"] = auth_mode + changes.append(f"auth.mode: {current_auth_mode} -> {auth_mode}") + + if current_trusted_proxies != trusted_proxies: + gateway["trustedProxies"] = trusted_proxies + changes.append(f"trustedProxies: {current_trusted_proxies} -> {trusted_proxies}") + + if auth_mode == "trusted-proxy": + if current_trusted_proxy_cfg != trusted_proxy_cfg_default: + auth["trustedProxy"] = trusted_proxy_cfg_default + changes.append("auth.trustedProxy: configured default userHeader=x-forwarded-user") if changes: if write_config(cfg): @@ -143,10 +166,74 @@ def apply_gateway_settings(mode: str, bind_mode: str, port: int, enable_openai_a print("ERROR: Failed to write config") return False else: - print(f"INFO: Gateway settings already correct (mode={mode}, bind={bind_mode}, port={port}, chatCompletions={enable_openai_api}, allowInsecureAuth={allow_insecure_auth})") + print(f"INFO: Gateway settings already correct (mode={mode}, bind={bind_mode}, port={port}, chatCompletions={enable_openai_api}, authMode={auth_mode}, trustedProxies={trusted_proxies})") return True +def set_control_ui_origins(origins_csv: str): + """ + Configure gateway.controlUi for the built-in HTTPS proxy. + + Sets: + - allowedOrigins: the HTTPS proxy origins so the browser WebSocket + is accepted (required since v2026.2.21). + - dangerouslyDisableDeviceAuth: true — skips the interactive device + pairing ceremony. In a self-hosted HA add-on the user already + controls the gateway token, so the pairing step adds friction + without meaningful security benefit. + + Also removes any stale/invalid keys (e.g. pairingMode) that may have + been written by earlier add-on versions. + + Args: + origins_csv: Comma-separated list of allowed origins. + Pass an empty string to clear / leave unset. + """ + cfg = read_config() + if cfg is None: + cfg = {} + + if "gateway" not in cfg: + cfg["gateway"] = {} + gateway = cfg["gateway"] + + if "controlUi" not in gateway: + gateway["controlUi"] = {} + + control_ui = gateway["controlUi"] + origins = [o.strip() for o in origins_csv.split(",") if o.strip()] + changes = [] + + # --- allowedOrigins --- + current_origins = control_ui.get("allowedOrigins", []) + if current_origins != origins: + control_ui["allowedOrigins"] = origins + changes.append(f"allowedOrigins: {current_origins} -> {origins}") + + # --- dangerouslyDisableDeviceAuth --- + # Skips the interactive pairing handshake (error 1008: pairing required). + # Token auth is still enforced; this only disables the per-device approval. + if control_ui.get("dangerouslyDisableDeviceAuth") is not True: + control_ui["dangerouslyDisableDeviceAuth"] = True + changes.append("dangerouslyDisableDeviceAuth: True") + + # --- Remove invalid keys from earlier add-on versions --- + for stale_key in ("pairingMode",): + if stale_key in control_ui: + del control_ui[stale_key] + changes.append(f"removed invalid key: {stale_key}") + + if not changes: + print(f"INFO: controlUi already correct: origins={origins}, deviceAuth=disabled") + return True + + if write_config(cfg): + print(f"INFO: Updated controlUi: {', '.join(changes)}") + return True + print("ERROR: Failed to write config") + return False + + def main(): """CLI entry point for use by run.sh""" if len(sys.argv) < 2: @@ -156,15 +243,16 @@ def main(): cmd = sys.argv[1] if cmd == "apply-gateway-settings": - if len(sys.argv) != 7: - print("Usage: oc_config_helper.py apply-gateway-settings ") + if len(sys.argv) != 8: + print("Usage: oc_config_helper.py apply-gateway-settings ") sys.exit(1) mode = sys.argv[2] bind_mode = sys.argv[3] port = int(sys.argv[4]) enable_openai_api = sys.argv[5].lower() == "true" - allow_insecure_auth = sys.argv[6].lower() == "true" - success = apply_gateway_settings(mode, bind_mode, port, enable_openai_api, allow_insecure_auth) + auth_mode = sys.argv[6] + trusted_proxies_csv = sys.argv[7] + success = apply_gateway_settings(mode, bind_mode, port, enable_openai_api, auth_mode, trusted_proxies_csv) sys.exit(0 if success else 1) elif cmd == "get": @@ -177,6 +265,14 @@ def main(): print(value) sys.exit(0) + elif cmd == "set-control-ui-origins": + if len(sys.argv) != 3: + print("Usage: oc_config_helper.py set-control-ui-origins ") + sys.exit(1) + origins_csv = sys.argv[2] + success = set_control_ui_origins(origins_csv) + sys.exit(0 if success else 1) + elif cmd == "set": if len(sys.argv) != 4: print("Usage: oc_config_helper.py set ") diff --git a/openclaw_assistant/render_nginx.py b/openclaw_assistant/render_nginx.py new file mode 100644 index 0000000..3cbc5f6 --- /dev/null +++ b/openclaw_assistant/render_nginx.py @@ -0,0 +1,118 @@ +#!/usr/bin/env python3 +""" +Render nginx.conf and landing page HTML from templates. + +Called by run.sh with the following env vars: + GW_PUBLIC_URL, GW_TOKEN, TERMINAL_PORT, + ENABLE_HTTPS_PROXY, HTTPS_PROXY_PORT, + GATEWAY_INTERNAL_PORT, ACCESS_MODE, + DISK_TOTAL, DISK_USED, DISK_AVAIL, DISK_PCT +""" + +import os +import subprocess +from pathlib import Path + + +def main(): + tpl = Path('/etc/nginx/nginx.conf.tpl').read_text() + landing_tpl = Path('/etc/nginx/landing.html.tpl').read_text() + + public_url = os.environ.get('GW_PUBLIC_URL', '') + terminal_port = os.environ.get('TERMINAL_PORT', '7681') + enable_https = os.environ.get('ENABLE_HTTPS_PROXY', 'false') == 'true' + https_port = os.environ.get('HTTPS_PROXY_PORT', '') + internal_gw_port = os.environ.get('GATEWAY_INTERNAL_PORT', '') + access_mode = os.environ.get('ACCESS_MODE', 'custom') + + # Disk usage info (collected by run.sh) + disk_total = os.environ.get('DISK_TOTAL', '') + disk_used = os.environ.get('DISK_USED', '') + disk_avail = os.environ.get('DISK_AVAIL', '') + disk_pct = os.environ.get('DISK_PCT', '') + + # Token comes from environment (best-effort CLI query in run.sh) + token = os.environ.get('GW_TOKEN', '') + + gw_path = '' if public_url.endswith('/') else '/' + + # ── nginx.conf ────────────────────────────────────────────── + conf = tpl.replace('__TERMINAL_PORT__', terminal_port) + + # Build HTTPS gateway proxy block (only for lan_https mode) + https_block = '' + if enable_https and https_port and internal_gw_port: + https_block = f""" + # --- HTTPS Gateway Proxy (lan_https mode) --- + server {{ + listen {https_port} ssl; + + ssl_certificate /config/certs/gateway.crt; + ssl_certificate_key /config/certs/gateway.key; + ssl_protocols TLSv1.2 TLSv1.3; + ssl_ciphers HIGH:!aNULL:!MD5; + + # Proxy all traffic to the loopback gateway with WebSocket support + location / {{ + proxy_pass http://127.0.0.1:{internal_gw_port}; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto https; + proxy_read_timeout 86400s; + proxy_send_timeout 86400s; + proxy_buffering off; + }} + + # Download the local CA certificate (install on phone for trusted access) + location = /cert/ca.crt {{ + alias /etc/nginx/html/openclaw-ca.crt; + default_type application/x-x509-ca-cert; + add_header Content-Disposition 'attachment; filename="openclaw-ca.crt"'; + }} + }} +""" + + conf = conf.replace('__HTTPS_GATEWAY_BLOCK__', https_block) + Path('/etc/nginx/nginx.conf').write_text(conf) + + # ── landing page ──────────────────────────────────────────── + # If lan_https and no explicit public URL, auto-construct one + if enable_https and not public_url: + try: + lan_ip = subprocess.check_output( + ['hostname', '-I'], text=True, timeout=2 + ).split()[0] + except Exception: + lan_ip = '127.0.0.1' + public_url = f'https://{lan_ip}:{https_port}' + gw_path = '/' + + landing = landing_tpl.replace('__GATEWAY_TOKEN__', token) + landing = landing.replace('__GATEWAY_PUBLIC_URL__', public_url) + landing = landing.replace('__GW_PUBLIC_URL_PATH__', gw_path) + landing = landing.replace('__ACCESS_MODE__', access_mode) + landing = landing.replace('__HTTPS_PORT__', https_port if enable_https else '') + landing = landing.replace('__DISK_TOTAL__', disk_total) + landing = landing.replace('__DISK_USED__', disk_used) + landing = landing.replace('__DISK_AVAIL__', disk_avail) + landing = landing.replace('__DISK_PCT__', disk_pct) + + out_dir = Path('/etc/nginx/html') + out_dir.mkdir(parents=True, exist_ok=True) + out_file = out_dir / 'index.html' + out_file.write_text(landing) + + # Ensure nginx can read it even if base image uses restrictive umask/permissions. + try: + out_dir.chmod(0o755) + out_file.chmod(0o644) + except Exception: + pass + + +if __name__ == '__main__': + main() diff --git a/openclaw_assistant/run.sh b/openclaw_assistant/run.sh index fa89a64..4a13fae 100644 --- a/openclaw_assistant/run.sh +++ b/openclaw_assistant/run.sh @@ -50,11 +50,52 @@ GATEWAY_MODE=$(jq -r '.gateway_mode // "local"' "$OPTIONS_FILE") GATEWAY_BIND_MODE=$(jq -r '.gateway_bind_mode // "loopback"' "$OPTIONS_FILE") GATEWAY_PORT=$(jq -r '.gateway_port // 18789' "$OPTIONS_FILE") ENABLE_OPENAI_API=$(jq -r '.enable_openai_api // false' "$OPTIONS_FILE") -ALLOW_INSECURE_AUTH=$(jq -r '.allow_insecure_auth // false' "$OPTIONS_FILE") +GATEWAY_AUTH_MODE=$(jq -r '.gateway_auth_mode // "token"' "$OPTIONS_FILE") +GATEWAY_TRUSTED_PROXIES=$(jq -r '.gateway_trusted_proxies // empty' "$OPTIONS_FILE") FORCE_IPV4_DNS=$(jq -r '.force_ipv4_dns // false' "$OPTIONS_FILE") +ACCESS_MODE=$(jq -r '.access_mode // "custom"' "$OPTIONS_FILE") export TZ="$TZNAME" +# ------------------------------------------------------------------------------ +# Access mode presets — override individual gateway settings for common scenarios +# ------------------------------------------------------------------------------ +ENABLE_HTTPS_PROXY=false +GATEWAY_INTERNAL_PORT="$GATEWAY_PORT" + +case "$ACCESS_MODE" in + local_only) + GATEWAY_BIND_MODE="loopback" + GATEWAY_AUTH_MODE="token" + echo "INFO: Access mode: local_only (loopback + token, Ingress/terminal only)" + ;; + lan_https) + # Gateway binds loopback on internal port; nginx terminates TLS on the external port. + GATEWAY_BIND_MODE="loopback" + GATEWAY_AUTH_MODE="token" + ENABLE_HTTPS_PROXY=true + GATEWAY_INTERNAL_PORT=$((GATEWAY_PORT + 1)) + echo "INFO: Access mode: lan_https (built-in HTTPS proxy on 0.0.0.0:${GATEWAY_PORT})" + ;; + lan_reverse_proxy) + GATEWAY_BIND_MODE="lan" + GATEWAY_AUTH_MODE="trusted-proxy" + if [ -z "$GATEWAY_TRUSTED_PROXIES" ]; then + echo "ERROR: access_mode=lan_reverse_proxy requires gateway_trusted_proxies to be set." + echo "ERROR: Set it to your reverse proxy's IP/CIDR (e.g. 127.0.0.1,192.168.88.0/24)." + fi + echo "INFO: Access mode: lan_reverse_proxy (LAN bind + trusted-proxy auth)" + ;; + tailnet_https) + GATEWAY_BIND_MODE="tailnet" + GATEWAY_AUTH_MODE="token" + echo "INFO: Access mode: tailnet_https (Tailscale bind + token auth)" + ;; + custom|*) + echo "INFO: Access mode: custom (using individual gateway_bind_mode/auth_mode settings)" + ;; +esac + # Reduce risk of secrets ending up in logs set +x @@ -98,7 +139,7 @@ export OPENCLAW_CONFIG_DIR=/config/.openclaw export OPENCLAW_WORKSPACE_DIR=/config/clawd export XDG_CONFIG_HOME=/config -mkdir -p /config/.openclaw /config/clawd /config/keys /config/secrets +mkdir -p /config/.openclaw /config/.openclaw/identity /config/clawd /config/keys /config/secrets # ------------------------------------------------------------------------------ # Sync built-in OpenClaw skills from image to persistent storage @@ -353,7 +394,9 @@ fi if [ -f "$OPENCLAW_CONFIG_PATH" ]; then if [ -f "$HELPER_PATH" ]; then - if ! python3 "$HELPER_PATH" apply-gateway-settings "$GATEWAY_MODE" "$GATEWAY_BIND_MODE" "$GATEWAY_PORT" "$ENABLE_OPENAI_API" "$ALLOW_INSECURE_AUTH"; then + # In lan_https mode the gateway uses an internal port; nginx owns the external one. + EFFECTIVE_GW_PORT="$GATEWAY_INTERNAL_PORT" + if ! python3 "$HELPER_PATH" apply-gateway-settings "$GATEWAY_MODE" "$GATEWAY_BIND_MODE" "$EFFECTIVE_GW_PORT" "$ENABLE_OPENAI_API" "$GATEWAY_AUTH_MODE" "$GATEWAY_TRUSTED_PROXIES"; then rc=$? echo "ERROR: Failed to apply gateway settings via oc_config_helper.py (exit code ${rc})." echo "ERROR: Gateway configuration may be incorrect; aborting startup." @@ -368,6 +411,88 @@ else echo "INFO: Run 'openclaw onboard' first, then restart the add-on" fi +# ------------------------------------------------------------------------------ +# TLS certificate generation for built-in HTTPS proxy (lan_https mode) +# Generates a local CA + server cert so phones/tablets get proper HTTPS. +# The CA cert can be installed once on a device for trusted access. +# ------------------------------------------------------------------------------ +if [ "$ENABLE_HTTPS_PROXY" = "true" ]; then + CERT_DIR="/config/certs" + mkdir -p "$CERT_DIR" + + # Detect primary LAN IP + LAN_IP=$(hostname -I 2>/dev/null | awk '{print $1}') + STORED_IP=$(cat "$CERT_DIR/.cert_ip" 2>/dev/null || echo "") + + # --- Local CA (generated once, persists across restarts) --- + if [ ! -f "$CERT_DIR/ca.key" ] || [ ! -f "$CERT_DIR/ca.crt" ]; then + echo "INFO: Generating local CA certificate (one-time)..." + openssl genrsa -out "$CERT_DIR/ca.key" 2048 2>/dev/null + openssl req -new -x509 -key "$CERT_DIR/ca.key" -out "$CERT_DIR/ca.crt" \ + -days 3650 -nodes -subj "/CN=OpenClaw Local CA" 2>/dev/null + chmod 600 "$CERT_DIR/ca.key" + STORED_IP="" # force server cert regeneration + echo "INFO: Local CA created at $CERT_DIR/ca.crt" + fi + + # --- Server cert (regenerated when LAN IP changes) --- + if [ ! -f "$CERT_DIR/gateway.crt" ] || [ ! -f "$CERT_DIR/gateway.key" ] || [ "$LAN_IP" != "$STORED_IP" ]; then + echo "INFO: Generating server TLS certificate for IP: ${LAN_IP:-unknown}..." + openssl genrsa -out "$CERT_DIR/gateway.key" 2048 2>/dev/null + openssl req -new -key "$CERT_DIR/gateway.key" -out "$CERT_DIR/gateway.csr" \ + -subj "/CN=OpenClaw Gateway" 2>/dev/null + + # SAN extension — include LAN IP, loopback, and common mDNS names + cat > "$CERT_DIR/_san.ext" </dev/null + + rm -f "$CERT_DIR/gateway.csr" "$CERT_DIR/_san.ext" "$CERT_DIR/ca.srl" + chmod 600 "$CERT_DIR/gateway.key" + printf '%s' "$LAN_IP" > "$CERT_DIR/.cert_ip" + echo "INFO: Server TLS certificate generated (SAN includes IP:${LAN_IP:-127.0.0.1})" + else + echo "INFO: Reusing existing TLS certificate (IP: $STORED_IP)" + fi + + # Make CA cert available for download via nginx + mkdir -p /etc/nginx/html + cp "$CERT_DIR/ca.crt" /etc/nginx/html/openclaw-ca.crt 2>/dev/null || true + echo "INFO: CA certificate available for download at /cert/ca.crt on the HTTPS port" + + # ------------------------------------------------------------------ + # Configure gateway.controlUi for the HTTPS proxy: + # + # 1. allowedOrigins — the browser's HTTPS origin must be listed, + # otherwise v2026.2.21+ rejects with 1008 "origin not allowed". + # + # 2. dangerouslyDisableDeviceAuth — skips the interactive device + # pairing ceremony (1008 "pairing required"). In a self-hosted + # add-on the user already controls the token, so per-device + # approval adds friction without real security benefit. + # + # NOTE: v2026.2.22+ emits a startup security warning when this + # flag is active. The warning is expected and harmless for this + # use case — run `openclaw security audit` for details. + # + # Also cleans up any stale keys (e.g. pairingMode) from older + # add-on versions that would cause "Unrecognized key" errors. + # ------------------------------------------------------------------ + if [ -n "$LAN_IP" ] && [ -f "$HELPER_PATH" ] && [ -f "$OPENCLAW_CONFIG_PATH" ]; then + ALLOWED_ORIGINS="https://${LAN_IP}:${GATEWAY_PORT}" + # Also permit common mDNS/hostname variants so the cert SAN names work too + ALLOWED_ORIGINS="${ALLOWED_ORIGINS},https://homeassistant.local:${GATEWAY_PORT}" + ALLOWED_ORIGINS="${ALLOWED_ORIGINS},https://homeassistant:${GATEWAY_PORT}" + python3 "$HELPER_PATH" set-control-ui-origins "$ALLOWED_ORIGINS" || \ + echo "WARN: Could not set controlUi settings — gateway may reject the Control UI" + fi +fi + # ------------------------------------------------------------------------------ # Proxy shim for undici/OpenClaw startup # Keep official OpenClaw npm release while enabling HTTP(S)_PROXY support. @@ -456,40 +581,29 @@ fi # The gateway token is NOT managed by the add-on; OpenClaw will generate/store it. # Best-effort: query it via CLI (works even if openclaw.json is JSON5). If unknown, we hide the button. GW_TOKEN="$(timeout 2s openclaw config get gateway.auth.token 2>/dev/null | tr -d '\n' || true)" -GW_PUBLIC_URL="$GW_PUBLIC_URL" GW_TOKEN="$GW_TOKEN" TERMINAL_PORT="$TERMINAL_PORT" python3 - <<'PY' -import os -from pathlib import Path -tpl = Path('/etc/nginx/nginx.conf.tpl').read_text() -landing_tpl = Path('/etc/nginx/landing.html.tpl').read_text() -public_url = os.environ.get('GW_PUBLIC_URL','') -terminal_port = os.environ.get('TERMINAL_PORT', '7681') +# Collect disk usage for landing page status card +DISK_TOTAL="" DISK_USED="" DISK_AVAIL="" DISK_PCT="" +if df -h /config >/dev/null 2>&1; then + DISK_TOTAL=$(df -h /config | awk 'NR==2{print $2}') + DISK_USED=$(df -h /config | awk 'NR==2{print $3}') + DISK_AVAIL=$(df -h /config | awk 'NR==2{print $4}') + DISK_PCT=$(df -h /config | awk 'NR==2{print $5}') + echo "INFO: Disk usage: ${DISK_USED}/${DISK_TOTAL} (${DISK_PCT} used, ${DISK_AVAIL} free)" + # Warn early if disk is getting full + DISK_PCT_NUM=${DISK_PCT//%/} + if [ "$DISK_PCT_NUM" -ge 90 ] 2>/dev/null; then + echo "WARNING: Disk is ${DISK_PCT} full! Add-on updates may fail. Run 'oc-cleanup' in the terminal." + elif [ "$DISK_PCT_NUM" -ge 75 ] 2>/dev/null; then + echo "NOTICE: Disk is ${DISK_PCT} full. Consider running 'oc-cleanup' in the terminal." + fi +fi -# Token comes from environment (best-effort CLI query in run.sh) -token = os.environ.get('GW_TOKEN','') - -gw_path = '' if public_url.endswith('/') else '/' - -# Replace terminal port placeholder in nginx config -conf = tpl.replace('__TERMINAL_PORT__', terminal_port) -Path('/etc/nginx/nginx.conf').write_text(conf) - -landing = landing_tpl.replace('__GATEWAY_TOKEN__', token) -landing = landing.replace('__GATEWAY_PUBLIC_URL__', public_url) -landing = landing.replace('__GW_PUBLIC_URL_PATH__', gw_path) - -out_dir = Path('/etc/nginx/html') -out_dir.mkdir(parents=True, exist_ok=True) -out_file = out_dir / 'index.html' -out_file.write_text(landing) - -# Ensure nginx can read it even if base image uses restrictive umask/permissions. -try: - out_dir.chmod(0o755) - out_file.chmod(0o644) -except Exception: - pass -PY +GW_PUBLIC_URL="$GW_PUBLIC_URL" GW_TOKEN="$GW_TOKEN" TERMINAL_PORT="$TERMINAL_PORT" \ + ENABLE_HTTPS_PROXY="$ENABLE_HTTPS_PROXY" HTTPS_PROXY_PORT="$GATEWAY_PORT" \ + GATEWAY_INTERNAL_PORT="$GATEWAY_INTERNAL_PORT" ACCESS_MODE="$ACCESS_MODE" \ + DISK_TOTAL="$DISK_TOTAL" DISK_USED="$DISK_USED" DISK_AVAIL="$DISK_AVAIL" DISK_PCT="$DISK_PCT" \ + python3 /render_nginx.py echo "Starting ingress proxy (nginx) on :48099 ..." nginx -g 'daemon off;' & diff --git a/openclaw_assistant/translations/bg.yaml b/openclaw_assistant/translations/bg.yaml index e8a6514..b20b256 100644 --- a/openclaw_assistant/translations/bg.yaml +++ b/openclaw_assistant/translations/bg.yaml @@ -46,23 +46,46 @@ configuration: gateway_mode: name: Режим на Gateway description: Режим на работа на Gateway - local (локално изпълнение на gateway, препоръчително) или remote (свързване към отдалечен gateway) - + options: + local: "Локален (препоръчително)" + remote: "Отдалечен" + gateway_bind_mode: name: Режим на свързване на Gateway - description: Режим на мрежово свързване - auto (OpenClaw избира), loopback (само 127.0.0.1, по-сигурно), lan (всички интерфейси) или tailnet (само Tailscale интерфейс). - + description: Режим на мрежово свързване - loopback (само 127.0.0.1, най-сигурен), lan (всички интерфейси) или tailnet (само Tailscale интерфейс). Пренебрегва се от предварителните режими на достъп. + options: + loopback: "Loopback (само 127.0.0.1, най-сигурен)" + lan: "LAN (всички интерфейси)" + tailnet: "Tailnet (само Tailscale)" + gateway_port: name: Порт на Gateway description: Номер на порт, на който OpenClaw gateway да слуша (по подразбиране - 18789) - + + access_mode: + name: Режим на достъп + description: "Опростява настройката на сигурен достъп. Пренебрегва gateway_bind_mode и gateway_auth_mode, когато не е зададен на Потребителски." + options: + custom: "Потребителски (индивидуални настройки)" + local_only: "Само локален (loopback + token, само Ingress)" + lan_https: "LAN HTTPS (вграден HTTPS прокси — препоръчително за телефони)" + lan_reverse_proxy: "LAN Reverse Proxy (външен прокси с trusted-proxy удостоверяване)" + tailnet_https: "Tailscale HTTPS (Tailscale + token)" + + gateway_auth_mode: + name: Режим на удостоверяване на Gateway + description: Режим на удостоверяване - token (по подразбиране) или trusted-proxy (за HTTPS reverse proxy). Пренебрегва се, когато access_mode не е Потребителски. + options: + token: "Token (по подразбиране)" + trusted-proxy: "Доверен прокси (за reverse proxy)" + + gateway_trusted_proxies: + name: Доверени прокси на Gateway + description: Списък с доверени прокси IP/CIDR, разделени със запетая, за trusted-proxy режим (пример - 127.0.0.1,192.168.88.0/24). + enable_openai_api: name: Активиране на OpenAI API description: Активиране на OpenAI-съвместим Chat Completions ендпойнт. Позволява използването на OpenClaw като разговорен агент в HA Assist pipeline чрез Extended OpenAI Conversation (HACS) или всеки OpenAI-съвместим клиент. - - allow_insecure_auth: - name: Разрешаване на HTTP автентикация - description: Разрешаване на HTTP автентикация за достъп до gateway в локалната мрежа. ВНИМАНИЕ - Активирайте само ако използвате HTTP (не HTTPS) за gateway_public_url. Необходимо за достъп от браузър през HTTP. - force_ipv4_dns: name: Принудителен IPv4 DNS ред description: Принудително задава IPv4-приоритет при DNS резолв за Node мрежови заявки. Полезно е, когато IPv6 DNS се резолвира, но IPv6 интернет маршрутизацията е неработеща (може да влияе на Telegram API polling). diff --git a/openclaw_assistant/translations/de.yaml b/openclaw_assistant/translations/de.yaml index f0945b9..ae2524c 100644 --- a/openclaw_assistant/translations/de.yaml +++ b/openclaw_assistant/translations/de.yaml @@ -46,23 +46,46 @@ configuration: gateway_mode: name: Gateway-Modus description: Gateway-Betriebsmodus - local (Gateway lokal ausführen, empfohlen) oder remote (mit einem entfernten Gateway verbinden) - + options: + local: "Lokal (empfohlen)" + remote: "Remote" + gateway_bind_mode: name: Gateway-Bindungsmodus - description: Netzwerk-Bindungsmodus - auto (OpenClaw wählt), loopback (nur 127.0.0.1, sicherer), lan (alle Schnittstellen) oder tailnet (nur Tailscale-Schnittstelle). - + description: Netzwerk-Bindungsmodus - loopback (nur 127.0.0.1, am sichersten), lan (alle Schnittstellen) oder tailnet (nur Tailscale-Schnittstelle). Wird durch Zugriffsmodus-Voreinstellungen überschrieben. + options: + loopback: "Loopback (nur 127.0.0.1, am sichersten)" + lan: "LAN (alle Schnittstellen)" + tailnet: "Tailnet (nur Tailscale)" + gateway_port: name: Gateway-Port description: Portnummer, auf der das OpenClaw-Gateway lauscht (Standard - 18789) - + + access_mode: + name: Zugriffsmodus + description: "Vereinfacht die sichere Zugriffskonfiguration. Überschreibt gateway_bind_mode und gateway_auth_mode wenn nicht auf Benutzerdefiniert gesetzt." + options: + custom: "Benutzerdefiniert (individuelle Einstellungen)" + local_only: "Nur lokal (Loopback + Token, nur Ingress)" + lan_https: "LAN HTTPS (eingebauter HTTPS-Proxy — empfohlen für Smartphones)" + lan_reverse_proxy: "LAN Reverse-Proxy (externer Proxy mit Trusted-Proxy-Auth)" + tailnet_https: "Tailscale HTTPS (Tailscale-Bindung + Token)" + + gateway_auth_mode: + name: Gateway-Authentifizierungsmodus + description: Gateway-Auth-Modus - token (Standard) oder trusted-proxy (für HTTPS-Reverse-Proxys). Wird überschrieben wenn access_mode nicht Benutzerdefiniert ist. + options: + token: "Token (Standard)" + trusted-proxy: "Vertrauenswürdiger Proxy (für Reverse-Proxys)" + + gateway_trusted_proxies: + name: Vertrauenswürdige Gateway-Proxys + description: Komma-getrennte Liste vertrauenswürdiger Proxy-IPs/CIDRs für den Trusted-Proxy-Modus (Beispiel - 127.0.0.1,192.168.88.0/24). + enable_openai_api: name: OpenAI API aktivieren description: OpenAI-kompatiblen Chat Completions Endpunkt aktivieren. Ermöglicht die Verwendung von OpenClaw als Gesprächsagent in der HA Assist Pipeline über Extended OpenAI Conversation (HACS) oder jeden OpenAI-kompatiblen Client. - - allow_insecure_auth: - name: Unsichere HTTP-Authentifizierung erlauben - description: HTTP-Authentifizierung für Gateway-Zugriff im LAN erlauben. WARNUNG - Nur aktivieren, wenn HTTP (nicht HTTPS) für gateway_public_url verwendet wird. Erforderlich für Browser-Zugriff über HTTP. - force_ipv4_dns: name: IPv4-DNS-Reihenfolge erzwingen description: Erzwingt IPv4-vorrangige DNS-Auflösung für Node-Netzwerkaufrufe. Nützlich, wenn IPv6-DNS aufgelöst wird, aber IPv6-Internet-Routing nicht funktioniert (kann Telegram-API-Polling beeinträchtigen). diff --git a/openclaw_assistant/translations/en.yaml b/openclaw_assistant/translations/en.yaml index 191b024..aec02af 100644 --- a/openclaw_assistant/translations/en.yaml +++ b/openclaw_assistant/translations/en.yaml @@ -46,23 +46,46 @@ configuration: gateway_mode: name: Gateway Mode description: Gateway operation mode - local (run gateway locally, recommended) or remote (connect to a remote gateway) - + options: + local: "Local (recommended)" + remote: "Remote" + gateway_bind_mode: name: Gateway Bind Mode - description: Network bind mode - auto (OpenClaw selects), loopback (127.0.0.1 only, more secure), lan (all interfaces), or tailnet (Tailscale interface only). - + description: Network bind mode - loopback (127.0.0.1 only, most secure), lan (all interfaces), or tailnet (Tailscale interface only). Overridden by access_mode presets. + options: + loopback: "Loopback (127.0.0.1 only, most secure)" + lan: "LAN (all interfaces)" + tailnet: "Tailnet (Tailscale only)" + gateway_port: name: Gateway Port description: Port number for the OpenClaw gateway to listen on (default - 18789) - + + access_mode: + name: Access Mode + description: "Simplifies secure access setup. Overrides gateway_bind_mode and gateway_auth_mode when not set to Custom." + options: + custom: "Custom (use individual settings)" + local_only: "Local Only (loopback + token, Ingress only)" + lan_https: "LAN HTTPS (built-in HTTPS proxy — recommended for phones)" + lan_reverse_proxy: "LAN Reverse Proxy (external proxy with trusted-proxy auth)" + tailnet_https: "Tailscale HTTPS (Tailscale bind + token)" + + gateway_auth_mode: + name: Gateway Auth Mode + description: Gateway auth mode - token (default) or trusted-proxy (for HTTPS reverse proxies). Overridden when access_mode is not Custom. + options: + token: "Token (default)" + trusted-proxy: "Trusted Proxy (for reverse proxies)" + + gateway_trusted_proxies: + name: Gateway Trusted Proxies + description: Comma-separated trusted proxy IP/CIDR list for trusted-proxy mode (example - 127.0.0.1,192.168.88.0/24). + enable_openai_api: name: Enable OpenAI API description: Enable OpenAI-compatible Chat Completions endpoint. Allows using OpenClaw as a conversation agent in HA Assist pipeline via Extended OpenAI Conversation (HACS) or any OpenAI-compatible client. - - allow_insecure_auth: - name: Allow Insecure HTTP Auth - description: Allow HTTP authentication for gateway access on LAN. WARNING - Only enable if using HTTP (not HTTPS) for gateway_public_url. Required for browser access over HTTP. - force_ipv4_dns: name: Force IPv4 DNS Order description: Force IPv4-first DNS ordering for Node network calls. Useful when IPv6 DNS resolves but IPv6 internet routing is broken (can affect Telegram API polling). diff --git a/openclaw_assistant/translations/es.yaml b/openclaw_assistant/translations/es.yaml index 8a7ce84..b5224fa 100644 --- a/openclaw_assistant/translations/es.yaml +++ b/openclaw_assistant/translations/es.yaml @@ -46,23 +46,46 @@ configuration: gateway_mode: name: Modo del Gateway description: Modo de operación del Gateway - local (ejecutar gateway localmente, recomendado) o remote (conectar a un gateway remoto) - + options: + local: "Local (recomendado)" + remote: "Remoto" + gateway_bind_mode: name: Modo de enlace del Gateway - description: "Modo de enlace de red: auto (OpenClaw selecciona), loopback (solo 127.0.0.1, más seguro), lan (todas las interfaces) o tailnet (solo interfaz Tailscale)." - + description: "Modo de enlace de red: loopback (solo 127.0.0.1, más seguro), lan (todas las interfaces) o tailnet (solo interfaz Tailscale). Se anula con las preselecciones del modo de acceso." + options: + loopback: "Loopback (solo 127.0.0.1, más seguro)" + lan: "LAN (todas las interfaces)" + tailnet: "Tailnet (solo Tailscale)" + gateway_port: name: Puerto del Gateway description: Número de puerto en el que el gateway de OpenClaw escuchará (predeterminado - 18789) - + + access_mode: + name: Modo de acceso + description: "Simplifica la configuración de acceso seguro. Anula gateway_bind_mode y gateway_auth_mode cuando no es Personalizado." + options: + custom: "Personalizado (configuración individual)" + local_only: "Solo local (loopback + token, solo Ingress)" + lan_https: "LAN HTTPS (proxy HTTPS integrado — recomendado para teléfonos)" + lan_reverse_proxy: "LAN Proxy inverso (proxy externo con auth trusted-proxy)" + tailnet_https: "Tailscale HTTPS (Tailscale + token)" + + gateway_auth_mode: + name: Modo de autenticación del Gateway + description: Modo de autenticación - token (predeterminado) o trusted-proxy (para proxys inversos HTTPS). Se anula cuando access_mode no es Personalizado. + options: + token: "Token (predeterminado)" + trusted-proxy: "Proxy de confianza (para proxys inversos)" + + gateway_trusted_proxies: + name: Proxys de confianza del Gateway + description: Lista de IPs/CIDR de proxys de confianza separados por comas para el modo trusted-proxy (ejemplo - 127.0.0.1,192.168.88.0/24). + enable_openai_api: name: Activar API OpenAI description: Activar endpoint de Chat Completions compatible con OpenAI. Permite usar OpenClaw como agente de conversación en HA Assist pipeline mediante Extended OpenAI Conversation (HACS) o cualquier cliente compatible con OpenAI. - - allow_insecure_auth: - name: Permitir autenticación HTTP insegura - description: Permitir autenticación HTTP para acceso al gateway en LAN. ADVERTENCIA - Solo habilitar si usa HTTP (no HTTPS) para gateway_public_url. Requerido para acceso desde navegador por HTTP. - force_ipv4_dns: name: Forzar orden DNS IPv4 description: Fuerza el orden de DNS con prioridad IPv4 para llamadas de red de Node. Útil cuando el DNS IPv6 resuelve, pero el enrutamiento IPv6 a Internet falla (puede afectar el polling de la API de Telegram). diff --git a/openclaw_assistant/translations/pl.yaml b/openclaw_assistant/translations/pl.yaml index 7b6324d..5dcc7cd 100644 --- a/openclaw_assistant/translations/pl.yaml +++ b/openclaw_assistant/translations/pl.yaml @@ -45,24 +45,47 @@ configuration: gateway_bind_mode: name: Tryb bindowania Gateway - description: Tryb bindowania sieci - auto (OpenClaw wybiera), loopback (tylko 127.0.0.1, bezpieczniej), lan (wszystkie interfejsy) lub tailnet (tylko interfejs Tailscale). - + description: Tryb bindowania sieci - loopback (tylko 127.0.0.1, najbezpieczniejszy), lan (wszystkie interfejsy) lub tailnet (tylko interfejs Tailscale). Nadpisywane przez ustawienia trybu dostępu. + options: + loopback: "Loopback (tylko 127.0.0.1, najbezpieczniejszy)" + lan: "LAN (wszystkie interfejsy)" + tailnet: "Tailnet (tylko Tailscale)" + gateway_port: name: Port Gateway description: Numer portu na którym gateway OpenClaw będzie nasłuchiwał (domyślnie - 18789) - - enable_openai_api: - name: Włącz API OpenAI - description: Włącz endpoint Chat Completions kompatybilny z OpenAI. Pozwala używać OpenClaw jako agenta konwersacji w HA Assist pipeline przez Extended OpenAI Conversation (HACS) lub dowolnego klienta kompatybilnego z OpenAI. - - allow_insecure_auth: - name: Zezwól na niezabezpieczone uwierzytelnianie HTTP - description: Zezwól na uwierzytelnianie HTTP dla dostępu do gateway w sieci LAN. UWAGA - Włącz tylko jeśli używasz HTTP (nie HTTPS) dla gateway_public_url. Wymagane dla dostępu przez przeglądarkę przez HTTP. - + gateway_mode: name: Tryb Gateway description: Tryb działania gateway - local (uruchom gateway lokalnie, zalecane) lub remote (połącz się ze zdalnym gateway) + options: + local: "Lokalny (zalecane)" + remote: "Zdalny" + access_mode: + name: Tryb dostępu + description: "Upraszcza konfigurację bezpiecznego dostępu. Nadpisuje gateway_bind_mode i gateway_auth_mode gdy nie jest ustawiony na Niestandardowy." + options: + custom: "Niestandardowy (indywidualne ustawienia)" + local_only: "Tylko lokalny (loopback + token, tylko Ingress)" + lan_https: "LAN HTTPS (wbudowany proxy HTTPS — zalecane dla telefonów)" + lan_reverse_proxy: "LAN Reverse Proxy (zewnętrzny proxy z auth trusted-proxy)" + tailnet_https: "Tailscale HTTPS (Tailscale + token)" + + gateway_auth_mode: + name: Tryb uwierzytelniania Gateway + description: Tryb uwierzytelniania - token (domyślnie) lub trusted-proxy (dla reverse proxy HTTPS). Nadpisywane gdy access_mode nie jest Niestandardowy. + options: + token: "Token (domyślnie)" + trusted-proxy: "Zaufany proxy (dla reverse proxy)" + + gateway_trusted_proxies: + name: Zaufane proxy Gateway + description: Lista zaufanych IP/CIDR proxy rozdzielona przecinkami dla trybu trusted-proxy (przykład - 127.0.0.1,192.168.88.0/24). + + enable_openai_api: + name: Włącz API OpenAI + description: Włącz endpoint Chat Completions kompatybilny z OpenAI. Pozwala używać OpenClaw jako agenta konwersacji w HA Assist pipeline przez Extended OpenAI Conversation (HACS) lub dowolnego klienta kompatybilnego z OpenAI. force_ipv4_dns: name: Wymuś kolejność DNS IPv4 description: Wymusza preferowanie IPv4 przy rozwiązywaniu DNS dla wywołań sieciowych Node. Przydatne, gdy DNS IPv6 się rozwiązuje, ale routing IPv6 do Internetu nie działa (może wpływać na polling API Telegrama). diff --git a/openclaw_assistant/translations/pt-BR.yaml b/openclaw_assistant/translations/pt-BR.yaml index d688d7f..5f82838 100644 --- a/openclaw_assistant/translations/pt-BR.yaml +++ b/openclaw_assistant/translations/pt-BR.yaml @@ -46,23 +46,46 @@ configuration: gateway_mode: name: Modo do Gateway description: Modo de operação do gateway - local (executar gateway localmente, recomendado) ou remote (conectar a um gateway remoto) - + options: + local: "Local (recomendado)" + remote: "Remoto" + gateway_bind_mode: name: Modo de Vinculação do Gateway - description: Modo de vinculação de rede - auto (OpenClaw escolhe), loopback (somente 127.0.0.1, mais seguro), lan (todas as interfaces) ou tailnet (somente interface Tailscale). - + description: Modo de vinculação de rede - loopback (somente 127.0.0.1, mais seguro), lan (todas as interfaces) ou tailnet (somente interface Tailscale). Substituído pelas predefinições do modo de acesso. + options: + loopback: "Loopback (somente 127.0.0.1, mais seguro)" + lan: "LAN (todas as interfaces)" + tailnet: "Tailnet (somente Tailscale)" + gateway_port: name: Porta do Gateway description: Número da porta para o gateway do OpenClaw escutar (padrão - 18789) - + + access_mode: + name: Modo de Acesso + description: "Simplifica a configuração de acesso seguro. Substitui gateway_bind_mode e gateway_auth_mode quando não definido como Personalizado." + options: + custom: "Personalizado (configurações individuais)" + local_only: "Apenas local (loopback + token, apenas Ingress)" + lan_https: "LAN HTTPS (proxy HTTPS integrado — recomendado para celulares)" + lan_reverse_proxy: "LAN Reverse Proxy (proxy externo com auth trusted-proxy)" + tailnet_https: "Tailscale HTTPS (Tailscale + token)" + + gateway_auth_mode: + name: Modo de Autenticação do Gateway + description: Modo de autenticação - token (padrão) ou trusted-proxy (para reverse proxies HTTPS). Substituído quando access_mode não é Personalizado. + options: + token: "Token (padrão)" + trusted-proxy: "Proxy Confiável (para reverse proxies)" + + gateway_trusted_proxies: + name: Proxies Confiáveis do Gateway + description: Lista de IPs/CIDR de proxies confiáveis separados por vírgula para o modo trusted-proxy (exemplo - 127.0.0.1,192.168.88.0/24). + enable_openai_api: name: Habilitar API OpenAI description: Habilitar endpoint de Chat Completions compatível com OpenAI. Permite usar o OpenClaw como agente de conversação no pipeline do HA Assist via Extended OpenAI Conversation (HACS) ou qualquer cliente compatível com OpenAI. - - allow_insecure_auth: - name: Permitir Autenticação HTTP Insegura - description: Permitir autenticação HTTP para acesso ao gateway na LAN. AVISO - Habilite somente se estiver usando HTTP (não HTTPS) para gateway_public_url. Necessário para acesso pelo navegador via HTTP. - force_ipv4_dns: name: Forçar ordem DNS IPv4 description: Força a ordem de DNS com prioridade para IPv4 nas chamadas de rede do Node. Útil quando o DNS IPv6 resolve, mas o roteamento IPv6 para a internet está quebrado (pode afetar o polling da API do Telegram).