sing-box Linux Client Setup: Local SOCKS and HTTP Proxy

sing-box Linux Client Setup: Local SOCKS and HTTP Proxy

Ryan Foster
October 11, 2026· 12 min read

For a sing-box Linux client setup, create a local SOCKS HTTP proxy: bind a mixed inbound to 127.0.0.1:2080, connect it to an authorized remote endpoint, and explicitly point one application at that local port. This guide uses Ubuntu 24.04 LTS and sing-box 1.14.3 with curl; it does not configure device-wide traffic capture. It is compiled from official documentation, without a complete end-to-end author test.[1]

Key Takeaways

  • SOCKS and HTTP describe the local entry; VLESS/REALITY describes this example's remote connection.
  • A valid configuration and a listening port do not prove a working exit.
  • Test new requests with bad credentials and with the local process stopped.
  • Loopback blocks ordinary remote access, but does not authenticate other local users.
  • Keep existing services and proxy settings intact; remove only this exercise's changes.

Use the self-hosting planning guide to confirm who owns the endpoint, credentials, updates and recovery. If your application cannot use an explicit proxy, consult the TUN and system-proxy coverage comparison before changing the task. This procedure does not establish UDP, IPv6, DNS or other applications' coverage.

Step 1: Prepare an authorized endpoint and a separate binary

You need a remote VLESS/REALITY endpoint you own or are authorized to use, with its address, TCP port, UUID, REALITY public key, short ID, approved server name and flow setting. Ask its administrator for those exact values. A subscription label or an IP address alone is insufficient; do not obtain credentials from public node lists.

Confirm Ubuntu 24.04 LTS with cat /etc/os-release and the architecture with uname -m. From the official 1.14.3 release page, choose the matching Linux archive: amd64 for x86_64, or arm64 for aarch64. Extract it privately, then place its executable at $HOME/.local/lib/sing-box-1.14.3/sing-box in a new directory you own; stop if that destination already exists. Use the official distribution channels and available release-integrity instructions, rather than an unknown installation script.[1][2]

This user-local archive route avoids replacing a system package or enabling its service. Do not run package-manager service commands from a different installation method. Before proceeding, save relevant existing configuration and application proxy preferences privately; record any active system proxy or VPN, and leave it unchanged.

SB_BIN="$HOME/.local/lib/sing-box-1.14.3/sing-box"
"$SB_BIN" version
pgrep -a -x sing-box
ss -ltn 'sport = :2080'

The version must report 1.14.3; the port inspection must show no existing listener. No pgrep match is normal; limited process visibility is not proof that the machine has no other proxy. If a service or port conflicts, identify its owner and stop this exercise instead of killing it. For another core version, review the migration notes and fields before using this example.[3]

Step 2: Write a loopback-only sing-box mixed inbound

Create a fresh private directory. The restrictive umask applies only inside the command substitution below; your current terminal keeps its original default file permissions. Keep the printed path: a second terminal must use that same directory, not create another one.

LOCAL_PROXY_DIR=$(
  umask 077
  mktemp -d "$HOME/sing-box-local.XXXXXX"
)
printf '%s\n' "$LOCAL_PROXY_DIR"

With a local editor, save the following as config.json inside it. Replace every uppercase placeholder before checking or starting. The port 443 is illustrative and must match your endpoint. This template assumes VLESS over TCP with REALITY and Vision; if your endpoint uses another flow or transport, obtain its supported configuration instead of guessing fields.[4][5][6]

{
  "log": { "level": "info" },
  "inbounds": [
    {
      "type": "mixed",
      "tag": "local-mixed",
      "listen": "127.0.0.1",
      "listen_port": 2080,
      "set_system_proxy": false
    }
  ],
  "outbounds": [
    {
      "type": "vless",
      "tag": "authorized-exit",
      "server": "YOUR_SERVER_IP",
      "server_port": 443,
      "uuid": "YOUR_AUTHORIZED_UUID",
      "flow": "xtls-rprx-vision",
      "network": "tcp",
      "tls": {
        "enabled": true,
        "server_name": "YOUR_APPROVED_SERVER_NAME",
        "insecure": false,
        "utls": { "enabled": true, "fingerprint": "chrome" },
        "reality": {
          "enabled": true,
          "public_key": "YOUR_REALITY_PUBLIC_KEY",
          "short_id": "YOUR_SHORT_ID"
        }
      }
    }
  ],
  "route": { "final": "authorized-exit" }
}
ReplacementObtain and check
YOUR_SERVER_IP, server_portThe authorized endpoint's numeric address and TCP port; using an IP avoids a separate server-name bootstrap lookup here.
YOUR_AUTHORIZED_UUIDThe VLESS user identifier currently enabled on that endpoint.
YOUR_APPROVED_SERVER_NAMEThe server name supplied for this REALITY endpoint; it is not automatically the server IP.
YOUR_REALITY_PUBLIC_KEYThe server's REALITY public key, never its private key.
YOUR_SHORT_ID, flowThe exact accepted short ID and matching Vision setting.

The core, inbound and outbound explanation helps keep the roles separate. A sing-box mixed inbound accepts local SOCKS/HTTP; it does not make a remote HTTP proxy compatible with VLESS. The explicit final outbound has no direct fallback.[4][5][7]

set_system_proxy: false prevents this instance from automatically changing system proxy settings. With no users configured, the local entry has no authentication: 127.0.0.1 restricts its network reach, not which local account can use it. Review the SOCKS listener trust boundary before using a shared host. Protect the directory and credentials; do not paste them into issue reports.[4][8]

Step 3: Check the configuration, then start in the foreground

Run these commands as your ordinary user in the preparation terminal:

"$SB_BIN" check -c "$LOCAL_PROXY_DIR/config.json"

Continue only on a successful exit. A check failure leaves your working setup untouched: correct the reported JSON, placeholder or unsupported field in this separate file. The check cannot prove endpoint authorization, remote availability or a destination's response. The official client guide separates local proxy entry from outbound behavior.[9]

"$SB_BIN" run -c "$LOCAL_PROXY_DIR/config.json"

Keep that terminal open. In a second terminal, run ss -ltnp 'sport = :2080'; expect a TCP listener on 127.0.0.1:2080, owned by this instance where process information is visible. If it shows 0.0.0.0, [::], a LAN address or an unexpected process, stop this instance with Ctrl-C and investigate. Do not add firewall exceptions or switch to root to hide a startup failure.[8]

Step 4: Send explicit HTTP and SOCKS requests

In the second terminal, set CHECK_URL to an HTTPS URL you are allowed to query. Use a predictable response on a service you control when possible; the placeholder below is not a working host. Run each command separately and record its exit status, response and corresponding process log privately.

CHECK_URL="https://YOUR_AUTHORIZED_TEST_HOST/"
curl -q --noproxy "" --proxy http://127.0.0.1:2080 \
  --connect-timeout 5 --max-time 20 --fail --show-error "$CHECK_URL"
curl -q --noproxy "" --proxy socks5h://127.0.0.1:2080 \
  --connect-timeout 5 --max-time 20 --fail --show-error "$CHECK_URL"

Here -q, as curl's first option, avoids a hidden .curlrc; an empty --noproxy overrides bypass lists. The explicit proxy applies to these invocations only. HTTP proxying of HTTPS uses CONNECT; socks5h:// passes the destination hostname to the proxy, while socks5:// makes curl resolve it locally. In this configuration a forwarded hostname reaches the VLESS endpoint; this does not audit the remote resolver or all host DNS traffic.[10]

For a curl exit check, correlate a fresh request with the source address recorded by your controlled destination, accounting for any trusted reverse proxy in front of it. Expect the authorized server's actual egress, which may differ from its connection address. A status code or successful page download alone cannot establish that address.

If you explicitly configure a browser to the same local entry, open the IP address tool in that browser and compare the displayed exit. Its result belongs to that tool request; an unconfigured browser cannot verify curl, and neither result proves another application's path. Save and later restore that browser's preferences if you change them.

Step 5: Check failure and listener boundaries

The following table gives methods, expected behavior and failure handling, not observed test results. Use new curl invocations, not a cached browser page or an existing connection.

MethodExpected behaviorFailure handling
Stop this foreground instance with Ctrl-C, confirm no listener, then repeat both explicit requests.Both new requests fail to connect to the local entry.If one succeeds, check its actual arguments, another listener and any wrapper; do not claim fail-closed coverage.
With the original stopped, copy config.json to invalid.json; replace only its UUID with a syntactically valid UUID the administrator confirms is unauthorized. Check, then run that copy and repeat both requests.Local listening may succeed, but the protected destination response fails because remote authorization fails.If the expected content arrives, stop and inspect which file, process, endpoint and identity were actually used.
While the isolated instance is listening, try its host's LAN IP and port 2080 from another authorized device; also inspect the local socket.The remote device cannot use the entry; locally it remains bound to 127.0.0.1.A remote failure alone may be a firewall effect. If the bind is wider, stop and correct it; never expose the port for the test.

For the bad-UUID branch, use "$SB_BIN" check -c "$LOCAL_PROXY_DIR/invalid.json" before "$SB_BIN" run -c "$LOCAL_PROXY_DIR/invalid.json" in the first terminal. Stop it afterward, then restart the original only if you need further checks. Keep exactly one exercise instance running. Never change the real server's credentials to manufacture a negative result.

These checks cover a narrow sing-box Linux client setup. The TCP-only outbound does not validate UDP forwarding; a loopback IPv4 entry does not capture host IPv6. Another local user may still connect to the unauthenticated entry. If that trust model is unsuitable, stop and design local authentication or isolation separately.[4][5]

Step 6: Restore preferences and remove this instance

Restore any application preferences you changed to their recorded values. The curl commands create no persistent proxy preference, so stop using their explicit proxy arguments. Do not globally unset environment variables or reset system networking that this exercise did not modify.

In the first terminal, press Ctrl-C for the running exercise instance. Confirm with ss -ltnp 'sport = :2080' that its listener has disappeared. If it remains, identify that process before cleanup; do not use killall or stop an unrelated service. A request deliberately still pointing at the stopped entry should fail; after restoring an application, verify its ordinary behavior separately.

Only after confirming the directory is the fresh path you created, remove its two known files and the empty directory:

rm -f -- "$LOCAL_PROXY_DIR/config.json" "$LOCAL_PROXY_DIR/invalid.json"
rmdir -- "$LOCAL_PROXY_DIR"

Keep private baseline backups until recovery is confirmed. The separately installed binary can remain for reuse; uninstall only that exact user-local installation if you no longer need it. This procedure creates no startup service, system route or system proxy change to undo.

Why does a sing-box Linux client setup fail?

Start at the first failed layer. No listener means checking the foreground error, file path and port ownership. A listener with remote failure means checking the endpoint, UUID, key, short ID, flow, server name and clock with the administrator; never disable certificate verification or add a direct fallback.

If only hostname requests fail, compare curl's local versus proxy-side resolution and the remote service's resolver policy. Do not change system DNS merely because one application failed. If a downloaded profile appears unchanged at runtime, follow the active-configuration checklist. When applications differ, use the per-app troubleshooting steps to isolate their settings rather than expand the proxy's scope.

Summary

A useful sing-box Linux client setup has an identified binary, a private configuration, a loopback listener, explicit application requests and a verified recovery path. Keep your own method/expectation/observation record; configuration parsing, a browser IP result and another machine's connection refusal each answer different questions.

FAQ

Is mixed the same protocol as the remote endpoint?

No. Mixed accepts SOCKS and HTTP locally; this example sends those connections through a VLESS/REALITY outbound. The remote endpoint must match the outbound configuration, not the local application's proxy label.

Why can configuration checking pass while requests fail?

Checking can detect configuration problems without proving a working remote session. Wrong credentials, an unavailable endpoint, destination restrictions or resolver behavior can still stop a new request after the local listener starts.

Why do my browser and terminal show different exits?

Each application chooses its own proxy behavior. The commands here explicitly configure curl, while the browser may use different preferences or no proxy. Check the request from the application in question and compare actual settings.

Does socks5h keep every DNS request off my machine?

No. It passes that curl request's destination hostname to the proxy instead of resolving it in curl. Other applications, local background services and the remote resolver have separate behavior that this procedure does not verify.

Does this cover UDP and IPv6?

It does not establish that coverage. The example restricts its VLESS outbound to TCP and accepts connections on IPv4 loopback. UDP applications and host IPv6 traffic need separate design and validation; HTTP success is insufficient.

Can other local users use the port?

Yes, potentially. Loopback is a network boundary, and this entry has no user authentication. A private configuration protects its file contents but does not reserve the listener for one account; shared hosts need an additional trust assessment.

How do I recover after stopping sing-box?

Restore changed application preferences and stop passing the local proxy argument to curl. Confirm this instance's listener is gone, then check ordinary application behavior. Do not alter an existing VPN or system service to restore this separate exercise.


This guide covers systems and endpoints you own or are authorized to use. Follow applicable law and network policy. The checks are reader procedures and expectations, not a claim of completed author testing or device-wide protection.

Sources:

  1. SagerNet, sing-box 1.14.3 release. https://github.com/SagerNet/sing-box/releases/tag/v1.14.3
  2. sing-box, official installation channels. https://sing-box.sagernet.org/installation/package-manager/
  3. sing-box, migration notes. https://sing-box.sagernet.org/migration/
  4. sing-box, Mixed inbound. https://sing-box.sagernet.org/configuration/inbound/mixed/
  5. sing-box, VLESS outbound. https://sing-box.sagernet.org/configuration/outbound/vless/
  6. sing-box, TLS and REALITY fields. https://sing-box.sagernet.org/configuration/shared/tls/
  7. sing-box, Route final outbound. https://sing-box.sagernet.org/configuration/route/
  8. sing-box, Listen fields. https://sing-box.sagernet.org/configuration/shared/listen/
  9. sing-box, client proxy guide. https://sing-box.sagernet.org/manual/proxy/client/
  10. curl, proxy, hostname resolution and configuration options. https://curl.se/docs/manpage.html

Sources checked 11 October 2026.

Related Articles:

Start your 3-day free trial

Sign up to experience all premium features at no cost.

*Available only to new users. Each user is limited to one trial.

sing-box Linux Client Setup: Local SOCKS and HTTP Proxy | AethoVPN