Failed to Proxypass to Unix Socket

1. The problem I’m having:

I use SSH tunnel remote forwarder with unix socket as listener in the remote to expose my local port, below is how the command:

ssh -N -R /tmp/dpanel.sock::3000 -i secret dpanel@<MY-TUNNEL-SERVER>

Then, I try to call the socket using simple go script below:

package main

import (
	"context"
	"fmt"
	"io"
	"net"
	"net/http"
	"time"
)

func main() {
	socketPath := "/tmp/dpanel.sock"

	// Create a custom http.Client
	client := http.Client{
		Transport: &http.Transport{
			// Custom DialContext to connect to the Unix socket
			DialContext: func(ctx context.Context, _, _ string) (net.Conn, error) {
				return net.DialUnix("unix", nil, &net.UnixAddr{Name: socketPath, Net: "unix"})
			},
		},
		Timeout: 5 * time.Second, // Set a timeout for the request
	}

	// Make an HTTP request using the custom client
	// The host in the URL (e.g., "http://localhost") is largely irrelevant
	// when using Unix sockets, but it's required by the http.Request structure.
	// You can use any valid host here.
	req, err := http.NewRequest("GET", "http://localhost/api/data", nil)
	if err != nil {
		fmt.Printf("Error creating request: %v\n", err)
		return
	}

	resp, err := client.Do(req)
	if err != nil {
		fmt.Printf("Error sending request: %v\n", err)
		return
	}
	defer resp.Body.Close()

	// Read and print the response body
	body, err := io.ReadAll(resp.Body)
	if err != nil {
		fmt.Printf("Error reading response body: %v\n", err)
		return
	}

	fmt.Printf("Response Status: %s\n", resp.Status)
	fmt.Printf("Response Body: %s\n", body)
}

It works as expected, with response from my local service.

Now, what I’am expecting is CaddyServer will also works as my golang app, I use this config below in my Caddyfile:

with-socket.beta.devetek.app/demo {
         handle {
                 reverse_proxy unix//tmp/dpanel.sock
         }
}

2. Error messages and/or full log output:

There is no useful information I found why, I believe Caddy have different behaviour with my golang code, but I didn’t found from any link to mimic my go to caddyfile config.

3. Caddy version:

v2.10.0 h1:fonubSaQKF1YANl8TXqGcn4IbIRUDdfAkpcsfI/vX5U=

4. How I installed and ran Caddy:

I install custom caddy with extra plugins from repository Releases · devetek/d-panel-router · GitHub

And running it using systemd

a. System environment:

Distributor ID: Ubuntu
Description: Ubuntu 24.04 LTS
Release: 24.04
Codename: noble

Running with systemd 255 (255.4-1ubuntu8.8)

b. Command:

I use normal caddy command:

ExecStart="/usr/local/bin/caddy" run --environ --config "/etc/caddy/Caddyfile"
ExecReload="/usr/local/bin/caddy" reload --config "/etc/caddy/Caddyfile"

c. Service/unit/compose file:

[Service]
Restart=always
RestartSec=10s

; User and group the process will run as.
User=root
Group=root

; Letsencrypt-issued certificates will be written to this directory.
Environment=CADDYPATH=/etc/ssl/caddy

ExecStart="/usr/local/bin/caddy" run --environ --config "/etc/caddy/Caddyfile"
ExecReload="/usr/local/bin/caddy" reload --config "/etc/caddy/Caddyfile"

; Limit the number of file descriptors; see `man systemd.exec` for more limit settings.
LimitNOFILE=1048576

; Use private /tmp and /var/tmp, which are discarded after caddy stops.
PrivateTmp=true
; Use a minimal /dev
PrivateDevices=true
; Hide /home, /root, and /run/user. Nobody will steal your SSH-keys.
ProtectHome=false
; Make /usr, /boot, /etc and possibly some more folders read-only.
ProtectSystem=full
; ... except /etc/ssl/caddy, because we want Letsencrypt-certificates there.
;   This merely retains r/w access rights, it does not add any new. Must still be writable on the host!
ReadWriteDirectories=/etc/ssl/caddy /var/log/caddy

d. My complete Caddy config:

with-socket.beta.devetek.app/demo {
         handle {
                 reverse_proxy unix//tmp/dpanel.sock
         }
}

5. Links to relevant resources:

Not found any relevant link to resolve this issue

Resolved!, issue from the tunnel