WrtNova – browser config generator that builds pre-configured images via OpenWrt's ASU

Hello!
I hope you're doing well I wanted to ask if I didn't select "Enable Internet Access for IoT Devices" when building the firmware how can I enable it afterwards?

Edit IoT firewall zone, in the Allow forward to destination zones:, choose wan zone, save and apply.

1 Like

Thank you so much one more thing are seperate rules needed when the wan is doing the same thing like for guest and iot? For example I understand the dns dhcp and ntp rule others like dhcpv6 icmp ping mld etc?

Those exist just in case someone has IPv6 PD GUA bigger than /64 and decides to use it for the IoT and Guest interfaces.

1 Like

Hello, this is really nice and very interesting concept, especially for those that are affraid of CLI and package hunting. very cool keep it up!!! Kudos!

1 Like

May I ask how is the WireGuard setup is done to make it seperated from the wan I'm trying to learn to do things myself also not just rely on a automated configuration because I'm trying to do this setup just using normal bridge ports and not vlans with pbr but that's not getting it to work I saw that with mwan3 there were no routing tables that the configuration made but without mwan3 it creates ipv4 routes when I tried doing it myself it didn't work out so if you're willing to help I would appreciate it my goal is to seperate wireguard from main to just be routed through that wifi network

First make sure you have luci-proto-wireguard installed.
These are the basic steps. Remember to edit the variables at the top, then copy and paste the commands over SSH and reboot the router.

You'll still need to set up the watchdog and connection probe scripts. For more details, see:

# WireGuard tunnel (from your provider's config)
WG_PRIVATE_KEY=
WG_CLIENT_IPV4='172.16.0.2/32'
WG_CLIENT_IPV6='2606:4700:110:8398:66a4:acc3:d66f:2731/128'
WG_DNS_IPV4=
WG_DNS_IPV6=

PEER_PUBLIC_KEY=''
PRESHARED_KEY=''
ENDPOINT_HOST='162.159.192.8'
ENDPOINT_PORT='2408'

WG_IFACE='wg0'		# e.g. wg0, wg1, ...
WG_ROUTE_TABLE='20'	# Each tunnel should have its own routing table

# LAN VPN network
LAN_VPN_IF='lan_wg0'
LAN_VPN_BRIDGE='br-wg0'
LAN_VPN_IPV4='192.168.7.1'
#LAN_PORT='lan1'		# Which lan port to attach to this bridge

# WiFi
WIFI_RADIO='radio1'
WIFI_SSID='MyVPN'
WIFI_KEY='123123123'
WIFI_ENC='psk2'

# === End config section ===

# 1. WireGuard client interface (routes go into table 20)
uci set network."$WG_IFACE"=interface
uci set network."$WG_IFACE".proto='wireguard'
uci set network."$WG_IFACE".private_key="$WG_PRIVATE_KEY"
uci add_list network.vpn.addresses="$WG_CLIENT_IPV4"
[ -n "$WG_CLIENT_IPV6" ] && uci add_list network."$WG_IFACE".addresses="$WG_CLIENT_IPV6"
uci set network."$WG_IFACE".ip4table="$WG_ROUTE_TABLE"
uci set network."$WG_IFACE".ip6table="$WG_ROUTE_TABLE"

# 2. WireGuard peer
uci add network wireguard_"$WG_IFACE"
uci set network.@wireguard_vpn[-1].public_key="$PEER_PUBLIC_KEY"
[ -n "$PRESHARED_KEY" ] && uci set network.@wireguard_vpn[-1].preshared_key="$PRESHARED_KEY"
uci set network.@wireguard_vpn[-1].endpoint_host="$ENDPOINT_HOST"
uci set network.@wireguard_vpn[-1].endpoint_port="$ENDPOINT_PORT"
uci set network.@wireguard_vpn[-1].persistent_keepalive='25'
uci set network.@wireguard_vpn[-1].route_allowed_ips='1'
uci add_list network.@wireguard_vpn[-1].allowed_ips='0.0.0.0/0'
uci add_list network.@wireguard_vpn[-1].allowed_ips='::/0'

# 3. $LAN_VPN_IF bridge + LAN VPN interface
uci add network device
uci set network.@device[-1].type='bridge'
uci set network.@device[-1].name="$LAN_VPN_BRIDGE"
[ -n "$LAN_PORT" ] && {
	uci add_list network.@device[-1].ports="$LAN_PORT"
	uci del_list network.@device[0].ports="$LAN_PORT"
}

uci set network."$LAN_VPN_IF"=interface
uci set network."$LAN_VPN_IF".proto='static'
uci set network."$LAN_VPN_IF".device="$LAN_VPN_BRIDGE"
uci add_list "network.${LAN_VPN_IF}.ipaddr=${LAN_VPN_IPV4}/24"
uci set network."$LAN_VPN_IF".ip6assign='60'
uci add_list network."$LAN_VPN_IF".ip6class='local'

# 4. DHCP for LAN VPN clients
uci set dhcp."$LAN_VPN_IF"=dhcp
uci set dhcp."$LAN_VPN_IF".interface="$LAN_VPN_IF"
uci set dhcp."$LAN_VPN_IF".start=100
uci set dhcp."$LAN_VPN_IF".limit=100
uci set dhcp."$LAN_VPN_IF".leasetime=12h
uci set dhcp."$LAN_VPN_IF".ra='server'
uci set dhcp."$LAN_VPN_IF".dhcpv6='server'
uci set dhcp."$LAN_VPN_IF".ra_default='1'
uci add_list dhcp."$LAN_VPN_IF".ra_flags='managed-config'
uci add_list dhcp."$LAN_VPN_IF".ra_flags='other-config'
uci add_list "dhcp.${LAN_VPN_IF}.dhcp_option=6,${WG_DNS_IPV4:-$LAN_VPN_IPV4}"
[ -n "$WG_DNS_IPV6" ] && uci add_list dhcp."$LAN_VPN_IF".dns="$WG_DNS_IPV6"

# 5. WiFi SSID bound to "$LAN_VPN_IF" iface
uci set wireless.wifi_"$LAN_VPN_IF"=wifi-iface
uci set wireless.wifi_"$LAN_VPN_IF".device="$WIFI_RADIO"
uci set wireless.wifi_"$LAN_VPN_IF".mode='ap'
uci set wireless.wifi_"$LAN_VPN_IF".network="$LAN_VPN_IF"
uci set wireless.wifi_"$LAN_VPN_IF".ssid="$WIFI_SSID"
uci set wireless.wifi_"$LAN_VPN_IF".encryption="$WIFI_ENC"
uci set wireless.wifi_"$LAN_VPN_IF".key="$WIFI_KEY"

# 6. Policy routing + routing level kill switch
# from "$LAN_VPN_IF" -> use table 20 (WG). If the table has no route (tunnel
# down), prohibit instead of falling through to main table -> no leak.
uci add network rule
uci set network.@rule[-1].in="$LAN_VPN_IF"
uci set network.@rule[-1].lookup="$WG_ROUTE_TABLE"
uci set network.@rule[-1].priority='990'

uci add network rule6
uci set network.@rule6[-1].in="$LAN_VPN_IF"
uci set network.@rule6[-1].lookup="$WG_ROUTE_TABLE"
uci set network.@rule6[-1].priority='990'

uci add network rule
uci set network.@rule[-1].in="$LAN_VPN_IF"
uci set network.@rule[-1].action='prohibit'
uci set network.@rule[-1].priority='991'

uci add network rule6
uci set network.@rule6[-1].in="$LAN_VPN_IF"
uci set network.@rule6[-1].action='prohibit'
uci set network.@rule6[-1].priority='991'

# 7. Firewall: VPN clients zone + tunnel zone (NAT4+NAT6, MSS clamp)
uci add firewall zone
uci set firewall.@zone[-1].name="vpn_lan"
uci add_list firewall.@zone[-1].network="$LAN_VPN_IF"
uci set firewall.@zone[-1].input='ACCEPT'
uci set firewall.@zone[-1].output='ACCEPT'
uci set firewall.@zone[-1].forward='REJECT'

uci add firewall zone
uci set firewall.@zone[-1].name='vpn_wan'
uci add_list firewall.@zone[-1].network="$WG_IFACE"
uci set firewall.@zone[-1].masq='1'
uci set firewall.@zone[-1].masq6='1'
uci set firewall.@zone[-1].mtu_fix='1'
uci set firewall.@zone[-1].input='REJECT'
uci set firewall.@zone[-1].output='ACCEPT'
uci set firewall.@zone[-1].forward='REJECT'

# forward "$LAN_VPN_IF" -> tunnel
uci add firewall forwarding
uci set firewall.@forwarding[-1].src="vpn_lan"
uci set firewall.@forwarding[-1].dest='vpn_wan'

uci commit
1 Like

Thank you so much!

I setup WireGuard works but now having and issue which I didn't normally did when using WrtNova configuration was that it always connected WireGuard it never had an issue where because of NTP time it didn't connect properly I have to sometimes restart the WireGuard interface to make it work I added the Race Condition script from WireGuard extra that works but then because of it setting the time to 2030 vnstat2 having an issue that it's showing data of only that day and year etc

What kind of script and setup you had that fixed this WireGuard issue of Time Issue on Boot Up?

It's in wrtnova.sh

hplug_ifup_wan=/etc/hotplug.d/iface/96-ifup-wan
cat > "$hplug_ifup_wan" <<'EOF'
[ ifup = "$ACTION" ] || exit 0
. /lib/functions/network.sh
sleep 5
network_find_wan WAN_IF
network_find_wan6 WAN6_IF

[ "$WAN_IF" = "$INTERFACE" ] ||
[ "$WAN6_IF" = "$INTERFACE" ] || exit 0

ntpd -q -p pool.ntp.org &
EOF

wg_iface=${WG_IFACE:-vpn}
[ "$WG_ENABLE" = 1 ] && [ "$AP_MODE" != 1 ] && {
	echo "*/2 * * * * wireguard_watchdog" >> /etc/crontabs/root
	echo "*/10 * * * * wg-check $wg_iface" >> /etc/crontabs/root
	_uci system "" "@system[0]" cronloglevel=9

	cat > /etc/hotplug.d/iface/98-wg-"$wg_iface" <<-EOF
	[ ifup = "\$ACTION" ] || exit 0
	[ $wg_iface = "\$INTERFACE" ] || exit 0

	[ -x /usr/sbin/mwan3 ] && {
		ip -6 ru | grep '^999:' ||
		ip -6 ru add iif lo lookup 2 prio 999
	}

	sleep 2
	wg-check $wg_iface
	EOF
}

cat > /sbin/wg-check <<'EOF'
#!/bin/sh
IFACE=$1
PING_IP=${2:-9.9.9.9}
PING_IP6=${3:-2620:fe::9}
[ -z "$IFACE" ] && exit 0
[ -d /sys/class/net/"$IFACE" ] || exit 0

L=/tmp/${IFACE}_lock
mkdir "$L" || exit 0
trap 'rmdir "$L"' EXIT

ping -c2 -W2 -I "$IFACE" "$PING_IP" ||
ping6 -c2 -W2 -I "$IFACE" "$PING_IP6" || {
	ifdown "$IFACE"
	sleep 2
	ifup "$IFACE"
}
EOF
chmod +x /sbin/wg-check

I have ipv6 completely disabled from everywhere so would this script be alright or it needs some changing?

my wireguard interface name is wg_mullvad and the lan interface name as vpn

Just try it bro.

I literally just copied what was in wrtnova.sh, so you'll need to adapt it.

Okay I will try :sweat_smile::sweat_smile:

I added the script I ls'ed into the folder of hotplug it only shows 96-ifup-wan file only also I don't see the cron jobs for wireguard watchdog and wg-check in the scheduled tasks list and I get this error

Tue Jan  1 00:04:02 2030 cron.err crond[1638]: user root: parse error at sleep
Thu Jul  2 23:57:16 2026 cron.err crond[1638]: user root: parse error at sleep
Thu Jul  2 23:57:16 2026 cron.err crond[1638]: time disparity of -1840326 minutes detected

also edited the script removed ipv6 things and changed the interface name to what mine is to actually can you confirm it's correct?

hplug_ifup_wan=/etc/hotplug.d/iface/96-ifup-wan
cat > "$hplug_ifup_wan" <<'EOF'
[ ifup = "$ACTION" ] || exit 0
. /lib/functions/network.sh
sleep 5
network_find_wan WAN_IF

[ "$WAN_IF" = "$INTERFACE" ] || exit 0

ntpd -q -p pool.ntp.org &
EOF

wg_iface=${WG_IFACE:-wg_mullvad}

[ "$WG_ENABLE" = 1 ] && [ "$AP_MODE" != 1 ] && {
	echo "*/2 * * * * wireguard_watchdog" >> /etc/crontabs/root
	echo "*/10 * * * * wg-check $wg_iface" >> /etc/crontabs/root
	_uci system "" "@system[0]" cronloglevel=9

	cat > /etc/hotplug.d/iface/98-wg-"$wg_iface" <<-EOF
	[ ifup = "\$ACTION" ] || exit 0
	[ $wg_iface = "\$INTERFACE" ] || exit 0

	sleep 2
	wg-check $wg_iface
	EOF
}

cat > /sbin/wg-check <<'EOF'
#!/bin/sh
IFACE=$1
PING_IP=${2:-9.9.9.9}
[ -z "$IFACE" ] && exit 0
[ -d /sys/class/net/"$IFACE" ] || exit 0

L=/tmp/${IFACE}_lock
mkdir "$L" || exit 0
trap 'rmdir "$L"' EXIT

ping -c2 -W2 -I "$IFACE" "$PING_IP" || {
	ifdown "$IFACE"
	sleep 2
	ifup "$IFACE"
}
EOF
chmod +x /sbin/wg-check

Hello! I hope you're doing well
I wanted to say that when you're not even enabling or selecting DDNS option in wrtnova builder it still adds luci-app-ddns in packages list shouldn't this be removed and only added when someone wants to add DDNS?

You are right. I'l fix that.

1 Like