mirror of
				https://github.com/juanfont/headscale.git
				synced 2025-10-28 10:51:44 +01:00 
			
		
		
		
	Merge branch 'main' into main
This commit is contained in:
		
						commit
						c8aa653275
					
				
							
								
								
									
										2
									
								
								.github/workflows/build.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/build.yml
									
									
									
									
										vendored
									
									
								
							| @ -31,7 +31,7 @@ jobs: | ||||
|         if: steps.changed-files.outputs.any_changed == 'true' | ||||
|         uses: actions/setup-go@v2 | ||||
|         with: | ||||
|           go-version: "1.17.7" | ||||
|           go-version: "1.18.0" | ||||
| 
 | ||||
|       - name: Install dependencies | ||||
|         if: steps.changed-files.outputs.any_changed == 'true' | ||||
|  | ||||
							
								
								
									
										2
									
								
								.github/workflows/release.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/release.yml
									
									
									
									
										vendored
									
									
								
							| @ -18,7 +18,7 @@ jobs: | ||||
|       - name: Set up Go | ||||
|         uses: actions/setup-go@v2 | ||||
|         with: | ||||
|           go-version: 1.17.7 | ||||
|           go-version: 1.18.0 | ||||
| 
 | ||||
|       - name: Install dependencies | ||||
|         run: | | ||||
|  | ||||
							
								
								
									
										2
									
								
								.github/workflows/test-integration.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/test-integration.yml
									
									
									
									
										vendored
									
									
								
							| @ -25,7 +25,7 @@ jobs: | ||||
|         if: steps.changed-files.outputs.any_changed == 'true' | ||||
|         uses: actions/setup-go@v2 | ||||
|         with: | ||||
|           go-version: "1.17.7" | ||||
|           go-version: "1.18.0" | ||||
| 
 | ||||
|       - name: Run Integration tests | ||||
|         if: steps.changed-files.outputs.any_changed == 'true' | ||||
|  | ||||
							
								
								
									
										2
									
								
								.github/workflows/test.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/test.yml
									
									
									
									
										vendored
									
									
								
							| @ -25,7 +25,7 @@ jobs: | ||||
|         if: steps.changed-files.outputs.any_changed == 'true' | ||||
|         uses: actions/setup-go@v2 | ||||
|         with: | ||||
|           go-version: "1.17.7" | ||||
|           go-version: "1.18.0" | ||||
| 
 | ||||
|       - name: Install dependencies | ||||
|         if: steps.changed-files.outputs.any_changed == 'true' | ||||
|  | ||||
| @ -29,6 +29,7 @@ | ||||
| - Fix a limitation in the ACLs that prevented users to write rules with `*` as source [#374](https://github.com/juanfont/headscale/issues/374) | ||||
| - Reduce the overhead of marshal/unmarshal for Hostinfo, routes and endpoints by using specific types in Machine [#371](https://github.com/juanfont/headscale/pull/371) | ||||
| - Apply normalization function to FQDN on hostnames when hosts registers and retrieve informations [#363](https://github.com/juanfont/headscale/issues/363) | ||||
| - Fix a bug that prevented the use of `tailscale logout` with OIDC [#508](https://github.com/juanfont/headscale/issues/508) | ||||
| 
 | ||||
| ## 0.14.0 (2022-02-24) | ||||
| 
 | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| # Builder image | ||||
| FROM docker.io/golang:1.17.8-bullseye AS build | ||||
| FROM docker.io/golang:1.18.0-bullseye AS build | ||||
| ENV GOPATH /go | ||||
| WORKDIR /go/src/headscale | ||||
| 
 | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| # Builder image | ||||
| FROM docker.io/golang:1.17.8-alpine AS build | ||||
| FROM docker.io/golang:1.18.0-alpine AS build | ||||
| ENV GOPATH /go | ||||
| WORKDIR /go/src/headscale | ||||
| 
 | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| # Builder image | ||||
| FROM docker.io/golang:1.17.8-bullseye AS build | ||||
| FROM docker.io/golang:1.18.0-bullseye AS build | ||||
| ENV GOPATH /go | ||||
| WORKDIR /go/src/headscale | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										22
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										22
									
								
								README.md
									
									
									
									
									
								
							| @ -447,6 +447,15 @@ make build | ||||
|             <sub style="font-size:14px"><b>Tjerk Woudsma</b></sub> | ||||
|         </a> | ||||
|     </td> | ||||
|     <td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0"> | ||||
|         <a href=https://github.com/y0ngb1n> | ||||
|             <img src=https://avatars.githubusercontent.com/u/25719408?v=4 width="100;"  style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px" alt=Yang Bin/> | ||||
|             <br /> | ||||
|             <sub style="font-size:14px"><b>Yang Bin</b></sub> | ||||
|         </a> | ||||
|     </td> | ||||
| </tr> | ||||
| <tr> | ||||
|     <td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0"> | ||||
|         <a href=https://github.com/zekker6> | ||||
|             <img src=https://avatars.githubusercontent.com/u/1367798?v=4 width="100;"  style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px" alt=Zakhar Bessarab/> | ||||
| @ -454,8 +463,6 @@ make build | ||||
|             <sub style="font-size:14px"><b>Zakhar Bessarab</b></sub> | ||||
|         </a> | ||||
|     </td> | ||||
| </tr> | ||||
| <tr> | ||||
|     <td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0"> | ||||
|         <a href=https://github.com/Bpazy> | ||||
|             <img src=https://avatars.githubusercontent.com/u/9838749?v=4 width="100;"  style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px" alt=ZiYuan/> | ||||
| @ -463,6 +470,13 @@ make build | ||||
|             <sub style="font-size:14px"><b>ZiYuan</b></sub> | ||||
|         </a> | ||||
|     </td> | ||||
|     <td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0"> | ||||
|         <a href=https://github.com/bravechamp> | ||||
|             <img src=https://avatars.githubusercontent.com/u/48980452?v=4 width="100;"  style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px" alt=bravechamp/> | ||||
|             <br /> | ||||
|             <sub style="font-size:14px"><b>bravechamp</b></sub> | ||||
|         </a> | ||||
|     </td> | ||||
|     <td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0"> | ||||
|         <a href=https://github.com/derelm> | ||||
|             <img src=https://avatars.githubusercontent.com/u/465155?v=4 width="100;"  style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px" alt=derelm/> | ||||
| @ -484,6 +498,8 @@ make build | ||||
|             <sub style="font-size:14px"><b>lion24</b></sub> | ||||
|         </a> | ||||
|     </td> | ||||
| </tr> | ||||
| <tr> | ||||
|     <td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0"> | ||||
|         <a href=https://github.com/pernila> | ||||
|             <img src=https://avatars.githubusercontent.com/u/12460060?v=4 width="100;"  style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px" alt=pernila/> | ||||
| @ -498,8 +514,6 @@ make build | ||||
|             <sub style="font-size:14px"><b>Wakeful-Cloud</b></sub> | ||||
|         </a> | ||||
|     </td> | ||||
| </tr> | ||||
| <tr> | ||||
|     <td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0"> | ||||
|         <a href=https://github.com/xpzouying> | ||||
|             <img src=https://avatars.githubusercontent.com/u/3946563?v=4 width="100;"  style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px" alt=zy/> | ||||
|  | ||||
							
								
								
									
										25
									
								
								app.go
									
									
									
									
									
								
							
							
						
						
									
										25
									
								
								app.go
									
									
									
									
									
								
							| @ -47,6 +47,14 @@ import ( | ||||
| 	"tailscale.com/types/key" | ||||
| ) | ||||
| 
 | ||||
| const ( | ||||
| 	errSTUNAddressNotSet                   = Error("STUN address not set") | ||||
| 	errUnsupportedDatabase                 = Error("unsupported DB") | ||||
| 	errUnsupportedLetsEncryptChallengeType = Error( | ||||
| 		"unknown value for Lets Encrypt challenge type", | ||||
| 	) | ||||
| ) | ||||
| 
 | ||||
| const ( | ||||
| 	AuthPrefix         = "Bearer " | ||||
| 	Postgres           = "postgres" | ||||
| @ -58,11 +66,6 @@ const ( | ||||
| 	registerCacheExpiration = time.Minute * 15 | ||||
| 	registerCacheCleanup    = time.Minute * 20 | ||||
| 
 | ||||
| 	errUnsupportedDatabase                 = Error("unsupported DB") | ||||
| 	errUnsupportedLetsEncryptChallengeType = Error( | ||||
| 		"unknown value for Lets Encrypt challenge type", | ||||
| 	) | ||||
| 
 | ||||
| 	DisabledClientAuth = "disabled" | ||||
| 	RelaxedClientAuth  = "relaxed" | ||||
| 	EnforcedClientAuth = "enforced" | ||||
| @ -124,7 +127,6 @@ type DERPConfig struct { | ||||
| 	ServerRegionID   int | ||||
| 	ServerRegionCode string | ||||
| 	ServerRegionName string | ||||
| 	STUNEnabled      bool | ||||
| 	STUNAddr         string | ||||
| 	URLs             []url.URL | ||||
| 	Paths            []string | ||||
| @ -409,8 +411,6 @@ func (h *Headscale) httpAuthenticationMiddleware(ctx *gin.Context) { | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	ctx.AbortWithStatus(http.StatusUnauthorized) | ||||
| 
 | ||||
| 	valid, err := h.ValidateAPIKey(strings.TrimPrefix(authHeader, AuthPrefix)) | ||||
| 	if err != nil { | ||||
| 		log.Error(). | ||||
| @ -502,10 +502,13 @@ func (h *Headscale) Serve() error { | ||||
| 	h.DERPMap = GetDERPMap(h.cfg.DERP) | ||||
| 
 | ||||
| 	if h.cfg.DERP.ServerEnabled { | ||||
| 		h.DERPMap.Regions[h.DERPServer.region.RegionID] = &h.DERPServer.region | ||||
| 		if h.cfg.DERP.STUNEnabled { | ||||
| 			go h.ServeSTUN() | ||||
| 		// When embedded DERP is enabled we always need a STUN server
 | ||||
| 		if h.cfg.DERP.STUNAddr == "" { | ||||
| 			return errSTUNAddressNotSet | ||||
| 		} | ||||
| 
 | ||||
| 		h.DERPMap.Regions[h.DERPServer.region.RegionID] = &h.DERPServer.region | ||||
| 		go h.ServeSTUN() | ||||
| 	} | ||||
| 
 | ||||
| 	if h.cfg.DERP.AutoUpdate { | ||||
|  | ||||
| @ -55,6 +55,9 @@ func LoadConfig(path string) error { | ||||
| 
 | ||||
| 	viper.SetDefault("dns_config", nil) | ||||
| 
 | ||||
| 	viper.SetDefault("derp.server.enabled", false) | ||||
| 	viper.SetDefault("derp.server.stun.enabled", true) | ||||
| 
 | ||||
| 	viper.SetDefault("unix_socket", "/var/run/headscale.sock") | ||||
| 	viper.SetDefault("unix_socket_permission", "0o770") | ||||
| 
 | ||||
| @ -121,8 +124,11 @@ func GetDERPConfig() headscale.DERPConfig { | ||||
| 	serverRegionID := viper.GetInt("derp.server.region_id") | ||||
| 	serverRegionCode := viper.GetString("derp.server.region_code") | ||||
| 	serverRegionName := viper.GetString("derp.server.region_name") | ||||
| 	stunEnabled := viper.GetBool("derp.server.stun.enabled") | ||||
| 	stunAddr := viper.GetString("derp.server.stun.listen_addr") | ||||
| 	stunAddr := viper.GetString("derp.server.stun_listen_addr") | ||||
| 
 | ||||
| 	if serverEnabled && stunAddr == "" { | ||||
| 		log.Fatal().Msg("derp.server.stun_listen_addr must be set if derp.server.enabled is true") | ||||
| 	} | ||||
| 
 | ||||
| 	urlStrs := viper.GetStringSlice("derp.urls") | ||||
| 
 | ||||
| @ -149,7 +155,6 @@ func GetDERPConfig() headscale.DERPConfig { | ||||
| 		ServerRegionID:   serverRegionID, | ||||
| 		ServerRegionCode: serverRegionCode, | ||||
| 		ServerRegionName: serverRegionName, | ||||
| 		STUNEnabled:      stunEnabled, | ||||
| 		STUNAddr:         stunAddr, | ||||
| 		URLs:             urls, | ||||
| 		Paths:            paths, | ||||
|  | ||||
| @ -69,11 +69,11 @@ derp: | ||||
|     region_code: "headscale" | ||||
|     region_name: "Headscale Embedded DERP" | ||||
| 
 | ||||
|     # If enabled, also listens in UDP at the configured address for STUN connections to help on NAT traversal | ||||
|     # Listens in UDP at the configured address for STUN connections to help on NAT traversal. | ||||
|     # When the embedded DERP server is enabled stun_listen_addr MUST be defined. | ||||
|     # | ||||
|     # For more details on how this works, check this great article: https://tailscale.com/blog/how-tailscale-works/ | ||||
|     stun: | ||||
|       enabled: false | ||||
|       listen_addr: "0.0.0.0:3478" | ||||
|     stun_listen_addr: "0.0.0.0:3478" | ||||
| 
 | ||||
|   # List of externally available DERP maps encoded in JSON | ||||
|   urls: | ||||
|  | ||||
							
								
								
									
										4
									
								
								derp.go
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								derp.go
									
									
									
									
									
								
							| @ -148,7 +148,9 @@ func (h *Headscale) scheduledDERPMapUpdateWorker(cancelChan <-chan struct{}) { | ||||
| 		case <-ticker.C: | ||||
| 			log.Info().Msg("Fetching DERPMap updates") | ||||
| 			h.DERPMap = GetDERPMap(h.cfg.DERP) | ||||
| 			h.DERPMap.Regions[h.DERPServer.region.RegionID] = &h.DERPServer.region | ||||
| 			if h.cfg.DERP.ServerEnabled { | ||||
| 				h.DERPMap.Regions[h.DERPServer.region.RegionID] = &h.DERPServer.region | ||||
| 			} | ||||
| 
 | ||||
| 			namespaces, err := h.ListNamespaces() | ||||
| 			if err != nil { | ||||
|  | ||||
| @ -77,17 +77,15 @@ func (h *Headscale) generateRegionLocalDERP() (tailcfg.DERPRegion, error) { | ||||
| 		}, | ||||
| 	} | ||||
| 
 | ||||
| 	if h.cfg.DERP.STUNEnabled { | ||||
| 		_, portStr, err := net.SplitHostPort(h.cfg.DERP.STUNAddr) | ||||
| 		if err != nil { | ||||
| 			return tailcfg.DERPRegion{}, err | ||||
| 		} | ||||
| 		port, err := strconv.Atoi(portStr) | ||||
| 		if err != nil { | ||||
| 			return tailcfg.DERPRegion{}, err | ||||
| 		} | ||||
| 		localDERPregion.Nodes[0].STUNPort = port | ||||
| 	_, portSTUNStr, err := net.SplitHostPort(h.cfg.DERP.STUNAddr) | ||||
| 	if err != nil { | ||||
| 		return tailcfg.DERPRegion{}, err | ||||
| 	} | ||||
| 	portSTUN, err := strconv.Atoi(portSTUNStr) | ||||
| 	if err != nil { | ||||
| 		return tailcfg.DERPRegion{}, err | ||||
| 	} | ||||
| 	localDERPregion.Nodes[0].STUNPort = portSTUN | ||||
| 
 | ||||
| 	return localDERPregion, nil | ||||
| } | ||||
|  | ||||
| @ -55,6 +55,7 @@ docker run \ | ||||
|   --rm \ | ||||
|   --volume $(pwd)/config:/etc/headscale/ \ | ||||
|   --publish 127.0.0.1:8080:8080 \ | ||||
|   --publish 127.0.0.1:9090:9090 \ | ||||
|   headscale/headscale:<VERSION> \ | ||||
|   headscale serve | ||||
| 
 | ||||
| @ -80,7 +81,7 @@ docker ps | ||||
| Verify `headscale` is available: | ||||
| 
 | ||||
| ```shell | ||||
| curl http://127.0.0.1:8080/metrics | ||||
| curl http://127.0.0.1:9090/metrics | ||||
| ``` | ||||
| 
 | ||||
| 6. Create a namespace ([tailnet](https://tailscale.com/kb/1136/tailnet/)): | ||||
|  | ||||
| @ -67,7 +67,7 @@ To run `headscale` in the background, please follow the steps in the [SystemD se | ||||
| Verify `headscale` is available: | ||||
| 
 | ||||
| ```shell | ||||
| curl http://127.0.0.1:8080/metrics | ||||
| curl http://127.0.0.1:9090/metrics | ||||
| ``` | ||||
| 
 | ||||
| 8. Create a namespace ([tailnet](https://tailscale.com/kb/1136/tailnet/)): | ||||
|  | ||||
							
								
								
									
										4
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								go.mod
									
									
									
									
									
								
							| @ -1,9 +1,10 @@ | ||||
| module github.com/juanfont/headscale | ||||
| 
 | ||||
| go 1.17 | ||||
| go 1.18 | ||||
| 
 | ||||
| require ( | ||||
| 	github.com/AlecAivazis/survey/v2 v2.3.2 | ||||
| 	github.com/ccding/go-stun/stun v0.0.0-20200514191101-4dc67bcdb029 | ||||
| 	github.com/coreos/go-oidc/v3 v3.1.0 | ||||
| 	github.com/efekarakus/termcolor v1.0.1 | ||||
| 	github.com/fatih/set v0.2.1 | ||||
| @ -49,7 +50,6 @@ require ( | ||||
| 	github.com/akutz/memconn v0.1.0 // indirect | ||||
| 	github.com/atomicgo/cursor v0.0.1 // indirect | ||||
| 	github.com/beorn7/perks v1.0.1 // indirect | ||||
| 	github.com/ccding/go-stun/stun v0.0.0-20200514191101-4dc67bcdb029 // indirect | ||||
| 	github.com/cenkalti/backoff/v4 v4.1.2 // indirect | ||||
| 	github.com/cespare/xxhash/v2 v2.1.2 // indirect | ||||
| 	github.com/containerd/continuity v0.2.2 // indirect | ||||
|  | ||||
| @ -24,6 +24,5 @@ derp: | ||||
|     region_id: 999 | ||||
|     region_code: "headscale" | ||||
|     region_name: "Headscale Embedded DERP" | ||||
|     stun: | ||||
|       enabled: true | ||||
|       listen_addr: "0.0.0.0:3478" | ||||
| 
 | ||||
|     stun_listen_addr: "0.0.0.0:3478" | ||||
|  | ||||
							
								
								
									
										7
									
								
								oidc.go
									
									
									
									
									
								
							
							
						
						
									
										7
									
								
								oidc.go
									
									
									
									
									
								
							| @ -10,6 +10,7 @@ import ( | ||||
| 	"html/template" | ||||
| 	"net/http" | ||||
| 	"strings" | ||||
| 	"time" | ||||
| 
 | ||||
| 	"github.com/coreos/go-oidc/v3/oidc" | ||||
| 	"github.com/gin-gonic/gin" | ||||
| @ -129,6 +130,10 @@ func (h *Headscale) OIDCCallback(ctx *gin.Context) { | ||||
| 
 | ||||
| 	oauth2Token, err := h.oauth2Config.Exchange(context.Background(), code) | ||||
| 	if err != nil { | ||||
| 		log.Error(). | ||||
| 			Err(err). | ||||
| 			Caller(). | ||||
| 			Msg("Could not exchange code for token") | ||||
| 		ctx.String(http.StatusBadRequest, "Could not exchange code for token") | ||||
| 
 | ||||
| 		return | ||||
| @ -229,7 +234,7 @@ func (h *Headscale) OIDCCallback(ctx *gin.Context) { | ||||
| 			Str("machine", machine.Name). | ||||
| 			Msg("machine already registered, reauthenticating") | ||||
| 
 | ||||
| 		h.RefreshMachine(machine, *machine.Expiry) | ||||
| 		h.RefreshMachine(machine, time.Time{}) | ||||
| 
 | ||||
| 		var content bytes.Buffer | ||||
| 		if err := oidcCallbackTemplate.Execute(&content, oidcCallbackTemplateConfig{ | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user