Zum Inhalt

Outline VPN Cheatsheet

Outline VPN ist eine Open-Source-VPN-Lösung, die von Jigsaw (ein Tochterunternehmen von Alphabet Inc.) entwickelt wurde, die die Benutzerfreundlichkeit, Sicherheit und Widerstand gegen Blockierung priorisiert. Im Shadowsocks Protokoll gebaut, bietet Outline eine einfache Möglichkeit, persönliche VPN-Server zu erstellen und zu verwalten, während sie starke Verschlüsselungs- und Obfuskationsmöglichkeiten bieten, die es für Netzwerkadministratoren schwierig machen, den VPN-Verkehr zu erkennen und zu blockieren.

Überblick

Architektur und Design Philosophie

Outline VPN besteht aus zwei Hauptkomponenten: dem Outline Manager für die Serververwaltung und dem Outline Client für Endbenutzer-Konnektivität. Das System ist mit Einfachheit und Sicherheit als Kernprinzipien konzipiert, so dass es Benutzern ohne umfangreiche technische Kenntnisse und unter Beibehaltung von unternehmenseigenen Sicherheitsstandards zugänglich ist.

Der Outline Manager ist eine Desktop-Anwendung, mit der Administratoren Outline-Server auf verschiedenen Cloud-Plattformen wie DigitalOcean, Google Cloud Platform, Amazon Web Services und Vultr bereitstellen und verwalten können. Der Manager behandelt Serverbereitstellung, Benutzer-Schlüsselerzeugung und Verkehrsüberwachung über eine intuitive grafische Schnittstelle.

Die Outline Client-Anwendungen sind für Windows-, macOS-, Linux-, iOS- und Android-Plattformen verfügbar. Diese Clients nutzen die generierten Zugangsschlüssel, um sichere Verbindungen zu Outline-Servern herzustellen, um verschlüsselte Tunnelings für alle Netzwerk-Verkehrs.

Schlüsselmerkmale

```bash

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 ```_

Serverinstallation und Setup

Automatische Serverinstallation

```bash

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 ```_

Bereitstellung von Cloud Platform

```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 ```_

Docker komponiert Setup

```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 ```_

Outline Manager Konfiguration

Initial Setup und Serververbindung

```bash

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

\}

```_

Schlüsselverwaltung

```bash

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

\}

\}

```_

Serverkonfiguration

```bash

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" ```_

Client Konfiguration und Nutzung

Windows Client Setup

```powershell

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

```bash

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 ```_

Linux Client Setup

```bash

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 ```_

Mobile Client Konfiguration

```bash

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 ```_

Erweiterte Konfiguration

Individuelle Schatten Konfiguration

```bash

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 ```_

Lastausgleich und hohe Verfügbarkeit

```bash

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 ```_

Sicherheitshärten

```bash

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 = ^ - - [.] "." 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 ```_

Überwachung und Fehlerbehebung

Serverüberwachung

```bash

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 - ```_

Leistungsoptimierung

```bash

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 ```_

Probleme bei der Fehlerbehebung

```bash

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

```_

Automatisierung und Schrift

Automatisierte Bereitstellung Script

```bash

!/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 ```_

Bulk User Management

```bash

!/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 ```_

Ressourcen