mirror of
https://github.com/gravitl/netmaker.git
synced 2025-10-09 21:36:09 +08:00
create client for nodes on authenticate,generate dyn sec file on startup
This commit is contained in:
parent
3d5eac6905
commit
878430bf75
10 changed files with 208 additions and 178 deletions
|
@ -17,7 +17,7 @@ services:
|
||||||
volumes:
|
volumes:
|
||||||
- dnsconfig:/root/config/dnsconfig
|
- dnsconfig:/root/config/dnsconfig
|
||||||
- sqldata:/root/data
|
- sqldata:/root/data
|
||||||
- shared_certs:/etc/netmaker
|
- mosquitto_data:/etc/netmaker
|
||||||
environment:
|
environment:
|
||||||
SERVER_NAME: "broker.NETMAKER_BASE_DOMAIN"
|
SERVER_NAME: "broker.NETMAKER_BASE_DOMAIN"
|
||||||
SERVER_HOST: "SERVER_PUBLIC_IP"
|
SERVER_HOST: "SERVER_PUBLIC_IP"
|
||||||
|
@ -39,7 +39,7 @@ services:
|
||||||
VERBOSITY: "1"
|
VERBOSITY: "1"
|
||||||
MANAGE_IPTABLES: "on"
|
MANAGE_IPTABLES: "on"
|
||||||
PORT_FORWARD_SERVICES: "dns"
|
PORT_FORWARD_SERVICES: "dns"
|
||||||
MQ_ADMIN_PASSWORD: "MQ_ADMIN_PASSWORD"
|
MQ_ADMIN_PASSWORD: "REPLACE_MQ_ADMIN_PASSWORD"
|
||||||
ports:
|
ports:
|
||||||
- "51821-51830:51821-51830/udp"
|
- "51821-51830:51821-51830/udp"
|
||||||
expose:
|
expose:
|
||||||
|
@ -115,7 +115,6 @@ services:
|
||||||
NETMAKER_SERVER_HOST: "api.NETMAKER_BASE_DOMAIN"
|
NETMAKER_SERVER_HOST: "api.NETMAKER_BASE_DOMAIN"
|
||||||
volumes:
|
volumes:
|
||||||
- /root/mosquitto.conf:/mosquitto/config/mosquitto.conf
|
- /root/mosquitto.conf:/mosquitto/config/mosquitto.conf
|
||||||
- /root/dynamic-security.json:/mosquitto/config/dynamic-security.json
|
|
||||||
- /root/wait.sh:/mosquitto/config/wait.sh
|
- /root/wait.sh:/mosquitto/config/wait.sh
|
||||||
- mosquitto_data:/mosquitto/data
|
- mosquitto_data:/mosquitto/data
|
||||||
- mosquitto_logs:/mosquitto/log
|
- mosquitto_logs:/mosquitto/log
|
||||||
|
@ -130,7 +129,6 @@ services:
|
||||||
- traefik.tcp.routers.mqtts.entrypoints=websecure
|
- traefik.tcp.routers.mqtts.entrypoints=websecure
|
||||||
volumes:
|
volumes:
|
||||||
traefik_certs: {}
|
traefik_certs: {}
|
||||||
shared_certs: {}
|
|
||||||
sqldata: {}
|
sqldata: {}
|
||||||
dnsconfig: {}
|
dnsconfig: {}
|
||||||
mosquitto_data: {}
|
mosquitto_data: {}
|
||||||
|
|
|
@ -67,75 +67,94 @@ func authenticate(response http.ResponseWriter, request *http.Request) {
|
||||||
decoderErr.Error())
|
decoderErr.Error())
|
||||||
logic.ReturnErrorResponse(response, request, errorResponse)
|
logic.ReturnErrorResponse(response, request, errorResponse)
|
||||||
return
|
return
|
||||||
} else {
|
|
||||||
errorResponse.Code = http.StatusBadRequest
|
|
||||||
if authRequest.ID == "" {
|
|
||||||
errorResponse.Message = "W1R3: ID can't be empty"
|
|
||||||
logger.Log(0, request.Header.Get("user"), errorResponse.Message)
|
|
||||||
logic.ReturnErrorResponse(response, request, errorResponse)
|
|
||||||
return
|
|
||||||
} else if authRequest.Password == "" {
|
|
||||||
errorResponse.Message = "W1R3: Password can't be empty"
|
|
||||||
logger.Log(0, request.Header.Get("user"), errorResponse.Message)
|
|
||||||
logic.ReturnErrorResponse(response, request, errorResponse)
|
|
||||||
return
|
|
||||||
} else {
|
|
||||||
var err error
|
|
||||||
result, err = logic.GetNodeByID(authRequest.ID)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
errorResponse.Code = http.StatusBadRequest
|
|
||||||
errorResponse.Message = err.Error()
|
|
||||||
logger.Log(0, request.Header.Get("user"),
|
|
||||||
fmt.Sprintf("failed to get node info [%s]: %v", authRequest.ID, err))
|
|
||||||
logic.ReturnErrorResponse(response, request, errorResponse)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
err = bcrypt.CompareHashAndPassword([]byte(result.Password), []byte(authRequest.Password))
|
|
||||||
if err != nil {
|
|
||||||
errorResponse.Code = http.StatusBadRequest
|
|
||||||
errorResponse.Message = err.Error()
|
|
||||||
logger.Log(0, request.Header.Get("user"),
|
|
||||||
"error validating user password: ", err.Error())
|
|
||||||
logic.ReturnErrorResponse(response, request, errorResponse)
|
|
||||||
return
|
|
||||||
} else {
|
|
||||||
tokenString, err := logic.CreateJWT(authRequest.ID, authRequest.MacAddress, result.Network)
|
|
||||||
|
|
||||||
if tokenString == "" {
|
|
||||||
errorResponse.Code = http.StatusBadRequest
|
|
||||||
errorResponse.Message = "Could not create Token"
|
|
||||||
logger.Log(0, request.Header.Get("user"),
|
|
||||||
fmt.Sprintf("%s: %v", errorResponse.Message, err))
|
|
||||||
logic.ReturnErrorResponse(response, request, errorResponse)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var successResponse = models.SuccessResponse{
|
|
||||||
Code: http.StatusOK,
|
|
||||||
Message: "W1R3: Device " + authRequest.ID + " Authorized",
|
|
||||||
Response: models.SuccessfulLoginResponse{
|
|
||||||
AuthToken: tokenString,
|
|
||||||
ID: authRequest.ID,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
successJSONResponse, jsonError := json.Marshal(successResponse)
|
|
||||||
|
|
||||||
if jsonError != nil {
|
|
||||||
errorResponse.Code = http.StatusBadRequest
|
|
||||||
errorResponse.Message = err.Error()
|
|
||||||
logger.Log(0, request.Header.Get("user"),
|
|
||||||
"error marshalling resp: ", err.Error())
|
|
||||||
logic.ReturnErrorResponse(response, request, errorResponse)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
response.WriteHeader(http.StatusOK)
|
|
||||||
response.Header().Set("Content-Type", "application/json")
|
|
||||||
response.Write(successJSONResponse)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
errorResponse.Code = http.StatusBadRequest
|
||||||
|
if authRequest.ID == "" {
|
||||||
|
errorResponse.Message = "W1R3: ID can't be empty"
|
||||||
|
logger.Log(0, request.Header.Get("user"), errorResponse.Message)
|
||||||
|
logic.ReturnErrorResponse(response, request, errorResponse)
|
||||||
|
return
|
||||||
|
} else if authRequest.Password == "" {
|
||||||
|
errorResponse.Message = "W1R3: Password can't be empty"
|
||||||
|
logger.Log(0, request.Header.Get("user"), errorResponse.Message)
|
||||||
|
logic.ReturnErrorResponse(response, request, errorResponse)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var err error
|
||||||
|
result, err = logic.GetNodeByID(authRequest.ID)
|
||||||
|
if err != nil {
|
||||||
|
errorResponse.Code = http.StatusBadRequest
|
||||||
|
errorResponse.Message = err.Error()
|
||||||
|
logger.Log(0, request.Header.Get("user"),
|
||||||
|
fmt.Sprintf("failed to get node info [%s]: %v", authRequest.ID, err))
|
||||||
|
logic.ReturnErrorResponse(response, request, errorResponse)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err = bcrypt.CompareHashAndPassword([]byte(result.Password), []byte(authRequest.Password))
|
||||||
|
if err != nil {
|
||||||
|
errorResponse.Code = http.StatusBadRequest
|
||||||
|
errorResponse.Message = err.Error()
|
||||||
|
logger.Log(0, request.Header.Get("user"),
|
||||||
|
"error validating user password: ", err.Error())
|
||||||
|
logic.ReturnErrorResponse(response, request, errorResponse)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
event := mq.DynSecAction{
|
||||||
|
ActionType: mq.CreateClient,
|
||||||
|
Payload: mq.MqDynsecPayload{
|
||||||
|
Commands: []mq.MqDynSecCmd{
|
||||||
|
{
|
||||||
|
Command: mq.CreateClientCmd,
|
||||||
|
Username: result.ID,
|
||||||
|
Password: authRequest.Password,
|
||||||
|
Textname: result.Name,
|
||||||
|
Roles: make([]mq.MqDynSecRole, 0),
|
||||||
|
Groups: make([]mq.MqDynSecGroup, 0),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
if err := mq.PublishEventToDynSecTopic(event); err != nil {
|
||||||
|
logger.Log(0, fmt.Sprintf("failed to send DynSec command [%s]: %v",
|
||||||
|
event.ActionType, err.Error()))
|
||||||
|
errorResponse.Code = http.StatusInternalServerError
|
||||||
|
errorResponse.Message = fmt.Sprintf("could not create mq client for node [%s]: %v", result.ID, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
tokenString, err := logic.CreateJWT(authRequest.ID, authRequest.MacAddress, result.Network)
|
||||||
|
if tokenString == "" {
|
||||||
|
errorResponse.Code = http.StatusBadRequest
|
||||||
|
errorResponse.Message = "Could not create Token"
|
||||||
|
logger.Log(0, request.Header.Get("user"),
|
||||||
|
fmt.Sprintf("%s: %v", errorResponse.Message, err))
|
||||||
|
logic.ReturnErrorResponse(response, request, errorResponse)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var successResponse = models.SuccessResponse{
|
||||||
|
Code: http.StatusOK,
|
||||||
|
Message: "W1R3: Device " + authRequest.ID + " Authorized",
|
||||||
|
Response: models.SuccessfulLoginResponse{
|
||||||
|
AuthToken: tokenString,
|
||||||
|
ID: authRequest.ID,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
successJSONResponse, jsonError := json.Marshal(successResponse)
|
||||||
|
|
||||||
|
if jsonError != nil {
|
||||||
|
errorResponse.Code = http.StatusBadRequest
|
||||||
|
errorResponse.Message = err.Error()
|
||||||
|
logger.Log(0, request.Header.Get("user"),
|
||||||
|
"error marshalling resp: ", err.Error())
|
||||||
|
logic.ReturnErrorResponse(response, request, errorResponse)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
response.WriteHeader(http.StatusOK)
|
||||||
|
response.Header().Set("Content-Type", "application/json")
|
||||||
|
response.Write(successJSONResponse)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// auth middleware for api calls from nodes where node is has not yet joined the server (register, join)
|
// auth middleware for api calls from nodes where node is has not yet joined the server (register, join)
|
||||||
|
|
|
@ -1,68 +0,0 @@
|
||||||
{
|
|
||||||
"clients": [{
|
|
||||||
"username": "Netmaker-Admin",
|
|
||||||
"textName": "netmaker admin user",
|
|
||||||
"password": "T42rorlC/mAP+i19g/YqMlWShPpfo8F/nBz2ZQNRcjAnfczrgu4rIQam9z7T/87NBIHxqR1wMlCIvRN5JApHcw==",
|
|
||||||
"salt": "lHl24sEf+lJ/kFHk",
|
|
||||||
"iterations": 101,
|
|
||||||
"roles": [{
|
|
||||||
"rolename": "admin"
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"username": "netmaker-exporter",
|
|
||||||
"textName": "netmaker metrics exporter",
|
|
||||||
"password": "yl7HZglF4CvCxgjPLLIYc73LRtjEwp2/SAEQXeW5Ta1Dl4RoLN5/gjqiv8xmue+F9LfRk8KICkNbhSYuEfJ7ww==",
|
|
||||||
"salt": "veLl9eN02i+hKkyT",
|
|
||||||
"iterations": 101,
|
|
||||||
"roles": []
|
|
||||||
}],
|
|
||||||
"roles": [{
|
|
||||||
"rolename": "admin",
|
|
||||||
"acls": [{
|
|
||||||
"acltype": "publishClientSend",
|
|
||||||
"topic": "$CONTROL/dynamic-security/#",
|
|
||||||
"allow": true
|
|
||||||
}, {
|
|
||||||
"acltype": "publishClientReceive",
|
|
||||||
"topic": "$CONTROL/dynamic-security/#",
|
|
||||||
"allow": true
|
|
||||||
}, {
|
|
||||||
"acltype": "subscribePattern",
|
|
||||||
"topic": "$CONTROL/dynamic-security/#",
|
|
||||||
"allow": true
|
|
||||||
}, {
|
|
||||||
"acltype": "publishClientReceive",
|
|
||||||
"topic": "$SYS/#",
|
|
||||||
"allow": true
|
|
||||||
}, {
|
|
||||||
"acltype": "subscribePattern",
|
|
||||||
"topic": "$SYS/#",
|
|
||||||
"allow": true
|
|
||||||
}, {
|
|
||||||
"acltype": "publishClientReceive",
|
|
||||||
"topic": "#",
|
|
||||||
"allow": true
|
|
||||||
}, {
|
|
||||||
"acltype": "subscribePattern",
|
|
||||||
"topic": "#",
|
|
||||||
"allow": true
|
|
||||||
}, {
|
|
||||||
"acltype": "unsubscribePattern",
|
|
||||||
"topic": "#",
|
|
||||||
"allow": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"acltype": "publishClientSend",
|
|
||||||
"topic": "#",
|
|
||||||
"allow": true
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}],
|
|
||||||
"defaultACLAccess": {
|
|
||||||
"publishClientSend": true,
|
|
||||||
"publishClientReceive": true,
|
|
||||||
"subscribe": true,
|
|
||||||
"unsubscribe": true
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -4,5 +4,5 @@ allow_anonymous false
|
||||||
listener 1883
|
listener 1883
|
||||||
allow_anonymous false
|
allow_anonymous false
|
||||||
plugin /usr/lib/mosquitto_dynamic_security.so
|
plugin /usr/lib/mosquitto_dynamic_security.so
|
||||||
plugin_opt_config_file /mosquitto/config/dynamic-security.json
|
plugin_opt_config_file /mosquitto/data/dynamic-security.json
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#!/bin/sh
|
#!/bin/ash
|
||||||
|
|
||||||
wait_for_netmaker() {
|
wait_for_netmaker() {
|
||||||
|
echo "SERVER: ${NETMAKER_SERVER_HOST}"
|
||||||
until curl --output /dev/null --silent --fail --head \
|
until curl --output /dev/null --silent --fail --head \
|
||||||
--location "${NETMAKER_SERVER_HOST}/api/server/health"; do
|
--location "${NETMAKER_SERVER_HOST}/api/server/health"; do
|
||||||
echo "Waiting for netmaker server to startup"
|
echo "Waiting for netmaker server to startup"
|
||||||
|
@ -8,10 +9,15 @@ wait_for_netmaker() {
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
main() {
|
main(){
|
||||||
# wait for netmaker to startup
|
# wait for netmaker to startup
|
||||||
apk add curl
|
apk add curl
|
||||||
wait_for_netmaker
|
wait_for_netmaker
|
||||||
|
echo "Starting MQ..."
|
||||||
|
# Run the main container command.
|
||||||
|
/docker-entrypoint.sh
|
||||||
|
/usr/sbin/mosquitto -c /mosquitto/config/mosquitto.conf
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
main "${@}"
|
main "${@}"
|
|
@ -222,6 +222,11 @@ func genKeyName() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func GenKey() string {
|
func GenKey() string {
|
||||||
|
entropy, _ := rand.Int(rand.Reader, maxentropy)
|
||||||
|
return entropy.Text(16)[:16]
|
||||||
|
}
|
||||||
|
|
||||||
|
func GenPassWord() string {
|
||||||
entropy, _ := rand.Int(rand.Reader, maxentropy)
|
entropy, _ := rand.Int(rand.Reader, maxentropy)
|
||||||
return entropy.Text(62)[:64]
|
return entropy.Text(62)[:64]
|
||||||
}
|
}
|
||||||
|
|
127
mq/dynsec.go
127
mq/dynsec.go
|
@ -9,12 +9,88 @@ import (
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
mqtt "github.com/eclipse/paho.mqtt.golang"
|
mqtt "github.com/eclipse/paho.mqtt.golang"
|
||||||
|
"github.com/gravitl/netmaker/functions"
|
||||||
"github.com/gravitl/netmaker/logger"
|
"github.com/gravitl/netmaker/logger"
|
||||||
"github.com/gravitl/netmaker/logic"
|
"github.com/gravitl/netmaker/logic"
|
||||||
|
"github.com/gravitl/netmaker/netclient/ncutils"
|
||||||
"github.com/gravitl/netmaker/servercfg"
|
"github.com/gravitl/netmaker/servercfg"
|
||||||
"golang.org/x/crypto/pbkdf2"
|
"golang.org/x/crypto/pbkdf2"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
dynamicSecurityFile = "dynamic-security.json"
|
||||||
|
dynConfig = dynJSON{
|
||||||
|
Clients: []client{
|
||||||
|
{
|
||||||
|
Username: "Netmaker-Admin",
|
||||||
|
TextName: "netmaker admin user",
|
||||||
|
Password: "",
|
||||||
|
Salt: "",
|
||||||
|
Iterations: 0,
|
||||||
|
Roles: []clientRole{
|
||||||
|
{
|
||||||
|
Rolename: "admin",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Username: "Netmaker-Server",
|
||||||
|
TextName: "netmaker server user",
|
||||||
|
Password: "",
|
||||||
|
Salt: "",
|
||||||
|
Iterations: 0,
|
||||||
|
Roles: []clientRole{},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Username: "netmaker-exporter",
|
||||||
|
TextName: "netmaker metrics exporter",
|
||||||
|
Password: "yl7HZglF4CvCxgjPLLIYc73LRtjEwp2/SAEQXeW5Ta1Dl4RoLN5/gjqiv8xmue+F9LfRk8KICkNbhSYuEfJ7ww==",
|
||||||
|
Salt: "veLl9eN02i+hKkyT",
|
||||||
|
Iterations: 0,
|
||||||
|
Roles: []clientRole{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Roles: []role{
|
||||||
|
{
|
||||||
|
Rolename: "admin",
|
||||||
|
Acls: []Acl{
|
||||||
|
{
|
||||||
|
AclType: "publishClientSend",
|
||||||
|
Topic: "$CONTROL/dynamic-security/#",
|
||||||
|
Allow: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
AclType: "publishClientReceive",
|
||||||
|
Topic: "$CONTROL/dynamic-security/#",
|
||||||
|
Allow: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
AclType: "subscribePattern",
|
||||||
|
Topic: "$CONTROL/dynamic-security/#",
|
||||||
|
Allow: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
AclType: "publishClientReceive",
|
||||||
|
Topic: "$SYS/#",
|
||||||
|
Allow: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
AclType: "subscribePattern",
|
||||||
|
Topic: "$SYS/#",
|
||||||
|
Allow: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
DefaultAcl: defaultAccessAcl{
|
||||||
|
PublishClientSend: true,
|
||||||
|
PublishClientReceive: true,
|
||||||
|
Subscribe: true,
|
||||||
|
Unsubscribe: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
const DynamicSecSubTopic = "$CONTROL/dynamic-security/#"
|
const DynamicSecSubTopic = "$CONTROL/dynamic-security/#"
|
||||||
const DynamicSecPubTopic = "$CONTROL/dynamic-security/v1"
|
const DynamicSecPubTopic = "$CONTROL/dynamic-security/v1"
|
||||||
|
|
||||||
|
@ -37,29 +113,32 @@ var (
|
||||||
ModifyClientCmd = "modifyClient"
|
ModifyClientCmd = "modifyClient"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type dynJSON struct {
|
||||||
|
Clients []client `json:"clients"`
|
||||||
|
Roles []role `json:"roles"`
|
||||||
|
DefaultAcl defaultAccessAcl `json:"defaultACLAccess"`
|
||||||
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
mqAdminUserName string = "Netmaker-Admin"
|
mqAdminUserName string = "Netmaker-Admin"
|
||||||
mqNetmakerServerUserName string = "Netmaker-Server"
|
mqNetmakerServerUserName string = "Netmaker-Server"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type clientRole struct {
|
||||||
|
Rolename string `json:"rolename"`
|
||||||
|
}
|
||||||
type client struct {
|
type client struct {
|
||||||
Username string `json:"username"`
|
Username string `json:"username"`
|
||||||
TextName string `json:"textName"`
|
TextName string `json:"textName"`
|
||||||
Password string `json:"password"`
|
Password string `json:"password"`
|
||||||
Salt string `json:"salt"`
|
Salt string `json:"salt"`
|
||||||
Iterations int `json:"iterations"`
|
Iterations int `json:"iterations"`
|
||||||
Roles []struct {
|
Roles []clientRole `json:"roles"`
|
||||||
Rolename string `json:"rolename"`
|
|
||||||
} `json:"roles"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type role struct {
|
type role struct {
|
||||||
Rolename string `json:"rolename"`
|
Rolename string `json:"rolename"`
|
||||||
Acls []struct {
|
Acls []Acl `json:"acls"`
|
||||||
Acltype string `json:"acltype"`
|
|
||||||
Topic string `json:"topic"`
|
|
||||||
Allow bool `json:"allow"`
|
|
||||||
} `json:"acls"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type defaultAccessAcl struct {
|
type defaultAccessAcl struct {
|
||||||
|
@ -120,34 +199,26 @@ func encodePasswordToPBKDF2(password string, salt string, iterations int, keyLen
|
||||||
}
|
}
|
||||||
|
|
||||||
func Configure() error {
|
func Configure() error {
|
||||||
file := "/root/dynamic-security.json"
|
|
||||||
b, err := os.ReadFile(file)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
c := dynCnf{}
|
|
||||||
err = json.Unmarshal(b, &c)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
password := servercfg.GetMqAdminPassword()
|
password := servercfg.GetMqAdminPassword()
|
||||||
if password == "" {
|
if password == "" {
|
||||||
return errors.New("MQ admin password not provided")
|
return errors.New("MQ admin password not provided")
|
||||||
}
|
}
|
||||||
for i, cI := range c.Clients {
|
for i, cI := range dynConfig.Clients {
|
||||||
if cI.Username == mqAdminUserName || cI.Username == mqNetmakerServerUserName {
|
if cI.Username == mqAdminUserName || cI.Username == mqNetmakerServerUserName {
|
||||||
salt := logic.RandomString(12)
|
salt := logic.RandomString(12)
|
||||||
hashed := encodePasswordToPBKDF2(password, salt, 101, 64)
|
hashed := encodePasswordToPBKDF2(password, salt, 101, 64)
|
||||||
cI.Password = hashed
|
cI.Password = hashed
|
||||||
|
cI.Iterations = 101
|
||||||
cI.Salt = base64.StdEncoding.EncodeToString([]byte(salt))
|
cI.Salt = base64.StdEncoding.EncodeToString([]byte(salt))
|
||||||
c.Clients[i] = cI
|
dynConfig.Clients[i] = cI
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
data, err := json.MarshalIndent(c, "", " ")
|
data, err := json.MarshalIndent(dynConfig, "", " ")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return os.WriteFile(file, data, 0755)
|
path := functions.GetNetmakerPath() + ncutils.GetSeparator() + dynamicSecurityFile
|
||||||
|
return os.WriteFile(path, data, 0755)
|
||||||
}
|
}
|
||||||
|
|
||||||
func PublishEventToDynSecTopic(event DynSecAction) error {
|
func PublishEventToDynSecTopic(event DynSecAction) error {
|
||||||
|
@ -157,7 +228,7 @@ func PublishEventToDynSecTopic(event DynSecAction) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if token := mqAdminClient.Publish(DynamicSecPubTopic, 2, false, d); token.Error() != nil {
|
if token := mqAdminClient.Publish(DynamicSecPubTopic, 2, false, d); token.Error() != nil {
|
||||||
return err
|
return token.Error()
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -199,7 +199,7 @@ func JoinNetwork(cfg *config.ClientConfig, privateKey string) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if cfg.Node.Password == "" {
|
if cfg.Node.Password == "" {
|
||||||
cfg.Node.Password = logic.GenKey()
|
cfg.Node.Password = logic.GenPassWord()
|
||||||
}
|
}
|
||||||
//check if ListenPort was set on command line
|
//check if ListenPort was set on command line
|
||||||
if cfg.Node.ListenPort != 0 {
|
if cfg.Node.ListenPort != 0 {
|
||||||
|
|
|
@ -115,7 +115,6 @@ func checkin(currentRun int) {
|
||||||
config.Write(&nodeCfg, nodeCfg.Network)
|
config.Write(&nodeCfg, nodeCfg.Network)
|
||||||
}
|
}
|
||||||
Hello(&nodeCfg)
|
Hello(&nodeCfg)
|
||||||
checkCertExpiry(&nodeCfg)
|
|
||||||
if currentRun >= 5 && nodeCfg.Server.Is_EE {
|
if currentRun >= 5 && nodeCfg.Server.Is_EE {
|
||||||
logger.Log(0, "collecting metrics for node", nodeCfg.Node.Name)
|
logger.Log(0, "collecting metrics for node", nodeCfg.Node.Name)
|
||||||
publishMetrics(&nodeCfg)
|
publishMetrics(&nodeCfg)
|
||||||
|
|
|
@ -80,7 +80,7 @@ COREDNS_IP=$(ip route get 1 | sed -n 's/^.*src \([0-9.]*\) .*$/\1/p')
|
||||||
SERVER_PUBLIC_IP=$(curl -s ifconfig.me)
|
SERVER_PUBLIC_IP=$(curl -s ifconfig.me)
|
||||||
MASTER_KEY=$(tr -dc A-Za-z0-9 </dev/urandom | head -c 30 ; echo '')
|
MASTER_KEY=$(tr -dc A-Za-z0-9 </dev/urandom | head -c 30 ; echo '')
|
||||||
EMAIL="$(echo $RANDOM | md5sum | head -c 32)@email.com"
|
EMAIL="$(echo $RANDOM | md5sum | head -c 32)@email.com"
|
||||||
|
MQ_ADMIN_PASSWORD=$(tr -dc A-Za-z0-9 </dev/urandom | head -c 30 ; echo '')
|
||||||
if [ -n "$domain" ]; then
|
if [ -n "$domain" ]; then
|
||||||
NETMAKER_BASE_DOMAIN=$domain
|
NETMAKER_BASE_DOMAIN=$domain
|
||||||
fi
|
fi
|
||||||
|
@ -139,7 +139,7 @@ sed -i "s/SERVER_PUBLIC_IP/$SERVER_PUBLIC_IP/g" /root/docker-compose.yml
|
||||||
sed -i "s/COREDNS_IP/$COREDNS_IP/g" /root/docker-compose.yml
|
sed -i "s/COREDNS_IP/$COREDNS_IP/g" /root/docker-compose.yml
|
||||||
sed -i "s/REPLACE_MASTER_KEY/$MASTER_KEY/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/docker-compose.yml
|
sed -i "s/YOUR_EMAIL/$EMAIL/g" /root/docker-compose.yml
|
||||||
|
sed -i "s/REPLACE_MQ_ADMIN_PASSWORD/$MQ_ADMIN_PASSWORD/g" /root/docker-compose.yml
|
||||||
echo "starting containers..."
|
echo "starting containers..."
|
||||||
|
|
||||||
docker-compose -f /root/docker-compose.yml up -d
|
docker-compose -f /root/docker-compose.yml up -d
|
||||||
|
|
Loading…
Add table
Reference in a new issue