Xây dựng VPN tàng hình với Xray-core và XTLS-Reality trên Linux: Traffic trông như HTTPS thông thường

Network tutorial - IT technology blog
Network tutorial - IT technology blog

Tại sao VPN thông thường hay bị block?

Mình quản lý network cho văn phòng 50 người và một datacenter nhỏ, nên chuyện VPN bị chặn không còn xa lạ. OpenVPN, WireGuard — cả hai đều tốt về bảo mật, nhưng có điểm yếu chung: traffic của chúng có “fingerprint” đặc trưng. Deep Packet Inspection (DPI) chỉ cần vài giây là nhận ra và block ngay.

Xray-core với XTLS-Reality tiếp cận theo hướng khác hẳn. Thay vì đóng gói VPN rồi gửi đi, nó làm traffic trông hệt như HTTPS bình thường đến một website có tiếng. Firewall nhìn vào thấy TLS handshake hợp lệ với tên miền quen thuộc — không có gì khả nghi. Kỹ thuật này đôi khi gọi là “traffic camouflage”.

XTLS-Reality khác gì so với VPN thông thường?

  • OpenVPN/WireGuard: Tạo tunnel riêng biệt với header đặc trưng, dễ phát hiện qua DPI
  • XTLS-Reality: “Mượn” TLS certificate của website thật (ví dụ: www.microsoft.com) — traffic trông y chang HTTPS đến domain đó
  • Không cần domain riêng, không cần SSL certificate — server vẫn hoạt động bình thường
  • Dùng giao thức VLESS — nhẹ hơn VMess, không có overhead thừa

Chuẩn bị trước khi bắt đầu

Trước khi bắt đầu, chuẩn bị mấy thứ này:

  • 1 VPS Linux (Ubuntu 20.04+ hoặc Debian 11+) nằm ngoài vùng mạng bị chặn
  • SSH access vào server với quyền root hoặc sudo
  • Port 443 chưa bị chiếm bởi nginx hay apache

Hướng dẫn này chạy trên Ubuntu 22.04. Port 443 đang bận? Đổi Xray sang 8443 hoặc setup nginx làm reverse proxy — mình nói kỹ hơn ở phần xử lý lỗi cuối bài.

Cài đặt Xray-core trên Linux Server

Bước 1: Cài đặt Xray-core

Xray-core có script cài đặt chính thức — một lệnh là xong:

# Cài đặt Xray-core bản mới nhất
bash -c "$(curl -L https://github.com/XTLS/Xray-install/raw/main/install-release.sh)" @ install

# Kiểm tra version
xray version

Installer tự xử lý phần còn lại:

  • Tải binary về /usr/local/bin/xray
  • Tạo systemd service xray.service
  • Tạo thư mục config tại /usr/local/etc/xray/

Bước 2: Tạo UUID và keypair cho XTLS-Reality

Điểm khác biệt của Reality là dùng keypair X25519 thay vì SSL certificate thông thường. Không cần đăng ký domain riêng, không cần Let’s Encrypt — nhẹ đầu hơn nhiều so với cách truyền thống.

# Tạo UUID (dùng làm "password" cho client)
xray uuid
# Output ví dụ: a3f2b1c4-d5e6-7890-abcd-ef1234567890

# Tạo keypair cho Reality
xray x25519
# Output:
# Private key: aBcDeFgH...
# Public key:  XyZwVuTs...

Lưu cả ba ngay bây giờ: UUID, Private key, và Public key. Private key đặc biệt nhạy cảm — ai có được là có thể giả mạo server của bạn.

Bước 3: Tạo Short ID

# Tạo short ID ngẫu nhiên (8 bytes hex)
openssl rand -hex 8
# Ví dụ: a1b2c3d4e5f6a7b8

Cấu hình Xray-core với XTLS-Reality

Cấu hình phía server

Tạo file /usr/local/etc/xray/config.json:

{
  "log": {
    "loglevel": "warning",
    "access": "/var/log/xray/access.log",
    "error": "/var/log/xray/error.log"
  },
  "inbounds": [
    {
      "listen": "0.0.0.0",
      "port": 443,
      "protocol": "vless",
      "settings": {
        "clients": [
          {
            "id": "THAY-BANG-UUID-CUA-BAN",
            "flow": "xtls-rprx-vision"
          }
        ],
        "decryption": "none"
      },
      "streamSettings": {
        "network": "tcp",
        "security": "reality",
        "realitySettings": {
          "show": false,
          "dest": "www.microsoft.com:443",
          "xver": 0,
          "serverNames": [
            "www.microsoft.com"
          ],
          "privateKey": "THAY-BANG-PRIVATE-KEY",
          "shortIds": [
            "THAY-BANG-SHORT-ID"
          ]
        }
      },
      "sniffing": {
        "enabled": true,
        "destOverride": ["http", "tls"]
      }
    }
  ],
  "outbounds": [
    {
      "protocol": "freedom",
      "tag": "direct"
    },
    {
      "protocol": "blackhole",
      "tag": "block"
    }
  ]
}

Ba tham số quan trọng nhất cần hiểu:

  • dest: "www.microsoft.com:443" — traffic trông như đang kết nối đến Microsoft. Thay được bằng bất kỳ domain lớn nào hỗ trợ TLS 1.3
  • flow: "xtls-rprx-vision" — mode XTLS mới nhất, bypass DPI hiệu quả nhất hiện tại
  • privateKey — điền Private key (không phải Public key!) từ lệnh xray x25519

Khởi động service

# Tạo thư mục log
mkdir -p /var/log/xray
chown nobody:nogroup /var/log/xray

# Validate config trước khi khởi động
xray run -test -config /usr/local/etc/xray/config.json

# Khởi động và bật autostart
systemctl start xray
systemctl enable xray

# Xem trạng thái
systemctl status xray
# Mở port trên UFW (Ubuntu)
ufw allow 443/tcp
ufw reload

# Nếu dùng iptables
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
iptables-save > /etc/iptables/rules.v4

Cấu hình phía Client

Import bằng connection string (cách nhanh nhất)

Cách nhanh nhất là tạo URI rồi paste thẳng vào app. v2rayN (Windows), v2rayNG (Android), Shadowrocket (iOS) đều đọc được format này:

vless://UUID@SERVER-IP:443?encryption=none&flow=xtls-rprx-vision&security=reality&sni=www.microsoft.com&fp=chrome&pbk=PUBLIC-KEY&sid=SHORT-ID&type=tcp#MyXrayVPN

Thay từng phần tương ứng:

  • UUID → UUID tạo ở bước 2
  • SERVER-IP → IP của VPS
  • PUBLIC-KEY → Public key (không phải Private key)
  • SHORT-ID → Short ID từ bước 3

Cấu hình thủ công trên Linux client

Trên Linux client, cài Xray theo cách tương tự server rồi tạo config riêng. Xray local sẽ chạy như SOCKS5 proxy trên cổng 1080, các app khác route traffic qua đó:

{
  "inbounds": [
    {
      "port": 1080,
      "listen": "127.0.0.1",
      "protocol": "socks",
      "settings": { "udp": true }
    }
  ],
  "outbounds": [
    {
      "protocol": "vless",
      "settings": {
        "vnext": [
          {
            "address": "SERVER-IP",
            "port": 443,
            "users": [
              {
                "id": "UUID",
                "flow": "xtls-rprx-vision",
                "encryption": "none"
              }
            ]
          }
        ]
      },
      "streamSettings": {
        "network": "tcp",
        "security": "reality",
        "realitySettings": {
          "serverName": "www.microsoft.com",
          "fingerprint": "chrome",
          "show": false,
          "publicKey": "PUBLIC-KEY",
          "shortId": "SHORT-ID",
          "spiderX": "/"
        }
      }
    }
  ]
}
# Chạy Xray client
xray run -config client-config.json

# Test kết nối qua SOCKS5 proxy
curl --proxy socks5h://127.0.0.1:1080 https://api.ipify.org
# Output sẽ là IP của VPS — xác nhận traffic đang đi qua proxy

Kiểm tra và Monitoring

Xem log và trạng thái server

# Xem log realtime
journalctl -u xray -f

# Xem access log
tail -f /var/log/xray/access.log

# Xem error log
tail -f /var/log/xray/error.log

# Kiểm tra port đang lắng nghe
ss -tlnp | grep :443

Script monitoring nhanh

Script này mình dùng để check Xray mỗi sáng — 2 giây là biết server ổn hay không:

#!/bin/bash
# Lưu vào /usr/local/bin/xray-check.sh rồi chmod +x

echo "=== Xray Service ==="
systemctl is-active xray && echo "Status: RUNNING" || echo "Status: STOPPED"

echo ""
echo "=== Active Connections ==="
ss -tnp | grep xray | wc -l | xargs -I{} echo "Connections: {}"

echo ""
echo "=== Last 5 Errors ==="
tail -5 /var/log/xray/error.log 2>/dev/null || echo "No errors"

echo ""
echo "=== Memory Usage ==="
ps aux | grep '[x]ray' | awk '{print "CPU: "$3"% | MEM: "$4"% | PID: "$2}'
chmod +x /usr/local/bin/xray-check.sh
xray-check.sh

Update Xray-core khi có phiên bản mới

# Chạy lại installer để update
bash -c "$(curl -L https://github.com/XTLS/Xray-install/raw/main/install-release.sh)" @ install

# Xác nhận version mới
xray version

# Restart service
systemctl restart xray

Lỗi thường gặp và cách xử lý

Lỗi “failed to handler mux client connection”: Client và server dùng flow khác nhau. Kiểm tra cả hai đều dùng xtls-rprx-vision.

Port 443 bị chiếm bởi nginx/apache: Đổi Xray sang port 8443 trong config, hoặc cấu hình nginx stream proxy chuyển tiếp traffic đến Xray dựa trên SNI.

Traffic vẫn bị block: Thử đổi dest sang domain khác có TLS 1.3 mạnh — addons.mozilla.org:443 hoặc www.cloudflare.com:443 thường hoạt động tốt. Nhớ cập nhật serverNames cho khớp.

Thêm user mới: Tạo UUID mới (xray uuid), thêm vào mảng clients trong config server, rồi systemctl reload xray là xong. Mỗi người một UUID riêng — quản lý rất gọn.

Share: