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:
parent
2ccc3ace25
commit
df58e96a9a
@ -388,7 +388,8 @@
|
|||||||
"Bash(__NEW_LINE_755a36c329effceb__ echo \"\")",
|
"Bash(__NEW_LINE_755a36c329effceb__ echo \"\")",
|
||||||
"Bash(__NEW_LINE_02bd2dd51e90cbf8__ echo \"\")",
|
"Bash(__NEW_LINE_02bd2dd51e90cbf8__ echo \"\")",
|
||||||
"Bash(__NEW_LINE_70eb6f3ae1c26753__ echo \"\")",
|
"Bash(__NEW_LINE_70eb6f3ae1c26753__ echo \"\")",
|
||||||
"WebFetch(domain:radio.gk2.secubox.in)"
|
"WebFetch(domain:radio.gk2.secubox.in)",
|
||||||
|
"WebFetch(domain:nextcloud-talk.readthedocs.io)"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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 callEnable = rpc.declare({ object: 'luci.turn', method: 'enable', expect: {} });
|
||||||
var callDisable = rpc.declare({ object: 'luci.turn', method: 'disable', 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 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 callSSL = rpc.declare({ object: 'luci.turn', method: 'ssl', params: ['domain'], expect: {} });
|
||||||
var callExpose = rpc.declare({ object: 'luci.turn', method: 'expose', 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: {} });
|
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('div', { 'class': 'sb-section' }, [
|
||||||
E('h3', {}, 'SSL & Expose'),
|
E('h3', {}, 'SSL & Expose'),
|
||||||
E('div', { 'class': 'form-row' }, [
|
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() {
|
handleSSL: function() {
|
||||||
var domain = document.getElementById('ssl-domain').value || 'turn.secubox.in';
|
var domain = document.getElementById('ssl-domain').value || 'turn.secubox.in';
|
||||||
return callSSL(domain).then(function(res) {
|
return callSSL(domain).then(function(res) {
|
||||||
|
|||||||
@ -7,7 +7,7 @@ uci_get() { uci -q get "turn.$1" 2>/dev/null || echo "$2"; }
|
|||||||
|
|
||||||
case "$1" in
|
case "$1" in
|
||||||
list)
|
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)
|
call)
|
||||||
case "$2" in
|
case "$2" in
|
||||||
@ -159,6 +159,27 @@ case "$1" in
|
|||||||
json_dump
|
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)
|
ssl)
|
||||||
read -r input
|
read -r input
|
||||||
json_load "$input"
|
json_load "$input"
|
||||||
|
|||||||
@ -9,7 +9,7 @@
|
|||||||
},
|
},
|
||||||
"write": {
|
"write": {
|
||||||
"ubus": {
|
"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"]
|
"uci": ["turn"]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -118,6 +118,93 @@ cmd_setup_jitsi() {
|
|||||||
echo ""
|
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 ---
|
#--- Generate Credentials ---
|
||||||
cmd_credentials() {
|
cmd_credentials() {
|
||||||
local username="${1:-$(date +%s)}"
|
local username="${1:-$(date +%s)}"
|
||||||
@ -343,6 +430,8 @@ ${GREEN}Service Commands:${NC}
|
|||||||
${GREEN}Setup:${NC}
|
${GREEN}Setup:${NC}
|
||||||
setup-jitsi [domain] [turn-domain]
|
setup-jitsi [domain] [turn-domain]
|
||||||
Configure TURN for Jitsi Meet
|
Configure TURN for Jitsi Meet
|
||||||
|
setup-nextcloud [turn-domain] [port-443]
|
||||||
|
Configure TURN for Nextcloud Talk
|
||||||
ssl [domain] Setup SSL certificate
|
ssl [domain] Setup SSL certificate
|
||||||
expose [domain] Configure DNS and firewall
|
expose [domain] Configure DNS and firewall
|
||||||
|
|
||||||
@ -354,6 +443,7 @@ ${GREEN}Operations:${NC}
|
|||||||
|
|
||||||
${GREEN}Examples:${NC}
|
${GREEN}Examples:${NC}
|
||||||
turnctl setup-jitsi jitsi.secubox.in turn.secubox.in
|
turnctl setup-jitsi jitsi.secubox.in turn.secubox.in
|
||||||
|
turnctl setup-nextcloud turn.secubox.in
|
||||||
turnctl ssl turn.secubox.in
|
turnctl ssl turn.secubox.in
|
||||||
turnctl credentials webrtc-user 3600
|
turnctl credentials webrtc-user 3600
|
||||||
turnctl expose turn.secubox.in
|
turnctl expose turn.secubox.in
|
||||||
@ -375,6 +465,7 @@ case "$1" in
|
|||||||
enable) cmd_enable ;;
|
enable) cmd_enable ;;
|
||||||
disable) cmd_disable ;;
|
disable) cmd_disable ;;
|
||||||
setup-jitsi) shift; cmd_setup_jitsi "$@" ;;
|
setup-jitsi) shift; cmd_setup_jitsi "$@" ;;
|
||||||
|
setup-nextcloud) shift; cmd_setup_nextcloud "$@" ;;
|
||||||
ssl) shift; cmd_ssl "$@" ;;
|
ssl) shift; cmd_ssl "$@" ;;
|
||||||
expose) shift; cmd_expose "$@" ;;
|
expose) shift; cmd_expose "$@" ;;
|
||||||
credentials) shift; cmd_credentials "$@" ;;
|
credentials) shift; cmd_credentials "$@" ;;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user