Table of Contents
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
Getting SSL
ACME
To manage SSL certificates using ACME:
-
Ensure your domain is correctly resolved to the server.
-
Run the
x-uicommand in the terminal, then chooseSSL Certificate Management. -
You will be presented with the following options:
- Get SSL: Obtain SSL certificates.
- Revoke: Revoke existing SSL certificates.
- Force Renew: Force renewal of SSL certificates.
- Show Existing Domains: Display all domain certificates available on the server.
- Set Certificate Paths for the Panel: Specify the certificate for your domain to be used by the panel.
Certbot
To install and use Certbot:
apt-get install certbot -y
certbot certonly --standalone --agree-tos --register-unsafely-without-email -d yourdomain.com
certbot renew --dry-run
Cloudflare
The management script includes a built-in SSL certificate application for Cloudflare. To use this script to apply for a certificate, you need the following:
- Cloudflare registered email
- Cloudflare Global API Key
- The domain name must be resolved to the current server through Cloudflare
How to get the Cloudflare Global API Key:
- Run the
x-uicommand in the terminal, then chooseCloudflare SSL Certificate. - Visit the link: Cloudflare API Tokens.
- Click on "View Global API Key" (see the screenshot below):
- You may need to re-authenticate your account. After that, the API Key will be shown (see the screenshot below):
When using, just enter your domain name, email, and API KEY. The diagram is as follows:
Available environment variables
XUI_LOG_LEVEL
- Description: Default log level
- Type:
string - Acceptable values:
debug|info|warn|error - Default value:
info
XUI_DEBUG
- Description: Whether debug mode should be enabled
- Type:
boolean - Default value:
false
XUI_BIN_FOLDER
- Description: Path to the folder with xray-core, geosite & geoip databases
- Type:
string - Default value:
bin
XUI_DB_FOLDER
- Description: Path to the 3x-ui database
- Type:
string - Default value:
/etc/x-ui
XUI_LOG_FOLDER
- Description: Path to the logs
- Type:
string - Default value:
/var/log
XUI_ENABLE_FAIL2BAN
- Description: Should fail2ban be working
- Type:
boolean - Default value:
true
Reverse Proxy
Nginx
To configure the reverse proxy, add the following paths to your nginx config
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Range $http_range;
proxy_set_header If-Range $http_if_range;
proxy_redirect off;
proxy_pass http://127.0.0.1:2053;
}
Note
The URL in the panel settings needs to end with /.
For the subscriptions
location /sub {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Range $http_range;
proxy_set_header If-Range $http_if_range;
proxy_redirect off;
proxy_pass http://127.0.0.1:2096;
}
Note
Ensure that the "URI Path" in the /sub panel settings is the same.
Caddy
Important
A huge thanks to @Gill-Bates for providing the config
Important
This configuration will work when the “WebSocket” transport is set inbound
Before configuring caddyfile, make sure that the following parameters are set in the panel setup
After customizing the panel, modify the caddyfile as follows
vpn.example.com {
encode gzip
# TLS 1.3 mandatory!
tls {
protocols tls1.3
}
# Protect your GUI with Basic Auth
route /admin* {
basic_auth {
admin ******
}
reverse_proxy xx.xx.xx.xx:2053
}
# Obfuscate the Endpoint
route /api/v1* {
@websockets {
header Connection *Upgrade*
header Upgrade websocket
}
reverse_proxy @websockets xx.xx.xx.xx:54321
respond "Forbidden" 403
}
# Security Header
header {
header_up Authorization { >Authorization }
header_up Content-Type { >Content-Type }
Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
X-Content-Type-Options nosniff
X-Frame-Options SAMEORIGIN
Referrer-Policy strict-origin-when-cross-origin
-Server
-X-Powered-By
}
# Fallback
respond "Not found!" 404
}
The following data must be replaced in the config:
vpn.example.com-> your domain.admin *****-> replace the asterisks with your password.
If you do not need HTTP Auth, remove the following line
basic_auth {
admin ******
}
reverse_proxy xx.xx.xx.xx-> replace thexx.xx.xx.xxwith your IPreverse_proxy @websockets xx.xx.xx.xx:54321-> replace54321with your inbound port
Setting Fail2Ban
Note
IP Limit won't work correctly when using IP Tunnel.
For versions up to v1.6.1:
The IP limit is built-in to the panel
For versions v1.7.0 and newer:
To enable the IP Limit functionality, you need to install fail2ban and its required files by following these steps:
-
Run the
x-uicommand in the terminal, then chooseIP Limit Management. -
You will see the following options:
- Change Ban Duration: Adjust the duration of bans.
- Unban Everyone: Lift all current bans.
- Check Logs: Review the logs.
- Fail2ban Status: Check the status of
fail2ban. - Restart Fail2ban: Restart the
fail2banservice. - Uninstall Fail2ban: Uninstall Fail2ban with configuration.
-
Add a path for the access log on the panel by setting
Xray Configs/log/Access logto./access.logthen save and restart xray.
-
For versions before
v2.1.3:-
You need to set the access log path manually in your Xray configuration:
"log": { "access": "./access.log", "dnsLog": false, "loglevel": "warning" },
-
-
For versions
v2.1.3and newer:- There is an option for configuring
access.logdirectly from the panel.
- There is an option for configuring
API Documentation
Authentication
-
Endpoint:
/login -
Method:
POST -
Body:
{ "username": "", "password": "" } -
Use this endpoint to authenticate and receive a session.
Inbounds API
Base path: /panel/api/inbounds
| Method | Path | Description |
|---|---|---|
GET |
/list |
Get all inbounds |
GET |
/get/:id |
Get inbound by ID |
GET |
/getClientTraffics/:email |
Get client traffics by email |
GET |
/getClientTrafficsById/:id |
Get client traffics by inbound ID |
POST |
/add |
Add new inbound |
POST |
/del/:id |
Delete inbound by ID |
POST |
/update/:id |
Update inbound by ID |
POST |
/clientIps/:email |
Get client IP addresses |
POST |
/clearClientIps/:email |
Clear client IP addresses |
POST |
/addClient |
Add client to inbound |
POST |
/:id/delClient/:clientId |
Delete client by clientId* |
POST |
/updateClient/:clientId |
Update client by clientId* |
POST |
/:id/resetClientTraffic/:email |
Reset a client’s traffic usage |
POST |
/resetAllTraffics |
Reset traffics for all inbounds |
POST |
/resetAllClientTraffics/:id |
Reset traffics for all clients in inbound |
POST |
/delDepletedClients/:id |
Delete depleted clients in inbound (-1: all) |
POST |
/import |
Import inbound configuration |
POST |
/onlines |
Get currently online clients (emails list) |
POST |
/lastOnline |
Get last online status of clients |
POST |
/updateClientTraffic/:email |
Update traffic for specific client |
POST |
/import |
import inbound |
POST |
/lastOnline |
last Online |
POST |
/{id}/delClientByEmail/{email} |
Delete Client By Email |
* clientId mapping:
client.id→ VMESS / VLESSclient.password→ TROJANclient.email→ Shadowsocks
Server API
Base path: /panel/api/server
| Method | Path | Description |
|---|---|---|
GET |
/status |
Get server status |
GET |
/getXrayVersion |
Get available Xray versions |
GET |
/getConfigJson |
Download current config.json |
GET |
/getDb |
Download database file (x-ui.db) |
GET |
/getNewUUID |
Generate new UUID |
GET |
/getNewX25519Cert |
Generate new X25519 certificate |
GET |
/getNewmldsa65 |
Generate new ML-DSA-65 certificate |
GET |
/getNewmlkem768 |
Generate new ML-KEM-768 key pair |
GET |
/getNewVlessEnc |
Generate new VLESS encryption keys |
POST |
/stopXrayService |
Stop Xray service |
POST |
/restartXrayService |
Restart Xray service |
POST |
/installXray/:version |
Install/Update Xray to given version |
POST |
/updateGeofile |
Update GeoIP/GeoSite data files |
POST |
/updateGeofile/:fileName |
Update specific Geo file |
POST |
/logs/:count |
Get system logs (with level, syslog) |
POST |
/xraylogs/:count |
Get Xray logs (with filters) |
POST |
/importDB |
Import database |
POST |
/getNewEchCert |
Generate new ECH certificate (requires sni) |
Extra API
Base path: /panel/api
| Method | Path | Description |
|---|---|---|
GET |
/backuptotgbot |
Backup DB/config and send to Telegram Bot |
Geosites
What is it?
The Geosites in Xray-core play a key role in traffic routing, enabling flexible control over traffic distribution based on the geographical location of IP addresses and domains. Here are their main files:
-
geoip.datcontains a database of IP addresses classified by country (e.g.,geoip:cnfor China orgeoip:privatefor private networks). This allows:-
Redirecting traffic for specific countries (e.g., Chinese IPs via direct, others via proxy).
-
Blocking or allowing access to IPs from certain regions.
-
-
geosite.datincludes domain lists grouped by categories (e.g.,geosite:cnfor Chinese domains,geosite:googlefor Google services). This is used for:- Granular traffic control (e.g., ad domains → block, streaming → proxy).
Sources
3X-UI uses multiple geofiles sources for flexible traffic routing:
| Repository | Files | Available geosites |
|---|---|---|
| Loyalsoldier/v2ray-rules-dat | geoip.dat geosite.dat |
View |
| 🇮🇷 chocolate4u/Iran-v2ray-rules | geoip_IR.dat geosite_IR.dat |
View |
| 🇷🇺 runetfreedom/russia-v2ray-rules-dat | geoip_RU.dat geosite_RU.dat |
View |
Updating geofiles
- Open panel and click to Xray version
- Open
Geofilesdropdown and update the needed geofile
3X-UI
Overview
Setup
- ⬇️ Installation (One-line)
- ⬇️ Installation (Docker)
- ⬇️ Install Legacy version
- ⬇️ Manual installation
Configuration
- 🔐 Getting SSL certificate
- 🛡️ Setting Fail2Ban
- 🗝️ Environment variables
- ➡️ Using Reverse proxy
- 🛜 API Documentation
- 🌎 Geosites

