- Overview
- Features
- Quick Start
- System Requirements
- Installation
- Architecture
- Configuration
- User Guide
- Operations
- Troubleshooting
- Development
- License
WireShield is an automated WireGuard VPN deployment tool with integrated two-factor authentication. It enforces pre-connection 2FA using TOTP (Time-based One-Time Password), ensuring that only authenticated users can access the VPN tunnel.
How it works:
- Client connects to WireGuard VPN
- Firewall gates all traffic except DNS and the 2FA portal
- Browser redirects to captive portal for authentication
- User verifies with Google Authenticator or compatible TOTP app
- Upon successful verification, client IP is added to ipset allowlist
- Full internet access is granted through the VPN tunnel
Session Management Rules:
-
Absolute Timeout (24 Hours):
- Every authenticated session is valid for a maximum of 24 hours.
- After 24 hours, you must re-authenticate with 2FA, regardless of activity.
-
Inactivity/Disconnect (1 Hour Grace Period):
- If you disconnect the VPN or your device sleeps, your session remains active for 1 Hour.
- Reconnecting < 1 Hour: No 2FA required. Instant access.
- Reconnecting > 1 Hour: Session expired. 2FA required.
-
Strict Revocation:
- Once a session expires (either due to the 24h limit or >1h inactivity), it is immediately revoked.
- The firewall blocks all internet access until 2FA is verified again.
- ✅ Pre-connection 2FA using TOTP (Google Authenticator, Authy, etc.)
- ✅ TLS/SSL encryption with Let's Encrypt or self-signed certificates
- ✅ Rate limiting (30 requests per 60 seconds per IP/endpoint)
- ✅ Audit logging for all authentication events
- ✅ Session monitoring with WireGuard handshake-aware revocation
- ✅ ipset-based allowlisting for verified clients
- ✅ User activity logging with configurable retention
- ✅ Admin Console for granular access control and log viewing
- ✅ One-command installation via interactive CLI
- ✅ Cross-platform support for 9+ Linux distributions
- ✅ Automatic firewall configuration (iptables/ip6tables)
- ✅ Let's Encrypt integration with auto-renewal
- ✅ Systemd service with hardened configuration
- ✅ QR code setup for easy authenticator enrollment
- ✅ Responsive web UI for authentication
- ✅ Automatic captive portal redirection
- ✅ Client configuration generation with optimized QR codes
- ✅ Web Console for user and log management
- ✅ Jinja2 template architecture for maintainable UI components
# Clone the repository
git clone https://github.com/siyamsarker/WireShield.git
cd WireShield
# Run installer (requires root)
sudo ./wireshield.sh
# Follow interactive prompts for:
# - Public IP or domain
# - WireGuard port (UDP)
# - DNS servers
# - SSL/TLS configuration
# Installation creates first client automatically
# Client config: ~/<client_name>.confTime to deploy: ~5 minutes
- OS: Linux with systemd
- Kernel: Linux 5.6+ (WireGuard built-in) or compatible kernel module
- Architecture: x86_64, ARM64
- RAM: 512 MB minimum
- Root access: Required for installation
- Network: Public IP or domain name, open UDP port
| Distribution | Minimum Version | Status |
|---|---|---|
| Ubuntu | 18.04 (Bionic) | ✅ Tested |
| Debian | 10 (Buster) | ✅ Tested |
| Fedora | 32 | ✅ Tested |
| CentOS Stream | 8 | ✅ Tested |
| AlmaLinux | 8 | ✅ Tested |
| Rocky Linux | 8 | ✅ Tested |
| Oracle Linux | 8+ | ✅ Supported |
| Arch Linux | Rolling | ✅ Supported |
| Alpine Linux | 3.14+ | ✅ Supported |
- WireGuard client (Windows, macOS, Linux, iOS, Android)
- TOTP authenticator app (Google Authenticator, Authy, Microsoft Authenticator, etc.)
- Web browser for 2FA verification
# Clone repository
git clone https://github.com/siyamsarker/WireShield.git
cd WireShield
# Make installer executable
chmod +x wireshield.sh
# Run installer
sudo ./wireshield.shThe installer will prompt for:
- Public IP or domain: Auto-detected or manually specified
- WireGuard interface name: Default
wg0 - WireGuard IPv4/IPv6: Default
10.66.66.1/24,fd42:42:42::1/64 - UDP port: Random port 49152-65535 or custom
- DNS servers: Default
1.1.1.1,1.0.0.1 - SSL/TLS configuration:
- Let's Encrypt (requires domain, port 80/443 accessible)
- Self-signed certificate (for IP addresses)
- No SSL (development only)
# Check WireGuard status
sudo wg show
# Check 2FA service
sudo systemctl status wireshield.service
# View logs
sudo journalctl -u wireshield.service -f/etc/wireguard/
├── wg0.conf # WireGuard server configuration
└── params # Installation parameters
/etc/wireshield/2fa/
├── run.py # Service entry point
├── app/ # Application package
│ ├── main.py # Application factory
│ ├── core/ # Core logic (config, db, security)
│ ├── routers/ # API endpoints
│ └── templates.py # Template rendering functions
├── templates/ # Jinja2 HTML templates
│ ├── base.html # Base template
│ ├── 2fa_setup.html # 2FA setup page
│ ├── 2fa_verify.html # 2FA verification page
│ ├── success.html # Success page
│ ├── access_denied.html # Access denied page
│ └── console.html # Admin console dashboard
├── requirements.txt # Python dependencies
├── auth.db # SQLite database (users, sessions, audit logs)
├── config.env # Environment configuration
├── cert.pem # SSL certificate
├── key.pem # SSL private key
├── .venv/ # Python virtual environment
├── tests/ # Test suite
└── 2fa-helper.sh # Management helper script
/etc/systemd/system/
├── wireshield.service # 2FA service
└── wireshield-2fa-renew.timer # Let's Encrypt renewal timer (if applicable)
┌─────────────┐
│ Client │
│ (WireGuard) │
└──────┬──────┘
│ Connect
▼
┌─────────────────────────────────────────────┐
│ WireGuard Server (wg0) │
│ ┌───────────────────────────────────────┐ │
│ │ iptables/ip6tables Firewall │ │
│ │ │ │
│ │ 1. Check ipset allowlist │ │
│ │ ws_2fa_allowed_v4/v6 │ │
│ │ │ │
│ │ 2. If NOT in allowlist: │ │
│ │ └─> Jump to WS_2FA_PORTAL chain │ │
│ │ ├─ Allow DNS (53/tcp,udp) │ │
│ │ ├─ Allow portal (80,443/tcp) │ │
│ │ └─ DROP all else │ │
│ │ │ │
│ │ 3. If in allowlist: │ │
│ │ └─> ACCEPT & MASQUERADE │ │
│ └───────────────────────────────────────┘ │
└─────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────┐
│ 2FA Service (FastAPI + Python) │
│ ┌───────────────────────────────────────┐ │
│ │ Captive Portal (HTTPS) │ │
│ │ ├─ QR code generation │ │
│ │ ├─ TOTP verification │ │
│ │ └─ Session management │ │
│ └───────────────────────────────────────┘ │
│ ┌───────────────────────────────────────┐ │
│ │ Background Monitors │ │
│ │ ├─ WireGuard handshake monitor │ │
│ │ ├─ ipset sync daemon │ │
│ │ └─ HTTP→HTTPS redirector │ │
│ └───────────────────────────────────────┘ │
│ ┌───────────────────────────────────────┐ │
│ │ SQLite Database │ │
│ │ ├─ users (client_id, TOTP secrets) │ │
│ │ ├─ sessions (tokens, expiry) │ │
│ │ └─ audit_log (security events) │ │
│ └───────────────────────────────────────┘ │
└─────────────────────────────────────────────┘
IPv4 chains:
# ipset allowlists
ipset create ws_2fa_allowed_v4 hash:ip family inet
# Portal chain (before verification)
iptables -N WS_2FA_PORTAL
iptables -A WS_2FA_PORTAL -p tcp --dport 53 -j ACCEPT
iptables -A WS_2FA_PORTAL -p udp --dport 53 -j ACCEPT
iptables -A WS_2FA_PORTAL -d <portal_ip> -p tcp --dport 443 -j ACCEPT
iptables -A WS_2FA_PORTAL -d <portal_ip> -p tcp --dport 80 -j ACCEPT
iptables -A WS_2FA_PORTAL -j DROP
# Forward chain (order matters!)
iptables -A FORWARD -i wg0 -m set --match-set ws_2fa_allowed_v4 src -j ACCEPT
iptables -A FORWARD -i wg0 -j WS_2FA_PORTALIPv6 chains: Identical structure with ip6tables and ws_2fa_allowed_v6
The background monitor polls WireGuard handshakes every 3 seconds:
- Reads
wg show <interface> dumpto get handshake timestamps - Calculates age for each client IP
- Applies dual-threshold logic:
- Idle threshold (3600s): Client active if any handshake ≤ 3600s
- Disconnect grace (3600s): Client expired if all handshakes > 3600s
- Removes stale sessions from database
- Syncs ipset allowlists (removes IPs without active sessions)
Location: /etc/wireshield/2fa/config.env
Core settings:
# Database
WS_2FA_DB_PATH=/etc/wireshield/2fa/auth.db
# Network
WS_2FA_HOST=0.0.0.0
WS_2FA_PORT=443
WS_2FA_HTTP_PORT=80
# Logging
WS_2FA_LOG_LEVEL=INFO
# Rate Limiting
WS_2FA_RATE_LIMIT_MAX_REQUESTS=30
WS_2FA_RATE_LIMIT_WINDOW=60
# Session Management
WS_2FA_SESSION_TIMEOUT=1440 # 24 hours (in minutes)
WS_2FA_SESSION_IDLE_TIMEOUT=3600 # 1 hour (in seconds)
WS_2FA_DISCONNECT_GRACE_SECONDS=3600 # 1 hour (in seconds)
# SSL/TLS
WS_2FA_SSL_ENABLED=true
WS_2FA_SSL_TYPE=letsencrypt # or 'self-signed'
WS_2FA_DOMAIN=vpn.example.com # for Let's Encrypt
WS_HOSTNAME_2FA=127.0.0.1 # for self-signed
# WireGuard
WS_WG_INTERFACE=wg0
WS_WIREGUARD_PARAMS=/etc/wireguard/params
# Security (must be set for production)
WS_2FA_SECRET_KEY=<generate-random-key>All config.env settings can be overridden via environment variables. The service uses a priority system:
WS_2FA_*prefixed variables2FA_*prefixed variables (legacy)- Default values
Scenario 1: Increase idle tolerance to 2 hours
# Edit /etc/wireshield/2fa/config.env
WS_2FA_SESSION_IDLE_TIMEOUT=7200
# Restart service
sudo systemctl restart wireshield.serviceScenario 2: Faster disconnect detection (10 seconds)
WS_2FA_DISCONNECT_GRACE_SECONDS=10
sudo systemctl restart wireshield.serviceScenario 3: Extend session validity to 7 days
WS_2FA_SESSION_TIMEOUT=10080 # 7 days in minutes
sudo systemctl restart wireshield.service-
Receive your WireGuard configuration
- Download
<your-name>.conffrom admin - Import into WireGuard client (desktop/mobile)
- Download
-
Connect to VPN
- Click "Connect" or "Activate" in WireGuard app
- Wait for tunnel to establish
-
Complete 2FA enrollment
- Browser automatically opens to
https://<vpn-domain>/?client_id=<your-name> - Click "Setup Authenticator"
- Scan QR code with Google Authenticator, Authy, or compatible app
- Enter 6-digit verification code
- Save backup codes (if provided)
- Browser automatically opens to
-
Verification success
- You'll see "Verification Successful" page
- Full internet access is now active through VPN
- Session valid for 24 hours
-
After disconnection or session expiry:
- Connect VPN again
- Browser opens to 2FA page
- Enter current 6-digit code from authenticator app
- No need to re-scan QR code
-
Authenticator apps:
- Google Authenticator (iOS/Android)
- Authy (iOS/Android/Desktop)
- Microsoft Authenticator (iOS/Android)
- 1Password, Bitwarden, LastPass Authenticator
- Any TOTP-compatible app
"Cannot reach 2FA portal"
- Ensure VPN is connected (check WireGuard status)
- Verify DNS is working:
nslookup google.com - Try accessing portal manually:
https://<vpn-ip-or-domain>
"Invalid code" error
- Ensure device clock is synchronized (TOTP relies on time)
- Wait for next code rotation (codes change every 30 seconds)
- Verify you're using the correct authenticator entry
"Session expired immediately"
- Contact admin to check
WS_2FA_SESSION_IDLE_TIMEOUTsetting - Ensure WireGuard
PersistentKeepaliveis set (usually 25 seconds)
# Start/stop/restart 2FA service
sudo systemctl start wireshield.service
sudo systemctl stop wireshield.service
sudo systemctl restart wireshield.service
# Enable/disable auto-start
sudo systemctl enable wireshield.service
sudo systemctl disable wireshield.service
# Check status
sudo systemctl status wireshield.service
# View logs (real-time)
sudo journalctl -u wireshield.service -f
# View logs (last 100 lines)
sudo journalctl -u wireshield.service -n 100# Start/stop WireGuard
sudo systemctl start wg-quick@wg0
sudo systemctl stop wg-quick@wg0
# View active peers
sudo wg show
# View peer handshakes and traffic
sudo wg show wg0 dump
# Reload configuration
sudo systemctl restart wg-quick@wg0# Via interactive menu
sudo ./wireshield.sh
# Select option: "Add a new client"
# Enter client name: alice
# Config saved to ~/alice.conf
# Send alice.conf to user securely# Via interactive menu
sudo ./wireshield.sh
# Select option: "List existing clients"
# Or manually check WireGuard config
sudo grep -A 3 "Peer" /etc/wireguard/wg0.conf# Via interactive menu
sudo ./wireshield.sh
# Select option: "Revoke an existing client"
# Enter client name to remove
# This removes:
# - WireGuard peer configuration
# - 2FA database entries
# - Active sessions
# - ipset allowlist entriesIf a user loses their authenticator device, you can reset their 2FA status without revoking their VPN access.
# Via interactive menu
sudo ./wireshield.sh
# Select option: "Remove Client 2FA"
# Select the client from the listThis will:
- Clear the TOTP secret and session
- Remove the client from the allowlist
- Prompt the user to re-register on their next connection
Control which users can access the web-based Admin Console (/console).
# Via interactive menu
sudo ./wireshield.sh
# Select option: "Console Access Management"
# Toggle access for specific clients# Via SQLite
sudo sqlite3 /etc/wireshield/2fa/auth.db \
"SELECT client_id, enabled, created_at, wg_ipv4, wg_ipv6 FROM users;"sudo sqlite3 /etc/wireshield/2fa/auth.db \
"SELECT s.client_id, s.device_ip, s.expires_at, s.created_at
FROM sessions s
WHERE s.expires_at > datetime('now')
ORDER BY s.created_at DESC;"# Via interactive menu
sudo ./wireshield.sh
# Select option: "View Audit Logs"# Remove specific client from allowlist
sudo ipset del ws_2fa_allowed_v4 10.66.66.2
sudo ipset del ws_2fa_allowed_v6 fd42:42:42::2
# Delete session from database
sudo sqlite3 /etc/wireshield/2fa/auth.db \
"DELETE FROM sessions WHERE client_id='alice';"WireShield includes a built-in activity logger that tracks connection history for auditing purposes. Traffic logs are captured from the kernel, parsed, and stored in an SQLite database for efficient querying and analysis.
How it works:
- iptables/netfilter logs network traffic from the WireGuard interface to the kernel log
- A background service continuously ingests logs from
journalctlinto the database - Logs are enriched with client identification and DNS resolution data
- Old logs are automatically purged based on retention policy
# Via interactive menu
sudo ./wireshield.sh
# Select option: "Activity Logs Management" -> "Enable/Disable Activity Logging"When enabled, the system logs every NEW connection made by authenticated clients from the WireGuard interface. Logs are captured via iptables LOG rules and ingested into the database in real-time.
Via CLI:
sudo ./wireshield.sh
# Select option: "Activity Logs Management" -> "View User Logs"Via Web Console:
https://<your-server-ip>:443/console
# Navigate to: Traffic Activity
You can:
- View all logs: Display the latest 100 activity records
- Filter by user: View logs for a specific client
- Search: Filter by IP, protocol, or domain name
- Date range: Query logs within a specific time period
CLI Output format:
┌────────────────────┬────────────┬──────┬────────┬─────────────────┬──────┬─────────────────┬──────┬────────────────────┐
│ Time │ Client │ Dir │ Proto │ Source IP │ Port │ Dest IP │ Port │ Domain │
├────────────────────┼────────────┼──────┼────────┼─────────────────┼──────┼─────────────────┼──────┼────────────────────┤
│ 2026-01-19 10:00:00│ alice │ OUT │ TCP │ 10.66.66.2 │ 4433 │ 142.250.185.46 │ 443 │ google.com │
└────────────────────┴────────────┴──────┴────────┴─────────────────┴──────┴─────────────────┴──────┴────────────────────┘
By default, logs are kept for 30 days. You can adjust this period:
# Via interactive menu
sudo ./wireshield.sh
# Select option: "Activity Logs Management" -> "Configure Retention Period"The retention period controls how long activity logs are kept in the database. A background cleanup task runs daily to:
- Delete logs older than the configured retention period
- Record cleanup metrics for monitoring
- Optimize database storage
To change retention via environment variable:
echo "WS_2FA_ACTIVITY_LOG_RETENTION_DAYS=60" >> /etc/wireguard/2fa.env
sudo systemctl restart wireshield# Check renewal timer status
sudo systemctl status wireshield-2fa-renew.timer
# Check renewal service logs
sudo journalctl -u wireshield-2fa-renew.service
# Manually renew certificates
sudo certbot renew --quiet --post-hook "systemctl reload wireshield"
# Test renewal (dry run)
sudo certbot renew --dry-run
# View certificate details
sudo certbot certificates# Check certificate expiry
sudo openssl x509 -in /etc/wireshield/2fa/cert.pem -noout -dates
# Regenerate certificate (365-day validity)
sudo openssl req -x509 -newkey rsa:4096 \
-keyout /etc/wireshield/2fa/key.pem \
-out /etc/wireshield/2fa/cert.pem \
-days 365 -nodes \
-subj "/CN=<your-ip-or-hostname>"
# Restart service
sudo systemctl restart wireshield.service# View ipset allowlists
sudo ipset list ws_2fa_allowed_v4
sudo ipset list ws_2fa_allowed_v6
# View iptables rules (IPv4)
sudo iptables -L WS_2FA_PORTAL -v -n
sudo iptables -L FORWARD -v -n | grep -A 2 wg0
sudo iptables -t nat -L PREROUTING -v -n
# View ip6tables rules (IPv6)
sudo ip6tables -L WS_2FA_PORTAL6 -v -n
sudo ip6tables -L FORWARD -v -n | grep -A 2 wg0# Real-time 2FA service logs
sudo journalctl -u wireshield.service -f
# Monitor WireGuard handshakes
watch -n 2 'sudo wg show'
# Monitor ipset changes
watch -n 5 'sudo ipset list ws_2fa_allowed_v4 | grep -v "^Name:"'
# Check service resource usage
sudo systemctl status wireshield.service | grep -E "Memory|CPU"Symptoms:
- 2FA verification succeeds
- Browser shows "Verification Successful"
- Cannot browse websites or ping external IPs
Diagnosis:
# Check if client IP is in allowlist
sudo ipset list ws_2fa_allowed_v4 | grep <client-wg-ip>
# Check WireGuard handshakes
sudo wg show | grep -A 5 <client-public-key>
# Check recent 2FA logs
sudo journalctl -u wireshield.service -n 50 | grep -i sessionSolutions:
-
Verify firewall rule order:
# Allowlist rule MUST come before portal rule sudo iptables -L FORWARD -n --line-numbers | grep wg0 # Line with "match-set ws_2fa_allowed_v4" should be BEFORE "WS_2FA_PORTAL"
-
Manually add to allowlist (temporary fix):
sudo ipset add ws_2fa_allowed_v4 <client-wg-ip> -exist
-
Check NAT/masquerading:
sudo iptables -t nat -L POSTROUTING -n -v # Should see MASQUERADE rule for public interface
Symptoms:
- Browser cannot load
https://<vpn-domain> - Connection timeout or "server not responding"
Diagnosis:
# Check 2FA service status
sudo systemctl status wireshield.service
# Check if ports are listening
sudo ss -tlnp | grep -E ':80|:443'
# Check firewall INPUT rules
sudo iptables -L INPUT -n | grep -E '80|443'Solutions:
-
Restart 2FA service:
sudo systemctl restart wireshield.service
-
Verify SSL certificate exists:
sudo ls -lh /etc/wireshield/2fa/cert.pem /etc/wireshield/2fa/key.pem
-
Check DNAT rules (for clients behind VPN):
sudo iptables -t nat -L PREROUTING -n -v | grep -E '80|443'
Symptoms:
- Need to re-verify 2FA every few minutes
- Session expires despite active connection
Diagnosis:
# Check current timeout settings
grep -E "IDLE_TIMEOUT|DISCONNECT_GRACE" /etc/wireshield/2fa/config.env
# Check monitor logs
sudo journalctl -u wireshield.service | grep "SESSION_MONITOR"
# Check WireGuard handshake frequency
sudo wg show wg0 | grep "latest handshake"Solutions:
-
Increase idle timeout:
sudo nano /etc/wireshield/2fa/config.env # Change: WS_2FA_SESSION_IDLE_TIMEOUT=7200 # 2 hours sudo systemctl restart wireshield.service -
Enable PersistentKeepalive on client:
# In client .conf file [Peer] PersistentKeepalive = 25 -
Adjust disconnect grace period:
# In /etc/wireshield/2fa/config.env WS_2FA_DISCONNECT_GRACE_SECONDS=60 # More lenient sudo systemctl restart wireshield.service
Symptoms:
- Certificate expiring soon (< 30 days)
- Renewal timer shows failed status
Diagnosis:
# Check renewal service logs
sudo journalctl -u wireshield-2fa-renew.service
# Test renewal
sudo certbot renew --dry-runSolutions:
-
Ensure ports 80/443 are accessible:
# Temporarily stop 2FA service sudo systemctl stop wireshield.service # Test renewal sudo certbot renew --force-renewal # Restart service sudo systemctl start wireshield.service
-
Check DNS resolution:
nslookup <your-domain> # Should resolve to your server IP
-
Manual renewal:
sudo certbot certonly --standalone -d <your-domain> --force-renewal sudo systemctl restart wireshield.service
Symptoms:
- 2FA service won't start
- Errors mentioning SQLite in logs
Diagnosis:
# Check database integrity
sudo sqlite3 /etc/wireshield/2fa/auth.db "PRAGMA integrity_check;"Solutions:
-
Backup and recreate database:
# Backup sudo cp /etc/wireshield/2fa/auth.db /etc/wireshield/2fa/auth.db.backup # Restart service (will recreate tables) sudo systemctl restart wireshield.service
-
Restore from backup (if exists):
sudo systemctl stop wireshield.service sudo cp /etc/wireshield/2fa/auth.db.backup /etc/wireshield/2fa/auth.db sudo systemctl start wireshield.service
# Increase file descriptor limits
sudo nano /etc/systemd/system/wireshield.service
# Add under [Service]:
LimitNOFILE=65535
# Reload and restart
sudo systemctl daemon-reload
sudo systemctl restart wireshield.service# Increase polling interval (edit app.py)
# Change poll_interval from 3 to 5 or 10 seconds
# Trade-off: slower disconnect detection# Clone repository
git clone https://github.com/siyamsarker/WireShield.git
cd WireShield/2fa-auth
# Create virtual environment
python3 -m venv .venv
source .venv/bin/activate # On Windows: .venv\Scripts\activate
# Install dependencies
pip install -r requirements.txt
# Run development server
python app.py
# Service runs on localhost:443 (requires SSL cert/key or disable SSL in code)cd 2fa-auth
source .venv/bin/activate
pytest -vWireShield/
├── wireshield.sh # Main installer and manager CLI
├── LICENSE # GPLv3 license
├── README.md # This file
├── assets/ # Project assets (logo, images)
├── tests/ # Test suite
│ ├── test_rate_limit.py # Rate limiter tests
│ ├── test-2fa-access.sh # 2FA access testing
│ └── test-integration.sh # Integration test suite
└── 2fa-auth/
├── run.py # Service entry point
├── 2fa-helper.sh # Management helper scripts
├── generate-certs.sh # SSL certificate generation script
├── requirements.txt # Python dependencies
├── wireshield.service # Systemd service file
├── app/ # Application package
│ ├── __init__.py # Package initialization
│ ├── main.py # Application factory & startup
│ ├── templates.py # Jinja2 template rendering functions
│ ├── core/ # Core logic
│ │ ├── config.py # Configuration loading
│ │ ├── database.py # Database interactions
│ │ ├── security.py # Authentication & rate limiting
│ │ ├── sniffer.py # Network sniffer & WireGuard monitoring
│ │ └── tasks.py # Background tasks & session management
│ └── routers/ # API endpoints
│ ├── auth.py # Authentication routes
│ ├── console.py # Admin console routes
│ └── health.py # Health check endpoints
├── static/ # Static assets
│ └── fonts/ # Custom fonts
└── templates/ # Jinja2 HTML templates
├── base.html # Base template
├── 2fa_setup.html # 2FA setup page
├── 2fa_verify.html # 2FA verification page
├── success.html # Success page
├── access_denied.html # Access denied page
└── console.html # Admin console dashboard
wireshield.sh
- Interactive installation wizard
- WireGuard configuration generator
- Firewall rules setup (iptables/ip6tables)
- Client management (add/list/revoke)
- SSL/TLS provisioning (Let's Encrypt or self-signed)
app.py
- FastAPI web service (HTTPS server)
- TOTP verification endpoints
- Session management and token generation
- SQLite database operations
- WireGuard handshake monitor (background thread)
- ipset synchronization daemon
- HTTP→HTTPS redirector for captive portal
UI Routes:
GET /- Main 2FA setup/verification pageGET /success- Post-verification success pageGET /health- Health check endpoint
API Routes:
POST /api/setup-start- Generate TOTP secret and QR codePOST /api/setup-verify- Verify initial TOTP code during setupPOST /api/verify- Verify TOTP code for existing usersPOST /api/validate-session- Check session token validity
Admin Console API:
GET /console- Admin console dashboard interfaceGET /api/console/users- User management with pagination and searchGET /api/console/audit-logs- Audit logs with filtering (2FA events, auth attempts)GET /api/console/activity-logs- Traffic activity logs from database with DNS resolutionGET /api/console/activity-metrics- Activity log statistics and retention metricsGET /api/console/dashboard-stats- Dashboard statistics and metricsGET /api/console/bandwidth-usage- Bandwidth usage charts and dataGET /api/console/dashboard-charts- Chart data for visualization
users table:
CREATE TABLE users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
client_id TEXT UNIQUE NOT NULL,
totp_secret TEXT,
backup_codes TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
enabled BOOLEAN DEFAULT 1,
wg_ipv4 TEXT,
wg_ipv6 TEXT
);sessions table:
CREATE TABLE sessions (
id INTEGER PRIMARY KEY AUTOINCREMENT,
client_id TEXT NOT NULL,
session_token TEXT UNIQUE NOT NULL,
expires_at TIMESTAMP NOT NULL,
device_ip TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (client_id) REFERENCES users(client_id)
);audit_log table:
CREATE TABLE audit_log (
id INTEGER PRIMARY KEY AUTOINCREMENT,
client_id TEXT,
action TEXT NOT NULL,
status TEXT,
ip_address TEXT,
timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);activity_log table:
CREATE TABLE activity_log (
id INTEGER PRIMARY KEY AUTOINCREMENT,
timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
client_id TEXT,
direction TEXT,
protocol TEXT,
src_ip TEXT,
src_port TEXT,
dst_ip TEXT,
dst_port TEXT,
raw_line TEXT,
line_hash TEXT UNIQUE
);dns_cache table:
CREATE TABLE dns_cache (
ip_address TEXT PRIMARY KEY,
domain TEXT NOT NULL,
timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);bandwidth_usage table:
CREATE TABLE bandwidth_usage (
id INTEGER PRIMARY KEY AUTOINCREMENT,
client_id TEXT NOT NULL,
scan_date DATE NOT NULL,
rx_bytes INTEGER DEFAULT 0,
tx_bytes INTEGER DEFAULT 0,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
UNIQUE(client_id, scan_date)
);Contributions are welcome! Please:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Development guidelines:
- Follow existing code style
- Add tests for new features
- Update documentation as needed
- Test on multiple distributions before submitting
This project is licensed under the GNU General Public License v3.0 (GPLv3).
See LICENSE file for full terms.
Key permissions:
- ✅ Commercial use
- ✅ Modification
- ✅ Distribution
- ✅ Private use
Conditions:
- Source code must be disclosed
- Modified versions must use same license
- Changes must be documented
Author: Siyam Sarker
Repository: https://github.com/siyamsarker/WireShield
License: GPLv3
Built with:
- WireGuard - Fast, modern VPN protocol
- FastAPI - Modern web framework for Python
- pyotp - TOTP implementation
- qrcode - QR code generation
- SQLite - Embedded database
For issues, questions, or contributions:
- GitHub Issues: https://github.com/siyamsarker/WireShield/issues
- Documentation: This README
- Security Issues: Please report privately via GitHub Security Advisories