UCI script creation help

Hello!
I am recovering from self-inflicted router failure and consequently I'm redoing my router from scratch. To help me learn better and be able to recover quicker from crashes, I'm trying to create a script for setting everything up. I've combined several different things I've found on the internet, I've pasted it below.
Here are my questions:

  1. Do you have any advice on making the script better? Should I add anything to the firewall, etc?
  2. I'd like to attach one physical port from the router to the "guest" network. How do i script that up?

I'm using a TP-LINK archer C2600, OenWrt 21.02.1
Thank you for your help!

# Configuration parameters
NET_ID="guest"
NET_ID1="guest2"
SSID_guest0="wifi_5G_Guest"
SSID_guest1="wifi_Guest"
GST_PSK_KEY="PasswordGuest"
SSID_LAN0="wifi_5G"
SSID_LAN1="wifi"
PSK_KEY="SuperStrongPassword"
WIFI_DEV0="$(uci get wireless.@wifi-iface[0].device)"
WIFI_DEV1="$(uci get wireless.@wifi-iface[1].device)" 

# Fetch upstream zone
. /lib/functions/network.sh
network_flush_cache
network_find_wan NET_IF
FW_WAN="$(fw3 -q network "${NET_IF}")"
 
# Set up guest WLAN
uci -q batch << EOF
delete network.${NET_ID}_dev
set network.${NET_ID}_dev=device
set network.${NET_ID}_dev.type=bridge
set network.${NET_ID}_dev.name=br-${NET_ID}
delete network.${NET_ID}
set network.${NET_ID}=interface
set network.${NET_ID}.proto=static
set network.${NET_ID}.device=br-${NET_ID}
set network.${NET_ID}.ipaddr=192.168.99.1
set network.${NET_ID}.netmask=255.255.255.0
commit network
set wireless.radio0.channel='36'
set wireless.default_radio0.ssid=${SSID_LAN0}
set wireless.default_radio0.encryption="psk2"
set wireless.default_radio0.key="${PSK_KEY}"
set wireless.radio1.channel='11'
set wireless.default_radio1.ssid=${SSID_LAN1}
set wireless.default_radio1.encryption="psk2"
set wireless.default_radio1.key="${PSK_KEY}"
delete wireless.${NET_ID}
set wireless.${NET_ID}=wifi-iface
set wireless.${NET_ID}.device=${WIFI_DEV0}
set wireless.${NET_ID}.mode=ap
set wireless.${NET_ID}.network=${NET_ID}
set wireless.${NET_ID}.ssid=${SSID_guest0}
set wireless.${NET_ID}.encryption="psk2"
set wireless.${NET_ID}.key="${GST_PSK_KEY}"
delete wireless.${NET_ID1}
set wireless.${NET_ID1}="wifi-iface"
set wireless.${NET_ID1}.device="${WIFI_DEV1}"
set wireless.${NET_ID1}.mode="ap"
set wireless.${NET_ID1}.network="guest"
set wireless.${NET_ID1}.ssid=${SSID_guest1}
set wireless.${NET_ID1}.encryption="psk2"
set wireless.${NET_ID1}.key="${GST_PSK_KEY}"
commit wireless
delete dhcp.${NET_ID}
set dhcp.${NET_ID}=dhcp
set dhcp.${NET_ID}.interface=${NET_ID}
set dhcp.${NET_ID}.start=100
set dhcp.${NET_ID}.limit=150
set dhcp.${NET_ID}.leasetime=1h
commit dhcp
delete firewall.${NET_ID}
set firewall.${NET_ID}=zone
set firewall.${NET_ID}.name=${NET_ID}
set firewall.${NET_ID}.network=${NET_ID}
set firewall.${NET_ID}.input=REJECT
set firewall.${NET_ID}.output=ACCEPT
set firewall.${NET_ID}.forward=REJECT
delete firewall.${NET_ID}_${FW_WAN}
set firewall.${NET_ID}_${FW_WAN}=forwarding
set firewall.${NET_ID}_${FW_WAN}.src=${NET_ID}
set firewall.${NET_ID}_${FW_WAN}.dest=${FW_WAN}
delete firewall.${NET_ID}_dns
set firewall.${NET_ID}_dns=rule
set firewall.${NET_ID}_dns.name=Allow-DNS-${NET_ID}
set firewall.${NET_ID}_dns.src=${NET_ID}
set firewall.${NET_ID}_dns.dest_port=53
add_list firewall.${NET_ID}_dns.proto=tcp
add_list firewall.${NET_ID}_dns.proto=udp
set firewall.${NET_ID}_dns.target=ACCEPT
delete firewall.${NET_ID}_dhcp
set firewall.${NET_ID}_dhcp=rule
set firewall.${NET_ID}_dhcp.name=Allow-DHCP-${NET_ID}
set firewall.${NET_ID}_dhcp.src=${NET_ID}
set firewall.${NET_ID}_dhcp.dest_port=67
set firewall.${NET_ID}_dhcp.proto=udp
set firewall.${NET_ID}_dhcp.family=ipv4
set firewall.${NET_ID}_dhcp.target=ACCEPT
commit firewall
EOF
/etc/init.d/network reload
/etc/init.d/dnsmasq restart
/etc/init.d/firewall restart

I was told that it's not guaranteed which radio (bgn or acn) will come up in the list first, so the config_foreach is a safer option:

setup_radio() {
	local radio="$1"
	uci -q del "wireless.${radio}.disabled"
	uci set "wireless.${radio}.channel=auto"
	uci set "wireless.${radio}.country=XX"
	uci set "wireless.default_${radio}.key=wifipassword"
	uci set "wireless.default_${radio}.encryption=psk2+ccmp"
	uci set "wireless.default_${radio}.bursting=1"
	uci set "wireless.default_${radio}.compression=1"
	uci set "wireless.default_${radio}.legacy_rates=0"
	uci set "wireless.default_${radio}.disassoc_low_ack=0"
	uci set "wireless.default_${radio}.ff=1"
	uci set "wireless.default_${radio}.skip_inactivity_poll=1"
	uci set "wireless.default_${radio}.turbo=1"
	uci set "wireless.default_${radio}.wpa_group_rekey=3600"
	uci set "wireless.default_${radio}.wps_pushbutton=0"
	uci set "wireless.default_${radio}.wpa_disable_eapol_key_retries=1"
	if [ "$(uci -q get wireless."${radio}".hwmode)" = "11a" ]; then
		uci set "wireless.${radio}.htmode=VHT80"
		uci set "wireless.${radio}.txpower=23"
		uci set "wireless.default_${radio}.ssid=SSID-5G"
	else
		uci set "wireless.${radio}.htmode=HT40+"
		uci set "wireless.${radio}.noscan=1"
		uci set "wireless.${radio}.txpower=30"
		uci set "wireless.default_${radio}.ssid=SSID"
	return 0
}
. /lib/functions.sh; config_load 'wireless'; 
config_foreach setup_radio 'wifi-device'; uci commit wireless;

You way want to add setup of the Guest SSIDs on both or a single radio only.

2 Likes

might give you a few ideas.

Thanks for the replies stangri and mercygroundabyss, I appreciate you taking the time to send me some information.

I spent more time on this than I'd like to admit, but I learned some new things and i'm pretty good at getting out of soft bricking my router. Below is my latest, I'm still looking for feedback and any ideas on adding a port to the "guest" network.

#!/bin/sh
# Configuration parameters
NET_ID="guest"
NET_ID1="guest2"
SSID_guest_5G="test_5G_Guest"
SSID_guest_24G="test_Guest"
GST_PSK_KEY="test"
SSID_LAN_5G="test_5G"
SSID_LAN_24G="test"
PSK_KEY="test"
setup_radio() {
	local radio="$1"
	echo "radio is: $radio"
	local hw_mode="$(uci -q get wireless."${radio}".hwmode)"
	#echo "hwmode is: $hw_mode"
	
	uci -q del "wireless.${radio}.disabled"
	uci set "wireless.${radio}.channel=auto"
	#uci set "wireless.${radio}.country=XX"
	uci set wireless.default_${radio}.key=${PSK_KEY}
	uci set wireless.default_${radio}.encryption=psk2
	#uci set "wireless.default_${radio}.bursting=1"
	#uci set "wireless.default_${radio}.compression=1"
	#uci set "wireless.default_${radio}.legacy_rates=0"
	#uci set "wireless.default_${radio}.disassoc_low_ack=0"
	#uci set "wireless.default_${radio}.ff=1"
	#uci set "wireless.default_${radio}.skip_inactivity_poll=1"
	#uci set "wireless.default_${radio}.turbo=1"
	#uci set "wireless.default_${radio}.wpa_group_rekey=3600"
	#uci set "wireless.default_${radio}.wps_pushbutton=0"
	#uci set "wireless.default_${radio}.wpa_disable_eapol_key_retries=1"
	
	
	#uci delete wireless.guest_${radio}
	uci set wireless.guest_${radio}=wifi-iface
	uci set wireless.guest_${radio}.device=${radio}
	uci set wireless.guest_${radio}.mode=ap
	uci set wireless.guest_${radio}.network=${NET_ID}
	uci set wireless.guest_${radio}.encryption="psk2"
	uci set wireless.guest_${radio}.key="${GST_PSK_KEY}"
	
	if [ "$hw_mode" == "11a" ]; then
		#uci set "wireless.${radio}.htmode=VHT80"
		#uci set "wireless.${radio}.txpower=23"
		uci set wireless.default_${radio}.channel='12'
		uci set wireless.default_${radio}.ssid=${SSID_LAN_5G}
		
		uci set wireless.guest_${radio}.ssid=${SSID_guest_5G}
	else
		#uci set "wireless.${radio}.htmode=HT40+"
		#uci set "wireless.${radio}.noscan=1"
		#uci set "wireless.${radio}.txpower=30"
		uci set wireless.default_${radio}.channel='36'
		uci set wireless.default_${radio}.ssid=${SSID_LAN_24G}
		
		uci set wireless.guest_${radio}.ssid=${SSID_guest_24G}
	fi
}
echo 'UPDATING ROOT PASSWORD'
NEWPASSWD=getabetterpassword
passwd <<EOF
$NEWPASSWD
$NEWPASSWD
EOF

# Install packages
#opkg update
#opkg install adblock
 
# Provide web interface
#opkg install luci-app-adblock
 
# Backup the blocklists
#uci set adblock.global.adb_backupdir="/etc/adblock"
 
# Save and apply
#uci commit adblock
#/etc/init.d/adblock restart

# Fetch upstream zone
. /lib/functions.sh; config_load 'wireless';
config_foreach setup_radio 'wifi-device'; uci commit wireless;

. /lib/functions/network.sh
network_flush_cache
network_find_wan NET_IF
FW_WAN="$(fw3 -q network "${NET_IF}")"

#setup guest network stuff
uci -q batch << EOF
delete network.${NET_ID}_dev
set network.${NET_ID}_dev=device
set network.${NET_ID}_dev.type=bridge
set network.${NET_ID}_dev.name=br-${NET_ID}
delete network.${NET_ID}
set network.${NET_ID}=interface
set network.${NET_ID}.proto=static
set network.${NET_ID}.device=br-${NET_ID}
set network.${NET_ID}.ipaddr=192.168.99.1
set network.${NET_ID}.netmask=255.255.255.0
#set network.lan.ipaddr='192.18.2.1'
commit network
delete dhcp.${NET_ID}
set dhcp.${NET_ID}=dhcp
set dhcp.${NET_ID}.interface=${NET_ID}
set dhcp.${NET_ID}.start=100
set dhcp.${NET_ID}.limit=150
set dhcp.${NET_ID}.leasetime=1h
commit dhcp
delete firewall.${NET_ID}
set firewall.${NET_ID}=zone
set firewall.${NET_ID}.name=${NET_ID}
set firewall.${NET_ID}.network=${NET_ID}
set firewall.${NET_ID}.input=REJECT
set firewall.${NET_ID}.output=ACCEPT
set firewall.${NET_ID}.forward=REJECT
delete firewall.${NET_ID}_${FW_WAN}
set firewall.${NET_ID}_${FW_WAN}=forwarding
set firewall.${NET_ID}_${FW_WAN}.src=${NET_ID}
set firewall.${NET_ID}_${FW_WAN}.dest=${FW_WAN}
delete firewall.${NET_ID}_dns
set firewall.${NET_ID}_dns=rule
set firewall.${NET_ID}_dns.name=Allow-DNS-${NET_ID}
set firewall.${NET_ID}_dns.src=${NET_ID}
set firewall.${NET_ID}_dns.dest_port=53
add_list firewall.${NET_ID}_dns.proto=tcp
add_list firewall.${NET_ID}_dns.proto=udp
set firewall.${NET_ID}_dns.target=ACCEPT
delete firewall.${NET_ID}_dhcp
set firewall.${NET_ID}_dhcp=rule
set firewall.${NET_ID}_dhcp.name=Allow-DHCP-${NET_ID}
set firewall.${NET_ID}_dhcp.src=${NET_ID}
set firewall.${NET_ID}_dhcp.dest_port=67
set firewall.${NET_ID}_dhcp.proto=udp
set firewall.${NET_ID}_dhcp.family=ipv4
set firewall.${NET_ID}_dhcp.target=ACCEPT
commit firewall
EOF

/etc/init.d/network reload
/etc/init.d/dnsmasq restart
/etc/init.d/firewall restart
#/etc/init.d/adblock restart

thanks!

OK, I can get what I want (I think), and I can see the changes that need to happen when I "uci show network", however, when I add those lines to my scripts, they don't get implemented. Then I try them manually and they don't take either. Here's an example of the code I'm running that doesn't take:

"uci set network.@switch_vlan[2]=switch_vlan"
then I commit it and all that, but it never appears.
When I modified the other vlan, it seems to have taken it, I did:
"uci set network.@switch_vlan[0].ports='6t 4 3 2' " and that worked.

uci -q batch << EOF
set network.@switch_vlan[0].ports='6t 4 3 2'
set network.@switch_vlan[2]=switch_vlan
set network.@switch_vlan[2].device='switch0'
set network.@switch_vlan[2].vlan='3'
set network.@switch_vlan[2].ports='6t 1'
set network.@switch_vlan[2].vid='3'
commit network
delete network.${NET_ID}_dev
set network.${NET_ID}_dev=device
set network.${NET_ID}_dev.type=bridge
set network.${NET_ID}_dev.name=br-guest
set network.${NET_ID}_dev.ports=eth1.3
.......

Any ideas what I'm doing wrong here?
thanks!

OK! I believe I figured it out. below is my latest script. Let me know if you have any advice.

Thanks!


setup_radio() {
	local radio="$1"
	echo "radio is: $radio"
	local hw_mode="$(uci -q get wireless."${radio}".hwmode)"
	#echo "hwmode is: $hw_mode"
	
	uci -q del "wireless.${radio}.disabled"
	uci set "wireless.${radio}.channel=auto"
	#uci set "wireless.${radio}.country=XX"
	uci set wireless.default_${radio}.key=${PSK_KEY}
	uci set wireless.default_${radio}.encryption=psk2
	#uci set "wireless.default_${radio}.bursting=1"
	#uci set "wireless.default_${radio}.compression=1"
	#uci set "wireless.default_${radio}.legacy_rates=0"
	#uci set "wireless.default_${radio}.disassoc_low_ack=0"
	#uci set "wireless.default_${radio}.ff=1"
	#uci set "wireless.default_${radio}.skip_inactivity_poll=1"
	#uci set "wireless.default_${radio}.turbo=1"
	#uci set "wireless.default_${radio}.wpa_group_rekey=3600"
	#uci set "wireless.default_${radio}.wps_pushbutton=0"
	#uci set "wireless.default_${radio}.wpa_disable_eapol_key_retries=1"
	
	
	#uci delete wireless.guest_${radio}
	uci set wireless.guest_${radio}=wifi-iface
	uci set wireless.guest_${radio}.device=${radio}
	uci set wireless.guest_${radio}.mode=ap
	uci set wireless.guest_${radio}.network=${NET_ID}
	uci set wireless.guest_${radio}.encryption="psk2"
	uci set wireless.guest_${radio}.key="${GST_PSK_KEY}"
	
	if [ "$hw_mode" == "11a" ]; then
		#echo "good for you"
		#uci set "wireless.${radio}.htmode=VHT80"
		#uci set "wireless.${radio}.txpower=23"
		uci set wireless.default_${radio}.channel='12'
		uci set wireless.default_${radio}.ssid=${SSID_LAN_5G}
		
		uci set wireless.guest_${radio}.ssid=${SSID_guest_5G}
	else
		#echo "bad"
		#uci set "wireless.${radio}.htmode=HT40+"
		#uci set "wireless.${radio}.noscan=1"
		#uci set "wireless.${radio}.txpower=30"
		uci set wireless.default_${radio}.channel='36'
		uci set wireless.default_${radio}.ssid=${SSID_LAN_24G}
		
		uci set wireless.guest_${radio}.ssid=${SSID_guest_24G}
	fi
}
#echo 'UPDATING ROOT PASSWORD'
#
passwd <<EOF
$NEWPASSWD
$NEWPASSWD
EOF

# Install packages
#opkg update
#opkg install adblock
 
# Provide web interface
#opkg install luci-app-adblock
 
# Backup the blocklists
#uci set adblock.global.adb_backupdir="/etc/adblock"
 
# Save and apply
#uci commit adblock
#/etc/init.d/adblock restart

# Fetch upstream zone
. /lib/functions.sh; config_load 'wireless';
config_foreach setup_radio 'wifi-device'; uci commit wireless;

. /lib/functions/network.sh
network_flush_cache
network_find_wan NET_IF
FW_WAN="$(fw3 -q network "${NET_IF}")"

#setup guest network stuff
uci -q batch << EOF
set network.@switch_vlan[0].ports='6t 4 3 2'
add network switch_vlan
set network.@switch_vlan[-1].device='switch0'
set network.@switch_vlan[-1]=switch_vlan
set network.@switch_vlan[-1].vlan='3'
set network.@switch_vlan[-1].ports='6t 1'
set network.@switch_vlan[-1].vid='3'
commit network
delete network.${NET_ID}_dev
set network.${NET_ID}_dev=device
set network.${NET_ID}_dev.type=bridge
set network.${NET_ID}_dev.name=br-${NET_ID}
set network.${NET_ID}_dev.ports='eth1.3'
delete network.${NET_ID}
set network.${NET_ID}=interface
set network.${NET_ID}.proto=static
set network.${NET_ID}.device=br-${NET_ID}
set network.${NET_ID}.ipaddr=192.168.99.1
set network.${NET_ID}.netmask=255.255.255.0
#set network.lan.ipaddr='192.18.2.1'
commit network
delete dhcp.${NET_ID}
set dhcp.${NET_ID}=dhcp
set dhcp.${NET_ID}.interface=${NET_ID}
set dhcp.${NET_ID}.start=100
set dhcp.${NET_ID}.limit=150
set dhcp.${NET_ID}.leasetime=1h
commit dhcp
delete firewall.${NET_ID}
set firewall.${NET_ID}=zone
set firewall.${NET_ID}.name=${NET_ID}
set firewall.${NET_ID}.network=${NET_ID}
set firewall.${NET_ID}.input=REJECT
set firewall.${NET_ID}.output=ACCEPT
set firewall.${NET_ID}.forward=REJECT
delete firewall.${NET_ID}_${FW_WAN}
set firewall.${NET_ID}_${FW_WAN}=forwarding
set firewall.${NET_ID}_${FW_WAN}.src=${NET_ID}
set firewall.${NET_ID}_${FW_WAN}.dest=${FW_WAN}
#
delete firewall.${NET_ID}_DHCP_DNS
set firewall.${NET_ID}_dns=rule
set firewall.${NET_ID}_dns.name=${NET_ID}-DHCP&DNS
set firewall.${NET_ID}_dns.src=${NET_ID}
set firewall.${NET_ID}_dns.dest_port=53 67 68
add_list firewall.${NET_ID}_dns.proto=tcp
add_list firewall.${NET_ID}_dns.proto=udp
set firewall.${NET_ID}_dns.target=ACCEPT
delete firewall.${NET_ID}_nolan
set firewall.${NET_ID}_nolan=rule
set firewall.${NET_ID}_nolan.name=NO_LAN-${NET_ID}
set firewall.${NET_ID}_nolan.src=${NET_ID}
set firewall.${NET_ID}_nolan.dest='lan'
set firewall.${NET_ID}_nolan.proto='all'
set firewall.${NET_ID}_nolan.dest_ip='192.168.1.0/0'
set firewall.${NET_ID}_nolan.target='DROP'

commit firewall
EOF

/etc/init.d/network reload
/etc/init.d/dnsmasq restart
/etc/init.d/firewall restart

Hi @augustus

I have two of the same model router and am looking to use a script like this for painless swaps.
Is this still the latest version of the script?

Thanks

AFAIK, if you're using this in uci-defaults, the network may not be up by the time this runs, so NET_IF may be empty. On the default installation, the default wan interface is wan, if you're creating other interfaces and setting them default in your uci-defaults file, better use their name which you should know.

OpenWrt 23.05 and newer use fw4. There's still a softlink for fw3 but you should consider future-proofing the code.

Port for what?