[PR #2756] [CLOSED] <fix> Convert the derpmap parsing from yaml to json to ensure compati… #2837

Closed
opened 2025-12-29 04:19:15 +01:00 by adam · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/juanfont/headscale/pull/2756
Author: @liuxocakn
Created: 8/31/2025
Status: Closed

Base: mainHead: fix_derpmap_config


📝 Commits (1)

  • c86e046 Convert the derpmap parsing from yaml to json to ensure compatibility with the tags defined at the time of the DERPMap structure

📊 Changes

1 file changed (+1 additions, -2 deletions)

View changed files

📝 hscontrol/derp/derp.go (+1 -2)

📄 Description

When I use a self-signed and self-hosted derp server, I need to set InsecureForTests to true in order to skip the certificate check. However, when I set InsecureForTests to true in yaml, it didn't work. I added a print of InsecureForTests in the code, and it showed false.

func loadDERPMapFromPath(path string) (*tailcfg.DERPMap, error) {
	derpFile, err := os.Open(path)
	if err != nil {
		return nil, err
	}
	defer derpFile.Close()
	var derpMap tailcfg.DERPMap
	b, err := io.ReadAll(derpFile)
	if err != nil {
		return nil, err
	}
	err = json.Unmarshal(b, &derpMap)

       // print node InsecureForTests 

	return &derpMap, err
}

After some trouble, I found that the definition of the DERPNode structure only has json tags and no yaml, which led to problems with the inversion of the bool type.

// DERPNode describes a DERP packet relay node running within a DERPRegion.
type DERPNode struct {
	// Name is a unique node name (across all regions).
	// It is not a host name.
	// It's typically of the form "1b", "2a", "3b", etc. (region
	// ID + suffix within that region)
	Name string

	// RegionID is the RegionID of the DERPRegion that this node
	// is running in.
	RegionID int

	// HostName is the DERP node's hostname.
	//
	// It is required but need not be unique; multiple nodes may
	// have the same HostName but vary in configuration otherwise.
	HostName string

	// CertName optionally specifies the expected TLS cert common
	// name. If empty, HostName is used. If CertName is non-empty,
	// HostName is only used for the TCP dial (if IPv4/IPv6 are
	// not present) + TLS ClientHello.
	//
	// As a special case, if CertName starts with "sha256-raw:",
	// then the rest of the string is a hex-encoded SHA256 of the
	// cert to expect. This is used for self-signed certs.
	// In this case, the HostName field will typically be an IP
	// address literal.
	CertName string `json:",omitempty"`

	// IPv4 optionally forces an IPv4 address to use, instead of using DNS.
	// If empty, A record(s) from DNS lookups of HostName are used.
	// If the string is not an IPv4 address, IPv4 is not used; the
	// conventional string to disable IPv4 (and not use DNS) is
	// "none".
	IPv4 string `json:",omitempty"`

	// IPv6 optionally forces an IPv6 address to use, instead of using DNS.
	// If empty, AAAA record(s) from DNS lookups of HostName are used.
	// If the string is not an IPv6 address, IPv6 is not used; the
	// conventional string to disable IPv6 (and not use DNS) is
	// "none".
	IPv6 string `json:",omitempty"`

	// Port optionally specifies a STUN port to use.
	// Zero means 3478.
	// To disable STUN on this node, use -1.
	STUNPort int `json:",omitempty"`

	// STUNOnly marks a node as only a STUN server and not a DERP
	// server.
	STUNOnly bool `json:",omitempty"`

	// DERPPort optionally provides an alternate TLS port number
	// for the DERP HTTPS server.
	//
	// If zero, 443 is used.
	DERPPort int `json:",omitempty"`

	// InsecureForTests is used by unit tests to disable TLS verification.
	// It should not be set by users.
	InsecureForTests bool `json:",omitempty"`
	// or
	//   InsecureForTests bool `json:",omitempty" yaml:"InsecureForTests,omitempty"`

	// STUNTestIP is used in tests to override the STUN server's IP.
	// If empty, it's assumed to be the same as the DERP server.
	STUNTestIP string `json:",omitempty"`

	// CanPort80 specifies whether this DERP node is accessible over HTTP
	// on port 80 specifically. This is used for captive portal checks.
	CanPort80 bool `json:",omitempty"`
}

Since the DERPNode code is not in the headscale, I think it would be more reasonable to modify its parsing method to json.


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/juanfont/headscale/pull/2756 **Author:** [@liuxocakn](https://github.com/liuxocakn) **Created:** 8/31/2025 **Status:** ❌ Closed **Base:** `main` ← **Head:** `fix_derpmap_config` --- ### 📝 Commits (1) - [`c86e046`](https://github.com/juanfont/headscale/commit/c86e046a3b8153d6fd52548379b7c59e9fa964cf) <fix> Convert the derpmap parsing from yaml to json to ensure compatibility with the tags defined at the time of the DERPMap structure ### 📊 Changes **1 file changed** (+1 additions, -2 deletions) <details> <summary>View changed files</summary> 📝 `hscontrol/derp/derp.go` (+1 -2) </details> ### 📄 Description When I use a self-signed and self-hosted derp server, I need to set InsecureForTests to true in order to skip the certificate check. However, when I set InsecureForTests to true in yaml, it didn't work. I added a print of InsecureForTests in the code, and it showed false. ``` go func loadDERPMapFromPath(path string) (*tailcfg.DERPMap, error) { derpFile, err := os.Open(path) if err != nil { return nil, err } defer derpFile.Close() var derpMap tailcfg.DERPMap b, err := io.ReadAll(derpFile) if err != nil { return nil, err } err = json.Unmarshal(b, &derpMap) // print node InsecureForTests return &derpMap, err } ``` After some trouble, I found that the definition of the DERPNode structure only has json tags and no yaml, which led to problems with the inversion of the bool type. ``` go // DERPNode describes a DERP packet relay node running within a DERPRegion. type DERPNode struct { // Name is a unique node name (across all regions). // It is not a host name. // It's typically of the form "1b", "2a", "3b", etc. (region // ID + suffix within that region) Name string // RegionID is the RegionID of the DERPRegion that this node // is running in. RegionID int // HostName is the DERP node's hostname. // // It is required but need not be unique; multiple nodes may // have the same HostName but vary in configuration otherwise. HostName string // CertName optionally specifies the expected TLS cert common // name. If empty, HostName is used. If CertName is non-empty, // HostName is only used for the TCP dial (if IPv4/IPv6 are // not present) + TLS ClientHello. // // As a special case, if CertName starts with "sha256-raw:", // then the rest of the string is a hex-encoded SHA256 of the // cert to expect. This is used for self-signed certs. // In this case, the HostName field will typically be an IP // address literal. CertName string `json:",omitempty"` // IPv4 optionally forces an IPv4 address to use, instead of using DNS. // If empty, A record(s) from DNS lookups of HostName are used. // If the string is not an IPv4 address, IPv4 is not used; the // conventional string to disable IPv4 (and not use DNS) is // "none". IPv4 string `json:",omitempty"` // IPv6 optionally forces an IPv6 address to use, instead of using DNS. // If empty, AAAA record(s) from DNS lookups of HostName are used. // If the string is not an IPv6 address, IPv6 is not used; the // conventional string to disable IPv6 (and not use DNS) is // "none". IPv6 string `json:",omitempty"` // Port optionally specifies a STUN port to use. // Zero means 3478. // To disable STUN on this node, use -1. STUNPort int `json:",omitempty"` // STUNOnly marks a node as only a STUN server and not a DERP // server. STUNOnly bool `json:",omitempty"` // DERPPort optionally provides an alternate TLS port number // for the DERP HTTPS server. // // If zero, 443 is used. DERPPort int `json:",omitempty"` // InsecureForTests is used by unit tests to disable TLS verification. // It should not be set by users. InsecureForTests bool `json:",omitempty"` // or // InsecureForTests bool `json:",omitempty" yaml:"InsecureForTests,omitempty"` // STUNTestIP is used in tests to override the STUN server's IP. // If empty, it's assumed to be the same as the DERP server. STUNTestIP string `json:",omitempty"` // CanPort80 specifies whether this DERP node is accessible over HTTP // on port 80 specifically. This is used for captive portal checks. CanPort80 bool `json:",omitempty"` } ``` Since the DERPNode code is not in the headscale, I think it would be more reasonable to modify its parsing method to json. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
adam added the pull-request label 2025-12-29 04:19:15 +01:00
adam closed this issue 2025-12-29 04:19:15 +01:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/headscale#2837