feat(migrations): Add WARP auto-integration with redsocks and iptables
- Implemented migration 067 to set up Cloudflare WARP with automatic routing for VPN client TCP traffic through a redsocks proxy. - Included installation scripts for WARP and redsocks, along with iptables rules for traffic redirection. - Added detection for X-Ray and patching of its outbound configuration. - Created uninstall scripts to clean up configurations and remove installed packages. fix(migrations): Enhance WARP install script for heredoc compatibility - Implemented migration 068 to fix nested heredoc conflicts and streamline the WARP installation script for panel compatibility. - Removed duplicate `set -eo pipefail` and adjusted formatting for better readability. feat(migrations): Auto-detect AIVPN subnet for routing in WARP setup - Implemented migration 069 to enhance the WARP installation script by adding detection for AIVPN subnets alongside existing AWG container detection. - Updated routing logic to handle both container IPs and host-level VPN subnets. - Ensured proper configuration of iptables for seamless traffic routing through the WARP proxy.
This commit is contained in:
@@ -0,0 +1,296 @@
|
||||
-- =====================================================================
|
||||
-- Migration 066: Add Cloudflare WARP proxy protocol
|
||||
-- Installs Cloudflare WARP on VPS and enables SOCKS5/HTTPS proxy mode
|
||||
-- Creates chain: AmneziaWG → WARP (127.0.0.1:40000) → Internet
|
||||
-- Adds DPI/censorship bypass layer via Cloudflare tunnel
|
||||
-- =====================================================================
|
||||
|
||||
-- 1. Insert the Cloudflare WARP protocol
|
||||
INSERT INTO protocols (name, slug, description, install_script, uninstall_script, output_template, show_text_content, ubuntu_compatible, is_active, definition, created_at, updated_at)
|
||||
SELECT
|
||||
'Cloudflare WARP Proxy',
|
||||
'cf-warp',
|
||||
'Cloudflare WARP — прокси-слой для обхода DPI/цензуры. Устанавливает WARP на сервер в режиме SOCKS5 прокси (127.0.0.1:40000). Трафик идёт по цепочке: VPN-клиент → AmneziaWG → WARP → Cloudflare → Интернет. Скрывает конечные домены от провайдера VPS.',
|
||||
'#!/bin/bash
|
||||
set -eo pipefail
|
||||
|
||||
# ======================================================================
|
||||
# Cloudflare WARP Proxy Installer
|
||||
# Installs WARP in proxy mode (SOCKS5 on 127.0.0.1:40000)
|
||||
# For chain: AmneziaWG → WARP → Internet
|
||||
# ======================================================================
|
||||
|
||||
WARP_PROXY_PORT="${WARP_PROXY_PORT:-40000}"
|
||||
WARP_MODE="${WARP_MODE:-proxy}"
|
||||
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
echo "=== Installing Cloudflare WARP ==="
|
||||
|
||||
# Detect OS
|
||||
if [ -f /etc/os-release ]; then
|
||||
. /etc/os-release
|
||||
OS_ID="$ID"
|
||||
OS_VERSION="$VERSION_ID"
|
||||
else
|
||||
OS_ID="unknown"
|
||||
OS_VERSION="0"
|
||||
fi
|
||||
|
||||
echo "Detected OS: $OS_ID $OS_VERSION"
|
||||
|
||||
# Check architecture
|
||||
ARCH=$(uname -m)
|
||||
if [ "$ARCH" != "x86_64" ] && [ "$ARCH" != "aarch64" ]; then
|
||||
echo "ERROR: WARP supports only x86_64 and aarch64, got: $ARCH"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Install prerequisites
|
||||
apt-get update -qq
|
||||
apt-get install -y -qq curl gnupg lsb-release >/dev/null 2>&1
|
||||
|
||||
# Add Cloudflare WARP repository
|
||||
curl -fsSL https://pkg.cloudflareclient.com/pubkey.gpg | gpg --yes --dearmor -o /usr/share/keyrings/cloudflare-warp-archive-keyring.gpg
|
||||
|
||||
# Determine correct repo codename
|
||||
REPO_CODENAME=""
|
||||
case "$OS_ID" in
|
||||
ubuntu)
|
||||
case "$OS_VERSION" in
|
||||
24.04) REPO_CODENAME="noble" ;;
|
||||
22.04) REPO_CODENAME="jammy" ;;
|
||||
20.04) REPO_CODENAME="focal" ;;
|
||||
*) REPO_CODENAME="jammy" ;;
|
||||
esac
|
||||
;;
|
||||
debian)
|
||||
case "$OS_VERSION" in
|
||||
12*) REPO_CODENAME="bookworm" ;;
|
||||
11*) REPO_CODENAME="bullseye" ;;
|
||||
*) REPO_CODENAME="bookworm" ;;
|
||||
esac
|
||||
;;
|
||||
*)
|
||||
REPO_CODENAME="jammy"
|
||||
echo "WARNING: Unsupported OS $OS_ID, trying Ubuntu Jammy repo"
|
||||
;;
|
||||
esac
|
||||
|
||||
echo "deb [signed-by=/usr/share/keyrings/cloudflare-warp-archive-keyring.gpg] https://pkg.cloudflareclient.com/ $REPO_CODENAME main" > /etc/apt/sources.list.d/cloudflare-client.list
|
||||
|
||||
# Install WARP client
|
||||
apt-get update -qq
|
||||
apt-get install -y -qq cloudflare-warp >/dev/null 2>&1
|
||||
|
||||
echo "WARP package installed"
|
||||
|
||||
# Check if already registered
|
||||
WARP_STATUS=$(warp-cli --accept-tos status 2>/dev/null || echo "unregistered")
|
||||
|
||||
if echo "$WARP_STATUS" | grep -qiE "Registration Missing|unregistered"; then
|
||||
echo "Registering WARP..."
|
||||
warp-cli --accept-tos registration new
|
||||
echo "WARP registered"
|
||||
else
|
||||
echo "WARP already registered"
|
||||
fi
|
||||
|
||||
# Set proxy mode
|
||||
echo "Setting WARP to proxy mode on port $WARP_PROXY_PORT..."
|
||||
warp-cli --accept-tos mode proxy
|
||||
warp-cli --accept-tos proxy port "$WARP_PROXY_PORT"
|
||||
|
||||
# Connect WARP
|
||||
echo "Connecting WARP..."
|
||||
warp-cli --accept-tos connect
|
||||
|
||||
# Wait for connection
|
||||
for i in $(seq 1 15); do
|
||||
CONN_STATUS=$(warp-cli --accept-tos status 2>/dev/null || echo "")
|
||||
if echo "$CONN_STATUS" | grep -qi "Connected"; then
|
||||
echo "WARP connected successfully"
|
||||
break
|
||||
fi
|
||||
if [ "$i" -eq 15 ]; then
|
||||
echo "WARNING: WARP connection timeout, may still be connecting..."
|
||||
fi
|
||||
sleep 2
|
||||
done
|
||||
|
||||
# Verify proxy is listening
|
||||
sleep 2
|
||||
if command -v ss >/dev/null 2>&1; then
|
||||
LISTENING=$(ss -tlnp 2>/dev/null | grep ":${WARP_PROXY_PORT}" || true)
|
||||
elif command -v netstat >/dev/null 2>&1; then
|
||||
LISTENING=$(netstat -tlnp 2>/dev/null | grep ":${WARP_PROXY_PORT}" || true)
|
||||
else
|
||||
LISTENING=""
|
||||
fi
|
||||
|
||||
if [ -n "$LISTENING" ]; then
|
||||
echo "WARP SOCKS5 proxy listening on 127.0.0.1:${WARP_PROXY_PORT}"
|
||||
else
|
||||
echo "WARNING: Proxy port ${WARP_PROXY_PORT} not yet listening, WARP may need more time"
|
||||
fi
|
||||
|
||||
# Test proxy connectivity
|
||||
PROXY_TEST=$(curl -x socks5h://127.0.0.1:${WARP_PROXY_PORT} -s -o /dev/null -w "%{http_code}" --max-time 10 https://cloudflare.com/cdn-cgi/trace 2>/dev/null || echo "000")
|
||||
if [ "$PROXY_TEST" = "200" ]; then
|
||||
echo "WARP proxy test: OK (HTTP 200)"
|
||||
else
|
||||
echo "WARNING: WARP proxy test returned HTTP $PROXY_TEST (may need a moment to initialize)"
|
||||
fi
|
||||
|
||||
# Get WARP IP info
|
||||
WARP_IP=$(curl -x socks5h://127.0.0.1:${WARP_PROXY_PORT} -s --max-time 10 https://cloudflare.com/cdn-cgi/trace 2>/dev/null | grep "ip=" | cut -d= -f2 || echo "unknown")
|
||||
WARP_ACCOUNT=$(warp-cli --accept-tos registration show 2>/dev/null | grep -i "Account ID" | awk "{print \$NF}" || echo "unknown")
|
||||
|
||||
# Enable WARP service to start on boot
|
||||
systemctl enable warp-svc 2>/dev/null || true
|
||||
|
||||
# Get server external IP
|
||||
EXTERNAL_IP=$(curl -s -4 ifconfig.me 2>/dev/null || curl -s -4 icanhazip.com 2>/dev/null || echo "YOUR_SERVER_IP")
|
||||
|
||||
echo ""
|
||||
echo "=== Cloudflare WARP Proxy Installed ==="
|
||||
echo "Variable: warp_proxy_port=$WARP_PROXY_PORT"
|
||||
echo "Variable: warp_mode=$WARP_MODE"
|
||||
echo "Variable: warp_ip=$WARP_IP"
|
||||
echo "Variable: warp_account=$WARP_ACCOUNT"
|
||||
echo "Variable: server_host=$EXTERNAL_IP"
|
||||
echo "Variable: proxy_address=127.0.0.1:${WARP_PROXY_PORT}"',
|
||||
'#!/bin/bash
|
||||
set -eo pipefail
|
||||
|
||||
echo "=== Uninstalling Cloudflare WARP ==="
|
||||
|
||||
# Disconnect and deregister
|
||||
warp-cli --accept-tos disconnect 2>/dev/null || true
|
||||
warp-cli --accept-tos registration delete 2>/dev/null || true
|
||||
|
||||
# Stop service
|
||||
systemctl stop warp-svc 2>/dev/null || true
|
||||
systemctl disable warp-svc 2>/dev/null || true
|
||||
|
||||
# Remove package
|
||||
apt-get remove -y cloudflare-warp 2>/dev/null || true
|
||||
apt-get autoremove -y 2>/dev/null || true
|
||||
|
||||
# Clean up config
|
||||
rm -rf /var/lib/cloudflare-warp 2>/dev/null || true
|
||||
rm -f /etc/apt/sources.list.d/cloudflare-client.list 2>/dev/null || true
|
||||
rm -f /usr/share/keyrings/cloudflare-warp-archive-keyring.gpg 2>/dev/null || true
|
||||
|
||||
echo "{\"success\":true,\"message\":\"Cloudflare WARP uninstalled\"}"',
|
||||
'WARP SOCKS5 Proxy: socks5h://127.0.0.1:{{warp_proxy_port}}
|
||||
WARP IP: {{warp_ip}}
|
||||
Mode: {{warp_mode}}
|
||||
Server: {{server_host}}',
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
JSON_OBJECT(
|
||||
'engine', 'shell',
|
||||
'metadata', JSON_OBJECT(
|
||||
'container_name', '',
|
||||
'port_range', JSON_ARRAY(40000, 40000),
|
||||
'config_dir', '/var/lib/cloudflare-warp',
|
||||
'is_proxy_layer', true,
|
||||
'proxy_port', 40000,
|
||||
'proxy_protocol', 'socks5'
|
||||
)
|
||||
),
|
||||
NOW(),
|
||||
NOW()
|
||||
WHERE NOT EXISTS (SELECT 1 FROM protocols WHERE slug = 'cf-warp');
|
||||
|
||||
-- 2. Add protocol variables for WARP
|
||||
INSERT INTO protocol_variables (protocol_id, variable_name, variable_type, default_value, description, required)
|
||||
SELECT p.id, 'warp_proxy_port', 'number', '40000', 'WARP SOCKS5 proxy port (default 40000)', true
|
||||
FROM protocols p WHERE p.slug = 'cf-warp'
|
||||
AND NOT EXISTS (SELECT 1 FROM protocol_variables WHERE protocol_id = p.id AND variable_name = 'warp_proxy_port');
|
||||
|
||||
INSERT INTO protocol_variables (protocol_id, variable_name, variable_type, default_value, description, required)
|
||||
SELECT p.id, 'warp_mode', 'string', 'proxy', 'WARP mode (proxy / warp)', false
|
||||
FROM protocols p WHERE p.slug = 'cf-warp'
|
||||
AND NOT EXISTS (SELECT 1 FROM protocol_variables WHERE protocol_id = p.id AND variable_name = 'warp_mode');
|
||||
|
||||
INSERT INTO protocol_variables (protocol_id, variable_name, variable_type, default_value, description, required)
|
||||
SELECT p.id, 'warp_ip', 'string', '', 'WARP exit IP address (via Cloudflare)', false
|
||||
FROM protocols p WHERE p.slug = 'cf-warp'
|
||||
AND NOT EXISTS (SELECT 1 FROM protocol_variables WHERE protocol_id = p.id AND variable_name = 'warp_ip');
|
||||
|
||||
INSERT INTO protocol_variables (protocol_id, variable_name, variable_type, default_value, description, required)
|
||||
SELECT p.id, 'warp_account', 'string', '', 'WARP account ID', false
|
||||
FROM protocols p WHERE p.slug = 'cf-warp'
|
||||
AND NOT EXISTS (SELECT 1 FROM protocol_variables WHERE protocol_id = p.id AND variable_name = 'warp_account');
|
||||
|
||||
INSERT INTO protocol_variables (protocol_id, variable_name, variable_type, default_value, description, required)
|
||||
SELECT p.id, 'server_host', 'string', '', 'Server hostname or IP', true
|
||||
FROM protocols p WHERE p.slug = 'cf-warp'
|
||||
AND NOT EXISTS (SELECT 1 FROM protocol_variables WHERE protocol_id = p.id AND variable_name = 'server_host');
|
||||
|
||||
INSERT INTO protocol_variables (protocol_id, variable_name, variable_type, default_value, description, required)
|
||||
SELECT p.id, 'proxy_address', 'string', '127.0.0.1:40000', 'Full proxy address', false
|
||||
FROM protocols p WHERE p.slug = 'cf-warp'
|
||||
AND NOT EXISTS (SELECT 1 FROM protocol_variables WHERE protocol_id = p.id AND variable_name = 'proxy_address');
|
||||
|
||||
-- 3. Add default template for WARP
|
||||
INSERT INTO protocol_templates (protocol_id, template_name, template_content, is_default)
|
||||
SELECT p.id, 'Default WARP', 'WARP SOCKS5 Proxy: socks5h://127.0.0.1:{{warp_proxy_port}}
|
||||
WARP IP: {{warp_ip}}
|
||||
Mode: {{warp_mode}}
|
||||
Server: {{server_host}}', true
|
||||
FROM protocols p WHERE p.slug = 'cf-warp'
|
||||
AND NOT EXISTS (SELECT 1 FROM protocol_templates WHERE protocol_id = p.id AND template_name = 'Default WARP');
|
||||
|
||||
-- 4. Add translations for Cloudflare WARP
|
||||
INSERT INTO translations (locale, category, key_name, translation) VALUES
|
||||
('en', 'protocols', 'protocol_cf_warp', 'Cloudflare WARP Proxy')
|
||||
ON DUPLICATE KEY UPDATE translation = VALUES(translation);
|
||||
|
||||
INSERT INTO translations (locale, category, key_name, translation) VALUES
|
||||
('ru', 'protocols', 'protocol_cf_warp', 'Cloudflare WARP Прокси')
|
||||
ON DUPLICATE KEY UPDATE translation = VALUES(translation);
|
||||
|
||||
-- WARP-specific UI translations
|
||||
INSERT INTO translations (locale, category, key_name, translation) VALUES
|
||||
('en', 'protocols', 'warp_status', 'WARP Status')
|
||||
ON DUPLICATE KEY UPDATE translation = VALUES(translation);
|
||||
|
||||
INSERT INTO translations (locale, category, key_name, translation) VALUES
|
||||
('ru', 'protocols', 'warp_status', 'Статус WARP')
|
||||
ON DUPLICATE KEY UPDATE translation = VALUES(translation);
|
||||
|
||||
INSERT INTO translations (locale, category, key_name, translation) VALUES
|
||||
('en', 'protocols', 'warp_connected', 'Connected via Cloudflare')
|
||||
ON DUPLICATE KEY UPDATE translation = VALUES(translation);
|
||||
|
||||
INSERT INTO translations (locale, category, key_name, translation) VALUES
|
||||
('ru', 'protocols', 'warp_connected', 'Подключён через Cloudflare')
|
||||
ON DUPLICATE KEY UPDATE translation = VALUES(translation);
|
||||
|
||||
INSERT INTO translations (locale, category, key_name, translation) VALUES
|
||||
('en', 'protocols', 'warp_disconnected', 'Disconnected')
|
||||
ON DUPLICATE KEY UPDATE translation = VALUES(translation);
|
||||
|
||||
INSERT INTO translations (locale, category, key_name, translation) VALUES
|
||||
('ru', 'protocols', 'warp_disconnected', 'Отключён')
|
||||
ON DUPLICATE KEY UPDATE translation = VALUES(translation);
|
||||
|
||||
INSERT INTO translations (locale, category, key_name, translation) VALUES
|
||||
('en', 'protocols', 'warp_proxy_info', 'WARP proxy adds a Cloudflare encryption layer to hide destination domains from VPS provider. Traffic chain: Client → AmneziaWG → WARP → Cloudflare → Internet')
|
||||
ON DUPLICATE KEY UPDATE translation = VALUES(translation);
|
||||
|
||||
INSERT INTO translations (locale, category, key_name, translation) VALUES
|
||||
('ru', 'protocols', 'warp_proxy_info', 'WARP прокси добавляет слой шифрования Cloudflare для скрытия конечных доменов от провайдера VPS. Цепочка: Клиент → AmneziaWG → WARP → Cloudflare → Интернет')
|
||||
ON DUPLICATE KEY UPDATE translation = VALUES(translation);
|
||||
|
||||
INSERT INTO translations (locale, category, key_name, translation) VALUES
|
||||
('en', 'protocols', 'warp_warning_ram', '⚠️ Cloudflare WARP uses ~50-100MB additional RAM')
|
||||
ON DUPLICATE KEY UPDATE translation = VALUES(translation);
|
||||
|
||||
INSERT INTO translations (locale, category, key_name, translation) VALUES
|
||||
('ru', 'protocols', 'warp_warning_ram', '⚠️ Cloudflare WARP использует ~50-100 МБ дополнительной RAM')
|
||||
ON DUPLICATE KEY UPDATE translation = VALUES(translation);
|
||||
Reference in New Issue
Block a user