gluetun_wireguard_proxy/install.sh

464 lines
13 KiB
Bash
Raw Permalink Normal View History

2025-08-23 19:05:12 +02:00
#!/bin/bash
# WireGuard Server Setup with Gluetun (Docker)
# Author: Assistant
# Date: $(date +%Y-%m-%d)
set -e
# Colors for better readability
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Logging functions
log() {
echo -e "${BLUE}[$(date +'%Y-%m-%d %H:%M:%S')]${NC} $1"
}
error() {
echo -e "${RED}[ERROR]${NC} $1" >&2
}
success() {
echo -e "${GREEN}[SUCCESS]${NC} $1"
}
warning() {
echo -e "${YELLOW}[WARNING]${NC} $1"
}
# Check root privileges
check_root() {
if [[ $EUID -ne 0 ]]; then
error "This script must be run as root!"
exit 1
fi
}
# Check operating system
check_os() {
if [[ ! -f /etc/debian_version ]]; then
error "This script is designed for Debian systems!"
exit 1
fi
success "Debian system detected"
}
# Check package availability
check_packages() {
log "Checking installed packages..."
local required_packages=("curl" "wget" "apt-transport-https" "ca-certificates" "gnupg" "lsb-release" "net-tools" "iptables")
local missing_packages=()
for package in "${required_packages[@]}"; do
if ! dpkg -l | grep -q "^ii $package "; then
missing_packages+=("$package")
else
success "$package is already installed"
fi
done
# Check Docker
if ! command -v docker &> /dev/null; then
missing_packages+=("docker")
warning "Docker is not installed"
else
success "Docker is already installed"
fi
if ! command -v docker-compose &> /dev/null; then
missing_packages+=("docker-compose")
warning "Docker Compose is not installed"
else
success "Docker Compose is already installed"
fi
if [[ ${#missing_packages[@]} -gt 0 ]]; then
warning "The following packages need to be installed: ${missing_packages[*]}"
return 1
else
success "All required packages are already installed"
return 0
fi
}
# Update system
update_system() {
log "Updating package list..."
apt update -q
log "Performing system upgrade..."
apt upgrade -y -q
success "System has been updated"
}
# Install basic packages
install_basic_packages() {
log "Installing basic packages..."
local packages=("curl" "wget" "apt-transport-https" "ca-certificates" "gnupg" "lsb-release" "net-tools" "iptables" "ufw" "nano")
apt install -y "${packages[@]}"
success "Basic packages installed"
}
# Install Docker
install_docker() {
if command -v docker &> /dev/null; then
success "Docker is already installed"
return 0
fi
log "Installing Docker..."
# Remove old Docker versions
apt remove -y docker docker-engine docker.io containerd runc 2>/dev/null || true
# Add Docker GPG key
curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
# Add Docker repository
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null
# Update package list
apt update -q
# Install Docker
apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
# Start and enable Docker
systemctl enable docker
systemctl start docker
success "Docker has been installed and started"
}
# Install Docker Compose
install_docker_compose() {
if command -v docker-compose &> /dev/null; then
success "Docker Compose is already installed"
return 0
fi
log "Installing Docker Compose..."
# Get latest version
local compose_version=$(curl -s https://api.github.com/repos/docker/compose/releases/latest | grep 'tag_name' | cut -d\" -f4)
# Download Docker Compose
curl -L "https://github.com/docker/compose/releases/download/${compose_version}/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
# Make executable
chmod +x /usr/local/bin/docker-compose
# Create symlink
ln -sf /usr/local/bin/docker-compose /usr/bin/docker-compose
success "Docker Compose has been installed"
}
# Configure static IP
configure_static_ip() {
log "Configuring static IP..."
# Show available network interfaces
echo -e "\n${YELLOW}Available network interfaces:${NC}"
ip link show | grep -E "^[0-9]+: " | cut -d: -f2 | tr -d ' '
echo -e "\n${YELLOW}Current IP configuration:${NC}"
ip addr show | grep -E "inet [0-9]" | grep -v 127.0.0.1
echo -e "\n"
read -p "Would you like to configure a static IP? (y/n): " configure_ip
if [[ $configure_ip =~ ^[Yy]$ ]]; then
read -p "Interface (e.g. eth0, ens18): " interface
read -p "Static IP address (e.g. 192.168.1.100/24): " static_ip
read -p "Gateway (e.g. 192.168.1.1): " gateway
read -p "DNS server (e.g. 8.8.8.8): " dns_server
# Backup current configuration
cp /etc/network/interfaces /etc/network/interfaces.backup.$(date +%s)
# Create new configuration
cat > /etc/network/interfaces << EOF
# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).
source /etc/network/interfaces.d/*
# The loopback network interface
auto lo
iface lo inet loopback
# Static IP configuration
auto $interface
iface $interface inet static
address $static_ip
gateway $gateway
dns-nameservers $dns_server
EOF
success "Static IP configuration created"
warning "Network will be restarted after script completion"
else
log "Static IP configuration skipped"
fi
}
# Get WireGuard configuration
get_wireguard_config() {
log "Getting WireGuard configuration..."
echo -e "\n${YELLOW}Please enter your WireGuard configuration data:${NC}"
read -p "WireGuard Private Key: " WG_PRIVATE_KEY
read -p "WireGuard Public Key: " WG_PUBLIC_KEY
read -p "WireGuard Preshared Key (optional, Enter for empty): " WG_PRESHARED_KEY
read -p "WireGuard Endpoint (e.g. vpn.example.com:51820): " WG_ENDPOINT
read -p "WireGuard Allowed IPs (e.g. 0.0.0.0/0): " WG_ALLOWED_IPS
read -p "WireGuard Interface IP - IPv4 only (e.g. 10.0.0.2/32): " WG_INTERFACE_IP
# Remove IPv6 addresses from input (Gluetun compatibility)
WG_INTERFACE_IP=$(echo "$WG_INTERFACE_IP" | grep -oE '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/[0-9]+' | head -1)
if [[ -z "$WG_INTERFACE_IP" ]]; then
warning "No valid IPv4 address detected. Please use IPv4 only (e.g. 10.0.0.2/32)"
read -p "WireGuard Interface IP (IPv4 only): " WG_INTERFACE_IP
fi
# Validation
if [[ -z "$WG_PRIVATE_KEY" ]] || [[ -z "$WG_PUBLIC_KEY" ]] || [[ -z "$WG_ENDPOINT" ]]; then
error "Private Key, Public Key and Endpoint are required!"
exit 1
fi
success "WireGuard configuration captured"
}
# Setup Gluetun directory and configuration
setup_gluetun() {
log "Creating Gluetun configuration..."
# Create working directory
mkdir -p /opt/gluetun
cd /opt/gluetun
# Create Docker Compose file
cat > docker-compose.yml << EOF
services:
gluetun:
image: qmcgaw/gluetun:latest
container_name: gluetun-wireguard
restart: unless-stopped
cap_add:
- NET_ADMIN
devices:
- /dev/net/tun:/dev/net/tun
ports:
- "8888:8888/tcp" # HTTP proxy
- "8388:8388/tcp" # Shadowsocks
- "8388:8388/udp" # Shadowsocks
environment:
- VPN_SERVICE_PROVIDER=custom
- VPN_TYPE=wireguard
- WIREGUARD_ENDPOINT_IP=${WG_ENDPOINT%:*}
- WIREGUARD_ENDPOINT_PORT=${WG_ENDPOINT#*:}
- WIREGUARD_PRIVATE_KEY=${WG_PRIVATE_KEY}
- WIREGUARD_PUBLIC_KEY=${WG_PUBLIC_KEY}
- WIREGUARD_ADDRESSES=${WG_INTERFACE_IP}
- WIREGUARD_ALLOWED_IPS=${WG_ALLOWED_IPS:-0.0.0.0/0}
- HTTPPROXY=on
- HTTPPROXY_LOG=on
- HTTPPROXY_LISTENING_ADDRESS=:8888
- SHADOWSOCKS=on
- SHADOWSOCKS_LOG=on
- SHADOWSOCKS_LISTENING_ADDRESS=:8388
- LOG_LEVEL=info
- HEALTH_VPN_DURATION_INITIAL=10s
- HEALTH_VPN_DURATION_ADDITION=5s
- DOT=off
- FIREWALL_OUTBOUND_SUBNETS=192.168.0.0/16,172.16.0.0/12,10.0.0.0/8
EOF
# Add preshared key if provided
if [[ -n "$WG_PRESHARED_KEY" ]]; then
echo " - WIREGUARD_PRESHARED_KEY=${WG_PRESHARED_KEY}" >> docker-compose.yml
fi
success "Gluetun Docker Compose file created"
}
# Configure firewall
configure_firewall() {
log "Configuring UFW firewall..."
# Reset and enable UFW
ufw --force reset
ufw --force enable
# Default rules
ufw default deny incoming
ufw default allow outgoing
# Allow SSH
ufw allow ssh
# Allow proxy ports
ufw allow 8888/tcp comment "Gluetun HTTP Proxy"
ufw allow 8388 comment "Gluetun SOCKS Proxy"
# Allow Docker subnets
ufw allow from 172.17.0.0/16
ufw allow from 172.18.0.0/16
success "Firewall configured"
}
# Start Gluetun
start_gluetun() {
log "Starting Gluetun container..."
cd /opt/gluetun
# Stop container if already running
docker-compose down 2>/dev/null || true
# Update images
docker-compose pull
# Start container
docker-compose up -d
success "Gluetun container started"
}
# Check status
check_status() {
log "Checking container status..."
sleep 5
if docker ps | grep -q gluetun-wireguard; then
success "Gluetun container is running"
# Show logs
echo -e "\n${YELLOW}Container logs (last 20 lines):${NC}"
docker logs --tail 20 gluetun-wireguard
# Check VPN status
echo -e "\n${YELLOW}Checking VPN status...${NC}"
sleep 10
# Check IP address via VPN
local vpn_ip=$(docker exec gluetun-wireguard wget -qO- https://ipinfo.io/ip 2>/dev/null || echo "Error retrieving IP")
echo -e "${GREEN}VPN IP address: ${vpn_ip}${NC}"
else
error "Gluetun container is not running!"
echo -e "\n${RED}Container logs:${NC}"
docker logs gluetun-wireguard 2>/dev/null || echo "No logs available"
fi
}
# Create systemd service
create_systemd_service() {
log "Creating systemd service..."
cat > /etc/systemd/system/gluetun.service << EOF
[Unit]
Description=Gluetun VPN Container
Requires=docker.service
After=docker.service
[Service]
Type=oneshot
RemainAfterExit=yes
WorkingDirectory=/opt/gluetun
ExecStart=/usr/local/bin/docker-compose up -d
ExecStop=/usr/local/bin/docker-compose down
TimeoutStartSec=0
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable gluetun.service
success "Systemd service created and enabled"
}
# Show summary
show_summary() {
echo -e "\n${GREEN}===========================================${NC}"
echo -e "${GREEN} Installation completed successfully!${NC}"
echo -e "${GREEN}===========================================${NC}"
echo -e "\n${YELLOW}Proxy Settings:${NC}"
echo -e "HTTP/HTTPS Proxy: http://$(hostname -I | awk '{print $1}'):8888"
echo -e "SOCKS5 Proxy: $(hostname -I | awk '{print $1}'):8388"
echo -e "\n${YELLOW}Useful Commands:${NC}"
echo -e "Container status: ${BLUE}docker ps${NC}"
echo -e "Container logs: ${BLUE}docker logs gluetun-wireguard${NC}"
echo -e "Stop container: ${BLUE}systemctl stop gluetun${NC}"
echo -e "Start container: ${BLUE}systemctl start gluetun${NC}"
echo -e "Restart container: ${BLUE}systemctl restart gluetun${NC}"
echo -e "\n${YELLOW}Configuration Files:${NC}"
echo -e "Docker Compose: ${BLUE}/opt/gluetun/docker-compose.yml${NC}"
echo -e "Systemd Service: ${BLUE}/etc/systemd/system/gluetun.service${NC}"
if [[ $configure_ip =~ ^[Yy]$ ]]; then
echo -e "\n${YELLOW}Important:${NC} System must be rebooted to activate static IP!"
read -p "Would you like to reboot the system now? (y/n): " reboot_now
if [[ $reboot_now =~ ^[Yy]$ ]]; then
log "Rebooting system..."
reboot
fi
fi
}
# Main function
main() {
echo -e "${BLUE}"
echo "=============================================="
echo " WireGuard Server Setup with Gluetun (Docker)"
echo "=============================================="
echo -e "${NC}\n"
# Validations
check_root
check_os
# System setup
if ! check_packages; then
update_system
install_basic_packages
install_docker
install_docker_compose
fi
# Network configuration
configure_static_ip
# WireGuard setup
get_wireguard_config
setup_gluetun
configure_firewall
create_systemd_service
start_gluetun
# Status and summary
check_status
show_summary
}
# Execute script
main "$@"