Operational Security Guide¶
Security recommendations for running and using MoaV safely.
Table of Contents¶
- For Server Operators
- Server Security
- Firewall & Docker
- Admin & Monitoring Access Control
- Domain Security
- Credential Management
- Monitoring
- Docker Security Hardening
- If Server is Blocked
- For Users
- Device Security
- Connection Security
- App Security
- Behavior Security
- If You Suspect Compromise
- Distribution Security
- Legal Considerations
- Emergency Procedures
- Checklist
For Server Operators¶
Server Security¶
-
Keep system updated:
-
Use SSH keys, disable password auth:
-
Change SSH port (optional but recommended):
Firewall & Docker¶
Important: Docker bypasses UFW/iptables. Docker publishes ports by inserting iptables rules before UFW's chains. This means
ufw deny 9443does NOT block access to port 9443 if Docker is publishing it. Ports listed indocker-compose.ymlunderports:are publicly accessible regardless of UFW rules.Ports listed under
expose:(withoutports:) are Docker-internal only and NOT affected.
Basic UFW setup (for non-Docker ports like SSH):
Warning: UFW rules only effectively control non-Docker services (SSH, system services). For Docker-published ports, use the methods below.
Protocol ports (published by Docker — UFW rules are informational only):
| Port | Service | Notes |
|---|---|---|
| 443/tcp | Reality (VLESS) | Required |
| 443/udp | Hysteria2 | Required if enabled |
| 8443/tcp | Trojan | Required if enabled |
| 4443/tcp+udp | TrustTunnel | Required if enabled |
| 2082/tcp | CDN WebSocket | Required if enabled |
| 51820/udp | WireGuard | Required if enabled |
| 51821/udp | AmneziaWG | Required if enabled |
| 8080/tcp | wstunnel | Required if enabled |
| 993/tcp | Telegram MTProxy | Required if enabled |
| 2096/tcp | XHTTP | Required if enabled |
| 53/udp | XDNS (default) or dnstt/Slipstream | Required if DNS tunnels enabled |
| 5353/udp | dnstt/Slipstream (when XDNS uses 53) | Only if dnstt/Slipstream enabled alongside XDNS |
| 80/tcp | Let's Encrypt | Required during cert renewal |
| 9443/tcp | Admin dashboard | See access control below |
| 9444/tcp | Grafana | See access control below |
| 2083/tcp | Grafana CDN proxy | See access control below |
Protocol ports (Reality, Hysteria2, etc.) are designed to be public — they require authentication. The concern is admin/monitoring ports.
Option 1: Use ADMIN_IP_WHITELIST (Recommended)¶
MoaV's admin dashboard has built-in IP whitelisting. Set in .env:
# Allow only your IP (comma-separated for multiple)
ADMIN_IP_WHITELIST=YOUR_HOME_IP,YOUR_OFFICE_IP
# Then restart admin
moav restart admin
This blocks all other IPs at the application level, regardless of Docker/UFW.
Option 2: Bind to localhost + SSH tunnel¶
For maximum security, bind admin/monitoring to 127.0.0.1 so they're only accessible via SSH tunnel:
Then access via SSH tunnel:
# From your local machine
ssh -L 9443:127.0.0.1:9443 -L 9444:127.0.0.1:9444 root@YOUR_SERVER
# Then open https://localhost:9443 in your browser
Option 3: ufw-docker (Advanced)¶
ufw-docker patches UFW to work with Docker by adding rules to the DOCKER-USER iptables chain. This makes ufw commands effective for Docker ports.
# Install
sudo wget -O /usr/local/bin/ufw-docker https://github.com/chaifeng/ufw-docker/raw/master/ufw-docker
sudo chmod +x /usr/local/bin/ufw-docker
sudo ufw-docker install
sudo systemctl restart ufw
# Allow specific ports from any IP
sudo ufw-docker allow moav-sing-box 443/tcp
sudo ufw-docker allow moav-sing-box 443/udp
# Allow admin only from your IP
sudo ufw-docker allow moav-admin 8443/tcp from YOUR_IP
Trade-offs: Requires modifying UFW config files (
/etc/ufw/after.rules). Rules useufw routesyntax. Needs reload after container restarts. Works well but adds complexity. For most users,ADMIN_IP_WHITELISTis simpler.
Admin & Monitoring Access Control¶
Admin dashboard (https://server:9443):
- Username: admin
- Password: set during install (in .env as ADMIN_PASSWORD)
- Reset: moav admin password
- IP whitelist: ADMIN_IP_WHITELIST in .env
Grafana (https://server:9444):
- Username: admin
- Password: same as ADMIN_PASSWORD
- Accessible from any IP by default (password-protected)
Internal services (not publicly accessible):
- Prometheus (9091) — expose: only, Docker-internal
- All exporters — expose: only, Docker-internal
- cAdvisor — expose: only, Docker-internal
- Docker socket proxy — expose: only, Docker-internal
Domain Security¶
- Use WHOIS privacy — hide personal information in domain registration
- Use a neutral registrar — avoid country-specific registrars
- Keep registration info generic — don't use real name if possible
- Pay anonymously — use crypto if available
- Separate domain from identity — don't use a domain linked to your name
Credential Management¶
- Never share master credentials — each user gets unique credentials
- Revoke compromised users immediately:
- Rotate server keys periodically — re-bootstrap if concerned
- Keep backups:
- Use strong admin password — at least 16 characters, generated randomly
Monitoring¶
-
Use
moav doctorto check for configuration issues: -
Check logs regularly:
-
Inspect connections to see who's connecting and what they're accessing:
-
Grafana dashboards (if monitoring enabled):
- Per-user traffic and connections
- GeoIP country distribution
- Protocol breakdown
-
System health (CPU, RAM, disk)
-
Watch for unusual patterns:
- Sudden traffic spikes from unexpected countries
- Single IPs with very high error counts (scanning/probing)
- Connections to suspicious destinations
Docker Security Hardening¶
MoaV applies these hardening measures to all containers (since v1.7.2):
cap_drop: ALL— drops all Linux capabilities, adds back only what's neededread_only: true— read-only root filesystem with targetedtmpfsmountsno-new-privileges: true— prevents privilege escalationmem_limitandcpus— resource limits per container- Non-root users — containers run as unprivileged
moavuser where possible - Docker socket proxy — admin uses
tecnativa/docker-socket-proxyinstead of mounting the raw Docker socket
If Server is Blocked¶
- Try different protocols first — switch from Reality to Hysteria2, XHTTP, or CDN mode
- CDN mode — routes through Cloudflare/CloudFront, works when server IP is blocked
- DNS tunnels — XDNS/dnstt/Slipstream work when most traffic is blocked
- If IP is burned:
- Donate bandwidth — even if your server is blocked for your users, it can still serve millions through Psiphon Conduit, Tor Snowflake, and MahsaNet
For Users¶
Device Security¶
- Use a separate profile/user for circumvention apps on shared devices
- Don't screenshot QR codes — or delete immediately after import
- Delete bundle files after importing to your apps
- Use device encryption — enable full disk encryption
- Set strong device PIN/password
Connection Security¶
- Verify you're connected:
- Check your IP: https://whatismyip.com
-
Should show server IP, not your real IP
-
Use HTTPS everywhere even over tunnel:
- The tunnel encrypts transport, HTTPS encrypts content
-
Protects against compromised tunnel endpoints
-
Don't trust public WiFi even with VPN:
- Your device can still be attacked locally
- Tunnel doesn't protect against local network attacks
App Security¶
- Keep apps updated — updates often fix detection bypasses
- Download from official sources:
- iOS: App Store (Happ, Streisand, Hiddify)
- Android: GitHub releases (Happ, v2rayNG, Hiddify)
-
Avoid random APK sites
-
Backup your configs — export from apps, store securely
Behavior Security¶
- Don't share your credentials — each person should have their own
- Don't share screenshots showing server addresses or QR codes
- Don't mention specific servers in public forums
- Use secure messaging to receive configs (Signal, encrypted email)
If You Suspect Compromise¶
- Stop using that config immediately
- Contact admin for new credentials
- Check your device for malware
- Change passwords for any accounts accessed over that connection
Distribution Security¶
Sharing Bundles Safely¶
DO: - Use end-to-end encrypted messaging (Signal, Telegram secret chat) - Share in person when possible (scan QR code directly) - Use encrypted file sharing (OnionShare) - Delete messages after recipient confirms receipt
DON'T: - Email unencrypted configs - Post links in public channels - Share via unencrypted cloud storage - Send screenshots of QR codes to groups
Recommended Distribution Methods¶
- In Person — safest, scan QR code directly
- Signal — send configs as files, enable disappearing messages
- Telegram (Secret Chat only) — NOT regular chats, use self-destruct timer
- Admin Dashboard — share download links directly (HTTPS, password-protected)
Legal Considerations¶
Disclaimer: This is not legal advice.
- Laws vary by country — running or using circumvention tools may carry legal risks
- Assess your personal risk level
- The decoy website provides plausible deniability (server looks like a normal HTTPS site)
Data Retention¶
MoaV is configured for minimal logging: - No URLs logged - No request content - Basic connection stats only (for admin dashboard) - IP addresses are in memory only (not persisted to disk)
To minimize logging further:
Emergency Procedures¶
If You Think You're Monitored¶
- Stop using current credentials
- Contact admin through alternate channel
- Get fresh credentials
- Consider using a different device
- Assess whether to continue using service
If Server is Seized¶
User data exposure is limited: - No content is logged - IP addresses are in memory only - User identifiers are usernames (not real names)
But assume: - Server IP is known - User identifiers are known - Active connections at time of seizure are known
If User is Compromised¶
As admin:
1. Revoke user immediately: moav user revoke username
2. Monitor for unusual activity
3. Consider rotating server if credentials were extracted
4. Do NOT contact compromised user through normal channels
Checklist¶
Server Operator¶
- [ ] SSH keys only, no password auth
- [ ] SSH port changed from default 22
- [ ] System auto-updates enabled
- [ ] Admin IP whitelist configured (
ADMIN_IP_WHITELIST) - [ ] Strong admin password (16+ characters)
- [ ] Unique user credentials for everyone
- [ ]
moav doctorpasses all checks - [ ] Backup plan if blocked (new IP or migration ready)
- [ ] Secure distribution channel established
- [ ] Monitoring enabled (Grafana) or logs checked regularly
User¶
- [ ] Device encrypted
- [ ] App from official source
- [ ] Config imported securely
- [ ] Bundle files deleted after import
- [ ] Knows which protocol to try if one fails
- [ ] Knows how to contact admin securely