Browse Source

Merge pull request #2002 from gravitl/GRA-1011/remove_mq_dyn_sec

Gra 1011/remove mq dyn sec
dcarns 2 years ago
parent
commit
d5c85b1d87

+ 7 - 5
compose/docker-compose.ee.yml

@@ -8,9 +8,9 @@ services:
     volumes:
       - dnsconfig:/root/config/dnsconfig
       - sqldata:/root/data
-      - mosquitto_data:/etc/netmaker
     environment:
       SERVER_NAME: "broker.NETMAKER_BASE_DOMAIN"
+      STUN_DOMAIN: "stun.NETMAKER_BASE_DOMAIN"
       SERVER_HOST: "SERVER_PUBLIC_IP"
       SERVER_API_CONN_STRING: "api.NETMAKER_BASE_DOMAIN:443"
       COREDNS_ADDR: "SERVER_PUBLIC_IP"
@@ -24,14 +24,17 @@ services:
       NODE_ID: "netmaker-server-1"
       MQ_HOST: "mq"
       MQ_PORT: "443"
+      STUN_PORT: "3478"
       MQ_SERVER_PORT: "1883"
       VERBOSITY: "1"
       METRICS_EXPORTER: "on"
       LICENSE_KEY: "YOUR_LICENSE_KEY"
       NETMAKER_ACCOUNT_ID: "YOUR_ACCOUNT_ID"
-      MQ_ADMIN_PASSWORD: "REPLACE_MQ_ADMIN_PASSWORD"
+      MQ_PASSWORD: "REPLACE_MQ_PASSWORD"
+      MQ_USERNAME: "REPLACE_MQ_USERNAME"
     ports:
       - "51821-51830:51821-51830/udp"
+      - "3478:3478/udp"
   netmaker-ui:
     container_name: netmaker-ui
     image: gravitl/netmaker-ui:v0.18.0
@@ -70,11 +73,11 @@ services:
     restart: unless-stopped
     command: ["/mosquitto/config/wait.sh"]
     environment:
-      NETMAKER_SERVER_HOST: "https://api.NETMAKER_BASE_DOMAIN"
+      MQ_PASSWORD: "REPLACE_MQ_PASSWORD"
+      MQ_USERNAME: "REPLACE_MQ_USERNAME"
     volumes:
       - /root/mosquitto.conf:/mosquitto/config/mosquitto.conf
       - /root/wait.sh:/mosquitto/config/wait.sh
-      - mosquitto_data:/mosquitto/data
       - mosquitto_logs:/mosquitto/log
     ports:
       - "1883:1883"
@@ -125,7 +128,6 @@ volumes:
   caddy_conf: {}
   sqldata: {}
   dnsconfig: {}
-  mosquitto_data: {}
   mosquitto_logs: {}
   prometheus_data: {}
   grafana_data: {}

+ 4 - 5
compose/docker-compose.yml

@@ -8,7 +8,6 @@ services:
     volumes:
       - dnsconfig:/root/config/dnsconfig
       - sqldata:/root/data
-      - mosquitto_data:/etc/netmaker
     environment:
       BROKER_NAME: "broker.NETMAKER_BASE_DOMAIN"
       SERVER_NAME: "NETMAKER_BASE_DOMAIN"
@@ -28,7 +27,8 @@ services:
       MQ_PORT: "443"
       MQ_SERVER_PORT: "1883"
       VERBOSITY: "1"
-      MQ_ADMIN_PASSWORD: "REPLACE_MQ_ADMIN_PASSWORD"
+      MQ_PASSWORD: "REPLACE_MQ_PASSWORD"
+      MQ_USERNAME: "REPLACE_MQ_USERNAME"
       STUN_PORT: "3478"
       PROXY: "on"
     ports:
@@ -72,16 +72,15 @@ services:
     restart: unless-stopped
     command: ["/mosquitto/config/wait.sh"]
     environment:
-      NETMAKER_SERVER_HOST: "https://api.NETMAKER_BASE_DOMAIN"
+      MQ_PASSWORD: "REPLACE_MQ_PASSWORD"
+      MQ_USERNAME: "REPLACE_MQ_USERNAME"
     volumes:
       - /root/mosquitto.conf:/mosquitto/config/mosquitto.conf
       - /root/wait.sh:/mosquitto/config/wait.sh
-      - mosquitto_data:/mosquitto/data
       - mosquitto_logs:/mosquitto/log
 volumes:
   caddy_data: {}
   caddy_conf: {}
   sqldata: {}
   dnsconfig: {}
-  mosquitto_data: {}
   mosquitto_logs: {}

+ 2 - 1
config/config.go

@@ -67,7 +67,8 @@ type ServerConfig struct {
 	Server                string `yaml:"server"`
 	Broker                string `yam:"broker"`
 	PublicIPService       string `yaml:"publicipservice"`
-	MQAdminPassword       string `yaml:"mqadminpassword"`
+	MQPassword            string `yaml:"mqpassword"`
+	MQUserName            string `yaml:"mqusername"`
 	MetricsExporter       string `yaml:"metrics_exporter"`
 	BasicAuth             string `yaml:"basic_auth"`
 	LicenseValue          string `yaml:"license_value"`

+ 0 - 5
controllers/hosts.go

@@ -97,7 +97,6 @@ func updateHost(w http.ResponseWriter, r *http.Request) {
 	if updateRelay {
 		logic.UpdateHostRelay(currHost.ID.String(), currHost.RelayedHosts, newHost.RelayedHosts)
 	}
-
 	// publish host update through MQ
 	if err := mq.HostUpdate(&models.HostUpdate{
 		Action: models.UpdateHost,
@@ -177,10 +176,6 @@ func deleteHost(w http.ResponseWriter, r *http.Request) {
 		logger.Log(0, r.Header.Get("user"), "failed to send delete host update: ", currHost.ID.String(), err.Error())
 	}
 
-	if err = mq.DeleteMqClient(currHost.ID.String()); err != nil {
-		logger.Log(0, "error removing DynSec credentials for host:", currHost.Name, err.Error())
-	}
-
 	apiHostData := currHost.ConvertNMHostToAPI()
 	logger.Log(2, r.Header.Get("user"), "removed host", currHost.Name)
 	w.WriteHeader(http.StatusOK)

+ 0 - 14
controllers/node.go

@@ -577,8 +577,6 @@ func createNode(w http.ResponseWriter, r *http.Request) {
 	}
 	server := servercfg.GetServerInfo()
 	server.TrafficKey = key
-	// consume password before hashing for mq client creation
-	hostPassword := data.Host.HostPass
 	data.Node.Server = servercfg.GetServer()
 	if !logic.HostExists(&data.Host) {
 		logic.CheckHostPorts(&data.Host)
@@ -606,18 +604,6 @@ func createNode(w http.ResponseWriter, r *http.Request) {
 			logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
 			return
 		}
-	} else {
-		// Create client for this host in Mq
-		if err := mq.CreateMqClient(&mq.MqClient{
-			ID:       data.Host.ID.String(),
-			Text:     data.Host.Name,
-			Password: hostPassword,
-			Networks: []string{networkName},
-		}); err != nil {
-			logger.Log(0, fmt.Sprintf("failed to create DynSec client: %v", err.Error()))
-			logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
-			return
-		}
 	}
 
 	err = logic.AssociateNodeToHost(&data.Node, &data.Host)

+ 1 - 2
docker/mosquitto.conf

@@ -7,5 +7,4 @@ listener 1883
 protocol websockets
 allow_anonymous false
 
-plugin /usr/lib/mosquitto_dynamic_security.so
-plugin_opt_config_file /mosquitto/data/dynamic-security.json
+password_file /mosquitto/password.txt

+ 5 - 10
docker/wait.sh

@@ -1,18 +1,13 @@
 #!/bin/ash
 
-wait_for_netmaker() {
-  echo "SERVER: ${NETMAKER_SERVER_HOST}"
-  until curl --output /dev/null --silent --fail --head \
-    --location "${NETMAKER_SERVER_HOST}/api/server/health"; do
-    echo "Waiting for netmaker server to startup"
-    sleep 1
-  done
+encrypt_password() {
+  echo "${MQ_USERNAME}:${MQ_PASSWORD}" > /mosquitto/password.txt
+  mosquitto_passwd -U /mosquitto/password.txt
 }
 
 main(){
- # wait for netmaker to startup
- apk add curl
- wait_for_netmaker
+
+ encrypt_password
  echo "Starting MQ..."
  # Run the main container command.
  /docker-entrypoint.sh

+ 0 - 6
main.go

@@ -118,11 +118,6 @@ func startControllers() {
 			logger.Log(0, "error occurred initializing DNS: ", err.Error())
 		}
 	}
-	if servercfg.IsMessageQueueBackend() {
-		if err := mq.Configure(); err != nil {
-			logger.FatalLog("failed to configure MQ: ", err.Error())
-		}
-	}
 
 	//Run Rest Server
 	if servercfg.IsRestBackend() {
@@ -172,7 +167,6 @@ func runMessageQueue(wg *sync.WaitGroup) {
 	defer wg.Done()
 	brokerHost, secure := servercfg.GetMessageQueueEndpoint()
 	logger.Log(0, "connecting to mq broker at", brokerHost, "with TLS?", fmt.Sprintf("%v", secure))
-	mq.SetUpAdminClient()
 	mq.SetupMQTT()
 	ctx, cancel := context.WithCancel(context.Background())
 	go mq.Keepalive(ctx)

+ 2 - 0
models/structs.go

@@ -229,6 +229,8 @@ type ServerConfig struct {
 	DNSMode     string `yaml:"dnsmode"`
 	Version     string `yaml:"version"`
 	MQPort      string `yaml:"mqport"`
+	MQUserName  string `yaml:"mq_username"`
+	MQPassword  string `yaml:"mq_password"`
 	Server      string `yaml:"server"`
 	Broker      string `yaml:"broker"`
 	Is_EE       bool   `yaml:"isee"`

+ 0 - 214
mq/dynsec.go

@@ -1,214 +0,0 @@
-package mq
-
-import (
-	"crypto/sha512"
-	"encoding/base64"
-	"encoding/json"
-	"errors"
-	"fmt"
-	"os"
-	"time"
-
-	mqtt "github.com/eclipse/paho.mqtt.golang"
-	"github.com/gravitl/netmaker/functions"
-	"github.com/gravitl/netmaker/logger"
-	"github.com/gravitl/netmaker/logic"
-	"github.com/gravitl/netmaker/netclient/ncutils"
-	"github.com/gravitl/netmaker/servercfg"
-	"golang.org/x/crypto/pbkdf2"
-)
-
-// mq client for admin
-var mqAdminClient mqtt.Client
-
-const (
-	// constant for client command
-	CreateClientCmd = "createClient"
-	// constant for disable command
-	DisableClientCmd = "disableClient"
-	// constant for delete client command
-	DeleteClientCmd = "deleteClient"
-	// constant for modify client command
-	ModifyClientCmd = "modifyClient"
-
-	// constant for create role command
-	CreateRoleCmd = "createRole"
-	// constant for delete role command
-	DeleteRoleCmd = "deleteRole"
-
-	// constant for admin user name
-	mqAdminUserName = "Netmaker-Admin"
-	// constant for server user name
-	mqNetmakerServerUserName = "Netmaker-Server"
-	// constant for exporter user name
-	mqExporterUserName = "Netmaker-Exporter"
-
-	// DynamicSecSubTopic - constant for dynamic security subscription topic
-	dynamicSecSubTopic = "$CONTROL/dynamic-security/#"
-	// DynamicSecPubTopic - constant for dynamic security subscription topic
-	dynamicSecPubTopic = "$CONTROL/dynamic-security/v1"
-)
-
-// struct for dynamic security file
-type dynJSON struct {
-	Clients    []client         `json:"clients"`
-	Roles      []role           `json:"roles"`
-	DefaultAcl defaultAccessAcl `json:"defaultACLAccess"`
-}
-
-// struct for client role
-type clientRole struct {
-	Rolename string `json:"rolename"`
-}
-
-// struct for MQ client
-type client struct {
-	Username   string       `json:"username"`
-	TextName   string       `json:"textName"`
-	Password   string       `json:"password"`
-	Salt       string       `json:"salt"`
-	Iterations int          `json:"iterations"`
-	Roles      []clientRole `json:"roles"`
-}
-
-// struct for MQ role
-type role struct {
-	Rolename string `json:"rolename"`
-	Acls     []Acl  `json:"acls"`
-}
-
-// struct for default acls
-type defaultAccessAcl struct {
-	PublishClientSend    bool `json:"publishClientSend"`
-	PublishClientReceive bool `json:"publishClientReceive"`
-	Subscribe            bool `json:"subscribe"`
-	Unsubscribe          bool `json:"unsubscribe"`
-}
-
-// MqDynSecGroup - struct for MQ client group
-type MqDynSecGroup struct {
-	Groupname string `json:"groupname"`
-	Priority  int    `json:"priority"`
-}
-
-// MqDynSecRole - struct for MQ client role
-type MqDynSecRole struct {
-	Rolename string `json:"rolename"`
-	Priority int    `json:"priority"`
-}
-
-// Acl - struct for MQ acls
-type Acl struct {
-	AclType  string `json:"acltype"`
-	Topic    string `json:"topic"`
-	Priority int    `json:"priority,omitempty"`
-	Allow    bool   `json:"allow"`
-}
-
-// MqDynSecCmd - struct for MQ dynamic security command
-type MqDynSecCmd struct {
-	Command         string          `json:"command"`
-	Username        string          `json:"username"`
-	Password        string          `json:"password"`
-	RoleName        string          `json:"rolename,omitempty"`
-	Acls            []Acl           `json:"acls,omitempty"`
-	Clientid        string          `json:"clientid"`
-	Textname        string          `json:"textname"`
-	Textdescription string          `json:"textdescription"`
-	Groups          []MqDynSecGroup `json:"groups"`
-	Roles           []MqDynSecRole  `json:"roles"`
-}
-
-// MqDynsecPayload - struct for dynamic security command payload
-type MqDynsecPayload struct {
-	Commands []MqDynSecCmd `json:"commands"`
-}
-
-// encodePasswordToPBKDF2 - encodes the given password with PBKDF2 hashing for MQ
-func encodePasswordToPBKDF2(password string, salt string, iterations int, keyLength int) string {
-	binaryEncoded := pbkdf2.Key([]byte(password), []byte(salt), iterations, keyLength, sha512.New)
-	return base64.StdEncoding.EncodeToString(binaryEncoded)
-}
-
-// Configure - configures the dynamic initial configuration for MQ
-func Configure() error {
-
-	logger.Log(0, "Configuring MQ...")
-	dynConfig := dynConfigInI
-	path := functions.GetNetmakerPath() + ncutils.GetSeparator() + dynamicSecurityFile
-
-	password := servercfg.GetMqAdminPassword()
-	if password == "" {
-		return errors.New("MQ admin password not provided")
-	}
-	if logic.CheckIfFileExists(path) {
-		data, err := os.ReadFile(path)
-		if err == nil {
-			var cfg dynJSON
-			err = json.Unmarshal(data, &cfg)
-			if err == nil {
-				logger.Log(0, "MQ config exists already, So Updating Existing Config...")
-				dynConfig = cfg
-			}
-		}
-	}
-	exporter := false
-	for i, cI := range dynConfig.Clients {
-		if cI.Username == mqAdminUserName || cI.Username == mqNetmakerServerUserName {
-			salt := logic.RandomString(12)
-			hashed := encodePasswordToPBKDF2(password, salt, 101, 64)
-			cI.Password = hashed
-			cI.Iterations = 101
-			cI.Salt = base64.StdEncoding.EncodeToString([]byte(salt))
-			dynConfig.Clients[i] = cI
-		} else if servercfg.Is_EE && cI.Username == mqExporterUserName {
-			exporter = true
-			exporterPassword := servercfg.GetLicenseKey()
-			salt := logic.RandomString(12)
-			hashed := encodePasswordToPBKDF2(exporterPassword, salt, 101, 64)
-			cI.Password = hashed
-			cI.Iterations = 101
-			cI.Salt = base64.StdEncoding.EncodeToString([]byte(salt))
-			dynConfig.Clients[i] = cI
-		}
-	}
-	if servercfg.Is_EE && !exporter {
-		exporterPassword := servercfg.GetLicenseKey()
-		salt := logic.RandomString(12)
-		hashed := encodePasswordToPBKDF2(exporterPassword, salt, 101, 64)
-		exporterMQClient.Password = hashed
-		exporterMQClient.Iterations = 101
-		exporterMQClient.Salt = base64.StdEncoding.EncodeToString([]byte(salt))
-		dynConfig.Clients = append(dynConfig.Clients, exporterMQClient)
-	}
-	data, err := json.MarshalIndent(dynConfig, "", " ")
-	if err != nil {
-		return err
-	}
-	return os.WriteFile(path, data, 0755)
-}
-
-// publishes the message to dynamic security topic
-func publishEventToDynSecTopic(payload MqDynsecPayload) error {
-
-	d, err := json.Marshal(payload)
-	if err != nil {
-		return err
-	}
-	var connecterr error
-	if token := mqAdminClient.Publish(dynamicSecPubTopic, 2, false, d); !token.WaitTimeout(MQ_TIMEOUT*time.Second) || token.Error() != nil {
-		if token.Error() == nil {
-			connecterr = errors.New("connect timeout")
-		} else {
-			connecterr = token.Error()
-		}
-	}
-	return connecterr
-}
-
-// watchDynSecTopic - message handler for dynamic security responses
-func watchDynSecTopic(client mqtt.Client, msg mqtt.Message) {
-
-	logger.Log(1, fmt.Sprintf("----->WatchDynSecTopic Message: %+v", string(msg.Payload())))
-
-}

+ 0 - 47
mq/dynsec_clients.go

@@ -1,47 +0,0 @@
-package mq
-
-// MqClient - type for taking in an MQ client's data
-type MqClient struct {
-	ID       string
-	Text     string
-	Password string
-	Networks []string
-}
-
-// DeleteMqClient - removes a client from the DynSec system
-func DeleteMqClient(hostID string) error {
-
-	event := MqDynsecPayload{
-		Commands: []MqDynSecCmd{
-			{
-				Command:  DeleteClientCmd,
-				Username: hostID,
-			},
-		},
-	}
-	return publishEventToDynSecTopic(event)
-}
-
-// CreateMqClient - creates an MQ DynSec client
-func CreateMqClient(client *MqClient) error {
-
-	event := MqDynsecPayload{
-		Commands: []MqDynSecCmd{
-			{
-				Command:  CreateClientCmd,
-				Username: client.ID,
-				Password: client.Password,
-				Textname: client.Text,
-				Roles: []MqDynSecRole{
-					{
-						Rolename: genericRole,
-						Priority: -1,
-					},
-				},
-				Groups: make([]MqDynSecGroup, 0),
-			},
-		},
-	}
-
-	return publishEventToDynSecTopic(event)
-}

+ 0 - 187
mq/dynsec_helper.go

@@ -1,187 +0,0 @@
-package mq
-
-import (
-	"errors"
-	"time"
-
-	mqtt "github.com/eclipse/paho.mqtt.golang"
-	"github.com/gravitl/netmaker/servercfg"
-)
-
-const (
-	// constant for admin role
-	adminRole = "admin"
-	// constant for generic role
-	genericRole = "generic"
-
-	// const for dynamic security file
-	dynamicSecurityFile = "dynamic-security.json"
-)
-
-var (
-	// default configuration of dynamic security
-	dynConfigInI = dynJSON{
-		Clients: []client{
-			{
-				Username:   mqAdminUserName,
-				TextName:   "netmaker admin user",
-				Password:   "",
-				Salt:       "",
-				Iterations: 0,
-				Roles: []clientRole{
-					{
-						Rolename: adminRole,
-					},
-				},
-			},
-			{
-				Username:   mqNetmakerServerUserName,
-				TextName:   "netmaker server user",
-				Password:   "",
-				Salt:       "",
-				Iterations: 0,
-				Roles: []clientRole{
-					{
-						Rolename: genericRole,
-					},
-				},
-			},
-			exporterMQClient,
-		},
-		Roles: []role{
-			{
-				Rolename: adminRole,
-				Acls:     fetchAdminAcls(),
-			},
-			{
-				Rolename: genericRole,
-				Acls:     fetchGenericAcls(),
-			},
-		},
-		DefaultAcl: defaultAccessAcl{
-			PublishClientSend:    false,
-			PublishClientReceive: true,
-			Subscribe:            false,
-			Unsubscribe:          true,
-		},
-	}
-
-	exporterMQClient = client{
-		Username:   mqExporterUserName,
-		TextName:   "netmaker metrics exporter",
-		Password:   "",
-		Salt:       "",
-		Iterations: 101,
-		Roles: []clientRole{
-			{
-				Rolename: genericRole,
-			},
-		},
-	}
-)
-
-// GetAdminClient - fetches admin client of the MQ
-func GetAdminClient() (mqtt.Client, error) {
-	opts := mqtt.NewClientOptions()
-	setMqOptions(mqAdminUserName, servercfg.GetMqAdminPassword(), opts)
-	mqclient := mqtt.NewClient(opts)
-	var connecterr error
-	if token := mqclient.Connect(); !token.WaitTimeout(MQ_TIMEOUT*time.Second) || token.Error() != nil {
-		if token.Error() == nil {
-			connecterr = errors.New("connect timeout")
-		} else {
-			connecterr = token.Error()
-		}
-	}
-	return mqclient, connecterr
-}
-
-// genericAcls - fetches generice role related acls
-func fetchGenericAcls() []Acl {
-	return []Acl{
-		{
-			AclType:  "publishClientSend",
-			Topic:    "#",
-			Priority: -1,
-			Allow:    true,
-		},
-		{
-			AclType:  "publishClientReceive",
-			Topic:    "#",
-			Priority: -1,
-			Allow:    true,
-		},
-		{
-			AclType:  "subscribePattern",
-			Topic:    "#",
-			Priority: -1,
-			Allow:    true,
-		},
-		{
-			AclType:  "unsubscribePattern",
-			Topic:    "#",
-			Priority: -1,
-			Allow:    true,
-		},
-	}
-}
-
-// fetchAdminAcls - fetches admin role related acls
-func fetchAdminAcls() []Acl {
-	return []Acl{
-		{
-			AclType:  "publishClientSend",
-			Topic:    "$CONTROL/dynamic-security/#",
-			Priority: -1,
-			Allow:    true,
-		},
-		{
-			AclType:  "publishClientReceive",
-			Topic:    "$CONTROL/dynamic-security/#",
-			Priority: -1,
-			Allow:    true,
-		},
-		{
-			AclType:  "subscribePattern",
-			Topic:    "$CONTROL/dynamic-security/#",
-			Priority: -1,
-			Allow:    true,
-		},
-		{
-			AclType:  "publishClientReceive",
-			Topic:    "$SYS/#",
-			Priority: -1,
-			Allow:    true,
-		},
-		{
-			AclType:  "subscribePattern",
-			Topic:    "$SYS/#",
-			Priority: -1,
-			Allow:    true,
-		},
-		{
-			AclType:  "publishClientReceive",
-			Topic:    "#",
-			Priority: -1,
-			Allow:    true,
-		},
-		{
-			AclType:  "subscribePattern",
-			Topic:    "#",
-			Priority: -1,
-			Allow:    true,
-		},
-		{
-			AclType:  "unsubscribePattern",
-			Topic:    "#",
-			Priority: -1,
-			Allow:    true,
-		},
-		{
-			AclType:  "publishClientSend",
-			Topic:    "#",
-			Priority: -1,
-			Allow:    true,
-		},
-	}
-}

+ 1 - 35
mq/mq.go

@@ -2,7 +2,6 @@ package mq
 
 import (
 	"context"
-	"fmt"
 	"time"
 
 	mqtt "github.com/eclipse/paho.mqtt.golang"
@@ -23,39 +22,6 @@ var peer_force_send = 0
 
 var mqclient mqtt.Client
 
-// SetUpAdminClient - sets up admin client for the MQ
-func SetUpAdminClient() {
-	opts := mqtt.NewClientOptions()
-	setMqOptions(mqAdminUserName, servercfg.GetMqAdminPassword(), opts)
-	mqAdminClient = mqtt.NewClient(opts)
-	opts.SetOnConnectHandler(func(client mqtt.Client) {
-		if token := client.Subscribe(dynamicSecSubTopic, 2, mqtt.MessageHandler(watchDynSecTopic)); token.WaitTimeout(MQ_TIMEOUT*time.Second) && token.Error() != nil {
-			client.Disconnect(240)
-			logger.Log(0, fmt.Sprintf("Dynamic security client subscription failed: %v ", token.Error()))
-		}
-
-		opts.SetOrderMatters(true)
-		opts.SetResumeSubs(true)
-	})
-	tperiod := time.Now().Add(10 * time.Second)
-	for {
-		if token := mqAdminClient.Connect(); !token.WaitTimeout(MQ_TIMEOUT*time.Second) || token.Error() != nil {
-			logger.Log(2, "Admin: unable to connect to broker, retrying ...")
-			if time.Now().After(tperiod) {
-				if token.Error() == nil {
-					logger.FatalLog("Admin: could not connect to broker, token timeout, exiting ...")
-				} else {
-					logger.FatalLog("Admin: could not connect to broker, exiting ...", token.Error().Error())
-				}
-			}
-		} else {
-			break
-		}
-		time.Sleep(2 * time.Second)
-	}
-
-}
-
 func setMqOptions(user, password string, opts *mqtt.ClientOptions) {
 	broker, _ := servercfg.GetMessageQueueEndpoint()
 	opts.AddBroker(broker)
@@ -73,7 +39,7 @@ func setMqOptions(user, password string, opts *mqtt.ClientOptions) {
 // SetupMQTT creates a connection to broker and return client
 func SetupMQTT() {
 	opts := mqtt.NewClientOptions()
-	setMqOptions(mqNetmakerServerUserName, servercfg.GetMqAdminPassword(), opts)
+	setMqOptions(servercfg.GetMqUserName(), servercfg.GetMqPassword(), opts)
 	opts.SetOnConnectHandler(func(client mqtt.Client) {
 		if token := client.Subscribe("ping/#", 2, mqtt.MessageHandler(Ping)); token.WaitTimeout(MQ_TIMEOUT*time.Second) && token.Error() != nil {
 			client.Disconnect(240)

+ 48 - 5
scripts/nm-quick-interactive.sh

@@ -188,9 +188,7 @@ NETMAKER_BASE_DOMAIN=nm.$(curl -s ifconfig.me | tr . -).nip.io
 COREDNS_IP=$(ip route get 1 | sed -n 's/^.*src \([0-9.]*\) .*$/\1/p')
 SERVER_PUBLIC_IP=$(curl -s ifconfig.me)
 MASTER_KEY=$(tr -dc A-Za-z0-9 </dev/urandom | head -c 30 ; echo '')
-MQ_PASSWORD=$(tr -dc A-Za-z0-9 </dev/urandom | head -c 30 ; echo '')
 DOMAIN_TYPE=""
-
 echo "-----------------------------------------------------"
 echo "Would you like to use your own domain for netmaker, or an auto-generated domain?"
 echo "To use your own domain, add a Wildcard DNS record (e.x: *.netmaker.example.com) pointing to $SERVER_PUBLIC_IP"
@@ -267,6 +265,49 @@ else
   EMAIL="$GET_EMAIL"
 fi
 
+wait_seconds 1
+
+unset GET_MQ_USERNAME
+unset GET_MQ_PASSWORD
+unset CONFIRM_MQ_PASSWORD
+echo "Enter Credentials For MQ..."
+read -p "MQ Username (click 'enter' to use 'netmaker'): " GET_MQ_USERNAME
+if [ -z "$GET_MQ_USERNAME" ]; then
+  echo "using default username for mq"
+  MQ_USERNAME="netmaker"
+else
+  MQ_USERNAME="$GET_MQ_USERNAME"
+fi
+
+select domain_option in "Auto Generated Password" "Input Your Own Password"; do
+	case $REPLY in
+	1)
+	echo "generating random password for mq"
+	MQ_PASSWORD=$(tr -dc A-Za-z0-9 </dev/urandom | head -c 30 ; echo '')
+	break
+	;;      
+    2)
+	while true
+    do
+        echo "Enter your Password For MQ: " 
+        read -s GET_MQ_PASSWORD
+        echo "Enter your password again to confirm: "
+        read -s CONFIRM_MQ_PASSWORD
+        if [ ${GET_MQ_PASSWORD} != ${CONFIRM_MQ_PASSWORD} ]; then
+            echo "wrong password entered, try again..."
+            continue
+        fi
+		MQ_PASSWORD="$GET_MQ_PASSWORD"
+        echo "MQ Password Saved Successfully!!"
+        break
+    done
+      break
+      ;;
+    *) echo "invalid option $REPLY";;
+  esac
+done
+
+
 wait_seconds 2
 
 echo "-----------------------------------------------------------------"
@@ -301,8 +342,9 @@ if [ "$INSTALL_TYPE" = "ee" ]; then
 	CADDY_URL="https://raw.githubusercontent.com/gravitl/netmaker/master/docker/Caddyfile-EE"
 fi
 
-wget -O /root/docker-compose.yml $COMPOSE_URL && wget -O /root/mosquitto.conf https://raw.githubusercontent.com/gravitl/netmaker/master/docker/mosquitto.conf && wget -O /root/Caddyfile $CADDY_URL && wget -q -O /root/wait.sh https://raw.githubusercontent.com/gravitl/netmaker/master/docker/wait.sh && chmod +x /root/wait.sh
-
+wget -O /root/docker-compose.yml $COMPOSE_URL && wget -O /root/mosquitto.conf https://raw.githubusercontent.com/gravitl/netmaker/master/docker/mosquitto.conf && wget -O /root/Caddyfile $CADDY_URL
+wget -O /root/wait.sh https://raw.githubusercontent.com/gravitl/netmaker/master/docker/wait.sh
+chmod +x /root/wait.sh
 mkdir -p /etc/netmaker
 
 echo "Setting docker-compose and Caddyfile..."
@@ -312,7 +354,8 @@ sed -i "s/NETMAKER_BASE_DOMAIN/$NETMAKER_BASE_DOMAIN/g" /root/Caddyfile
 sed -i "s/NETMAKER_BASE_DOMAIN/$NETMAKER_BASE_DOMAIN/g" /root/docker-compose.yml
 sed -i "s/REPLACE_MASTER_KEY/$MASTER_KEY/g" /root/docker-compose.yml
 sed -i "s/YOUR_EMAIL/$EMAIL/g" /root/Caddyfile
-sed -i "s/REPLACE_MQ_ADMIN_PASSWORD/$MQ_PASSWORD/g" /root/docker-compose.yml 
+sed -i "s/REPLACE_MQ_PASSWORD/$MQ_PASSWORD/g" /root/docker-compose.yml
+sed -i "s/REPLACE_MQ_USERNAME/$MQ_USERNAME/g" /root/docker-compose.yml 
 if [ "$INSTALL_TYPE" = "ee" ]; then
 	sed -i "s~YOUR_LICENSE_KEY~$LICENSE_KEY~g" /root/docker-compose.yml
 	sed -i "s/YOUR_ACCOUNT_ID/$ACCOUNT_ID/g" /root/docker-compose.yml

+ 19 - 6
servercfg/serverconf.go

@@ -88,6 +88,8 @@ func GetServerInfo() models.ServerConfig {
 	var cfg models.ServerConfig
 	cfg.Server = GetServer()
 	cfg.Broker = GetBroker()
+	cfg.MQUserName = GetMqUserName()
+	cfg.MQPassword = GetMqPassword()
 	cfg.API = GetAPIConnString()
 	cfg.CoreDNSAddr = GetCoreDNSAddr()
 	cfg.APIPort = GetAPIPort()
@@ -589,13 +591,24 @@ func GetMQServerPort() string {
 	return port
 }
 
-// GetMqAdminPassword - fetches the MQ Admin password
-func GetMqAdminPassword() string {
+// GetMqPassword - fetches the MQ password
+func GetMqPassword() string {
 	password := ""
-	if os.Getenv("MQ_ADMIN_PASSWORD") != "" {
-		password = os.Getenv("MQ_ADMIN_PASSWORD")
-	} else if config.Config.Server.MQAdminPassword != "" {
-		password = config.Config.Server.MQAdminPassword
+	if os.Getenv("MQ_PASSWORD") != "" {
+		password = os.Getenv("MQ_PASSWORD")
+	} else if config.Config.Server.MQPassword != "" {
+		password = config.Config.Server.MQPassword
+	}
+	return password
+}
+
+// GetMqUserName - fetches the MQ username
+func GetMqUserName() string {
+	password := ""
+	if os.Getenv("MQ_USERNAME") != "" {
+		password = os.Getenv("MQ_USERNAME")
+	} else if config.Config.Server.MQUserName != "" {
+		password = config.Config.Server.MQUserName
 	}
 	return password
 }