### Install Nginx Source: https://github.com/andyshaman/3x-ui-skill/blob/main/skill/references/fallback-nginx.md Installs Nginx on the server. This is a prerequisite for setting up the fallback site. ```bash ssh {nickname} "sudo apt update && sudo apt install -y nginx" ``` -------------------------------- ### Verify 3x-ui-setup Skill Installation Source: https://context7.com/andyshaman/3x-ui-skill/llms.txt Checks if the 3x-ui-setup skill has been installed correctly by verifying the presence of its main markdown file. Expected output is 'Verification: OK'. ```bash # Expected output: "Verification: OK" ls ~/.claude/skills/3x-ui-setup/SKILL.md ``` -------------------------------- ### Manual Install 3x-ui Skill Source: https://github.com/andyshaman/3x-ui-skill/blob/main/README.md Clone the repository and copy the skill to the Claude skills directory for manual installation. ```bash git clone https://github.com/AndyShaman/3x-ui-skill.git cp -r 3x-ui-skill/skill ~/.claude/skills/3x-ui-setup rm -rf 3x-ui-skill ``` -------------------------------- ### Install Base Packages and Enable Time Sync Source: https://github.com/andyshaman/3x-ui-skill/blob/main/skill/SKILL.md Installs essential packages like chrony for time synchronization, curl, wget, unzip, and net-tools. It also ensures chrony starts on boot. ```bash sudo apt install -y chrony curl wget unzip net-tools sudo systemctl enable chrony ``` -------------------------------- ### Install 3x-ui Skill with curl Source: https://github.com/andyshaman/3x-ui-skill/blob/main/README.md Use this command to quickly install the 3x-ui skill script from GitHub. ```bash curl -fsSL https://raw.githubusercontent.com/AndyShaman/3x-ui-skill/main/install.sh | bash ``` -------------------------------- ### Install 3x-ui Panel Source: https://context7.com/andyshaman/3x-ui-skill/llms.txt Downloads and installs the 3x-ui panel. Answers 'n' to port customization for auto-generated random port and credentials. Capture the output for panel username, password, port, and web base path. ```bash ssh myserver "curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh \ -o /tmp/3x-ui-install.sh && echo 'n' | sudo bash /tmp/3x-ui-install.sh" ``` ```bash ssh myserver "sudo x-ui status" ``` -------------------------------- ### Install and Configure Fail2ban Source: https://context7.com/andyshaman/3x-ui-skill/llms.txt Installs Fail2ban, configures it to protect SSH, and enables it to start on boot. It sets ban time, find time, and max retries for SSH. ```bash ssh myserver 'sudo apt install -y fail2ban && sudo tee /etc/fail2ban/jail.local << JAILEOF [DEFAULT] bantime = 1h findtime = 10m maxretry = 5 [sshd] enabled = true port = ssh filter = sshd logpath = /var/log/auth.log maxretry = 3 bantime = 24h JAILEOF sudo systemctl enable fail2ban && sudo systemctl restart fail2ban' ``` -------------------------------- ### Install and Configure UFW Firewall Source: https://github.com/andyshaman/3x-ui-skill/blob/main/skill/SKILL.md Installs the Uncomplicated Firewall (UFW), sets default policies to deny incoming and allow outgoing traffic, and explicitly allows SSH, HTTP, and HTTPS. ```bash sudo apt install -y ufw sudo ufw default deny incoming sudo ufw default allow outgoing sudo ufw allow ssh sudo ufw allow 80/tcp sudo ufw allow 443/tcp sudo ufw --force enable sudo ufw status ``` -------------------------------- ### Install 3x-ui Panel Source: https://github.com/andyshaman/3x-ui-skill/blob/main/skill/SKILL.md Installs the 3x-ui panel script. The `echo 'n'` command bypasses the port customization prompt, generating random credentials and a port. Capture the output for access details. Do not use process substitution with sudo. ```bash ssh {nickname} "curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh -o /tmp/3x-ui-install.sh && echo 'n' | sudo bash /tmp/3x-ui-install.sh" ``` -------------------------------- ### Install SSH Key for New User Source: https://github.com/andyshaman/3x-ui-skill/blob/main/skill/SKILL.md Sets up the SSH authorized_keys file for the new user, ensuring secure key-based authentication. Permissions are set to restrict access. ```bash mkdir -p /home/{username}/.ssh echo "{PUBLIC_KEY_CONTENT}" > /home/{username}/.ssh/authorized_keys chmod 700 /home/{username}/.ssh chmod 600 /home/{username}/.ssh/authorized_keys chown -R {username}:{username} /home/{username}/.ssh ``` -------------------------------- ### Install SSH Public Key for New User Source: https://context7.com/andyshaman/3x-ui-skill/llms.txt Copies the generated SSH public key to the new user's authorized_keys file, enabling passwordless SSH login for that user. ```bash mkdir -p /home/deploy/.ssh echo "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA... deploy@myserver" > /home/deploy/.ssh/authorized_keys chmod 700 /home/deploy/.ssh chmod 600 /home/deploy/.ssh/authorized_keys chown -R deploy:deploy /home/deploy/.ssh ``` -------------------------------- ### Test New User Login and Sudo Access Source: https://context7.com/andyshaman/3x-ui-skill/llms.txt Tests the newly created user's ability to log in via SSH using the installed key and execute commands with sudo privileges. This is a critical checkpoint before proceeding. ```bash # Open a NEW terminal — keep root session alive ssh -i ~/.ssh/myserver_key deploy@203.0.113.42 # Verify sudo works sudo whoami # Must output: root # If test fails, debug as root: ls -la /home/deploy/.ssh/ chown -R deploy:deploy /home/deploy/.ssh ``` -------------------------------- ### Install and Configure Fail2ban Source: https://github.com/andyshaman/3x-ui-skill/blob/main/skill/SKILL.md Installs the fail2ban service to protect against brute-force attacks, configures it to monitor SSH logs, and enables it to automatically restart. It also locks down SSH by disabling root login and password authentication. ```bash ssh {nickname} 'sudo apt install -y fail2ban && sudo tee /etc/fail2ban/jail.local << JAILEOF [DEFAULT] bantime = 1h findtime = 10m maxretry = 5 [sshd] enabled = true port = ssh filter = sshd logpath = /var/log/auth.log maxretry = 3 bantime = 24h JAILEOF sudo systemctl enable fail2ban && sudo systemctl restart fail2ban' ``` ```bash ssh {nickname} 'sudo sed -i "s/^#\?PermitRootLogin.*/PermitRootLogin no/" /etc/ssh/sshd_config && sudo sed -i "s/^#\?PasswordAuthentication.*/PasswordAuthentication no/" /etc/ssh/sshd_config && sudo systemctl restart sshd' ``` -------------------------------- ### Manage x-ui Panel Service Source: https://context7.com/andyshaman/3x-ui-skill/llms.txt Provides commands to start, stop, restart, check status, view logs, reset settings, update, and manage SSL certificates for the x-ui panel. ```bash ssh myserver "sudo x-ui start" ``` ```bash ssh myserver "sudo x-ui stop" ``` ```bash ssh myserver "sudo x-ui restart" ``` ```bash ssh myserver "sudo x-ui status" ``` ```bash ssh myserver "sudo x-ui log" ``` ```bash ssh myserver "sudo x-ui setting -reset" ``` ```bash ssh myserver "sudo x-ui update" ``` ```bash ssh myserver "sudo x-ui cert" ``` -------------------------------- ### Check 3x-ui Status Source: https://github.com/andyshaman/3x-ui-skill/blob/main/skill/SKILL.md Verifies if the 3x-ui service is running. If not, it provides a command to start it. ```bash ssh {nickname} "sudo x-ui status" ``` ```bash ssh {nickname} "sudo x-ui start" ``` -------------------------------- ### Deploy Nginx Camouflage Page Source: https://context7.com/andyshaman/3x-ui-skill/llms.txt Installs Nginx to serve a camouflage page. This is applicable for VLESS TLS with TCP transport. ```bash ssh myserver "sudo apt update && sudo apt install -y nginx" ``` -------------------------------- ### Configure UFW Firewall Source: https://context7.com/andyshaman/3x-ui-skill/llms.txt Installs and configures the Uncomplicated Firewall (UFW) to deny incoming traffic by default, allow outgoing traffic, and permit SSH, HTTP, and HTTPS. ```bash sudo apt install -y ufw sudo ufw default deny incoming sudo ufw default allow outgoing sudo ufw allow ssh sudo ufw allow 80/tcp sudo ufw allow 443/tcp sudo ufw --force enable sudo ufw status # Output: # Status: active # To Action From # 22/tcp ALLOW Anywhere # 80/tcp ALLOW Anywhere # 443/tcp ALLOW Anywhere ``` -------------------------------- ### Get VLESS TLS Connection Link Source: https://github.com/andyshaman/3x-ui-skill/blob/main/skill/references/vless-tls.md Executes a command on a remote server to fetch VLESS TLS connection details. It queries the panel API, filters for VLESS protocol with TLS, and formats the output into a connection link. Ensure the panel port and nickname are correctly substituted. ```bash ssh {nickname} 'PANEL_PORT={panel_port}; curl -sk -b /tmp/3x-cookie "https://127.0.0.1:${PANEL_PORT}/{web_base_path}/panel/api/inbounds/list" | python3 -c " import json,sys data = json.load(sys.stdin) for inb in data.get(\"obj\", []): if inb.get(\"protocol\") == \"vless\" and \"tls\" in inb.get(\"streamSettings\", \""): settings = json.loads(inb[\"settings\"]) stream = json.loads(inb[\"streamSettings\"]) client = settings[\"clients\"][0] uuid = client[\"id\"] port = inb[\"port\"] sni = stream.get(\"tlsSettings\", {{}}).get(\"serverName\", \"") flow = client.get(\"flow\", \"") link = f\"vless://{uuid}@{sni}:{port}?type=tcp&security=tls&sni={sni}&fp=chrome&flow={flow}#vless-tls\" print(link) break "' ``` -------------------------------- ### Obtain SSL Certificate using acme.sh Source: https://github.com/andyshaman/3x-ui-skill/blob/main/skill/references/vless-tls.md A non-interactive method to obtain an SSL certificate using acme.sh. Ensure socat is installed and the script is executed with appropriate permissions. ```bash ssh {nickname} "sudo apt install -y socat && curl https://get.acme.sh | sh && sudo ~/.acme.sh/acme.sh --issue -d {domain} --standalone --httpport 80 && sudo ~/.acme.sh/acme.sh --install-cert -d {domain} --key-file /root/cert/{domain}/privkey.pem --fullchain-file /root/cert/{domain}/fullchain.pem --reloadcmd 'x-ui restart'" ``` -------------------------------- ### Test New User SSH Login Source: https://github.com/andyshaman/3x-ui-skill/blob/main/skill/SKILL.md Connect to the server using the new user's credentials and SSH key. This is a critical step to verify access before proceeding. ```bash ssh -i ~/.ssh/{nickname}_key {username}@{SERVER_IP} ``` -------------------------------- ### Verify Sudo Access for New User Source: https://github.com/andyshaman/3x-ui-skill/blob/main/skill/SKILL.md After logging in as the new user, run this command to confirm that sudo privileges are correctly configured. ```bash sudo whoami ``` -------------------------------- ### Update System Packages Non-interactively Source: https://context7.com/andyshaman/3x-ui-skill/llms.txt Updates package lists and upgrades installed packages on Debian/Ubuntu systems without user interaction, suitable for automation. ```bash apt update && DEBIAN_FRONTEND=noninteractive NEEDRESTART_MODE=a apt upgrade -y ``` -------------------------------- ### Final Verification Commands Source: https://github.com/andyshaman/3x-ui-skill/blob/main/skill/SKILL.md After setting up the SSH shortcut, connect using 'ssh {nickname}' and then run these commands on the server to verify firewall status and kernel network filtering. ```bash # Then on server: sudo ufw status sudo sysctl net.ipv4.conf.all.rp_filter ``` -------------------------------- ### Create Stub HTML Page Source: https://github.com/andyshaman/3x-ui-skill/blob/main/skill/references/fallback-nginx.md Creates a realistic-looking fake cloud login page at /var/www/html/index.html to serve as the fallback content. ```bash ssh {nickname} 'sudo tee /var/www/html/index.html << '"'"'HTML_EOF'"'"' Cloud Storage

Cloud Storage

Sign in to access your files

HTML_EOF' ``` -------------------------------- ### Run Reality Scanner in Local Mode (/24 subnet) Source: https://github.com/andyshaman/3x-ui-skill/blob/main/skill/SKILL.md Executes the RealiTLScanner directly on the VPS to scan the local /24 subnet. It determines the system architecture, downloads the correct scanner binary, makes it executable, and then runs the scan, limiting the output to the first 80 lines. This is useful when direct access to the VPS is available. ```bash ARCH=$(dpkg --print-architecture); case "$ARCH" in amd64) SA="64";; arm64|aarch64) SA="arm64-v8a";; *) SA="$ARCH";; esac && curl -sL "https://github.com/XTLS/RealiTLScanner/releases/latest/download/RealiTLScanner-linux-${SA}" -o /tmp/scanner && chmod +x /tmp/scanner && file /tmp/scanner | grep -q ELF || { echo "ERROR: scanner binary not valid for this architecture"; exit 1; }; MY_IP=$(curl -4 -s ifconfig.me); SUBNET=$(echo $MY_IP | sed "s/\[0-9]*\.0\/24/"); echo "Scanning subnet: $SUBNET"; timeout 120 /tmp/scanner --addr "$SUBNET" 2>&1 | head -80 ``` -------------------------------- ### Create VLESS Reality Inbound via API Source: https://context7.com/andyshaman/3x-ui-skill/llms.txt Authenticates to the 3x-ui panel API, generates necessary keys (X25519, UUID, short ID), and creates a VLESS Reality inbound on port 443. Includes a pre-check for port 443 conflicts. ```bash ssh myserver "ss -tlnp | grep ':443 '" ``` ```bash ssh myserver 'curl -sk -c /tmp/3x-cookie -b /tmp/3x-cookie \ -X POST "https://127.0.0.1:54321/panel/login" \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "username=x7kP2m&password=9vQr#Lx"' ``` ```bash ssh myserver "sudo /usr/local/x-ui/bin/xray-linux-* x25519" ``` ```bash ssh myserver "sudo /usr/local/x-ui/bin/xray-linux-* uuid" ``` ```bash ssh myserver "openssl rand -hex 8" ``` -------------------------------- ### Create Non-root User with Sudo Privileges Source: https://context7.com/andyshaman/3x-ui-skill/llms.txt Creates a new user account, sets a password, and adds the user to the sudo group, granting administrative privileges. ```bash useradd -m -s /bin/bash deploy echo "deploy:G7#kP2$xQm9vL" | chpasswd usermod -aG sudo deploy # Verify group membership groups deploy # Output: deploy : deploy sudo ``` -------------------------------- ### Add VLESS Reality Inbound via API Source: https://github.com/andyshaman/3x-ui-skill/blob/main/skill/SKILL.md Create a new VLESS Reality inbound configuration using the 3x-ui API. Ensure all placeholder values like {CLIENT_UUID}, {PRIVATE_KEY}, {PUBLIC_KEY}, {SHORT_ID}, {BEST_SNI}, and {web_base_path} are correctly substituted. ```bash ssh {nickname} 'PANEL_PORT={panel_port}; curl -sk -c /tmp/3x-cookie -b /tmp/3x-cookie -X POST "https://127.0.0.1:${PANEL_PORT}/{web_base_path}/panel/api/inbounds/add" -H "Content-Type: application/json" -d '"'"'{ "up": 0, "down": 0, "total": 0, "remark": "vless-reality", "enable": true, "expiryTime": 0, "listen": "", "port": 443, "protocol": "vless", "settings": "{\"clients\":[{\"id\":\"{CLIENT_UUID}\",\"flow\":\"xtls-rprx-vision\",\"email\":\"user1\",\"limitIp\":0,\"totalGB\":0,\"expiryTime\":0,\"enable\":true}],\"decryption\":\"none\",\"fallbacks\":[]}", "streamSettings": "{\"network\":\"tcp\",\"security\":\"reality\",\"externalProxy\":[],\"realitySettings\":{\"show\":false,\"xver\":0,\"dest\":\"{BEST_SNI}:443\",\"serverNames\":[\"{BEST_SNI}\"],\"privateKey\":\"{PRIVATE_KEY}\",\"minClient\":\"\",\"maxClient\":\"\",\"maxTimediff\":0,\"shortIds\":[\"{SHORT_ID}\"],\"settings\":{\"publicKey\":\"{PUBLIC_KEY}\",\"fingerprint\":\"chrome\",\"serverName\":\"\",\"spiderX\":\"/\"}},\"tcpSettings\":{\"acceptProxyProtocol\":false,\"header\":{\"type\":\"none\"}}}", "sniffing": "{\"enabled\":true,\"destOverride\":[\"http\",\"tls\",\"quic\",\"fakedns\"],\"metadataOnly\":false,\"routeOnly\":false}", "allocate": "{\"strategy\":\"always\",\"refresh\":5,\"concurrency\":3}" }'"'"'' ``` -------------------------------- ### Run Reality Scanner in Local Mode (/23 subnet) Source: https://github.com/andyshaman/3x-ui-skill/blob/main/skill/SKILL.md Executes RealiTLScanner on the VPS to scan a broader /23 subnet (512 IPs). This is used when the default /24 scan is insufficient. The command downloads the scanner, sets permissions, and runs the scan with an extended 180-second timeout. It's suitable for sparse subnets. ```bash MY_IP=$(curl -4 -s ifconfig.me); SUBNET=$(echo $MY_IP | sed "s/\[0-9]*\.0\/23/"); timeout 180 /tmp/scanner --addr "$SUBNET" 2>&1 | head -80 ``` -------------------------------- ### Create VLESS Reality Inbound via API Source: https://github.com/andyshaman/3x-ui-skill/blob/main/skill/SKILL.md This snippet demonstrates how to create a VLESS Reality inbound using the 3x-ui API. It includes steps for obtaining a session cookie, generating necessary keys, and making the API call to add the inbound configuration. ```APIDOC ## POST /panel/api/inbounds/add ### Description Creates a new VLESS Reality inbound configuration for the 3x-ui panel. ### Method POST ### Endpoint `https://127.0.0.1:{panel_port}/{web_base_path}/panel/api/inbounds/add` ### Parameters #### Request Body - **up** (integer) - Upload limit in bytes (0 for unlimited). - **down** (integer) - Download limit in bytes (0 for unlimited). - **total** (integer) - Total data limit in bytes (0 for unlimited). - **remark** (string) - A descriptive remark for the inbound. - **enable** (boolean) - Whether the inbound is enabled. - **expiryTime** (integer) - Expiry time in Unix timestamp (0 for no expiry). - **listen** (string) - Listen address (empty string for default). - **port** (integer) - The port for the inbound (e.g., 443). - **protocol** (string) - The protocol to use (e.g., "vless"). - **settings** (string) - JSON string containing client settings. Example: `{"clients":[{"id":"{CLIENT_UUID}","flow":"xtls-rprx-vision","email":"user1","limitIp":0,"totalGB":0,"expiryTime":0,"enable":true}],"decryption":"none","fallbacks":[]}` - **streamSettings** (string) - JSON string containing stream settings. Example: `{"network":"tcp","security":"reality","externalProxy":[],"realitySettings":{"show":false,"xver":0,"dest":"{BEST_SNI}:443","serverNames":["{BEST_SNI}"],"privateKey":"{PRIVATE_KEY}","minClient":"","maxClient":"","maxTimediff":0,"shortIds":["{SHORT_ID}"],"settings":{"publicKey":"{PUBLIC_KEY}","fingerprint":"chrome","serverName":"","spiderX":"/"}},"tcpSettings":{"acceptProxyProtocol":false,"header":{"type":"none"}}}` - **sniffing** (string) - JSON string for sniffing settings. Example: `{"enabled":true,"destOverride":["http","tls","quic","fakedns"],"metadataOnly":false,"routeOnly":false}` - **allocate** (string) - JSON string for allocation strategy. Example: `{"strategy":"always","refresh":5,"concurrency":3}` ### Request Example ```bash ssh {nickname} 'PANEL_PORT={panel_port}; curl -sk -c /tmp/3x-cookie -b /tmp/3x-cookie -X POST "https://127.0.0.1:${PANEL_PORT}/{web_base_path}/panel/api/inbounds/add" -H "Content-Type: application/json" -d "'"'"'{ "up": 0, "down": 0, "total": 0, "remark": "vless-reality", "enable": true, "expiryTime": 0, "listen": "", "port": 443, "protocol": "vless", "settings": "{\"clients\":[{\"id\":\"{CLIENT_UUID}\",\"flow\":\"xtls-rprx-vision\",\"email\":\"user1\",\"limitIp\":0,\"totalGB\":0,\"expiryTime\":0,\"enable\":true}],\"decryption\":\"none\",\"fallbacks\":[]}", "streamSettings": "{\"network\":\"tcp\",\"security\":\"reality\",\"externalProxy\":[],\"realitySettings\":{\"show\":false,\"xver\":0,\"dest\":\"{BEST_SNI}:443\",\"serverNames\":[\"{BEST_SNI}\"],\"privateKey\":\"{PRIVATE_KEY}\",\"minClient\":\"\",\"maxClient\":\"\",\"maxTimediff\":0,\"shortIds\":[\"{SHORT_ID}\"],\"settings\":{\"publicKey\":\"{PUBLIC_KEY}\",\"fingerprint\":\"chrome\",\"serverName\":\"\",\"spiderX\":\"/\"}},\"tcpSettings\":{\"acceptProxyProtocol\":false,\"header\":{\"type\":\"none\"}}}", "sniffing": "{\"enabled\":true,\"destOverride\":[\"http\",\"tls\",\"quic\",\"fakedns\"],\"metadataOnly\":false,\"routeOnly\":false}", "allocate": "{\"strategy\":\"always\",\"refresh\":5,\"concurrency\":3}" }'"'"'' ``` ### Response #### Success Response (200) - **msg** (string) - Success message. - **obj** (object) - The created inbound object. #### Response Example ```json { "msg": "add inbounds success", "obj": { "id": 1, "up": 0, "down": 0, "total": 0, "remark": "vless-reality", "enable": true, "expiryTime": 0, "listen": "", "port": 443, "protocol": "vless", "settings": "{\"clients\":[{\"id\":\"{CLIENT_UUID}\",\"flow\":\"xtls-rprx-vision\",\"email\":\"user1\",\"limitIp\":0,\"totalGB\":0,\"expiryTime\":0,\"enable\":true}],\"decryption\":\"none\",\"fallbacks\":[]}", "streamSettings": "{\"network\":\"tcp\",\"security\":\"reality\",\"externalProxy\":[],\"realitySettings\":{\"show\":false,\"xver\":0,\"dest\":\"{BEST_SNI}:443\",\"serverNames\":[\"{BEST_SNI}\"],\"privateKey\":\"{PRIVATE_KEY}\",\"minClient\":\"\",\"maxClient\":\"\",\"maxTimediff\":0,\"shortIds\":[\"{SHORT_ID}\"],\"settings\":{\"publicKey\":\"{PUBLIC_KEY}\",\"fingerprint\":\"chrome\",\"serverName\":\"\",\"spiderX\":\"/\"}},\"tcpSettings\":{\"acceptProxyProtocol\":false,\"header\":{\"type\":\"none\"}}}", "sniffing": "{\"enabled\":true,\"destOverride\":[\"http\",\"tls\",\"quic\",\"fakedns\"],\"metadataOnly\":false,\"routeOnly\":false}", "allocate": "{\"strategy\":\"always\",\"refresh\":5,\"concurrency\":3}" } } ``` -------------------------------- ### Generate Client Connection Link Source: https://github.com/andyshaman/3x-ui-skill/blob/main/skill/SKILL.md Fetches the client connection link from the 3x-ui API. This script parses the API response to find VLESS protocol configurations and constructs a shareable link, including REALITY settings. It requires SSH access to the server. ```bash ssh {nickname} 'PANEL_PORT={panel_port}; curl -sk -b /tmp/3x-cookie "https://127.0.0.1:${PANEL_PORT}/{web_base_path}/panel/api/inbounds/list" | python3 -c " import json,sys data = json.load(sys.stdin) for inb in data.get(\"obj\", []): if inb.get(\"protocol\") == \"vless\": settings = json.loads(inb[\"settings\"]) stream = json.loads(inb[\"streamSettings\"]) client = settings[\"clients\"][0] uuid = client[\"id\"] port = inb[\"port\"] security = stream.get(\"security\", \"none\") if security == \"reality\": rs = stream[\"realitySettings\"] sni = rs[\"serverNames\"][0] pbk = rs[\"settings\"][\"publicKey\"] sid = rs[\"shortIds\"][0] fp = rs[\"settings\"].get(\"fingerprint\", \"chrome\") flow = client.get(\"flow\", \"\") link = f\"vless://{uuid}@$(curl -4 -s ifconfig.me):{port}?type=tcp&security=reality&pbk={pbk}&fp={fp}&sni={sni}&sid={sid}&spx=%2F&flow={flow}#vless-reality\" print(link) break "' ``` -------------------------------- ### Connect to Server as Root Source: https://context7.com/andyshaman/3x-ui-skill/llms.txt Initial SSH connection to the server as the root user. May require a password change on first login. ```bash ssh root@203.0.113.42 # If provider forces password change on first login: # Enter current password → set new temporary password → reconnect ssh root@203.0.113.42 # reconnect with new password ``` -------------------------------- ### Apply SSL Certificate to x-ui Panel Source: https://github.com/andyshaman/3x-ui-skill/blob/main/skill/references/vless-tls.md Configure the x-ui panel to use the obtained SSL certificate for HTTPS access. Restart the panel to apply changes. ```bash ssh {nickname} "sudo /usr/local/x-ui/x-ui cert -webCert /root/cert/{domain}/fullchain.pem -webCertKey /root/cert/{domain}/privkey.pem" ``` ```bash ssh {nickname} "sudo x-ui restart" ``` -------------------------------- ### Obtain SSL Certificate using x-ui Source: https://github.com/andyshaman/3x-ui-skill/blob/main/skill/references/vless-tls.md Use the x-ui built-in certificate management to obtain an SSL certificate for your domain. This process is interactive. ```bash ssh {nickname} "sudo x-ui cert" ``` -------------------------------- ### Configure Nginx Stub Server Source: https://github.com/andyshaman/3x-ui-skill/blob/main/skill/references/fallback-nginx.md Sets up Nginx to listen on localhost:8081 and serve static files from /var/www/html. This Nginx instance acts as the fallback server. ```bash ssh {nickname} "sudo tee /etc/nginx/sites-available/stub << 'NGINX_EOF' server { listen 127.0.0.1:8081; server_name _; root /var/www/html; index index.html; location / { try_files $uri $uri/ =404; } } NGINX_EOF sudo ln -sf /etc/nginx/sites-available/stub /etc/nginx/sites-enabled/stub && sudo rm -f /etc/nginx/sites-enabled/default && sudo nginx -t && sudo systemctl reload nginx" ``` -------------------------------- ### Debug SSH Permissions Source: https://github.com/andyshaman/3x-ui-skill/blob/main/skill/SKILL.md If the new user's sudo access fails, use these commands to inspect SSH directory permissions and the authorized_keys file on the server. ```bash # Check on server as root: ls -la /home/{username}/.ssh/ cat /home/{username}/.ssh/authorized_keys # Fix ownership: chown -R {username}:{username} /home/{username}/.ssh ``` -------------------------------- ### Generate Reality Keys (x25519) Source: https://github.com/andyshaman/3x-ui-skill/blob/main/skill/SKILL.md Generate the necessary private and public keys for Reality configuration using the xray binary. Note that 'Password' output from xray is the public key. ```bash ssh {nickname} "sudo /usr/local/x-ui/bin/xray-linux-* x25519" ``` -------------------------------- ### Create Non-Root User and Set Password Source: https://github.com/andyshaman/3x-ui-skill/blob/main/skill/SKILL.md Creates a new user with a bash shell, sets a strong temporary password, and adds them to the sudo group. Remember to save the generated password for the user. ```bash useradd -m -s /bin/bash {username} echo "{username}:{GENERATE_STRONG_PASSWORD}" | chpasswd usermod -aG sudo {username} ``` -------------------------------- ### Create VLESS Reality Inbound Source: https://context7.com/andyshaman/3x-ui-skill/llms.txt Adds a VLESS Reality inbound configuration to the panel API. Ensure the panel is running and accessible. ```bash ssh myserver 'curl -sk -c /tmp/3x-cookie -b /tmp/3x-cookie \ -X POST "https://127.0.0.1:54321/panel/api/inbounds/add" \ -H "Content-Type: application/json" \ -d '"'"'{ "remark": "vless-reality", "enable": true, "port": 443, "protocol": "vless", "settings": "{\"clients\":[{\"id\":\"550e8400-e29b-41d4-a716-446655440000\",\"flow\":\"xtls-rprx-vision\",\"email\":\"user1\",\"limitIp\":0,\"totalGB\":0,\"expiryTime\":0,\"enable\":true}],\"decryption\":\"none\",\"fallbacks\":[]}", "streamSettings": "{\"network\":\"tcp\",\"security\":\"reality\",\"realitySettings\":{\"dest\":\"shop.finn-auto.fi:443\",\"serverNames\":[\"shop.finn-auto.fi\"],\"privateKey\":\"eKmFk3...\",\"shortIds\":[\"a3f8c21d9e047b5c\"],\"settings\":{\"publicKey\":\"bNpQ7r...\",\"fingerprint\":\"chrome\",\"spiderX\":\"/\"}}}", "sniffing": "{\"enabled\":true,\"destOverride\":[\"http\",\"tls\",\"quic\",\"fakedns\"]}" }'"'"'' ``` -------------------------------- ### Configure Local SSH Shortcut Source: https://context7.com/andyshaman/3x-ui-skill/llms.txt Appends an entry to the local SSH config file, allowing connection to the server using a simple alias 'myserver'. ```bash cat >> ~/.ssh/config << 'EOF' Host myserver HostName 203.0.113.42 User deploy IdentityFile ~/.ssh/myserver_key IdentitiesOnly yes EOF ``` -------------------------------- ### Configure Local SSH Client Config Source: https://github.com/andyshaman/3x-ui-skill/blob/main/skill/SKILL.md Adds an entry to the local SSH configuration file to create a shortcut for connecting to the server. This simplifies future connections by using a nickname instead of IP and username. ```bash cat >> ~/.ssh/config << 'EOF' Host {nickname} HostName {SERVER_IP} User {username} IdentityFile ~/.ssh/{nickname}_key IdentitiesOnly yes EOF ``` -------------------------------- ### Configure Nginx for Localhost Only Source: https://context7.com/andyshaman/3x-ui-skill/llms.txt Sets up Nginx to listen on localhost:8081, serving static files from /var/www/html. This configuration is useful for fallback pages. ```bash ssh myserver "sudo tee /etc/nginx/sites-available/stub << 'EOF' server { listen 127.0.0.1:8081; server_name _; root /var/www/html; index index.html; location / { try_files $uri $uri/ =404; } } EOF sudo ln -sf /etc/nginx/sites-available/stub /etc/nginx/sites-enabled/stub sudo rm -f /etc/nginx/sites-enabled/default sudo nginx -t && sudo systemctl reload nginx" ``` -------------------------------- ### Troubleshoot SSH Permission Denied Source: https://github.com/andyshaman/3x-ui-skill/blob/main/README.md If you encounter 'Permission denied (publickey)', check and correct SSH key permissions on your client machine. ```bash chmod 700 ~/.ssh && chmod 600 ~/.ssh/* ``` -------------------------------- ### Deploy Stub HTML Page Source: https://context7.com/andyshaman/3x-ui-skill/llms.txt Deploys a simple HTML file to serve as a stub page, typically for fallback or placeholder content. ```bash ssh myserver 'sudo tee /var/www/html/index.html << "'"'"'HTML_EOF'"'"'"'" Cloud Storage

Cloud Storage

Sign in to access your files

HTML_EOF' ``` -------------------------------- ### Login to x-ui API Source: https://github.com/andyshaman/3x-ui-skill/blob/main/skill/references/vless-tls.md Authenticate with the x-ui panel's API using provided credentials to perform subsequent API operations. Cookies are stored in /tmp/3x-cookie. ```bash ssh {nickname} 'PANEL_PORT={panel_port}; curl -sk -c /tmp/3x-cookie -b /tmp/3x-cookie -X POST "https://127.0.0.1:${PANEL_PORT}/{web_base_path}/login" -H "Content-Type: application/x-www-form-urlencoded" -d "username={panel_username}&password={panel_password}"' ``` -------------------------------- ### Create VLESS TLS Inbound Source: https://context7.com/andyshaman/3x-ui-skill/llms.txt Adds a VLESS TLS inbound configuration to the panel API using specified certificate files. Ensure the certificate files exist. ```bash ssh myserver 'curl -sk -c /tmp/3x-cookie -b /tmp/3x-cookie \ -X POST "https://127.0.0.1:54321/panel/api/inbounds/add" \ -H "Content-Type: application/json" \ -d '"'"'{ "remark": "vless-tls", "enable": true, "port": 443, "protocol": "vless", "settings": "{\"clients\":[{\"id\":\"550e8400-e29b-41d4-a716-446655440000\",\"flow\":\"xtls-rprx-vision\",\"email\":\"user1\",\"limitIp\":0,\"totalGB\":0,\"expiryTime\":0,\"enable\":true}],\"decryption\":\"none\",\"fallbacks\":[]}", "streamSettings": "{\"network\":\"tcp\",\"security\":\"tls\",\"tlsSettings\":{\"serverName\":\"vpn.example.com\",\"minVersion\":\"1.2\",\"maxVersion\":\"1.3\",\"certificates\":[{\"certificateFile\":\"/root/cert/vpn.example.com/fullchain.pem\",\"keyFile\":\"/root/cert/vpn.example.com/privkey.pem\",\"ocspStapling\":3600}],\"alpn\":[\"h2\",\"http/1.1\"]}}", "sniffing": "{\"enabled\":true,\"destOverride\":[\"http\",\"tls\",\"quic\",\"fakedns\"]}" }'"'"'' ``` -------------------------------- ### Troubleshoot Panel Not Accessible via SSH Tunnel Source: https://github.com/andyshaman/3x-ui-skill/blob/main/README.md If the 3x-ui panel is not accessible in your browser, use an SSH tunnel to forward the panel's port. ```bash ssh -L 2053:localhost:2053 user@server ``` -------------------------------- ### Extract VLESS Connection Link Source: https://context7.com/andyshaman/3x-ui-skill/llms.txt Fetches the VLESS connection URL from the panel API and formats it as a vless:// link. Requires jq for JSON parsing. ```bash ssh myserver 'curl -sk -b /tmp/3x-cookie \ "https://127.0.0.1:54321/panel/api/inbounds/list" | python3 -c " import json, sys data = json.load(sys.stdin) for inb in data.get(\"obj\", []): if inb.get(\"protocol\") == \"vless\": settings = json.loads(inb[\"settings\"]) stream = json.loads(inb[\"streamSettings\"]) client = settings[\"clients\"][0] uuid = client[\"id\"] port = inb[\"port\"] if stream.get(\"security\") == \"reality\": rs = stream[\"realitySettings\"] sni = rs[\"serverNames\"][0] pbk = rs[\"settings\"][\"publicKey\"] sid = rs[\"shortIds\"][0] fp = rs[\"settings\"].get(\"fingerprint\", \"chrome\") flow = client.get(\"flow\", \"\")$(curl -4 -s ifconfig.me):{port}?type=tcp&security=reality&pbk={pbk}&fp={fp}&sni={sni}&sid={sid}&spx=%2F&flow={flow}#vless-reality" print(link) break "' ``` ```bash ssh myserver "echo 'vless://...' > ~/vpn-link.txt" ``` ```bash ssh myserver "rm -f /tmp/3x-cookie" ``` -------------------------------- ### Create VLESS TLS Inbound via API Source: https://github.com/andyshaman/3x-ui-skill/blob/main/skill/references/vless-tls.md Add a VLESS TLS inbound configuration to the x-ui panel using its API. This requires a valid client UUID and domain, and configures port 443 with TLS settings. ```bash ssh {nickname} 'PANEL_PORT={panel_port}; curl -sk -c /tmp/3x-cookie -b /tmp/3x-cookie -X POST "https://127.0.0.1:${PANEL_PORT}/{web_base_path}/panel/api/inbounds/add" -H "Content-Type: application/json" -d '"'"'{ "up": 0, "down": 0, "total": 0, "remark": "vless-tls", "enable": true, "expiryTime": 0, "listen": "", "port": 443, "protocol": "vless", "settings": "{\"clients\":[{\"id\":\"{CLIENT_UUID}\",\"flow\":\"xtls-rprx-vision\",\"email\":\"user1\",\"limitIp\":0,\"totalGB\":0,\"expiryTime\":0,\"enable\":true}],\"decryption\":\"none\",\"fallbacks\":[]}", "streamSettings": "{\"network\":\"tcp\",\"security\":\"tls\",\"externalProxy\":[],\"tlsSettings\":{\"serverName\":\"{domain}\",\"minVersion\":\"1.2\",\"maxVersion\":\"1.3\",\"cipherSuites\":\"\",\"rejectUnknownSni\":false,\"disableSystemRoot\":false,\"enableSessionResumption\":false,\"certificates\":[{\"certificateFile\":\"/root/cert/{domain}/fullchain.pem\",\"keyFile\":\"/root/cert/{domain}/privkey.pem\",\"ocspStapling\":3600,\"oneTimeLoading\":false,\"usage\":\"encipherment\",\"buildChain\":false}],\"alpn\":[\"h2\",\"http/1.1\"]},\"tcpSettings\":{\"acceptProxyProtocol\":false,\"header\":{\"type\":\"none\"}}}", "sniffing": "{\"enabled\":true,\"destOverride\":[\"http\",\"tls\",\"quic\",\"fakedns\"],\"metadataOnly\":false,\"routeOnly\":false}", "allocate": "{\"strategy\":\"always\",\"refresh\":5,\"concurrency\":3}" }'"'"'' ``` -------------------------------- ### Run Reality Scanner in Remote Mode (/24 subnet) Source: https://github.com/andyshaman/3x-ui-skill/blob/main/skill/SKILL.md Executes the RealiTLScanner on a remote server via SSH to scan the local /24 subnet. It automatically detects the architecture, downloads the appropriate scanner binary, and initiates the scan, outputting the first 80 lines of results. Ensure the SSH user has necessary permissions. ```bash ssh {nickname} 'ARCH=$(dpkg --print-architecture); case "$ARCH" in amd64) SA="64";; arm64|aarch64) SA="arm64-v8a";; *) SA="$ARCH";; esac && curl -sL "https://github.com/XTLS/RealiTLScanner/releases/latest/download/RealiTLScanner-linux-${SA}" -o /tmp/scanner && chmod +x /tmp/scanner && file /tmp/scanner | grep -q ELF || { echo "ERROR: scanner binary not valid for this architecture"; exit 1; }; MY_IP=$(curl -4 -s ifconfig.me); SUBNET=$(echo $MY_IP | sed "s/\[0-9]*\.0\/24/"); echo "Scanning subnet: $SUBNET"; timeout 120 /tmp/scanner --addr "$SUBNET" 2>&1 | head -80' ``` -------------------------------- ### Check Port 443 Availability Source: https://github.com/andyshaman/3x-ui-skill/blob/main/skill/SKILL.md Verify if port 443 is already in use before configuring the VLESS inbound. If it is, stop and disable the occupying service. ```bash ssh {nickname} "ss -tlnp | grep ':443 '" ``` -------------------------------- ### Configure Kernel Security Settings Source: https://github.com/andyshaman/3x-ui-skill/blob/main/skill/SKILL.md Applies various network security enhancements by configuring kernel parameters. These settings help protect against common network attacks. ```bash sudo tee /etc/sysctl.d/99-security.conf << 'EOF' net.ipv4.conf.all.rp_filter = 1 net.ipv4.conf.default.rp_filter = 1 net.ipv4.conf.all.accept_redirects = 0 net.ipv4.conf.default.accept_redirects = 0 net.ipv4.conf.all.send_redirects = 0 net.ipv4.conf.default.send_redirects = 0 net.ipv4.tcp_syncookies = 1 net.ipv4.conf.all.log_martians = 1 net.ipv4.conf.default.log_martians = 1 net.ipv4.icmp_echo_ignore_broadcasts = 1 net.ipv4.conf.all.accept_source_route = 0 net.ipv4.conf.default.accept_source_route = 0 EOF sudo sysctl -p /etc/sysctl.d/99-security.conf ``` -------------------------------- ### Verify Connection Status Source: https://github.com/andyshaman/3x-ui-skill/blob/main/skill/SKILL.md Checks the status of the x-ui service and lists active network connections on ports 443 and the specified panel port. This is used to verify that the VPN connection is active and the server is listening on the correct ports. ```bash ssh {nickname} "sudo x-ui status && ss -tlnp | grep -E '443|{panel_port}'" ``` -------------------------------- ### Troubleshoot SSH Host Key Verification Failed Source: https://github.com/andyshaman/3x-ui-skill/blob/main/README.md To resolve 'Host key verification failed', remove the old host key entry for the server IP from your known_hosts file. ```bash ssh-keygen -R ``` -------------------------------- ### Verify SSH Key Access Source: https://context7.com/andyshaman/3x-ui-skill/llms.txt Confirms that SSH key-based authentication is working correctly before proceeding with further security configurations. ```bash ssh myserver "echo 'SSH key access OK'" ``` -------------------------------- ### Verify DNS Resolution Source: https://github.com/andyshaman/3x-ui-skill/blob/main/skill/references/vless-tls.md Check if the domain's A-record points to the server's IP address. This is crucial for SSL certificate issuance. ```bash nslookup {domain} ``` ```bash ssh {nickname} "sudo apt install -y dnsutils > /dev/null 2>&1; nslookup {domain}" ``` -------------------------------- ### Save Connection Link to File Source: https://github.com/andyshaman/3x-ui-skill/blob/main/skill/SKILL.md Saves the generated VLESS connection link to a file named 'vpn-link.txt' in the user's home directory on the remote server. This provides an easy way to access the link later. ```bash ssh {nickname} "echo '{VLESS_LINK}' > ~/vpn-link.txt" ``` -------------------------------- ### Change Panel Credentials Source: https://github.com/andyshaman/3x-ui-skill/blob/main/skill/references/vless-tls.md Update the x-ui panel's username and password for enhanced security. Restart the panel after changing credentials. ```bash ssh {nickname} "sudo x-ui setting -username {new_username} -password {new_password}" ``` ```bash ssh {nickname} "sudo x-ui restart" ``` -------------------------------- ### Access Panel via SSH Tunnel Source: https://github.com/andyshaman/3x-ui-skill/blob/main/skill/references/vless-tls.md Establish an SSH tunnel to securely access the x-ui panel over HTTPS. Note that the browser will show a certificate mismatch warning, which is expected. ```bash ssh -L {panel_port}:127.0.0.1:{panel_port} {nickname} ``` -------------------------------- ### Configure VLESS Inbound Fallback Source: https://github.com/andyshaman/3x-ui-skill/blob/main/skill/references/fallback-nginx.md Adds a fallback destination to the VLESS inbound settings, directing traffic to the Nginx stub server on 127.0.0.1:8081 when direct connections fail. ```json "fallbacks": [{"dest": "127.0.0.1:8081"}] ``` -------------------------------- ### Reset 3x-ui Panel Password Source: https://github.com/andyshaman/3x-ui-skill/blob/main/README.md If you forget the 3x-ui panel password, you can reset it directly on the server using this command. ```bash sudo x-ui setting -reset ``` -------------------------------- ### Run Reality Scanner in Remote Mode (/23 subnet) Source: https://github.com/andyshaman/3x-ui-skill/blob/main/skill/SKILL.md Scans a wider /23 subnet (512 IPs) using RealiTLScanner via SSH. This is a fallback option when the /24 scan yields no results or times out, common with providers like OVH. The timeout is increased to 180 seconds to accommodate the larger scan range. ```bash ssh {nickname} 'MY_IP=$(curl -4 -s ifconfig.me); SUBNET=$(echo $MY_IP | sed "s/\[0-9]*\.0\/23/"); timeout 180 /tmp/scanner --addr "$SUBNET" 2>&1 | head -80' ``` -------------------------------- ### Verify SSH Lockdown Source: https://github.com/andyshaman/3x-ui-skill/blob/main/skill/SKILL.md Verifies that SSH lockdown configurations (disabling root login and password authentication) have been applied correctly and that the fail2ban service is running. It also confirms that SSH key access is still functional. ```bash ssh {nickname} "grep -E 'PermitRootLogin|PasswordAuthentication' /etc/ssh/sshd_config && sudo systemctl status fail2ban --no-pager -l && echo 'Lockdown OK'" ```