feat: add support for awg2, mtproxy, and aivpn protocols, and implement user role-based access control.
This commit is contained in:
@@ -0,0 +1,32 @@
|
||||
-- Migration: Add user roles and permissions
|
||||
-- Date: 2025-11-10
|
||||
|
||||
-- User roles table
|
||||
CREATE TABLE IF NOT EXISTS user_roles (
|
||||
id INT PRIMARY KEY AUTO_INCREMENT,
|
||||
name VARCHAR(50) NOT NULL UNIQUE,
|
||||
display_name VARCHAR(100) NOT NULL,
|
||||
description TEXT,
|
||||
permissions JSON NOT NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- Add role to users table
|
||||
ALTER TABLE users
|
||||
ADD COLUMN role VARCHAR(50) DEFAULT 'viewer' AFTER ldap_dn,
|
||||
ADD INDEX idx_role (role);
|
||||
|
||||
-- Insert default roles
|
||||
INSERT IGNORE INTO user_roles (name, display_name, description, permissions) VALUES
|
||||
('admin', 'Administrator', 'Full access to all features', JSON_ARRAY('*')),
|
||||
('manager', 'Manager', 'Can manage servers and clients', JSON_ARRAY('servers.view', 'servers.create', 'servers.edit', 'clients.view', 'clients.create', 'clients.edit', 'clients.delete')),
|
||||
('viewer', 'Viewer', 'Can only view own clients', JSON_ARRAY('clients.view_own', 'clients.download_own'));
|
||||
|
||||
-- Insert default LDAP group mappings (examples)
|
||||
INSERT IGNORE INTO ldap_group_mappings (ldap_group, role_name, description) VALUES
|
||||
('vpn-admins', 'admin', 'VPN administrators with full access'),
|
||||
('vpn-managers', 'manager', 'VPN managers who can create and manage clients'),
|
||||
('vpn-users', 'viewer', 'Regular VPN users with view-only access');
|
||||
|
||||
-- Update existing users to admin role (backward compatibility)
|
||||
UPDATE users SET role = 'admin' WHERE role IS NULL OR role = '';
|
||||
@@ -0,0 +1,381 @@
|
||||
-- =====================================================================
|
||||
-- Migration 058: Add AmneziaWG 2.0 protocol (amneziawg-go userspace)
|
||||
-- Uses amneziawg-go (Go userspace) instead of kernel module
|
||||
-- https://github.com/amnezia-vpn/amneziawg-go
|
||||
-- =====================================================================
|
||||
|
||||
-- 1. Insert the protocol entry (clone output_template from amnezia-wg-advanced)
|
||||
INSERT INTO protocols (name, slug, description, install_script, uninstall_script, output_template, ubuntu_compatible, is_active, definition, created_at, updated_at)
|
||||
SELECT
|
||||
'AmneziaWG 2.0',
|
||||
'awg2',
|
||||
'AmneziaWG 2.0 — userspace Go implementation (amneziawg-go). No kernel module required.',
|
||||
'#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
# Use exported variables from panel (SERVER_PORT, SERVER_CONTAINER) or defaults
|
||||
CONTAINER_NAME="${SERVER_CONTAINER:-amnezia-awg2}"
|
||||
PORT_RANGE_START=${PORT_RANGE_START:-30000}
|
||||
PORT_RANGE_END=${PORT_RANGE_END:-65000}
|
||||
VPN_PORT="${SERVER_PORT:-$((RANDOM % (PORT_RANGE_END - PORT_RANGE_START + 1) + PORT_RANGE_START))}"
|
||||
MTU=${MTU:-1420}
|
||||
|
||||
# Install git if not available
|
||||
if ! command -v git &> /dev/null; then
|
||||
apt-get update -qq && apt-get install -y -qq git >/dev/null 2>&1
|
||||
fi
|
||||
|
||||
mkdir -p /opt/amnezia/awg2
|
||||
|
||||
# Clone amneziawg-go source for Docker build
|
||||
if [ ! -d /opt/amnezia/awg2/src ]; then
|
||||
git clone --depth=1 https://github.com/amnezia-vpn/amneziawg-go.git /opt/amnezia/awg2/src
|
||||
fi
|
||||
|
||||
# Build Docker image using the repo Dockerfile (multi-stage: Go compile + tools)
|
||||
docker build --no-cache -t amnezia-awg2 /opt/amnezia/awg2/src
|
||||
|
||||
# Run container (userspace: no SYS_MODULE, no /lib/modules)
|
||||
EXISTING=$(docker ps -aq -f "name=$CONTAINER_NAME" 2>/dev/null | head -1)
|
||||
if [ -z "$EXISTING" ]; then
|
||||
docker run -d --name "$CONTAINER_NAME" --restart always --cap-add=NET_ADMIN --device /dev/net/tun -p "${VPN_PORT}:${VPN_PORT}/udp" -v /opt/amnezia/awg2:/opt/amnezia/awg amnezia-awg2 sh -c "while [ ! -f /opt/amnezia/awg/wg0.conf ]; do sleep 1; done; WG_QUICK_USERSPACE_IMPLEMENTATION=amneziawg-go awg-quick up /opt/amnezia/awg/wg0.conf && sleep infinity"
|
||||
|
||||
sleep 2
|
||||
else
|
||||
STATUS=$(docker inspect --format="{{.State.Status}}" "$CONTAINER_NAME" 2>/dev/null || echo "")
|
||||
if [ \"$STATUS\" != \"running\" ]; then
|
||||
docker start \"$CONTAINER_NAME\" >/dev/null 2>&1 || true
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check for existing config
|
||||
if [ -f /opt/amnezia/awg2/wg0.conf ]; then
|
||||
PORT=$(grep -E "^ListenPort" /opt/amnezia/awg2/wg0.conf | cut -d= -f2 | tr -d "[:space:]")
|
||||
PSK=$(cat /opt/amnezia/awg2/wireguard_psk.key 2>/dev/null || true)
|
||||
if [ -z "$PSK" ]; then
|
||||
PSK=$(grep -E "^PresharedKey" /opt/amnezia/awg2/wg0.conf | cut -d= -f2 | tr -d "[:space:]")
|
||||
fi
|
||||
PUBKEY=$(cat /opt/amnezia/awg2/wireguard_server_public_key.key 2>/dev/null || true)
|
||||
if [ -z "$PUBKEY" ]; then
|
||||
PRIVKEY=$(cat /opt/amnezia/awg2/wireguard_server_private_key.key 2>/dev/null || true)
|
||||
if [ -n "$PRIVKEY" ]; then
|
||||
PUBKEY=$(echo "$PRIVKEY" | docker exec -i "$CONTAINER_NAME" wg pubkey)
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "Using existing AmneziaWG 2.0 configuration"
|
||||
echo "Port: ${PORT:-$VPN_PORT}"
|
||||
if [ -n "${PUBKEY:-}" ]; then echo "Server Public Key: $PUBKEY"; fi
|
||||
if [ -n "${PSK:-}" ]; then echo "PresharedKey = $PSK"; fi
|
||||
|
||||
EXTERNAL_IP=$(curl -s -4 ifconfig.me 2>/dev/null || curl -s -4 icanhazip.com 2>/dev/null || echo "YOUR_SERVER_IP")
|
||||
echo "Server Host: $EXTERNAL_IP"
|
||||
|
||||
# Output AWG params from existing config
|
||||
for P in Jc Jmin Jmax S1 S2 S3 S4 H1 H2 H3 H4; do
|
||||
VAL=$(grep -E "^$P " /opt/amnezia/awg2/wg0.conf | cut -d= -f2 | tr -d "[:space:]")
|
||||
if [ -n "$VAL" ]; then echo "Variable: $P=$VAL"; fi
|
||||
done
|
||||
echo "Variable: dns_servers=1.1.1.1, 1.0.0.1"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Generate keys
|
||||
PRIVATE_KEY=$(docker exec "$CONTAINER_NAME" wg genkey)
|
||||
PUBLIC_KEY=$(echo "$PRIVATE_KEY" | docker exec -i "$CONTAINER_NAME" wg pubkey)
|
||||
PRESHARED_KEY=$(docker exec "$CONTAINER_NAME" wg genpsk)
|
||||
|
||||
# AWG obfuscation parameters
|
||||
JC=5
|
||||
JMIN=50
|
||||
JMAX=1000
|
||||
S1_VAL=50
|
||||
S2_VAL=100
|
||||
S3_VAL=20
|
||||
S4_VAL=10
|
||||
# H1-H4: header ranges (string format "x-y" per AWG2 spec)
|
||||
H1_VAL="1-4294967295"
|
||||
H2_VAL="1-4294967295"
|
||||
H3_VAL="1-4294967295"
|
||||
H4_VAL="1-4294967295"
|
||||
|
||||
# Write config
|
||||
cat > /opt/amnezia/awg2/wg0.conf << EOF
|
||||
[Interface]
|
||||
PrivateKey = $PRIVATE_KEY
|
||||
Address = 10.8.1.1/24
|
||||
ListenPort = $VPN_PORT
|
||||
MTU = $MTU
|
||||
Jc = $JC
|
||||
Jmin = $JMIN
|
||||
Jmax = $JMAX
|
||||
S1 = $S1_VAL
|
||||
S2 = $S2_VAL
|
||||
S3 = $S3_VAL
|
||||
S4 = $S4_VAL
|
||||
H1 = $H1_VAL
|
||||
H2 = $H2_VAL
|
||||
H3 = $H3_VAL
|
||||
H4 = $H4_VAL
|
||||
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
|
||||
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
|
||||
|
||||
[Peer]
|
||||
PublicKey =
|
||||
PresharedKey = $PRESHARED_KEY
|
||||
AllowedIPs = 10.8.1.2/32
|
||||
EOF
|
||||
|
||||
echo "$PRIVATE_KEY" > /opt/amnezia/awg2/wireguard_server_private_key.key
|
||||
echo "$PUBLIC_KEY" > /opt/amnezia/awg2/wireguard_server_public_key.key
|
||||
echo "$PRESHARED_KEY" > /opt/amnezia/awg2/wireguard_psk.key
|
||||
echo "[]" > /opt/amnezia/awg2/clientsTable
|
||||
|
||||
# Get 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 "AmneziaWG 2.0 installed successfully"
|
||||
echo "Port: $VPN_PORT"
|
||||
echo "Server Public Key: $PUBLIC_KEY"
|
||||
echo "PresharedKey = $PRESHARED_KEY"
|
||||
echo "Server Host: $EXTERNAL_IP"
|
||||
echo "Variable: Jc=$JC"
|
||||
echo "Variable: Jmin=$JMIN"
|
||||
echo "Variable: Jmax=$JMAX"
|
||||
echo "Variable: S1=$S1_VAL"
|
||||
echo "Variable: S2=$S2_VAL"
|
||||
echo "Variable: S3=$S3_VAL"
|
||||
echo "Variable: S4=$S4_VAL"
|
||||
echo "Variable: H1=$H1_VAL"
|
||||
echo "Variable: H2=$H2_VAL"
|
||||
echo "Variable: H3=$H3_VAL"
|
||||
echo "Variable: H4=$H4_VAL"
|
||||
echo "Variable: dns_servers=1.1.1.1, 1.0.0.1"',
|
||||
'#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
CONTAINER_NAME="${CONTAINER_NAME:-amnezia-awg2}"
|
||||
|
||||
docker stop "$CONTAINER_NAME" 2>/dev/null || true
|
||||
docker rm -fv "$CONTAINER_NAME" 2>/dev/null || true
|
||||
docker image rm amnezia-awg2 2>/dev/null || true
|
||||
rm -rf /opt/amnezia/awg2 2>/dev/null || true
|
||||
|
||||
echo "{\"success\":true,\"message\":\"AmneziaWG 2.0 uninstalled\"}"',
|
||||
p.output_template,
|
||||
1,
|
||||
1,
|
||||
JSON_OBJECT(
|
||||
'engine', 'shell',
|
||||
'metadata', JSON_OBJECT(
|
||||
'container_name', 'amnezia-awg2',
|
||||
'vpn_subnet', '10.8.1.0/24',
|
||||
'port_range', JSON_ARRAY(30000, 65000),
|
||||
'config_dir', '/opt/amnezia/awg2'
|
||||
)
|
||||
),
|
||||
NOW(),
|
||||
NOW()
|
||||
FROM protocols p
|
||||
WHERE p.slug = 'amnezia-wg-advanced'
|
||||
AND NOT EXISTS (SELECT 1 FROM protocols WHERE slug = 'awg2');
|
||||
|
||||
-- 2. Clone protocol variables from amnezia-wg-advanced to awg2
|
||||
INSERT INTO protocol_variables (protocol_id, variable_name, variable_type, default_value, description, required)
|
||||
SELECT
|
||||
(SELECT id FROM protocols WHERE slug = 'awg2' LIMIT 1),
|
||||
src.variable_name,
|
||||
src.variable_type,
|
||||
src.default_value,
|
||||
src.description,
|
||||
src.required
|
||||
FROM protocol_variables src
|
||||
WHERE src.protocol_id = (SELECT id FROM protocols WHERE slug = 'amnezia-wg-advanced' LIMIT 1)
|
||||
AND NOT EXISTS (
|
||||
SELECT 1 FROM protocol_variables ev
|
||||
WHERE ev.protocol_id = (SELECT id FROM protocols WHERE slug = 'awg2' LIMIT 1)
|
||||
AND ev.variable_name = src.variable_name
|
||||
);
|
||||
|
||||
-- 3. Clone protocol templates from amnezia-wg-advanced to awg2
|
||||
INSERT INTO protocol_templates (protocol_id, template_name, template_content, is_default)
|
||||
SELECT
|
||||
(SELECT id FROM protocols WHERE slug = 'awg2' LIMIT 1),
|
||||
src.template_name,
|
||||
src.template_content,
|
||||
src.is_default
|
||||
FROM protocol_templates src
|
||||
WHERE src.protocol_id = (SELECT id FROM protocols WHERE slug = 'amnezia-wg-advanced' LIMIT 1)
|
||||
AND NOT EXISTS (
|
||||
SELECT 1 FROM protocol_templates et
|
||||
WHERE et.protocol_id = (SELECT id FROM protocols WHERE slug = 'awg2' LIMIT 1)
|
||||
AND et.template_name = src.template_name
|
||||
);
|
||||
|
||||
-- 4. Update install_script for existing awg2 protocol (in case migration was already run)
|
||||
UPDATE protocols SET install_script = '#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
CONTAINER_NAME="${SERVER_CONTAINER:-amnezia-awg2}"
|
||||
PORT_RANGE_START=${PORT_RANGE_START:-30000}
|
||||
PORT_RANGE_END=${PORT_RANGE_END:-65000}
|
||||
VPN_PORT="${SERVER_PORT:-$((RANDOM % (PORT_RANGE_END - PORT_RANGE_START + 1) + PORT_RANGE_START))}"
|
||||
MTU=${MTU:-1420}
|
||||
|
||||
if ! command -v git &> /dev/null; then
|
||||
apt-get update -qq && apt-get install -y -qq git >/dev/null 2>&1
|
||||
fi
|
||||
|
||||
mkdir -p /opt/amnezia/awg2
|
||||
|
||||
if [ ! -d /opt/amnezia/awg2/src ]; then
|
||||
git clone --depth=1 https://github.com/amnezia-vpn/amneziawg-go.git /opt/amnezia/awg2/src
|
||||
fi
|
||||
|
||||
docker build --no-cache -t amnezia-awg2 /opt/amnezia/awg2/src
|
||||
|
||||
EXISTING=$(docker ps -aq -f "name=$CONTAINER_NAME" 2>/dev/null | head -1)
|
||||
if [ -z "$EXISTING" ]; then
|
||||
docker run -d --name "$CONTAINER_NAME" --restart always --cap-add=NET_ADMIN --device /dev/net/tun -p "${VPN_PORT}:${VPN_PORT}/udp" -v /opt/amnezia/awg2:/opt/amnezia/awg amnezia-awg2 sh -c "while [ ! -f /opt/amnezia/awg/wg0.conf ]; do sleep 1; done; WG_QUICK_USERSPACE_IMPLEMENTATION=amneziawg-go awg-quick up /opt/amnezia/awg/wg0.conf && sleep infinity"
|
||||
sleep 2
|
||||
else
|
||||
STATUS=$(docker inspect --format="{{.State.Status}}" "$CONTAINER_NAME" 2>/dev/null || echo "")
|
||||
if [ \"$STATUS\" != \"running\" ]; then
|
||||
docker start \"$CONTAINER_NAME\" >/dev/null 2>&1 || true
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -f /opt/amnezia/awg2/wg0.conf ]; then
|
||||
PORT=$(grep -E "^ListenPort" /opt/amnezia/awg2/wg0.conf | cut -d= -f2 | tr -d "[:space:]")
|
||||
PSK=$(cat /opt/amnezia/awg2/wireguard_psk.key 2>/dev/null || true)
|
||||
if [ -z "$PSK" ]; then
|
||||
PSK=$(grep -E "^PresharedKey" /opt/amnezia/awg2/wg0.conf | cut -d= -f2 | tr -d "[:space:]")
|
||||
fi
|
||||
PUBKEY=$(cat /opt/amnezia/awg2/wireguard_server_public_key.key 2>/dev/null || true)
|
||||
if [ -z "$PUBKEY" ]; then
|
||||
PRIVKEY=$(cat /opt/amnezia/awg2/wireguard_server_private_key.key 2>/dev/null || true)
|
||||
if [ -n "$PRIVKEY" ]; then
|
||||
PUBKEY=$(echo "$PRIVKEY" | docker exec -i "$CONTAINER_NAME" wg pubkey)
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "Using existing AmneziaWG 2.0 configuration"
|
||||
echo "Port: ${PORT:-$VPN_PORT}"
|
||||
if [ -n "${PUBKEY:-}" ]; then echo "Server Public Key: $PUBKEY"; fi
|
||||
if [ -n "${PSK:-}" ]; then echo "PresharedKey = $PSK"; fi
|
||||
|
||||
EXTERNAL_IP=$(curl -s -4 ifconfig.me 2>/dev/null || curl -s -4 icanhazip.com 2>/dev/null || echo "YOUR_SERVER_IP")
|
||||
echo "Server Host: $EXTERNAL_IP"
|
||||
|
||||
for P in Jc Jmin Jmax S1 S2 S3 S4 H1 H2 H3 H4; do
|
||||
VAL=$(grep -E "^$P " /opt/amnezia/awg2/wg0.conf | cut -d= -f2 | tr -d "[:space:]")
|
||||
if [ -n "$VAL" ]; then echo "Variable: $P=$VAL"; fi
|
||||
done
|
||||
echo "Variable: dns_servers=1.1.1.1, 1.0.0.1"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
PRIVATE_KEY=$(docker exec "$CONTAINER_NAME" wg genkey)
|
||||
PUBLIC_KEY=$(echo "$PRIVATE_KEY" | docker exec -i "$CONTAINER_NAME" wg pubkey)
|
||||
PRESHARED_KEY=$(docker exec "$CONTAINER_NAME" wg genpsk)
|
||||
|
||||
JC=5
|
||||
JMIN=50
|
||||
JMAX=1000
|
||||
S1_VAL=50
|
||||
S2_VAL=100
|
||||
S3_VAL=20
|
||||
S4_VAL=10
|
||||
H1_VAL="1-4294967295"
|
||||
H2_VAL="1-4294967295"
|
||||
H3_VAL="1-4294967295"
|
||||
H4_VAL="1-4294967295"
|
||||
|
||||
cat > /opt/amnezia/awg2/wg0.conf << EOF
|
||||
[Interface]
|
||||
PrivateKey = $PRIVATE_KEY
|
||||
Address = 10.8.1.1/24
|
||||
ListenPort = $VPN_PORT
|
||||
MTU = $MTU
|
||||
Jc = $JC
|
||||
Jmin = $JMIN
|
||||
Jmax = $JMAX
|
||||
S1 = $S1_VAL
|
||||
S2 = $S2_VAL
|
||||
S3 = $S3_VAL
|
||||
S4 = $S4_VAL
|
||||
H1 = $H1_VAL
|
||||
H2 = $H2_VAL
|
||||
H3 = $H3_VAL
|
||||
H4 = $H4_VAL
|
||||
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
|
||||
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
|
||||
|
||||
[Peer]
|
||||
PublicKey =
|
||||
PresharedKey = $PRESHARED_KEY
|
||||
AllowedIPs = 10.8.1.2/32
|
||||
EOF
|
||||
|
||||
echo "$PRIVATE_KEY" > /opt/amnezia/awg2/wireguard_server_private_key.key
|
||||
echo "$PUBLIC_KEY" > /opt/amnezia/awg2/wireguard_server_public_key.key
|
||||
echo "$PRESHARED_KEY" > /opt/amnezia/awg2/wireguard_psk.key
|
||||
echo "[]" > /opt/amnezia/awg2/clientsTable
|
||||
|
||||
EXTERNAL_IP=$(curl -s -4 ifconfig.me 2>/dev/null || curl -s -4 icanhazip.com 2>/dev/null || echo "YOUR_SERVER_IP")
|
||||
|
||||
echo "AmneziaWG 2.0 installed successfully"
|
||||
echo "Port: $VPN_PORT"
|
||||
echo "Server Public Key: $PUBLIC_KEY"
|
||||
echo "PresharedKey = $PRESHARED_KEY"
|
||||
echo "Server Host: $EXTERNAL_IP"
|
||||
echo "Variable: Jc=$JC"
|
||||
echo "Variable: Jmin=$JMIN"
|
||||
echo "Variable: Jmax=$JMAX"
|
||||
echo "Variable: S1=$S1_VAL"
|
||||
echo "Variable: S2=$S2_VAL"
|
||||
echo "Variable: S3=$S3_VAL"
|
||||
echo "Variable: S4=$S4_VAL"
|
||||
echo "Variable: H1=$H1_VAL"
|
||||
echo "Variable: H2=$H2_VAL"
|
||||
echo "Variable: H3=$H3_VAL"
|
||||
echo "Variable: H4=$H4_VAL"
|
||||
echo "Variable: dns_servers=1.1.1.1, 1.0.0.1"'
|
||||
WHERE slug = 'awg2';
|
||||
|
||||
-- 5. Update output_template for AWG2 (add S3/S4 padding params)
|
||||
UPDATE protocols SET output_template = '[Interface]
|
||||
PrivateKey = {{private_key}}
|
||||
Address = {{client_ip}}/32
|
||||
DNS = {{dns_servers}}
|
||||
MTU = 1280
|
||||
Jc = {{Jc}}
|
||||
Jmin = {{Jmin}}
|
||||
Jmax = {{Jmax}}
|
||||
S1 = {{S1}}
|
||||
S2 = {{S2}}
|
||||
S3 = {{S3}}
|
||||
S4 = {{S4}}
|
||||
H1 = {{H1}}
|
||||
H2 = {{H2}}
|
||||
H3 = {{H3}}
|
||||
H4 = {{H4}}
|
||||
|
||||
[Peer]
|
||||
PublicKey = {{server_public_key}}
|
||||
PresharedKey = {{preshared_key}}
|
||||
AllowedIPs = 0.0.0.0/0, ::/0
|
||||
Endpoint = {{server_host}}:{{server_port}}
|
||||
PersistentKeepalive = 25'
|
||||
WHERE slug = 'awg2';
|
||||
|
||||
-- 6. Add S3/S4 protocol variables for awg2
|
||||
INSERT INTO protocol_variables (protocol_id, variable_name, variable_type, default_value, description, required)
|
||||
SELECT p.id, 'S3', 'number', '20', 'Padding of handshake cookie message', false
|
||||
FROM protocols p WHERE p.slug = 'awg2'
|
||||
AND NOT EXISTS (SELECT 1 FROM protocol_variables WHERE protocol_id = p.id AND variable_name = 'S3');
|
||||
|
||||
INSERT INTO protocol_variables (protocol_id, variable_name, variable_type, default_value, description, required)
|
||||
SELECT p.id, 'S4', 'number', '10', 'Padding of transport messages', false
|
||||
FROM protocols p WHERE p.slug = 'awg2'
|
||||
AND NOT EXISTS (SELECT 1 FROM protocol_variables WHERE protocol_id = p.id AND variable_name = 'S4');
|
||||
@@ -0,0 +1,113 @@
|
||||
-- =====================================================================
|
||||
-- Migration 059: Add MTProxy (Telegram) protocol
|
||||
-- https://hub.docker.com/r/telegrammessenger/proxy/
|
||||
-- Zero-configuration Telegram MTProto proxy server
|
||||
-- =====================================================================
|
||||
|
||||
-- 1. Insert the MTProxy 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
|
||||
'MTProxy (Telegram)',
|
||||
'mtproxy',
|
||||
'Telegram MTProto proxy — zero-configuration proxy server for Telegram messenger.',
|
||||
'#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
# Use exported variables from panel (SERVER_PORT, SERVER_CONTAINER) or defaults
|
||||
CONTAINER_NAME="${SERVER_CONTAINER:-amnezia-mtproxy}"
|
||||
PORT_RANGE_START=${PORT_RANGE_START:-30000}
|
||||
PORT_RANGE_END=${PORT_RANGE_END:-65000}
|
||||
MTPROXY_PORT="${SERVER_PORT:-$((RANDOM % (PORT_RANGE_END - PORT_RANGE_START + 1) + PORT_RANGE_START))}"
|
||||
|
||||
mkdir -p /opt/amnezia/mtproxy
|
||||
|
||||
# Generate secret if not exists
|
||||
if [ -f /opt/amnezia/mtproxy/secret ]; then
|
||||
SECRET=$(cat /opt/amnezia/mtproxy/secret)
|
||||
echo "Using existing MTProxy secret"
|
||||
else
|
||||
SECRET=$(cat /dev/urandom | tr -dc a-f0-9 | head -c 32 || true)
|
||||
echo "$SECRET" > /opt/amnezia/mtproxy/secret
|
||||
fi
|
||||
|
||||
# Store port
|
||||
echo "$MTPROXY_PORT" > /opt/amnezia/mtproxy/port
|
||||
|
||||
# Remove existing container
|
||||
docker rm -f "$CONTAINER_NAME" >/dev/null 2>&1 || true
|
||||
|
||||
# Run MTProxy container (single line for heredoc compatibility)
|
||||
docker run -d --name "$CONTAINER_NAME" --restart always -p "${MTPROXY_PORT}:443" -v /opt/amnezia/mtproxy:/data -e SECRET="$SECRET" telegrammessenger/proxy:latest
|
||||
|
||||
sleep 3
|
||||
|
||||
# Get 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 "MTProxy installed successfully"
|
||||
echo "Port: $MTPROXY_PORT"
|
||||
echo "Secret: $SECRET"
|
||||
echo "Server Host: $EXTERNAL_IP"',
|
||||
'#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
CONTAINER_NAME="${CONTAINER_NAME:-amnezia-mtproxy}"
|
||||
|
||||
docker stop "$CONTAINER_NAME" 2>/dev/null || true
|
||||
docker rm -fv "$CONTAINER_NAME" 2>/dev/null || true
|
||||
docker image rm telegrammessenger/proxy:latest 2>/dev/null || true
|
||||
rm -rf /opt/amnezia/mtproxy 2>/dev/null || true
|
||||
|
||||
echo "{\"success\":true,\"message\":\"MTProxy uninstalled\"}"',
|
||||
'tg://proxy?server={{server_host}}&port={{server_port}}&secret={{secret}}',
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
JSON_OBJECT(
|
||||
'engine', 'shell',
|
||||
'metadata', JSON_OBJECT(
|
||||
'container_name', 'amnezia-mtproxy',
|
||||
'port_range', JSON_ARRAY(30000, 65000),
|
||||
'config_dir', '/opt/amnezia/mtproxy'
|
||||
)
|
||||
),
|
||||
NOW(),
|
||||
NOW()
|
||||
WHERE NOT EXISTS (SELECT 1 FROM protocols WHERE slug = 'mtproxy');
|
||||
|
||||
-- 2. Add protocol variables for MTProxy
|
||||
INSERT INTO protocol_variables (protocol_id, variable_name, variable_type, default_value, description, required)
|
||||
SELECT p.id, 'secret', 'string', '', 'MTProxy secret (32 hex chars)', true
|
||||
FROM protocols p WHERE p.slug = 'mtproxy'
|
||||
AND NOT EXISTS (SELECT 1 FROM protocol_variables WHERE protocol_id = p.id AND variable_name = 'secret');
|
||||
|
||||
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 = 'mtproxy'
|
||||
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, 'server_port', 'number', '443', 'MTProxy external port', true
|
||||
FROM protocols p WHERE p.slug = 'mtproxy'
|
||||
AND NOT EXISTS (SELECT 1 FROM protocol_variables WHERE protocol_id = p.id AND variable_name = 'server_port');
|
||||
|
||||
-- 3. Add default template for MTProxy
|
||||
INSERT INTO protocol_templates (protocol_id, template_name, template_content, is_default)
|
||||
SELECT p.id, 'Default MTProxy', 'tg://proxy?server={{server_host}}&port={{server_port}}&secret={{secret}}', true
|
||||
FROM protocols p WHERE p.slug = 'mtproxy'
|
||||
AND NOT EXISTS (SELECT 1 FROM protocol_templates WHERE protocol_id = p.id AND template_name = 'Default MTProxy');
|
||||
|
||||
-- 4. Add QR code template (same as output)
|
||||
UPDATE protocols SET
|
||||
qr_code_template = 'tg://proxy?server={{server_host}}&port={{server_port}}&secret={{secret}}',
|
||||
qr_code_format = 'raw'
|
||||
WHERE slug = 'mtproxy';
|
||||
|
||||
-- 5. Add translations for MTProxy
|
||||
INSERT INTO translations (locale, category, key_name, translation) VALUES
|
||||
('en', 'protocols', 'protocol_mtproxy', 'MTProxy (Telegram)')
|
||||
ON DUPLICATE KEY UPDATE translation = VALUES(translation);
|
||||
|
||||
INSERT INTO translations (locale, category, key_name, translation) VALUES
|
||||
('ru', 'protocols', 'protocol_mtproxy', 'MTProxy (Telegram)')
|
||||
ON DUPLICATE KEY UPDATE translation = VALUES(translation);
|
||||
@@ -0,0 +1,153 @@
|
||||
-- =====================================================================
|
||||
-- Migration 060: Add AIVPN protocol (AI-powered VPN with traffic disguise)
|
||||
-- https://github.com/infosave2007/aivpn
|
||||
-- Neural Resonance AI for DPI bypass, Zero-RTT, PFS
|
||||
-- =====================================================================
|
||||
|
||||
-- 1. Insert the AIVPN 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
|
||||
'AIVPN',
|
||||
'aivpn',
|
||||
'AIVPN — AI-powered VPN с маскировкой трафика под реальные приложения (Zoom, TikTok, DNS). Neural Resonance для обхода DPI.',
|
||||
'#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
# Use exported variables from panel (SERVER_PORT, SERVER_CONTAINER) or defaults
|
||||
CONTAINER_NAME="${SERVER_CONTAINER:-aivpn-server}"
|
||||
VPN_PORT="${SERVER_PORT:-443}"
|
||||
CONFIG_DIR="/etc/aivpn"
|
||||
|
||||
# Install git and iptables if not available
|
||||
if ! command -v git &> /dev/null || ! command -v iptables &> /dev/null; then
|
||||
apt-get update -qq
|
||||
if ! command -v git &> /dev/null; then
|
||||
apt-get install -y -qq git >/dev/null 2>&1
|
||||
fi
|
||||
if ! command -v iptables &> /dev/null; then
|
||||
apt-get install -y -qq iptables >/dev/null 2>&1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Install Docker if not available
|
||||
if ! command -v docker &> /dev/null; then
|
||||
apt-get update -qq
|
||||
apt-get install -y -qq apt-transport-https ca-certificates curl gnupg lsb-release >/dev/null 2>&1
|
||||
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
|
||||
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" > /etc/apt/sources.list.d/docker.list
|
||||
apt-get update -qq && apt-get install -y -qq docker-ce docker-ce-cli containerd.io >/dev/null 2>&1
|
||||
fi
|
||||
|
||||
mkdir -p "$CONFIG_DIR"
|
||||
|
||||
# Enable IP forwarding
|
||||
sysctl -w net.ipv4.ip_forward=1 2>/dev/null || true
|
||||
|
||||
# Generate server key if not exists
|
||||
if [ ! -f "$CONFIG_DIR/server.key" ]; then
|
||||
openssl rand 32 > "$CONFIG_DIR/server.key"
|
||||
chmod 600 "$CONFIG_DIR/server.key"
|
||||
echo "Generated new AIVPN server key"
|
||||
else
|
||||
echo "Using existing AIVPN server key"
|
||||
fi
|
||||
|
||||
# Setup NAT
|
||||
iptables -t nat -C POSTROUTING -s 10.0.0.0/24 -o eth0 -j MASQUERADE 2>/dev/null || \
|
||||
iptables -t nat -A POSTROUTING -s 10.0.0.0/24 -o eth0 -j MASQUERADE
|
||||
|
||||
# Get external IP
|
||||
EXTERNAL_IP=$(curl -s -4 ifconfig.me 2>/dev/null || curl -s -4 icanhazip.com 2>/dev/null || echo "YOUR_SERVER_IP")
|
||||
|
||||
# Clone AIVPN source for Docker build
|
||||
if [ ! -d /opt/amnezia/aivpn ]; then
|
||||
git clone --depth=1 https://github.com/infosave2007/aivpn.git /opt/amnezia/aivpn
|
||||
fi
|
||||
|
||||
# Build Docker image
|
||||
cd /opt/amnezia/aivpn
|
||||
docker build --no-cache -t aivpn-server -f Dockerfile .
|
||||
|
||||
# Remove existing container
|
||||
docker rm -f "$CONTAINER_NAME" >/dev/null 2>&1 || true
|
||||
|
||||
# Run AIVPN container
|
||||
docker run -d --name "$CONTAINER_NAME" --restart always --cap-add=NET_ADMIN --device /dev/net/tun --network host -v "$CONFIG_DIR:/etc/aivpn" aivpn-server --listen "0.0.0.0:${VPN_PORT}" --key-file /etc/aivpn/server.key
|
||||
|
||||
sleep 3
|
||||
|
||||
# Check container status
|
||||
STATUS=$(docker inspect --format="{{.State.Status}}" "$CONTAINER_NAME" 2>/dev/null || echo "unknown")
|
||||
if [ "$STATUS" != "running" ]; then
|
||||
echo "ERROR: AIVPN container is not running"
|
||||
docker logs "$CONTAINER_NAME" 2>&1
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "AIVPN installed successfully"
|
||||
echo "Port: $VPN_PORT"
|
||||
echo "ExternalIP: $EXTERNAL_IP"
|
||||
echo "ConfigDir: $CONFIG_DIR"',
|
||||
'#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
CONTAINER_NAME="${CONTAINER_NAME:-aivpn-server}"
|
||||
|
||||
docker stop "$CONTAINER_NAME" 2>/dev/null || true
|
||||
docker rm -fv "$CONTAINER_NAME" 2>/dev/null || true
|
||||
docker image rm aivpn-server 2>/dev/null || true
|
||||
rm -rf /opt/amnezia/aivpn 2>/dev/null || true
|
||||
|
||||
# Remove NAT rules
|
||||
iptables -t nat -D POSTROUTING -s 10.0.0.0/24 -o eth0 -j MASQUERADE 2>/dev/null || true
|
||||
|
||||
echo "{\"success\":true,\"message\":\"AIVPN uninstalled\"}"',
|
||||
'aivpn://{{connection_key}}',
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
JSON_OBJECT(
|
||||
'engine', 'shell',
|
||||
'metadata', JSON_OBJECT(
|
||||
'container_name', 'aivpn-server',
|
||||
'port_range', JSON_ARRAY(443, 443),
|
||||
'config_dir', '/etc/aivpn',
|
||||
'vpn_subnet', '10.0.0.0/24',
|
||||
'requires_docker_build', true,
|
||||
'git_repo', 'https://github.com/infosave2007/aivpn.git'
|
||||
)
|
||||
),
|
||||
NOW(),
|
||||
NOW()
|
||||
WHERE NOT EXISTS (SELECT 1 FROM protocols WHERE slug = 'aivpn');
|
||||
|
||||
-- 2. Add protocol variables for AIVPN
|
||||
INSERT INTO protocol_variables (protocol_id, variable_name, variable_type, default_value, description, required)
|
||||
SELECT p.id, 'connection_key', 'string', '', 'AIVPN connection key (generated by server)', true
|
||||
FROM protocols p WHERE p.slug = 'aivpn'
|
||||
AND NOT EXISTS (SELECT 1 FROM protocol_variables WHERE protocol_id = p.id AND variable_name = 'connection_key');
|
||||
|
||||
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 = 'aivpn'
|
||||
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, 'server_port', 'number', '443', 'AIVPN server port', true
|
||||
FROM protocols p WHERE p.slug = 'aivpn'
|
||||
AND NOT EXISTS (SELECT 1 FROM protocol_variables WHERE protocol_id = p.id AND variable_name = 'server_port');
|
||||
|
||||
-- 3. Add default template for AIVPN
|
||||
INSERT INTO protocol_templates (protocol_id, template_name, template_content, is_default)
|
||||
SELECT p.id, 'Default AIVPN', 'aivpn://{{connection_key}}', true
|
||||
FROM protocols p WHERE p.slug = 'aivpn'
|
||||
AND NOT EXISTS (SELECT 1 FROM protocol_templates WHERE protocol_id = p.id AND template_name = 'Default AIVPN');
|
||||
|
||||
-- 4. Add translations for AIVPN
|
||||
INSERT INTO translations (locale, category, key_name, translation) VALUES
|
||||
('en', 'protocols', 'protocol_aivpn', 'AIVPN (AI-Powered)')
|
||||
ON DUPLICATE KEY UPDATE translation = VALUES(translation);
|
||||
|
||||
INSERT INTO translations (locale, category, key_name, translation) VALUES
|
||||
('ru', 'protocols', 'protocol_aivpn', 'AIVPN (ИИ-протокол)')
|
||||
ON DUPLICATE KEY UPDATE translation = VALUES(translation);
|
||||
Reference in New Issue
Block a user