Merge branch 'develop' into NET-39/nm-quick-refactor

# Conflicts:
#	docker/Caddyfile
#	scripts/nm-quick.sh
This commit is contained in:
Tobias Cudnik 2023-05-08 09:29:39 +02:00
commit a97e27cd6c
42 changed files with 561 additions and 106 deletions

View file

@ -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

View file

@ -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 \

View file

@ -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

View file

@ -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

View file

@ -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" />

View file

@ -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:

View file

@ -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: {}

View file

@ -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

View file

@ -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: {}

View file

@ -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: {}

View file

@ -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

View file

@ -10,7 +10,7 @@
//
// Schemes: https
// BasePath: /
// Version: 0.18.7
// Version: 0.19.0
// Host: netmaker.io
//
// Consumes:

View file

@ -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")

View file

@ -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.

View file

@ -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

View file

@ -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

View file

@ -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
View file

@ -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
View file

@ -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=

View file

@ -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"

View file

@ -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"

View file

@ -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:

View file

@ -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:

View file

@ -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
}

View file

@ -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])

View file

@ -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 {

View file

@ -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")

View file

@ -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,
}
}

View file

@ -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

View file

@ -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, "\""))

View file

@ -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() {

View file

@ -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

View file

@ -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"`

View file

@ -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

View file

@ -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 {

View file

@ -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)

View file

@ -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)
}

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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: