diff --git a/Dockers/vpn-proxy/Dockerfile b/Dockers/vpn-proxy/Dockerfile new file mode 100644 index 0000000..3887457 --- /dev/null +++ b/Dockers/vpn-proxy/Dockerfile @@ -0,0 +1,39 @@ +FROM alpine:latest + +# Install necessary packages +RUN apk add --no-cache \ + openvpn \ + squid \ + curl \ + bash \ + iptables \ + ip6tables \ + net-tools \ + procps \ + && rm -rf /var/cache/apk/* + +# Create directories +RUN mkdir -p /etc/openvpn /var/log/squid /var/cache/squid /var/run/squid + +# Copy configuration files +COPY squid.conf /etc/squid/squid.conf +COPY start.sh /start.sh +COPY version /version + +# Make scripts executable +RUN chmod +x /start.sh + +# Expose proxy port +EXPOSE 3128 + +# Set environment variables +ENV PROXY_URL="" +ENV VPN_CONFIG="" +ENV VPN_TYPE="openvpn" + +# Health check +HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \ + CMD curl -f http://localhost:3128/ || exit 1 + +# Start the service +CMD ["/start.sh"] diff --git a/Dockers/vpn-proxy/README.md b/Dockers/vpn-proxy/README.md new file mode 100644 index 0000000..0c0de08 --- /dev/null +++ b/Dockers/vpn-proxy/README.md @@ -0,0 +1,169 @@ +# VPN Proxy Docker Container + +A Docker container that creates a proxy server routed through a VPN connection (OpenVPN or WireGuard). This allows you to access websites through a VPN tunnel by using the container as a proxy. + +## Features + +- Supports both OpenVPN (.ovpn) and WireGuard (.conf) configurations +- Squid proxy server for HTTP/HTTPS traffic +- Automatic VPN connection and health monitoring +- Configurable target URL for testing +- Health checks and automatic restart on failure + +## Usage + +### Prerequisites + +- Docker with `--cap-add=NET_ADMIN` capability +- Access to `/dev/net/tun` device (for OpenVPN) +- VPN configuration file (.ovpn or .conf) + +### Basic Usage + +1. **Build the container:** + + ```bash + docker build -t vpn-proxy . + ``` + +2. **Run with OpenVPN:** + + ```bash + docker run -d \ + --name vpn-proxy \ + --cap-add=NET_ADMIN \ + --device /dev/net/tun \ + -p 3128:3128 \ + -e PROXY_URL=https://example.com \ + -e VPN_CONFIG=/vpn/config.ovpn \ + -e VPN_TYPE=openvpn \ + -v /path/to/your/config.ovpn:/vpn/config.ovpn:ro \ + vpn-proxy + ``` + +3. **Run with WireGuard:** + ```bash + docker run -d \ + --name vpn-proxy \ + --cap-add=NET_ADMIN \ + -p 3128:3128 \ + -e PROXY_URL=https://example.com \ + -e VPN_CONFIG=/vpn/wg0.conf \ + -e VPN_TYPE=wireguard \ + -v /path/to/your/wg0.conf:/vpn/wg0.conf:ro \ + vpn-proxy + ``` + +### Environment Variables + +| Variable | Required | Default | Description | +| ------------ | -------- | --------- | ---------------------------------- | +| `PROXY_URL` | Yes | - | Target URL to proxy through VPN | +| `VPN_CONFIG` | Yes | - | Path to VPN configuration file | +| `VPN_TYPE` | No | `openvpn` | VPN type: `openvpn` or `wireguard` | + +### Using the Proxy + +Once the container is running, you can use it as a proxy: + +```bash +# Test the proxy +curl -x localhost:3128 https://httpbin.org/ip + +# Use in applications +export http_proxy=http://localhost:3128 +export https_proxy=http://localhost:3128 +``` + +### Docker Compose Example + +```yaml +version: "3.8" +services: + vpn-proxy: + build: . + container_name: vpn-proxy + cap_add: + - NET_ADMIN + devices: + - /dev/net/tun + ports: + - "3128:3128" + environment: + - PROXY_URL=https://example.com + - VPN_CONFIG=/vpn/config.ovpn + - VPN_TYPE=openvpn + volumes: + - ./config.ovpn:/vpn/config.ovpn:ro + restart: unless-stopped +``` + +## Configuration Files + +### OpenVPN Configuration + +Your `.ovpn` file should contain all necessary connection details including: + +- Server address and port +- Authentication credentials +- Certificate data +- Cipher settings + +### WireGuard Configuration + +Your `.conf` file should follow the standard WireGuard format: + +```ini +[Interface] +PrivateKey = your_private_key +Address = 10.0.0.2/24 +DNS = 8.8.8.8 + +[Peer] +PublicKey = server_public_key +Endpoint = server.example.com:51820 +AllowedIPs = 0.0.0.0/0 +``` + +## Monitoring + +The container includes health checks and will automatically restart if: + +- VPN connection is lost +- Proxy server stops responding +- Container receives SIGTERM/SIGINT + +Check logs with: + +```bash +docker logs vpn-proxy +``` + +## Security Notes + +- The container runs with `NET_ADMIN` capability to manage network interfaces +- VPN credentials are stored in mounted configuration files +- The proxy server is configured to forward all traffic through the VPN +- No caching is performed to ensure fresh data through VPN + +## Troubleshooting + +1. **VPN won't connect:** + + - Check that the configuration file is properly mounted + - Verify VPN credentials and server availability + - Check container logs for specific error messages + +2. **Proxy not working:** + + - Ensure port 3128 is accessible + - Test with `curl -x localhost:3128 http://httpbin.org/ip` + - Check that the VPN connection is active + +3. **Permission denied:** + - Ensure the container has `--cap-add=NET_ADMIN` + - For OpenVPN, ensure `/dev/net/tun` is accessible + +## License + +This project is open source and available under the MIT License. diff --git a/Dockers/vpn-proxy/env.example b/Dockers/vpn-proxy/env.example new file mode 100644 index 0000000..5c57fb7 --- /dev/null +++ b/Dockers/vpn-proxy/env.example @@ -0,0 +1,25 @@ +# VPN Proxy Environment Variables + +# Target URL to proxy (required) +# This is the website you want to access through the VPN +PROXY_URL=https://example.com + +# VPN Configuration file path (required) +# Mount your .ovpn or .conf file and specify the path here +VPN_CONFIG=/vpn/config.ovpn + +# VPN Type (optional, defaults to openvpn) +# Options: openvpn, wireguard +VPN_TYPE=openvpn + +# Example usage: +# docker run -d \ +# --name vpn-proxy \ +# --cap-add=NET_ADMIN \ +# --device /dev/net/tun \ +# -p 3128:3128 \ +# -e PROXY_URL=https://example.com \ +# -e VPN_CONFIG=/vpn/config.ovpn \ +# -e VPN_TYPE=openvpn \ +# -v /path/to/your/config.ovpn:/vpn/config.ovpn:ro \ +# vpn-proxy diff --git a/Dockers/vpn-proxy/squid.conf b/Dockers/vpn-proxy/squid.conf new file mode 100644 index 0000000..7948b38 --- /dev/null +++ b/Dockers/vpn-proxy/squid.conf @@ -0,0 +1,61 @@ +# Squid configuration for VPN proxy +http_port 3128 + +# Allow access from any IP (since we're in a container) +acl localnet src 0.0.0.1-0.255.255.255 +acl localnet src 10.0.0.0/8 +acl localnet src 100.64.0.0/10 +acl localnet src 169.254.0.0/16 +acl localnet src 172.16.0.0/12 +acl localnet src 192.168.0.0/16 +acl localnet src fc00::/7 +acl localnet src fe80::/10 + +# Allow all HTTP and HTTPS traffic +acl SSL_ports port 443 +acl Safe_ports port 80 +acl Safe_ports port 21 +acl Safe_ports port 443 +acl Safe_ports port 70 +acl Safe_ports port 210 +acl Safe_ports port 1025-65535 +acl Safe_ports port 280 +acl Safe_ports port 488 +acl Safe_ports port 591 +acl Safe_ports port 777 +acl CONNECT method CONNECT + +# Deny requests to certain unsafe ports +http_access deny !Safe_ports + +# Deny CONNECT to other than secure SSL ports +http_access deny CONNECT !SSL_ports + +# Allow localhost management +http_access allow localhost manager +http_access deny manager + +# Allow access from local networks +http_access allow localnet +http_access allow localhost + +# Allow all other traffic (since we're proxying through VPN) +http_access allow all + +# Cache settings (minimal for proxy) +cache_dir ufs /var/cache/squid 100 16 256 +maximum_object_size 1024 MB + +# Logging +access_log /var/log/squid/access.log squid +cache_log /var/log/squid/cache.log + +# Don't forward private IPs +never_direct allow all + +# Forward all requests through the VPN interface +forwarded_for off +via off + +# Hide client IP +forwarded_for delete diff --git a/Dockers/vpn-proxy/start.sh b/Dockers/vpn-proxy/start.sh new file mode 100644 index 0000000..5ec2bfc --- /dev/null +++ b/Dockers/vpn-proxy/start.sh @@ -0,0 +1,218 @@ +#!/bin/bash + +set -e + +# Function to log messages +log() { + echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" +} + +# Function to check if VPN is connected +check_vpn() { + if [ "$VPN_TYPE" = "openvpn" ]; then + # Check if tun interface exists and has an IP + if ip addr show tun0 >/dev/null 2>&1; then + TUN_IP=$(ip addr show tun0 | grep 'inet ' | awk '{print $2}' | cut -d'/' -f1) + if [ -n "$TUN_IP" ]; then + return 0 + fi + fi + elif [ "$VPN_TYPE" = "wireguard" ]; then + # Check if wg interface exists and has an IP + if ip addr show wg0 >/dev/null 2>&1; then + WG_IP=$(ip addr show wg0 | grep 'inet ' | awk '{print $2}' | cut -d'/' -f1) + if [ -n "$WG_IP" ]; then + return 0 + fi + fi + fi + return 1 +} + +# Function to start OpenVPN +start_openvpn() { + log "Starting OpenVPN with config: $VPN_CONFIG" + + if [ ! -f "$VPN_CONFIG" ]; then + log "ERROR: VPN config file not found: $VPN_CONFIG" + exit 1 + fi + + # Start OpenVPN in background + openvpn --config "$VPN_CONFIG" --daemon --log /var/log/openvpn.log + + # Wait for VPN to connect + log "Waiting for VPN connection..." + for i in {1..30}; do + if check_vpn; then + log "VPN connected successfully" + return 0 + fi + sleep 2 + done + + log "ERROR: VPN failed to connect within 60 seconds" + exit 1 +} + +# Function to start WireGuard +start_wireguard() { + log "Starting WireGuard with config: $VPN_CONFIG" + + if [ ! -f "$VPN_CONFIG" ]; then + log "ERROR: WireGuard config file not found: $VPN_CONFIG" + exit 1 + fi + + # Start WireGuard + wg-quick up "$VPN_CONFIG" + + # Wait for WireGuard to connect + log "Waiting for WireGuard connection..." + for i in {1..30}; do + if check_vpn; then + log "WireGuard connected successfully" + return 0 + fi + sleep 2 + done + + log "ERROR: WireGuard failed to connect within 60 seconds" + exit 1 +} + +# Function to setup routing +setup_routing() { + log "Setting up routing for VPN proxy" + + # Get the VPN interface IP + if [ "$VPN_TYPE" = "openvpn" ]; then + VPN_IP=$(ip addr show tun0 | grep 'inet ' | awk '{print $2}' | cut -d'/' -f1) + VPN_INTERFACE="tun0" + elif [ "$VPN_TYPE" = "wireguard" ]; then + VPN_IP=$(ip addr show wg0 | grep 'inet ' | awk '{print $2}' | cut -d'/' -f1) + VPN_INTERFACE="wg0" + fi + + log "VPN Interface: $VPN_INTERFACE, IP: $VPN_IP" + + # Set up iptables rules to route traffic through VPN + iptables -t nat -A OUTPUT -p tcp --dport 80 -j DNAT --to-destination $VPN_IP:80 + iptables -t nat -A OUTPUT -p tcp --dport 443 -j DNAT --to-destination $VPN_IP:443 + + # Allow traffic through VPN interface + iptables -A OUTPUT -o $VPN_INTERFACE -j ACCEPT + iptables -A INPUT -i $VPN_INTERFACE -j ACCEPT +} + +# Function to start Squid proxy +start_squid() { + log "Starting Squid proxy server" + + # Initialize Squid cache + squid -z -N -d 1 + + # Start Squid + squid -N -d 1 & + SQUID_PID=$! + + # Wait for Squid to start + sleep 5 + + if kill -0 $SQUID_PID 2>/dev/null; then + log "Squid proxy started successfully on port 3128" + else + log "ERROR: Failed to start Squid proxy" + exit 1 + fi +} + +# Function to test proxy +test_proxy() { + log "Testing proxy connection" + + # Test if we can reach the target URL through the proxy + if [ -n "$PROXY_URL" ]; then + log "Testing connection to: $PROXY_URL" + if curl -x localhost:3128 --connect-timeout 10 --max-time 30 -s -o /dev/null "$PROXY_URL"; then + log "Proxy test successful - can reach $PROXY_URL" + else + log "WARNING: Proxy test failed - cannot reach $PROXY_URL" + fi + fi +} + +# Main execution +main() { + log "Starting VPN Proxy container" + + # Check required environment variables + if [ -z "$PROXY_URL" ]; then + log "ERROR: PROXY_URL environment variable is required" + exit 1 + fi + + if [ -z "$VPN_CONFIG" ]; then + log "ERROR: VPN_CONFIG environment variable is required" + exit 1 + fi + + log "Configuration:" + log " PROXY_URL: $PROXY_URL" + log " VPN_CONFIG: $VPN_CONFIG" + log " VPN_TYPE: ${VPN_TYPE:-openvpn}" + + # Start VPN based on type + if [ "$VPN_TYPE" = "wireguard" ]; then + start_wireguard + else + start_openvpn + fi + + # Setup routing + setup_routing + + # Start Squid proxy + start_squid + + # Test proxy + test_proxy + + log "VPN Proxy is ready and listening on port 3128" + log "Use this container as a proxy: http://localhost:3128" + + # Keep container running and monitor + while true; do + if ! check_vpn; then + log "ERROR: VPN connection lost, restarting..." + exit 1 + fi + + if ! kill -0 $SQUID_PID 2>/dev/null; then + log "ERROR: Squid proxy died, restarting..." + exit 1 + fi + + sleep 30 + done +} + +# Handle shutdown +cleanup() { + log "Shutting down VPN Proxy" + if [ -n "$SQUID_PID" ]; then + kill $SQUID_PID 2>/dev/null || true + fi + + if [ "$VPN_TYPE" = "wireguard" ] && [ -f "$VPN_CONFIG" ]; then + wg-quick down "$VPN_CONFIG" 2>/dev/null || true + fi + + exit 0 +} + +# Set up signal handlers +trap cleanup SIGTERM SIGINT + +# Run main function +main "$@" diff --git a/Dockers/vpn-proxy/version b/Dockers/vpn-proxy/version new file mode 100644 index 0000000..3eefcb9 --- /dev/null +++ b/Dockers/vpn-proxy/version @@ -0,0 +1 @@ +1.0.0