# Xray-Core VLESS Proxy Tutorial

# Xray-Core VLESS Proxy Tutorial

Source: https://github.com/wpdevelopment11/xray-tutorial

## Introduction

This tutorial demonstrates setting up an Xray-core VLESS proxy server to access blocked websites and applications. The guide was originally published on community.hetzner.com but has been republished here.

Xray is a proxy with support for multiple network protocols. It's commonly used to penetrate firewalls to access blocked websites and apps. Xray is a Chinese-developed fork of V2Ray with extensive configuration options.

**Prerequisites**: A user with sudo privileges

## Step 1: Installing Xray-Core on the Server

Connect via SSH and install the `unzip` package, then download and install Xray:

```bash
cd ~ \
&& curl -fLo xray.zip "https://github.com/XTLS/Xray-core/releases/latest/download/Xray-linux-$(uname -m | sed -e s/x86_64/64/ -e s/aarch64/arm64-v8a/).zip" \
&& sudo unzip -d /usr/local/xray xray.zip \
&& rm xray.zip
```

Add Xray to PATH:

```bash
export PATH=$PATH:/usr/local/xray
```

Add this line to `~/.profile` to persist between logins.

Verify installation:

```bash
xray version
```

To update, run `sudo rm -r /usr/local/xray` and repeat Step 1.

## Step 2: Server Configuration

### Create Configuration Directory

```bash
sudo mkdir -p /usr/local/etc/xray
```

### Basic Configuration Structure

```json
{
  "log": {
    "loglevel": "warning"
  },
  "inbounds": [
    {
      "port": 443,
      "protocol": "vless",
      "settings": {
        "clients": [],
        "decryption": "none"
      },
      "streamSettings": {
        "network": "tcp",
        "security": "tls",
        "tlsSettings": {
          "certificates": []
        }
      }
    }
  ],
  "outbounds": [
    {
      "protocol": "freedom"
    }
  ]
}
```

Key points:
- Port 443 (HTTPS) is a privileged port requiring additional configuration
- `inbounds` define accepted protocols (VLESS here)
- `outbounds` define proxying behavior ("freedom" routes to appropriate destination)
- Clients must be added to `inbounds[].settings.clients`
- `streamSettings` specify data transmission over the wire

### Adding Clients

Generate a UUID:

```bash
xray uuid
```

Client object structure:

```json
{
  "id": "<User UUID>",
  "email": "<Name or email>"
}
```

Add this to `inbounds[].settings.clients` array.

### Certificate Configuration

#### Option 1: Self-Signed Certificate

```bash
sudo /usr/local/xray/xray tls cert -file /usr/local/etc/xray/my > /dev/null
```

Creates:
- `/usr/local/etc/xray/my_cert.pem` (self-signed certificate)
- `/usr/local/etc/xray/my_key.pem` (private key)

Add to configuration:

```json
{
  "certificateFile": "/usr/local/etc/xray/my_cert.pem",
  "keyFile": "/usr/local/etc/xray/my_key.pem"
}
```

#### Option 2: Let's Encrypt Certificate

Prerequisites:
- Domain with A/AAAA DNS records pointing to server
- Certbot installed via Snap (preferred) or package manager

```bash
sudo certbot certonly --standalone --agree-tos -m user@example.com -d example.com
```

Certificate files:
- `/etc/letsencrypt/live/example.com/fullchain.pem`
- `/etc/letsencrypt/live/example.com/privkey.pem`

Note: Xray supports hot reloading of certificates.

For non-root access:

```bash
mydomain=example.com
sudo chmod a+rx /etc/letsencrypt/{live,archive}
sudo chgrp $USER "/etc/letsencrypt/live/$mydomain/privkey.pem"
sudo chmod g+r "/etc/letsencrypt/live/$mydomain/privkey.pem"
```

Add to configuration:

```json
{
  "certificateFile": "/etc/letsencrypt/live/example.com/fullchain.pem",
  "keyFile": "/etc/letsencrypt/live/example.com/privkey.pem"
}
```

### Complete Server Configuration Example

```json
{
  "log": {
    "loglevel": "warning"
  },
  "inbounds": [
    {
      "port": 443,
      "protocol": "vless",
      "settings": {
        "clients": [
          {
            "id": "4d6e0338-f67a-4187-bca3-902e232466bc",
            "email": "John"
          }
        ],
        "decryption": "none"
      },
      "streamSettings": {
        "network": "tcp",
        "security": "tls",
        "tlsSettings": {
          "certificates": [
            {
              "certificateFile": "/usr/local/etc/xray/my_cert.pem",
              "keyFile": "/usr/local/etc/xray/my_key.pem"
            }
          ]
        }
      }
    }
  ],
  "outbounds": [
    {
      "protocol": "freedom"
    }
  ]
}
```

### Testing and Running

Test configuration:

```bash
xray run -test -c /usr/local/etc/xray/config.json
```

For privileged port 443:

```bash
sudo setcap cap_net_bind_service=+ep /usr/local/xray/xray
```

Run in foreground for testing:

```bash
xray run -c /usr/local/etc/xray/config.json
```

### Systemd Service Setup

```bash
echo "[Unit]
Description=xray-core
After=network-online.target
Wants=network-online.target

[Service]
User=$USER
Type=exec
ExecStart=/usr/local/xray/xray -c /usr/local/etc/xray/config.json
Restart=on-failure

[Install]
WantedBy=multi-user.target" | sudo tee /etc/systemd/system/xray.service
```

Start and enable:

```bash
sudo systemctl start xray && sudo systemctl enable xray
```

## Step 3: Client Configuration

### Step 3.1: Android Client

Install v2rayNG from Google Play Store.

Configuration:
1. Tap `+` to add new configuration
2. Select "Type manually[VLESS]"
3. Fill fields:
   - **address**: Domain or IP (use IP for self-signed certificates)
   - **id**: Client UUID from server configuration
4. Open TLS menu and select "tls"
5. For self-signed certificates, set **allowInsecure** to "true"
6. Save and tap play button to connect

### Step 3.2: Windows Client

Download latest Xray release for Windows:

```powershell
cd ~
curl.exe -fLo xray.zip https://github.com/XTLS/Xray-core/releases/latest/download/Xray-windows-64.zip
Expand-Archive xray.zip xray
rm xray.zip
cd xray
pwd
```

Add directory to system PATH.

#### SOCKS Proxy

Client configuration:

```json
{
  "log": {
    "loglevel": "warning"
  },
  "inbounds": [
    {
      "listen": "127.0.0.1",
      "port": "1080",
      "protocol": "socks",
      "settings": {
        "udp": true,
        "ip": "127.0.0.1"
      }
    }
  ],
  "outbounds": [
    {
      "protocol": "vless",
      "settings": {
        "vnext": [
          {
            "address": "example.com",
            "port": 443,
            "users": [
              {
                "id": "4d6e0338-f67a-4187-bca3-902e232466bc",
                "encryption": "none",
                "level": 0
              }
            ]
          }
        ]
      },
      "streamSettings": {
        "network": "tcp",
        "security": "tls",
        "tlsSettings": {
          "allowInsecure": false
        }
      }
    }
  ]
}
```

Save as `xray_config.json` and run:

```powershell
xray run -c "$env:USERPROFILE\xray_config.json"
```

**Google Chrome**: Modify shortcut target to add `--proxy-server="socks5://127.0.0.1:1080"`

**Firefox**: Settings → Network Settings → SOCKS Host: 127.0.0.1, Port: 1080, SOCKS v5, check "Proxy DNS when using SOCKS v5"

#### Route All Traffic (v2rayN + TUN)

Download `zz_v2rayN-With-Core-SelfContained.7z` from latest v2rayN release and extract. Run `v2rayN.exe` as Administrator, add VLESS server, restart, and click "Enable Tun". All traffic now routes through the proxy.

### Step 3.3: Linux Client

Install Xray as in Step 1. Use same SOCKS proxy config as Windows.

```bash
xray run -c /usr/local/etc/xray/config.json
```

**Chrome**: `google-chrome --proxy-server="socks5://127.0.0.1:1080"`

**Firefox**: Same as Windows section.

**System-wide**: Depends on desktop environment — consult distro docs for SOCKS proxy configuration.
