From 9e4987d25f8292e8acb56915d644ab50abbfa341 Mon Sep 17 00:00:00 2001 From: techartdev Date: Thu, 5 Feb 2026 09:57:41 +0200 Subject: [PATCH 1/6] Add configurable terminal port support and update translations - Updated nginx configuration to use a placeholder for terminal port. - Modified run.sh to read terminal port from options file and start ttyd on the specified port. - Added terminal port configuration option in English, Bulgarian, German, and Spanish translations. --- openclaw_assistant/nginx.conf.tpl | 2 +- openclaw_assistant/run.sh | 21 +++++++++++++++------ openclaw_assistant/translations/bg.yaml | 4 ++++ openclaw_assistant/translations/de.yaml | 4 ++++ openclaw_assistant/translations/en.yaml | 4 ++++ openclaw_assistant/translations/es.yaml | 4 ++++ 6 files changed, 32 insertions(+), 7 deletions(-) diff --git a/openclaw_assistant/nginx.conf.tpl b/openclaw_assistant/nginx.conf.tpl index e48f913..d344673 100644 --- a/openclaw_assistant/nginx.conf.tpl +++ b/openclaw_assistant/nginx.conf.tpl @@ -31,7 +31,7 @@ http { # Proxy everything under /terminal/ (including websocket /terminal/ws) location ^~ /terminal/ { # IMPORTANT: no trailing slash in proxy_pass so nginx preserves the full URI - proxy_pass http://127.0.0.1:7681; + proxy_pass http://127.0.0.1:__TERMINAL_PORT__; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; diff --git a/openclaw_assistant/run.sh b/openclaw_assistant/run.sh index b252207..38faaf8 100644 --- a/openclaw_assistant/run.sh +++ b/openclaw_assistant/run.sh @@ -21,6 +21,10 @@ TZNAME=$(jq -r '.timezone // "Europe/Sofia"' "$OPTIONS_FILE") GW_PUBLIC_URL=$(jq -r '.gateway_public_url // empty' "$OPTIONS_FILE") HA_TOKEN=$(jq -r '.homeassistant_token // empty' "$OPTIONS_FILE") ENABLE_TERMINAL=$(jq -r '.enable_terminal // true' "$OPTIONS_FILE") +TERMINAL_PORT=$(jq -r '.terminal_port // 7681' "$OPTIONS_FILE") + +echo "DEBUG: enable_terminal config value: '$ENABLE_TERMINAL'" +echo "DEBUG: terminal_port config value: '$TERMINAL_PORT'" # Generic router SSH settings ROUTER_HOST=$(jq -r '.router_ssh_host // empty' "$OPTIONS_FILE") @@ -239,12 +243,15 @@ openclaw gateway run & GW_PID=$! # Start web terminal (optional) -if [ "$ENABLE_TERMINAL" = "true" ]; then - echo "Starting web terminal (ttyd) on 127.0.0.1:7681 ..." - ttyd -W -i 127.0.0.1 -p 7681 -b /terminal bash & +# Kill any stray ttyd processes from previous runs to avoid port conflicts +pkill -f "ttyd.*-p.*-b /terminal" || true + +if [ "$ENABLE_TERMINAL" = "true" ] || [ "$ENABLE_TERMINAL" = "1" ]; then + echo "Starting web terminal (ttyd) on 127.0.0.1:${TERMINAL_PORT} ..." + ttyd -W -i 127.0.0.1 -p "${TERMINAL_PORT}" -b /terminal bash & TTYD_PID=$! else - echo "Terminal disabled (enable_terminal=false)" + echo "Terminal disabled (enable_terminal=$ENABLE_TERMINAL)" fi # Start ingress reverse proxy (nginx). This provides the add-on UI inside HA. @@ -254,20 +261,22 @@ 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" python3 - <<'PY' +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') # Token comes from environment (best-effort CLI query in run.sh) token = os.environ.get('GW_TOKEN','') gw_path = '' if public_url.endswith('/') else '/' -conf = tpl +# 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) diff --git a/openclaw_assistant/translations/bg.yaml b/openclaw_assistant/translations/bg.yaml index 0aaf82c..8bd312a 100644 --- a/openclaw_assistant/translations/bg.yaml +++ b/openclaw_assistant/translations/bg.yaml @@ -7,6 +7,10 @@ configuration: name: Активиране на уеб терминал description: Активиране на уеб терминал бутона в Home Assistant (Ingress) чрез ttyd + terminal_port: + name: Порт на терминал + description: Номер на порт за уеб терминала (по подразбиране - 7681). Променете, ако този порт е в конфликт с друга услуга. + gateway_public_url: name: Публичен URL на Gateway description: Публичен базов URL за отваряне на Gateway уеб интерфейса в нов таб (не вграден). Пример - https://example.duckdns.org:12345 или http://192.168.1.10:18789 diff --git a/openclaw_assistant/translations/de.yaml b/openclaw_assistant/translations/de.yaml index 3c95ac1..658d821 100644 --- a/openclaw_assistant/translations/de.yaml +++ b/openclaw_assistant/translations/de.yaml @@ -7,6 +7,10 @@ configuration: name: Web-Terminal aktivieren description: Web-Terminal-Schaltfläche in Home Assistant (Ingress) über ttyd aktivieren + terminal_port: + name: Terminal-Port + description: Portnummer für das Web-Terminal (Standard - 7681). Ändern Sie diese, wenn dieser Port mit einem anderen Dienst in Konflikt steht. + gateway_public_url: name: Öffentliche Gateway-URL description: Öffentliche Basis-URL zum Öffnen der Gateway-Weboberfläche in einem neuen Tab (nicht eingebettet). Beispiel - https://example.duckdns.org:12345 oder http://192.168.1.10:18789 diff --git a/openclaw_assistant/translations/en.yaml b/openclaw_assistant/translations/en.yaml index 5f16300..e38d137 100644 --- a/openclaw_assistant/translations/en.yaml +++ b/openclaw_assistant/translations/en.yaml @@ -7,6 +7,10 @@ configuration: name: Enable Web Terminal description: Enable web terminal Button inside Home Assistant (Ingress) via ttyd + terminal_port: + name: Terminal Port + description: Port number for the web terminal (default - 7681). Change if this port conflicts with another service. + gateway_public_url: name: Gateway Public URL description: Public base URL for opening the Gateway Web UI in a new tab (not embedded). Example - https://example.duckdns.org:12345 or http://192.168.1.10:18789 diff --git a/openclaw_assistant/translations/es.yaml b/openclaw_assistant/translations/es.yaml index ef88940..7a4bdb0 100644 --- a/openclaw_assistant/translations/es.yaml +++ b/openclaw_assistant/translations/es.yaml @@ -7,6 +7,10 @@ configuration: name: Activar terminal web description: Activar botón de terminal web dentro de Home Assistant (Ingress) mediante ttyd + terminal_port: + name: Puerto del terminal + description: Número de puerto para el terminal web (predeterminado - 7681). Cambie si este puerto entra en conflicto con otro servicio. + gateway_public_url: name: URL pública del Gateway description: URL base pública para abrir la interfaz web del Gateway en una nueva pestaña (no integrada). Ejemplo - https://example.duckdns.org:12345 o http://192.168.1.10:18789 From c59417a180b5774a19cb4251316e67d2bde4e973 Mon Sep 17 00:00:00 2001 From: techartdev Date: Thu, 5 Feb 2026 12:03:05 +0200 Subject: [PATCH 2/6] Add terminal port configuration option to config.yaml --- openclaw_assistant/config.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/openclaw_assistant/config.yaml b/openclaw_assistant/config.yaml index 56453d7..43c8781 100644 --- a/openclaw_assistant/config.yaml +++ b/openclaw_assistant/config.yaml @@ -28,6 +28,9 @@ options: # Enable web terminal inside Home Assistant (Ingress) via ttyd enable_terminal: true + # Terminal port (change if 7681 conflicts with another service) + terminal_port: 7681 + # Public base URL for opening the Gateway Web UI in a new tab (not embedded). # Recommended: NO trailing slash. # Example: "https://example.duckdns.org:12345" or "http://192.168.1.10:18789" @@ -65,6 +68,7 @@ options: schema: timezone: str enable_terminal: bool? + terminal_port: int(1024,65535)? gateway_public_url: str? homeassistant_token: str? From c3301c24453aa1c34562feb2048c683088f7cf79 Mon Sep 17 00:00:00 2001 From: TechArtDev Date: Thu, 5 Feb 2026 12:04:07 +0200 Subject: [PATCH 3/6] Update openclaw_assistant/run.sh Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- openclaw_assistant/run.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/openclaw_assistant/run.sh b/openclaw_assistant/run.sh index 38faaf8..925b19f 100644 --- a/openclaw_assistant/run.sh +++ b/openclaw_assistant/run.sh @@ -244,7 +244,10 @@ GW_PID=$! # Start web terminal (optional) # Kill any stray ttyd processes from previous runs to avoid port conflicts -pkill -f "ttyd.*-p.*-b /terminal" || true +TTYD_PATTERN="ttyd .* -i 127.0.0.1 .* -p ${TERMINAL_PORT} .* -b /terminal" +if pgrep -f "$TTYD_PATTERN" >/dev/null 2>&1; then + pkill -f "$TTYD_PATTERN" || true +fi if [ "$ENABLE_TERMINAL" = "true" ] || [ "$ENABLE_TERMINAL" = "1" ]; then echo "Starting web terminal (ttyd) on 127.0.0.1:${TERMINAL_PORT} ..." From 65de88dc148f2d3fa345fb014f2595653569f75b Mon Sep 17 00:00:00 2001 From: techartdev Date: Thu, 5 Feb 2026 12:07:39 +0200 Subject: [PATCH 4/6] Add terminal configuration options to documentation --- DOCS.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/DOCS.md b/DOCS.md index 61685d5..7f48a84 100644 --- a/DOCS.md +++ b/DOCS.md @@ -170,7 +170,13 @@ Control how the OpenClaw gateway binds to the network: These settings are applied automatically on add-on startup. No need to run `openclaw config` commands manually. ### Terminal -- `enable_terminal` (bool, default **true**) +- **`enable_terminal`** (bool, default **true**) + - Enable or disable the web terminal button inside Home Assistant + +- **`terminal_port`** (int, default **7681**) + - Port number for the web terminal (ttyd) to listen on + - Change this if port 7681 conflicts with another service on your system + - Valid range: 1024-65535 Security note: the terminal gives shell access inside the add-on container. From 517a4fbbd7deedb6ae581b6e9a0b06082d8e8096 Mon Sep 17 00:00:00 2001 From: techartdev Date: Thu, 5 Feb 2026 12:09:27 +0200 Subject: [PATCH 5/6] Validate terminal port configuration and improve error handling in run.sh --- openclaw_assistant/run.sh | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/openclaw_assistant/run.sh b/openclaw_assistant/run.sh index 925b19f..dd06f69 100644 --- a/openclaw_assistant/run.sh +++ b/openclaw_assistant/run.sh @@ -21,10 +21,19 @@ TZNAME=$(jq -r '.timezone // "Europe/Sofia"' "$OPTIONS_FILE") GW_PUBLIC_URL=$(jq -r '.gateway_public_url // empty' "$OPTIONS_FILE") HA_TOKEN=$(jq -r '.homeassistant_token // empty' "$OPTIONS_FILE") ENABLE_TERMINAL=$(jq -r '.enable_terminal // true' "$OPTIONS_FILE") -TERMINAL_PORT=$(jq -r '.terminal_port // 7681' "$OPTIONS_FILE") +TERMINAL_PORT_RAW=$(jq -r '.terminal_port // 7681' "$OPTIONS_FILE") + +# SECURITY: Validate TERMINAL_PORT to prevent nginx config injection +# Only allow numeric values in valid port range (1024-65535) +if [[ "$TERMINAL_PORT_RAW" =~ ^[0-9]+$ ]] && [ "$TERMINAL_PORT_RAW" -ge 1024 ] && [ "$TERMINAL_PORT_RAW" -le 65535 ]; then + TERMINAL_PORT="$TERMINAL_PORT_RAW" +else + echo "ERROR: Invalid terminal_port '$TERMINAL_PORT_RAW'. Must be numeric 1024-65535. Using default 7681." + TERMINAL_PORT="7681" +fi echo "DEBUG: enable_terminal config value: '$ENABLE_TERMINAL'" -echo "DEBUG: terminal_port config value: '$TERMINAL_PORT'" +echo "DEBUG: terminal_port config value: '$TERMINAL_PORT' (validated)" # Generic router SSH settings ROUTER_HOST=$(jq -r '.router_ssh_host // empty' "$OPTIONS_FILE") @@ -244,10 +253,7 @@ GW_PID=$! # Start web terminal (optional) # Kill any stray ttyd processes from previous runs to avoid port conflicts -TTYD_PATTERN="ttyd .* -i 127.0.0.1 .* -p ${TERMINAL_PORT} .* -b /terminal" -if pgrep -f "$TTYD_PATTERN" >/dev/null 2>&1; then - pkill -f "$TTYD_PATTERN" || true -fi +pkill -f "ttyd.*-p.*-b /terminal" || true if [ "$ENABLE_TERMINAL" = "true" ] || [ "$ENABLE_TERMINAL" = "1" ]; then echo "Starting web terminal (ttyd) on 127.0.0.1:${TERMINAL_PORT} ..." From f9c80534ea015ac73c8847c56be27f39246a55d0 Mon Sep 17 00:00:00 2001 From: techartdev Date: Thu, 5 Feb 2026 12:24:55 +0200 Subject: [PATCH 6/6] Implement PID file management for ttyd to prevent port conflicts --- openclaw_assistant/run.sh | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/openclaw_assistant/run.sh b/openclaw_assistant/run.sh index dd06f69..ffa804d 100644 --- a/openclaw_assistant/run.sh +++ b/openclaw_assistant/run.sh @@ -252,13 +252,27 @@ openclaw gateway run & GW_PID=$! # Start web terminal (optional) -# Kill any stray ttyd processes from previous runs to avoid port conflicts -pkill -f "ttyd.*-p.*-b /terminal" || true +TTYD_PID_FILE="/var/run/openclaw-ttyd.pid" + +# Clean up stale ttyd process from previous run using PID file +if [ -f "$TTYD_PID_FILE" ]; then + OLD_PID=$(cat "$TTYD_PID_FILE" 2>/dev/null || echo "") + if [ -n "$OLD_PID" ] && kill -0 "$OLD_PID" 2>/dev/null; then + echo "Stopping previous ttyd process (PID $OLD_PID)..." + kill "$OLD_PID" 2>/dev/null || true + sleep 1 + # Force kill if still running + kill -9 "$OLD_PID" 2>/dev/null || true + fi + rm -f "$TTYD_PID_FILE" +fi if [ "$ENABLE_TERMINAL" = "true" ] || [ "$ENABLE_TERMINAL" = "1" ]; then echo "Starting web terminal (ttyd) on 127.0.0.1:${TERMINAL_PORT} ..." ttyd -W -i 127.0.0.1 -p "${TERMINAL_PORT}" -b /terminal bash & TTYD_PID=$! + echo "$TTYD_PID" > "$TTYD_PID_FILE" + echo "ttyd started with PID $TTYD_PID" else echo "Terminal disabled (enable_terminal=$ENABLE_TERMINAL)" fi