make nebula a service that can install itself
This commit is contained in:
		 Ryan Huber
					Ryan Huber
				
			
				
					committed by
					
						 Slack Security Team
						Slack Security Team
					
				
			
			
				
	
			
			
			 Slack Security Team
						Slack Security Team
					
				
			
						parent
						
							61d9f241b9
						
					
				
				
					commit
					8ed69c8eaf
				
			
							
								
								
									
										38
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										38
									
								
								Makefile
									
									
									
									
									
								
							| @@ -1,55 +1,56 @@ | |||||||
|  | NEBULA_CMD_PATH = "./cmd/nebula" | ||||||
| BUILD_NUMBER ?= dev+$(shell date -u '+%Y%m%d%H%M%S') | BUILD_NUMBER ?= dev+$(shell date -u '+%Y%m%d%H%M%S') | ||||||
| GO111MODULE = on | GO111MODULE = on | ||||||
| export GO111MODULE | export GO111MODULE | ||||||
|  |  | ||||||
| all: | all: | ||||||
| 	make bin-linux | 	make NEBULA_CMD_PATH=${NEBULA_CMD_PATH} bin-linux | ||||||
| 	make bin-arm | 	make NEBULA_CMD_PATH=${NEBULA_CMD_PATH} bin-arm | ||||||
| 	make bin-arm6 | 	make NEBULA_CMD_PATH=${NEBULA_CMD_PATH} bin-arm6 | ||||||
| 	make bin-arm64 | 	make NEBULA_CMD_PATH=${NEBULA_CMD_PATH} bin-arm64 | ||||||
| 	make bin-darwin | 	make NEBULA_CMD_PATH=${NEBULA_CMD_PATH} bin-darwin | ||||||
| 	make bin-windows | 	make NEBULA_CMD_PATH=${NEBULA_CMD_PATH} bin-windows | ||||||
|  |  | ||||||
| bin: | bin: | ||||||
| 	go build -ldflags "-X main.Build=$(BUILD_NUMBER)" -o ./nebula ./cmd/nebula | 	go build -ldflags "-X main.Build=$(BUILD_NUMBER)" -o ./nebula ./cmd/nebula | ||||||
| 	go build -ldflags "-X main.Build=$(BUILD_NUMBER)" -o ./nebula-cert ./cmd/nebula-cert | 	go build -ldflags "-X main.Build=$(BUILD_NUMBER)" -o ./nebula-cert ./cmd/nebula-cert | ||||||
|  |  | ||||||
| install: | install: | ||||||
| 	go install -ldflags "-X main.Build=$(BUILD_NUMBER)" ./cmd/nebula | 	go install -ldflags "-X main.Build=$(BUILD_NUMBER)" ${NEBULA_CMD_PATH} | ||||||
| 	go install -ldflags "-X main.Build=$(BUILD_NUMBER)" ./cmd/nebula-cert | 	go install -ldflags "-X main.Build=$(BUILD_NUMBER)" ./cmd/nebula-cert | ||||||
|  |  | ||||||
| bin-arm: | bin-arm: | ||||||
| 	mkdir -p build/arm | 	mkdir -p build/arm | ||||||
| 	GOARCH=arm GOOS=linux go build -o build/arm/nebula -ldflags "-X main.Build=$(BUILD_NUMBER)" ./cmd/nebula | 	GOARCH=arm GOOS=linux go build -o build/arm/nebula -ldflags "-X main.Build=$(BUILD_NUMBER)" ${NEBULA_CMD_PATH} | ||||||
| 	GOARCH=arm GOOS=linux go build -o build/arm/nebula-cert -ldflags "-X main.Build=$(BUILD_NUMBER)" ./cmd/nebula-cert | 	GOARCH=arm GOOS=linux go build -o build/arm/nebula-cert -ldflags "-X main.Build=$(BUILD_NUMBER)" ./cmd/nebula-cert | ||||||
|  |  | ||||||
| bin-arm6: | bin-arm6: | ||||||
| 	mkdir -p build/arm6 | 	mkdir -p build/arm6 | ||||||
| 	GOARCH=arm GOARM=6 GOOS=linux go build -o build/arm6/nebula -ldflags "-X main.Build=$(BUILD_NUMBER)" ./cmd/nebula | 	GOARCH=arm GOARM=6 GOOS=linux go build -o build/arm6/nebula -ldflags "-X main.Build=$(BUILD_NUMBER)" ${NEBULA_CMD_PATH} | ||||||
| 	GOARCH=arm GOARM=6 GOOS=linux go build -o build/arm6/nebula-cert -ldflags "-X main.Build=$(BUILD_NUMBER)" ./cmd/nebula-cert | 	GOARCH=arm GOARM=6 GOOS=linux go build -o build/arm6/nebula-cert -ldflags "-X main.Build=$(BUILD_NUMBER)" ./cmd/nebula-cert | ||||||
|  |  | ||||||
| bin-arm64: | bin-arm64: | ||||||
| 	mkdir -p build/arm64 | 	mkdir -p build/arm64 | ||||||
| 	GOARCH=arm64 GOOS=linux go build -o build/arm64/nebula -ldflags "-X main.Build=$(BUILD_NUMBER)" ./cmd/nebula | 	GOARCH=arm64 GOOS=linux go build -o build/arm64/nebula -ldflags "-X main.Build=$(BUILD_NUMBER)" ${NEBULA_CMD_PATH} | ||||||
| 	GOARCH=arm64 GOOS=linux go build -o build/arm64/nebula-cert -ldflags "-X main.Build=$(BUILD_NUMBER)" ./cmd/nebula-cert | 	GOARCH=arm64 GOOS=linux go build -o build/arm64/nebula-cert -ldflags "-X main.Build=$(BUILD_NUMBER)" ./cmd/nebula-cert | ||||||
|  |  | ||||||
| bin-vagrant: | bin-vagrant: | ||||||
| 	GOARCH=amd64 GOOS=linux go build -o nebula -ldflags "-X main.Build=$(BUILD_NUMBER)" ./cmd/nebula | 	GOARCH=amd64 GOOS=linux go build -o nebula -ldflags "-X main.Build=$(BUILD_NUMBER)" ${NEBULA_CMD_PATH} | ||||||
| 	GOARCH=amd64 GOOS=linux go build -ldflags "-X main.Build=$(BUILD_NUMBER)" -o ./nebula-cert ./cmd/nebula-cert | 	GOARCH=amd64 GOOS=linux go build -ldflags "-X main.Build=$(BUILD_NUMBER)" -o ./nebula-cert ./cmd/nebula-cert | ||||||
|  |  | ||||||
| bin-darwin: | bin-darwin: | ||||||
| 	mkdir -p build/darwin | 	mkdir -p build/darwin | ||||||
| 	GOARCH=amd64 GOOS=darwin go build -o build/darwin/nebula -ldflags "-X main.Build=$(BUILD_NUMBER)" ./cmd/nebula | 	GOARCH=amd64 GOOS=darwin go build -o build/darwin/nebula -ldflags "-X main.Build=$(BUILD_NUMBER)" ${NEBULA_CMD_PATH} | ||||||
| 	GOARCH=amd64 GOOS=darwin go build -o build/darwin/nebula-cert -ldflags "-X main.Build=$(BUILD_NUMBER)" ./cmd/nebula-cert | 	GOARCH=amd64 GOOS=darwin go build -o build/darwin/nebula-cert -ldflags "-X main.Build=$(BUILD_NUMBER)" ./cmd/nebula-cert | ||||||
|  |  | ||||||
| bin-windows: | bin-windows: | ||||||
| 	mkdir -p build/windows | 	mkdir -p build/windows | ||||||
| 	GOARCH=amd64 GOOS=windows go build -o build/windows/nebula.exe -ldflags "-X main.Build=$(BUILD_NUMBER)" ./cmd/nebula | 	GOARCH=amd64 GOOS=windows go build -o build/windows/nebula.exe -ldflags "-X main.Build=$(BUILD_NUMBER)" ${NEBULA_CMD_PATH} | ||||||
| 	GOARCH=amd64 GOOS=windows go build -o build/windows/nebula-cert.exe -ldflags "-X main.Build=$(BUILD_NUMBER)" ./cmd/nebula-cert | 	GOARCH=amd64 GOOS=windows go build -o build/windows/nebula-cert.exe -ldflags "-X main.Build=$(BUILD_NUMBER)" ./cmd/nebula-cert | ||||||
|  |  | ||||||
| bin-linux: | bin-linux: | ||||||
| 	mkdir -p build/linux | 	mkdir -p build/linux | ||||||
| 	GOARCH=amd64 GOOS=linux go build -o build/linux/nebula -ldflags "-X main.Build=$(BUILD_NUMBER)" ./cmd/nebula | 	GOARCH=amd64 GOOS=linux go build -o build/linux/nebula -ldflags "-X main.Build=$(BUILD_NUMBER)" ${NEBULA_CMD_PATH} | ||||||
| 	GOARCH=amd64 GOOS=linux go build -o build/linux/nebula-cert -ldflags "-X main.Build=$(BUILD_NUMBER)" ./cmd/nebula-cert | 	GOARCH=amd64 GOOS=linux go build -o build/linux/nebula-cert -ldflags "-X main.Build=$(BUILD_NUMBER)" ./cmd/nebula-cert | ||||||
|  |  | ||||||
| release: all | release: all | ||||||
| @@ -91,6 +92,13 @@ nebula.pb.go: nebula.proto .FORCE | |||||||
| cert/cert.pb.go: cert/cert.proto .FORCE | cert/cert.pb.go: cert/cert.proto .FORCE | ||||||
| 	$(MAKE) -C cert cert.pb.go | 	$(MAKE) -C cert cert.pb.go | ||||||
|  |  | ||||||
|  | service: | ||||||
|  | 	@echo > /dev/null | ||||||
|  | 	$(eval NEBULA_CMD_PATH := "./cmd/nebula-service") | ||||||
|  | ifeq ($(words $(MAKECMDGOALS)),1) | ||||||
|  | 	$(MAKE) service ${.DEFAULT_GOAL} --no-print-directory | ||||||
|  | endif | ||||||
|  |  | ||||||
| .FORCE: | .FORCE: | ||||||
| .PHONY: test test-cov-html bench bench-cpu bench-cpu-long bin proto release | .PHONY: test test-cov-html bench bench-cpu bench-cpu-long bin proto release service | ||||||
| .DEFAULT_GOAL := bin | .DEFAULT_GOAL := bin | ||||||
|   | |||||||
							
								
								
									
										49
									
								
								cmd/nebula-service/main.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								cmd/nebula-service/main.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,49 @@ | |||||||
|  | package main | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"flag" | ||||||
|  | 	"fmt" | ||||||
|  | 	"os" | ||||||
|  |  | ||||||
|  | 	"github.com/slackhq/nebula" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // A version string that can be set with | ||||||
|  | // | ||||||
|  | //     -ldflags "-X main.Build=SOMEVERSION" | ||||||
|  | // | ||||||
|  | // at compile-time. | ||||||
|  | var Build string | ||||||
|  |  | ||||||
|  | func main() { | ||||||
|  | 	serviceFlag := flag.String("service", "", "Control the system service.") | ||||||
|  | 	configPath := flag.String("config", "", "Path to either a file or directory to load configuration from") | ||||||
|  | 	configTest := flag.Bool("test", false, "Test the config and print the end result. Non zero exit indicates a faulty config") | ||||||
|  | 	printVersion := flag.Bool("version", false, "Print version") | ||||||
|  | 	printUsage := flag.Bool("help", false, "Print command line usage") | ||||||
|  |  | ||||||
|  | 	flag.Parse() | ||||||
|  |  | ||||||
|  | 	if *printVersion { | ||||||
|  | 		fmt.Printf("Build: %s\n", Build) | ||||||
|  | 		os.Exit(0) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if *printUsage { | ||||||
|  | 		flag.Usage() | ||||||
|  | 		os.Exit(0) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if *serviceFlag != "" { | ||||||
|  | 		doService(configPath, configTest, Build, serviceFlag) | ||||||
|  | 		os.Exit(1) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if *configPath == "" { | ||||||
|  | 		fmt.Println("-config flag must be set") | ||||||
|  | 		flag.Usage() | ||||||
|  | 		os.Exit(1) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	nebula.Main(*configPath, *configTest, Build) | ||||||
|  | } | ||||||
							
								
								
									
										106
									
								
								cmd/nebula-service/service.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										106
									
								
								cmd/nebula-service/service.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,106 @@ | |||||||
|  | package main | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"log" | ||||||
|  | 	"os" | ||||||
|  | 	"path/filepath" | ||||||
|  |  | ||||||
|  | 	"github.com/kardianos/service" | ||||||
|  | 	"github.com/slackhq/nebula" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | var logger service.Logger | ||||||
|  |  | ||||||
|  | type program struct { | ||||||
|  | 	exit       chan struct{} | ||||||
|  | 	configPath *string | ||||||
|  | 	configTest *bool | ||||||
|  | 	build      string | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (p *program) Start(s service.Service) error { | ||||||
|  | 	if service.Interactive() { | ||||||
|  | 		logger.Info("Running in terminal.") | ||||||
|  | 	} else { | ||||||
|  | 		logger.Info("Running under service manager.") | ||||||
|  | 	} | ||||||
|  | 	p.exit = make(chan struct{}) | ||||||
|  |  | ||||||
|  | 	// Start should not block. Do the actual work async. | ||||||
|  | 	go p.run() | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (p *program) run() error { | ||||||
|  | 	nebula.Main(*p.configPath, *p.configTest, Build) | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (p *program) Stop(s service.Service) error { | ||||||
|  | 	// Any work in Stop should be quick, usually a few seconds at most. | ||||||
|  | 	logger.Info("I'm Stopping!") | ||||||
|  | 	close(p.exit) | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func doService(configPath *string, configTest *bool, build string, serviceFlag *string) { | ||||||
|  |  | ||||||
|  | 	if *configPath == "" { | ||||||
|  | 		ex, err := os.Executable() | ||||||
|  | 		if err != nil { | ||||||
|  | 			panic(err) | ||||||
|  | 		} | ||||||
|  | 		*configPath = filepath.Dir(ex) + "/config.yaml" | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	svcConfig := &service.Config{ | ||||||
|  | 		Name:        "Nebula", | ||||||
|  | 		DisplayName: "Nebula Network Service", | ||||||
|  | 		Description: "Nebula network connectivity daemon for encrypted communications", | ||||||
|  | 		Arguments:   []string{"-service", "run", "-config", *configPath}, | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	prg := &program{ | ||||||
|  | 		configPath: configPath, | ||||||
|  | 		configTest: configTest, | ||||||
|  | 		build:      build, | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	s, err := service.New(prg, svcConfig) | ||||||
|  | 	if err != nil { | ||||||
|  | 		log.Fatal(err) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	errs := make(chan error, 5) | ||||||
|  | 	logger, err = s.Logger(errs) | ||||||
|  | 	if err != nil { | ||||||
|  | 		log.Fatal(err) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	go func() { | ||||||
|  | 		for { | ||||||
|  | 			err := <-errs | ||||||
|  | 			if err != nil { | ||||||
|  | 				log.Print(err) | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	}() | ||||||
|  |  | ||||||
|  | 	//if len(*serviceFlag) != 0 { | ||||||
|  | 	switch *serviceFlag { | ||||||
|  | 	case "run": | ||||||
|  | 		err = s.Run() | ||||||
|  | 		if err != nil { | ||||||
|  | 			logger.Error(err) | ||||||
|  | 		} | ||||||
|  | 	default: | ||||||
|  | 		err := service.Control(s, *serviceFlag) | ||||||
|  | 		if err != nil { | ||||||
|  | 			log.Printf("Valid actions: %q\n", service.ControlAction) | ||||||
|  | 			log.Fatal(err) | ||||||
|  | 		} | ||||||
|  | 		return | ||||||
|  | 		//} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | } | ||||||
							
								
								
									
										1
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								go.mod
									
									
									
									
									
								
							| @@ -10,6 +10,7 @@ require ( | |||||||
| 	github.com/flynn/noise v0.0.0-20180327030543-2492fe189ae6 | 	github.com/flynn/noise v0.0.0-20180327030543-2492fe189ae6 | ||||||
| 	github.com/golang/protobuf v1.3.1 | 	github.com/golang/protobuf v1.3.1 | ||||||
| 	github.com/imdario/mergo v0.3.7 | 	github.com/imdario/mergo v0.3.7 | ||||||
|  | 	github.com/kardianos/service v1.0.0 | ||||||
| 	github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect | 	github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect | ||||||
| 	github.com/kr/pretty v0.1.0 // indirect | 	github.com/kr/pretty v0.1.0 // indirect | ||||||
| 	github.com/miekg/dns v1.1.12 | 	github.com/miekg/dns v1.1.12 | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								go.sum
									
									
									
									
									
								
							| @@ -30,6 +30,7 @@ github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y | |||||||
| github.com/imdario/mergo v0.3.7 h1:Y+UAYTZ7gDEuOfhxKWy+dvb5dRQ6rJjFSdX2HZY1/gI= | github.com/imdario/mergo v0.3.7 h1:Y+UAYTZ7gDEuOfhxKWy+dvb5dRQ6rJjFSdX2HZY1/gI= | ||||||
| github.com/imdario/mergo v0.3.7/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= | github.com/imdario/mergo v0.3.7/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= | ||||||
| github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= | github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= | ||||||
|  | github.com/kardianos/service v1.0.0/go.mod h1:8CzDhVuCuugtsHyZoTvsOBuvonN/UDBvl0kH+BUxvbo= | ||||||
| github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= | github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= | ||||||
| github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s= | github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s= | ||||||
| github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= | github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= | ||||||
| @@ -97,6 +98,7 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ | |||||||
| golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | ||||||
| golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | ||||||
| golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | ||||||
|  | golang.org/x/sys v0.0.0-20190204203706-41f3e6584952/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | ||||||
| golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | ||||||
| golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||||
| golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user