Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feature request] support abstract UNIX domain socket #5341

Closed
IceCodeNew opened this issue Jan 30, 2023 · 6 comments
Closed

[feature request] support abstract UNIX domain socket #5341

IceCodeNew opened this issue Jan 30, 2023 · 6 comments
Labels
discussion 💬 The right solution needs to be found help wanted 🆘 Extra attention is needed

Comments

@IceCodeNew
Copy link

Use Case & Problem:
There is a backend service that supports abstract UNIX domain sockets managed by the docker compose along with caddy. There is also a named volume for sharing the UNIX socket file between these two services.
Sometimes the backend will run into a panic and restart itself. Since there is no one cleaning the UNIX socket file before the backend restarted, the backend will fail to bind to the UNIX domain socket.

services:
  caddy:
    build: ./caddy/
    cap_add:
      - NET_BIND_SERVICE
    cap_drop:
      - ALL
    container_name: composed-caddy
    init: true
    ports:
      - "80:80"
      - "443:443"
    restart: always
    volumes:
      - share-unix-socket:/tmp/unix-socket/
      - type: bind
        source: ./caddy/
        target: /etc/caddy/
        read_only: true
  v2ray:
    cap_drop:
      - ALL
    command: [ "run", "-d", "/usr/local/etc/v2ray/conf.d/" ]
    container_name: composed-v2ray
    image: v2fly/v2fly-core:latest
    init: true
    read_only: true
    restart: always
    volumes:
      - share-unix-socket:/tmp/unix-socket/
      - type: bind
        source: ./v2ray/conf.d/
        target: /usr/local/etc/v2ray/conf.d/
        read_only: true

volumes:
  share-unix-socket:
{
	admin off
}

REPLACE_ME_V2RAY_HOSTS {
	root * /usr/share/caddy

	encode zstd gzip

	file_server

	reverse_proxy REPLACE_ME_V2RAY_PATH unix+h2c//tmp/unix-socket/send-to-v2ray.sock
}

The best solution should be to make the caddy support the abstract UNIX domain socket.
I searched for configuring a pre-hook for docker compose, to intervene in the restarting process and manually clean the UNIX domain file. But only to my disappointment to find out that this is a long stale issue and the community is unwilling to approve such a feature.

@francislavoie
Copy link
Member

francislavoie commented Jan 30, 2023

Hmm, I'm only now learning of abstract unix domain sockets.

It seems like Go already supports this. Try using @ as a path prefix. Does that work? For example:

unix+h2c/@/tmp/unix-socket/send-to-v2ray.sock

@IceCodeNew
Copy link
Author

Hmm, I'm only now learning of abstract unix domain sockets.

It seems like Go already supports this. Try using @ as a path prefix. Does that work? For example:

unix+h2c/@/tmp/unix-socket/send-to-v2ray.sock

Then it should be unix+h2c/@send-to-v2ray.sock or unix+h2c/@@send-to-v2ray.sock (for abstract UNIX domain sockets which enabled padding)
I will give it a try, thanks for the quick response!

@IceCodeNew
Copy link
Author

IceCodeNew commented Jan 30, 2023

Hmm, I'm only now learning of abstract unix domain sockets.

It seems like Go already supports this. Try using @ as a path prefix. Does that work? For example:

unix+h2c/@/tmp/unix-socket/send-to-v2ray.sock

I managed to make it work. Just do the following change:

services:
  caddy:
    build: ./caddy/
    cap_add:
      - NET_BIND_SERVICE
    cap_drop:
      - ALL
    container_name: composed-caddy
    init: true
    ports:
      - "80:80"
      - "443:443"
    restart: always
    volumes:
-       - share-unix-socket:/tmp/unix-socket/
      - type: bind
        source: ./caddy/
        target: /etc/caddy/
        read_only: true
  v2ray:
    cap_drop:
      - ALL
    command: [ "run", "-d", "/usr/local/etc/v2ray/conf.d/" ]
    container_name: composed-v2ray
    image: v2fly/v2fly-core:latest
    init: true
+     network_mode: "service:caddy"
    read_only: true
    restart: always
    volumes:
-       - share-unix-socket:/tmp/unix-socket/
      - type: bind
        source: ./v2ray/conf.d/
        target: /usr/local/etc/v2ray/conf.d/
        read_only: true

- volumes:
-   share-unix-socket:
{
	admin off
}

REPLACE_ME_V2RAY_HOSTS {
	root * /usr/share/caddy

	encode zstd gzip

	file_server

- 	reverse_proxy REPLACE_ME_V2RAY_PATH unix+h2c//tmp/unix-socket/send-to-v2ray.sock
+ 	reverse_proxy REPLACE_ME_V2RAY_PATH unix+h2c/@/tmp/unix-socket/send-to-v2ray.sock
}

// you will also need to switch to the abstract UNIX domain socket on the backend.

@IceCodeNew
Copy link
Author

IceCodeNew commented Jan 30, 2023

Although It seems caddy does not support padding abstract domain sockets yet, I have not yet been blocked by this problem. Closing this issue.


Just for the record, here is the error log:

root@machine-1:~/git/repo# nsenter -n -t "$(docker inspect composed-caddy | jq .[].State.Pid)" lsof -U
COMMAND     PID USER   FD   TYPE             DEVICE SIZE/OFF     NODE NAME
v2ray   1334041 root    3u  unix 0x0000000000000000      0t0 13478402 @/tmp/unix-socket/send-to-v2ray.sock@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ type=STREAM
root@machine-1:~/git/repo# docker logs -f composed-caddy
{"level":"info","ts":1675052533.181184,"msg":"using provided configuration","config_file":"/etc/caddy/Caddyfile","config_adapter":"caddyfile"}
2023-01-30T12:22:13+08:00	WARN	admin	admin endpoint disabled
2023-01-30T12:22:51+08:00	ERROR	http.log.error	dial unix @@/tmp/unix-socket/send-to-v2ray.sock: connect: connection refused	{"request": {"remote_ip": "172.21.0.5", "remote_port": "49536", "proto": "HTTP/2.0", "method": "PUT", "host": "machine-1.example.org", "uri": "REDACTED", "headers": {"Accept-Encoding": ["identity"], "User-Agent": ["Go-http-client/2.0"]}, "tls": {"resumed": false, "version": 772, "cipher_suite": 4867, "proto": "h2", "server_name": "machine-1.example.org"}}, "duration": 0.003093776, "status": 502, "err_id": "k44jmtriz", "err_trace": "reverseproxy.statusError (reverseproxy.go:1272)"}

And the Caddyfile configuration

{
	admin off
}

REPLACE_ME_V2RAY_HOSTS {
	root * /usr/share/caddy

	encode zstd gzip

	file_server

	reverse_proxy REPLACE_ME_V2RAY_PATH unix+h2c/@@/tmp/unix-socket/send-to-v2ray.sock
}

change the bind addr to reverse_proxy REPLACE_ME_V2RAY_PATH unix+h2c/@/tmp/unix-socket/send-to-v2ray.sock does not solve the problem.

@mholt mholt added the discussion 💬 The right solution needs to be found label Jan 30, 2023
@mholt
Copy link
Member

mholt commented Jan 30, 2023

What is this sorcery... I've also never heard of these 😵

I'm not sure what it takes to connect to a UDS prefixed with @@... like is it a bug in Caddy or something about the system/environment?

@IceCodeNew
Copy link
Author

What is this sorcery... I've also never heard of these 😵

I'm not sure what it takes to connect to a UDS prefixed with @@... like is it a bug in Caddy or something about the system/environment?

I think it might be a bug in Caddy, but I am afraid I do not have enough knowledge to collect solid proof for this thought.
Until others bring this problem to the surface again, I thought we can focus on other issues ;-)

@mholt mholt added the help wanted 🆘 Extra attention is needed label Jan 30, 2023
lxhao61 referenced this issue Jun 24, 2023
* core: Add optional unix socket file permissions

This commit also changes the default unix socket file permissions to `u=w,g=,o=` (octal: `0200`).
It used to default to the shell's umask (usually `u=rwx,g=rx,o=rx`, octal: `0755`).

`/run/caddy.sock` -> `/run/caddy.sock` with `0200` default perms
`/run/caddy.sock|0222` -> `/run/caddy.sock` with `0222` perms

`|` instead of `:` is used as a separator, to account for the `:` in Windows drive letters (e.g. `C:\absolute\path.sock`)

Fun fact:
The old unix(7) man page (pre Jun 2016) stated a socket needs both read and write perms.
Turns out, only write perms are needed.
Corrected in mkerrisk/man-pages@7578ea2
Despite this, most implementations still default to read+write to this date.

* Add cases with Windows paths to test

* Require write perms for the owning user
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
discussion 💬 The right solution needs to be found help wanted 🆘 Extra attention is needed
Projects
None yet
Development

No branches or pull requests

3 participants