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.


TUIC server setup pairs a protected UDP listener with a client that verifies the server's TLS identity and supplies a UUID and password. This guide uses sing-box 1.14.3 on Ubuntu 24.04 LTS amd64 at both ends and checks one explicitly proxied TCP request. It is based on the listed official documentation; no complete end-to-end author test was performed.[1]
Key Takeaways
- A listening process is only the first check; UDP, TLS, authentication, and forwarding can fail separately.
- Use your own domain and trusted certificate, with 0-RTT disabled.
- The local proxy stays on loopback; this procedure does not capture the whole device.
- Record a recovery baseline before installing packages or opening a port.
Choose this task when you own the server and can maintain its certificate, credentials, firewall, and updates. The guide to assigning self-hosting duties helps establish those owners. If your goal is simply an everyday public exit, compare running a VPS with using a maintained VPN service before adding a server.
This is one implementation at both ends. The Hysteria2 protocol explanation describes a neighboring protocol, not a configuration you can relabel as TUIC. For the distinction between an encrypted connection and its coverage, use the VPN coverage primer.
Prepare two dedicated, authorized Ubuntu hosts with no working sing-box installation to preserve. Reserve UDP 24443; the server must receive that traffic, including any authorized upstream NAT mapping. Obtain a valid certificate chain and matching private key for your own domain through its existing CA renewal procedure. The example domain and all uppercase address or credential values below are replacements, not usable deployment values.
Save the package inventory, service state, relevant firewall rules, addresses, routes, DNS settings, and configuration privately. Check a new independent SSH or provider-console connection. If a package, APT source, user, unit, or configuration path below already belongs to another service, stop and reconcile ownership rather than overwrite it.
On both hosts, install prerequisites from Ubuntu's trusted repositories. Then use the official APT repository below. Replace APT_VERSION_FOR_1.14.3 with the exact package version shown by apt-cache madison that contains core 1.14.3; stop if it is absent. Do not substitute sing-box-beta or run an unreviewed installer script.[5]
sudo apt-get update
sudo apt-get install curl ca-certificates openssl
sudo install -d -m 755 /etc/apt/keyrings
sudo curl -fsSL https://sing-box.app/gpg.key -o /etc/apt/keyrings/sagernet.asc
sudo chmod 644 /etc/apt/keyrings/sagernet.asc
sudo tee /etc/apt/sources.list.d/sagernet.sources >/dev/null <<'REPO'
Types: deb
URIs: https://deb.sagernet.org/
Suites: *
Components: *
Enabled: yes
Signed-By: /etc/apt/keyrings/sagernet.asc
REPO
sudo apt-get update
apt-cache madison sing-box
sudo apt-get install sing-box='APT_VERSION_FOR_1.14.3' curl ca-certificates openssl
sing-box version
Confirm the executable reports 1.14.3 on both hosts. Keep a recoverable package or official release artifact and consult release notes and security advisories before later upgrades. Installation can introduce the distribution's default unit: inspect it, and do not activate or alter an existing working service for this exercise.
On the server, create a separate service identity and copy your already-issued certificate from its private source. The command assumes these names are unused.[4]
sudo useradd --system --user-group --no-create-home --shell /usr/sbin/nologin sbtuic
sudo install -d -o root -g sbtuic -m 750 /etc/sing-box-tuic
sudo install -o root -g sbtuic -m 640 /PRIVATE/SOURCE/fullchain.pem /etc/sing-box-tuic/fullchain.pem
sudo install -o root -g sbtuic -m 640 /PRIVATE/SOURCE/privkey.pem /etc/sing-box-tuic/privkey.pem
Generate a UUID with sing-box generate uuid and a random password with openssl rand -base64 32 in a private terminal. Save both securely and transfer them through an authorized secure channel. Do not put passwords in shell command arguments, screenshots, chat, or public repositories. A UUID identifies this user; keeping only the UUID does not replace the configured password.[2]
Use a private privileged editor to create /etc/sing-box-tuic/config.json. Replace SERVER_LOCAL_IPV4 with an IPv4 address actually assigned to the server, not an external NAT address. Replace the UUID and password identically in both JSON files. Set the configuration owner to root:sbtuic and mode 640.
{
"log": {
"level": "info"
},
"dns": {
"servers": [
{
"type": "local",
"tag": "system-dns"
}
]
},
"inbounds": [
{
"type": "tuic",
"tag": "tuic-in",
"listen": "SERVER_LOCAL_IPV4",
"listen_port": 24443,
"users": [
{
"name": "reader-test",
"password": "REPLACE_WITH_PRIVATE_PASSWORD",
"uuid": "REPLACE_WITH_GENERATED_UUID"
}
],
"tls": {
"enabled": true,
"certificate_path": "/etc/sing-box-tuic/fullchain.pem",
"key_path": "/etc/sing-box-tuic/privkey.pem"
},
"zero_rtt_handshake": false
}
],
"outbounds": [
{
"type": "direct",
"tag": "direct"
}
],
"route": {
"final": "direct",
"default_domain_resolver": "system-dns"
}
}
The inbound requires TLS and a user; direct forwarding is deliberately separate from authentication. The local DNS server delegates destination-name resolution to this server's operating-system resolver. default_domain_resolver explicitly selects it for direct destination dialing; it does not change the client's system DNS.[2][6]
Create /etc/systemd/system/sing-box-tuic.service as root-owned mode 644 with this unit. It runs an unprivileged identity and reads only this exercise's configuration and certificate files. Port 24443 does not require privileged-port capabilities.
[Unit]
Description=Isolated sing-box tuic reader exercise
After=network-online.target
Wants=network-online.target
[Service]
User=sbtuic
Group=sbtuic
ExecStart=/usr/bin/sing-box run -c /etc/sing-box-tuic/config.json
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
PrivateTmp=true
Restart=on-failure
RestartSec=3
[Install]
WantedBy=multi-user.target
Check configuration as the service identity before starting. A successful check validates configuration, not a remote handshake or public forwarding.
sudo -u sbtuic /usr/bin/sing-box check -c /etc/sing-box-tuic/config.json
sudo systemctl daemon-reload
sudo systemctl start sing-box-tuic.service
sudo systemctl status sing-box-tuic.service --no-pager
sudo ss -lnup
Read bounded recent logs with sudo journalctl -u sing-box-tuic.service -n 30 --no-pager. Keep logs private; even routine diagnostics can expose client addresses. A bind or permission failure is a reason to fix the selected address or file access, not to make the private key world-readable.
Identify the active firewall owner and preserve management access. If an already-active UFW owns policy, add only an inbound UDP rule from the test client's observed public address to the server's local address on port 24443, with comment tuic-test. Apply the equivalent narrow provider rule if needed. Record the exact addition for removal; do not enable, reset, or flush a shared firewall.
For an already-active UFW policy only, replace both address placeholders before adding this rule:
sudo ufw allow proto udp from CLIENT_PUBLIC_IP to SERVER_LOCAL_IPV4 port 24443 comment 'tuic-test'
Opening TCP 24443 does not satisfy TUIC's outer QUIC/UDP transport. The network: tcp setting below limits the application traffic this example enables; it does not turn the server listener into TCP.[3]
Create tuic-client.json privately on the client. Replace SERVER_PUBLIC_IPV4 with the reachable numeric endpoint and tuic.example.com with the certificate's real name. Connecting to an IP while verifying the domain separates reachability from TLS identity. Keep insecure false.[4]
{
"log": {
"level": "info"
},
"inbounds": [
{
"type": "mixed",
"tag": "local-in",
"listen": "127.0.0.1",
"listen_port": 1080
}
],
"outbounds": [
{
"type": "tuic",
"tag": "tuic-out",
"server": "SERVER_PUBLIC_IPV4",
"server_port": 24443,
"password": "REPLACE_WITH_PRIVATE_PASSWORD",
"tls": {
"enabled": true,
"server_name": "tuic.example.com",
"insecure": false
},
"uuid": "REPLACE_WITH_GENERATED_UUID",
"zero_rtt_handshake": false,
"network": "tcp"
}
],
"route": {
"final": "tuic-out"
}
}
chmod 600 tuic-client.json
sing-box check -c tuic-client.json
sing-box run -c tuic-client.json
Leave this foreground process running and use another terminal for requests. Only applications explicitly pointed at 127.0.0.1:1080 use it; retain the device's existing network controls. Do not change or close another proxy application to manufacture success.
Run one bounded request with remote hostname resolution through SOCKS. A response establishes that this request traversed the configured path, not that all applications, DNS, IPv6, or application UDP are covered.
curl --noproxy "" --proxy socks5h://127.0.0.1:1080 --connect-timeout 5 --max-time 20 https://example.com/
For an exit-address check, explicitly configure a separate browser profile to use the local HTTP proxy and open the tool that shows that browser request's visible IP. Restore that profile's original proxy setting afterward. A browser result is separate evidence from the command above.
Use copies of the client configuration for negative checks. Stop only your foreground client with Ctrl-C and start a fresh process for each changed condition, preventing an already-authenticated connection from hiding the failure.
| Reader check | Expected observation | If the result differs |
|---|---|---|
| Correct endpoint, name, UUID, and password | The bounded application request completes | Separate local listener, server log, DNS, and destination failures |
| Change only UUID, then only password | A fresh request is rejected or fails | Confirm the changed file is loaded and no old client serves 1080 |
| Change only TLS server name to an unrelated name | Certificate verification prevents connection | Inspect certificate names; never enable insecure mode |
| Remove only the exercise's UDP allowance in an isolated test policy | Fresh connection fails when that removal actually blocks the path | Other allow rules may still permit traffic; inspect policy ownership |
| Remove the user, validate configuration, restart this unit | Removed credentials fail on a fresh connection | Check effective file, unit command, and fresh client identity |
| Restart with the retained valid user | A new authorized request works | Compare the private baseline and recent service logs |
These are expected checks, not reported test results. For the UDP test, restore the exact removed rule before proceeding and verify management still works. Do not insert a broad deny on a shared network. If you cannot isolate the path safely, mark this check unperformed.
Keep zero_rtt_handshake: false at both ends. The implementation recommends disabling this replay-sensitive optimization; changing congestion control is not evidence of better speed or resistance to blocking.[2][3]
Renew the certificate through its established CA workflow. Install the new chain and matching key with the same restrictive ownership, check configuration, restart only sing-box-tuic.service, and make a fresh authorized request. Compare the served identity and expiry with the intended certificate; a restarted process alone is insufficient. File reloading is documented, but this exercise uses an explicit restart to make the verification point clear.[4]
For credential compromise, remove or replace the affected user and restart this isolated unit; a restart interrupts its existing connections. Do not restore a compromised password from backup. Recheck both new-user success and old-user refusal before enabling startup with sudo systemctl enable sing-box-tuic.service.
For retirement, stop and disable this unit, stop the owned client, and remove only the recorded exercise firewall/provider allowance. Restore the browser proxy, then remove this exercise's unit and private configuration after preserving necessary diagnostics. Run sudo systemctl daemon-reload, inspect the port, and verify the original management and DNS paths. Remove packages or APT files only if your baseline proves this exercise introduced them and nothing else uses them. If restoration fails, stop further experiments and use the independent recovery channel.
Inspect the deployed certificate file with sudo openssl x509 -in /etc/sing-box-tuic/fullchain.pem -noout -subject -issuer -dates. This shows local identity and validity dates; combine it with a fresh TLS-verified client request, since reading a file alone does not prove which certificate a remote process serves.
After removing the exercise files, remove its newly created sbtuic account only after confirming that no remaining process, service unit, or file depends on its UID or group. Use sudo userdel sbtuic without force or home-directory removal; if its dedicated group remains and has no other members or dependencies, remove it with sudo groupdel sbtuic. Preserve pre-existing identities and stop if ownership is uncertain. Delete the owned tuic-client.json and negative-test copies when no longer needed; keep any necessary backups private and never reactivate revoked credentials.[7][8]
TUIC uses outer UDP/QUIC. A TCP result does not validate that UDP port, the TLS handshake, user authentication, or forwarding.
No. This configuration supplies both fields for one user; the client must match the server's configured UUID and password.[2][3]
The implementation warns about replay risk. This guide keeps it disabled and makes no claim that enabling it improves your workload.[2]
Do not infer that from a file edit. This exercise validates the changed file and restarts its isolated service, then checks a fresh connection with removed credentials.
No. It describes the tested browser request. Other applications, DNS, IPv6, and UDP need separate coverage and failure checks.
No. Use the selected TUIC implementation and matching fields. A neighboring protocol's profile does not establish compatibility with this server.
Keep the independent management path working, stop the owned processes, restore the exact firewall and client settings, then verify the baseline before removing private files.
Disclaimer: Use only hosts and networks you own or are authorized to administer, and follow applicable law and network policy. The instructions and expected checks are not an author deployment record or a performance guarantee.
Sources:
Sources checked 11 October 2026.
Related Articles:
Sign up to experience all premium features at no cost.
*Available only to new users. Each user is limited to one trial.