VPN en línea Cheatsheet
"Clase de la hoja" id="copy-btn" class="copy-btn" onclick="copyAllCommands()" Copiar todos los comandos de VPN en línea id="pdf-btn" class="pdf-btn" onclick="generatePDF()" Generar la guía de PDF VPN en línea ■/div titulada
Outline VPN es una solución VPN de código abierto desarrollada por Jigsaw (una subsidiaria de Alphabet Inc.) que prioriza la facilidad de uso, seguridad y resistencia al bloqueo. Construido en el protocolo Shadowsocks, Outline proporciona una manera sencilla de crear y gestionar servidores VPN personales mientras ofrece capacidades fuertes de encriptación y obfuscación que dificultan la detección y bloqueo del tráfico VPN.
Panorama general de la Plataforma
Filosofía de Arquitectura y Diseño
Esquema VPN consta de dos componentes principales: el Administrador de Esquemas para la administración del servidor y el Cliente Esquemático para la conectividad de usuario final. El sistema está diseñado con sencillez y seguridad como principios fundamentales, lo que hace que sea accesible a los usuarios sin conocimientos técnicos amplios, manteniendo al mismo tiempo normas de seguridad a nivel empresarial.
El Administrador de Esquemas es una aplicación de escritorio que permite a los administradores desplegar y gestionar servidores de Esquema en varias plataformas de nube, incluyendo DigitalOcean, Google Cloud Platform, Amazon Web Services, y Vultr. El administrador maneja el suministro de servidores, generación de claves de usuario y monitoreo de tráfico a través de una interfaz gráfica intuitiva.
Las aplicaciones Outline Client están disponibles para plataformas Windows, macOS, Linux, iOS y Android. Estos clientes utilizan las claves de acceso generadas para establecer conexiones seguras a servidores Outline, proporcionando túneles cifrados para todo el tráfico de red.
Características clave
# Core Outline VPN Capabilities
- Shadowsocks-based protocol for enhanced obfuscation
- Automatic server deployment on major cloud platforms
- Simple access key sharing system
- Cross-platform client applications
- Traffic monitoring and usage analytics
- Resistance to deep packet inspection (DPI)
- No logging policy and privacy-focused design
- Open-source transparency and auditability
Instalación y configuración del servidor
Instalación manual del servidor
# Install Outline server on Ubuntu/Debian
curl -sS https://raw.githubusercontent.com/Jigsaw-Code/outline-server/master/src/server_manager/install_scripts/install_server.sh|bash
# The installation script will:
# 1. Install Docker and Docker Compose
# 2. Download and run the Outline server container
# 3. Generate initial configuration
# 4. Display management API URL and certificate fingerprint
# Verify installation
sudo docker ps|grep outline
# Check server status
sudo docker logs outline-server
# View server configuration
sudo cat /opt/outline/access.txt
# Manual Docker installation (alternative method)
sudo docker run -d \
--name outline-server \
--restart unless-stopped \
-p 443:443/tcp \
-p 443:443/udp \
-p 8080:8080/tcp \
-v outline-data:/root/shadowbox/persisted-state \
quay.io/outline/shadowbox:stable
# Configure firewall for Outline server
sudo ufw allow 443/tcp
sudo ufw allow 443/udp
sudo ufw allow 8080/tcp
sudo ufw enable
# Enable IP forwarding
echo 'net.ipv4.ip_forward=1'|sudo tee -a /etc/sysctl.conf
echo 'net.ipv6.conf.all.forwarding=1'|sudo tee -a /etc/sysctl.conf
sudo sysctl -p
Despliegue de la plataforma en la nube
# DigitalOcean deployment script
#!/bin/bash
DROPLET_NAME="outline-vpn-server"
REGION="nyc3"
SIZE="s-1vcpu-1gb"
IMAGE="ubuntu-20-04-x64"
# Create droplet
doctl compute droplet create $DROPLET_NAME \
--region $REGION \
--size $SIZE \
--image $IMAGE \
--ssh-keys $(doctl compute ssh-key list --format ID --no-header|tr '\n' ',') \
--wait
# Get droplet IP
DROPLET_IP=$(doctl compute droplet list --format Name,PublicIPv4 --no-header|grep $DROPLET_NAME|awk '\\\\{print $2\\\\}')
# Install Outline server
ssh root@$DROPLET_IP 'curl -sS https://raw.githubusercontent.com/Jigsaw-Code/outline-server/master/src/server_manager/install_scripts/install_server.sh|bash'
# AWS EC2 deployment with Terraform
cat > outline-server.tf ``<< 'EOF'
provider "aws" \\\{
region = "us-east-1"
\\\}
resource "aws_instance" "outline_server" \\\{
ami = "ami-0c02fb55956c7d316" # Ubuntu 20.04 LTS
instance_type = "t3.micro"
key_name = "your-key-pair"
vpc_security_group_ids = [aws_security_group.outline_sg.id]
user_data = <<-EOF
#!/bin/bash
curl -sS https://raw.githubusercontent.com/Jigsaw-Code/outline-server/master/src/server_manager/install_scripts/install_server.sh|bash
EOF
tags = \\\{
Name = "Outline VPN Server"
\\\}
\\\}
resource "aws_security_group" "outline_sg" \\\{
name_prefix = "outline-server-"
ingress \\\{
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
\\\}
ingress \\\{
from_port = 443
to_port = 443
protocol = "udp"
cidr_blocks = ["0.0.0.0/0"]
\\\}
ingress \\\{
from_port = 8080
to_port = 8080
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
\\\}
ingress \\\{
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
\\\}
egress \\\{
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
\\\}
\\\}
output "server_ip" \\\{
value = aws_instance.outline_server.public_ip
\\\}
EOF
# Deploy with Terraform
terraform init
terraform plan
terraform apply
Docker Compose Setup
# docker-compose.yml for Outline server
version: '3.8'
services:
outline-server:
image: quay.io/outline/shadowbox:stable
container_name: outline-server
restart: unless-stopped
ports:
- "443:443/tcp"
- "443:443/udp"
- "8080:8080/tcp"
volumes:
- outline-data:/root/shadowbox/persisted-state
- /etc/letsencrypt:/etc/letsencrypt:ro
environment:
- SB_API_PORT=8080
- SB_CERTIFICATE_FILE=/etc/letsencrypt/live/your-domain.com/fullchain.pem
- SB_PRIVATE_KEY_FILE=/etc/letsencrypt/live/your-domain.com/privkey.pem
networks:
- outline-network
watchtower:
image: containrrr/watchtower
container_name: outline-watchtower
restart: unless-stopped
volumes:
- /var/run/docker.sock:/var/run/docker.sock
command: --interval 86400 outline-server
networks:
- outline-network
volumes:
outline-data:
networks:
outline-network:
driver: bridge
Configuración del administrador de línea
Configuración inicial y conexión de servidor
# Download Outline Manager
# Windows: https://github.com/Jigsaw-Code/outline-client/releases/latest/download/Outline-Manager.exe
# macOS: https://github.com/Jigsaw-Code/outline-client/releases/latest/download/Outline-Manager.dmg
# Linux: https://github.com/Jigsaw-Code/outline-client/releases/latest/download/Outline-Manager.AppImage
# Connect to existing server using management API
# Format: https://server-ip:8080/management-api-url
# Example connection string from server installation:
# \\\{"apiUrl":"https://192.168.1.100:8080/management-api-url","certSha256":"certificate-fingerprint"\\\}
# Verify server connection
curl -k -H "Content-Type: application/json" \
"https://your-server-ip:8080/management-api-url/server"
# Get server information
curl -k -H "Content-Type: application/json" \
"https://your-server-ip:8080/management-api-url/server/info"
# Example response:
# \\\{
# "name": "Outline Server",
# "serverId": "server-id-123",
# "metricsEnabled": true,
# "createdTimestampMs": 1640995200000,
# "version": "1.8.0",
# "accessKeyDataLimit": null,
# "portForNewAccessKeys": 443
# \\\}
Access Key Management
# Create new access key
curl -k -X POST \
-H "Content-Type: application/json" \
"https://your-server-ip:8080/management-api-url/access-keys"
# Example response:
# \\\{
# "id": "0",
# "name": "User 1",
# "password": "password123",
# "port": 443,
# "method": "chacha20-ietf-poly1305",
# "accessUrl": "ss://Y2hhY2hhMjAtaWV0Zi1wb2x5MTMwNTpwYXNzd29yZDEyMw@192.168.1.100:443/?outline=1"
# \\\}
# List all access keys
curl -k -H "Content-Type: application/json" \
"https://your-server-ip:8080/management-api-url/access-keys"
# Rename access key
curl -k -X PUT \
-H "Content-Type: application/json" \
-d '\\\{"name": "John Doe"\\\}' \
"https://your-server-ip:8080/management-api-url/access-keys/0/name"
# Set data limit for access key (in bytes)
curl -k -X PUT \
-H "Content-Type: application/json" \
-d '\\\{"limit": \\\{"bytes": 10737418240\\\}\\\}' \
"https://your-server-ip:8080/management-api-url/access-keys/0/data-limit"
# Remove data limit
curl -k -X DELETE \
"https://your-server-ip:8080/management-api-url/access-keys/0/data-limit"
# Delete access key
curl -k -X DELETE \
"https://your-server-ip:8080/management-api-url/access-keys/0"
# Get access key metrics
curl -k -H "Content-Type: application/json" \
"https://your-server-ip:8080/management-api-url/metrics/transfer"
# Example metrics response:
# \\\{
# "bytesTransferredByUserId": \\\{
# "0": 1073741824,
# "1": 2147483648
# \\\}
# \\\}
Configuración del servidor
# Change server name
curl -k -X PUT \
-H "Content-Type: application/json" \
-d '\\\{"name": "Company VPN Server"\\\}' \
"https://your-server-ip:8080/management-api-url/server/name"
# Set default port for new access keys
curl -k -X PUT \
-H "Content-Type: application/json" \
-d '\\\{"port": 8443\\\}' \
"https://your-server-ip:8080/management-api-url/server/port-for-new-access-keys"
# Enable/disable metrics collection
curl -k -X PUT \
-H "Content-Type: application/json" \
-d '\\\{"metricsEnabled": true\\\}' \
"https://your-server-ip:8080/management-api-url/server/metrics-enabled"
# Set server-wide data limit
curl -k -X PUT \
-H "Content-Type: application/json" \
-d '\\\{"limit": \\\{"bytes": 107374182400\\\}\\\}' \
"https://your-server-ip:8080/management-api-url/server/access-key-data-limit"
# Get server configuration
curl -k -H "Content-Type: application/json" \
"https://your-server-ip:8080/management-api-url/server"
Configuración y uso del cliente
Configuración del cliente de Windows
# Download and install Outline Client for Windows
$OutlineClientUrl = "https://github.com/Jigsaw-Code/outline-client/releases/latest/download/Outline-Client.exe"
$OutlineClientPath = "$env:TEMP\Outline-Client.exe"
Invoke-WebRequest -Uri $OutlineClientUrl -OutFile $OutlineClientPath
Start-Process -FilePath $OutlineClientPath -Wait
# Import access key via command line (if supported)
# Note: Outline Client primarily uses GUI for key import
# Access key format: ss://base64-encoded-config@server:port/?outline=1
# Example access key:
# ss://Y2hhY2hhMjAtaWV0Zi1wb2x5MTMwNTpwYXNzd29yZDEyMw@192.168.1.100:443/?outline=1
# Registry settings for Outline Client (advanced configuration)
$OutlineRegPath = "HKCU:\Software\Outline"
if (!(Test-Path $OutlineRegPath)) \\\{
New-Item -Path $OutlineRegPath -Force
\\\}
# Set auto-connect on startup
Set-ItemProperty -Path $OutlineRegPath -Name "AutoConnect" -Value 1
# Configure proxy settings
Set-ItemProperty -Path $OutlineRegPath -Name "ProxyMode" -Value "auto"
MacOS Client Setup
# Download Outline Client for macOS
curl -L -o "Outline-Client.dmg" \
"https://github.com/Jigsaw-Code/outline-client/releases/latest/download/Outline-Client.dmg"
# Mount and install
hdiutil mount Outline-Client.dmg
cp -R "/Volumes/Outline Client/Outline Client.app" /Applications/
hdiutil unmount "/Volumes/Outline Client"
# Launch Outline Client
open "/Applications/Outline Client.app"
# Import access key via URL scheme (if supported)
open "ss://Y2hhY2hhMjAtaWV0Zi1wb2x5MTMwNTpwYXNzd29yZDEyMw@192.168.1.100:443/?outline=1"
# Configure system proxy settings
networksetup -setautoproxyurl "Wi-Fi" "http://127.0.0.1:1080/proxy.pac"
# Check VPN connection status
scutil --nc list|grep -i outline
Configuración de cliente de Linux
# Download Outline Client AppImage
wget -O Outline-Client.AppImage \
"https://github.com/Jigsaw-Code/outline-client/releases/latest/download/Outline-Client.AppImage"
chmod +x Outline-Client.AppImage
# Run Outline Client
./Outline-Client.AppImage
# Alternative: Install via Snap
sudo snap install outline-client
# Create desktop entry
cat >`` ~/.local/share/applications/outline-client.desktop ``<< 'EOF'
[Desktop Entry]
Name=Outline Client
Comment=Outline VPN Client
Exec=/path/to/Outline-Client.AppImage
Icon=outline-client
Terminal=false
Type=Application
Categories=Network;Security;
EOF
# Configure system-wide proxy (Ubuntu/Debian)
gsettings set org.gnome.system.proxy mode 'auto'
gsettings set org.gnome.system.proxy autoconfig-url 'http://127.0.0.1:1080/proxy.pac'
# Configure iptables for VPN traffic (advanced)
sudo iptables -t nat -A OUTPUT -p tcp --dport 80 -j REDIRECT --to-port 1080
sudo iptables -t nat -A OUTPUT -p tcp --dport 443 -j REDIRECT --to-port 1080
Configuración del cliente móvil
# iOS Configuration
# 1. Download Outline app from App Store
# 2. Tap "Add Server" or "+"
# 3. Scan QR code or paste access key
# 4. Tap "Connect"
# Generate QR code for access key (server-side)
qrencode -t PNG -o access-key-qr.png \
"ss://Y2hhY2hhMjAtaWV0Zi1wb2x5MTMwNTpwYXNzd29yZDEyMw@192.168.1.100:443/?outline=1"
# Android Configuration
# 1. Download Outline app from Google Play Store
# 2. Tap "Add Server"
# 3. Scan QR code or manually enter access key
# 4. Tap "Connect"
# Android ADB commands for automation (requires root)
adb shell am start -a android.intent.action.VIEW \
-d "ss://Y2hhY2hhMjAtaWV0Zi1wb2x5MTMwNTpwYXNzd29yZDEyMw@192.168.1.100:443/?outline=1" \
org.outline.android.client
Configuración avanzada
Sombras aduaneras Configuración
# Manual Shadowsocks server configuration
cat >`` /etc/shadowsocks-libev/config.json << 'EOF'
\\\\{
"server": "0.0.0.0",
"server_port": 443,
"password": "your-strong-password",
"timeout": 300,
"method": "chacha20-ietf-poly1305",
"fast_open": false,
"workers": 1,
"prefer_ipv6": false,
"no_delay": true,
"reuse_port": true,
"mode": "tcp_and_udp"
\\\\}
EOF
# Install Shadowsocks-libev
sudo apt update
sudo apt install shadowsocks-libev
# Start Shadowsocks server
sudo systemctl enable shadowsocks-libev
sudo systemctl start shadowsocks-libev
# Configure multiple ports for load balancing
cat > /etc/shadowsocks-libev/multi-port.json << 'EOF'
\\\\{
"server": "0.0.0.0",
"port_password": \\\\{
"443": "password1",
"8443": "password2",
"9443": "password3"
\\\\},
"timeout": 300,
"method": "chacha20-ietf-poly1305",
"fast_open": false
\\\\}
EOF
# Advanced obfuscation with simple-obfs
sudo apt install simple-obfs
cat > /etc/shadowsocks-libev/obfs-config.json << 'EOF'
\\\\{
"server": "0.0.0.0",
"server_port": 443,
"password": "your-password",
"timeout": 300,
"method": "chacha20-ietf-poly1305",
"plugin": "obfs-server",
"plugin_opts": "obfs=tls;obfs-host=www.google.com"
\\\\}
EOF
Equilibrio de carga y alta disponibilidad
# HAProxy configuration for multiple Outline servers
cat > /etc/haproxy/haproxy.cfg << 'EOF'
global
daemon
maxconn 4096
defaults
mode tcp
timeout connect 5000ms
timeout client 50000ms
timeout server 50000ms
frontend outline_frontend
bind *:443
default_backend outline_servers
backend outline_servers
balance roundrobin
server outline1 192.168.1.101:443 check
server outline2 192.168.1.102:443 check
server outline3 192.168.1.103:443 check
EOF
# Start HAProxy
sudo systemctl enable haproxy
sudo systemctl start haproxy
# Nginx stream proxy for load balancing
cat > /etc/nginx/nginx.conf << 'EOF'
events \\\\{
worker_connections 1024;
\\\\}
stream \\\\{
upstream outline_backend \\\\{
server 192.168.1.101:443;
server 192.168.1.102:443;
server 192.168.1.103:443;
\\\\}
server \\\\{
listen 443;
proxy_pass outline_backend;
proxy_timeout 1s;
proxy_responses 1;
\\\\}
\\\\}
EOF
# Keepalived for high availability
cat > /etc/keepalived/keepalived.conf << 'EOF'
vrrp_script chk_outline \\\\{
script "/usr/local/bin/check_outline.sh"
interval 2
weight -2
fall 3
rise 2
\\\\}
vrrp_instance VI_1 \\\\{
state MASTER
interface eth0
virtual_router_id 51
priority 101
advert_int 1
authentication \\\\{
auth_type PASS
auth_pass outline123
\\\\}
virtual_ipaddress \\\\{
192.168.1.100
\\\\}
track_script \\\\{
chk_outline
\\\\}
\\\\}
EOF
# Health check script
cat > /usr/local/bin/check_outline.sh << 'EOF'
#!/bin/bash
curl -k --connect-timeout 5 https://localhost:8080/management-api-url/server >/dev/null 2>&1
exit $?
EOF
chmod +x /usr/local/bin/check_outline.sh
Hardening de seguridad
# Firewall configuration with iptables
#!/bin/bash
# Flush existing rules
iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X
# Default policies
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
# Allow loopback
iptables -A INPUT -i lo -j ACCEPT
# Allow established connections
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# Allow SSH (change port as needed)
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
# Allow Outline VPN
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
iptables -A INPUT -p udp --dport 443 -j ACCEPT
iptables -A INPUT -p tcp --dport 8080 -s 192.168.1.0/24 -j ACCEPT
# Enable NAT for VPN clients
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
iptables -A FORWARD -i tun+ -j ACCEPT
iptables -A FORWARD -o tun+ -j ACCEPT
# Rate limiting for SSH
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --set
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 60 --hitcount 4 -j DROP
# Save rules
iptables-save > /etc/iptables/rules.v4
# Fail2ban configuration for additional security
cat > /etc/fail2ban/jail.local << 'EOF'
[DEFAULT]
bantime = 3600
findtime = 600
maxretry = 3
[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
[outline-api]
enabled = true
port = 8080
filter = outline-api
logpath = /var/log/outline/access.log
maxretry = 5
EOF
# Create custom filter for Outline API
cat > /etc/fail2ban/filter.d/outline-api.conf << 'EOF'
[Definition]
failregex = ^<HOST> - - \[.*\] ".*" 40[13] .*$
ignoreregex =
EOF
# SSL/TLS certificate with Let's Encrypt
sudo apt install certbot
# Generate certificate
sudo certbot certonly --standalone -d your-domain.com
# Configure automatic renewal
echo "0 12 * * * /usr/bin/certbot renew --quiet"|sudo crontab -
# Update Outline server to use SSL certificate
sudo docker exec outline-server \
sh -c 'echo "SB_CERTIFICATE_FILE=/etc/letsencrypt/live/your-domain.com/fullchain.pem" >> /opt/outline/environment'
sudo docker exec outline-server \
sh -c 'echo "SB_PRIVATE_KEY_FILE=/etc/letsencrypt/live/your-domain.com/privkey.pem" >> /opt/outline/environment'
sudo docker restart outline-server
Vigilancia y solución de problemas
Supervisión del servidor
# Monitor Outline server logs
sudo docker logs -f outline-server
# Monitor system resources
htop
iotop
nethogs
# Check network connections
sudo netstat -tulpn|grep :443
sudo ss -tulpn|grep :443
# Monitor bandwidth usage
vnstat -i eth0
iftop -i eth0
# Custom monitoring script
cat > /usr/local/bin/outline-monitor.sh << 'EOF'
#!/bin/bash
LOG_FILE="/var/log/outline-monitor.log"
API_URL="https://localhost:8080/management-api-url"
# Function to log with timestamp
log_message() \\\\{
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> $LOG_FILE
\\\\}
# Check server health
check_server_health() \\\\{
if curl -k -s "$API_URL/server" >/dev/null 2>&1; then
log_message "Server health check: OK"
return 0
else
log_message "Server health check: FAILED"
return 1
fi
\\\\}
# Check Docker container status
check_container_status() \\\\{
if docker ps|grep -q outline-server; then
log_message "Container status: Running"
return 0
else
log_message "Container status: Not running"
return 1
fi
\\\\}
# Get transfer metrics
get_transfer_metrics() \\\\{
METRICS=$(curl -k -s "$API_URL/metrics/transfer" 2>/dev/null)
if [ $? -eq 0 ]; then
log_message "Transfer metrics: $METRICS"
else
log_message "Failed to retrieve transfer metrics"
fi
\\\\}
# Main monitoring loop
main() \\\\{
log_message "Starting Outline monitoring"
if ! check_container_status; then
log_message "Attempting to restart Outline server"
docker restart outline-server
sleep 10
fi
if check_server_health; then
get_transfer_metrics
else
log_message "Server health check failed, investigating..."
docker logs --tail 50 outline-server >> $LOG_FILE
fi
\\\\}
main
EOF
chmod +x /usr/local/bin/outline-monitor.sh
# Add to crontab for regular monitoring
echo "*/5 * * * * /usr/local/bin/outline-monitor.sh"|crontab -
Optimización del rendimiento
# Optimize TCP settings for VPN performance
cat > /etc/sysctl.d/99-outline-performance.conf << 'EOF'
# TCP optimization
net.core.rmem_max = 134217728
net.core.wmem_max = 134217728
net.ipv4.tcp_rmem = 4096 87380 134217728
net.ipv4.tcp_wmem = 4096 65536 134217728
net.ipv4.tcp_congestion_control = bbr
net.core.default_qdisc = fq
# Network buffer optimization
net.core.netdev_max_backlog = 5000
net.core.netdev_budget = 600
# Connection tracking optimization
net.netfilter.nf_conntrack_max = 1048576
net.netfilter.nf_conntrack_tcp_timeout_established = 7200
# IP forwarding and routing
net.ipv4.ip_forward = 1
net.ipv6.conf.all.forwarding = 1
EOF
# Apply settings
sudo sysctl -p /etc/sysctl.d/99-outline-performance.conf
# Docker container resource limits
sudo docker update --memory=1g --cpus=2 outline-server
# Optimize Shadowsocks configuration for performance
cat > /opt/outline/shadowsocks-optimized.json << 'EOF'
\\\\{
"server": "0.0.0.0",
"server_port": 443,
"password": "your-password",
"timeout": 300,
"method": "chacha20-ietf-poly1305",
"fast_open": true,
"workers": 4,
"prefer_ipv6": false,
"no_delay": true,
"reuse_port": true,
"mode": "tcp_and_udp"
\\\\}
EOF
Problemas comunes
# Connection issues troubleshooting
# 1. Check server accessibility
ping your-server-ip
telnet your-server-ip 443
# 2. Verify DNS resolution
nslookup your-domain.com
dig your-domain.com
# 3. Check firewall rules
sudo iptables -L -n
sudo ufw status
# 4. Test port connectivity
nc -zv your-server-ip 443
nc -zuv your-server-ip 443
# Client connection debugging
# Enable debug logging in Outline client
# Windows: %APPDATA%\Outline\logs\
# macOS: ~/Library/Logs/Outline/
# Linux: ~/.config/Outline/logs/
# Server-side debugging
sudo docker exec -it outline-server /bin/bash
cat /var/log/shadowbox.log
# Network troubleshooting
# Check routing table
ip route show
route -n
# Monitor network traffic
sudo tcpdump -i any port 443
sudo tcpdump -i any host your-client-ip
# Check for packet loss
mtr your-server-ip
# Bandwidth testing
iperf3 -s # On server
iperf3 -c your-server-ip # On client
# Certificate issues
openssl s_client -connect your-server-ip:443 -servername your-domain.com
openssl x509 -in /etc/letsencrypt/live/your-domain.com/fullchain.pem -text -noout
# Reset Outline server configuration
sudo docker stop outline-server
sudo docker rm outline-server
sudo rm -rf /opt/outline/
# Reinstall using installation script
Automatización y scripting
Script de despliegue automatizado
#!/bin/bash
# Automated Outline VPN deployment script
set -e
# Configuration variables
SERVER_NAME="Outline VPN Server"
DOMAIN_NAME=""
EMAIL=""
CLOUD_PROVIDER="digitalocean" # digitalocean, aws, gcp, vultr
REGION="nyc3"
SIZE="s-1vcpu-1gb"
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# Logging function
log() \\\\{
echo -e "$\\\\{GREEN\\\\}[$(date +'%Y-%m-%d %H:%M:%S')]$\\\\{NC\\\\} $1"
\\\\}
error() \\\\{
echo -e "$\\\\{RED\\\\}[ERROR]$\\\\{NC\\\\} $1" >&2
exit 1
\\\\}
warning() \\\\{
echo -e "$\\\\{YELLOW\\\\}[WARNING]$\\\\{NC\\\\} $1"
\\\\}
# Check prerequisites
check_prerequisites() \\\\{
log "Checking prerequisites..."
# Check if running as root
if [[ $EUID -eq 0 ]]; then
error "This script should not be run as root"
fi
# Check required commands
for cmd in curl docker docker-compose; do
if ! command -v $cmd &> /dev/null; then
error "$cmd is required but not installed"
fi
done
log "Prerequisites check passed"
\\\\}
# Install Docker if not present
install_docker() \\\\{
if ! command -v docker &> /dev/null; then
log "Installing Docker..."
curl -fsSL https://get.docker.com -o get-docker.sh
sh get-docker.sh
sudo usermod -aG docker $USER
rm get-docker.sh
log "Docker installed successfully"
fi
\\\\}
# Deploy Outline server
deploy_outline() \\\\{
log "Deploying Outline server..."
# Create outline directory
sudo mkdir -p /opt/outline
cd /opt/outline
# Download and run installation script
curl -sS https://raw.githubusercontent.com/Jigsaw-Code/outline-server/master/src/server_manager/install_scripts/install_server.sh|sudo bash
# Wait for server to start
sleep 30
# Check if server is running
if sudo docker ps|grep -q outline-server; then
log "Outline server deployed successfully"
else
error "Failed to deploy Outline server"
fi
\\\\}
# Configure SSL certificate
configure_ssl() \\\\{
if [[ -n "$DOMAIN_NAME" && -n "$EMAIL" ]]; then
log "Configuring SSL certificate for $DOMAIN_NAME..."
# Install certbot
sudo apt update
sudo apt install -y certbot
# Stop outline server temporarily
sudo docker stop outline-server
# Generate certificate
sudo certbot certonly --standalone -d $DOMAIN_NAME --email $EMAIL --agree-tos --non-interactive
# Update outline configuration
sudo docker exec outline-server \
sh -c "echo 'SB_CERTIFICATE_FILE=/etc/letsencrypt/live/$DOMAIN_NAME/fullchain.pem' >> /opt/outline/environment"
sudo docker exec outline-server \
sh -c "echo 'SB_PRIVATE_KEY_FILE=/etc/letsencrypt/live/$DOMAIN_NAME/privkey.pem' >> /opt/outline/environment"
# Restart outline server
sudo docker start outline-server
# Setup auto-renewal
echo "0 12 * * * /usr/bin/certbot renew --quiet && docker restart outline-server"|sudo crontab -
log "SSL certificate configured successfully"
else
warning "Domain name or email not provided, skipping SSL configuration"
fi
\\\\}
# Create access keys
create_access_keys() \\\\{
log "Creating initial access keys..."
# Wait for API to be ready
sleep 10
# Get API URL from server
API_URL=$(sudo cat /opt/outline/access.txt|grep -o 'https://[^"]*')
if [[ -n "$API_URL" ]]; then
# Create 3 initial access keys
for i in \\\\{1..3\\\\}; do
RESPONSE=$(curl -k -X POST -H "Content-Type: application/json" "$API_URL/access-keys" 2>/dev/null)
if [[ $? -eq 0 ]]; then
KEY_ID=$(echo $RESPONSE|grep -o '"id":"[^"]*'|cut -d'"' -f4)
ACCESS_URL=$(echo $RESPONSE|grep -o '"accessUrl":"[^"]*'|cut -d'"' -f4)
# Rename the key
curl -k -X PUT -H "Content-Type: application/json" \
-d "\\\\{\"name\": \"User $i\"\\\\}" \
"$API_URL/access-keys/$KEY_ID/name" 2>/dev/null
log "Created access key for User $i: $ACCESS_URL"
fi
done
else
error "Failed to get API URL"
fi
\\\\}
# Setup monitoring
setup_monitoring() \\\\{
log "Setting up monitoring..."
# Create monitoring script
sudo tee /usr/local/bin/outline-health-check.sh > /dev/null << 'EOF'
#!/bin/bash
API_URL=$(cat /opt/outline/access.txt|grep -o 'https://[^"]*')
if curl -k -s "$API_URL/server" >/dev/null 2>&1; then
echo "$(date): Outline server is healthy"
else
echo "$(date): Outline server health check failed"
docker restart outline-server
fi
EOF
sudo chmod +x /usr/local/bin/outline-health-check.sh
# Add to crontab
echo "*/5 * * * * /usr/local/bin/outline-health-check.sh >> /var/log/outline-health.log 2>&1"|sudo crontab -
log "Monitoring setup completed"
\\\\}
# Main deployment function
main() \\\\{
log "Starting Outline VPN deployment..."
check_prerequisites
install_docker
deploy_outline
configure_ssl
create_access_keys
setup_monitoring
log "Outline VPN deployment completed successfully!"
log "Server management information:"
sudo cat /opt/outline/access.txt
\\\\}
# Parse command line arguments
while [[ $# -gt 0 ]]; do
case $1 in
-d|--domain)
DOMAIN_NAME="$2"
shift 2
;;
-e|--email)
EMAIL="$2"
shift 2
;;
-h|--help)
echo "Usage: $0 [OPTIONS]"
echo "Options:"
echo " -d, --domain DOMAIN Domain name for SSL certificate"
echo " -e, --email EMAIL Email for Let's Encrypt"
echo " -h, --help Show this help message"
exit 0
;;
*)
error "Unknown option: $1"
;;
esac
done
# Run main function
main
Gestión de usuarios a granel
#!/bin/bash
# Bulk user management script for Outline VPN
API_URL=$(cat /opt/outline/access.txt|grep -o 'https://[^"]*')
USERS_FILE="users.csv"
# Create users from CSV file
# CSV format: username,data_limit_gb
create_users_from_csv() \\\\{
if [[ ! -f "$USERS_FILE" ]]; then
echo "Users file not found: $USERS_FILE"
exit 1
fi
while IFS=',' read -r username data_limit_gb; do
# Skip header line
if [[ "$username" == "username" ]]; then
continue
fi
echo "Creating user: $username"
# Create access key
RESPONSE=$(curl -k -X POST -H "Content-Type: application/json" "$API_URL/access-keys" 2>/dev/null)
KEY_ID=$(echo $RESPONSE|grep -o '"id":"[^"]*'|cut -d'"' -f4)
ACCESS_URL=$(echo $RESPONSE|grep -o '"accessUrl":"[^"]*'|cut -d'"' -f4)
# Set username
curl -k -X PUT -H "Content-Type: application/json" \
-d "\\\\{\"name\": \"$username\"\\\\}" \
"$API_URL/access-keys/$KEY_ID/name" 2>/dev/null
# Set data limit if specified
if [[ -n "$data_limit_gb" && "$data_limit_gb" != "unlimited" ]]; then
DATA_LIMIT_BYTES=$((data_limit_gb * 1024 * 1024 * 1024))
curl -k -X PUT -H "Content-Type: application/json" \
-d "\\\\{\"limit\": \\\\{\"bytes\": $DATA_LIMIT_BYTES\\\\}\\\\}" \
"$API_URL/access-keys/$KEY_ID/data-limit" 2>/dev/null
fi
echo "User $username created with key ID: $KEY_ID"
echo "Access URL: $ACCESS_URL"
echo "---"
done < "$USERS_FILE"
\\\\}
# Generate usage report
generate_usage_report() \\\\{
echo "Generating usage report..."
# Get all access keys
KEYS=$(curl -k -s "$API_URL/access-keys" 2>/dev/null)
# Get transfer metrics
METRICS=$(curl -k -s "$API_URL/metrics/transfer" 2>/dev/null)
echo "User Usage Report - $(date)"
echo "================================"
printf "%-20s %-10s %-15s\n" "Username" "Key ID" "Data Used (MB)"
echo "--------------------------------"
# Parse and display usage for each user
echo "$KEYS"|jq -r '.accessKeys[]|"\(.id)|\(.name)"'|while IFS='|' read -r key_id username; do
BYTES_USED=$(echo "$METRICS"|jq -r ".bytesTransferredByUserId.\"$key_id\" // 0")
MB_USED=$((BYTES_USED / 1024 / 1024))
printf "%-20s %-10s %-15s\n" "$username" "$key_id" "$MB_USED"
done
\\\\}
# Backup access keys
backup_access_keys() \\\\{
BACKUP_FILE="outline-backup-$(date +%Y%m%d-%H%M%S).json"
echo "Creating backup: $BACKUP_FILE"
# Get all access keys and server info
KEYS=$(curl -k -s "$API_URL/access-keys" 2>/dev/null)
SERVER_INFO=$(curl -k -s "$API_URL/server" 2>/dev/null)
# Create backup JSON
jq -n \
--argjson keys "$KEYS" \
--argjson server "$SERVER_INFO" \
'\\\\{
"backup_date": now|strftime("%Y-%m-%d %H:%M:%S"),
"server_info": $server,
"access_keys": $keys
\\\\}' > "$BACKUP_FILE"
echo "Backup created: $BACKUP_FILE"
\\\\}
# Show usage
show_usage() \\\\{
echo "Usage: $0 [COMMAND]"
echo "Commands:"
echo " create-users Create users from CSV file"
echo " usage-report Generate usage report"
echo " backup Backup access keys"
echo " help Show this help message"
\\\\}
# Main script logic
case "$1" in
create-users)
create_users_from_csv
;;
usage-report)
generate_usage_report
;;
backup)
backup_access_keys
;;
help|--help|-h)
show_usage
;;
*)
echo "Unknown command: $1"
show_usage
exit 1
;;
esac