NAT VPS Optimal Node Setup
6 min read
0
This guide will walk you through building a high-performance node on a German LXC NAT VPS (or IPv6-only VPS) using Cloudflare Argo Tunnel. This architecture perfectly solves common issues like lack of public IPv4, restricted ports, and dirty IP addresses.
Architecture Overview:
- Ingress: Cloudflare Anycast IP -> Argo Tunnel (HTTP/2)
- Middleware: X-UI Panel (VLESS/gRPC)
- Egress: WARP (Unlocks streaming / Provides clean IPv6)
- Optimization: BBR + TCP Window Tuning
Part 1: Manual Deployment Steps
1. Initialize Environment
Connect via SSH and update the system with necessary network tools.
apt update && apt upgrade -y
apt install -y curl wget sudo nano net-tools iptables-persistent
2. System Kernel Optimization (LXC Specific)
Enable BBR and optimize TCP windows for high-latency cross-continent connections. (Note: LXC shares the host kernel, so we enable modules without changing the kernel)
# 1. Enable BBR (if supported by host)
echo "net.core.default_qdisc=fq" >> /etc/sysctl.conf
echo "net.ipv4.tcp_congestion_control=bbr" >> /etc/sysctl.conf
# 2. Optimize TCP Windows (Critical for 170ms+ latency)
cat <<EOF >> /etc/sysctl.conf
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 16384 16777216
EOF
# 3. Fix Ping permission issues in LXC containers
echo '0 2147483647' > /proc/sys/net/ipv4/ping_group_range
# Apply changes
sysctl -p
3. Install Cloudflare WARP (Outbound Traffic)
This assigns a clean exit IP to your VPS, preventing Google CAPTCHAs.
wget -N https://gitlab.com/fscarmen/warp/-/raw/main/menu.sh && bash menu.sh
# Recommended: Select [1] Install WARP -> [1] System Interface -> [2] IPv4 Priority or Dual Stack
4. Install 3x-ui Panel
bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh)
Configuration Recommendations:
- Panel Port: Set to
8080(to match the script below). - Inbound Listen IP: Set to
127.0.0.1(Only allow local tunnel access for security). - Inbound Port:
8080.
5. Deploy Cloudflared Tunnel (Intranet Penetration)
A. Install & Login
curl -L --output cloudflared.deb https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb && dpkg -i cloudflared.deb
cloudflared tunnel login
# Copy the link provided and authorize via browser
B. Create Tunnel
# 1. Create a tunnel (Name it whatever you want, e.g., my-tunnel)
cloudflared tunnel create my-tunnel
# 2. Route DNS (Replace with your actual domain)
cloudflared tunnel route dns my-tunnel node.yourdomain.com
C. Configure Routing & Daemon
Create the config file ~/.cloudflared/config.yml:
(Replace <Your-Tunnel-ID> with the actual ID generated)
tunnel: <Your-Tunnel-ID>
credentials-file: /root/.cloudflared/<Your-Tunnel-ID>.json
protocol: http2
ingress:
- hostname: node.yourdomain.com
service: http://127.0.0.1:8080
- service: http_status:404
Finally, install the system service for auto-start:
cloudflared service install
systemctl start cloudflared
Part 2: All-in-One Automation Script
If you prefer not to configure everything manually, use the script below. It automatically detects the environment, asks for your domain, and generates the configuration files.
How to use:
- Create file:
nano setup.sh - Paste the code below.
- Run:
chmod +x setup.sh && ./setup.sh
#!/bin/bash
# ==========================================
# German NAT VPS / IPv6 Only Setup Script
# Blog Version - Auto Config for Argo Tunnel + WARP + BBR
# ==========================================
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
PLAIN='\033[0m'
# 1. Environment Init & LXC Optimization
echo -e "${GREEN}>>> [1/5] Initializing environment & kernel optimization...${PLAIN}"
apt update && apt install -y curl wget sudo nano net-tools
# Fix LXC Ping permissions
echo '0 2147483647' > /proc/sys/net/ipv4/ping_group_range
# Write BBR & TCP optimization parameters
sed -i '/net.core.default_qdisc/d' /etc/sysctl.conf
sed -i '/net.ipv4.tcp_congestion_control/d' /etc/sysctl.conf
echo "net.core.default_qdisc=fq" >> /etc/sysctl.conf
echo "net.ipv4.tcp_congestion_control=bbr" >> /etc/sysctl.conf
# Optimize TCP window for high latency
cat <<EOF >> /etc/sysctl.conf
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 16384 16777216
EOF
sysctl -p
# 2. Install WARP
echo -e "${GREEN}>>> [2/5] Installing Cloudflare WARP...${PLAIN}"
echo -e "${YELLOW}Tip: In the interactive menu, recommend selecting [1] Install -> [2] IPv4 Priority${PLAIN}"
read -p "Press Enter to continue..."
wget -N https://gitlab.com/fscarmen/warp/-/raw/main/menu.sh && bash menu.sh
# 3. Install X-UI
echo -e "${GREEN}>>> [3/5] Installing 3x-ui Panel...${PLAIN}"
echo -e "${YELLOW}Tip: Recommend setting panel port to 8080 to match default config${PLAIN}"
read -p "Press Enter to continue..."
bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh)
# 4. Configure Cloudflared Tunnel
echo -e "${GREEN}>>> [4/5] Configuring Cloudflared Tunnel...${PLAIN}"
curl -L --output cloudflared.deb https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb && dpkg -i cloudflared.deb
echo -e "${YELLOW}>>> Please copy the link below to authorize Cloudflare in your browser:${PLAIN}"
cloudflared tunnel login
echo -e "\n"
read -p "Enter a name for your tunnel (e.g., my-vps): " TUNNEL_NAME
cloudflared tunnel create $TUNNEL_NAME
# Auto-fetch ID
TUNNEL_ID=$(cloudflared tunnel list | grep $TUNNEL_NAME | awk '{print $1}')
if [ -z "$TUNNEL_ID" ]; then
echo -e "${RED}Tunnel creation failed. Please check authorization.${PLAIN}"
exit 1
fi
read -p "Enter the full domain to bind (e.g., node.example.com): " DOMAIN_NAME
cloudflared tunnel route dns $TUNNEL_NAME $DOMAIN_NAME
# Generate config (Force HTTP2 to avoid UDP blocking)
mkdir -p /root/.cloudflared
cat <<EOF > /root/.cloudflared/config.yml
tunnel: $TUNNEL_ID
credentials-file: /root/.cloudflared/${TUNNEL_ID}.json
protocol: http2
ingress:
- hostname: $DOMAIN_NAME
service: http://127.0.0.1:8080
- service: http_status:404
EOF
# 5. Persistence Service
echo -e "${GREEN}>>> [5/5] Creating Systemd Service...${PLAIN}"
cat <<EOF > /etc/systemd/system/cloudflared.service
[Unit]
Description=Cloudflare Tunnel
After=network.target
[Service]
Type=simple
User=root
ExecStart=/usr/bin/cloudflared tunnel --config /root/.cloudflared/config.yml run
Restart=on-failure
RestartSec=10
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable cloudflared
systemctl start cloudflared
echo -e "${GREEN}==============================================${PLAIN}"
echo -e "${GREEN} Deployment Successful! ${PLAIN}"
echo -e "Your Node Domain: ${YELLOW}${DOMAIN_NAME}${PLAIN}"
echo -e "Action Required: Go to X-UI panel, create an inbound with Port 8080 and Listen IP 127.0.0.1"
echo -e "${GREEN}==============================================${PLAIN}"
Part 3: Troubleshooting Guide
🔧 YouTube Client Can’t Connect (WebUI Works Fine)
If the web UI works but clients like YouTube cannot connect, the outbound strategy is likely the issue.
🎯 Core Fix: Force IPv6 Priority
- Open the panel: Click Panel Settings -> Xray Configuration on the left.
- Find the JSON: Locate the section under
"outbounds": [in the right-hand editor. - Edit the Freedom outbound: Find the first block where
protocolisfreedom(this handles direct outbound). - Add the key line: Inside the
settingsobject{}, add"domainStrategy": "UseIPv6".
The updated block should look like this (note the commas):
{
"protocol": "freedom",
"settings": {
"domainStrategy": "UseIPv6"
},
"tag": "direct"
}- Before:
settingsis empty{}or only containsuserLevel. - After: Xray will always prefer IPv6 when resolving and connecting to sites like YouTube. Your IPv6 is clean, while IPv4 is a shared “dirty IP,” so IPv6 avoids Google’s blocks.
⚡️ Another Potential Setting: Sniffing
If the change above isn’t enough, you may have turned off Sniffing for the inbound.
- Go to Inbounds.
- Click Edit for your node.
- Ensure the Sniffing toggle is Enabled.
- With sniffing on, Xray can detect the domain (e.g.,
youtube.com) and apply theUseIPv6strategy.
- With sniffing on, Xray can detect the domain (e.g.,
Usually, just domainStrategy: UseIPv6 fixes it. Save and restart Xray after changes.
Client Connection Tips (For Blog Readers)
When configuring clients like v2rayN, Shadowrocket, or Clash:
- Address: Use a Cloudflare Optimized IP (e.g.,
visa.cnorcf.090227.xyz). Do NOT put your bound domain here. - Port:
443 - SNI / Host / Pseudo Domain: Enter your bound domain (e.g.,
node.yourdomain.com). - TLS: Must be ON.