A LuCI web application for OpenWrt that provides a user-friendly interface to manage Mullvad WireGuard VPN server selection and monitor connection status.
Download the latest release - Ready-to-install IPK package for all OpenWrt routers.
Install dependencies and the package on your router:
# Install dependencies
opkg update
opkg install luci-base luci-proto-wireguard wireguard-tools curl jsonfilter
# Download and install the package
cd /tmp
wget https://github.com/linakis/luci-app-mullvad/releases/latest/download/luci-app-mullvad_1.0.0_all.ipk
opkg install luci-app-mullvad_1.0.0_all.ipk
# Restart services
/etc/init.d/rpcd restart && /etc/init.d/uhttpd restartThen access the application at Services → Mullvad WireGuard in your router's LuCI interface.
- Server Selection: Browse and select from all available Mullvad WireGuard servers
- Connection Status: Real-time display of connection status, handshake time, and transfer statistics
- Server List Caching: Optional local caching with configurable TTL to reduce API calls
- Manual Refresh: Update server list on-demand from Mullvad's API
- Safe Configuration: Changes are staged and require explicit confirmation before applying
- Status Monitoring: Shows current endpoint, last handshake, and data transfer metrics
- Auto-Detection: Automatically detects your WireGuard interface name on first run
luci-baseluci-proto-wireguardwireguard-toolscurljsonfilter
This app assumes you already have a working Mullvad WireGuard configuration in /etc/config/network with:
- A WireGuard interface (the app will auto-detect it, or defaults to
MullvadWG) - An associated peer section
- Your Mullvad account's private key configured
The app will update the peer's public key and endpoint when switching servers.
If you haven't set up Mullvad WireGuard on OpenWrt yet, follow the official guides:
Official Mullvad Guides:
- WireGuard on a Router - Complete WireGuard setup for routers including OpenWrt
- OpenWrt Routers and Mullvad VPN - General OpenWrt guide (OpenVPN-focused but has useful background)
Quick Setup Summary:
- Install packages:
luci-proto-wireguard,wireguard-tools - Generate WireGuard keys:
wg genkey | tee privatekey | wg pubkey > publickey - Get your Mullvad IP address from the API with your account number and public key
- Configure the WireGuard interface in LuCI (Network → Interfaces)
- Install this app to easily manage server selection
This method works without downloading packages. All files are scripts and configs that work as-is.
- Copy files to your router:
scp -r luci-app-mullvad root@<router-ip>:/root/- SSH into your router:
ssh root@<router-ip>- Install the application (on the router):
cd /root/luci-app-mullvad
cp -r root/* /
cp -r htdocs/* /www/
# Make scripts executable
chmod +x /usr/bin/mullvad-fetch-servers.sh
chmod +x /usr/bin/mullvad-apply-server.sh
chmod +x /usr/bin/mullvad-get-status.sh
# Fix file permissions
chmod 644 /usr/share/rpcd/acl.d/luci-app-mullvad.json
chmod 644 /usr/share/luci/menu.d/luci-app-mullvad.json
chmod 644 /etc/config/mullvad
chmod 644 /www/luci-static/resources/view/mullvad/manager.js
# Fix directory permissions
chmod 755 /www/luci-static/resources/view/mullvad- Initialize configuration (on the router):
uci commit mullvad- Restart services (on the router):
/etc/init.d/rpcd restart
/etc/init.d/uhttpd restart- Verify installation (optional):
# Check that scripts are executable
ls -la /usr/bin/mullvad-*.sh
# Check that all files have correct permissions
ls -la /usr/share/rpcd/acl.d/luci-app-mullvad.json
ls -la /usr/share/luci/menu.d/luci-app-mullvad.json
ls -la /etc/config/mullvad
ls -la /www/luci-static/resources/view/mullvad/manager.js
# Test the fetch script
/usr/bin/mullvad-fetch-servers.sh- Access the application:
- Navigate to your router's LuCI interface (e.g., http://10.0.0.1)
- Go to Services → Mullvad WireGuard
- Open your router's LuCI web interface
- Navigate to Services → Mullvad WireGuard
- View Current Status: The status section shows your current connection state
- Refresh Server List (optional): Click "Refresh Server List" to get the latest servers from Mullvad
- Select Server: Choose a server from the dropdown list
- Servers are displayed in the format: Country - City - Hostname (Provider)
- The list is sorted alphabetically by country, then city, then hostname
- Mullvad-owned servers are labeled as "(Mullvad Owned)"
- Apply Server: Click "Apply Selected Server" to switch to the new server
- Confirm Change: A confirmation dialog will show the server details before applying
- Verify Connection: Status will update within 30 seconds showing the new server
- Enable Caching: Store server list locally to reduce API calls
- Cache TTL: Set how long cached data remains valid (default: 24 hours)
- WireGuard Interface: Specify which interface to manage (auto-detected, or defaults to
MullvadWG)
The app automatically detects your WireGuard interface on first run. However, if you need to manually configure it:
The app will automatically detect your WireGuard interface by:
- Looking for interfaces with
proto=wireguardin/etc/config/network - Checking for an associated peer section following the pattern
wireguard_<InterfaceName> - Saving the detected interface name to
/etc/config/mullvadfor future use
No manual configuration needed in most cases!
If auto-detection doesn't work or you want to specify a different interface:
-
Check your current WireGuard interface name:
wg show # Shows all WireGuard interfaces uci show network | grep "proto='wireguard'" # Shows UCI config
-
Set the interface name manually:
uci set mullvad.config.wireguard_interface='YOUR_INTERFACE_NAME' uci commit mullvad
-
Restart LuCI:
/etc/init.d/uhttpd restart
For an interface named wg0:
uci set mullvad.config.wireguard_interface='wg0'
uci commit mullvadFor the Mullvad guide's recommended name WGINTERFACE:
uci set mullvad.config.wireguard_interface='WGINTERFACE'
uci commit mullvadFetches the server list from Mullvad's API (https://api.mullvad.net/app/v1/relays) and caches it locally.
Usage:
/usr/bin/mullvad-fetch-servers.shOutput: /tmp/mullvad_servers.json
Updates the WireGuard peer configuration with a new server's details.
Usage:
/usr/bin/mullvad-apply-server.sh <hostname> <public_key> <endpoint_ip> <endpoint_port>Example:
/usr/bin/mullvad-apply-server.sh gr-ath-wg-102 "server_public_key" "185.213.154.68" "51820"Retrieves current WireGuard connection status and formats it as JSON.
Usage:
/usr/bin/mullvad-get-status.shOutput: JSON with connection status, endpoint, handshake time, and transfer statistics
config settings 'config'
option cache_enabled '1' # Enable/disable caching
option cache_ttl '86400' # Cache TTL in seconds (24 hours)
option auto_refresh_enabled '0' # Reserved for future use
option wireguard_interface 'MullvadWG' # WireGuard interface name
option last_fetch '0' # Timestamp of last API fetch
config cache 'servers'
option data '' # Cached server list (JSON)
option timestamp '0' # Cache timestamp
When you switch servers, the app updates /etc/config/network:
Before:
config wireguard_MullvadWG
option description 'se-sto-wg-101'
option public_key 'old_server_public_key'
option endpoint_host '185.65.134.66'
option endpoint_port '51820'
After:
config wireguard_MullvadWG
option description 'gr-ath-wg-102'
option public_key 'new_server_public_key'
option endpoint_host '185.213.154.68'
option endpoint_port '51820'
- Check internet connectivity:
ping api.mullvad.net - Verify curl is installed:
opkg list-installed | grep curl - Manually test API:
/usr/bin/mullvad-fetch-servers.sh - Check logs:
logread | grep mullvad
- Verify scripts are executable:
ls -l /usr/bin/mullvad-*.sh - Check UCI permissions:
uci show mullvad - Verify network configuration:
uci show network | grep -A5 MullvadWG - Check WireGuard status:
wg show MullvadWG
- Verify WireGuard interface is up:
ifstatus MullvadWG - Check recent handshake:
wg show MullvadWG latest-handshakes - Test network connectivity:
ping -I MullvadWG 1.1.1.1 - Verify firewall rules allow WireGuard traffic
- Restart LuCI:
/etc/init.d/uhttpd restart - Clear browser cache
- Verify menu file exists:
ls /usr/share/luci/menu.d/luci-app-mullvad.json - Check ACL permissions:
cat /usr/share/rpcd/acl.d/luci-app-mullvad.json
- Ensure scripts are executable:
chmod +x /usr/bin/mullvad-*.sh - Verify ACL file is present and valid
- Check rpcd is running:
/etc/init.d/rpcd status - Restart rpcd:
/etc/init.d/rpcd restart
- Private Key Protection: Your Mullvad private key is never exposed or modified by this app
- ACL Restrictions: The app uses minimal permissions (UCI access for network/mullvad configs only)
- Input Validation: All scripts validate inputs to prevent command injection
- HTTPS Only: Always access LuCI over HTTPS in production environments
- API Security: Server list is fetched over HTTPS from Mullvad's official API
On first run or when not configured, the app automatically detects your WireGuard interface:
- Searches for WireGuard interfaces with
proto=wireguardin/etc/config/network - Validates the interface by checking for an associated peer section (
wireguard_<InterfaceName>) - Saves the detected name to
/etc/config/mullvadfor future use - Falls back to
MullvadWGif auto-detection fails
This ensures compatibility with any WireGuard interface name, whether you followed Mullvad's official guide (using WGINTERFACE) or chose your own naming convention.
- User selects a server in the UI
- JavaScript calls backend script with server details
mullvad-apply-server.shupdates UCI network configuration- Script commits changes but doesn't reload network immediately
- LuCI's save/apply mechanism triggers network reload
- WireGuard interface reconnects to the new server
- Status display updates with new endpoint information
Connection is considered active when:
- WireGuard interface is up
- Peer endpoint is configured
- Last handshake occurred within 3 minutes
Mullvad API → fetch script → /tmp/cache → UCI config → JavaScript UI
↓
User Selection → apply script → UCI network config → network reload
↑
Auto-detect interface (first run)
GET https://api.mullvad.net/app/v1/relays
Returns a list of all Mullvad relay servers including WireGuard configurations.
When modifying this application:
- Test all changes on a development router first
- Verify ACL permissions are minimal and appropriate
- Ensure backward compatibility with existing configurations
- Update this README with any new features or changes
This is a custom application for managing Mullvad WireGuard configurations on OpenWrt routers.
- 1.0.0 - Initial release
- Server selection and switching
- Connection status monitoring
- Country/city filtering
- Server list caching
- Manual refresh capability
