Clash API does not honor IPv4-only wildcard binding for `0.0.0.0`
Nobody has claimed this yet.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 90/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Active
- Tech stack
- go
- Domain
- networking
Research direction
Start in experimental/clashapi/server.go and compare the listener setup with the inbound TCP listener behavior described in the issue. Reuse M.NetworkFromNetAddr so a 0.0.0.0 address selects tcp4; verify the Clash API binds IPv4-only for that address and preserves existing behavior for other addresses.
Written by the indexing model from the issue text.
Description
Operating system
Linux
System version
Alpine 3.24
Installation type
Original sing-box Command Line
If you are using a graphical client, please provide the version of the client.
No response
Version
sing-box version 1.13.21
Environment: go1.27.0 linux/amd64
Tags: with_gvisor,with_quic,with_dhcp,with_wireguard,with_utls,with_acme,with_clash_api,with_tailscale,badlinkname,tfogo_checklinkname0
CGO: enabled
Description
Setting experimental.clash_api.external_controller to 0.0.0.0:1090 creates a listener reported as [::]:1090, instead of an IPv4-only listener.
This differs from the behavior of inbound listeners. Inbound listeners use M.NetworkFromNetAddr to select tcp4 for 0.0.0.0, while the Clash API always passes "tcp" to net.Listen.
On systems supporting IPv4-mapped IPv6 sockets, Go can interpret "tcp" with an IPv4 wildcard address as a dual-stack listener. Consequently, the Clash API may also accept IPv6 connections despite being configured with 0.0.0.0.
Expected behavior: the Clash API should handle wildcard addresses consistently with inbound listeners, using tcp4 when the configured address is 0.0.0.0.
Reproduction
- Save the following complete configuration as
config.json:
{
"log": {
"level": "info"
},
"experimental": {
"clash_api": {
"external_controller": "0.0.0.0:1090"
}
}
}
- Run:
sing-box run -c config.json
- Observe that the Clash API reports
[::]:1090, although the configured address is0.0.0.0:1090.
This reproduction requires no remote server, TUN, or graphical client.
Proposed solution
Reuse M.NetworkFromNetAddr, as the inbound TCP listener already does.
In experimental/clashapi/server.go, add:
M "github.com/sagernet/sing/common/metadata"
N "github.com/sagernet/sing/common/network"
Replace:
listener, err = net.Listen("tcp", s.httpServer.Addr)
with:
listener, err = net.Listen(M.NetworkFromNetAddr(N.NetworkTCP, M.ParseSocksaddr(s.httpServer.Addr).Addr), s.httpServer.Addr)
This selects tcp4 for 0.0.0.0, while preserving the existing "tcp" behavior for other addresses, including ::.
The change has been cross-compiled successfully.
Logs
INFO[0000] network: updated default interface eth0, index 2
INFO[0000] clash-api: restful api listening at [::]:1090
INFO[0000] sing-box started (0.02s)
Supporter
- I am a sponsor
Integrity requirements
- I confirm that I have read the documentation, understand the meaning of all the configuration items I wrote, and did not pile up seemingly useful options or default values.
- I confirm that I have provided the server and client configuration files and process that can be reproduced locally, instead of a complicated client configuration file that has been stripped of sensitive data.
- I confirm that I have provided the simplest configuration that can be used to reproduce the error I reported, instead of depending on remote servers, TUN, graphical interface clients, or other closed-source software.
- I confirm that I have provided the complete configuration files and logs, rather than just providing parts I think are useful out of confidence in my own intelligence.
- Dominant language
- Go
- Stars
- 38.9k
- Forks
- 4.7k
- PR merge metrics
- No merged PRs in 30d
Getting set up
- Ships a Dockerfile or Docker Compose file
- No pull request template
- No contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from SagerNet/sing-box
-
Difficulty 1/5 Under an hour Newbie friendliness 66/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 70/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
-
Difficulty 1/5 Under an hour Newbie friendliness 88/100
All issues in SagerNet/sing-box
Similar issues
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
Maintainers usually reply within 1 day
-
Mend: dependency security vulnerability
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
kube-tarian/sigrun#202 ·
-
good first issue help wanted
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
eugenioenko/ttt#1085 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 62/100
fullsend-ai/fullsend#8688 · 1 comment ·
Maintainers usually reply within 1 day
-
question raised-by:verifier
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
medici-finance/assay#4013 ·
Maintainers usually reply within 1 day