Aperçu du VPN Feuilles de chaleur
Outline VPN est une solution VPN open-source développée par Jigsaw (filiale d'Alphabet Inc.) qui privilégie la facilité d'utilisation, la sécurité et la résistance au blocage. Construit sur le protocole Shadowsocks, Outline offre un moyen simple de créer et de gérer des serveurs VPN personnels tout en offrant de fortes capacités de chiffrement et d'obfuscation qui rendent difficile la détection et le blocage du trafic VPN par les administrateurs de réseau.
Aperçu général de la plateforme
Architecture et philosophie du design
Le VPN Outline se compose de deux composants principaux : le Gestionnaire Outline pour l'administration du serveur et le Client Outline pour la connectivité utilisateur final. Le système est conçu avec simplicité et sécurité comme principes de base, le rendant accessible aux utilisateurs sans connaissances techniques étendues tout en maintenant des normes de sécurité de qualité.
Le Outline Manager est une application de bureau qui permet aux administrateurs de déployer et de gérer des serveurs Outline sur différentes plates-formes cloud, notamment DigitalOcean, Google Cloud Platform, Amazon Web Services et Vultr. Le gestionnaire s'occupe de la fourniture du serveur, de la génération des clés utilisateur et de la surveillance du trafic grâce à une interface graphique intuitive.
Les applications Outline Client sont disponibles pour les plateformes Windows, MacOS, Linux, iOS et Android. Ces clients utilisent les clés d'accès générées pour établir des connexions sécurisées aux serveurs Outline, fournissant un tunnel chiffré pour tout le trafic réseau.
Caractéristiques principales
# 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
Installation et configuration du serveur
Installation manuelle du serveur
# 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
```_
### Déploiement de la plateforme Cloud
```bash
# 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
```_
### Configuration de Docker Compose
```yaml
# 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
Configuration du gestionnaire principal
Configuration initiale et connexion du serveur
# 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
# \\\}
Gestion des clés d'accès
# 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
# \\\}
# \\\}
Configuration du serveur
# 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"
Configuration et utilisation du client
Configuration du client 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"
Configuration du client macOS
# 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
Configuration du client 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
Configuration du client mobile
# 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
Configuration avancée
Scies d'ombre personnalisées Configuration
# 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
Équilibre de charge et grande disponibilité
# 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
Renforcement de la sécurité
# 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
Surveillance et dépannage
Surveillance du serveur
# 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 -
Optimisation des performances
# 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
Résolution de problèmes communs
# 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
Automatisation et écriture
Scénario de déploiement automatisé
#!/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
Gestion des utilisateurs en vrac
#!/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
Ressources
- Site Web principal du VPN
- [Répertoire GitHub du serveur externe] (LINK_5)
- [Répertoire GitHub du client principal] (LINK_5)
- [Documentation relative au Protocole de Shadowsocks] (LINK_5)
- [Site officiel de Google] (LINK_5)