3U
Networking Azure

3X-UI on Ubuntu 24.04 on Azure User Guide

| Product: 3X-UI on Ubuntu 24.04 LTS on Azure

Overview

3X-UI is a web based management panel for Xray-core, the proxy platform behind protocols such as VLESS, VMess, Trojan and Shadowsocks. It gives you a browser interface to create and manage inbound connections and client accounts, apply per client traffic limits and expiry dates, watch live traffic and system statistics, and control the underlying Xray process, all without hand editing JSON configuration. The panel stores its accounts, inbounds and settings in an embedded SQLite database and runs Xray-core as a managed child process, regenerating its configuration and reloading it for you whenever you change an inbound. The cloudimg image serves 3X-UI 3.5.0 on a hardened, fully patched Ubuntu 24.04 LTS base as a single self contained Go binary managed by systemd.

This is proxy infrastructure with a privileged admin panel, so the image is built to be secure by default. There are no shared or default credentials: the well known upstream admin / admin login is never present on a running VM, because a per VM administrator username and password are generated on your own VM at first boot. The panel is served under a random secret base path, so it is not exposed at a predictable URL. And the image ships with zero inbounds, so Xray binds no proxy port and nothing relays traffic until you deliberately create an inbound. Backed by 24/7 cloudimg support.

What is included:

  • 3X-UI 3.5.0, from the pinned upstream release, as a single Go binary managed by systemd
  • The bundled Xray-core engine, managed by the panel as a child process
  • A per VM admin username and password generated at first boot, never baked into the image
  • A random secret web base path per VM, so the panel is not reachable at a predictable URL
  • Zero inbounds and zero proxy accounts: Xray binds no proxy port on a fresh VM
  • The subscription server disabled by default, so the panel is the only public surface
  • Plain HTTP on port 2053 with no baked TLS certificate, ready for you to add your own
  • x-ui.service as an enabled systemd unit, gated behind first boot credential rotation
  • 24/7 cloudimg support

Prerequisites

An active Azure subscription, an SSH key pair, and a VNet plus subnet in the target region. Standard_B2s (2 vCPU / 4 GiB RAM) is a sensible starting point. NSG inbound: allow 22/tcp from your management network and 2053/tcp for the panel.

Read this before you boot the VM. 3X-UI configures a proxy server that will relay arbitrary traffic once you create an inbound, and the panel is a privileged admin surface. Treat this VM as your own authorised use proxy infrastructure. Scope the inbound NSG rule for 2053/tcp (the panel) and 22/tcp (SSH) to your own IP address before you boot the VM. Do not leave the panel open to 0.0.0.0/0. The panel is protected by a per VM credential and a secret base path, but limiting who can reach it at all is your first line of defence.

Step 1 - Deploy from the Azure Marketplace

Sign in to the Azure Portal, choose Create a resource, search the Marketplace for 3X-UI by cloudimg, and select Create. On Basics pick your subscription, resource group, region and size; under Administrator account choose SSH public key and paste your key; under Inbound port rules allow SSH (22), then add a custom rule for 2053 scoped to your own IP. Then Review + create then Create.

Step 2 - Deploy from the Azure CLI

az vm create \
  --resource-group <your-rg> \
  --name 3x-ui \
  --image <marketplace-image-urn> \
  --size Standard_B2s \
  --admin-username azureuser \
  --generate-ssh-keys \
  --public-ip-sku Standard

Then open the panel port, restricted to your own address:

az network nsg rule create \
  --resource-group <your-rg> \
  --nsg-name 3x-uiNSG \
  --name allow-3x-ui-panel \
  --priority 900 \
  --source-address-prefixes <your-ip>/32 \
  --destination-port-ranges 2053 \
  --access Allow --protocol Tcp

Step 3 - Confirm the service and listeners

SSH in as azureuser and confirm the panel is active. The only ports open to the network are 22 for SSH and 2053 for the panel; Xray binds no proxy port because the image ships with zero inbounds.

systemctl is-active x-ui
sudo ss -tlnH | awk '{print $4}' | grep -vE '^(127\.|\[::1\])' | sort -u

The command above lists every publicly bound port. On a fresh VM it prints exactly 0.0.0.0:22 (SSH) and one entry for the panel on 2053 - nothing else, because there are no inbounds and the subscription server is disabled by default.

The x-ui service active, only ports 22 and 2053 publicly bound, Xray running as a managed child with no proxy port, and the subscription server disabled

Step 4 - Get your per VM credentials

The image ships with no usable login: the well known upstream admin / admin default never exists on a running VM. On the first boot of every VM a one shot service generates a random administrator username and password and a random secret base path, and writes them to a root only file. Read it to get your panel URL, username and password:

sudo cat /root/3x-ui-credentials.txt

The panel.url line is your login URL. It includes the random base path, so the panel is reachable only at that address; a bare visit to the host and port returns 404. Keep this file safe - it is mode 0600 and readable only by root.

The first boot credentials note showing the per VM admin username, the secret base path and the panel URL, with the password line redacted, plus the panel bound to 2053 and no baked TLS certificate

Step 5 - Log in to the panel

Open the panel.url from the credentials file in your browser - it looks like http://<vm-public-ip>:2053/<random-base-path>/. The panel opens on its login form. Enter the panel.username and panel.password from the credentials file and select Login. There are no default credentials to change, because none ship - the account you are logging in with was generated for this VM alone.

The 3X-UI login form, reached only under the per VM secret base path - a bare request to the host and port returns 404

Step 6 - The dashboard

After signing in, the dashboard shows the panel and Xray status, system statistics (CPU, memory, network throughput and uptime), and your inbound and client totals. On a fresh VM the inbound count is zero: Xray is running but has no proxy listener, so the VM is not relaying any traffic yet.

The 3X-UI dashboard after sign in, showing Xray running, system statistics, and zero inbounds on a fresh VM

Step 7 - Create your first inbound

The Inbounds page is where you create the proxy endpoints your clients connect to. Select Add Inbound to open the inbound form: choose a protocol (for example VLESS, VMess or Trojan) from the Basics tab, set a remark and a port, and use the Protocol, Stream, Security and Sniffing tabs to tune the transport, then Create.

The 3X-UI Add Inbound form, where you choose the protocol, port and transport for a new proxy endpoint across the Basics, Protocol, Stream, Security and Sniffing tabs

When you select Create, the panel writes the inbound to its database, regenerates the Xray configuration and reloads Xray so it starts listening on the new port immediately - you do not restart anything by hand. The screenshot below shows an inbound that has just been created and is listed as enabled. Because the image ships with none, this is your own first inbound: the panel is doing the one thing it exists to do, turning a form into a live Xray listener.

The 3X-UI Inbounds page showing a newly created, enabled VLESS inbound on its port - the panel has written it to the database and reloaded Xray to listen

Open the inbound to manage its clients. Each client has its own UUID or password, and you can set a traffic limit, an expiry date and get its connection string or QR code to share with a device.

Step 8 - Confirm the secure by default posture

These checks confirm, from the command line, the security properties the image ships with. They read your per VM credentials from the credentials file, so they work as written.

The panel is reachable only under your secret base path - a bare request to the host and port returns 404:

PORT=$(sudo grep '^panel.port=' /root/3x-ui-credentials.txt | cut -d= -f2-)
curl -s -o /dev/null -w 'bare / -> HTTP %{http_code}  (404 = panel hidden under your secret base path)\n' http://127.0.0.1:${PORT}/

The well known upstream default admin / admin is rejected by the credential check - it returns success:false, not an error, because the credential is genuinely evaluated and genuinely wrong:

CREDS=/root/3x-ui-credentials.txt
PORT=$(sudo grep '^panel.port=' $CREDS | cut -d= -f2-)
BP=$(sudo grep '^panel.basepath=' $CREDS | cut -d= -f2-)
B="http://127.0.0.1:${PORT}"
TOK=$(curl -s -c /tmp/xui-cj "${B}${BP}csrf-token" | jq -r .obj)
curl -s -b /tmp/xui-cj -X POST -H "X-CSRF-Token: ${TOK}" -H 'Content-Type: application/json' \
     -d '{"username":"admin","password":"admin"}' "${B}${BP}login"; echo

Your per VM credential, by contrast, logs in successfully:

CREDS=/root/3x-ui-credentials.txt
U=$(sudo grep '^panel.username=' $CREDS | cut -d= -f2-)
P=$(sudo grep '^panel.password=' $CREDS | cut -d= -f2-)
PORT=$(sudo grep '^panel.port=' $CREDS | cut -d= -f2-)
BP=$(sudo grep '^panel.basepath=' $CREDS | cut -d= -f2-)
B="http://127.0.0.1:${PORT}"
TOK=$(curl -s -c /tmp/xui-cj "${B}${BP}csrf-token" | jq -r .obj)
curl -s -b /tmp/xui-cj -X POST -H "X-CSRF-Token: ${TOK}" -H 'Content-Type: application/json' \
     -d "{\"username\":\"${U}\",\"password\":\"${P}\"}" "${B}${BP}login"; echo
rm -f /tmp/xui-cj

Command line proof of the secure defaults: a bare request returning 404, the admin/admin default rejected with success false, and the per VM credential logging in successfully

Step 9 - Change the panel port (optional hardening)

The panel listens on 2053 by default. Moving it to a port of your choice, together with the secret base path, further reduces drive by exposure:

sudo /usr/local/x-ui/x-ui setting -port 48291
sudo systemctl restart x-ui

Update your NSG rule and your bookmark to the new port. You can review the current settings, including the base path and port, at any time with sudo /usr/local/x-ui/x-ui setting -show true.

Step 10 - Put TLS in front of the panel

The image serves plain HTTP on port 2053. Until you terminate TLS, your panel password crosses the network in clear text, so this is not optional for anything beyond a short lived test.

Point a DNS name at the VM's public IP, obtain a certificate (for example with certbot in standalone mode, or from your own CA), then tell the panel to use it:

sudo /usr/local/x-ui/x-ui setting -webCert /etc/letsencrypt/live/panel.your-domain.com/fullchain.pem
sudo /usr/local/x-ui/x-ui setting -webCertKey /etc/letsencrypt/live/panel.your-domain.com/privkey.pem
sudo systemctl restart x-ui

The panel then serves HTTPS on 2053. The image ships no certificate, so nothing about your TLS setup is shared with any other VM.

Step 11 - Verify the stack

/usr/local/x-ui/x-ui -v
systemctl is-enabled x-ui 3x-ui-firstboot
sudo sqlite3 /etc/x-ui/x-ui.db 'SELECT COUNT(*) AS inbounds FROM inbounds;'

The inbound count above is 0 on a fresh VM, and it rises only as you add your own inbounds.

The deployed 3X-UI version, both units enabled for the customer boot, zero inbounds in the database, and a fully patched OS

Step 12 - Where your data lives

Everything 3X-UI stores - the admin account, your inbounds and client accounts, settings and traffic statistics - lives in the SQLite database at /etc/x-ui/x-ui.db. The panel binary and the bundled Xray engine are under /usr/local/x-ui and hold no per instance state.

sudo ls -la /etc/x-ui/

Back up /etc/x-ui/x-ui.db to preserve your panel configuration. It contains your admin credential (as a bcrypt hash), your inbounds and every client account.

Security notes

  • No default credentials. The upstream admin / admin default never exists on a running VM. A per VM administrator username and password are generated from the system random source on your own VM at first boot and written to /root/3x-ui-credentials.txt (mode 0600). The panel service will not start until that rotation has happened.
  • Secret base path. The panel is served under a random base path generated per VM, so it is not reachable at a predictable URL. A bare request to the host and port returns 404.
  • Zero inbounds ship. The image contains no inbounds and no proxy accounts, so Xray binds no proxy port and the VM relays nothing until you create an inbound. The subscription server is disabled by default, so the panel on 2053 is the only public surface.
  • Scope the NSG. This is proxy infrastructure with a privileged admin panel. Restrict inbound access to 2053 and 22 to your own IP address before first boot.
  • Plain HTTP by default. The panel serves HTTP and ships no TLS certificate. Add your own certificate (Step 10) before using it beyond a short lived test.
  • Patching. The image ships fully patched and unattended-upgrades remains enabled, so security updates continue to apply on your VM.
  • Authorised use. Run only proxy endpoints you are authorised to operate. You are responsible for the traffic your inbounds relay.

Support

cloudimg provides 24/7 support for this image. Contact support@cloudimg.co.uk with the VM name, region and the output of systemctl status x-ui.