[Bug] Insecure TLS Configuration in Headscale creating #732

Closed
opened 2025-12-29 02:23:01 +01:00 by adam · 0 comments
Owner

Originally created by @sy2339226 on GitHub (Jun 19, 2024).

Is this a support request?

  • This is not a support request

Is there an existing issue for this?

  • I have searched the existing issues

Current Behavior

Within the WaitForRunning function of the HeadscaleInContainer struct(headscale/integration/hsic/hsic.go), when TLS is detected as enabled, the code creates an insecure TLS configuration where InsecureSkipVerify is set to true. It is used in Headscale, Headscale returns a ControlServer instance based on hsic. This causes the client to communicate with the server without verifying the server's certificate, potentially exposing the connection to man-in-the-middle attacks. An attacker can position themselves between the client (the application making the health check request) and the intended server ("headscale" service). This could happen over an unsecured network or through compromised network infrastructure, may causing the inability to create a new headscale.

    func (t *HeadscaleInContainer) WaitForRunning() error {
        url := t.GetHealthEndpoint()
    
        log.Printf("waiting for headscale to be ready at %s", url)
    
        client := &http.Client{}
    
        if t.hasTLS() {
	        insecureTransport := http.DefaultTransport.(*http.Transport).Clone()      //nolint
	        insecureTransport.TLSClientConfig = &tls.Config{InsecureSkipVerify: true} //nolint
	        client = &http.Client{Transport: insecureTransport}
        }
    
        return t.pool.Retry(func() error {
	        resp, err := client.Get(url) //nolint
	        if err != nil {
		        return fmt.Errorf("headscale is not ready: %w", err)
	        }
    
	        if resp.StatusCode != http.StatusOK {
		        return errHeadscaleStatusCodeNotOk
	        }
    
	        return nil
        })
    }

Expected Behavior

The TLS configuration should be secure and verify the server's certificate to prevent any security vulnerabilities that might arise from skipping the certificate verification process.

Steps To Reproduce

Ensure that the application is configured to use TLS for communication.
Observe the TLS configuration generated within the WaitForRunning function.
Notice that the InsecureSkipVerify parameter is set to true.
Recognize the potential security implications of this configuration.

Environment

- OS: all 
- Headscale version: 0.0.1
- Tailscale version: 0.22.3

Runtime environment

  • Headscale is behind a (reverse) proxy
  • Headscale runs in a container

Anything else?

No response

Originally created by @sy2339226 on GitHub (Jun 19, 2024). ### Is this a support request? - [X] This is not a support request ### Is there an existing issue for this? - [X] I have searched the existing issues ### Current Behavior Within the WaitForRunning function of the HeadscaleInContainer struct(headscale/integration/hsic/hsic.go), when TLS is detected as enabled, the code creates an insecure TLS configuration where InsecureSkipVerify is set to true. It is used in Headscale, Headscale returns a ControlServer instance based on hsic. This causes the client to communicate with the server without verifying the server's certificate, potentially exposing the connection to man-in-the-middle attacks. An attacker can position themselves between the client (the application making the health check request) and the intended server ("headscale" service). This could happen over an unsecured network or through compromised network infrastructure, may causing the inability to create a new headscale. func (t *HeadscaleInContainer) WaitForRunning() error { url := t.GetHealthEndpoint() log.Printf("waiting for headscale to be ready at %s", url) client := &http.Client{} if t.hasTLS() { insecureTransport := http.DefaultTransport.(*http.Transport).Clone() //nolint insecureTransport.TLSClientConfig = &tls.Config{InsecureSkipVerify: true} //nolint client = &http.Client{Transport: insecureTransport} } return t.pool.Retry(func() error { resp, err := client.Get(url) //nolint if err != nil { return fmt.Errorf("headscale is not ready: %w", err) } if resp.StatusCode != http.StatusOK { return errHeadscaleStatusCodeNotOk } return nil }) } ### Expected Behavior The TLS configuration should be secure and verify the server's certificate to prevent any security vulnerabilities that might arise from skipping the certificate verification process. ### Steps To Reproduce Ensure that the application is configured to use TLS for communication. Observe the TLS configuration generated within the WaitForRunning function. Notice that the InsecureSkipVerify parameter is set to true. Recognize the potential security implications of this configuration. ### Environment ```markdown - OS: all - Headscale version: 0.0.1 - Tailscale version: 0.22.3 ``` ### Runtime environment - [ ] Headscale is behind a (reverse) proxy - [ ] Headscale runs in a container ### Anything else? _No response_
adam added the bug label 2025-12-29 02:23:01 +01:00
adam closed this issue 2025-12-29 02:23:01 +01:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/headscale#732