mirror of
https://github.com/juanfont/headscale.git
synced 2024-12-20 19:09:07 +01:00
Remove all instances of undefined numbers (gonmd)
This commit is contained in:
parent
796072a5a4
commit
85f28a3f4a
@ -29,7 +29,6 @@ linters:
|
||||
- testpackage
|
||||
- stylecheck
|
||||
- wrapcheck
|
||||
- gomnd
|
||||
- goerr113
|
||||
- errorlint
|
||||
- forcetypeassert
|
||||
|
24
acls.go
24
acls.go
@ -24,6 +24,14 @@ const (
|
||||
errorInvalidPortFormat = Error("invalid port format")
|
||||
)
|
||||
|
||||
const (
|
||||
PORT_RANGE_BEGIN = 0
|
||||
PORT_RANGE_END = 65535
|
||||
BASE_10 = 10
|
||||
BIT_SIZE_16 = 16
|
||||
EXPECTED_TOKEN_ITEMS = 2
|
||||
)
|
||||
|
||||
// LoadACLPolicy loads the ACL policy from the specify path, and generates the ACL rules.
|
||||
func (h *Headscale) LoadACLPolicy(path string) error {
|
||||
policyFile, err := os.Open(path)
|
||||
@ -114,7 +122,7 @@ func (h *Headscale) generateACLPolicyDestPorts(
|
||||
d string,
|
||||
) ([]tailcfg.NetPortRange, error) {
|
||||
tokens := strings.Split(d, ":")
|
||||
if len(tokens) < 2 || len(tokens) > 3 {
|
||||
if len(tokens) < EXPECTED_TOKEN_ITEMS || len(tokens) > 3 {
|
||||
return nil, errorInvalidPortFormat
|
||||
}
|
||||
|
||||
@ -125,7 +133,7 @@ func (h *Headscale) generateACLPolicyDestPorts(
|
||||
// tag:montreal-webserver:80,443
|
||||
// tag:api-server:443
|
||||
// example-host-1:*
|
||||
if len(tokens) == 2 {
|
||||
if len(tokens) == EXPECTED_TOKEN_ITEMS {
|
||||
alias = tokens[0]
|
||||
} else {
|
||||
alias = fmt.Sprintf("%s:%s", tokens[0], tokens[1])
|
||||
@ -248,14 +256,16 @@ func (h *Headscale) expandAlias(s string) ([]string, error) {
|
||||
|
||||
func (h *Headscale) expandPorts(s string) (*[]tailcfg.PortRange, error) {
|
||||
if s == "*" {
|
||||
return &[]tailcfg.PortRange{{First: 0, Last: 65535}}, nil
|
||||
return &[]tailcfg.PortRange{
|
||||
{First: PORT_RANGE_BEGIN, Last: PORT_RANGE_END},
|
||||
}, nil
|
||||
}
|
||||
|
||||
ports := []tailcfg.PortRange{}
|
||||
for _, p := range strings.Split(s, ",") {
|
||||
rang := strings.Split(p, "-")
|
||||
if len(rang) == 1 {
|
||||
pi, err := strconv.ParseUint(rang[0], 10, 16)
|
||||
pi, err := strconv.ParseUint(rang[0], BASE_10, BIT_SIZE_16)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -263,12 +273,12 @@ func (h *Headscale) expandPorts(s string) (*[]tailcfg.PortRange, error) {
|
||||
First: uint16(pi),
|
||||
Last: uint16(pi),
|
||||
})
|
||||
} else if len(rang) == 2 {
|
||||
start, err := strconv.ParseUint(rang[0], 10, 16)
|
||||
} else if len(rang) == EXPECTED_TOKEN_ITEMS {
|
||||
start, err := strconv.ParseUint(rang[0], BASE_10, BIT_SIZE_16)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
last, err := strconv.ParseUint(rang[1], 10, 16)
|
||||
last, err := strconv.ParseUint(rang[1], BASE_10, BIT_SIZE_16)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
22
api.go
22
api.go
@ -18,10 +18,12 @@ import (
|
||||
"tailscale.com/types/wgkey"
|
||||
)
|
||||
|
||||
const RESERVED_RESPONSE_HEADER_SIZE = 4
|
||||
|
||||
// KeyHandler provides the Headscale pub key
|
||||
// Listens in /key.
|
||||
func (h *Headscale) KeyHandler(c *gin.Context) {
|
||||
c.Data(200, "text/plain; charset=utf-8", []byte(h.publicKey.HexString()))
|
||||
c.Data(http.StatusOK, "text/plain; charset=utf-8", []byte(h.publicKey.HexString()))
|
||||
}
|
||||
|
||||
// RegisterWebAPI shows a simple message in the browser to point to the CLI
|
||||
@ -139,7 +141,7 @@ func (h *Headscale) RegistrationHandler(c *gin.Context) {
|
||||
|
||||
return
|
||||
}
|
||||
c.Data(200, "application/json; charset=utf-8", respBody)
|
||||
c.Data(http.StatusOK, "application/json; charset=utf-8", respBody)
|
||||
|
||||
return
|
||||
}
|
||||
@ -170,7 +172,7 @@ func (h *Headscale) RegistrationHandler(c *gin.Context) {
|
||||
}
|
||||
machineRegistrations.WithLabelValues("update", "web", "success", m.Namespace.Name).
|
||||
Inc()
|
||||
c.Data(200, "application/json; charset=utf-8", respBody)
|
||||
c.Data(http.StatusOK, "application/json; charset=utf-8", respBody)
|
||||
|
||||
return
|
||||
}
|
||||
@ -213,7 +215,7 @@ func (h *Headscale) RegistrationHandler(c *gin.Context) {
|
||||
}
|
||||
machineRegistrations.WithLabelValues("new", "web", "success", m.Namespace.Name).
|
||||
Inc()
|
||||
c.Data(200, "application/json; charset=utf-8", respBody)
|
||||
c.Data(http.StatusOK, "application/json; charset=utf-8", respBody)
|
||||
|
||||
return
|
||||
}
|
||||
@ -239,7 +241,7 @@ func (h *Headscale) RegistrationHandler(c *gin.Context) {
|
||||
|
||||
return
|
||||
}
|
||||
c.Data(200, "application/json; charset=utf-8", respBody)
|
||||
c.Data(http.StatusOK, "application/json; charset=utf-8", respBody)
|
||||
|
||||
return
|
||||
}
|
||||
@ -275,7 +277,7 @@ func (h *Headscale) RegistrationHandler(c *gin.Context) {
|
||||
|
||||
return
|
||||
}
|
||||
c.Data(200, "application/json; charset=utf-8", respBody)
|
||||
c.Data(http.StatusOK, "application/json; charset=utf-8", respBody)
|
||||
}
|
||||
|
||||
func (h *Headscale) getMapResponse(
|
||||
@ -360,7 +362,7 @@ func (h *Headscale) getMapResponse(
|
||||
}
|
||||
}
|
||||
// declare the incoming size on the first 4 bytes
|
||||
data := make([]byte, 4)
|
||||
data := make([]byte, RESERVED_RESPONSE_HEADER_SIZE)
|
||||
binary.LittleEndian.PutUint32(data, uint32(len(respBody)))
|
||||
data = append(data, respBody...)
|
||||
|
||||
@ -390,7 +392,7 @@ func (h *Headscale) getMapKeepAliveResponse(
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
data := make([]byte, 4)
|
||||
data := make([]byte, RESERVED_RESPONSE_HEADER_SIZE)
|
||||
binary.LittleEndian.PutUint32(data, uint32(len(respBody)))
|
||||
data = append(data, respBody...)
|
||||
|
||||
@ -430,7 +432,7 @@ func (h *Headscale) handleAuthKey(
|
||||
|
||||
return
|
||||
}
|
||||
c.Data(401, "application/json; charset=utf-8", respBody)
|
||||
c.Data(http.StatusUnauthorized, "application/json; charset=utf-8", respBody)
|
||||
log.Error().
|
||||
Str("func", "handleAuthKey").
|
||||
Str("machine", m.Name).
|
||||
@ -490,7 +492,7 @@ func (h *Headscale) handleAuthKey(
|
||||
}
|
||||
machineRegistrations.WithLabelValues("new", "authkey", "success", m.Namespace.Name).
|
||||
Inc()
|
||||
c.Data(200, "application/json; charset=utf-8", respBody)
|
||||
c.Data(http.StatusOK, "application/json; charset=utf-8", respBody)
|
||||
log.Info().
|
||||
Str("func", "handleAuthKey").
|
||||
Str("machine", m.Name).
|
||||
|
15
app.go
15
app.go
@ -47,9 +47,11 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
AUTH_PREFIX = "Bearer "
|
||||
POSTGRESQL = "postgresql"
|
||||
SQLITE = "sqlite3"
|
||||
AUTH_PREFIX = "Bearer "
|
||||
POSTGRESQL = "postgresql"
|
||||
SQLITE = "sqlite3"
|
||||
UPDATE_RATE_MILLISECONDS = 5000
|
||||
HTTP_READ_TIMEOUT = 30 * time.Second
|
||||
)
|
||||
|
||||
// Config contains the initial Headscale configuration.
|
||||
@ -507,14 +509,13 @@ func (h *Headscale) Serve() error {
|
||||
}
|
||||
|
||||
// I HATE THIS
|
||||
updateMillisecondsWait := int64(5000)
|
||||
go h.watchForKVUpdates(updateMillisecondsWait)
|
||||
go h.expireEphemeralNodes(updateMillisecondsWait)
|
||||
go h.watchForKVUpdates(UPDATE_RATE_MILLISECONDS)
|
||||
go h.expireEphemeralNodes(UPDATE_RATE_MILLISECONDS)
|
||||
|
||||
httpServer := &http.Server{
|
||||
Addr: h.cfg.Addr,
|
||||
Handler: r,
|
||||
ReadTimeout: 30 * time.Second,
|
||||
ReadTimeout: HTTP_READ_TIMEOUT,
|
||||
// Go does not handle timeouts in HTTP very well, and there is
|
||||
// no good way to handle streaming timeouts, therefore we need to
|
||||
// keep this at unlimited and be careful to clean up connections
|
||||
|
@ -195,7 +195,8 @@ var renameNamespaceCmd = &cobra.Command{
|
||||
Use: "rename OLD_NAME NEW_NAME",
|
||||
Short: "Renames a namespace",
|
||||
Args: func(cmd *cobra.Command, args []string) error {
|
||||
if len(args) < 2 {
|
||||
expectedArguments := 2
|
||||
if len(args) < expectedArguments {
|
||||
return fmt.Errorf("Missing parameters")
|
||||
}
|
||||
|
||||
|
@ -7,6 +7,7 @@ import (
|
||||
"time"
|
||||
|
||||
survey "github.com/AlecAivazis/survey/v2"
|
||||
"github.com/juanfont/headscale"
|
||||
v1 "github.com/juanfont/headscale/gen/go/headscale/v1"
|
||||
"github.com/pterm/pterm"
|
||||
"github.com/spf13/cobra"
|
||||
@ -450,7 +451,7 @@ func nodesToPtables(
|
||||
d = append(
|
||||
d,
|
||||
[]string{
|
||||
strconv.FormatUint(machine.Id, 10),
|
||||
strconv.FormatUint(machine.Id, headscale.BASE_10),
|
||||
machine.Name,
|
||||
nodeKey.ShortString(),
|
||||
namespace,
|
||||
|
@ -12,6 +12,10 @@ import (
|
||||
"google.golang.org/protobuf/types/known/timestamppb"
|
||||
)
|
||||
|
||||
const (
|
||||
DEFAULT_PRE_AUTH_KEY_EXPIRY = 24 * time.Hour
|
||||
)
|
||||
|
||||
func init() {
|
||||
rootCmd.AddCommand(preauthkeysCmd)
|
||||
preauthkeysCmd.PersistentFlags().StringP("namespace", "n", "", "Namespace")
|
||||
@ -27,7 +31,7 @@ func init() {
|
||||
createPreAuthKeyCmd.PersistentFlags().
|
||||
Bool("ephemeral", false, "Preauthkey for ephemeral nodes")
|
||||
createPreAuthKeyCmd.Flags().
|
||||
DurationP("expiration", "e", 24*time.Hour, "Human-readable expiration of the key (30m, 24h, 365d...)")
|
||||
DurationP("expiration", "e", DEFAULT_PRE_AUTH_KEY_EXPIRY, "Human-readable expiration of the key (30m, 24h, 365d...)")
|
||||
}
|
||||
|
||||
var preauthkeysCmd = &cobra.Command{
|
||||
|
4
derp.go
4
derp.go
@ -32,7 +32,7 @@ func loadDERPMapFromPath(path string) (*tailcfg.DERPMap, error) {
|
||||
}
|
||||
|
||||
func loadDERPMapFromURL(addr url.URL) (*tailcfg.DERPMap, error) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
ctx, cancel := context.WithTimeout(context.Background(), HTTP_READ_TIMEOUT)
|
||||
defer cancel()
|
||||
|
||||
req, err := http.NewRequestWithContext(ctx, "GET", addr.String(), nil)
|
||||
@ -41,7 +41,7 @@ func loadDERPMapFromURL(addr url.URL) (*tailcfg.DERPMap, error) {
|
||||
}
|
||||
|
||||
client := http.Client{
|
||||
Timeout: 10 * time.Second,
|
||||
Timeout: HTTP_READ_TIMEOUT,
|
||||
}
|
||||
|
||||
resp, err := client.Do(req)
|
||||
|
8
dns.go
8
dns.go
@ -10,6 +10,10 @@ import (
|
||||
"tailscale.com/util/dnsname"
|
||||
)
|
||||
|
||||
const (
|
||||
BYTE_SIZE = 8
|
||||
)
|
||||
|
||||
// generateMagicDNSRootDomains generates a list of DNS entries to be included in `Routes` in `MapResponse`.
|
||||
// This list of reverse DNS entries instructs the OS on what subnets and domains the Tailscale embedded DNS
|
||||
// server (listening in 100.100.100.100 udp/53) should be used for.
|
||||
@ -43,10 +47,10 @@ func generateMagicDNSRootDomains(
|
||||
maskBits, _ := netRange.Mask.Size()
|
||||
|
||||
// lastOctet is the last IP byte covered by the mask
|
||||
lastOctet := maskBits / 8
|
||||
lastOctet := maskBits / BYTE_SIZE
|
||||
|
||||
// wildcardBits is the number of bits not under the mask in the lastOctet
|
||||
wildcardBits := 8 - maskBits%8
|
||||
wildcardBits := BYTE_SIZE - maskBits%BYTE_SIZE
|
||||
|
||||
// min is the value in the lastOctet byte of the IP
|
||||
// max is basically 2^wildcardBits - i.e., the value when all the wildcardBits are set to 1
|
||||
|
@ -523,7 +523,7 @@ func (m Machine) toNode(
|
||||
n := tailcfg.Node{
|
||||
ID: tailcfg.NodeID(m.ID), // this is the actual ID
|
||||
StableID: tailcfg.StableNodeID(
|
||||
strconv.FormatUint(m.ID, 10),
|
||||
strconv.FormatUint(m.ID, BASE_10),
|
||||
), // in headscale, unlike tailcontrol server, IDs are permanent
|
||||
Name: hostname,
|
||||
User: tailcfg.UserID(m.NamespaceID),
|
||||
|
@ -320,7 +320,7 @@ func getMapResponseUserProfiles(m Machine, peers Machines) []tailcfg.UserProfile
|
||||
|
||||
func (n *Namespace) toProto() *v1.Namespace {
|
||||
return &v1.Namespace{
|
||||
Id: strconv.FormatUint(uint64(n.ID), 10),
|
||||
Id: strconv.FormatUint(uint64(n.ID), BASE_10),
|
||||
Name: n.Name,
|
||||
CreatedAt: timestamppb.New(n.CreatedAt),
|
||||
}
|
||||
|
15
oidc.go
15
oidc.go
@ -17,6 +17,12 @@ import (
|
||||
"golang.org/x/oauth2"
|
||||
)
|
||||
|
||||
const (
|
||||
OIDC_STATE_CACHE_EXPIRATION = time.Minute * 5
|
||||
OIDC_STATE_CACHE_CLEANUP_INTERVAL = time.Minute * 10
|
||||
RANDOM_BYTE_SIZE = 16
|
||||
)
|
||||
|
||||
type IDTokenClaims struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
Groups []string `json:"groups,omitempty"`
|
||||
@ -50,7 +56,10 @@ func (h *Headscale) initOIDC() error {
|
||||
|
||||
// init the state cache if it hasn't been already
|
||||
if h.oidcStateCache == nil {
|
||||
h.oidcStateCache = cache.New(time.Minute*5, time.Minute*10)
|
||||
h.oidcStateCache = cache.New(
|
||||
OIDC_STATE_CACHE_EXPIRATION,
|
||||
OIDC_STATE_CACHE_CLEANUP_INTERVAL,
|
||||
)
|
||||
}
|
||||
|
||||
return nil
|
||||
@ -67,7 +76,7 @@ func (h *Headscale) RegisterOIDC(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
b := make([]byte, 16)
|
||||
b := make([]byte, RANDOM_BYTE_SIZE)
|
||||
if _, err := rand.Read(b); err != nil {
|
||||
log.Error().Msg("could not read 16 bytes from rand")
|
||||
c.String(http.StatusInternalServerError, "could not read 16 bytes from rand")
|
||||
@ -78,7 +87,7 @@ func (h *Headscale) RegisterOIDC(c *gin.Context) {
|
||||
stateStr := hex.EncodeToString(b)[:32]
|
||||
|
||||
// place the machine key into the state cache, so it can be retrieved later
|
||||
h.oidcStateCache.Set(stateStr, mKeyStr, time.Minute*5)
|
||||
h.oidcStateCache.Set(stateStr, mKeyStr, OIDC_STATE_CACHE_EXPIRATION)
|
||||
|
||||
authUrl := h.oauth2Config.AuthCodeURL(stateStr)
|
||||
log.Debug().Msgf("Redirecting to %s for authentication", authUrl)
|
||||
|
13
poll.go
13
poll.go
@ -15,6 +15,11 @@ import (
|
||||
"tailscale.com/types/wgkey"
|
||||
)
|
||||
|
||||
const (
|
||||
KEEP_ALIVE_INTERVAL = 60 * time.Second
|
||||
UPDATE_CHECK_INTERVAL = 10 * time.Second
|
||||
)
|
||||
|
||||
// PollNetMapHandler takes care of /machine/:id/map
|
||||
//
|
||||
// This is the busiest endpoint, as it keeps the HTTP long poll that updates
|
||||
@ -127,7 +132,7 @@ func (h *Headscale) PollNetMapHandler(c *gin.Context) {
|
||||
Str("handler", "PollNetMap").
|
||||
Str("machine", m.Name).
|
||||
Msg("Client is starting up. Probably interested in a DERP map")
|
||||
c.Data(200, "application/json; charset=utf-8", data)
|
||||
c.Data(http.StatusOK, "application/json; charset=utf-8", data)
|
||||
|
||||
return
|
||||
}
|
||||
@ -159,7 +164,7 @@ func (h *Headscale) PollNetMapHandler(c *gin.Context) {
|
||||
Str("handler", "PollNetMap").
|
||||
Str("machine", m.Name).
|
||||
Msg("Client sent endpoint update and is ok with a response without peer list")
|
||||
c.Data(200, "application/json; charset=utf-8", data)
|
||||
c.Data(http.StatusOK, "application/json; charset=utf-8", data)
|
||||
|
||||
// It sounds like we should update the nodes when we have received a endpoint update
|
||||
// even tho the comments in the tailscale code dont explicitly say so.
|
||||
@ -483,8 +488,8 @@ func (h *Headscale) scheduledPollWorker(
|
||||
req tailcfg.MapRequest,
|
||||
m *Machine,
|
||||
) {
|
||||
keepAliveTicker := time.NewTicker(60 * time.Second)
|
||||
updateCheckerTicker := time.NewTicker(10 * time.Second)
|
||||
keepAliveTicker := time.NewTicker(KEEP_ALIVE_INTERVAL)
|
||||
updateCheckerTicker := time.NewTicker(UPDATE_CHECK_INTERVAL)
|
||||
|
||||
for {
|
||||
select {
|
||||
|
@ -156,7 +156,7 @@ func (h *Headscale) generateKey() (string, error) {
|
||||
func (key *PreAuthKey) toProto() *v1.PreAuthKey {
|
||||
protoKey := v1.PreAuthKey{
|
||||
Namespace: key.Namespace.Name,
|
||||
Id: strconv.FormatUint(key.ID, 10),
|
||||
Id: strconv.FormatUint(key.ID, BASE_10),
|
||||
Key: key.Key,
|
||||
Ephemeral: key.Ephemeral,
|
||||
Reusable: key.Reusable,
|
||||
|
Loading…
Reference in New Issue
Block a user