Browse Source

NET-814: Deprecating TURN (#2723)

* deprecate turn

* process signals through mq
Abhishek K 1 year ago
parent
commit
98c01c4325

+ 1 - 21
compose/docker-compose.yml

@@ -25,10 +25,6 @@ services:
       - COREDNS_ADDR=${SERVER_HOST}
       # Overrides SERVER_HOST if set. Useful for making HTTP available via different interfaces/networks.
       - SERVER_HTTP_HOST=api.${NM_DOMAIN}
-      # domain for your turn server
-      - TURN_SERVER_HOST=turn.${NM_DOMAIN}
-      # domain of the turn api server
-      - TURN_SERVER_API_HOST=https://turnapi.${NM_DOMAIN}
 
   netmaker-ui:
     container_name: netmaker-ui
@@ -82,22 +78,6 @@ services:
       - ./wait.sh:/mosquitto/config/wait.sh
       - mosquitto_logs:/mosquitto/log
       - mosquitto_data:/mosquitto/data
-
-  turn:
-    container_name: turn
-    image: gravitl/turnserver:v1.0.0
-    env_file: ./netmaker.env
-    environment:
-      # config-dependant vars
-      - USERNAME=${TURN_USERNAME}
-      - PASSWORD=${TURN_PASSWORD}
-      # domain for your turn server
-      - TURN_SERVER_HOST=turn.${NM_DOMAIN}
-    network_mode: "host"
-    volumes:
-      - turn_server:/etc/config
-    restart: always
-
 volumes:
   caddy_data: { } # runtime data for caddy
   caddy_conf: { } # configuration file for Caddy
@@ -105,4 +85,4 @@ volumes:
   dnsconfig: { } # storage for coredns
   mosquitto_logs: { } # storage for mqtt logs
   mosquitto_data: { } # storage for mqtt data
-  turn_server: { }
+

+ 0 - 7
controllers/enrollmentkeys.go

@@ -231,13 +231,6 @@ func handleHostRegister(w http.ResponseWriter, r *http.Request) {
 		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
 		return
 	}
-	// re-register host with turn just in case.
-	if servercfg.IsUsingTurn() {
-		err = logic.RegisterHostWithTurn(newHost.ID.String(), newHost.HostPass)
-		if err != nil {
-			logger.Log(0, "failed to register host with turn server: ", err.Error())
-		}
-	}
 	// check if host already exists
 	hostExists := false
 	if hostExists = logic.HostExists(&newHost); hostExists && len(enrollmentKey.Networks) == 0 {

+ 2 - 7
controllers/hosts.go

@@ -544,19 +544,14 @@ func signalPeer(w http.ResponseWriter, r *http.Request) {
 		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
 		return
 	}
-	if signal.ToHostPubKey == "" || (!servercfg.IsPro && signal.TurnRelayEndpoint == "") {
+	if signal.ToHostPubKey == "" {
 		msg := "insufficient data to signal peer"
 		logger.Log(0, r.Header.Get("user"), msg)
 		logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New(msg), "badrequest"))
 		return
 	}
 	signal.IsPro = servercfg.IsPro
-	var peerHost *models.Host
-	if signal.ToHostID == "" {
-		peerHost, err = logic.GetHostByPubKey(signal.ToHostPubKey)
-	} else {
-		peerHost, err = logic.GetHost(signal.ToHostID)
-	}
+	peerHost, err := logic.GetHost(signal.ToHostID)
 	if err != nil {
 		logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("failed to signal, peer not found"), "badrequest"))
 		return

+ 0 - 10
docker/Caddyfile

@@ -24,16 +24,6 @@ https://api.{$NM_DOMAIN} {
 	reverse_proxy http://netmaker:8081
 }
 
-# TURN
-https://turn.{$NM_DOMAIN} {
-	reverse_proxy host.docker.internal:3479
-}
-
-# TURN API
-https://turnapi.{$NM_DOMAIN} {
-	reverse_proxy http://host.docker.internal:8089
-}
-
 # MQ
 wss://broker.{$NM_DOMAIN} {
 	reverse_proxy ws://mq:8883 # For EMQX websockets use `reverse_proxy ws://mq:8083`

+ 0 - 10
docker/Caddyfile-pro

@@ -39,16 +39,6 @@ https://api.{$NM_DOMAIN} {
 	reverse_proxy http://netmaker:8081
 }
 
-# TURN
-https://turn.{$NM_DOMAIN} {
-	reverse_proxy host.docker.internal:3479
-}
-
-# TURN API
-https://turnapi.{$NM_DOMAIN} {
-	reverse_proxy http://host.docker.internal:8089
-}
-
 # MQ
 wss://broker.{$NM_DOMAIN} {
 	reverse_proxy ws://mq:8883

+ 0 - 63
logic/hosts.go

@@ -2,16 +2,12 @@ package logic
 
 import (
 	"crypto/md5"
-	"encoding/base64"
 	"encoding/json"
 	"errors"
 	"fmt"
-	"net/http"
 	"sort"
-	"strconv"
 	"sync"
 
-	"github.com/devilcove/httpclient"
 	"github.com/google/uuid"
 	"golang.org/x/crypto/bcrypt"
 
@@ -197,12 +193,6 @@ func CreateHost(h *models.Host) error {
 	if (err != nil && !database.IsEmptyRecord(err)) || (err == nil) {
 		return ErrHostExists
 	}
-	if servercfg.IsUsingTurn() {
-		err = RegisterHostWithTurn(h.ID.String(), h.HostPass)
-		if err != nil {
-			logger.Log(0, "failed to register host with turn server: ", err.Error())
-		}
-	}
 
 	// encrypt that password so we never see it
 	hash, err := bcrypt.GenerateFromPassword([]byte(h.HostPass), 5)
@@ -306,10 +296,6 @@ func RemoveHost(h *models.Host, forceDelete bool) error {
 		return fmt.Errorf("host still has associated nodes")
 	}
 
-	if servercfg.IsUsingTurn() {
-		DeRegisterHostWithTurn(h.ID.String())
-	}
-
 	if len(h.Nodes) > 0 {
 		if err := DisassociateAllNodesFromHost(h.ID.String()); err != nil {
 			return err
@@ -329,9 +315,6 @@ func RemoveHost(h *models.Host, forceDelete bool) error {
 
 // RemoveHostByID - removes a given host by id from server
 func RemoveHostByID(hostID string) error {
-	if servercfg.IsUsingTurn() {
-		DeRegisterHostWithTurn(hostID)
-	}
 
 	err := database.DeleteRecord(database.HOSTS_TABLE_NAME, hostID)
 	if err != nil {
@@ -568,52 +551,6 @@ func ConvHostPassToHash(hostPass string) string {
 	return fmt.Sprintf("%x", md5.Sum([]byte(hostPass)))
 }
 
-// RegisterHostWithTurn - registers the host with the given turn server
-func RegisterHostWithTurn(hostID, hostPass string) error {
-	auth := servercfg.GetTurnUserName() + ":" + servercfg.GetTurnPassword()
-	api := httpclient.JSONEndpoint[models.SuccessResponse, models.ErrorResponse]{
-		URL:           servercfg.GetTurnApiHost(),
-		Route:         "/api/v1/host/register",
-		Method:        http.MethodPost,
-		Authorization: fmt.Sprintf("Basic %s", base64.StdEncoding.EncodeToString([]byte(auth))),
-		Data: models.HostTurnRegister{
-			HostID:       hostID,
-			HostPassHash: ConvHostPassToHash(hostPass),
-		},
-		Response:      models.SuccessResponse{},
-		ErrorResponse: models.ErrorResponse{},
-	}
-	_, errData, err := api.GetJSON(models.SuccessResponse{}, models.ErrorResponse{})
-	if err != nil {
-		if errors.Is(err, httpclient.ErrStatus) {
-			logger.Log(1, "error server status", strconv.Itoa(errData.Code), errData.Message)
-		}
-		return err
-	}
-	return nil
-}
-
-// DeRegisterHostWithTurn - to be called when host need to be deregistered from a turn server
-func DeRegisterHostWithTurn(hostID string) error {
-	auth := servercfg.GetTurnUserName() + ":" + servercfg.GetTurnPassword()
-	api := httpclient.JSONEndpoint[models.SuccessResponse, models.ErrorResponse]{
-		URL:           servercfg.GetTurnApiHost(),
-		Route:         fmt.Sprintf("/api/v1/host/deregister?host_id=%s", hostID),
-		Method:        http.MethodPost,
-		Authorization: fmt.Sprintf("Basic %s", base64.StdEncoding.EncodeToString([]byte(auth))),
-		Response:      models.SuccessResponse{},
-		ErrorResponse: models.ErrorResponse{},
-	}
-	_, errData, err := api.GetJSON(models.SuccessResponse{}, models.ErrorResponse{})
-	if err != nil {
-		if errors.Is(err, httpclient.ErrStatus) {
-			logger.Log(1, "error server status", strconv.Itoa(errData.Code), errData.Message)
-		}
-		return err
-	}
-	return nil
-}
-
 // SortApiHosts - Sorts slice of ApiHosts by their ID alphabetically with numbers first
 func SortApiHosts(unsortedHosts []models.ApiHost) {
 	sort.Slice(unsortedHosts, func(i, j int) bool {

+ 11 - 16
models/host.go

@@ -110,8 +110,6 @@ const (
 	RequestAck HostMqAction = "REQ_ACK"
 	// CheckIn - update last check in times and public address and interfaces
 	CheckIn HostMqAction = "CHECK_IN"
-	// RegisterWithTurn - registers host with turn server if configured
-	RegisterWithTurn HostMqAction = "REGISTER_WITH_TURN"
 	// UpdateKeys - update wireguard private/public keys
 	UpdateKeys HostMqAction = "UPDATE_KEYS"
 	// RequestPull - request a pull from a host
@@ -122,8 +120,6 @@ const (
 type SignalAction string
 
 const (
-	// Disconnect - action to stop using turn connection
-	Disconnect SignalAction = "DISCONNECT"
 	// ConnNegotiation - action to negotiate connection between peers
 	ConnNegotiation SignalAction = "CONNECTION_NEGOTIATION"
 	// RelayME - action to relay the peer
@@ -146,18 +142,17 @@ type HostTurnRegister struct {
 
 // Signal - struct for signalling peer
 type Signal struct {
-	Server            string       `json:"server"`
-	FromHostPubKey    string       `json:"from_host_pubkey"`
-	TurnRelayEndpoint string       `json:"turn_relay_addr"`
-	ToHostPubKey      string       `json:"to_host_pubkey"`
-	FromHostID        string       `json:"from_host_id"`
-	ToHostID          string       `json:"to_host_id"`
-	FromNodeID        string       `json:"from_node_id"`
-	ToNodeID          string       `json:"to_node_id"`
-	Reply             bool         `json:"reply"`
-	Action            SignalAction `json:"action"`
-	IsPro             bool         `json:"is_pro"`
-	TimeStamp         int64        `json:"timestamp"`
+	Server         string       `json:"server"`
+	FromHostPubKey string       `json:"from_host_pubkey"`
+	ToHostPubKey   string       `json:"to_host_pubkey"`
+	FromHostID     string       `json:"from_host_id"`
+	ToHostID       string       `json:"to_host_id"`
+	FromNodeID     string       `json:"from_node_id"`
+	ToNodeID       string       `json:"to_node_id"`
+	Reply          bool         `json:"reply"`
+	Action         SignalAction `json:"action"`
+	IsPro          bool         `json:"is_pro"`
+	TimeStamp      int64        `json:"timestamp"`
 }
 
 // RegisterMsg - login message struct for hosts to join via SSO login

+ 0 - 4
models/structs.go

@@ -264,11 +264,7 @@ type ServerConfig struct {
 	Server      string `yaml:"server"`
 	Broker      string `yaml:"broker"`
 	IsPro       bool   `yaml:"isee" json:"Is_EE"`
-	StunPort    int    `yaml:"stun_port"`
 	TrafficKey  []byte `yaml:"traffickey"`
-	TurnDomain  string `yaml:"turn_domain"`
-	TurnPort    int    `yaml:"turn_port"`
-	UseTurn     bool   `yaml:"use_turn"`
 }
 
 // User.NameInCharset - returns if name is in charset below or not

+ 26 - 8
mq/handlers.go

@@ -7,6 +7,7 @@ import (
 	mqtt "github.com/eclipse/paho.mqtt.golang"
 	"github.com/google/uuid"
 	"github.com/gravitl/netmaker/database"
+	"github.com/gravitl/netmaker/logger"
 	"github.com/gravitl/netmaker/logic"
 	"github.com/gravitl/netmaker/logic/hostactions"
 	"github.com/gravitl/netmaker/models"
@@ -193,14 +194,8 @@ func UpdateHost(client mqtt.Client, msg mqtt.Message) {
 			return
 		}
 		sendPeerUpdate = true
-	case models.RegisterWithTurn:
-		if servercfg.IsUsingTurn() {
-			err = logic.RegisterHostWithTurn(hostUpdate.Host.ID.String(), hostUpdate.Host.HostPass)
-			if err != nil {
-				slog.Error("failed to register host with turn server", "id", currentHost.ID, "error", err)
-				return
-			}
-		}
+	case models.SignalHost:
+		signalPeer(hostUpdate.Signal)
 
 	}
 
@@ -212,6 +207,29 @@ func UpdateHost(client mqtt.Client, msg mqtt.Message) {
 	}
 }
 
+func signalPeer(signal models.Signal) {
+
+	if signal.ToHostPubKey == "" {
+		msg := "insufficient data to signal peer"
+		logger.Log(0, msg)
+		return
+	}
+	signal.IsPro = servercfg.IsPro
+	peerHost, err := logic.GetHost(signal.ToHostID)
+	if err != nil {
+		slog.Error("failed to signal, peer not found", "error", err)
+		return
+	}
+	err = HostUpdate(&models.HostUpdate{
+		Action: models.SignalHost,
+		Host:   *peerHost,
+		Signal: signal,
+	})
+	if err != nil {
+		slog.Error("failed to publish signal to peer", "error", err)
+	}
+}
+
 // ClientPeerUpdate  message handler -- handles updating peers after signal from client nodes
 func ClientPeerUpdate(client mqtt.Client, msg mqtt.Message) {
 	id, err := GetID(msg.Topic())

+ 0 - 12
scripts/netmaker.default.env

@@ -6,10 +6,6 @@ NM_DOMAIN=
 SERVER_HOST=
 # The admin master key for accessing the API. Change this in any production installation.
 MASTER_KEY=
-# The username to set for turn api access
-TURN_USERNAME=
-# The password to set for turn api access
-TURN_PASSWORD=
 # The username to set for MQ access
 MQ_USERNAME=
 # The password to set for MQ access
@@ -42,18 +38,10 @@ DATABASE=sqlite
 # If using "host networking", it will find and detect the IP of the mq container.
 # For EMQX websockets use `SERVER_BROKER_ENDPOINT=ws://mq:8083/mqtt`
 SERVER_BROKER_ENDPOINT=ws://mq:1883 
-# The reachable port of STUN on the server
-STUN_PORT=3478
 # Logging verbosity level - 1, 2, or 3
 VERBOSITY=1
-# Port to access turn server
-TURN_PORT=3479
-# Config for using turn, accepts either true/false
-USE_TURN=true
 DEBUG_MODE=off
-TURN_API_PORT=8089
 # Enables the REST backend (API running on API_PORT at SERVER_HTTP_HOST).
-# Change to "off" to turn off.
 REST_BACKEND=on
 # If turned "on", Server will not set Host based on remote IP check.
 # This is already overridden if SERVER_HOST is set. Turned "off" by default.

+ 3 - 55
scripts/nm-quick.sh

@@ -305,11 +305,10 @@ save_config() { (
 		save_config_item SERVER_IMAGE_TAG "$IMAGE_TAG"
 	fi
 	# copy entries from the previous config
-	local toCopy=("SERVER_HOST" "MASTER_KEY" "TURN_USERNAME" "TURN_PASSWORD" "MQ_USERNAME" "MQ_PASSWORD"
+	local toCopy=("SERVER_HOST" "MASTER_KEY" "MQ_USERNAME" "MQ_PASSWORD"
 		"INSTALL_TYPE" "NODE_ID" "DNS_MODE" "NETCLIENT_AUTO_UPDATE" "API_PORT"
-		"CORS_ALLOWED_ORIGIN" "DISPLAY_KEYS" "DATABASE" "SERVER_BROKER_ENDPOINT" "STUN_PORT" "VERBOSITY"
-		"TURN_PORT" "USE_TURN" "DEBUG_MODE" "TURN_API_PORT" "REST_BACKEND"
-		"DISABLE_REMOTE_IP_CHECK" "TELEMETRY" "AUTH_PROVIDER" "CLIENT_ID" "CLIENT_SECRET"
+		"CORS_ALLOWED_ORIGIN" "DISPLAY_KEYS" "DATABASE" "SERVER_BROKER_ENDPOINT" "VERBOSITY"
+		"DEBUG_MODE"  "REST_BACKEND" "DISABLE_REMOTE_IP_CHECK" "TELEMETRY" "AUTH_PROVIDER" "CLIENT_ID" "CLIENT_SECRET"
 		"FRONTEND_URL" "AZURE_TENANT" "OIDC_ISSUER" "EXPORTER_API_PORT" "JWT_VALIDITY_DURATION" "RAC_AUTO_DISABLE")
 	for name in "${toCopy[@]}"; do
 		save_config_item $name "${!name}"
@@ -550,8 +549,6 @@ set_install_vars() {
 	echo "          dashboard.$NETMAKER_BASE_DOMAIN"
 	echo "                api.$NETMAKER_BASE_DOMAIN"
 	echo "             broker.$NETMAKER_BASE_DOMAIN"
-	echo "               turn.$NETMAKER_BASE_DOMAIN"
-	echo "            turnapi.$NETMAKER_BASE_DOMAIN"
 
 	if [ "$INSTALL_TYPE" = "pro" ]; then
 		echo "         prometheus.$NETMAKER_BASE_DOMAIN"
@@ -657,55 +654,6 @@ set_install_vars() {
 		done
 	fi
 
-	unset GET_TURN_USERNAME
-	unset GET_TURN_PASSWORD
-	unset CONFIRM_TURN_PASSWORD
-	echo "Enter Credentials For TURN..."
-	if [ -z $AUTO_BUILD ]; then
-		read -p "TURN Username (click 'enter' to use 'netmaker'): " GET_TURN_USERNAME
-	fi
-	if [ -z "$GET_TURN_USERNAME" ]; then
-		echo "using default username for TURN"
-		TURN_USERNAME="netmaker"
-	else
-		TURN_USERNAME="$GET_TURN_USERNAME"
-	fi
-
-	if test -z "$TURN_PASSWORD"; then
-		TURN_PASSWORD=$(
-			tr -dc A-Za-z0-9 </dev/urandom | head -c 30
-			echo ''
-		)
-	fi
-
-	if [ -z $AUTO_BUILD ]; then
-		select domain_option in "Auto Generated / Config Password" "Input Your Own Password"; do
-			case $REPLY in
-			1)
-				echo "using random password for turn"
-				break
-				;;
-			2)
-				while true; do
-					echo "Enter your Password For TURN: "
-					read -s GET_TURN_PASSWORD
-					echo "Enter your password again to confirm: "
-					read -s CONFIRM_TURN_PASSWORD
-					if [ ${GET_TURN_PASSWORD} != ${CONFIRM_TURN_PASSWORD} ]; then
-						echo "wrong password entered, try again..."
-						continue
-					fi
-					TURN_PASSWORD="$GET_TURN_PASSWORD"
-					echo "TURN Password Saved Successfully!!"
-					break
-				done
-				break
-				;;
-			*) echo "invalid option $REPLY" ;;
-			esac
-		done
-	fi
-
 	wait_seconds 2
 
 	echo "-----------------------------------------------------------------"

+ 0 - 2
scripts/nm-upgrade.sh

@@ -356,8 +356,6 @@ set_install_vars() {
 	echo "          dashboard.$NETMAKER_BASE_DOMAIN"
 	echo "                api.$NETMAKER_BASE_DOMAIN"
 	echo "             broker.$NETMAKER_BASE_DOMAIN"
-	echo "               turn.$NETMAKER_BASE_DOMAIN"
-	echo "            turnapi.$NETMAKER_BASE_DOMAIN"
 
 	if [ "$INSTALL_TYPE" = "pro" ]; then
 		echo "         prometheus.$NETMAKER_BASE_DOMAIN"

+ 0 - 89
servercfg/serverconf.go

@@ -45,7 +45,6 @@ func GetServerConfig() config.ServerConfig {
 	cfg.AllowedOrigin = GetAllowedOrigin()
 	cfg.RestBackend = "off"
 	cfg.NodeID = GetNodeID()
-	cfg.StunPort = GetStunPort()
 	cfg.BrokerType = GetBrokerType()
 	cfg.EmqxRestEndpoint = GetEmqxRestEndpoint()
 	if AutoUpdateEnabled() {
@@ -125,45 +124,9 @@ func GetServerInfo() models.ServerConfig {
 	}
 	cfg.Version = GetVersion()
 	cfg.IsPro = IsPro
-	cfg.StunPort = GetStunPort()
-	cfg.TurnDomain = GetTurnHost()
-	cfg.TurnPort = GetTurnPort()
-	cfg.UseTurn = IsUsingTurn()
 	return cfg
 }
 
-// GetTurnHost - fetches the turn host domain
-func GetTurnHost() string {
-	turnServer := ""
-	if os.Getenv("TURN_SERVER_HOST") != "" {
-		turnServer = os.Getenv("TURN_SERVER_HOST")
-	} else if config.Config.Server.TurnServer != "" {
-		turnServer = config.Config.Server.TurnServer
-	}
-	return turnServer
-}
-
-// IsUsingTurn - check if server has turn configured
-func IsUsingTurn() (b bool) {
-	if os.Getenv("USE_TURN") != "" {
-		b = os.Getenv("USE_TURN") == "true"
-	} else {
-		b = config.Config.Server.UseTurn
-	}
-	return
-}
-
-// GetTurnApiHost - fetches the turn api host domain
-func GetTurnApiHost() string {
-	turnApiServer := ""
-	if os.Getenv("TURN_SERVER_API_HOST") != "" {
-		turnApiServer = os.Getenv("TURN_SERVER_API_HOST")
-	} else if config.Config.Server.TurnApiServer != "" {
-		turnApiServer = config.Config.Server.TurnApiServer
-	}
-	return turnApiServer
-}
-
 // GetFrontendURL - gets the frontend url
 func GetFrontendURL() string {
 	var frontend = ""
@@ -646,58 +609,6 @@ func GetNetmakerTenantID() string {
 	return netmakerTenantID
 }
 
-// GetStunPort - Get the port to run the stun server on
-func GetStunPort() int {
-	port := 3478 //default
-	if os.Getenv("STUN_PORT") != "" {
-		portInt, err := strconv.Atoi(os.Getenv("STUN_PORT"))
-		if err == nil {
-			port = portInt
-		}
-	} else if config.Config.Server.StunPort != 0 {
-		port = config.Config.Server.StunPort
-	}
-	return port
-}
-
-// GetTurnPort - Get the port to run the turn server on
-func GetTurnPort() int {
-	port := 3479 //default
-	if os.Getenv("TURN_PORT") != "" {
-		portInt, err := strconv.Atoi(os.Getenv("TURN_PORT"))
-		if err == nil {
-			port = portInt
-		}
-	} else if config.Config.Server.TurnPort != 0 {
-		port = config.Config.Server.TurnPort
-	}
-	return port
-}
-
-// GetTurnUserName - fetches the turn server username
-func GetTurnUserName() string {
-	userName := ""
-	if os.Getenv("TURN_USERNAME") != "" {
-		userName = os.Getenv("TURN_USERNAME")
-	} else {
-		userName = config.Config.Server.TurnUserName
-	}
-	return userName
-
-}
-
-// GetTurnPassword - fetches the turn server password
-func GetTurnPassword() string {
-	pass := ""
-	if os.Getenv("TURN_PASSWORD") != "" {
-		pass = os.Getenv("TURN_PASSWORD")
-	} else {
-		pass = config.Config.Server.TurnPassword
-	}
-	return pass
-
-}
-
 // GetNetworkLimit - fetches free tier limits on users
 func GetUserLimit() int {
 	var userslimit int