From c6aaa37f2d120490cb65de5071e269ac4b0a2c60 Mon Sep 17 00:00:00 2001 From: Anton Schubert Date: Wed, 6 Jul 2022 13:39:10 +0200 Subject: [PATCH 01/18] ping db in health check --- api.go | 38 ++++++++++++++++++++++++++++++++++++++ app.go | 14 +------------- db.go | 12 ++++++++++++ 3 files changed, 51 insertions(+), 13 deletions(-) diff --git a/api.go b/api.go index fc27e46..ff0de0c 100644 --- a/api.go +++ b/api.go @@ -30,6 +30,44 @@ const ( ) ) +func (h *Headscale) HealthHandler( + writer http.ResponseWriter, + req *http.Request, +) { + respond := func(err error) { + writer.Header().Set("Content-Type", "application/health+json; charset=utf-8") + + res := struct { + Status string `json:"status"` + }{ + Status: "pass", + } + + if err != nil { + writer.WriteHeader(http.StatusInternalServerError) + log.Error().Caller().Err(err).Msg("health check failed") + res.Status = "fail" + } + + buf, err := json.Marshal(res) + if err != nil { + log.Error().Caller().Err(err).Msg("marshal failed") + } + _, err = writer.Write(buf) + if err != nil { + log.Error().Caller().Err(err).Msg("write failed") + } + } + + if err := h.pingDB(); err != nil { + respond(err) + + return + } + + respond(nil) +} + // KeyHandler provides the Headscale pub key // Listens in /key. func (h *Headscale) KeyHandler( diff --git a/app.go b/app.go index e4e6910..f988048 100644 --- a/app.go +++ b/app.go @@ -423,19 +423,7 @@ func (h *Headscale) createPrometheusRouter() *gin.Engine { func (h *Headscale) createRouter(grpcMux *runtime.ServeMux) *mux.Router { router := mux.NewRouter() - router.HandleFunc( - "/health", - func(writer http.ResponseWriter, req *http.Request) { - writer.WriteHeader(http.StatusOK) - _, err := writer.Write([]byte("{\"healthy\": \"ok\"}")) - if err != nil { - log.Error(). - Caller(). - Err(err). - Msg("Failed to write response") - } - }).Methods(http.MethodGet) - + router.HandleFunc("/health", h.HealthHandler).Methods(http.MethodGet) router.HandleFunc("/key", h.KeyHandler).Methods(http.MethodGet) router.HandleFunc("/register", h.RegisterWebAPI).Methods(http.MethodGet) router.HandleFunc("/machine/{mkey}/map", h.PollNetMapHandler).Methods(http.MethodPost) diff --git a/db.go b/db.go index e412468..5df9c23 100644 --- a/db.go +++ b/db.go @@ -1,6 +1,7 @@ package headscale import ( + "context" "database/sql/driver" "encoding/json" "errors" @@ -220,6 +221,17 @@ func (h *Headscale) setValue(key string, value string) error { return nil } +func (h *Headscale) pingDB() error { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + db, err := h.db.DB() + if err != nil { + return err + } + + return db.PingContext(ctx) +} + // This is a "wrapper" type around tailscales // Hostinfo to allow us to add database "serialization" // methods. This allows us to use a typed values throughout From aca5646032da4bd3bfe163766926ce170c48815e Mon Sep 17 00:00:00 2001 From: Jiang Zhu Date: Sat, 16 Jul 2022 02:03:46 +0800 Subject: [PATCH 02/18] remove gin completely, ~2MB reduction on final binary --- app.go | 17 ++++------------- go.mod | 11 ----------- go.sum | 23 ----------------------- 3 files changed, 4 insertions(+), 47 deletions(-) diff --git a/app.go b/app.go index e4e6910..11c8d68 100644 --- a/app.go +++ b/app.go @@ -17,17 +17,16 @@ import ( "time" "github.com/coreos/go-oidc/v3/oidc" - "github.com/gin-gonic/gin" "github.com/gorilla/mux" grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware" "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" v1 "github.com/juanfont/headscale/gen/go/headscale/v1" "github.com/patrickmn/go-cache" zerolog "github.com/philip-bui/grpc-zerolog" + "github.com/prometheus/client_golang/prometheus/promhttp" "github.com/puzpuzpuz/xsync" zl "github.com/rs/zerolog" "github.com/rs/zerolog/log" - ginprometheus "github.com/zsais/go-gin-prometheus" "golang.org/x/crypto/acme" "golang.org/x/crypto/acme/autocert" "golang.org/x/oauth2" @@ -411,15 +410,6 @@ func (h *Headscale) ensureUnixSocketIsAbsent() error { return os.Remove(h.cfg.UnixSocket) } -func (h *Headscale) createPrometheusRouter() *gin.Engine { - promRouter := gin.Default() - - prometheus := ginprometheus.NewPrometheus("gin") - prometheus.Use(promRouter) - - return promRouter -} - func (h *Headscale) createRouter(grpcMux *runtime.ServeMux) *mux.Router { router := mux.NewRouter() @@ -647,11 +637,12 @@ func (h *Headscale) Serve() error { log.Info(). Msgf("listening and serving HTTP on: %s", h.cfg.Addr) - promRouter := h.createPrometheusRouter() + promMux := http.NewServeMux() + promMux.Handle("/metrics", promhttp.Handler()) promHTTPServer := &http.Server{ Addr: h.cfg.MetricsAddr, - Handler: promRouter, + Handler: promMux, ReadTimeout: HTTPReadTimeout, WriteTimeout: 0, } diff --git a/go.mod b/go.mod index e10ae35..80a3e48 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,6 @@ require ( github.com/coreos/go-oidc/v3 v3.1.0 github.com/deckarep/golang-set/v2 v2.1.0 github.com/efekarakus/termcolor v1.0.1 - github.com/gin-gonic/gin v1.7.7 github.com/glebarez/sqlite v1.4.3 github.com/gofrs/uuid v4.2.0+incompatible github.com/gorilla/mux v1.8.0 @@ -28,7 +27,6 @@ require ( github.com/stretchr/testify v1.7.1 github.com/tailscale/hujson v0.0.0-20220506202205-92b4b88a9e17 github.com/tcnksm/go-latest v0.0.0-20170313132115-e3007ae9052e - github.com/zsais/go-gin-prometheus v0.1.0 golang.org/x/crypto v0.0.0-20220427172511-eb4f295cb31f golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5 golang.org/x/sync v0.0.0-20220513210516-0976fa681c29 @@ -61,11 +59,7 @@ require ( github.com/docker/go-connections v0.4.0 // indirect github.com/docker/go-units v0.4.0 // indirect github.com/fsnotify/fsnotify v1.5.1 // indirect - github.com/gin-contrib/sse v0.1.0 // indirect github.com/glebarez/go-sqlite v1.16.0 // indirect - github.com/go-playground/locales v0.13.0 // indirect - github.com/go-playground/universal-translator v0.17.0 // indirect - github.com/go-playground/validator/v10 v10.4.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/protobuf v1.5.2 // indirect github.com/google/go-cmp v0.5.8 // indirect @@ -90,11 +84,9 @@ require ( github.com/jinzhu/now v1.1.4 // indirect github.com/josharian/native v1.0.0 // indirect github.com/jsimonetti/rtnetlink v1.1.2-0.20220408201609-d380b505068b // indirect - github.com/json-iterator/go v1.1.12 // indirect github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect github.com/kr/pretty v0.3.0 // indirect github.com/kr/text v0.2.0 // indirect - github.com/leodido/go-urn v1.2.0 // indirect github.com/magiconair/properties v1.8.6 // indirect github.com/mattn/go-colorable v0.1.12 // indirect github.com/mattn/go-isatty v0.0.14 // indirect @@ -106,8 +98,6 @@ require ( github.com/mitchellh/go-ps v1.0.0 // indirect github.com/mitchellh/mapstructure v1.4.3 // indirect github.com/moby/term v0.0.0-20201216013528-df9cb8a40635 // indirect - github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect - github.com/modern-go/reflect2 v1.0.2 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.0.3-0.20220114050600-8b9d41f48198 // indirect github.com/opencontainers/runc v1.0.2 // indirect @@ -126,7 +116,6 @@ require ( github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/subosito/gotenv v1.2.0 // indirect - github.com/ugorji/go/codec v1.1.7 // indirect github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect github.com/xeipuuv/gojsonschema v1.2.0 // indirect diff --git a/go.sum b/go.sum index b4d03b9..3290d9c 100644 --- a/go.sum +++ b/go.sum @@ -236,10 +236,6 @@ github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5 github.com/fullstorydev/grpcurl v1.6.0/go.mod h1:ZQ+ayqbKMJNhzLmbpCiurTVlaK2M/3nqZCxaQ2Ze/sM= github.com/fzipp/gocyclo v0.3.1/go.mod h1:DJHO6AUmbdqj2ET4Z9iArSuwWgYDRryYt2wASxc7x3E= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= -github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= -github.com/gin-gonic/gin v1.7.7 h1:3DoBmSbJbZAWqXJC3SLjAPfutPJJRN1U5pALB7EeTTs= -github.com/gin-gonic/gin v1.7.7/go.mod h1:axIBovoeJpVj8S3BwE0uPMTeReE4+AfFtqpqaZ1qq1U= github.com/glebarez/go-sqlite v1.16.0 h1:h28rHued+hGof3fNLksBcLwz/a71fiGZ/eIJHK0SsLI= github.com/glebarez/go-sqlite v1.16.0/go.mod h1:i8/JtqoqzBAFkrUTxbQFkQ05odCOds3j7NlDaXjqiPY= github.com/glebarez/sqlite v1.4.3 h1:ZABNo+2YIau8F8sZ7Qh/1h/ZnlSUMHFGD4zJKPval7A= @@ -256,14 +252,6 @@ github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= -github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A= -github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= -github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= -github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= -github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no= -github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= -github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE= -github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= github.com/go-redis/redis v6.15.8+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= @@ -546,10 +534,8 @@ github.com/jsimonetti/rtnetlink v1.1.2-0.20220408201609-d380b505068b h1:Yws7RV6k github.com/jsimonetti/rtnetlink v1.1.2-0.20220408201609-d380b505068b/go.mod h1:TzDCVOZKUa79z6iXbbXqhtAflVgUKaFkZ21M5tK5tzY= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= @@ -595,8 +581,6 @@ github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+ github.com/kyoh86/exportloopref v0.1.8/go.mod h1:1tUcJeiioIs7VWe5gcOObrux3lb66+sBqGZrRkMwPgg= github.com/ldez/gomoddirectives v0.2.2/go.mod h1:cpgBogWITnCfRq2qGoDkKMEVSaarhdBr6g8G04uz6d0= github.com/ldez/tagliatelle v0.2.0/go.mod h1:8s6WJQwEYHbKZDsp/LjArytKOG8qaMrKQQ3mFukHs88= -github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= -github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= github.com/letsencrypt/pkcs11key/v4 v4.0.0/go.mod h1:EFUvBDay26dErnNb70Nd0/VW3tJiIbETBPTl9ATXQag= github.com/lib/pq v0.0.0-20180327071824-d34b9ff171c2/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= @@ -686,11 +670,9 @@ github.com/moby/sys/mountinfo v0.4.1/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2J github.com/moby/term v0.0.0-20201216013528-df9cb8a40635 h1:rzf0wL0CHVc8CEsgyygG0Mn9CNCCPZqOPaz8RiiHYQk= github.com/moby/term v0.0.0-20201216013528-df9cb8a40635/go.mod h1:FBS0z0QWA44HXygs7VXDUOGoN/1TV3RuWkLO04am3wc= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= github.com/moricho/tparallel v0.2.1/go.mod h1:fXEIZxG2vdfl0ZF8b42f5a78EhjjD5mX8qUplsoSU4k= @@ -925,10 +907,7 @@ github.com/tmc/grpc-websocket-proxy v0.0.0-20200427203606-3cfed13b9966/go.mod h1 github.com/tomarrell/wrapcheck/v2 v2.4.0/go.mod h1:68bQ/eJg55BROaRTbMjC7vuhL2OgfoG8bLp9ZyoBfyY= github.com/tomasen/realip v0.0.0-20180522021738-f0c99a92ddce/go.mod h1:o8v6yHRoik09Xen7gje4m9ERNah1d1PPsVq1VEx9vE4= github.com/tommy-muehle/go-mnd/v2 v2.4.0/go.mod h1:WsUAkMJMYww6l/ufffCD3m+P7LEvr8TnZn9lwVDlgzw= -github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= -github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs= -github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= github.com/ultraware/funlen v0.0.3/go.mod h1:Dp4UiAus7Wdb9KUZsYWZEWiRzGuM2kXM1lPbfaF6xhA= github.com/ultraware/whitespace v0.0.4/go.mod h1:aVMh/gQve5Maj9hQ/hg+F75lr/X5A89uZnzAmWSineA= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= @@ -962,8 +941,6 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= -github.com/zsais/go-gin-prometheus v0.1.0 h1:bkLv1XCdzqVgQ36ScgRi09MA2UC1t3tAB6nsfErsGO4= -github.com/zsais/go-gin-prometheus v0.1.0/go.mod h1:Slirjzuz8uM8Cw0jmPNqbneoqcUtY2GGjn2bEd4NRLY= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.4/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= go.etcd.io/etcd v0.0.0-20200513171258-e048e166ab9c/go.mod h1:xCI7ZzBfRuGgBXyXO6yfWfDmlWd35khcWpUa4L0xI/k= From b755d4765258027584b505e03a606f65380ada82 Mon Sep 17 00:00:00 2001 From: Jiang Zhu Date: Tue, 19 Jul 2022 20:45:23 +0800 Subject: [PATCH 03/18] update CHANGELOG --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1c63ae4..e1ec1b6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,7 +32,7 @@ - Improve obtuse UX regarding missing configuration (`ephemeral_node_inactivity_timeout` not set) [#639](https://github.com/juanfont/headscale/pull/639) - Fix nodes being shown as 'offline' in `tailscale status` [#648](https://github.com/juanfont/headscale/pull/648) - Improve shutdown behaviour [#651](https://github.com/juanfont/headscale/pull/651) -- Drop Gin as web framework in Headscale [648](https://github.com/juanfont/headscale/pull/648) +- Drop Gin as web framework in Headscale [648](https://github.com/juanfont/headscale/pull/648) [677](https://github.com/juanfont/headscale/pull/677) - Make tailnet node updates check interval configurable [#675](https://github.com/juanfont/headscale/pull/675) ## 0.15.0 (2022-03-20) From 5724f4607c0bc24ccb6ceca2e84870eed63f7d0e Mon Sep 17 00:00:00 2001 From: Jiang Zhu Date: Tue, 19 Jul 2022 20:45:32 +0800 Subject: [PATCH 04/18] fix nix build --- flake.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flake.nix b/flake.nix index afa8c8b..f9f3c83 100644 --- a/flake.nix +++ b/flake.nix @@ -24,7 +24,7 @@ # When updating go.mod or go.sum, a new sha will need to be calculated, # update this if you have a mismatch after doing a change to thos files. - vendorSha256 = "sha256-T6rH+aqofFmCPxDfoA5xd3kNUJeZkT4GRyuFEnenps8="; + vendorSha256 = "sha256-b9C6F+7N0ecW0HiTx+rztZnxb+n6U6YTSOJvp3GqnWQ="; ldflags = [ "-s" "-w" "-X github.com/juanfont/headscale/cmd/headscale/cli.Version=v${version}" ]; }; From 02c7a46b977462d47240de2a3a8a3476306c08e6 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 20 Jul 2022 07:21:19 +0000 Subject: [PATCH 05/18] docs(README): update contributors --- README.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index f00772e..38578c3 100644 --- a/README.md +++ b/README.md @@ -188,13 +188,6 @@ make build Ward Vandewege - - - Nico/ -
- Nico -
- Jiang @@ -202,6 +195,13 @@ make build Jiang Zhu + + + Nico/ +
+ Nico +
+ From 889eff265fdcaff348c406270666fa3067194559 Mon Sep 17 00:00:00 2001 From: Grigoriy Mikhalkin Date: Thu, 30 Jun 2022 23:35:22 +0200 Subject: [PATCH 06/18] graceful shutdown fix --- app.go | 23 +++++++++++++++++------ poll.go | 21 ++++++++++++--------- 2 files changed, 29 insertions(+), 15 deletions(-) diff --git a/app.go b/app.go index 11c8d68..de6ef66 100644 --- a/app.go +++ b/app.go @@ -95,6 +95,7 @@ type Headscale struct { ipAllocationMutex sync.Mutex shutdownChan chan struct{} + wg sync.WaitGroup } // Look up the TLS constant relative to user-supplied TLS client @@ -153,6 +154,7 @@ func NewHeadscale(cfg *Config) (*Headscale, error) { privateKey: privKey, aclRules: tailcfg.FilterAllowAll, // default allowall registrationCache: registrationCache, + wg: sync.WaitGroup{}, } err = app.initDB() @@ -567,6 +569,8 @@ func (h *Headscale) Serve() error { // https://github.com/soheilhy/cmux/issues/68 // https://github.com/soheilhy/cmux/issues/91 + var grpcServer *grpc.Server + var grpcListener net.Listener if tlsConfig != nil || h.cfg.GRPCAllowInsecure { log.Info().Msgf("Enabling remote gRPC at %s", h.cfg.GRPCAddr) @@ -587,12 +591,12 @@ func (h *Headscale) Serve() error { log.Warn().Msg("gRPC is running without security") } - grpcServer := grpc.NewServer(grpcOptions...) + grpcServer = grpc.NewServer(grpcOptions...) v1.RegisterHeadscaleServiceServer(grpcServer, newHeadscaleV1APIServer(h)) reflection.Register(grpcServer) - grpcListener, err := net.Listen("tcp", h.cfg.GRPCAddr) + grpcListener, err = net.Listen("tcp", h.cfg.GRPCAddr) if err != nil { return fmt.Errorf("failed to bind to TCP address: %w", err) } @@ -668,7 +672,7 @@ func (h *Headscale) Serve() error { syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGHUP) - go func(c chan os.Signal) { + sig_func := func(c chan os.Signal) { // Wait for a SIGINT or SIGKILL: for { sig := <-c @@ -678,7 +682,7 @@ func (h *Headscale) Serve() error { Str("signal", sig.String()). Msg("Received SIGHUP, reloading ACL and Config") - // TODO(kradalby): Reload config on SIGHUP + // TODO(kradalby): Reload config on SIGHUP if h.cfg.ACL.PolicyPath != "" { aclPath := AbsolutePathFromConfigPath(h.cfg.ACL.PolicyPath) @@ -698,7 +702,8 @@ func (h *Headscale) Serve() error { Str("signal", sig.String()). Msg("Received signal to stop, shutting down gracefully") - h.shutdownChan <- struct{}{} + close(h.shutdownChan) + h.wg.Wait() // Gracefully shut down servers ctx, cancel := context.WithTimeout(context.Background(), HTTPShutdownTimeout) @@ -710,6 +715,11 @@ func (h *Headscale) Serve() error { } grpcSocket.GracefulStop() + if grpcServer != nil { + grpcServer.GracefulStop() + grpcListener.Close() + } + // Close network listeners promHTTPListener.Close() httpListener.Close() @@ -736,7 +746,8 @@ func (h *Headscale) Serve() error { os.Exit(0) } } - }(sigc) + } + errorGroup.Go(func() error { sig_func(sigc); return nil }) return errorGroup.Wait() } diff --git a/poll.go b/poll.go index 6628a17..94941aa 100644 --- a/poll.go +++ b/poll.go @@ -290,6 +290,9 @@ func (h *Headscale) PollNetMapStream( keepAliveChan chan []byte, updateChan chan struct{}, ) { + h.wg.Add(1) + defer h.wg.Done() + ctx := context.WithValue(req.Context(), machineNameContextKey, machine.Hostname) ctx, cancel := context.WithCancel(ctx) @@ -353,9 +356,9 @@ func (h *Headscale) PollNetMapStream( Str("channel", "pollData"). Int("bytes", len(data)). Msg("Data from pollData channel written successfully") - // TODO(kradalby): Abstract away all the database calls, this can cause race conditions - // when an outdated machine object is kept alive, e.g. db is update from - // command line, but then overwritten. + // TODO(kradalby): Abstract away all the database calls, this can cause race conditions + // when an outdated machine object is kept alive, e.g. db is update from + // command line, but then overwritten. err = h.UpdateMachineFromDatabase(machine) if err != nil { log.Error(). @@ -431,9 +434,9 @@ func (h *Headscale) PollNetMapStream( Str("channel", "keepAlive"). Int("bytes", len(data)). Msg("Keep alive sent successfully") - // TODO(kradalby): Abstract away all the database calls, this can cause race conditions - // when an outdated machine object is kept alive, e.g. db is update from - // command line, but then overwritten. + // TODO(kradalby): Abstract away all the database calls, this can cause race conditions + // when an outdated machine object is kept alive, e.g. db is update from + // command line, but then overwritten. err = h.UpdateMachineFromDatabase(machine) if err != nil { log.Error(). @@ -588,9 +591,9 @@ func (h *Headscale) PollNetMapStream( Str("handler", "PollNetMapStream"). Str("machine", machine.Hostname). Msg("The client has closed the connection") - // TODO: Abstract away all the database calls, this can cause race conditions - // when an outdated machine object is kept alive, e.g. db is update from - // command line, but then overwritten. + // TODO: Abstract away all the database calls, this can cause race conditions + // when an outdated machine object is kept alive, e.g. db is update from + // command line, but then overwritten. err := h.UpdateMachineFromDatabase(machine) if err != nil { log.Error(). From 3f0639c87ddbb86fd9af3d210eafa98b80301ad1 Mon Sep 17 00:00:00 2001 From: Grigoriy Mikhalkin Date: Mon, 11 Jul 2022 20:33:24 +0200 Subject: [PATCH 07/18] graceful shutdown lint fixes --- app.go | 32 ++++++++++++++++++-------------- config.go | 13 +++++++++---- poll.go | 4 ++-- 3 files changed, 29 insertions(+), 20 deletions(-) diff --git a/app.go b/app.go index de6ef66..5f5e261 100644 --- a/app.go +++ b/app.go @@ -94,8 +94,8 @@ type Headscale struct { ipAllocationMutex sync.Mutex - shutdownChan chan struct{} - wg sync.WaitGroup + shutdownChan chan struct{} + pollNetMapStreamWG sync.WaitGroup } // Look up the TLS constant relative to user-supplied TLS client @@ -148,13 +148,13 @@ func NewHeadscale(cfg *Config) (*Headscale, error) { ) app := Headscale{ - cfg: cfg, - dbType: cfg.DBtype, - dbString: dbString, - privateKey: privKey, - aclRules: tailcfg.FilterAllowAll, // default allowall - registrationCache: registrationCache, - wg: sync.WaitGroup{}, + cfg: cfg, + dbType: cfg.DBtype, + dbString: dbString, + privateKey: privKey, + aclRules: tailcfg.FilterAllowAll, // default allowall + registrationCache: registrationCache, + pollNetMapStreamWG: sync.WaitGroup{}, } err = app.initDB() @@ -672,7 +672,7 @@ func (h *Headscale) Serve() error { syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGHUP) - sig_func := func(c chan os.Signal) { + sigFunc := func(c chan os.Signal) { // Wait for a SIGINT or SIGKILL: for { sig := <-c @@ -703,7 +703,7 @@ func (h *Headscale) Serve() error { Msg("Received signal to stop, shutting down gracefully") close(h.shutdownChan) - h.wg.Wait() + h.pollNetMapStreamWG.Wait() // Gracefully shut down servers ctx, cancel := context.WithTimeout(context.Background(), HTTPShutdownTimeout) @@ -747,7 +747,11 @@ func (h *Headscale) Serve() error { } } } - errorGroup.Go(func() error { sig_func(sigc); return nil }) + errorGroup.Go(func() error { + sigFunc(sigc) + + return nil + }) return errorGroup.Wait() } @@ -771,13 +775,13 @@ func (h *Headscale) getTLSSettings() (*tls.Config, error) { } switch h.cfg.TLS.LetsEncrypt.ChallengeType { - case "TLS-ALPN-01": + case tlsALPN01ChallengeType: // Configuration via autocert with TLS-ALPN-01 (https://tools.ietf.org/html/rfc8737) // The RFC requires that the validation is done on port 443; in other words, headscale // must be reachable on port 443. return certManager.TLSConfig(), nil - case "HTTP-01": + case http01ChallengeType: // Configuration via autocert with HTTP-01. This requires listening on // port 80 for the certificate validation in addition to the headscale // service, which can be configured to run on any other port. diff --git a/config.go b/config.go index 6789f6f..6935840 100644 --- a/config.go +++ b/config.go @@ -18,6 +18,11 @@ import ( "tailscale.com/types/dnstype" ) +const ( + tlsALPN01ChallengeType = "TLS-ALPN-01" + http01ChallengeType = "HTTP-01" +) + // Config contains the initial Headscale configuration. type Config struct { ServerURL string @@ -136,7 +141,7 @@ func LoadConfig(path string, isFile bool) error { viper.AutomaticEnv() viper.SetDefault("tls_letsencrypt_cache_dir", "/var/www/.cache") - viper.SetDefault("tls_letsencrypt_challenge_type", "HTTP-01") + viper.SetDefault("tls_letsencrypt_challenge_type", http01ChallengeType) viper.SetDefault("tls_client_auth_mode", "relaxed") viper.SetDefault("log_level", "info") @@ -179,15 +184,15 @@ func LoadConfig(path string, isFile bool) error { } if (viper.GetString("tls_letsencrypt_hostname") != "") && - (viper.GetString("tls_letsencrypt_challenge_type") == "TLS-ALPN-01") && + (viper.GetString("tls_letsencrypt_challenge_type") == tlsALPN01ChallengeType) && (!strings.HasSuffix(viper.GetString("listen_addr"), ":443")) { // this is only a warning because there could be something sitting in front of headscale that redirects the traffic (e.g. an iptables rule) log.Warn(). Msg("Warning: when using tls_letsencrypt_hostname with TLS-ALPN-01 as challenge type, headscale must be reachable on port 443, i.e. listen_addr should probably end in :443") } - if (viper.GetString("tls_letsencrypt_challenge_type") != "HTTP-01") && - (viper.GetString("tls_letsencrypt_challenge_type") != "TLS-ALPN-01") { + if (viper.GetString("tls_letsencrypt_challenge_type") != http01ChallengeType) && + (viper.GetString("tls_letsencrypt_challenge_type") != tlsALPN01ChallengeType) { errorText += "Fatal config error: the only supported values for tls_letsencrypt_challenge_type are HTTP-01 and TLS-ALPN-01\n" } diff --git a/poll.go b/poll.go index 94941aa..b9a757a 100644 --- a/poll.go +++ b/poll.go @@ -290,8 +290,8 @@ func (h *Headscale) PollNetMapStream( keepAliveChan chan []byte, updateChan chan struct{}, ) { - h.wg.Add(1) - defer h.wg.Done() + h.pollNetMapStreamWG.Add(1) + defer h.pollNetMapStreamWG.Done() ctx := context.WithValue(req.Context(), machineNameContextKey, machine.Hostname) From 395caaad421797ac7fba6a0ca0e7df87d13262f2 Mon Sep 17 00:00:00 2001 From: Grigoriy Mikhalkin Date: Mon, 11 Jul 2022 23:25:13 +0200 Subject: [PATCH 08/18] decompose OIDCCallback method --- oidc.go | 240 +++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 187 insertions(+), 53 deletions(-) diff --git a/oidc.go b/oidc.go index 8b5f024..5509bd4 100644 --- a/oidc.go +++ b/oidc.go @@ -136,6 +136,82 @@ func (h *Headscale) OIDCCallback( writer http.ResponseWriter, req *http.Request, ) { + code, state, ok := validateOIDCCallbackParams(writer, req) + if !ok { + return + } + + rawIDToken, ok := h.getIDTokenForOIDCCallback(writer, code, state) + if !ok { + return + } + + idToken, ok := h.verifyIDTokenForOIDCCallback(writer, rawIDToken) + if !ok { + return + } + + // TODO: we can use userinfo at some point to grab additional information about the user (groups membership, etc) + // userInfo, err := oidcProvider.UserInfo(context.Background(), oauth2.StaticTokenSource(oauth2Token)) + // if err != nil { + // c.String(http.StatusBadRequest, fmt.Sprintf("Failed to retrieve userinfo")) + // return + // } + + claims, ok := extractIDTokenClaims(writer, idToken) + if !ok { + return + } + + if ok := validateOIDCAllowedDomains(writer, h.cfg.OIDC.AllowedDomains, claims); !ok { + return + } + + if ok := validateOIDCAllowedUsers(writer, h.cfg.OIDC.AllowedUsers, claims); !ok { + return + } + + machineKey, ok := h.validateMachineForOIDCCallback(writer, state, claims) + if !ok { + return + } + + namespaceName, ok := getNamespaceName(writer, claims, h.cfg.OIDC.StripEmaildomain) + if !ok { + return + } + + // register the machine if it's new + log.Debug().Msg("Registering new machine after successful callback") + + namespace, ok := h.findOrCreateNewNamespaceForOIDCCallback(writer, namespaceName) + if !ok { + return + } + + if ok := h.registerMachineForOIDCCallback(writer, namespace, machineKey); !ok { + return + } + + content, ok := renderOIDCCallbackTemplate(writer, claims) + if !ok { + return + } + + writer.Header().Set("Content-Type", "text/html; charset=utf-8") + writer.WriteHeader(http.StatusOK) + if _, err := writer.Write(content.Bytes()); err != nil { + log.Error(). + Caller(). + Err(err). + Msg("Failed to write response") + } +} + +func validateOIDCCallbackParams( + writer http.ResponseWriter, + req *http.Request, +) (string, string, bool) { code := req.URL.Query().Get("code") state := req.URL.Query().Get("state") @@ -150,9 +226,16 @@ func (h *Headscale) OIDCCallback( Msg("Failed to write response") } - return + return "", "", false } + return code, state, true +} + +func (h *Headscale) getIDTokenForOIDCCallback( + writer http.ResponseWriter, + code, state string, +) (string, bool) { oauth2Token, err := h.oauth2Config.Exchange(context.Background(), code) if err != nil { log.Error(). @@ -169,7 +252,7 @@ func (h *Headscale) OIDCCallback( Msg("Failed to write response") } - return + return "", false } log.Trace(). @@ -190,11 +273,17 @@ func (h *Headscale) OIDCCallback( Msg("Failed to write response") } - return + return "", false } - verifier := h.oidcProvider.Verifier(&oidc.Config{ClientID: h.cfg.OIDC.ClientID}) + return rawIDToken, true +} +func (h *Headscale) verifyIDTokenForOIDCCallback( + writer http.ResponseWriter, + rawIDToken string, +) (*oidc.IDToken, bool) { + verifier := h.oidcProvider.Verifier(&oidc.Config{ClientID: h.cfg.OIDC.ClientID}) idToken, err := verifier.Verify(context.Background(), rawIDToken) if err != nil { log.Error(). @@ -211,19 +300,18 @@ func (h *Headscale) OIDCCallback( Msg("Failed to write response") } - return + return nil, false } - // TODO: we can use userinfo at some point to grab additional information about the user (groups membership, etc) - // userInfo, err := oidcProvider.UserInfo(context.Background(), oauth2.StaticTokenSource(oauth2Token)) - // if err != nil { - // c.String(http.StatusBadRequest, fmt.Sprintf("Failed to retrieve userinfo")) - // return - // } + return idToken, true +} - // Extract custom claims +func extractIDTokenClaims( + writer http.ResponseWriter, + idToken *oidc.IDToken, +) (*IDTokenClaims, bool) { var claims IDTokenClaims - if err = idToken.Claims(&claims); err != nil { + if err := idToken.Claims(claims); err != nil { log.Error(). Err(err). Caller(). @@ -238,13 +326,22 @@ func (h *Headscale) OIDCCallback( Msg("Failed to write response") } - return + return nil, false } - // If AllowedDomains is provided, check that the authenticated principal ends with @. - if len(h.cfg.OIDC.AllowedDomains) > 0 { + return &claims, true +} + +// validateOIDCAllowedDomains checks that if AllowedDomains is provided, +// that the authenticated principal ends with @. +func validateOIDCAllowedDomains( + writer http.ResponseWriter, + allowedDomains []string, + claims *IDTokenClaims, +) bool { + if len(allowedDomains) > 0 { if at := strings.LastIndex(claims.Email, "@"); at < 0 || - !IsStringInSlice(h.cfg.OIDC.AllowedDomains, claims.Email[at+1:]) { + !IsStringInSlice(allowedDomains, claims.Email[at+1:]) { log.Error().Msg("authenticated principal does not match any allowed domain") writer.Header().Set("Content-Type", "text/plain; charset=utf-8") writer.WriteHeader(http.StatusBadRequest) @@ -256,13 +353,22 @@ func (h *Headscale) OIDCCallback( Msg("Failed to write response") } - return + return false } } - // If AllowedUsers is provided, check that the authenticated princial is part of that list. - if len(h.cfg.OIDC.AllowedUsers) > 0 && - !IsStringInSlice(h.cfg.OIDC.AllowedUsers, claims.Email) { + return true +} + +// validateOIDCAllowedUsers checks that if AllowedUsers is provided, +// that the authenticated principal is part of that list. +func validateOIDCAllowedUsers( + writer http.ResponseWriter, + allowedUsers []string, + claims *IDTokenClaims, +) bool { + if len(allowedUsers) > 0 && + !IsStringInSlice(allowedUsers, claims.Email) { log.Error().Msg("authenticated principal does not match any allowed user") writer.Header().Set("Content-Type", "text/plain; charset=utf-8") writer.WriteHeader(http.StatusBadRequest) @@ -274,12 +380,23 @@ func (h *Headscale) OIDCCallback( Msg("Failed to write response") } - return + return false } + return true +} + +// validateMachine retrieves machine information if it exist +// The error is not important, because if it does not +// exist, then this is a new machine and we will move +// on to registration. +func (h *Headscale) validateMachineForOIDCCallback( + writer http.ResponseWriter, + state string, + claims *IDTokenClaims, +) (*key.MachinePublic, bool) { // retrieve machinekey from state cache machineKeyIf, machineKeyFound := h.registrationCache.Get(state) - if !machineKeyFound { log.Error(). Msg("requested machine state key expired before authorisation completed") @@ -293,13 +410,12 @@ func (h *Headscale) OIDCCallback( Msg("Failed to write response") } - return + return nil, false } - machineKeyFromCache, machineKeyOK := machineKeyIf.(string) - var machineKey key.MachinePublic - err = machineKey.UnmarshalText( + machineKeyFromCache, machineKeyOK := machineKeyIf.(string) + err := machineKey.UnmarshalText( []byte(MachinePublicKeyEnsurePrefix(machineKeyFromCache)), ) if err != nil { @@ -315,7 +431,7 @@ func (h *Headscale) OIDCCallback( Msg("Failed to write response") } - return + return nil, false } if !machineKeyOK { @@ -330,7 +446,7 @@ func (h *Headscale) OIDCCallback( Msg("Failed to write response") } - return + return nil, false } // retrieve machine information if it exist @@ -353,7 +469,7 @@ func (h *Headscale) OIDCCallback( Msg("Failed to refresh machine") http.Error(writer, "Failed to refresh machine", http.StatusInternalServerError) - return + return nil, false } var content bytes.Buffer @@ -377,7 +493,7 @@ func (h *Headscale) OIDCCallback( Msg("Failed to write response") } - return + return nil, false } writer.Header().Set("Content-Type", "text/html; charset=utf-8") @@ -390,12 +506,20 @@ func (h *Headscale) OIDCCallback( Msg("Failed to write response") } - return + return nil, false } + return &machineKey, true +} + +func getNamespaceName( + writer http.ResponseWriter, + claims *IDTokenClaims, + stripEmaildomain bool, +) (string, bool) { namespaceName, err := NormalizeToFQDNRules( claims.Email, - h.cfg.OIDC.StripEmaildomain, + stripEmaildomain, ) if err != nil { log.Error().Err(err).Caller().Msgf("couldn't normalize email") @@ -409,12 +533,16 @@ func (h *Headscale) OIDCCallback( Msg("Failed to write response") } - return + return "", false } - // register the machine if it's new - log.Debug().Msg("Registering new machine after successful callback") + return namespaceName, true +} +func (h *Headscale) findOrCreateNewNamespaceForOIDCCallback( + writer http.ResponseWriter, + namespaceName string, +) (*Namespace, bool) { namespace, err := h.GetNamespace(namespaceName) if errors.Is(err, errNamespaceNotFound) { namespace, err = h.CreateNamespace(namespaceName) @@ -434,7 +562,7 @@ func (h *Headscale) OIDCCallback( Msg("Failed to write response") } - return + return nil, false } } else if err != nil { log.Error(). @@ -452,17 +580,24 @@ func (h *Headscale) OIDCCallback( Msg("Failed to write response") } - return + return nil, false } - machineKeyStr := MachinePublicKeyStripPrefix(machineKey) + return namespace, true +} - _, err = h.RegisterMachineFromAuthCallback( +func (h *Headscale) registerMachineForOIDCCallback( + writer http.ResponseWriter, + namespace *Namespace, + machineKey *key.MachinePublic, +) bool { + machineKeyStr := MachinePublicKeyStripPrefix(*machineKey) + + if _, err := h.RegisterMachineFromAuthCallback( machineKeyStr, namespace.Name, RegisterMethodOIDC, - ) - if err != nil { + ); err != nil { log.Error(). Caller(). Err(err). @@ -477,9 +612,16 @@ func (h *Headscale) OIDCCallback( Msg("Failed to write response") } - return + return false } + return true +} + +func renderOIDCCallbackTemplate( + writer http.ResponseWriter, + claims *IDTokenClaims, +) (*bytes.Buffer, bool) { var content bytes.Buffer if err := oidcCallbackTemplate.Execute(&content, oidcCallbackTemplateConfig{ User: claims.Email, @@ -501,16 +643,8 @@ func (h *Headscale) OIDCCallback( Msg("Failed to write response") } - return + return nil, false } - writer.Header().Set("Content-Type", "text/html; charset=utf-8") - writer.WriteHeader(http.StatusOK) - _, err = writer.Write(content.Bytes()) - if err != nil { - log.Error(). - Caller(). - Err(err). - Msg("Failed to write response") - } + return &content, true } From 56858a56dbd50cc1c0547542a0b78948318e0f30 Mon Sep 17 00:00:00 2001 From: Grigoriy Mikhalkin Date: Thu, 21 Jul 2022 23:47:59 +0200 Subject: [PATCH 09/18] Revert "decompose OIDCCallback method" This reverts commit 395caaad421797ac7fba6a0ca0e7df87d13262f2. --- oidc.go | 240 +++++++++++++------------------------------------------- poll.go | 18 ++--- 2 files changed, 62 insertions(+), 196 deletions(-) diff --git a/oidc.go b/oidc.go index 5509bd4..8b5f024 100644 --- a/oidc.go +++ b/oidc.go @@ -136,82 +136,6 @@ func (h *Headscale) OIDCCallback( writer http.ResponseWriter, req *http.Request, ) { - code, state, ok := validateOIDCCallbackParams(writer, req) - if !ok { - return - } - - rawIDToken, ok := h.getIDTokenForOIDCCallback(writer, code, state) - if !ok { - return - } - - idToken, ok := h.verifyIDTokenForOIDCCallback(writer, rawIDToken) - if !ok { - return - } - - // TODO: we can use userinfo at some point to grab additional information about the user (groups membership, etc) - // userInfo, err := oidcProvider.UserInfo(context.Background(), oauth2.StaticTokenSource(oauth2Token)) - // if err != nil { - // c.String(http.StatusBadRequest, fmt.Sprintf("Failed to retrieve userinfo")) - // return - // } - - claims, ok := extractIDTokenClaims(writer, idToken) - if !ok { - return - } - - if ok := validateOIDCAllowedDomains(writer, h.cfg.OIDC.AllowedDomains, claims); !ok { - return - } - - if ok := validateOIDCAllowedUsers(writer, h.cfg.OIDC.AllowedUsers, claims); !ok { - return - } - - machineKey, ok := h.validateMachineForOIDCCallback(writer, state, claims) - if !ok { - return - } - - namespaceName, ok := getNamespaceName(writer, claims, h.cfg.OIDC.StripEmaildomain) - if !ok { - return - } - - // register the machine if it's new - log.Debug().Msg("Registering new machine after successful callback") - - namespace, ok := h.findOrCreateNewNamespaceForOIDCCallback(writer, namespaceName) - if !ok { - return - } - - if ok := h.registerMachineForOIDCCallback(writer, namespace, machineKey); !ok { - return - } - - content, ok := renderOIDCCallbackTemplate(writer, claims) - if !ok { - return - } - - writer.Header().Set("Content-Type", "text/html; charset=utf-8") - writer.WriteHeader(http.StatusOK) - if _, err := writer.Write(content.Bytes()); err != nil { - log.Error(). - Caller(). - Err(err). - Msg("Failed to write response") - } -} - -func validateOIDCCallbackParams( - writer http.ResponseWriter, - req *http.Request, -) (string, string, bool) { code := req.URL.Query().Get("code") state := req.URL.Query().Get("state") @@ -226,16 +150,9 @@ func validateOIDCCallbackParams( Msg("Failed to write response") } - return "", "", false + return } - return code, state, true -} - -func (h *Headscale) getIDTokenForOIDCCallback( - writer http.ResponseWriter, - code, state string, -) (string, bool) { oauth2Token, err := h.oauth2Config.Exchange(context.Background(), code) if err != nil { log.Error(). @@ -252,7 +169,7 @@ func (h *Headscale) getIDTokenForOIDCCallback( Msg("Failed to write response") } - return "", false + return } log.Trace(). @@ -273,17 +190,11 @@ func (h *Headscale) getIDTokenForOIDCCallback( Msg("Failed to write response") } - return "", false + return } - return rawIDToken, true -} - -func (h *Headscale) verifyIDTokenForOIDCCallback( - writer http.ResponseWriter, - rawIDToken string, -) (*oidc.IDToken, bool) { verifier := h.oidcProvider.Verifier(&oidc.Config{ClientID: h.cfg.OIDC.ClientID}) + idToken, err := verifier.Verify(context.Background(), rawIDToken) if err != nil { log.Error(). @@ -300,18 +211,19 @@ func (h *Headscale) verifyIDTokenForOIDCCallback( Msg("Failed to write response") } - return nil, false + return } - return idToken, true -} + // TODO: we can use userinfo at some point to grab additional information about the user (groups membership, etc) + // userInfo, err := oidcProvider.UserInfo(context.Background(), oauth2.StaticTokenSource(oauth2Token)) + // if err != nil { + // c.String(http.StatusBadRequest, fmt.Sprintf("Failed to retrieve userinfo")) + // return + // } -func extractIDTokenClaims( - writer http.ResponseWriter, - idToken *oidc.IDToken, -) (*IDTokenClaims, bool) { + // Extract custom claims var claims IDTokenClaims - if err := idToken.Claims(claims); err != nil { + if err = idToken.Claims(&claims); err != nil { log.Error(). Err(err). Caller(). @@ -326,22 +238,13 @@ func extractIDTokenClaims( Msg("Failed to write response") } - return nil, false + return } - return &claims, true -} - -// validateOIDCAllowedDomains checks that if AllowedDomains is provided, -// that the authenticated principal ends with @. -func validateOIDCAllowedDomains( - writer http.ResponseWriter, - allowedDomains []string, - claims *IDTokenClaims, -) bool { - if len(allowedDomains) > 0 { + // If AllowedDomains is provided, check that the authenticated principal ends with @. + if len(h.cfg.OIDC.AllowedDomains) > 0 { if at := strings.LastIndex(claims.Email, "@"); at < 0 || - !IsStringInSlice(allowedDomains, claims.Email[at+1:]) { + !IsStringInSlice(h.cfg.OIDC.AllowedDomains, claims.Email[at+1:]) { log.Error().Msg("authenticated principal does not match any allowed domain") writer.Header().Set("Content-Type", "text/plain; charset=utf-8") writer.WriteHeader(http.StatusBadRequest) @@ -353,22 +256,13 @@ func validateOIDCAllowedDomains( Msg("Failed to write response") } - return false + return } } - return true -} - -// validateOIDCAllowedUsers checks that if AllowedUsers is provided, -// that the authenticated principal is part of that list. -func validateOIDCAllowedUsers( - writer http.ResponseWriter, - allowedUsers []string, - claims *IDTokenClaims, -) bool { - if len(allowedUsers) > 0 && - !IsStringInSlice(allowedUsers, claims.Email) { + // If AllowedUsers is provided, check that the authenticated princial is part of that list. + if len(h.cfg.OIDC.AllowedUsers) > 0 && + !IsStringInSlice(h.cfg.OIDC.AllowedUsers, claims.Email) { log.Error().Msg("authenticated principal does not match any allowed user") writer.Header().Set("Content-Type", "text/plain; charset=utf-8") writer.WriteHeader(http.StatusBadRequest) @@ -380,23 +274,12 @@ func validateOIDCAllowedUsers( Msg("Failed to write response") } - return false + return } - return true -} - -// validateMachine retrieves machine information if it exist -// The error is not important, because if it does not -// exist, then this is a new machine and we will move -// on to registration. -func (h *Headscale) validateMachineForOIDCCallback( - writer http.ResponseWriter, - state string, - claims *IDTokenClaims, -) (*key.MachinePublic, bool) { // retrieve machinekey from state cache machineKeyIf, machineKeyFound := h.registrationCache.Get(state) + if !machineKeyFound { log.Error(). Msg("requested machine state key expired before authorisation completed") @@ -410,12 +293,13 @@ func (h *Headscale) validateMachineForOIDCCallback( Msg("Failed to write response") } - return nil, false + return } - var machineKey key.MachinePublic machineKeyFromCache, machineKeyOK := machineKeyIf.(string) - err := machineKey.UnmarshalText( + + var machineKey key.MachinePublic + err = machineKey.UnmarshalText( []byte(MachinePublicKeyEnsurePrefix(machineKeyFromCache)), ) if err != nil { @@ -431,7 +315,7 @@ func (h *Headscale) validateMachineForOIDCCallback( Msg("Failed to write response") } - return nil, false + return } if !machineKeyOK { @@ -446,7 +330,7 @@ func (h *Headscale) validateMachineForOIDCCallback( Msg("Failed to write response") } - return nil, false + return } // retrieve machine information if it exist @@ -469,7 +353,7 @@ func (h *Headscale) validateMachineForOIDCCallback( Msg("Failed to refresh machine") http.Error(writer, "Failed to refresh machine", http.StatusInternalServerError) - return nil, false + return } var content bytes.Buffer @@ -493,7 +377,7 @@ func (h *Headscale) validateMachineForOIDCCallback( Msg("Failed to write response") } - return nil, false + return } writer.Header().Set("Content-Type", "text/html; charset=utf-8") @@ -506,20 +390,12 @@ func (h *Headscale) validateMachineForOIDCCallback( Msg("Failed to write response") } - return nil, false + return } - return &machineKey, true -} - -func getNamespaceName( - writer http.ResponseWriter, - claims *IDTokenClaims, - stripEmaildomain bool, -) (string, bool) { namespaceName, err := NormalizeToFQDNRules( claims.Email, - stripEmaildomain, + h.cfg.OIDC.StripEmaildomain, ) if err != nil { log.Error().Err(err).Caller().Msgf("couldn't normalize email") @@ -533,16 +409,12 @@ func getNamespaceName( Msg("Failed to write response") } - return "", false + return } - return namespaceName, true -} + // register the machine if it's new + log.Debug().Msg("Registering new machine after successful callback") -func (h *Headscale) findOrCreateNewNamespaceForOIDCCallback( - writer http.ResponseWriter, - namespaceName string, -) (*Namespace, bool) { namespace, err := h.GetNamespace(namespaceName) if errors.Is(err, errNamespaceNotFound) { namespace, err = h.CreateNamespace(namespaceName) @@ -562,7 +434,7 @@ func (h *Headscale) findOrCreateNewNamespaceForOIDCCallback( Msg("Failed to write response") } - return nil, false + return } } else if err != nil { log.Error(). @@ -580,24 +452,17 @@ func (h *Headscale) findOrCreateNewNamespaceForOIDCCallback( Msg("Failed to write response") } - return nil, false + return } - return namespace, true -} + machineKeyStr := MachinePublicKeyStripPrefix(machineKey) -func (h *Headscale) registerMachineForOIDCCallback( - writer http.ResponseWriter, - namespace *Namespace, - machineKey *key.MachinePublic, -) bool { - machineKeyStr := MachinePublicKeyStripPrefix(*machineKey) - - if _, err := h.RegisterMachineFromAuthCallback( + _, err = h.RegisterMachineFromAuthCallback( machineKeyStr, namespace.Name, RegisterMethodOIDC, - ); err != nil { + ) + if err != nil { log.Error(). Caller(). Err(err). @@ -612,16 +477,9 @@ func (h *Headscale) registerMachineForOIDCCallback( Msg("Failed to write response") } - return false + return } - return true -} - -func renderOIDCCallbackTemplate( - writer http.ResponseWriter, - claims *IDTokenClaims, -) (*bytes.Buffer, bool) { var content bytes.Buffer if err := oidcCallbackTemplate.Execute(&content, oidcCallbackTemplateConfig{ User: claims.Email, @@ -643,8 +501,16 @@ func renderOIDCCallbackTemplate( Msg("Failed to write response") } - return nil, false + return } - return &content, true + writer.Header().Set("Content-Type", "text/html; charset=utf-8") + writer.WriteHeader(http.StatusOK) + _, err = writer.Write(content.Bytes()) + if err != nil { + log.Error(). + Caller(). + Err(err). + Msg("Failed to write response") + } } diff --git a/poll.go b/poll.go index b9a757a..9c17b5c 100644 --- a/poll.go +++ b/poll.go @@ -356,9 +356,9 @@ func (h *Headscale) PollNetMapStream( Str("channel", "pollData"). Int("bytes", len(data)). Msg("Data from pollData channel written successfully") - // TODO(kradalby): Abstract away all the database calls, this can cause race conditions - // when an outdated machine object is kept alive, e.g. db is update from - // command line, but then overwritten. + // TODO(kradalby): Abstract away all the database calls, this can cause race conditions + // when an outdated machine object is kept alive, e.g. db is update from + // command line, but then overwritten. err = h.UpdateMachineFromDatabase(machine) if err != nil { log.Error(). @@ -434,9 +434,9 @@ func (h *Headscale) PollNetMapStream( Str("channel", "keepAlive"). Int("bytes", len(data)). Msg("Keep alive sent successfully") - // TODO(kradalby): Abstract away all the database calls, this can cause race conditions - // when an outdated machine object is kept alive, e.g. db is update from - // command line, but then overwritten. + // TODO(kradalby): Abstract away all the database calls, this can cause race conditions + // when an outdated machine object is kept alive, e.g. db is update from + // command line, but then overwritten. err = h.UpdateMachineFromDatabase(machine) if err != nil { log.Error(). @@ -591,9 +591,9 @@ func (h *Headscale) PollNetMapStream( Str("handler", "PollNetMapStream"). Str("machine", machine.Hostname). Msg("The client has closed the connection") - // TODO: Abstract away all the database calls, this can cause race conditions - // when an outdated machine object is kept alive, e.g. db is update from - // command line, but then overwritten. + // TODO: Abstract away all the database calls, this can cause race conditions + // when an outdated machine object is kept alive, e.g. db is update from + // command line, but then overwritten. err := h.UpdateMachineFromDatabase(machine) if err != nil { log.Error(). From a4d0efbe8d1cfc61b4b3934d8e15d6032be71781 Mon Sep 17 00:00:00 2001 From: Juan Font Alonso Date: Thu, 21 Jul 2022 23:57:07 +0200 Subject: [PATCH 10/18] Fix API router --- app.go | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/app.go b/app.go index 11c8d68..d7d5ea5 100644 --- a/app.go +++ b/app.go @@ -445,11 +445,9 @@ func (h *Headscale) createRouter(grpcMux *runtime.ServeMux) *mux.Router { router.HandleFunc("/bootstrap-dns", h.DERPBootstrapDNSHandler) } - api := router.PathPrefix("/api").Subrouter() - api.Use(h.httpAuthenticationMiddleware) - { - api.HandleFunc("/v1/*any", grpcMux.ServeHTTP) - } + apiRouter := router.PathPrefix("/api").Subrouter() + apiRouter.Use(h.httpAuthenticationMiddleware) + apiRouter.PathPrefix("/v1/").HandlerFunc(grpcMux.ServeHTTP) router.PathPrefix("/").HandlerFunc(stdoutHandler) From 6c9f3420e250c610fa164af64ce8ac9d6c2d7779 Mon Sep 17 00:00:00 2001 From: Juan Font Alonso Date: Thu, 21 Jul 2022 23:59:44 +0200 Subject: [PATCH 11/18] Updated changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e1ec1b6..f43dfea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,6 +34,7 @@ - Improve shutdown behaviour [#651](https://github.com/juanfont/headscale/pull/651) - Drop Gin as web framework in Headscale [648](https://github.com/juanfont/headscale/pull/648) [677](https://github.com/juanfont/headscale/pull/677) - Make tailnet node updates check interval configurable [#675](https://github.com/juanfont/headscale/pull/675) +- Fix regression with HTTP API [#684](https://github.com/juanfont/headscale/pull/684) ## 0.15.0 (2022-03-20) From 936adb7d2c0abfcd9333f5166d240deaf2fc16b5 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 22 Jul 2022 07:36:16 +0000 Subject: [PATCH 12/18] docs(README): update contributors --- README.md | 39 +++++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 38578c3..d088767 100644 --- a/README.md +++ b/README.md @@ -283,6 +283,15 @@ make build Fernando De Lucchi + + + GrigoriyMikhalkin/ +
+ GrigoriyMikhalkin +
+ + + Hoàng @@ -290,8 +299,6 @@ make build Hoàng Đức Hiếu - - bravechamp/ @@ -327,6 +334,8 @@ make build Michael G. + + Paul @@ -334,8 +343,6 @@ make build Paul Tötterman - - Samuel @@ -371,6 +378,8 @@ make build Pavlos Vinieratos + + Silver @@ -378,8 +387,6 @@ make build Silver Bullet - - lachy2849/ @@ -415,6 +422,8 @@ make build Aofei Sheng + + Arthur @@ -422,8 +431,6 @@ make build Arthur Woimbée - - Bryan @@ -459,6 +466,8 @@ make build Felix Yan + + JJGadgets/ @@ -466,8 +475,6 @@ make build JJGadgets - - Jamie @@ -503,6 +510,8 @@ make build WhiteSource Renovate + + Ryan @@ -510,8 +519,6 @@ make build Ryan Fowler - - Shaanan @@ -547,6 +554,8 @@ make build Tianon Gravi + + Tjerk @@ -554,8 +563,6 @@ make build Tjerk Woudsma - - Yang @@ -591,6 +598,8 @@ make build henning mueller + + ignoramous/ @@ -598,8 +607,6 @@ make build ignoramous - - lion24/ From dc94570c4ad5a120b14751200605c181f43a94d3 Mon Sep 17 00:00:00 2001 From: Jiang Zhu Date: Sat, 23 Jul 2022 01:33:11 +0800 Subject: [PATCH 13/18] more intuitive output of node ls --- cmd/headscale/cli/nodes.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cmd/headscale/cli/nodes.go b/cmd/headscale/cli/nodes.go index 059a16d..c2b1e95 100644 --- a/cmd/headscale/cli/nodes.go +++ b/cmd/headscale/cli/nodes.go @@ -465,6 +465,7 @@ func nodesToPtables( ) (pterm.TableData, error) { tableHeader := []string{ "ID", + "Hostname", "Name", "NodeKey", "Namespace", @@ -566,6 +567,7 @@ func nodesToPtables( nodeData := []string{ strconv.FormatUint(machine.Id, headscale.Base10), machine.Name, + machine.GetGivenName(), nodeKey.ShortString(), namespace, strings.Join([]string{IPV4Address, IPV6Address}, ", "), From 49354f678efa1b58cc53727afb26daa249414c5f Mon Sep 17 00:00:00 2001 From: Jiang Zhu Date: Sat, 23 Jul 2022 04:47:37 +0800 Subject: [PATCH 14/18] update CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f43dfea..2c2ae62 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,6 +35,7 @@ - Drop Gin as web framework in Headscale [648](https://github.com/juanfont/headscale/pull/648) [677](https://github.com/juanfont/headscale/pull/677) - Make tailnet node updates check interval configurable [#675](https://github.com/juanfont/headscale/pull/675) - Fix regression with HTTP API [#684](https://github.com/juanfont/headscale/pull/684) +- nodes ls now print both Hostname and Name(Issue [#647](https://github.com/juanfont/headscale/issues/647) PR [#687](https://github.com/juanfont/headscale/pull/687)) ## 0.15.0 (2022-03-20) From 693f59ba2f07d4ac3ea7146ac0882b6a0ddf062b Mon Sep 17 00:00:00 2001 From: Juan Font Alonso Date: Mon, 25 Jul 2022 10:35:21 +0200 Subject: [PATCH 15/18] Prepare changelog structure for 0.17.0 --- CHANGELOG.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2c2ae62..cca3152 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,12 @@ # CHANGELOG -## 0.16.0 (2022-xx-xx) + +## 0.17.0 (2022-xx-xx) + + +## 0.16.0 (2022-07-25) + +**Note:** Take a backup of your database before upgrading. ### BREAKING From 6f4d5a532e168787933cf084c095f618c01d3cfe Mon Sep 17 00:00:00 2001 From: Juan Font Alonso Date: Tue, 26 Jul 2022 11:25:20 +0200 Subject: [PATCH 16/18] fixed linting errors --- CHANGELOG.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cca3152..d9a3a13 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,9 +1,7 @@ # CHANGELOG - ## 0.17.0 (2022-xx-xx) - ## 0.16.0 (2022-07-25) **Note:** Take a backup of your database before upgrading. From b344524a6d084323587d92c17676628a49007276 Mon Sep 17 00:00:00 2001 From: Juan Font Alonso Date: Tue, 26 Jul 2022 12:02:58 +0200 Subject: [PATCH 17/18] Update runc dependencies to fix security notification --- go.mod | 8 ++++---- go.sum | 18 ++++++++++++++++++ 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/go.mod b/go.mod index 80a3e48..4784ef2 100644 --- a/go.mod +++ b/go.mod @@ -14,7 +14,7 @@ require ( github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 github.com/grpc-ecosystem/grpc-gateway/v2 v2.10.0 github.com/klauspost/compress v1.15.4 - github.com/ory/dockertest/v3 v3.8.1 + github.com/ory/dockertest/v3 v3.9.1 github.com/patrickmn/go-cache v2.1.0+incompatible github.com/philip-bui/grpc-zerolog v1.0.1 github.com/prometheus/client_golang v1.12.1 @@ -50,9 +50,9 @@ require ( github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74 // indirect github.com/atomicgo/cursor v0.0.1 // indirect github.com/beorn7/perks v1.0.1 // indirect - github.com/cenkalti/backoff/v4 v4.1.2 // indirect + github.com/cenkalti/backoff/v4 v4.1.3 // indirect github.com/cespare/xxhash/v2 v2.1.2 // indirect - github.com/containerd/continuity v0.0.0-20190827140505-75bee3e2ccb6 // indirect + github.com/containerd/continuity v0.3.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/docker/cli v20.10.16+incompatible // indirect github.com/docker/docker v20.10.16+incompatible // indirect @@ -100,7 +100,7 @@ require ( github.com/moby/term v0.0.0-20201216013528-df9cb8a40635 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.0.3-0.20220114050600-8b9d41f48198 // indirect - github.com/opencontainers/runc v1.0.2 // indirect + github.com/opencontainers/runc v1.1.2 // indirect github.com/pelletier/go-toml v1.9.4 // indirect github.com/pelletier/go-toml/v2 v2.0.0-beta.8 // indirect github.com/pkg/errors v0.9.1 // indirect diff --git a/go.sum b/go.sum index 3290d9c..c2a781a 100644 --- a/go.sum +++ b/go.sum @@ -131,6 +131,8 @@ github.com/ccding/go-stun/stun v0.0.0-20200514191101-4dc67bcdb029 h1:POmUHfxXdey github.com/ccding/go-stun/stun v0.0.0-20200514191101-4dc67bcdb029/go.mod h1:Rpr5n9cGHYdM3S3IK8ROSUUUYjQOu+MSUCZDcJbYWi8= github.com/cenkalti/backoff/v4 v4.1.2 h1:6Yo7N8UP2K6LWZnW94DLVSSrbobcWdVzAYOisuDPIFo= github.com/cenkalti/backoff/v4 v4.1.2/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= +github.com/cenkalti/backoff/v4 v4.1.3 h1:cFAlzYUlVYDysBEH2T5hyJZMh3+5+WCBvSnK6Q8UtC4= +github.com/cenkalti/backoff/v4 v4.1.3/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= @@ -139,10 +141,12 @@ github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL github.com/charithe/durationcheck v0.0.9/go.mod h1:SSbRIBVfMjCi/kEB6K65XEA83D6prSM8ap1UCpNKtgg= github.com/chavacava/garif v0.0.0-20210405164556-e8a0a408d6af/go.mod h1:Qjyv4H3//PWVzTeCezG2b9IRn6myJxJSr4TD/xo6ojU= github.com/checkpoint-restore/go-criu/v5 v5.0.0/go.mod h1:cfwC0EG7HMUenopBsUf9d89JlCLQIfgVcNsNN0t6T2M= +github.com/checkpoint-restore/go-criu/v5 v5.3.0/go.mod h1:E/eQpaFtUKGOOSEBZgmKAcn+zUUwWxqcaKZlF54wK8E= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/cilium/ebpf v0.6.2/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= +github.com/cilium/ebpf v0.7.0/go.mod h1:/oI2+1shJiTGAMgl6/RgJr36Eo1jzrRcAWbcXO2usCA= github.com/cilium/ebpf v0.8.1 h1:bLSSEbBLqGPXxls55pGr5qWZaTqcmfDJHhou7t254ao= github.com/cilium/ebpf v0.8.1/go.mod h1:f5zLIM0FSNuAkSyLAN7X+Hy6yznlF1mNiWUMfxMtrgk= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= @@ -159,8 +163,11 @@ github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= github.com/containerd/console v1.0.2/go.mod h1:ytZPjGgY2oeTkAONYafi2kSj0aYggsf8acV1PGKCbzQ= +github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U= github.com/containerd/continuity v0.0.0-20190827140505-75bee3e2ccb6 h1:NmTXa/uVnDyp0TY5MKi197+3HWcnYWfnHGyaFthlnGw= github.com/containerd/continuity v0.0.0-20190827140505-75bee3e2ccb6/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= +github.com/containerd/continuity v0.3.0 h1:nisirsYROK15TAMVukJOUyGJjz4BNQJBVsNvAXZJ/eg= +github.com/containerd/continuity v0.3.0/go.mod h1:wJEAIwKOm/pBZuBd0JmeTvnLquTB1Ag8espWhkykbPM= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-oidc/v3 v3.1.0 h1:6avEvcdvTa1qYsOZ6I5PRkSYHzpTNWgKYmaJfaYbrRw= @@ -184,6 +191,7 @@ github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ github.com/creack/pty v1.1.17 h1:QeVUsEDNrLBW4tMgZHvxy18sKtr6VI492kBhUfhDJNI= github.com/creack/pty v1.1.17/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4= +github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= github.com/daixiang0/gci v0.2.9/go.mod h1:+4dZ7TISfSmqfAGv59ePaHfNzgGtIkHAhhdKggP1JAc= github.com/davecgh/go-spew v0.0.0-20161028175848-04cdfd42973b/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -271,6 +279,7 @@ github.com/go-toolsmith/typep v1.0.2/go.mod h1:JSQCQMUPdRlMZFswiq3TGpNp1GMktqkR2 github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b/go.mod h1:aUCEOzzezBEjDBbFBoSiya/gduyIiWYRP6CnSFIV8AM= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/godbus/dbus/v5 v5.0.6/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gofrs/uuid v4.2.0+incompatible h1:yyYWMnhkhrKwwr8gAOcOCYxOOscHgDS9yZgBrnJfGa0= @@ -667,6 +676,7 @@ github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RR github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/mitchellh/reflectwalk v1.0.1/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/moby/sys/mountinfo v0.4.1/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A= +github.com/moby/sys/mountinfo v0.5.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU= github.com/moby/term v0.0.0-20201216013528-df9cb8a40635 h1:rzf0wL0CHVc8CEsgyygG0Mn9CNCCPZqOPaz8RiiHYQk= github.com/moby/term v0.0.0-20201216013528-df9cb8a40635/go.mod h1:FBS0z0QWA44HXygs7VXDUOGoN/1TV3RuWkLO04am3wc= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -710,11 +720,16 @@ github.com/opencontainers/image-spec v1.0.3-0.20220114050600-8b9d41f48198 h1:+cz github.com/opencontainers/image-spec v1.0.3-0.20220114050600-8b9d41f48198/go.mod h1:j4h1pJW6ZcJTgMZWP3+7RlG3zTaP02aDZ/Qw0sppK7Q= github.com/opencontainers/runc v1.0.2 h1:opHZMaswlyxz1OuGpBE53Dwe4/xF7EZTY0A2L/FpCOg= github.com/opencontainers/runc v1.0.2/go.mod h1:aTaHFFwQXuA71CiyxOdFFIorAoemI04suvGRQFzWTD0= +github.com/opencontainers/runc v1.1.2 h1:2VSZwLx5k/BfsBxMMipG/LYUnmqOD/BPkIVgQUcTlLw= +github.com/opencontainers/runc v1.1.2/go.mod h1:Tj1hFw6eFWp/o33uxGf5yF2BX5yz2Z6iptFpuvbbKqc= github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/selinux v1.8.2/go.mod h1:MUIHuUEvKB1wtJjQdOyYRgOnLD2xAPP8dBsCoU0KuF8= +github.com/opencontainers/selinux v1.10.0/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/ory/dockertest/v3 v3.8.1 h1:vU/8d1We4qIad2YM0kOwRVtnyue7ExvacPiw1yDm17g= github.com/ory/dockertest/v3 v3.8.1/go.mod h1:wSRQ3wmkz+uSARYMk7kVJFDBGm8x5gSxIhI7NDc+BAQ= +github.com/ory/dockertest/v3 v3.9.1 h1:v4dkG+dlu76goxMiTT2j8zV7s4oPPEppKT8K8p2f1kY= +github.com/ory/dockertest/v3 v3.9.1/go.mod h1:42Ir9hmvaAPm0Mgibk6mBPi7SFvTXxEcnztDYOJ//uM= github.com/otiai10/copy v1.2.0/go.mod h1:rrF5dJ5F0t/EWSYODDu4j9/vEeYHMkc8jt0zJChqQWw= github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE= github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs= @@ -820,6 +835,7 @@ github.com/sanposhiho/wastedassign/v2 v2.0.6/go.mod h1:KyZ0MWTwxxBmfwn33zh3k1dms github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo= +github.com/seccomp/libseccomp-golang v0.9.2-0.20210429002308-3879420cc921/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg= github.com/securego/gosec/v2 v2.9.1/go.mod h1:oDcDLcatOJxkCGaCaq8lua1jTnYf6Sou4wdiJ1n4iHc= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= @@ -1222,6 +1238,8 @@ golang.org/x/sys v0.0.0-20210917161153-d61c044b1678/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211013075003-97ac67df715c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= From 75af83bb81439c1a454fc6a4ffad4095744fadd0 Mon Sep 17 00:00:00 2001 From: Juan Font Alonso Date: Tue, 26 Jul 2022 12:11:15 +0200 Subject: [PATCH 18/18] Update checksum for nix --- flake.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flake.nix b/flake.nix index f9f3c83..ec83d41 100644 --- a/flake.nix +++ b/flake.nix @@ -24,7 +24,7 @@ # When updating go.mod or go.sum, a new sha will need to be calculated, # update this if you have a mismatch after doing a change to thos files. - vendorSha256 = "sha256-b9C6F+7N0ecW0HiTx+rztZnxb+n6U6YTSOJvp3GqnWQ="; + vendorSha256 = "sha256-2o78hsi0B9U5NOcYXRqkBmg34p71J/R8FibXsgwEcSo="; ldflags = [ "-s" "-w" "-X github.com/juanfont/headscale/cmd/headscale/cli.Version=v${version}" ]; };