feat(turn): Add setup-nextcloud command for Nextcloud Talk

- turnctl setup-nextcloud [turn-domain] [use-port-443]
  - Configures TURN for Nextcloud Talk compatibility
  - Uses port 443 by default (firewall-friendly)
  - Generates auth secret if not exists
  - Outputs admin settings to paste into Nextcloud Talk

- LuCI integration:
  - New "Nextcloud Talk" section in TURN overview
  - Shows STUN/TURN/secret settings for easy copy-paste
  - RPC method: setup_nextcloud

- ACL updated with setup_nextcloud permission

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
CyberMind-FR 2026-02-21 18:11:42 +01:00
parent 2ccc3ace25
commit df58e96a9a
5 changed files with 143 additions and 3 deletions

View File

@ -388,7 +388,8 @@
"Bash(__NEW_LINE_755a36c329effceb__ echo \"\")",
"Bash(__NEW_LINE_02bd2dd51e90cbf8__ echo \"\")",
"Bash(__NEW_LINE_70eb6f3ae1c26753__ echo \"\")",
"WebFetch(domain:radio.gk2.secubox.in)"
"WebFetch(domain:radio.gk2.secubox.in)",
"WebFetch(domain:nextcloud-talk.readthedocs.io)"
]
}
}

View File

@ -10,6 +10,7 @@ var callStop = rpc.declare({ object: 'luci.turn', method: 'stop', expect: {} });
var callEnable = rpc.declare({ object: 'luci.turn', method: 'enable', expect: {} });
var callDisable = rpc.declare({ object: 'luci.turn', method: 'disable', expect: {} });
var callSetupJitsi = rpc.declare({ object: 'luci.turn', method: 'setup_jitsi', params: ['jitsi_domain', 'turn_domain'], expect: {} });
var callSetupNextcloud = rpc.declare({ object: 'luci.turn', method: 'setup_nextcloud', params: ['turn_domain', 'use_port_443'], expect: {} });
var callSSL = rpc.declare({ object: 'luci.turn', method: 'ssl', params: ['domain'], expect: {} });
var callExpose = rpc.declare({ object: 'luci.turn', method: 'expose', params: ['domain'], expect: {} });
var callCredentials = rpc.declare({ object: 'luci.turn', method: 'credentials', params: ['username', 'ttl'], expect: {} });
@ -76,6 +77,16 @@ return view.extend({
])
]),
E('div', { 'class': 'sb-section' }, [
E('h3', {}, 'Nextcloud Talk'),
E('p', {}, 'Configure TURN for Nextcloud Talk (uses port 443 for firewall compatibility)'),
E('div', { 'class': 'form-row' }, [
E('input', { 'type': 'text', 'id': 'nc-turn-domain', 'placeholder': 'turn.secubox.in', 'class': 'sb-input' }),
E('button', { 'class': 'sb-btn sb-btn-primary', 'click': ui.createHandlerFn(this, 'handleSetupNextcloud') }, 'Setup for Nextcloud')
]),
E('pre', { 'id': 'nextcloud-output', 'class': 'sb-output', 'style': 'display:none;' }, '')
]),
E('div', { 'class': 'sb-section' }, [
E('h3', {}, 'SSL & Expose'),
E('div', { 'class': 'form-row' }, [
@ -153,6 +164,22 @@ return view.extend({
});
},
handleSetupNextcloud: function() {
var turnDomain = document.getElementById('nc-turn-domain').value || 'turn.secubox.in';
return callSetupNextcloud(turnDomain, 'yes').then(function(res) {
var output = document.getElementById('nextcloud-output');
output.style.display = 'block';
output.textContent = 'Nextcloud Talk Admin Settings:\n\n' +
'STUN servers: ' + turnDomain + ':' + (res.stun_port || 3478) + '\n' +
'TURN server: ' + turnDomain + ':' + (res.tls_port || 443) + '\n' +
'TURN secret: ' + (res.auth_secret || '') + '\n' +
'Protocol: UDP and TCP\n\n' +
'Note: Do NOT add turn:// or turns:// prefix';
ui.addNotification(null, E('p', 'TURN configured for Nextcloud Talk on port ' + (res.tls_port || 443)));
});
},
handleSSL: function() {
var domain = document.getElementById('ssl-domain').value || 'turn.secubox.in';
return callSSL(domain).then(function(res) {

View File

@ -7,7 +7,7 @@ uci_get() { uci -q get "turn.$1" 2>/dev/null || echo "$2"; }
case "$1" in
list)
echo '{"status":{},"logs":{"lines":50},"test":{"host":""},"start":{},"stop":{},"restart":{},"enable":{},"disable":{},"setup_jitsi":{"jitsi_domain":"","turn_domain":""},"ssl":{"domain":""},"expose":{"domain":""},"credentials":{"username":"","ttl":86400}}'
echo '{"status":{},"logs":{"lines":50},"test":{"host":""},"start":{},"stop":{},"restart":{},"enable":{},"disable":{},"setup_jitsi":{"jitsi_domain":"","turn_domain":""},"setup_nextcloud":{"turn_domain":"","use_port_443":"yes"},"ssl":{"domain":""},"expose":{"domain":""},"credentials":{"username":"","ttl":86400}}'
;;
call)
case "$2" in
@ -159,6 +159,27 @@ case "$1" in
json_dump
;;
setup_nextcloud)
read -r input
json_load "$input"
json_get_var turn_domain turn_domain "turn.secubox.in"
json_get_var use_port_443 use_port_443 "yes"
output=$(turnctl setup-nextcloud "$turn_domain" "$use_port_443" 2>&1)
local auth_secret=$(uci_get main.static_auth_secret "")
local tls_port=$(uci_get main.tls_port "443")
local stun_port=$(uci_get main.listening_port "3478")
json_init
json_add_string result "ok"
json_add_string turn_domain "$turn_domain"
json_add_string auth_secret "$auth_secret"
json_add_int stun_port "$stun_port"
json_add_int tls_port "$tls_port"
json_add_string output "$output"
json_dump
;;
ssl)
read -r input
json_load "$input"

View File

@ -9,7 +9,7 @@
},
"write": {
"ubus": {
"luci.turn": ["start", "stop", "restart", "enable", "disable", "setup_jitsi", "ssl", "expose", "credentials"]
"luci.turn": ["start", "stop", "restart", "enable", "disable", "setup_jitsi", "setup_nextcloud", "ssl", "expose", "credentials"]
},
"uci": ["turn"]
}

View File

@ -118,6 +118,93 @@ cmd_setup_jitsi() {
echo ""
}
#--- Setup TURN for Nextcloud Talk ---
cmd_setup_nextcloud() {
local turn_domain="${1:-turn.secubox.in}"
local use_port_443="${2:-yes}"
log "Setting up TURN for Nextcloud Talk..."
# Enable TURN
uci set turn.main.enabled='1'
uci set turn.main.realm="$turn_domain"
# Nextcloud recommends port 443 for maximum firewall compatibility
if [ "$use_port_443" = "yes" ] || [ "$use_port_443" = "443" ]; then
uci set turn.main.tls_port='443'
log "Using port 443 for TURN TLS (recommended for Nextcloud)"
fi
# Auto-detect external IP
local external_ip=$(curl -s -4 https://ifconfig.me 2>/dev/null)
if [ -n "$external_ip" ]; then
uci set turn.main.external_ip="$external_ip"
log "Detected external IP: $external_ip"
fi
# Generate auth secret if not exists
local auth_secret=$(uci_get main.static_auth_secret "")
if [ -z "$auth_secret" ]; then
auth_secret=$(head -c 32 /dev/urandom | base64 | tr -d '/+=' | head -c 32)
uci set turn.main.static_auth_secret="$auth_secret"
log "Generated new auth secret"
fi
uci commit turn
# Setup SSL if using port 443
if [ "$use_port_443" = "yes" ] || [ "$use_port_443" = "443" ]; then
cmd_ssl "$turn_domain"
fi
# Start TURN server
/etc/init.d/turn restart
sleep 2
# Get configured ports
local stun_port=$(uci_get main.listening_port "3478")
local tls_port=$(uci_get main.tls_port "443")
log "TURN server configured for Nextcloud Talk!"
echo ""
echo -e "${CYAN}=== Nextcloud Talk Admin Settings ===${NC}"
echo ""
echo "Go to: Settings → Administration → Talk"
echo ""
echo -e "${YELLOW}STUN servers:${NC}"
echo " ${turn_domain}:${stun_port}"
echo ""
echo -e "${YELLOW}TURN server:${NC}"
echo " ${turn_domain}:${tls_port}"
echo ""
echo -e "${YELLOW}TURN secret:${NC}"
echo " ${auth_secret}"
echo ""
echo -e "${YELLOW}Protocol:${NC}"
echo " UDP and TCP"
echo ""
echo -e "${CYAN}=== Important Notes ===${NC}"
echo ""
echo "1. Do NOT add 'turn://' or 'turns://' prefix - just domain:port"
echo "2. Port 443 is recommended for firewall traversal"
echo "3. Both UDP and TCP should be enabled for maximum compatibility"
echo ""
echo -e "${CYAN}=== ICE Server Config (for testing) ===${NC}"
echo ""
echo "{"
echo " \"iceServers\": ["
echo " { \"urls\": \"stun:${turn_domain}:${stun_port}\" },"
echo " {"
echo " \"urls\": [\"turn:${turn_domain}:${tls_port}?transport=tcp\", \"turns:${turn_domain}:${tls_port}?transport=tcp\"],"
echo " \"username\": \"<time-limited-username>\","
echo " \"credential\": \"<hmac-credential>\""
echo " }"
echo " ]"
echo "}"
echo ""
echo -e "${GREEN}Use 'turnctl credentials [user] [ttl]' to generate time-limited credentials${NC}"
}
#--- Generate Credentials ---
cmd_credentials() {
local username="${1:-$(date +%s)}"
@ -343,6 +430,8 @@ ${GREEN}Service Commands:${NC}
${GREEN}Setup:${NC}
setup-jitsi [domain] [turn-domain]
Configure TURN for Jitsi Meet
setup-nextcloud [turn-domain] [port-443]
Configure TURN for Nextcloud Talk
ssl [domain] Setup SSL certificate
expose [domain] Configure DNS and firewall
@ -354,6 +443,7 @@ ${GREEN}Operations:${NC}
${GREEN}Examples:${NC}
turnctl setup-jitsi jitsi.secubox.in turn.secubox.in
turnctl setup-nextcloud turn.secubox.in
turnctl ssl turn.secubox.in
turnctl credentials webrtc-user 3600
turnctl expose turn.secubox.in
@ -375,6 +465,7 @@ case "$1" in
enable) cmd_enable ;;
disable) cmd_disable ;;
setup-jitsi) shift; cmd_setup_jitsi "$@" ;;
setup-nextcloud) shift; cmd_setup_nextcloud "$@" ;;
ssl) shift; cmd_ssl "$@" ;;
expose) shift; cmd_expose "$@" ;;
credentials) shift; cmd_credentials "$@" ;;