https://cmptrnb.github.io

3X-UI server with domestic relay server

The scenario here is that direct connection to an international VPS is blocked. However, connecting from a domestic VPS to an international VPS is allowed. Therefore the solution is a double hop from the client PC to a domestic VPS and from the domestic VPS to an international VPS.

+-----------+      +--------------+      +-------------------+
+           +      +              +      +                   +
+           +      +  45.45.45.45 +      +  123.123.123.123  +
+ Client PC +----->+ Domestic VPS +----->+ International VPS +-----> WWW
+           +      +    Relay     +      +      3X-UI        +
+           +      +              +      +                   +
+-----------+      +--------------+      +-------------------+

The international VPS will be configured using the 3X-UI panel.

For the domestic VPS relay, there are several common methods of relaying traffic from one server to another:

In this article we will use the Nginx stream proxy function to build a simple and efficient Layer 4 relay server.

This article draws in part on https://github.com/xcvtt/miniature-octo-palm-tree.

0. Prerequisites

We assume that you already have:

1. Install and configure 3X-UI on international server

3X-UI is a graphical tool for managing an xray-core server and generating client configurations. You can also configure subscription functionality, although we will not use that in this simple scenario. We use the installation script from the official 3X-UI repository.

1.1. Open firewall

At this point, you must open:

1.2. Set up Let's Encrypt

SSH into your international VPS as root.

Update your existing software packages on the server:

apt update && apt upgrade -y

Install the prerequisite packages for the ACME certificate management script:

apt install -y curl wget socat cron

Download and run the ACME installation script:

curl https://get.acme.sh | sh

Set the Certificate Authority to Let's Encrypt:

/root/.acme.sh/acme.sh --set-default-ca --server letsencrypt

1.3. Install 3X-UI

Run the official 3X-UI installation script:

bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh)

You are asked if you want a customized port or a random port:

Would you like to customize the Panel Port settings? (If not, a random port will be applied) [y/n]:

Enter n for no to get a random port.

The random port is displayed, e.g.:

Generated random port: 24784
Port set successfully: 24784
Username and password updated successfully
Base URI path set successfully

You are prompted for the option you want for SSL certificate set-up:

═══════════════════════════════════════════
     SSL Certificate Setup (MANDATORY)
═══════════════════════════════════════════
For security, SSL certificate is required for all panels.
Let's Encrypt now supports both domains and IP addresses!

Choose SSL certificate setup method:
1. Let's Encrypt for Domain (90-day validity, auto-renews)
2. Let's Encrypt for IP Address (6-day validity, auto-renews)
3. Custom SSL Certificate (Path to existing files)
Note: Options 1 & 2 require port 80 open. Option 3 requires manual paths.

In the scenario in this article, you will enter 2, meaning get a certificate for your IP address, without specifying a domain name.

You are prompted for an IPv6 address:

Using Let's Encrypt for IP certificate (shortlived profile)...
Do you have an IPv6 address to include? (leave empty to skip):

In the scenario in this article, you will just press Enter.

You are asked to confirm that you will use port 80 for validation:

Setting up Let's Encrypt IP certificate (shortlived profile)...
Note: IP certificates are valid for ~6 days and will auto-renew.
Default listener is port 80. If you choose another port, ensure external port 80 forwards to it.
Port to use for ACME HTTP-01 listener (default 80):

In the scenario in this article, just press Enter to use port 80.

At the end of its run, the script displays your generated details. For example:

═══════════════════════════════════════════
     Panel Installation Complete!
═══════════════════════════════════════════
Username:    XeDlq6j2e5
Password:    hDRavPCEcS
Port:        24784
WebBasePath: UMEZjfcEvUVWk7oKdo
Access URL:  https://123.123.123.123:24784/UMEZjfcEvUVWk7oKdo
═══════════════════════════════════════════

Details of the X-UI control menu are also displayed:

┌───────────────────────────────────────────────────────┐
│  x-ui control menu usages (subcommands):              │
│                                                       │
│  x-ui              - Admin Management Script          │
│  x-ui start        - Start                            │
│  x-ui stop         - Stop                             │
│  x-ui restart      - Restart                          │
│  x-ui status       - Current Status                   │
│  x-ui settings     - Current Settings                 │
│  x-ui enable       - Enable Autostart on OS Startup   │
│  x-ui disable      - Disable Autostart on OS Startup  │
│  x-ui log          - Check logs                       │
│  x-ui banlog       - Check Fail2ban ban logs          │
│  x-ui update       - Update                           │
│  x-ui legacy       - Legacy version                   │
│  x-ui install      - Install                          │
│  x-ui uninstall    - Uninstall                        │
└───────────────────────────────────────────────────────┘

1.4. Open firewall

You must now open your firewall for TCP input on the generated port.

In our example, that is port tcp/24784.

If necessary, and depending on what firewall you are using, remember also that you must persist this change across reboots.

1.5. Log in to 3X-UI panel

Exit your SSH session with the international VPS:

exit

Now open a browser.

Navigate to the generated panel URL https://ip:port/secret_path.

In our example, that is https://123.123.123.123:24784/UMEZjfcEvUVWk7oKdo.

Enter the generated username and password.

In our example, that is username XeDlq6j2e5 and password hDRavPCEcS.

1.6. Disable subscription service

After logging into the panel for the first time, disable the subscription service, which is not needed in this scenario:

  1. In the menu on the left, go to Panel Settings.
  2. Select the tab Subscription.
  3. Toggle Subscription Service to the OFF position.

1.7. Create inbound

Now create the inbound.

In the menu on the left of the 3X-UI panel, go to Inbounds.

Click Add Inbound and enter settings:

Expand Client and enter:

Note: An enhancement issue https://github.com/MHSanaei/3x-ui/issues/3841 requests adding flow and seed to VLESS Reality in 3X-UI. This will prevent a warning in the xray-core client: The feature VLESS (with no Flow, etc.) is deprecated, not recommended for using, and might be removed. Please migrate to VLESS with Flow & Seed as soon as possible.

Click Get New Cert.

Click Create.

1.8. Export client configuration URL

After adding an inbound, click the three dots at the start of its row.

Select Export All URLs.

Copy the export results to the Windows clipboard on your PC, e.g.:

vless://1eef213f-b861-4c18-8fe1-09fc6f6ce824@123.123.123.123:443?type=tcp&encryption=mlkem768x25519plus.native.0rtt.Y9RJQEANTXnZRUriFTOFaREKCKHMl059_cXiHUoRTgk&security=reality&pbk=vO8UgToRzHspcOYtYSctYBBatRjHK68EXJc2L9tUsQM&fp=chrome&sni=www.apple.com&sid=053f41e6&spx=%2F#7sy8zwxa

Paste this into Windows Notepad, in case you need to use the Windows clipboard for something else.

1.9. Log out

In the menu on the left of the 3X-UI panel, click Log Out.

2. Install and configure Nginx on domestic VPS

The domestic VPS will intercept packets from the client and relay them to the international VPS.

2.1. Open firewall

At this point, you must open for input:

2.2. Update server

SSH into your domestic VPS as root.

Update your existing software packages on the server:

apt update && apt upgrade -y

2.2. Install Nginx

Install Nginx and the Nginx stream module:

apt install -y nginx libnginx-mod-stream

2.3. Configure stream

Edit the Nginx configuration file /etc/nginx/nginx.conf.

Add a new stream configuration by appending these lines, replacing 123.123.123.123 by the actual IP address of your international server:

stream {
    upstream backend_server {
        server 123.123.123.123:443;
    }

    server {
        listen 443;
        proxy_pass backend_server;
    }
}

Save the file.

2.4. Activate stream

Check your configuration file:

nginx -t

Restart Nginx to apply the changes:

systemctl restart nginx

2.5. Log out

Exit your SSH session with the domestic server:

exit

3. Install and configure v2rayN on client PC

3.1. Install v2rayN

On your client PC, open a browser.

Navigate to https://github.com/2dust/v2rayn/releases.

Download v2rayN-windows-64.zip.

Unzip the zip file.

3.2. Configure v2rayN

Launch v2rayN.exe.

If you get a message, Windows protected your PC, then click More info followed by Run anyway.

Copy the internation server's configuration URL from Windows Notepad into the Windows clipboard.

In the v2ray main menu, select Configuration, then select Import share links from clipboard.

*** Now for the most important part to relay traffic via your domestic server! ***

*** In the server specification in v2rayN, replace the international IP 123.123.123.123 with the domestic relay server IP 45.45.45.45. ***

When you've done that, press Enter to start the v2rayN connection.

In the system tray at the bottom right of your Windows desktop, find the v2rayN icon, right-click on it, and select Set system proxy.