#!/bin/bash # Wireguard to Docker Bridge Setup Script # This script sets up a custom bridge for Docker that is accessible via Wireguard VPN # Exit on any error set -e # Configuration values - you can adjust these BRIDGE_NAME="br-vpn-docker" BRIDGE_SUBNET="172.20.0.0/16" BRIDGE_IP="172.20.0.1" DOCKER_NETWORK_NAME="private-net" WG_INTERFACE="wg0" EXTERNAL_INTERFACE="eth0" # Your server's internet-facing interface # Color codes for pretty output GREEN='\033[0;32m' YELLOW='\033[1;33m' RED='\033[0;31m' NC='\033[0m' # No Color # Function to print status messages status() { echo -e "${GREEN}[+]${NC} $1" } warning() { echo -e "${YELLOW}[!]${NC} $1" } error() { echo -e "${RED}[!]${NC} $1" exit 1 } # Check if running as root if [ "$(id -u)" -ne 0 ]; then error "This script must be run as root" fi # Step 1: Install dependencies status "Installing required packages..." apt-get update apt-get install -y wireguard netplan.io docker.io iptables bridge-utils # Step 2: Check if Wireguard is already configured if [ ! -f "/etc/wireguard/${WG_INTERFACE}.conf" ]; then warning "Wireguard configuration not found. You'll need to configure Wireguard separately." warning "See: https://www.wireguard.com/quickstart/" fi # Step 3: Remove existing Docker network if it exists status "Checking for existing Docker network..." if docker network inspect "${DOCKER_NETWORK_NAME}" &>/dev/null; then status "Removing existing Docker network '${DOCKER_NETWORK_NAME}'..." # Check for running containers using this network CONTAINERS=$(docker ps --filter network=${DOCKER_NETWORK_NAME} -q) if [ -n "$CONTAINERS" ]; then warning "Containers are using the network. Stopping them..." docker ps --filter network=${DOCKER_NETWORK_NAME} -q | xargs -r docker stop fi # Remove the network docker network rm "${DOCKER_NETWORK_NAME}" fi # Step 4: Configure the bridge with Netplan status "Creating Netplan configuration for bridge '${BRIDGE_NAME}'..." cat > /etc/netplan/02-${BRIDGE_NAME}.yaml </dev/null; then error "Failed to create bridge interface" fi status "Bridge '${BRIDGE_NAME}' created successfully" # Step 5: Create Docker network using the bridge status "Creating Docker network '${DOCKER_NETWORK_NAME}' using bridge '${BRIDGE_NAME}'..." docker network create --driver bridge \ --opt "com.docker.network.bridge.name"="${BRIDGE_NAME}" \ --subnet "${BRIDGE_SUBNET}" \ --gateway "${BRIDGE_IP}" \ "${DOCKER_NETWORK_NAME}" || error "Failed to create Docker network" status "Docker network created successfully" # Step 6: Create Wireguard iptables scripts status "Creating Wireguard iptables configuration scripts..." # Create the up script cat > /etc/wireguard/${WG_INTERFACE}-up.sh < /etc/wireguard/${WG_INTERFACE}-down.sh </dev/null || true # Remove forwarding rules iptables -D FORWARD -i ${WG_INTERFACE} -o ${BRIDGE_NAME} -j ACCEPT 2>/dev/null || true iptables -D FORWARD -i ${BRIDGE_NAME} -o ${WG_INTERFACE} -j ACCEPT 2>/dev/null || true # Remove Docker-User chain rules iptables -D DOCKER-USER -i ${WG_INTERFACE} -o ${BRIDGE_NAME} -j ACCEPT 2>/dev/null || true iptables -D DOCKER-USER -i ${BRIDGE_NAME} -o ${WG_INTERFACE} -j ACCEPT 2>/dev/null || true # Remove NAT rules iptables -t nat -D POSTROUTING -o ${BRIDGE_NAME} -j MASQUERADE 2>/dev/null || true iptables -t nat -D POSTROUTING -o ${EXTERNAL_INTERFACE} -j MASQUERADE 2>/dev/null || true echo "Wireguard to Docker bridge rules removed successfully" EOF # Make scripts executable chmod +x /etc/wireguard/${WG_INTERFACE}-up.sh chmod +x /etc/wireguard/${WG_INTERFACE}-down.sh status "Wireguard iptables scripts created" # Step 7: Configure Wireguard to use these scripts if [ -f "/etc/wireguard/${WG_INTERFACE}.conf" ]; then status "Configuring Wireguard to use the iptables scripts..." # Check if PostUp and PostDown are already configured if grep -q "PostUp" "/etc/wireguard/${WG_INTERFACE}.conf"; then warning "PostUp/PostDown directives already exist in Wireguard config" warning "Please manually add these lines to your Wireguard config:" echo "PostUp = /etc/wireguard/${WG_INTERFACE}-up.sh" echo "PostDown = /etc/wireguard/${WG_INTERFACE}-down.sh" else # Add the PostUp and PostDown commands cat >> "/etc/wireguard/${WG_INTERFACE}.conf" < /etc/systemd/system/wireguard-docker-rules.service </dev/null 2>&1; then TMP_CONFIG=$(mktemp) jq 'del(.iptables) | del(.bridge)' "$DOCKER_CONFIG" > "$TMP_CONFIG" mv "$TMP_CONFIG" "$DOCKER_CONFIG" else # Simple sed-based approach (less robust but works for basic cases) sed -i 's/"iptables":\s*false,\?//g' "$DOCKER_CONFIG" sed -i 's/"bridge":\s*"none",\?//g' "$DOCKER_CONFIG" # Clean up any syntax issues this might create sed -i 's/,\s*}/}/g' "$DOCKER_CONFIG" sed -i 's/{,\s*/{/g' "$DOCKER_CONFIG" sed -i 's/,,/,/g' "$DOCKER_CONFIG" fi fi else # Create default config file mkdir -p $(dirname "$DOCKER_CONFIG") echo '{}' > "$DOCKER_CONFIG" fi status "Docker iptables management properly configured" # Step 10: Enable IP forwarding permanently status "Enabling IP forwarding permanently..." echo "net.ipv4.ip_forward=1" > /etc/sysctl.d/99-ip-forward.conf sysctl -p /etc/sysctl.d/99-ip-forward.conf # Step 11: Create a Docker restart hook to reapply rules status "Creating Docker restart hook..." cat > /usr/local/bin/docker-post-start.sh < /etc/systemd/system/docker-vpn-fix.service <