mirror of
https://github.com/gravitl/netmaker.git
synced 2024-09-20 15:26:04 +08:00
Merge branch 'develop' into NET-39/nm-quick-refactor
# Conflicts: # docker/Caddyfile # scripts/nm-quick.sh
This commit is contained in:
commit
a97e27cd6c
1
.github/ISSUE_TEMPLATE/bug-report.yml
vendored
1
.github/ISSUE_TEMPLATE/bug-report.yml
vendored
|
@ -31,6 +31,7 @@ body:
|
|||
label: Version
|
||||
description: What version are you running?
|
||||
options:
|
||||
- v0.19.0
|
||||
- v0.18.7
|
||||
- v0.18.6
|
||||
- v0.18.5
|
||||
|
|
14
.github/workflows/deletedroplets.yml
vendored
14
.github/workflows/deletedroplets.yml
vendored
|
@ -23,7 +23,7 @@ jobs:
|
|||
webhook_token: ${{ secrets.DISCORD_WEBHOOK_TOKEN }}
|
||||
color: "#42f545"
|
||||
username: "GitHub Bot"
|
||||
message: " ${{ github.event.workflow_run.name }} was successful"
|
||||
message: "${{ github.respository }}: ${{ github.event.workflow_run.name }} was successful"
|
||||
file: ./results/results.log
|
||||
- name: discord server message
|
||||
uses: appleboy/discord-action@master
|
||||
|
@ -32,9 +32,10 @@ jobs:
|
|||
webhook_token: ${{ secrets.DISCORD_WEBHOOK_TOKEN }}
|
||||
color: "#42f545"
|
||||
username: "GitHub Bot"
|
||||
message: "droplets from this workflow will be deleted in 15 min"
|
||||
message: "droplets from this workflow (tag ${{ github.event.workflow_run.id }}-{{ $github.event.workflow_run.run_number }}) will be deleted in 15 min"
|
||||
file: ./server/serverinfo.txt
|
||||
- name: delete droplets
|
||||
if: success() || failure()
|
||||
run: |
|
||||
sleep 15m
|
||||
curl -X GET \
|
||||
|
@ -59,18 +60,18 @@ jobs:
|
|||
with:
|
||||
webhook_id: ${{ secrets.DISCORD_WEBHOOK_ID }}
|
||||
webhook_token: ${{ secrets.DISCORD_WEBHOOK_TOKEN }}
|
||||
color: "#42f545"
|
||||
color: "#990000"
|
||||
username: "GitHub Bot"
|
||||
message: " ${{ github.event.workflow_run.name }} failed"
|
||||
message: "${{ github.respository }}: ${{ github.event.workflow_run.name }} failed"
|
||||
file: ./results/results.log
|
||||
- name: discord server message
|
||||
uses: appleboy/discord-action@master
|
||||
with:
|
||||
webhook_id: ${{ secrets.DISCORD_WEBHOOK_ID }}
|
||||
webhook_token: ${{ secrets.DISCORD_WEBHOOK_TOKEN }}
|
||||
color: "#42f545"
|
||||
color: "#990000"
|
||||
username: "GitHub Bot"
|
||||
message: "droplets from this workflow will be deleted in 6 hours"
|
||||
message: "droplets from this workflow (tag ${{ github.event.workflow_run.id }}-{{ $github.event.workflow_run.run_number }}) will be deleted in 6 hours"
|
||||
file: ./server/serverinfo.txt
|
||||
- name: discord error message
|
||||
uses: appleboy/discord-action@master
|
||||
|
@ -82,6 +83,7 @@ jobs:
|
|||
message: "errors from ${{ github.event.workflow_run.name }}"
|
||||
file: ./results/errors.log
|
||||
- name: delete droplets
|
||||
if: success() || failure()
|
||||
run: |
|
||||
sleep 6h
|
||||
curl -X GET \
|
||||
|
|
|
@ -6,7 +6,7 @@ COPY . .
|
|||
|
||||
RUN GOOS=linux CGO_ENABLED=1 go build -ldflags="-s -w " -tags ${tags} .
|
||||
# RUN go build -tags=ee . -o netmaker main.go
|
||||
FROM alpine:3.16.2
|
||||
FROM alpine:3.17.2
|
||||
|
||||
# add a c lib
|
||||
# set the working directory
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#first stage - builder
|
||||
FROM alpine:3.15.2
|
||||
FROM alpine:3.17.2
|
||||
ARG version
|
||||
WORKDIR /app
|
||||
COPY ./netmaker /root/netmaker
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
<p align="center">
|
||||
<a href="https://github.com/gravitl/netmaker/releases">
|
||||
<img src="https://img.shields.io/badge/Version-0.18.7-informational?style=flat-square" />
|
||||
<img src="https://img.shields.io/badge/Version-0.19.0-informational?style=flat-square" />
|
||||
</a>
|
||||
<a href="https://hub.docker.com/r/gravitl/netmaker/tags">
|
||||
<img src="https://img.shields.io/docker/pulls/gravitl/netmaker?label=downloads" />
|
||||
|
|
|
@ -3,7 +3,7 @@ version: "3.4"
|
|||
services:
|
||||
netmaker:
|
||||
container_name: netmaker
|
||||
image: gravitl/netmaker:v0.18.7
|
||||
image: gravitl/netmaker:v0.19.0
|
||||
restart: on-failure
|
||||
volumes:
|
||||
- dnsconfig:/root/config/dnsconfig
|
||||
|
@ -36,7 +36,7 @@ services:
|
|||
- "3478:3478/udp"
|
||||
netmaker-ui:
|
||||
container_name: netmaker-ui
|
||||
image: gravitl/netmaker-ui:v0.18.7
|
||||
image: gravitl/netmaker-ui:v0.19.0
|
||||
depends_on:
|
||||
- netmaker
|
||||
links:
|
||||
|
|
|
@ -33,6 +33,12 @@ services:
|
|||
LICENSE_KEY: "YOUR_LICENSE_KEY"
|
||||
NETMAKER_ACCOUNT_ID: "YOUR_ACCOUNT_ID"
|
||||
DEFAULT_PROXY_MODE: "off"
|
||||
TURN_SERVER_HOST: "turn.NETMAKER_BASE_DOMAIN"
|
||||
TURN_SERVER_API_HOST: "https://turnapi.NETMAKER_BASE_DOMAIN"
|
||||
TURN_PORT: "3479"
|
||||
TURN_USERNAME: "REPLACE_TURN_USERNAME"
|
||||
TURN_PASSWORD: "REPLACE_TURN_PASSWORD"
|
||||
USE_TURN: "true"
|
||||
ports:
|
||||
- "3478:3478/udp"
|
||||
netmaker-ui:
|
||||
|
@ -119,6 +125,21 @@ services:
|
|||
API_PORT: "8085"
|
||||
LICENSE_KEY: "YOUR_LICENSE_KEY"
|
||||
PROMETHEUS_HOST: https://prometheus.NETMAKER_BASE_DOMAIN
|
||||
turn:
|
||||
container_name: turn
|
||||
image: gravitl/turnserver:v1.0.0
|
||||
network_mode: "host"
|
||||
volumes:
|
||||
- turn_server:/etc/config
|
||||
environment:
|
||||
DEBUG_MODE: "off"
|
||||
VERBOSITY: "1"
|
||||
TURN_PORT: "3479"
|
||||
TURN_API_PORT: "8089"
|
||||
CORS_ALLOWED_ORIGIN: "*"
|
||||
TURN_SERVER_HOST: "turn.NETMAKER_BASE_DOMAIN"
|
||||
USERNAME: "REPLACE_TURN_USERNAME"
|
||||
PASSWORD: "REPLACE_TURN_PASSWORD"
|
||||
volumes:
|
||||
caddy_data: {}
|
||||
caddy_conf: {}
|
||||
|
@ -127,3 +148,4 @@ volumes:
|
|||
mosquitto_logs: {}
|
||||
prometheus_data: {}
|
||||
grafana_data: {}
|
||||
turn_server: {}
|
||||
|
|
|
@ -3,7 +3,7 @@ version: "3.4"
|
|||
services:
|
||||
netclient:
|
||||
container_name: netclient
|
||||
image: 'gravitl/netclient:v0.18.7'
|
||||
image: 'gravitl/netclient:v0.19.0'
|
||||
hostname: netmaker-1
|
||||
network_mode: host
|
||||
restart: on-failure
|
||||
|
|
|
@ -40,6 +40,12 @@ services:
|
|||
AZURE_TENANT: "" # "<only for azure, you may optionally specify the tenant for the OAuth>"
|
||||
OIDC_ISSUER: "" # https://oidc.yourprovider.com - URL of oidc provider
|
||||
DEFAULT_PROXY_MODE: "off" # if ON, all new clients will enable proxy by default if OFF, all new clients will disable proxy by default, if AUTO, stick with the existing logic for NAT detection
|
||||
TURN_SERVER_HOST: "turn.NETMAKER_BASE_DOMAIN" # domain for your turn server
|
||||
TURN_SERVER_API_HOST: "https://turnapi.NETMAKER_BASE_DOMAIN" # domain of the turn api server
|
||||
TURN_PORT: "3479" # port to access turn server
|
||||
TURN_USERNAME: "REPLACE_TURN_USERNAME" # the username to set for turn api access
|
||||
TURN_PASSWORD: "REPLACE_TURN_PASSWORD" # the password to set for turn api access
|
||||
USE_TURN: "true" #config for using turn, accepts either true/false
|
||||
ports:
|
||||
- "3478:3478/udp" # the stun port
|
||||
netmaker-ui: # The Netmaker UI Component
|
||||
|
@ -89,6 +95,22 @@ services:
|
|||
ports:
|
||||
- "1883:1883"
|
||||
- "8883:8883"
|
||||
turn:
|
||||
container_name: turn
|
||||
image: gravitl/turnserver:v1.0.0
|
||||
network_mode: "host"
|
||||
volumes:
|
||||
- turn_server:/etc/config
|
||||
environment:
|
||||
DEBUG_MODE: "off"
|
||||
VERBOSITY: "1"
|
||||
TURN_PORT: "3479"
|
||||
TURN_API_PORT: "8089"
|
||||
CORS_ALLOWED_ORIGIN: "*"
|
||||
TURN_SERVER_HOST: "turn.NETMAKER_BASE_DOMAIN"
|
||||
USERNAME: "REPLACE_TURN_USERNAME"
|
||||
PASSWORD: "REPLACE_TURN_PASSWORD"
|
||||
USE_TURN: "true"
|
||||
volumes:
|
||||
caddy_data: {} # runtime data for caddy
|
||||
caddy_conf: {} # configuration file for Caddy
|
||||
|
@ -96,3 +118,4 @@ volumes:
|
|||
sqldata: {} # storage for embedded sqlite
|
||||
dnsconfig: {} # storage for coredns
|
||||
mosquitto_logs: {} # storage for mqtt logs
|
||||
turn_server: {}
|
|
@ -30,6 +30,12 @@ services:
|
|||
MQ_USERNAME: "REPLACE_MQ_USERNAME"
|
||||
STUN_PORT: "3478"
|
||||
DEFAULT_PROXY_MODE: "off"
|
||||
TURN_SERVER_HOST: "turn.NETMAKER_BASE_DOMAIN"
|
||||
TURN_SERVER_API_HOST: "https://turnapi.NETMAKER_BASE_DOMAIN"
|
||||
TURN_PORT: "3479"
|
||||
TURN_USERNAME: "REPLACE_TURN_USERNAME"
|
||||
TURN_PASSWORD: "REPLACE_TURN_PASSWORD"
|
||||
USE_TURN: "true"
|
||||
ports:
|
||||
- "3478:3478/udp"
|
||||
netmaker-ui:
|
||||
|
@ -46,6 +52,8 @@ services:
|
|||
image: caddy:2.6.2
|
||||
container_name: caddy
|
||||
restart: unless-stopped
|
||||
extra_hosts:
|
||||
- "host.docker.internal:host-gateway"
|
||||
volumes:
|
||||
- /root/Caddyfile:/etc/caddy/Caddyfile
|
||||
- /root/fullchain.pem:/root/fullchain.pem
|
||||
|
@ -78,9 +86,25 @@ services:
|
|||
- /root/mosquitto.conf:/mosquitto/config/mosquitto.conf
|
||||
- /root/wait.sh:/mosquitto/config/wait.sh
|
||||
- mosquitto_logs:/mosquitto/log
|
||||
turn:
|
||||
container_name: turn
|
||||
image: gravitl/turnserver:v1.0.0
|
||||
network_mode: "host"
|
||||
volumes:
|
||||
- turn_server:/etc/config
|
||||
environment:
|
||||
DEBUG_MODE: "off"
|
||||
VERBOSITY: "1"
|
||||
TURN_PORT: "3479"
|
||||
TURN_API_PORT: "8089"
|
||||
CORS_ALLOWED_ORIGIN: "*"
|
||||
TURN_SERVER_HOST: "turn.NETMAKER_BASE_DOMAIN"
|
||||
USERNAME: "REPLACE_TURN_USERNAME"
|
||||
PASSWORD: "REPLACE_TURN_PASSWORD"
|
||||
volumes:
|
||||
caddy_data: {}
|
||||
caddy_conf: {}
|
||||
sqldata: {}
|
||||
dnsconfig: {}
|
||||
mosquitto_logs: {}
|
||||
turn_server: {}
|
||||
|
|
|
@ -76,6 +76,12 @@ type ServerConfig struct {
|
|||
StunList string `yaml:"stun_list"`
|
||||
Proxy string `yaml:"proxy"`
|
||||
DefaultProxyMode ProxyMode `yaml:"defaultproxymode"`
|
||||
TurnServer string `yaml:"turn_server"`
|
||||
TurnApiServer string `yaml:"turn_api_server"`
|
||||
TurnPort int `yaml:"turn_port"`
|
||||
TurnUserName string `yaml:"turn_username"`
|
||||
TurnPassword string `yaml:"turn_password"`
|
||||
UseTurn bool `yaml:"use_turn"`
|
||||
}
|
||||
|
||||
// ProxyMode - default proxy mode for server
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
//
|
||||
// Schemes: https
|
||||
// BasePath: /
|
||||
// Version: 0.18.7
|
||||
// Version: 0.19.0
|
||||
// Host: netmaker.io
|
||||
//
|
||||
// Consumes:
|
||||
|
|
|
@ -153,6 +153,13 @@ func handleHostRegister(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
hostExists := false
|
||||
// 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
|
||||
if hostExists = logic.HostExists(&newHost); hostExists && len(enrollmentKey.Networks) == 0 {
|
||||
logger.Log(0, "host", newHost.ID.String(), newHost.Name, "attempted to re-register with no networks")
|
||||
|
|
|
@ -30,6 +30,7 @@ func hostHandlers(r *mux.Router) {
|
|||
r.HandleFunc("/api/hosts/{hostid}/relay", logic.SecurityCheck(false, http.HandlerFunc(deleteHostRelay))).Methods(http.MethodDelete)
|
||||
r.HandleFunc("/api/hosts/adm/authenticate", authenticateHost).Methods(http.MethodPost)
|
||||
r.HandleFunc("/api/v1/host", authorize(true, false, "host", http.HandlerFunc(pull))).Methods(http.MethodGet)
|
||||
r.HandleFunc("/api/v1/host/{hostid}/signalpeer", authorize(true, false, "host", http.HandlerFunc(signalPeer))).Methods(http.MethodPost)
|
||||
r.HandleFunc("/api/v1/auth-register/host", socketHandler)
|
||||
}
|
||||
|
||||
|
@ -94,6 +95,13 @@ func pull(w http.ResponseWriter, r *http.Request) {
|
|||
if servercfg.GetBrokerType() == servercfg.EmqxBrokerType {
|
||||
serverConf.MQUserName = hostID
|
||||
}
|
||||
key, keyErr := logic.RetrievePublicTrafficKey()
|
||||
if keyErr != nil {
|
||||
logger.Log(0, "error retrieving key:", keyErr.Error())
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
|
||||
return
|
||||
}
|
||||
serverConf.TrafficKey = key
|
||||
response := models.HostPull{
|
||||
Host: *host,
|
||||
ServerConfig: serverConf,
|
||||
|
@ -450,6 +458,72 @@ func authenticateHost(response http.ResponseWriter, request *http.Request) {
|
|||
response.Write(successJSONResponse)
|
||||
}
|
||||
|
||||
// swagger:route POST /api/hosts/{hostid}/signalpeer signalPeer
|
||||
//
|
||||
// send signal to peer.
|
||||
//
|
||||
// Schemes: https
|
||||
//
|
||||
// Security:
|
||||
// oauth
|
||||
//
|
||||
// Responses:
|
||||
// 200: signal
|
||||
func signalPeer(w http.ResponseWriter, r *http.Request) {
|
||||
var params = mux.Vars(r)
|
||||
hostid := params["hostid"]
|
||||
// confirm host exists
|
||||
_, err := logic.GetHost(hostid)
|
||||
if err != nil {
|
||||
logger.Log(0, r.Header.Get("user"), "failed to get host:", err.Error())
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
|
||||
return
|
||||
}
|
||||
var signal models.Signal
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
err = json.NewDecoder(r.Body).Decode(&signal)
|
||||
if err != nil {
|
||||
logger.Log(0, r.Header.Get("user"), "error decoding request body: ", err.Error())
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
|
||||
return
|
||||
}
|
||||
if signal.ToHostPubKey == "" || signal.TurnRelayEndpoint == "" {
|
||||
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
|
||||
}
|
||||
hosts, err := logic.GetAllHosts()
|
||||
if err != nil {
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
|
||||
return
|
||||
}
|
||||
// push the signal to host through mq
|
||||
found := false
|
||||
for _, hostI := range hosts {
|
||||
if hostI.PublicKey.String() == signal.ToHostPubKey {
|
||||
// found host publish message and break
|
||||
found = true
|
||||
err = mq.HostUpdate(&models.HostUpdate{
|
||||
Action: models.SignalHost,
|
||||
Host: hostI,
|
||||
Signal: signal,
|
||||
})
|
||||
if err != nil {
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("failed to publish signal to peer: "+err.Error()), "badrequest"))
|
||||
return
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("failed to signal, peer not found"), "badrequest"))
|
||||
return
|
||||
}
|
||||
w.WriteHeader(http.StatusOK)
|
||||
json.NewEncoder(w).Encode(signal)
|
||||
}
|
||||
|
||||
// swagger:route POST /api/hosts/keys host updateAllKeys
|
||||
//
|
||||
// Update keys for a network.
|
||||
|
|
|
@ -32,6 +32,18 @@ https://stun.NETMAKER_BASE_DOMAIN {
|
|||
reverse_proxy netmaker:3478
|
||||
}
|
||||
|
||||
# TURN
|
||||
https://turn.NETMAKER_BASE_DOMAIN {
|
||||
tls /root/fullchain.pem /root/privkey.pem
|
||||
reverse_proxy host.docker.internal:3479
|
||||
}
|
||||
|
||||
#TURN API
|
||||
https://turnapi.NETMAKER_BASE_DOMAIN {
|
||||
tls /root/fullchain.pem /root/privkey.pem
|
||||
reverse_proxy http://host.docker.internal:8089
|
||||
}
|
||||
|
||||
# MQ
|
||||
wss://broker.NETMAKER_BASE_DOMAIN {
|
||||
tls /root/fullchain.pem /root/privkey.pem
|
||||
|
|
|
@ -50,6 +50,16 @@ https://stun.NETMAKER_BASE_DOMAIN {
|
|||
reverse_proxy netmaker:3478
|
||||
}
|
||||
|
||||
# TURN
|
||||
https://turn.NETMAKER_BASE_DOMAIN {
|
||||
reverse_proxy host.docker.internal:3479
|
||||
}
|
||||
|
||||
#TURN API
|
||||
https://turnapi.NETMAKER_BASE_DOMAIN {
|
||||
reverse_proxy http://host.docker.internal:8089
|
||||
}
|
||||
|
||||
# MQ
|
||||
wss://broker.NETMAKER_BASE_DOMAIN {
|
||||
reverse_proxy ws://mq:8883
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
FROM golang:1.19-alpine3.16
|
||||
FROM golang:1.19.6-alpine3.17
|
||||
ARG version
|
||||
RUN apk add build-base
|
||||
WORKDIR /app
|
||||
|
|
7
go.mod
7
go.mod
|
@ -4,12 +4,12 @@ go 1.19
|
|||
|
||||
require (
|
||||
github.com/eclipse/paho.mqtt.golang v1.4.2
|
||||
github.com/go-playground/validator/v10 v10.12.0
|
||||
github.com/go-playground/validator/v10 v10.13.0
|
||||
github.com/golang-jwt/jwt/v4 v4.5.0
|
||||
github.com/google/uuid v1.3.0
|
||||
github.com/gorilla/handlers v1.5.1
|
||||
github.com/gorilla/mux v1.8.0
|
||||
github.com/lib/pq v1.10.8
|
||||
github.com/lib/pq v1.10.9
|
||||
github.com/mattn/go-sqlite3 v1.14.16
|
||||
github.com/rqlite/gorqlite v0.0.0-20210514125552-08ff1e76b22f
|
||||
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e
|
||||
|
@ -41,6 +41,7 @@ require (
|
|||
)
|
||||
|
||||
require (
|
||||
github.com/devilcove/httpclient v0.6.0
|
||||
github.com/guumaster/tablewriter v0.0.10
|
||||
github.com/matryer/is v1.4.1
|
||||
github.com/olekukonko/tablewriter v0.0.5
|
||||
|
@ -66,7 +67,7 @@ require (
|
|||
github.com/google/go-cmp v0.5.9 // indirect
|
||||
github.com/hashicorp/go-version v1.6.0
|
||||
github.com/josharian/native v1.0.0 // indirect
|
||||
github.com/leodido/go-urn v1.2.2 // indirect
|
||||
github.com/leodido/go-urn v1.2.3 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.13 // indirect
|
||||
github.com/mdlayher/genetlink v1.2.0 // indirect
|
||||
github.com/mdlayher/netlink v1.6.0 // indirect
|
||||
|
|
15
go.sum
15
go.sum
|
@ -21,6 +21,8 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3
|
|||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/devilcove/httpclient v0.6.0 h1:M5YAfHeNbu+0QxCiOCo/fKN+Hf0BtF/6aovu3NNgcKk=
|
||||
github.com/devilcove/httpclient v0.6.0/go.mod h1:ctrAO2gRgTT+GxtRdWBp2SMQ+vacuxXlbhmlM4oWhs8=
|
||||
github.com/eclipse/paho.mqtt.golang v1.4.2 h1:66wOzfUHSSI1zamx7jR6yMEI5EuHnT1G6rNA5PM12m4=
|
||||
github.com/eclipse/paho.mqtt.golang v1.4.2/go.mod h1:JGt0RsEwEX+Xa/agj90YJ9d9DH2b7upDZMK9HRbFvCA=
|
||||
github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
||||
|
@ -34,8 +36,8 @@ github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/o
|
|||
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
|
||||
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
|
||||
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
||||
github.com/go-playground/validator/v10 v10.12.0 h1:E4gtWgxWxp8YSxExrQFv5BpCahla0PVF2oTTEYaWQGI=
|
||||
github.com/go-playground/validator/v10 v10.12.0/go.mod h1:hCAPuzYvKdP33pxWa+2+6AIKXEKqjIUyqsNCtbsSJrA=
|
||||
github.com/go-playground/validator/v10 v10.13.0 h1:cFRQdfaSMCOSfGCCLB20MHvuoHb/s5G8L5pu2ppK5AQ=
|
||||
github.com/go-playground/validator/v10 v10.13.0/go.mod h1:dwu7+CG8/CtBiJFZDz4e+5Upb6OLw04gtBYw0mcG/z4=
|
||||
github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg=
|
||||
github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
|
@ -75,10 +77,10 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
|||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/leodido/go-urn v1.2.2 h1:7z68G0FCGvDk646jz1AelTYNYWrTNm0bEcFAo147wt4=
|
||||
github.com/leodido/go-urn v1.2.2/go.mod h1:kUaIbLZWttglzwNuG0pgsh5vuV6u2YcGBYz1hIPjtOQ=
|
||||
github.com/lib/pq v1.10.8 h1:3fdt97i/cwSU83+E0hZTC/Xpc9mTZxc6UWSCRcSbxiE=
|
||||
github.com/lib/pq v1.10.8/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/leodido/go-urn v1.2.3 h1:6BE2vPT0lqoz3fmOesHZiaiFh7889ssCo2GMvLCfiuA=
|
||||
github.com/leodido/go-urn v1.2.3/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4=
|
||||
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
|
||||
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/matryer/is v1.4.1 h1:55ehd8zaGABKLXQUe2awZ99BD/PTc2ls+KV/dXphgEQ=
|
||||
github.com/matryer/is v1.4.1/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU=
|
||||
|
@ -118,7 +120,6 @@ github.com/rqlite/gorqlite v0.0.0-20210514125552-08ff1e76b22f/go.mod h1:UW/gxgQw
|
|||
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/rwtodd/Go.Sed v0.0.0-20210816025313-55464686f9ef/go.mod h1:8AEUvGVi2uQ5b24BIhcr0GCcpd/RNAFWaN2CJFrWIIQ=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e h1:MRM5ITcdelLK2j1vwZ3Je0FKVCfqOLp5zO6trqMLYs0=
|
||||
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e/go.mod h1:XV66xRDqSt+GTGFMVlhk3ULuV0y9ZmzeVGR4mloJI3M=
|
||||
|
|
|
@ -16,7 +16,7 @@ spec:
|
|||
hostNetwork: true
|
||||
containers:
|
||||
- name: netclient
|
||||
image: gravitl/netclient:v0.18.7
|
||||
image: gravitl/netclient:v0.19.0
|
||||
env:
|
||||
- name: TOKEN
|
||||
value: "TOKEN_VALUE"
|
||||
|
|
|
@ -28,7 +28,7 @@ spec:
|
|||
# - "<node label value>"
|
||||
containers:
|
||||
- name: netclient
|
||||
image: gravitl/netclient:v0.18.7
|
||||
image: gravitl/netclient:v0.19.0
|
||||
env:
|
||||
- name: TOKEN
|
||||
value: "TOKEN_VALUE"
|
||||
|
|
|
@ -79,7 +79,7 @@ spec:
|
|||
value: "Kubernetes"
|
||||
- name: VERBOSITY
|
||||
value: "3"
|
||||
image: gravitl/netmaker:v0.18.7
|
||||
image: gravitl/netmaker:v0.19.0
|
||||
imagePullPolicy: Always
|
||||
name: netmaker
|
||||
ports:
|
||||
|
|
|
@ -15,7 +15,7 @@ spec:
|
|||
spec:
|
||||
containers:
|
||||
- name: netmaker-ui
|
||||
image: gravitl/netmaker-ui:v0.18.7
|
||||
image: gravitl/netmaker-ui:v0.19.0
|
||||
ports:
|
||||
- containerPort: 443
|
||||
env:
|
||||
|
|
|
@ -9,7 +9,6 @@ import (
|
|||
|
||||
"github.com/gravitl/netmaker/database"
|
||||
"github.com/gravitl/netmaker/models"
|
||||
"github.com/gravitl/netmaker/netclient/ncutils"
|
||||
)
|
||||
|
||||
// EnrollmentErrors - struct for holding EnrollmentKey error messages
|
||||
|
@ -190,9 +189,9 @@ func getUniqueEnrollmentID() (string, error) {
|
|||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
newID := ncutils.MakeRandomString(models.EnrollmentKeyLength)
|
||||
newID := RandomString(models.EnrollmentKeyLength)
|
||||
for _, ok := currentKeys[newID]; ok; {
|
||||
newID = ncutils.MakeRandomString(models.EnrollmentKeyLength)
|
||||
newID = RandomString(models.EnrollmentKeyLength)
|
||||
}
|
||||
return newID, nil
|
||||
}
|
||||
|
|
|
@ -25,6 +25,9 @@ func CreateEgressGateway(gateway models.EgressGatewayRequest) (models.Node, erro
|
|||
if host.OS != "linux" { // support for other OS to be added
|
||||
return models.Node{}, errors.New(host.OS + " is unsupported for egress gateways")
|
||||
}
|
||||
if host.FirewallInUse == models.FIREWALL_NONE {
|
||||
return models.Node{}, errors.New("firewall is not supported for egress gateways")
|
||||
}
|
||||
for i := len(gateway.Ranges) - 1; i >= 0; i-- {
|
||||
if gateway.Ranges[i] == "::/0" {
|
||||
logger.Log(0, "currently IPv6 internet gateways are not supported", gateway.Ranges[i])
|
||||
|
|
|
@ -1,12 +1,17 @@
|
|||
package logic
|
||||
|
||||
import (
|
||||
"crypto/md5"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"sort"
|
||||
"strconv"
|
||||
|
||||
"github.com/devilcove/httpclient"
|
||||
"github.com/google/uuid"
|
||||
"github.com/gravitl/netmaker/database"
|
||||
"github.com/gravitl/netmaker/logger"
|
||||
|
@ -92,6 +97,13 @@ 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)
|
||||
if err != nil {
|
||||
|
@ -207,11 +219,18 @@ func RemoveHost(h *models.Host) error {
|
|||
if len(h.Nodes) > 0 {
|
||||
return fmt.Errorf("host still has associated nodes")
|
||||
}
|
||||
if servercfg.IsUsingTurn() {
|
||||
DeRegisterHostWithTurn(h.ID.String())
|
||||
}
|
||||
|
||||
return database.DeleteRecord(database.HOSTS_TABLE_NAME, h.ID.String())
|
||||
}
|
||||
|
||||
// RemoveHostByID - removes a given host by id from server
|
||||
func RemoveHostByID(hostID string) error {
|
||||
if servercfg.IsUsingTurn() {
|
||||
DeRegisterHostWithTurn(hostID)
|
||||
}
|
||||
return database.DeleteRecord(database.HOSTS_TABLE_NAME, hostID)
|
||||
}
|
||||
|
||||
|
@ -435,6 +454,57 @@ func GetHostByNodeID(id string) *models.Host {
|
|||
return nil
|
||||
}
|
||||
|
||||
// ConvHostPassToHash - converts password to md5 hash
|
||||
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 {
|
||||
|
|
|
@ -19,10 +19,7 @@ var jwtSecretKey []byte
|
|||
func SetJWTSecret() {
|
||||
currentSecret, jwtErr := FetchJWTSecret()
|
||||
if jwtErr != nil {
|
||||
newValue, err := GenerateCryptoString(64)
|
||||
if err != nil {
|
||||
logger.FatalLog("something went wrong when generating JWT signature")
|
||||
}
|
||||
newValue := RandomString(64)
|
||||
jwtSecretKey = []byte(newValue) // 512 bit random password
|
||||
if err := StoreJWTSecret(string(jwtSecretKey)); err != nil {
|
||||
logger.FatalLog("something went wrong when configuring JWT authentication")
|
||||
|
|
|
@ -97,6 +97,7 @@ func GetProxyUpdateForHost(ctx context.Context, host *models.Host) (models.Proxy
|
|||
Proxy: peerHost.ProxyEnabled,
|
||||
PublicListenPort: int32(GetPeerListenPort(peerHost)),
|
||||
ProxyListenPort: GetProxyListenPort(peerHost),
|
||||
NatType: peerHost.NatType,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,11 +2,10 @@
|
|||
package logic
|
||||
|
||||
import (
|
||||
crand "crypto/rand"
|
||||
"crypto/rand"
|
||||
"encoding/base32"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"math/big"
|
||||
"math/rand"
|
||||
"net"
|
||||
"os"
|
||||
"strings"
|
||||
|
@ -14,6 +13,7 @@ import (
|
|||
|
||||
"github.com/c-robinson/iplib"
|
||||
"github.com/gravitl/netmaker/database"
|
||||
"github.com/gravitl/netmaker/logger"
|
||||
)
|
||||
|
||||
// IsBase64 - checks if a string is in base64 format
|
||||
|
@ -68,32 +68,15 @@ func SetNetworkNodesLastModified(networkName string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// GenerateCryptoString - generates random string of n length
|
||||
func GenerateCryptoString(n int) (string, error) {
|
||||
const chars = "123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-"
|
||||
ret := make([]byte, n)
|
||||
for i := range ret {
|
||||
num, err := crand.Int(crand.Reader, big.NewInt(int64(len(chars))))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
ret[i] = chars[num.Int64()]
|
||||
}
|
||||
|
||||
return string(ret), nil
|
||||
}
|
||||
|
||||
// RandomString - returns a random string in a charset
|
||||
func RandomString(length int) string {
|
||||
const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
|
||||
|
||||
var seededRand *rand.Rand = rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||
|
||||
b := make([]byte, length)
|
||||
for i := range b {
|
||||
b[i] = charset[seededRand.Intn(len(charset))]
|
||||
randombytes := make([]byte, length)
|
||||
_, err := rand.Read(randombytes)
|
||||
if err != nil {
|
||||
logger.Log(0, "random string", err.Error())
|
||||
return ""
|
||||
}
|
||||
return string(b)
|
||||
return base32.StdEncoding.EncodeToString(randombytes)[:length]
|
||||
}
|
||||
|
||||
// StringSliceContains - sees if a string slice contains a string element
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package ncutils
|
||||
package logic
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
@ -7,10 +7,10 @@ import (
|
|||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestMakeRandomString(t *testing.T) {
|
||||
func TestRandomString(t *testing.T) {
|
||||
for testCase := 0; testCase < 100; testCase++ {
|
||||
for size := 2; size < 2058; size++ {
|
||||
if length := len(MakeRandomString(size)); length != size {
|
||||
if length := len(RandomString(size)); length != size {
|
||||
t.Fatalf("expected random string of size %d, got %d instead", size, length)
|
||||
}
|
||||
}
|
||||
|
@ -18,9 +18,9 @@ func TestMakeRandomString(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestMakeRandomStringValid(t *testing.T) {
|
||||
lengthStr := MakeRandomString(10)
|
||||
lengthStr := RandomString(10)
|
||||
assert.Equal(t, len(lengthStr), 10)
|
||||
validMqID := MakeRandomString(23)
|
||||
validMqID := RandomString(23)
|
||||
assert.False(t, strings.Contains(validMqID, "#"))
|
||||
assert.False(t, strings.Contains(validMqID, "!"))
|
||||
assert.False(t, strings.Contains(validMqID, "\""))
|
2
main.go
2
main.go
|
@ -27,7 +27,7 @@ import (
|
|||
stunserver "github.com/gravitl/netmaker/stun-server"
|
||||
)
|
||||
|
||||
var version = "v0.18.7"
|
||||
var version = "v0.19.0"
|
||||
|
||||
// Start DB Connection and start API Request Handler
|
||||
func main() {
|
||||
|
|
|
@ -101,6 +101,8 @@ func ParseBool(s string) bool {
|
|||
type HostMqAction string
|
||||
|
||||
const (
|
||||
// SignalHost - const for host signal action
|
||||
SignalHost = "SIGNAL_HOST"
|
||||
// UpdateHost - constant for host update action
|
||||
UpdateHost = "UPDATE_HOST"
|
||||
// DeleteHost - constant for host delete action
|
||||
|
@ -113,6 +115,8 @@ const (
|
|||
RequestAck = "REQ_ACK"
|
||||
// CheckIn - update last check in times and public address and interfaces
|
||||
CheckIn = "CHECK_IN"
|
||||
// REGISTER_WITH_TURN - registers host with turn server if configured
|
||||
RegisterWithTurn = "REGISTER_WITH_TURN"
|
||||
// UpdateKeys - update wireguard private/public keys
|
||||
UpdateKeys = "UPDATE_KEYS"
|
||||
)
|
||||
|
@ -122,6 +126,22 @@ type HostUpdate struct {
|
|||
Action HostMqAction
|
||||
Host Host
|
||||
Node Node
|
||||
Signal Signal
|
||||
}
|
||||
|
||||
// HostTurnRegister - struct for host turn registration
|
||||
type HostTurnRegister struct {
|
||||
HostID string `json:"host_id"`
|
||||
HostPassHash string `json:"host_pass_hash"`
|
||||
}
|
||||
|
||||
// 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"`
|
||||
Reply bool `json:"reply"`
|
||||
}
|
||||
|
||||
// RegisterMsg - login message struct for hosts to join via SSO login
|
||||
|
|
|
@ -40,17 +40,16 @@ type PeerConf struct {
|
|||
ProxyListenPort int `json:"proxy_listen_port"`
|
||||
IsExtClient bool `json:"is_ext_client"`
|
||||
Address net.IP `json:"address"`
|
||||
ExtInternalIp net.IP `json:"ext_internal_ip"`
|
||||
IsRelayed bool `json:"is_relayed"`
|
||||
RelayedTo *net.UDPAddr `json:"relayed_to"`
|
||||
NatType string `json:"nat_type"`
|
||||
}
|
||||
|
||||
// ProxyManagerPayload - struct for proxy manager payload
|
||||
type ProxyManagerPayload struct {
|
||||
Action ProxyAction `json:"action"`
|
||||
InterfaceName string `json:"interface_name"`
|
||||
Server string `json:"server"`
|
||||
//WgAddr string `json:"wg_addr"`
|
||||
Action ProxyAction `json:"action"`
|
||||
InterfaceName string `json:"interface_name"`
|
||||
Server string `json:"server"`
|
||||
Peers []wgtypes.PeerConfig `json:"peers"`
|
||||
PeerMap map[string]PeerConf `json:"peer_map"`
|
||||
IsIngress bool `json:"is_ingress"`
|
||||
|
|
|
@ -240,6 +240,9 @@ type ServerConfig struct {
|
|||
StunPort int `yaml:"stun_port"`
|
||||
StunList []StunServer `yaml:"stun_list"`
|
||||
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
|
||||
|
|
|
@ -163,6 +163,15 @@ 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 {
|
||||
logger.Log(0, "failed to register host with turn server: ", err.Error())
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if sendPeerUpdate {
|
||||
|
|
4
mq/mq.go
4
mq/mq.go
|
@ -8,7 +8,7 @@ import (
|
|||
|
||||
mqtt "github.com/eclipse/paho.mqtt.golang"
|
||||
"github.com/gravitl/netmaker/logger"
|
||||
"github.com/gravitl/netmaker/netclient/ncutils"
|
||||
"github.com/gravitl/netmaker/logic"
|
||||
"github.com/gravitl/netmaker/servercfg"
|
||||
)
|
||||
|
||||
|
@ -27,7 +27,7 @@ var mqclient mqtt.Client
|
|||
func setMqOptions(user, password string, opts *mqtt.ClientOptions) {
|
||||
broker, _ := servercfg.GetMessageQueueEndpoint()
|
||||
opts.AddBroker(broker)
|
||||
id := ncutils.MakeRandomString(23)
|
||||
id := logic.RandomString(23)
|
||||
opts.ClientID = id
|
||||
opts.SetUsername(user)
|
||||
opts.SetPassword(password)
|
||||
|
|
|
@ -2,7 +2,6 @@ package ncutils
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/rand"
|
||||
"encoding/gob"
|
||||
)
|
||||
|
||||
|
@ -32,16 +31,3 @@ func ConvertBytesToKey(data []byte) (*[32]byte, error) {
|
|||
}
|
||||
return result, err
|
||||
}
|
||||
|
||||
// MakeRandomString - generates a random string of len n
|
||||
func MakeRandomString(n int) string {
|
||||
const validChars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
result := make([]byte, n)
|
||||
if _, err := rand.Reader.Read(result); err != nil {
|
||||
return ""
|
||||
}
|
||||
for i, b := range result {
|
||||
result[i] = validChars[b%byte(len(validChars))]
|
||||
}
|
||||
return string(result)
|
||||
}
|
||||
|
|
14
release.md
14
release.md
|
@ -1,14 +1,20 @@
|
|||
# Netmaker v0.18.7
|
||||
# Netmaker v0.19.0
|
||||
|
||||
## whats new
|
||||
- TURN
|
||||
- dependency updates
|
||||
- internet gateways (0.0.0.0/0) for egress
|
||||
- deprecated editing of network parameters
|
||||
- allow extra ips for extclient (not enabled in UI)
|
||||
|
||||
## whats fixed
|
||||
- nm-quick - determine lastest version from releases
|
||||
- wireguard public/private key rotation
|
||||
- ee-license checks
|
||||
- unbiased random string
|
||||
- get traffic keys on pull
|
||||
- CI updates
|
||||
- install/update script updates
|
||||
- firewall checks
|
||||
-
|
||||
-
|
||||
|
||||
## known issues
|
||||
- Caddy does not handle netmaker exporter well for EE
|
||||
|
|
|
@ -453,6 +453,8 @@ set_install_vars() {
|
|||
echo " api.$NETMAKER_BASE_DOMAIN"
|
||||
echo " broker.$NETMAKER_BASE_DOMAIN"
|
||||
echo " stun.$NETMAKER_BASE_DOMAIN"
|
||||
echo " turn.$NETMAKER_BASE_DOMAIN"
|
||||
echo " turnapi.$NETMAKER_BASE_DOMAIN"
|
||||
|
||||
if [ "$INSTALL_TYPE" = "ee" ]; then
|
||||
echo " prometheus.$NETMAKER_BASE_DOMAIN"
|
||||
|
@ -566,6 +568,51 @@ 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 mq"
|
||||
TURN_USERNAME="netmaker"
|
||||
else
|
||||
TURN_USERNAME="$GET_TURN_USERNAME"
|
||||
fi
|
||||
|
||||
TURN_PASSWORD=$(tr -dc A-Za-z0-9 </dev/urandom | head -c 30 ; echo '')
|
||||
|
||||
if [ -z $AUTO_BUILD ]; then
|
||||
select domain_option in "Auto Generated 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 "-----------------------------------------------------------------"
|
||||
|
@ -623,8 +670,11 @@ install_netmaker() {
|
|||
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_PASSWORD/$MQ_PASSWORD/g" /root/docker-compose.yml
|
||||
sed -i "s/REPLACE_MQ_USERNAME/$MQ_USERNAME/g" /root/docker-compose.yml
|
||||
sed -i "s/REPLACE_MQ_PASSWORD/$MQ_PASSWORD/g" /root/docker-compose.yml
|
||||
sed -i "s/REPLACE_TURN_USERNAME/$TURN_USERNAME/g" /root/docker-compose.yml
|
||||
sed -i "s/REPLACE_TURN_PASSWORD/$TURN_PASSWORD/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
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#!/bin/bash
|
||||
|
||||
LATEST="v0.18.6"
|
||||
LATEST="v0.19.0"
|
||||
INSTALL_PATH="/root"
|
||||
|
||||
trap restore_old_netmaker_instructions
|
||||
|
@ -260,10 +260,12 @@ collect_server_settings() {
|
|||
done
|
||||
|
||||
STUN_DOMAIN="stun.$SERVER_NAME"
|
||||
TURN_DOMAIN="turn.$SERVER_NAME"
|
||||
TURNAPI_DOMAIN="turnapi.$SERVER_NAME"
|
||||
echo "-----------------------------------------------------"
|
||||
echo "Netmaker v0.18 requires a new DNS entry for $STUN_DOMAIN."
|
||||
echo "Please confirm this is added to your DNS provider before continuing"
|
||||
echo "(note: this is not required if using an nip.io address)"
|
||||
echo "Netmaker v0.19 requires new DNS entries for $STUN_DOMAIN, $TURN_DOMAIN, and $TURNAPI_DOMAIN."
|
||||
echo "Please confirm this is added to your DNS provider before continuing."
|
||||
echo "You can skip this step if using a wildcard DNS entry (e.g. *.$SERVER_NAME) or a nip.io address."
|
||||
echo "-----------------------------------------------------"
|
||||
confirm
|
||||
}
|
||||
|
@ -337,6 +339,16 @@ cat <<EOT >> $INSTALL_PATH/Caddyfile
|
|||
https://$STUN_DOMAIN {
|
||||
reverse_proxy netmaker:3478
|
||||
}
|
||||
|
||||
# TURN
|
||||
https://$TURN_DOMAIN {
|
||||
reverse_proxy netmaker:3479
|
||||
}
|
||||
|
||||
#TURN API
|
||||
https://turnapi.$TURNAPI_DOMAIN {
|
||||
reverse_proxy http://host.docker.internal:8089
|
||||
}
|
||||
EOT
|
||||
|
||||
}
|
||||
|
@ -385,10 +397,55 @@ set_mq_credentials() {
|
|||
done
|
||||
}
|
||||
|
||||
# set_turn_credentials - sets mq credentials
|
||||
set_turn_credentials() {
|
||||
|
||||
unset GET_TURN_USERNAME
|
||||
unset GET_TURN_PASSWORD
|
||||
unset CONFIRM_TURN_PASSWORD
|
||||
echo "Enter Credentials For TURN..."
|
||||
read -p "TURN Username (click 'enter' to use 'netmaker'): " GET_TURN_USERNAME
|
||||
if [ -z "$GET_TURN_USERNAME" ]; then
|
||||
echo "using default username for turn"
|
||||
TURN_USERNAME="netmaker"
|
||||
else
|
||||
TURN_USERNAME="$GET_TURN_USERNAME"
|
||||
fi
|
||||
|
||||
select domain_option in "Auto Generated Password" "Input Your Own Password"; do
|
||||
case $REPLY in
|
||||
1)
|
||||
echo "generating random password for TURN"
|
||||
TURN_PASSWORD=$(tr -dc A-Za-z0-9 </dev/urandom | head -c 30 ; echo '')
|
||||
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
|
||||
}
|
||||
|
||||
# set_compose - set compose file with proper values
|
||||
set_compose() {
|
||||
|
||||
set_mq_credentials
|
||||
set_turn_credentials
|
||||
|
||||
echo "retrieving updated wait script and mosquitto conf"
|
||||
rm $INSTALL_PATH/wait.sh
|
||||
|
@ -407,21 +464,38 @@ set_compose() {
|
|||
|
||||
STUN_PORT=3478
|
||||
|
||||
# RELEASE_REPLACE - Use this once release is ready
|
||||
|
||||
#sed -i "s/v0.17.1/v0.18.6/g" /root/docker-compose.yml
|
||||
yq ".services.netmaker.environment.SERVER_NAME = \"$SERVER_NAME\"" -i $INSTALL_PATH/docker-compose.yml
|
||||
yq ".services.netmaker.environment += {\"BROKER_ENDPOINT\": \"wss://$BROKER_NAME\"}" -i $INSTALL_PATH/docker-compose.yml
|
||||
yq ".services.netmaker.environment += {\"SERVER_BROKER_ENDPOINT\": \"ws://mq:1883\"}" -i $INSTALL_PATH/docker-compose.yml
|
||||
yq ".services.netmaker.environment += {\"STUN_LIST\": \"$STUN_DOMAIN:$STUN_PORT,stun1.netmaker.io:3478,stun2.netmaker.io:3478,stun1.l.google.com:19302,stun2.l.google.com:19302\"}" -i $INSTALL_PATH/docker-compose.yml
|
||||
yq ".services.netmaker.environment += {\"MQ_PASSWORD\": \"$MQ_PASSWORD\"}" -i $INSTALL_PATH/docker-compose.yml
|
||||
yq ".services.netmaker.environment += {\"MQ_USERNAME\": \"$MQ_USERNAME\"}" -i $INSTALL_PATH/docker-compose.yml
|
||||
yq ".services.netmaker.environment += {\"MQ_PASSWORD\": \"$MQ_PASSWORD\"}" -i $INSTALL_PATH/docker-compose.yml
|
||||
yq ".services.netmaker.environment += {\"TURN_SERVER_HOST\": \"turn.$SERVER_NAME\"}" -i $INSTALL_PATH/docker-compose.yml
|
||||
yq ".services.netmaker.environment += {\"TURN_SERVER_API_HOST\": \"turnapi.$SERVER_NAME\"}" -i $INSTALL_PATH/docker-compose.yml
|
||||
yq ".services.netmaker.environment += {\"TURN_USERNAME\": \"$TURN_USERNAME\"}" -i $INSTALL_PATH/docker-compose.yml
|
||||
yq ".services.netmaker.environment += {\"TURN_PASSWORD\": \"$TURN_PASSWORD\"}" -i $INSTALL_PATH/docker-compose.yml
|
||||
yq ".services.netmaker.environment += {\"STUN_PORT\": \"$STUN_PORT\"}" -i $INSTALL_PATH/docker-compose.yml
|
||||
yq ".services.netmaker.environment += {\"TURN_PORT\": \"3479\"}" -i $INSTALL_PATH/docker-compose.yml
|
||||
yq ".services.netmaker.environment += {\"USE_TURN\": \"true\"}" -i $INSTALL_PATH/docker-compose.yml
|
||||
yq ".services.netmaker.ports += \"3478:3478/udp\"" -i $INSTALL_PATH/docker-compose.yml
|
||||
|
||||
yq ".services.mq.environment += {\"MQ_PASSWORD\": \"$MQ_PASSWORD\"}" -i $INSTALL_PATH/docker-compose.yml
|
||||
yq ".services.mq.environment += {\"MQ_USERNAME\": \"$MQ_USERNAME\"}" -i $INSTALL_PATH/docker-compose.yml
|
||||
yq ".services.mq.environment += {\"MQ_PASSWORD\": \"$MQ_PASSWORD\"}" -i $INSTALL_PATH/docker-compose.yml
|
||||
|
||||
yq ".services.turn += {\"container_name\": \"turn\"}" -i $INSTALL_PATH/docker-compose.yml
|
||||
yq ".services.turn += {\"image\": \"gravitl/turnserver:v1.0.0\"}" -i $INSTALL_PATH/docker-compose.yml
|
||||
yq ".services.turn += {\"network_mode\": \"host\"}" -i $INSTALL_PATH/docker-compose.yml
|
||||
yq ".services.turn.volumes += {\"turn_server:/etc/config\"}" -i $INSTALL_PATH/docker-compose.yml
|
||||
yq ".services.turn.environment += {\"DEBUG_MODE\": \"off\"}" -i $INSTALL_PATH/docker-compose.yml
|
||||
yq ".services.turn.environment += {\"VERBOSITY\": \"1\"}" -i $INSTALL_PATH/docker-compose.yml
|
||||
yq ".services.turn.environment += {\"TURN_PORT\": \"3479\"}" -i $INSTALL_PATH/docker-compose.yml
|
||||
yq ".services.turn.environment += {\"TURN_API_PORT\": \"8089\"}" -i $INSTALL_PATH/docker-compose.yml
|
||||
yq ".services.turn.environment += {\"CORS_ALLOWED_ORIGIN\": \"*\"}" -i $INSTALL_PATH/docker-compose.yml
|
||||
yq ".services.turn.environment += {\"TURN_SERVER_HOST\": \"$TURN_DOMAIN\"}" -i $INSTALL_PATH/docker-compose.yml
|
||||
yq ".services.turn.environment += {\"TURN_USERNAME\": \"$TURN_USERNAME\"}" -i $INSTALL_PATH/docker-compose.yml
|
||||
yq ".services.turn.environment += {\"TURN_PASSWORD\": \"$TURN_PASSWORD\"}" -i $INSTALL_PATH/docker-compose.yml
|
||||
|
||||
yq ".services.volumes += {\".turn_server\": \"{}\"}" -i $INSTALL_PATH/docker-compose.yml
|
||||
|
||||
#remove unnecessary ports
|
||||
yq eval 'del( .services.netmaker.ports[] | select(. == "51821*") )' -i $INSTALL_PATH/docker-compose.yml
|
|
@ -107,10 +107,44 @@ func GetServerInfo() models.ServerConfig {
|
|||
cfg.Is_EE = Is_EE
|
||||
cfg.StunPort = GetStunPort()
|
||||
cfg.StunList = GetStunList()
|
||||
|
||||
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 = ""
|
||||
|
@ -186,11 +220,11 @@ func GetAPIPort() string {
|
|||
// GetStunList - gets the stun servers
|
||||
func GetStunList() []models.StunServer {
|
||||
stunList := []models.StunServer{
|
||||
models.StunServer{
|
||||
{
|
||||
Domain: "stun1.netmaker.io",
|
||||
Port: 3478,
|
||||
},
|
||||
models.StunServer{
|
||||
{
|
||||
Domain: "stun2.netmaker.io",
|
||||
Port: 3478,
|
||||
},
|
||||
|
@ -642,6 +676,44 @@ func GetStunPort() int {
|
|||
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
|
||||
|
||||
}
|
||||
|
||||
// IsProxyEnabled - is proxy on or off
|
||||
func IsProxyEnabled() bool {
|
||||
var enabled = false //default
|
||||
|
|
|
@ -704,7 +704,7 @@ info:
|
|||
|
||||
API calls must be authenticated via a header of the format -H “Authorization: Bearer <YOUR_SECRET_KEY>” There are two methods to obtain YOUR_SECRET_KEY: 1. Using the masterkey. By default, this value is “secret key,” but you should change this on your instance and keep it secure. This value can be set via env var at startup or in a config file (config/environments/< env >.yaml). See the [Netmaker](https://docs.netmaker.org/index.html) documentation for more details. 2. Using a JWT received for a node. This can be retrieved by calling the /api/nodes/<network>/authenticate endpoint, as documented below.
|
||||
title: Netmaker
|
||||
version: 0.18.7
|
||||
version: 0.19.0
|
||||
paths:
|
||||
/api/dns:
|
||||
get:
|
||||
|
|
Loading…
Reference in a new issue