2025-10-08 17:56:29 +02:00
---
2025-10-09 00:30:31 +02:00
title: VPN - Encrypted Tunnel to Freedom
2025-10-08 17:56:29 +02:00
description: "The internet, but make it private!"
2025-10-09 00:30:31 +02:00
navigation:
icon: i-lucide-plug
2025-10-08 17:56:29 +02:00
---
2025-10-08 10:35:48 +02:00
> *"The internet, but make it private!"* - WireGuard
## What's This All About?
WG-Easy is your self-hosted VPN server powered by WireGuard! It's like having your own private tunnel through the internet - encrypt all your traffic, bypass geo-restrictions, access your home network from anywhere, and surf safely on sketchy public WiFi. Plus, it has a beautiful web UI for managing clients! 🚇
## The Privacy Protector
2025-10-09 00:30:31 +02:00
### :icon{name="lucide:shield"} WG-Easy
2025-10-08 10:35:48 +02:00
**Container**: `vpn_app`
**Image**: `ghcr.io/wg-easy/wg-easy:15`
**Ports**: 51820 (VPN), 51821 (Web UI)
**Home**: https://vpn.pivoine.art
WG-Easy makes WireGuard actually easy:
2025-10-09 00:30:31 +02:00
- :icon{name="lucide:palette"} **Beautiful Web UI ** : Manage VPN from browser
2025-10-09 16:46:34 +02:00
- :icon{name="lucide:phone"} **QR Codes ** : Instant mobile setup
2025-10-09 00:30:31 +02:00
- :icon{name="lucide:users"} **Multi-Client ** : Unlimited devices
- :icon{name="lucide:zap"} **WireGuard ** : Modern, fast, secure protocol
- :icon{name="lucide:bar-chart"} **Traffic Stats ** : See bandwidth usage
- :icon{name="lucide:lock"} **Encrypted ** : Industry-standard crypto
2025-10-09 17:24:27 +02:00
- :icon{name="lucide:globe"} **Route All Traffic ** : Or split-tunnel
2025-10-09 00:30:31 +02:00
- :icon{name="lucide:rocket"} **Performance ** : Faster than OpenVPN
2025-10-08 10:35:48 +02:00
## WireGuard: The Modern VPN Protocol
### Why WireGuard is Awesome
2025-10-09 00:30:31 +02:00
- :icon{name="lucide:zap"} **Fast ** : 4000+ lines of code vs OpenVPN's 600,000+
- :icon{name="lucide:lock"} **Secure ** : State-of-the-art cryptography
2025-10-09 16:46:34 +02:00
- :icon{name="lucide:phone"} **Battery Friendly ** : Less power consumption
2025-10-09 00:30:31 +02:00
- :icon{name="lucide:refresh-cw"} **Roaming ** : Seamless connection switching
2025-10-09 17:24:27 +02:00
- :icon{name="lucide:sparkles"} **Linux Kernel ** : Built into Linux 5.6+
2025-10-09 00:30:31 +02:00
- :icon{name="lucide:target"} **Simple ** : Easier to audit and configure
2025-10-08 10:35:48 +02:00
## Configuration Breakdown
### Network Configuration
The stack creates TWO networks:
**wg Network** (Internal WireGuard):
```yaml
subnet: 10.42.42.0/24 # IPv4
subnet: fdcc:ad94:bacf:61a3::/64 # IPv6
```
Your VPN clients get IPs from this range.
**kompose Network** (External):
```yaml
external: true
```
Connects to other services via Traefik.
### Environment Variables
**WireGuard Settings**:
```bash
WG_HOST=vpn.pivoine.art # Your public domain/IP
WG_PORT=51820 # WireGuard port (UDP)
WG_DEFAULT_ADDRESS=10.42.0.x # Client IP range
WG_DEFAULT_DNS=1.1.1.1 # DNS for clients
WG_ALLOWED_IPS=0.0.0.0/0 # Route all traffic through VPN
```
**Web UI Settings**:
```bash
PORT=51821 # Web interface port
UI_TRAFFIC_STATS=true # Show bandwidth graphs
UI_CHART_TYPE=0 # Chart style
```
### Security & Capabilities
Required Linux capabilities:
```yaml
cap_add:
- NET_ADMIN # Network configuration
- SYS_MODULE # Load kernel modules
```
System controls:
```yaml
sysctls:
- net.ipv4.ip_forward=1 # Enable IP forwarding
- net.ipv4.conf.all.src_valid_mark=1 # Packet routing
```
2025-10-09 00:30:31 +02:00
## First Time Setup :icon{name="lucide:rocket"}
2025-10-08 10:35:48 +02:00
### 1. Ensure Ports are Open
**Firewall**:
```bash
# Allow WireGuard port
sudo ufw allow 51820/udp
# Allow Web UI (temporary for setup)
sudo ufw allow 51821/tcp
```
**Router**:
- Forward UDP port 51820 to your server
- Check your router's port forwarding settings
### 2. Set Your Public Address
In `.env` :
```bash
# Use your domain
WG_HOST=vpn.yourdomain.com
# Or your public IP
WG_HOST=123.45.67.89
```
### 3. Start the Stack
```bash
docker compose up -d
```
### 4. Access Web UI
```
URL: https://vpn.pivoine.art
Password: (set via PASSWORD_HASH in .env)
```
### 5. Generate Password Hash
If you haven't set password yet:
```bash
# Generate bcrypt hash
echo -n 'your-password' | npx bcrypt-cli
# Or use Docker
docker run --rm -it node:alpine sh -c "npm install -g bcrypt-cli && echo -n 'your-password' | bcrypt"
# Copy hash to .env
PASSWORD_HASH=$2a$10$...your_hash...
```
Restart container:
```bash
docker compose restart
```
2025-10-09 16:46:34 +02:00
## Creating VPN Clients :icon{name="lucide:phone"}
2025-10-08 10:35:48 +02:00
### Add a Client
1. **Login to Web UI ** : https://vpn.pivoine.art
2. **Click "New Client" **
3. **Give it a name ** : "My iPhone", "Work Laptop", etc.
4. **Click "Create" **
### Mobile Setup (QR Code)
**For iPhone/Android**:
1. Install WireGuard app:
- [iOS ](https://apps.apple.com/app/wireguard/id1441195209 )
- [Android ](https://play.google.com/store/apps/details?id=com.wireguard.android )
2. Open app → "Add tunnel" → "Scan QR code"
3. Scan the QR code from web UI
4. Give tunnel a name
5. Toggle on!
### Desktop Setup (Config File)
**For Windows/Mac/Linux**:
1. Download WireGuard:
- [Windows ](https://download.wireguard.com/windows-client/ )
- [macOS ](https://apps.apple.com/app/wireguard/id1451685025 )
- [Linux ](https://www.wireguard.com/install/ )
2. In web UI, click "Download" next to client
3. Import config file into WireGuard app
4. Activate tunnel!
### Manual Configuration
Download the `.conf` file and inspect it:
```ini
[Interface]
PrivateKey = your_private_key
Address = 10.42.0.2/32
DNS = 1.1.1.1
[Peer]
PublicKey = server_public_key
PresharedKey = shared_key
Endpoint = vpn.pivoine.art:51820
AllowedIPs = 0.0.0.0/0, ::/0
PersistentKeepalive = 25
```
2025-10-09 00:30:31 +02:00
## Using Your VPN :icon{name="lucide:globe"}
2025-10-08 10:35:48 +02:00
### Full Tunnel (All Traffic)
**Default behavior** - all internet traffic goes through VPN:
2025-10-09 17:24:27 +02:00
- :icon{name="lucide:check"} Complete privacy
- :icon{name="lucide:check"} Bypass geo-blocks
- :icon{name="lucide:check"} Secure public WiFi
2025-10-09 00:30:31 +02:00
- :icon{name="lucide:alert-triangle"} Slightly slower (routing through your server)
2025-10-08 10:35:48 +02:00
### Split Tunnel (Selective Routing)
**Only route specific traffic** through VPN.
Edit client config to only route home network:
```ini
AllowedIPs = 10.0.0.0/24 # Only home network
# Instead of: 0.0.0.0/0
```
**Benefits**:
2025-10-09 00:30:31 +02:00
- :icon{name="lucide:home"} Access home services
- :icon{name="lucide:globe"} Normal internet speed
- :icon{name="lucide:bar-chart"} Less VPN bandwidth
2025-10-08 10:35:48 +02:00
2025-10-09 00:30:31 +02:00
## Traffic Statistics :icon{name="lucide:bar-chart"}
2025-10-08 10:35:48 +02:00
Web UI shows for each client:
2025-10-09 17:24:27 +02:00
- :icon{name="lucide:upload"} **Download ** : Data received
- :icon{name="lucide:download"} **Upload ** : Data sent
- :icon{name="lucide:clock"} **Last Seen ** : When last connected
2025-10-09 00:30:31 +02:00
- :icon{name="lucide:trending-up"} **Charts ** : Bandwidth over time
2025-10-08 10:35:48 +02:00
## Common Use Cases
2025-10-09 00:30:31 +02:00
### 1. Secure Public WiFi :icon{name="lucide:coffee"}
2025-10-08 10:35:48 +02:00
```
Coffee Shop WiFi → WireGuard → Your Server → Internet
```
Encrypt traffic on untrusted networks.
2025-10-09 00:30:31 +02:00
### 2. Access Home Network :icon{name="lucide:home"}
2025-10-08 10:35:48 +02:00
```
You (anywhere) → VPN → Home Network → NAS, Printer, etc.
```
Access devices as if you're home.
2025-10-09 17:24:27 +02:00
### 3. Bypass Geo-Restrictions :icon{name="lucide:globe"}
2025-10-08 10:35:48 +02:00
```
Your Location → VPN (Server Country) → Streaming Service
```
Appear to be in server's location.
2025-10-09 17:24:27 +02:00
### 4. Privacy from ISP :icon{name="lucide:hat-glasses"}
2025-10-08 10:35:48 +02:00
```
Your Device → Encrypted Tunnel → Your Server → Internet
```
ISP only sees encrypted traffic to your server.
### 5. Multiple Locations 🗺️
Deploy VPN servers in different countries:
- USA server for US content
- EU server for European services
- Home server for local access
2025-10-09 00:30:31 +02:00
## Security Features :icon{name="lucide:lock"}
2025-10-08 10:35:48 +02:00
### Encryption
- **Protocol**: Noise Protocol Framework
- **Key Exchange**: Curve25519
- **Cipher**: ChaCha20-Poly1305
- **Hash**: BLAKE2s
2025-10-09 00:30:31 +02:00
**Translation**: Military-grade encryption! :icon{name="lucide:dumbbell"}
2025-10-08 10:35:48 +02:00
### Authentication
- **Public/Private Keys**: Per-client keypairs
- **Preshared Keys**: Extra security layer
- **Endpoint Verification**: Prevents spoofing
### Privacy
- **No Logs**: WireGuard doesn't log by default
- **Perfect Forward Secrecy**: Past sessions stay secure
- **IP Masquerading**: Hides your real IP
2025-10-09 00:30:31 +02:00
## DNS Configuration :icon{name="lucide:globe"}
2025-10-08 10:35:48 +02:00
### Default DNS (Cloudflare)
```bash
WG_DEFAULT_DNS=1.1.1.1
```
### Other Options
**Google**:
```bash
WG_DEFAULT_DNS=8.8.8.8
```
**Quad9** (Security):
```bash
WG_DEFAULT_DNS=9.9.9.9
```
**AdGuard** (Ad-blocking):
```bash
WG_DEFAULT_DNS=94.140.14.14
```
**Custom** (Your Pi-hole):
```bash
WG_DEFAULT_DNS=192.168.1.2
```
2025-10-09 00:30:31 +02:00
## Performance Optimization :icon{name="lucide:zap"}
2025-10-08 10:35:48 +02:00
### Enable BBR (Better Congestion Control)
```bash
# On host
echo "net.core.default_qdisc=fq" >> /etc/sysctl.conf
echo "net.ipv4.tcp_congestion_control=bbr" >> /etc/sysctl.conf
sysctl -p
```
### Increase MTU
```ini
# In client config
[Interface]
MTU = 1420 # Default, try 1500 if stable
```
### Persistent Keepalive
```ini
# Keep connection alive through NAT
PersistentKeepalive = 25
```
2025-10-09 00:30:31 +02:00
## Troubleshooting :icon{name="lucide:wrench"}
2025-10-08 10:35:48 +02:00
**Q: Can't connect to VPN?**
```bash
# Check server is running
docker logs vpn_app
# Verify port is open
nc -zvu vpn.pivoine.art 51820
# Check firewall
sudo ufw status
```
**Q: Connected but no internet?**
```bash
# Verify IP forwarding
sysctl net.ipv4.ip_forward
# Should return: 1
# Check NAT rules
sudo iptables -t nat -L
```
**Q: Slow speeds?**
- Check server bandwidth
- Try different MTU values
- Enable BBR congestion control
- Use split-tunnel for non-sensitive traffic
**Q: Client won't auto-reconnect?**
- Add `PersistentKeepalive = 25` to config
- Check client has network connectivity
**Q: DNS not working?**
```bash
# Test DNS from client
nslookup google.com
# Change DNS in config
DNS = 8.8.8.8
```
2025-10-09 16:46:34 +02:00
## Mobile Tips :icon{name="lucide:phone"}
2025-10-08 10:35:48 +02:00
### iOS
- **On-Demand**: Auto-connect on untrusted WiFi
- **Shortcuts**: Create Siri shortcuts
- **Widget**: Quick toggle from home screen
### Android
- **Always-On**: VPN reconnects automatically
- **Kill Switch**: Block internet if VPN drops
- **Split Tunneling**: Exclude specific apps
## Advanced Configuration
### IPv6 Support
Already configured!
```yaml
enable_ipv6: true
subnet: fdcc:ad94:bacf:61a3::/64
```
### Custom Routing
**Route only specific subnets**:
```ini
AllowedIPs = 192.168.1.0/24, 10.0.0.0/24
```
**Block specific IPs**:
```bash
# On server
iptables -A FORWARD -d 192.168.1.100 -j DROP
```
### Port Forwarding
Forward ports through VPN:
```bash
# Forward port 8080 to client
iptables -t nat -A PREROUTING -p tcp --dport 8080 -j DNAT --to 10.42.0.2:8080
```
## Monitoring & Logs
### Check Connection Status
```bash
# Via web UI
https://vpn.pivoine.art
# Or check container
docker exec vpn_app wg show
```
### View Logs
```bash
docker logs vpn_app -f
```
### Bandwidth Stats
Web UI shows real-time graphs for each client!
2025-10-09 00:30:31 +02:00
## Backup & Restore :icon{name="lucide:refresh-cw"}
2025-10-08 10:35:48 +02:00
### Backup Configuration
```bash
# Backup WireGuard configs
docker exec vpn_app tar -czf /tmp/wg-backup.tar.gz /etc/wireguard
docker cp vpn_app:/tmp/wg-backup.tar.gz ./backups/
```
### Restore
```bash
# Copy backup to container
docker cp ./backups/wg-backup.tar.gz vpn_app:/tmp/
# Extract
docker exec vpn_app tar -xzf /tmp/wg-backup.tar.gz -C /
# Restart
docker compose restart
```
2025-10-09 00:30:31 +02:00
## Security Best Practices :icon{name="lucide:shield"}
2025-10-08 10:35:48 +02:00
1. **Strong Password ** : Use bcrypt hash for web UI
2. **Regular Updates ** : Keep WG-Easy updated
3. **Firewall ** : Only expose necessary ports
4. **Client Management ** : Remove inactive clients
5. **Monitoring ** : Watch for unusual traffic
6. **Backups ** : Regular config backups
7. **Access Control ** : Limit who can create clients
## Why Self-Host a VPN?
2025-10-09 00:30:31 +02:00
- :icon{name="lucide:lock"} **Full Control ** : Your server, your rules
- :icon{name="lucide:dollar-sign"} **Cost Effective ** : No monthly fees
- :icon{name="lucide:rocket"} **Performance ** : Direct to your server
2025-10-09 17:24:27 +02:00
- :icon{name="lucide:hat-glasses"} **Privacy ** : No third-party logging
- :icon{name="lucide:globe"} **Flexibility ** : Use any server location
2025-10-09 00:30:31 +02:00
- :icon{name="lucide:bar-chart"} **Transparency ** : You know what's happening
- :icon{name="lucide:hammer"} **Customization ** : Configure exactly as needed
2025-10-08 10:35:48 +02:00
## Resources
- [WireGuard Documentation ](https://www.wireguard.com/ )
- [WG-Easy GitHub ](https://github.com/wg-easy/wg-easy )
- [WireGuard Clients ](https://www.wireguard.com/install/ )
---
2025-10-09 00:30:31 +02:00
*"Privacy is not about having something to hide. It's about protecting what you value."* - VPN Philosophy :icon{name="lucide:lock"}:icon{name="lucide:sparkles"}