Merge pull request #323 from outis1one/claude/extensions-qr-code-popup-6jlkcp
Claude/extensions qr code popup 6jlkcp
This commit is contained in:
@@ -805,6 +805,41 @@ find_free_port() {
|
|||||||
eval "$_varname='$_port'"
|
eval "$_varname='$_port'"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# find_free_coturn_range MIN_VARNAME MAX_VARNAME RANGE_SIZE [START_PORT]
|
||||||
|
# A coturn relay port range can't be collision-checked with port_in_use /
|
||||||
|
# find_free_port the way a single fixed port can: coturn only opens ports
|
||||||
|
# inside min-port..max-port on demand, per active TURN allocation, so an
|
||||||
|
# idle range shows up as nothing listening either way — a live socket scan
|
||||||
|
# can't tell two coturn CONFIGS apart. The only reliable check is reading
|
||||||
|
# what range every other coturn-owning service on the box actually claims,
|
||||||
|
# from its own .env (COTURN_MAX_PORT for the shared instance in
|
||||||
|
# ~/docker/coturn/.env, TURN_MAX_PORT for every dedicated per-service coturn
|
||||||
|
# — Asterisk's own, each Mattermost instance's, etc., each in that service's
|
||||||
|
# own .env). Every service directory keeps its .env at the same top-level
|
||||||
|
# path, so one glob covers all of them without needing to know which
|
||||||
|
# services exist ahead of time.
|
||||||
|
#
|
||||||
|
# Writes a RANGE_SIZE-wide block starting safely past the highest claimed
|
||||||
|
# max-port back into MIN_VARNAME/MAX_VARNAME. No other coturn on the box at
|
||||||
|
# all (fresh install, nothing else uses TURN) leaves it at START_PORT — no
|
||||||
|
# collision is possible yet, so there's nothing to shift away from.
|
||||||
|
find_free_coturn_range() {
|
||||||
|
local _min_varname="$1" _max_varname="$2" _range_size="${3:-200}" _start="${4:-49152}"
|
||||||
|
local _highest_max=$((_start - 1)) _f _found
|
||||||
|
for _f in "$DOCKER_DIR"/*/.env; do
|
||||||
|
[ -f "$_f" ] || continue
|
||||||
|
_found="$(grep -E '^(COTURN|TURN)_MAX_PORT=' "$_f" 2>/dev/null | tail -1 | cut -d= -f2-)"
|
||||||
|
[[ "$_found" =~ ^[0-9]+$ ]] || continue
|
||||||
|
[ "$_found" -gt "$_highest_max" ] && _highest_max=$_found
|
||||||
|
done
|
||||||
|
local _min=$_start
|
||||||
|
if [ "$_highest_max" -ge "$_start" ]; then
|
||||||
|
_min=$((_highest_max + 50))
|
||||||
|
fi
|
||||||
|
eval "$_min_varname='$_min'"
|
||||||
|
eval "$_max_varname='$((_min + _range_size))'"
|
||||||
|
}
|
||||||
|
|
||||||
# ── Caddy reverse-proxy wiring (shared by every web service) ─────────────────
|
# ── Caddy reverse-proxy wiring (shared by every web service) ─────────────────
|
||||||
# Usage: configure_caddy_for_service "Name" "UPSTREAM" "default-subdomain" ["extra"]
|
# Usage: configure_caddy_for_service "Name" "UPSTREAM" "default-subdomain" ["extra"]
|
||||||
# UPSTREAM: container:port for caddy_net routing (e.g. "filebrowser:80"),
|
# UPSTREAM: container:port for caddy_net routing (e.g. "filebrowser:80"),
|
||||||
|
|||||||
+80
-14
@@ -123,6 +123,23 @@ if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
|||||||
log_success "Swapfile enabled (${SWAP_MB}MB, swappiness=10, persists across reboots)."
|
log_success "Swapfile enabled (${SWAP_MB}MB, swappiness=10, persists across reboots)."
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Standalone-mode copy of lib/common.sh's find_free_coturn_range() —
|
||||||
|
# kept in sync by hand, same as every other helper stubbed in this block.
|
||||||
|
find_free_coturn_range() {
|
||||||
|
local _min_varname="$1" _max_varname="$2" _range_size="${3:-200}" _start="${4:-49152}"
|
||||||
|
local _highest_max=$((_start - 1)) _f _found
|
||||||
|
for _f in "$DOCKER_DIR"/*/.env; do
|
||||||
|
[ -f "$_f" ] || continue
|
||||||
|
_found="$(grep -E '^(COTURN|TURN)_MAX_PORT=' "$_f" 2>/dev/null | tail -1 | cut -d= -f2-)"
|
||||||
|
[[ "$_found" =~ ^[0-9]+$ ]] || continue
|
||||||
|
[ "$_found" -gt "$_highest_max" ] && _highest_max=$_found
|
||||||
|
done
|
||||||
|
local _min=$_start
|
||||||
|
[ "$_highest_max" -ge "$_start" ] && _min=$((_highest_max + 50))
|
||||||
|
eval "$_min_varname='$_min'"
|
||||||
|
eval "$_max_varname='$((_min + _range_size))'"
|
||||||
|
}
|
||||||
|
|
||||||
configure_caddy_for_service() {
|
configure_caddy_for_service() {
|
||||||
local _name="$1" _upstream="$2" _subdomain="$3" _extra="${4:-}"
|
local _name="$1" _upstream="$2" _subdomain="$3" _extra="${4:-}"
|
||||||
local _caddy_dir="$DOCKER_DIR/caddy"
|
local _caddy_dir="$DOCKER_DIR/caddy"
|
||||||
@@ -1017,6 +1034,7 @@ _asterisk_offer_dashboard_and_trunk() {
|
|||||||
# the two call sites below for how each decides.
|
# the two call sites below for how each decides.
|
||||||
_asterisk_write_compose() {
|
_asterisk_write_compose() {
|
||||||
local PROJECT="$1" CONTAINER="$2" COTURN_CONTAINER="$3" USE_EMBEDDED_COTURN="${4:-true}"
|
local PROJECT="$1" CONTAINER="$2" COTURN_CONTAINER="$3" USE_EMBEDDED_COTURN="${4:-true}"
|
||||||
|
local COTURN_MIN_PORT_VAL="${5:-49152}" COTURN_MAX_PORT_VAL="${6:-49252}"
|
||||||
|
|
||||||
local _COTURN_DEPENDS=" depends_on:
|
local _COTURN_DEPENDS=" depends_on:
|
||||||
coturn:
|
coturn:
|
||||||
@@ -1040,8 +1058,8 @@ _asterisk_write_compose() {
|
|||||||
- --lt-cred-mech
|
- --lt-cred-mech
|
||||||
- --user=\${TURN_USERNAME:-easyasterisk}:\${TURN_PASSWORD}
|
- --user=\${TURN_USERNAME:-easyasterisk}:\${TURN_PASSWORD}
|
||||||
- --realm=\${DOMAIN_NAME:-localhost}
|
- --realm=\${DOMAIN_NAME:-localhost}
|
||||||
- --min-port=49152
|
- --min-port=${COTURN_MIN_PORT_VAL}
|
||||||
- --max-port=49252
|
- --max-port=${COTURN_MAX_PORT_VAL}
|
||||||
- --no-tls
|
- --no-tls
|
||||||
- --no-dtls
|
- --no-dtls
|
||||||
- --no-cli
|
- --no-cli
|
||||||
@@ -1296,6 +1314,7 @@ CADDY_BLOCK
|
|||||||
# ── DigitalOcean Cloud Firewall (network edge, in front of the droplet) ────
|
# ── DigitalOcean Cloud Firewall (network edge, in front of the droplet) ────
|
||||||
_asterisk_configure_do_cloud_firewall() {
|
_asterisk_configure_do_cloud_firewall() {
|
||||||
local DROPLET_ID="$1" WEB_ADMIN_PORT_VAL="$2" WEB_ADMIN_PUBLIC="$3"
|
local DROPLET_ID="$1" WEB_ADMIN_PORT_VAL="$2" WEB_ADMIN_PUBLIC="$3"
|
||||||
|
local COTURN_MIN_PORT_VAL="${4:-49152}" COTURN_MAX_PORT_VAL="${5:-49252}"
|
||||||
|
|
||||||
local DO_FW_RULES=(
|
local DO_FW_RULES=(
|
||||||
"protocol:tcp,ports:22,address:0.0.0.0/0,address:::/0"
|
"protocol:tcp,ports:22,address:0.0.0.0/0,address:::/0"
|
||||||
@@ -1311,7 +1330,7 @@ _asterisk_configure_do_cloud_firewall() {
|
|||||||
"protocol:tcp,ports:3478,address:0.0.0.0/0,address:::/0"
|
"protocol:tcp,ports:3478,address:0.0.0.0/0,address:::/0"
|
||||||
"protocol:udp,ports:3478,address:0.0.0.0/0,address:::/0"
|
"protocol:udp,ports:3478,address:0.0.0.0/0,address:::/0"
|
||||||
"protocol:udp,ports:10000-20000,address:0.0.0.0/0,address:::/0"
|
"protocol:udp,ports:10000-20000,address:0.0.0.0/0,address:::/0"
|
||||||
"protocol:udp,ports:49152-49252,address:0.0.0.0/0,address:::/0"
|
"protocol:udp,ports:${COTURN_MIN_PORT_VAL}-${COTURN_MAX_PORT_VAL},address:0.0.0.0/0,address:::/0"
|
||||||
)
|
)
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
@@ -1362,6 +1381,7 @@ _asterisk_configure_do_cloud_firewall() {
|
|||||||
# wide open proves nothing about a layer in front of it that UFW can't see.
|
# wide open proves nothing about a layer in front of it that UFW can't see.
|
||||||
_asterisk_remind_non_do_firewall() {
|
_asterisk_remind_non_do_firewall() {
|
||||||
local WEB_ADMIN_PORT_VAL="$1" WEB_ADMIN_PUBLIC_ACCESS_NEEDED="$2" USE_EMBEDDED_COTURN_VAL="${3:-true}"
|
local WEB_ADMIN_PORT_VAL="$1" WEB_ADMIN_PUBLIC_ACCESS_NEEDED="$2" USE_EMBEDDED_COTURN_VAL="${3:-true}"
|
||||||
|
local COTURN_MIN_PORT_VAL="${4:-49152}" COTURN_MAX_PORT_VAL="${5:-49252}"
|
||||||
echo ""
|
echo ""
|
||||||
log_warning "This box is reachable via FQDN but wasn't set up as a DigitalOcean droplet,"
|
log_warning "This box is reachable via FQDN but wasn't set up as a DigitalOcean droplet,"
|
||||||
log_warning "so no automatic network-edge firewall was configured (that step only exists"
|
log_warning "so no automatic network-edge firewall was configured (that step only exists"
|
||||||
@@ -1379,10 +1399,12 @@ _asterisk_remind_non_do_firewall() {
|
|||||||
echo " UDP 10000-20000 (RTP media)"
|
echo " UDP 10000-20000 (RTP media)"
|
||||||
if [[ "$USE_EMBEDDED_COTURN_VAL" == true ]]; then
|
if [[ "$USE_EMBEDDED_COTURN_VAL" == true ]]; then
|
||||||
echo " UDP/TCP 3478 (TURN/STUN)"
|
echo " UDP/TCP 3478 (TURN/STUN)"
|
||||||
echo " UDP 49152-49252 (TURN relay)"
|
echo " UDP ${COTURN_MIN_PORT_VAL}-${COTURN_MAX_PORT_VAL} (TURN relay)"
|
||||||
else
|
else
|
||||||
echo " UDP/TCP 3478 and UDP 49152-49252 too, if the shared coturn instance"
|
echo " UDP/TCP 3478 too, if the shared coturn instance (services/coturn.sh) lives"
|
||||||
echo " (services/coturn.sh) lives on this same box."
|
echo " on this same box — its exact TURN relay range is in its own README"
|
||||||
|
echo " (~/docker/coturn/README.md), not repeated here since it's independently"
|
||||||
|
echo " configurable and this install doesn't own it."
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1392,6 +1414,7 @@ _asterisk_remind_non_do_firewall() {
|
|||||||
_asterisk_write_readme() {
|
_asterisk_write_readme() {
|
||||||
local EA_DIR="$1" CONTAINER="$2" IS_DO="$3" DOMAIN_NAME="$4" PUBLIC_IP="$5" WEB_ADMIN_PORT_VAL="$6"
|
local EA_DIR="$1" CONTAINER="$2" IS_DO="$3" DOMAIN_NAME="$4" PUBLIC_IP="$5" WEB_ADMIN_PORT_VAL="$6"
|
||||||
local USE_EMBEDDED_COTURN="${7:-true}" TURN_USERNAME_VAL="${8:-easyasterisk}" TURN_SERVER_DISPLAY="${9:-}"
|
local USE_EMBEDDED_COTURN="${7:-true}" TURN_USERNAME_VAL="${8:-easyasterisk}" TURN_SERVER_DISPLAY="${9:-}"
|
||||||
|
local COTURN_MIN_PORT_VAL="${10:-49152}" COTURN_MAX_PORT_VAL="${11:-49252}"
|
||||||
local _host="${DOMAIN_NAME:-${PUBLIC_IP:-<host-ip>}}"
|
local _host="${DOMAIN_NAME:-${PUBLIC_IP:-<host-ip>}}"
|
||||||
[ -z "$TURN_SERVER_DISPLAY" ] && TURN_SERVER_DISPLAY="${_host}:3478"
|
[ -z "$TURN_SERVER_DISPLAY" ] && TURN_SERVER_DISPLAY="${_host}:3478"
|
||||||
|
|
||||||
@@ -1525,7 +1548,7 @@ docker exec -it ${CONTAINER} easy-asterisk
|
|||||||
| 8088/8089 | TCP | Asterisk HTTP/WS (ARI/AMI) |
|
| 8088/8089 | TCP | Asterisk HTTP/WS (ARI/AMI) |
|
||||||
| 3478 | UDP/TCP | TURN/STUN (coturn) |
|
| 3478 | UDP/TCP | TURN/STUN (coturn) |
|
||||||
| 10000–20000 | UDP | RTP media streams |
|
| 10000–20000 | UDP | RTP media streams |
|
||||||
| 49152–49252 | UDP | TURN relay media ports |
|
| ${COTURN_MIN_PORT_VAL}–${COTURN_MAX_PORT_VAL} | UDP | TURN relay media ports (only if this install runs its own dedicated coturn — see below) |
|
||||||
|
|
||||||
## Data directories (all inside ${EA_DIR}/, included in backup)
|
## Data directories (all inside ${EA_DIR}/, included in backup)
|
||||||
|
|
||||||
@@ -1885,6 +1908,7 @@ install_asterisk() {
|
|||||||
# end up with no TURN at all just because the shared path had a problem.
|
# end up with no TURN at all just because the shared path had a problem.
|
||||||
local USE_EMBEDDED_COTURN=true
|
local USE_EMBEDDED_COTURN=true
|
||||||
local TURN_USERNAME TURN_PASSWORD TURN_PORT_VAL TURN_SERVER_VAL
|
local TURN_USERNAME TURN_PASSWORD TURN_PORT_VAL TURN_SERVER_VAL
|
||||||
|
local FORCE_EMBEDDED_COTURN=""
|
||||||
|
|
||||||
# Only reachable here via an explicit "fresh" choice above — "update"
|
# Only reachable here via an explicit "fresh" choice above — "update"
|
||||||
# is handled separately and always preserves whatever coturn shape
|
# is handled separately and always preserves whatever coturn shape
|
||||||
@@ -1897,8 +1921,19 @@ install_asterisk() {
|
|||||||
log_warning "need updating once this completes."
|
log_warning "need updating once this completes."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
ensure_coturn_user "asterisk"
|
# Opt-out of the shared coturn preference below, for the rare case where
|
||||||
if [[ -n "${COTURN_HOST:-}" ]]; then
|
# you specifically want Asterisk isolated on its own TURN relay again
|
||||||
|
# (e.g. reproducing an older install's exact shape to rule out anything
|
||||||
|
# coturn-sharing-specific during troubleshooting). Only offered when a
|
||||||
|
# shared instance actually exists — no meaningful choice otherwise.
|
||||||
|
if [[ -d "$DOCKER_DIR/coturn" ]]; then
|
||||||
|
local _USE_SHARED_COTURN=""
|
||||||
|
prompt_yn "Use the shared coturn service for TURN? (n = run Asterisk's own dedicated coturn instead) (y/n):" "y" _USE_SHARED_COTURN
|
||||||
|
[[ "$_USE_SHARED_COTURN" =~ ^[Nn]$ ]] && FORCE_EMBEDDED_COTURN=true
|
||||||
|
fi
|
||||||
|
|
||||||
|
[[ "$FORCE_EMBEDDED_COTURN" != true ]] && ensure_coturn_user "asterisk"
|
||||||
|
if [[ "$FORCE_EMBEDDED_COTURN" != true && -n "${COTURN_HOST:-}" ]]; then
|
||||||
USE_EMBEDDED_COTURN=false
|
USE_EMBEDDED_COTURN=false
|
||||||
TURN_USERNAME="$COTURN_USERNAME"
|
TURN_USERNAME="$COTURN_USERNAME"
|
||||||
TURN_PASSWORD="$COTURN_PASSWORD"
|
TURN_PASSWORD="$COTURN_PASSWORD"
|
||||||
@@ -1918,10 +1953,32 @@ install_asterisk() {
|
|||||||
elif [[ -n "$DOMAIN_NAME" ]]; then
|
elif [[ -n "$DOMAIN_NAME" ]]; then
|
||||||
TURN_SERVER_VAL="${DOMAIN_NAME}:3478"
|
TURN_SERVER_VAL="${DOMAIN_NAME}:3478"
|
||||||
fi
|
fi
|
||||||
|
if [[ "$FORCE_EMBEDDED_COTURN" == true ]]; then
|
||||||
|
log_info "Running Asterisk's own dedicated coturn, as requested."
|
||||||
|
else
|
||||||
log_info "Shared coturn unavailable — Asterisk will run its own dedicated coturn."
|
log_info "Shared coturn unavailable — Asterisk will run its own dedicated coturn."
|
||||||
fi
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
_asterisk_write_compose "$ASTERISK_PROJECT" "$CONTAINER" "$ASTERISK_COTURN" "$USE_EMBEDDED_COTURN"
|
# A dedicated embedded coturn running ALONGSIDE any other coturn on the
|
||||||
|
# same box (the shared instance, Asterisk's own on a prior install,
|
||||||
|
# any Mattermost instance's own) is exactly the pre-merge collision bug
|
||||||
|
# this repo's coturn history warns about if two of them claim overlapping
|
||||||
|
# relay ports — confirmed live, two independent coturns' default ranges
|
||||||
|
# used to overlap by ~100 UDP ports. find_free_coturn_range (lib/common.sh)
|
||||||
|
# checks every coturn-owning service's .env on the box, not just the
|
||||||
|
# shared instance's, and picks a range starting safely past whatever's
|
||||||
|
# already claimed. No other coturn on the box at all leaves it at the
|
||||||
|
# historical 49152-49252 default — nothing to collide with yet.
|
||||||
|
local EMBEDDED_COTURN_MIN_PORT=49152 EMBEDDED_COTURN_MAX_PORT=49252
|
||||||
|
if [[ "$USE_EMBEDDED_COTURN" == true ]]; then
|
||||||
|
find_free_coturn_range EMBEDDED_COTURN_MIN_PORT EMBEDDED_COTURN_MAX_PORT 100 49152
|
||||||
|
[[ "$EMBEDDED_COTURN_MIN_PORT" != 49152 ]] && \
|
||||||
|
log_info "Dedicated coturn relay range shifted to ${EMBEDDED_COTURN_MIN_PORT}-${EMBEDDED_COTURN_MAX_PORT} to stay clear of another coturn already on this box."
|
||||||
|
fi
|
||||||
|
|
||||||
|
_asterisk_write_compose "$ASTERISK_PROJECT" "$CONTAINER" "$ASTERISK_COTURN" "$USE_EMBEDDED_COTURN" \
|
||||||
|
"$EMBEDDED_COTURN_MIN_PORT" "$EMBEDDED_COTURN_MAX_PORT"
|
||||||
|
|
||||||
# ── Pick a free port for the web admin ─────────────────────────────────────
|
# ── Pick a free port for the web admin ─────────────────────────────────────
|
||||||
# Hardcoding a single number gets fragile fast once several services share
|
# Hardcoding a single number gets fragile fast once several services share
|
||||||
@@ -1966,6 +2023,12 @@ TURN_PASSWORD=${TURN_PASSWORD}
|
|||||||
TURN_PORT=${TURN_PORT_VAL}
|
TURN_PORT=${TURN_PORT_VAL}
|
||||||
# Empty when there's no publicly resolvable address (LAN-only, no FQDN).
|
# Empty when there's no publicly resolvable address (LAN-only, no FQDN).
|
||||||
TURN_SERVER=${TURN_SERVER_VAL}
|
TURN_SERVER=${TURN_SERVER_VAL}
|
||||||
|
# This install's OWN coturn relay range -- only set when USE_EMBEDDED_COTURN
|
||||||
|
# is true above. Left blank when using the shared coturn service, so other
|
||||||
|
# services' find_free_coturn_range (lib/common.sh) scan correctly skips this
|
||||||
|
# file instead of treating a range this install doesn't actually own as claimed.
|
||||||
|
TURN_MIN_PORT=$( [[ "$USE_EMBEDDED_COTURN" == true ]] && echo "$EMBEDDED_COTURN_MIN_PORT" )
|
||||||
|
TURN_MAX_PORT=$( [[ "$USE_EMBEDDED_COTURN" == true ]] && echo "$EMBEDDED_COTURN_MAX_PORT" )
|
||||||
|
|
||||||
# ── RTP port range ────────────────────────────────────────────
|
# ── RTP port range ────────────────────────────────────────────
|
||||||
RTP_START=10000
|
RTP_START=10000
|
||||||
@@ -2032,7 +2095,7 @@ ENV
|
|||||||
if [[ "$USE_EMBEDDED_COTURN" == true ]]; then
|
if [[ "$USE_EMBEDDED_COTURN" == true ]]; then
|
||||||
ufw allow 3478/udp
|
ufw allow 3478/udp
|
||||||
ufw allow 3478/tcp
|
ufw allow 3478/tcp
|
||||||
ufw allow 49152:49252/udp
|
ufw allow "${EMBEDDED_COTURN_MIN_PORT}:${EMBEDDED_COTURN_MAX_PORT}/udp"
|
||||||
fi
|
fi
|
||||||
# Shared coturn opens its own ports once, at its own install time
|
# Shared coturn opens its own ports once, at its own install time
|
||||||
# (services/coturn.sh) — nothing to open here when using it.
|
# (services/coturn.sh) — nothing to open here when using it.
|
||||||
@@ -2042,9 +2105,11 @@ ENV
|
|||||||
|
|
||||||
# ── Network-edge firewall (in front of the box, not UFW) ──────────────────
|
# ── Network-edge firewall (in front of the box, not UFW) ──────────────────
|
||||||
if [[ "$IS_DO" == true ]]; then
|
if [[ "$IS_DO" == true ]]; then
|
||||||
_asterisk_configure_do_cloud_firewall "$DROPLET_ID" "$WEB_ADMIN_PORT_VAL" "$WEB_ADMIN_PUBLIC_ACCESS_NEEDED"
|
_asterisk_configure_do_cloud_firewall "$DROPLET_ID" "$WEB_ADMIN_PORT_VAL" "$WEB_ADMIN_PUBLIC_ACCESS_NEEDED" \
|
||||||
|
"$EMBEDDED_COTURN_MIN_PORT" "$EMBEDDED_COTURN_MAX_PORT"
|
||||||
elif [[ -n "$DOMAIN_NAME" ]]; then
|
elif [[ -n "$DOMAIN_NAME" ]]; then
|
||||||
_asterisk_remind_non_do_firewall "$WEB_ADMIN_PORT_VAL" "$WEB_ADMIN_PUBLIC_ACCESS_NEEDED" "$USE_EMBEDDED_COTURN"
|
_asterisk_remind_non_do_firewall "$WEB_ADMIN_PORT_VAL" "$WEB_ADMIN_PUBLIC_ACCESS_NEEDED" "$USE_EMBEDDED_COTURN" \
|
||||||
|
"$EMBEDDED_COTURN_MIN_PORT" "$EMBEDDED_COTURN_MAX_PORT"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# ── CrowdSec note ──────────────────────────────────────────────────────────
|
# ── CrowdSec note ──────────────────────────────────────────────────────────
|
||||||
@@ -2070,7 +2135,8 @@ ENV
|
|||||||
|
|
||||||
# ── README ────────────────────────────────────────────────────────────────
|
# ── README ────────────────────────────────────────────────────────────────
|
||||||
_asterisk_write_readme "$EA_DIR" "$CONTAINER" "$IS_DO" "$DOMAIN_NAME" "$PUBLIC_IP" "$WEB_ADMIN_PORT_VAL" \
|
_asterisk_write_readme "$EA_DIR" "$CONTAINER" "$IS_DO" "$DOMAIN_NAME" "$PUBLIC_IP" "$WEB_ADMIN_PORT_VAL" \
|
||||||
"$USE_EMBEDDED_COTURN" "$TURN_USERNAME" "$TURN_SERVER_VAL"
|
"$USE_EMBEDDED_COTURN" "$TURN_USERNAME" "$TURN_SERVER_VAL" \
|
||||||
|
"$EMBEDDED_COTURN_MIN_PORT" "$EMBEDDED_COTURN_MAX_PORT"
|
||||||
|
|
||||||
# ── Start ─────────────────────────────────────────────────────────────────
|
# ── Start ─────────────────────────────────────────────────────────────────
|
||||||
echo ""
|
echo ""
|
||||||
|
|||||||
+62
-3
@@ -59,6 +59,21 @@ if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
|||||||
eval "$_varname='$_port'"
|
eval "$_varname='$_port'"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
find_free_coturn_range() {
|
||||||
|
local _min_varname="$1" _max_varname="$2" _range_size="${3:-200}" _start="${4:-49152}"
|
||||||
|
local _highest_max=$((_start - 1)) _f _found
|
||||||
|
for _f in "$DOCKER_DIR"/*/.env; do
|
||||||
|
[ -f "$_f" ] || continue
|
||||||
|
_found="$(grep -E '^(COTURN|TURN)_MAX_PORT=' "$_f" 2>/dev/null | tail -1 | cut -d= -f2-)"
|
||||||
|
[[ "$_found" =~ ^[0-9]+$ ]] || continue
|
||||||
|
[ "$_found" -gt "$_highest_max" ] && _highest_max=$_found
|
||||||
|
done
|
||||||
|
local _min=$_start
|
||||||
|
[ "$_highest_max" -ge "$_start" ] && _min=$((_highest_max + 50))
|
||||||
|
eval "$_min_varname='$_min'"
|
||||||
|
eval "$_max_varname='$((_min + _range_size))'"
|
||||||
|
}
|
||||||
|
|
||||||
# Match common.sh's eval-based pattern so local vars in install_* are set correctly
|
# Match common.sh's eval-based pattern so local vars in install_* are set correctly
|
||||||
prompt_text() {
|
prompt_text() {
|
||||||
local _q="$1" _def="$2" _var="$3" _r
|
local _q="$1" _def="$2" _var="$3" _r
|
||||||
@@ -399,9 +414,23 @@ networks:
|
|||||||
# own and fighting over host relay ports.
|
# own and fighting over host relay ports.
|
||||||
local USE_EMBEDDED_COTURN=true
|
local USE_EMBEDDED_COTURN=true
|
||||||
local TURN_HOST_VAL="" TURN_PORT_VAL="" TURN_USERNAME_VAL="" TURN_PASSWORD_VAL=""
|
local TURN_HOST_VAL="" TURN_PORT_VAL="" TURN_USERNAME_VAL="" TURN_PASSWORD_VAL=""
|
||||||
|
local FORCE_EMBEDDED_COTURN=""
|
||||||
|
|
||||||
|
# Opt-out of the shared coturn preference, same as services/asterisk.sh —
|
||||||
|
# only offered on a genuinely fresh install (never re-asked on update,
|
||||||
|
# matching every other coturn-shape decision in this file) and only when
|
||||||
|
# a shared instance actually exists to opt out of.
|
||||||
|
if [ "$MODE" = "fresh" ] && [ -d "$DOCKER_DIR/coturn" ]; then
|
||||||
|
local _USE_SHARED_COTURN=""
|
||||||
|
prompt_yn "Use the shared coturn service for TURN? (n = run this instance's own dedicated coturn instead) (y/n):" "y" _USE_SHARED_COTURN
|
||||||
|
[[ "$_USE_SHARED_COTURN" =~ ^[Nn]$ ]] && FORCE_EMBEDDED_COTURN=true
|
||||||
|
fi
|
||||||
|
|
||||||
if [ "$MODE" = "update" ] && [ "$_HAD_EMBEDDED_COTURN" = true ]; then
|
if [ "$MODE" = "update" ] && [ "$_HAD_EMBEDDED_COTURN" = true ]; then
|
||||||
USE_EMBEDDED_COTURN=true # preserve exactly — never switch on update
|
USE_EMBEDDED_COTURN=true # preserve exactly — never switch on update
|
||||||
|
elif [ "$FORCE_EMBEDDED_COTURN" = true ]; then
|
||||||
|
USE_EMBEDDED_COTURN=true
|
||||||
|
log_info "Running this instance's own dedicated coturn, as requested."
|
||||||
else
|
else
|
||||||
ensure_coturn_user "$COTURN_CONSUMER"
|
ensure_coturn_user "$COTURN_CONSUMER"
|
||||||
if [ -n "${COTURN_HOST:-}" ]; then
|
if [ -n "${COTURN_HOST:-}" ]; then
|
||||||
@@ -415,6 +444,30 @@ networks:
|
|||||||
fi
|
fi
|
||||||
[ -n "$MM_SECRET" ] || MM_SECRET=$(generate_password 48)
|
[ -n "$MM_SECRET" ] || MM_SECRET=$(generate_password 48)
|
||||||
|
|
||||||
|
# A dedicated coturn here running alongside the shared instance, Asterisk's
|
||||||
|
# own, or a sibling Mattermost instance's own is the same pre-merge relay-
|
||||||
|
# port collision this repo's coturn history warns about (confirmed live:
|
||||||
|
# two independent coturns' default ranges used to overlap by ~100 UDP
|
||||||
|
# ports). find_free_coturn_range (lib/common.sh) checks every coturn-
|
||||||
|
# owning service's .env on the box and picks a range starting safely past
|
||||||
|
# whatever's already claimed; the historical 49153-49352 default only
|
||||||
|
# survives when nothing else on the box claims a range at all.
|
||||||
|
local MM_COTURN_MIN_PORT=49153 MM_COTURN_MAX_PORT=49352
|
||||||
|
if [ "$USE_EMBEDDED_COTURN" = true ] && [ "$MODE" != "update" ]; then
|
||||||
|
find_free_coturn_range MM_COTURN_MIN_PORT MM_COTURN_MAX_PORT 200 49153
|
||||||
|
[[ "$MM_COTURN_MIN_PORT" != 49153 ]] && \
|
||||||
|
log_info "Dedicated coturn relay range shifted to ${MM_COTURN_MIN_PORT}-${MM_COTURN_MAX_PORT} to stay clear of another coturn already on this box."
|
||||||
|
elif [ "$MODE" = "update" ] && [ -f "$DIR/.env" ]; then
|
||||||
|
# Preserve whatever range this instance was already using — an update
|
||||||
|
# must never silently move it (a live coturn container restarting on
|
||||||
|
# a different port range would break in-flight/repeat Calls sessions).
|
||||||
|
local _existing_min _existing_max
|
||||||
|
_existing_min="$(grep -E '^TURN_MIN_PORT=' "$DIR/.env" 2>/dev/null | cut -d= -f2-)"
|
||||||
|
_existing_max="$(grep -E '^TURN_MAX_PORT=' "$DIR/.env" 2>/dev/null | cut -d= -f2-)"
|
||||||
|
[[ "$_existing_min" =~ ^[0-9]+$ ]] && MM_COTURN_MIN_PORT="$_existing_min"
|
||||||
|
[[ "$_existing_max" =~ ^[0-9]+$ ]] && MM_COTURN_MAX_PORT="$_existing_max"
|
||||||
|
fi
|
||||||
|
|
||||||
local _COTURN_SERVICE=""
|
local _COTURN_SERVICE=""
|
||||||
if [ "$USE_EMBEDDED_COTURN" = true ]; then
|
if [ "$USE_EMBEDDED_COTURN" = true ]; then
|
||||||
_COTURN_SERVICE="
|
_COTURN_SERVICE="
|
||||||
@@ -431,8 +484,8 @@ networks:
|
|||||||
- --use-auth-secret
|
- --use-auth-secret
|
||||||
- --static-auth-secret=\${COTURN_SECRET}
|
- --static-auth-secret=\${COTURN_SECRET}
|
||||||
- --realm=\${MM_REALM:-localhost}
|
- --realm=\${MM_REALM:-localhost}
|
||||||
- --min-port=49153
|
- --min-port=${MM_COTURN_MIN_PORT}
|
||||||
- --max-port=49352
|
- --max-port=${MM_COTURN_MAX_PORT}
|
||||||
- --no-tls
|
- --no-tls
|
||||||
- --no-dtls
|
- --no-dtls
|
||||||
- --no-cli
|
- --no-cli
|
||||||
@@ -509,6 +562,12 @@ TURN_HOST=$TURN_HOST_VAL
|
|||||||
TURN_PORT=$TURN_PORT_VAL
|
TURN_PORT=$TURN_PORT_VAL
|
||||||
TURN_USERNAME=$TURN_USERNAME_VAL
|
TURN_USERNAME=$TURN_USERNAME_VAL
|
||||||
TURN_PASSWORD=$TURN_PASSWORD_VAL
|
TURN_PASSWORD=$TURN_PASSWORD_VAL
|
||||||
|
# This instance's OWN coturn relay range -- only set when it runs a dedicated
|
||||||
|
# coturn above. Left blank when using the shared coturn service, so other
|
||||||
|
# services' find_free_coturn_range (lib/common.sh) scan correctly skips this
|
||||||
|
# file instead of treating a range this instance doesn't actually own as claimed.
|
||||||
|
TURN_MIN_PORT=$( [ "$USE_EMBEDDED_COTURN" = true ] && echo "$MM_COTURN_MIN_PORT" )
|
||||||
|
TURN_MAX_PORT=$( [ "$USE_EMBEDDED_COTURN" = true ] && echo "$MM_COTURN_MAX_PORT" )
|
||||||
EOF
|
EOF
|
||||||
chmod 600 .env
|
chmod 600 .env
|
||||||
|
|
||||||
@@ -532,7 +591,7 @@ EOF
|
|||||||
ufw allow "${CALLS_UDP_PORT}/udp" comment "Mattermost Calls RTC${INSTANCE_SUFFIX:+ ($INSTANCE_SUFFIX)}"
|
ufw allow "${CALLS_UDP_PORT}/udp" comment "Mattermost Calls RTC${INSTANCE_SUFFIX:+ ($INSTANCE_SUFFIX)}"
|
||||||
if [ "$USE_EMBEDDED_COTURN" = true ]; then
|
if [ "$USE_EMBEDDED_COTURN" = true ]; then
|
||||||
ufw allow 3479/udp; ufw allow 3479/tcp
|
ufw allow 3479/udp; ufw allow 3479/tcp
|
||||||
ufw allow 49153:49352/udp comment "Mattermost coturn relay"
|
ufw allow "${MM_COTURN_MIN_PORT}:${MM_COTURN_MAX_PORT}/udp" comment "Mattermost coturn relay"
|
||||||
fi
|
fi
|
||||||
# Shared coturn opens its own ports once, at its own install time.
|
# Shared coturn opens its own ports once, at its own install time.
|
||||||
fi
|
fi
|
||||||
|
|||||||
Reference in New Issue
Block a user