Skip to content

Add Licenses and Upgrade Entitlement to End-of-Life ZoneDirectors

Ruckus will no longer sell you licenses or support for the ZD1000, ZD1100 and ZD3000.

To prevent e-waste and save these from landfills, you may use the procedure here to enable upgrades, enable URL filtering and apply the maximum number of AP licenses to your ZoneDirector for use in a homelab or personal environment.

ZoneDirector releases prior to 31 Aug 2023 (6.0 - 10.5.1.0.255)

The appropriate patch should be uploaded as a Software Upgrade (Administer > Upgrade > Software Upgrade):-

The upload process completes the patching; no upgrade will be offered. Instead you will receive confirmation the patch has successfully completed:-

TIP

Subsequent software upgrades will remove the patched support license: you will need to re-apply this patch each time you upgrade your ZoneDirector's software.

Creating the Patch Image yourself (from Linux or WSL)
bash
#!/bin/bash

# Create a ZoneDirector Upgrade Image which adds 50 AP Licenses and Upgrade Entitlement until August 2027.

function rks_encrypt {
RUCKUS_SRC="$1" RUCKUS_DEST="$2" python3 - <<END
import os
import struct

input_path = os.environ['RUCKUS_SRC']
output_path = os.environ['RUCKUS_DEST']

(xor_int, xor_flip) = struct.unpack('QQ', b')\x1aB\x05\xbd,\xd6\xf25\xad\xb8\xe0?T\xc58')
structInt8 = struct.Struct('Q')

with open(input_path, "rb") as input_file:
    with open(output_path, "wb") as output_file:
        input_len = os.path.getsize(input_path)
        input_blocks = input_len // 8
        output_int = 0
        input_data = input_file.read(input_blocks * 8)
        for input_int in struct.unpack_from(str(input_blocks) + "Q", input_data):
            output_int ^= xor_int ^ input_int
            xor_int ^= xor_flip
            output_file.write(structInt8.pack(output_int))
        
        input_block = input_file.read()
        input_padding = 8 - len(input_block)
        input_int = structInt8.unpack(input_block.ljust(8, bytes([input_padding | input_padding << 4])))[0]
        output_int ^= xor_int ^ input_int
        output_file.write(structInt8.pack(output_int))
END
}

cat <<END >metadata
PURPOSE=upgrade
VERSION=9.99.99.99
BUILD=999
REQUIRE_SIZE=1000
REQUIRE_VERSIONS=2.0.0.0 2.0.1.0 2.0.1.1 3.0.0.0 3.0.1.0 3.0.2.0 3.0.3.0 3.0.4.0 3.0.5.0 6.0.0.0 6.0.0.1 6.0.0.2 6.0.1.0 6.0.1.1 6.0.2.0 6.0.2.1 6.0.3.0 6.0.3.1 6.0.4.0 7.0.0.0 7.0.1.0 7.0.2.0 7.1.0.0 7.3.0.0 8.0.0.0 8.0.0.1 8.0.1.0 8.0.2.0 8.1.1.0 8.2.0.0 8.2.2.0 8.4.0.0 9.0.0.0 9.1.0.0 9.1.0.3 9.1.1.0 9.1.2.0 9.2.0.0 9.3.0.0 9.3.1.0 9.3.2.0 9.3.4.0
REQUIRE_PLATFORM=ar7100
ABILITY=ZD5000 
END

cat <<END >all_files
*
END

cat <<END >upgrade_check.sh
#!/bin/sh

mount -o remount,rw /

cat <<EOF >/etc/airespider-images/license-list.xml
<license-list name="50 AP Management" max-ap="50" max-client="1250" value="0x0000000f">
</license-list>
EOF

bsp set model ZD1050 > /dev/null 2>&1
bsp commit > /dev/null 2>&1

mount -o remount,ro /

echo "Added AP Licenses.\n<br />"

END

chmod +x upgrade_check.sh
cp upgrade_check.sh ac_upg.sh
rm -f zd.patch.tgz
tar czf zd.patch.tgz metadata all_files upgrade_check.sh ac_upg.sh
rks_encrypt zd.patch.tgz zd1000.licenses.patch.img
rm all_files metadata upgrade_check.sh ac_upg.sh zd.patch.tgz
bash
#!/bin/bash

# Create a ZoneDirector Upgrade Image which adds 50 AP Licenses and Upgrade Entitlement until August 2027.

function rks_encrypt {
RUCKUS_SRC="$1" RUCKUS_DEST="$2" python3 - <<END
import os
import struct

input_path = os.environ['RUCKUS_SRC']
output_path = os.environ['RUCKUS_DEST']

(xor_int, xor_flip) = struct.unpack('QQ', b')\x1aB\x05\xbd,\xd6\xf25\xad\xb8\xe0?T\xc58')
structInt8 = struct.Struct('Q')

with open(input_path, "rb") as input_file:
    with open(output_path, "wb") as output_file:
        input_len = os.path.getsize(input_path)
        input_blocks = input_len // 8
        output_int = 0
        input_data = input_file.read(input_blocks * 8)
        for input_int in struct.unpack_from(str(input_blocks) + "Q", input_data):
            output_int ^= xor_int ^ input_int
            xor_int ^= xor_flip
            output_file.write(structInt8.pack(output_int))
        
        input_block = input_file.read()
        input_padding = 8 - len(input_block)
        input_int = structInt8.unpack(input_block.ljust(8, bytes([input_padding | input_padding << 4])))[0]
        output_int ^= xor_int ^ input_int
        output_file.write(structInt8.pack(output_int))
END
}

cat <<END >metadata
PURPOSE=upgrade
VERSION=9.99.99.99
BUILD=999
REQUIRE_SIZE=1000
REQUIRE_VERSIONS=9.1.0.0 9.1.1.0 9.1.2.0 9.3.0.0 9.3.1.0 9.3.2.0 9.3.4.0 9.4.0.0 9.4.2.0 9.4.3.0 9.5.1.0 9.5.2.0 9.5.3.0 9.6.0.0 9.6.1.0 9.6.2.0 9.7.0.0 9.7.1.0 9.7.2.0 9.8.0.0 9.8.1.0 9.8.2.0 9.8.3.0 9.9.0.0 9.9.1.0 9.10.0.0 9.10.1.0 9.10.2.0
REQUIRE_PLATFORM=ar7161
END

cat <<END >all_files
*
END

cat <<END >upgrade_check.sh
#!/bin/sh

CUR_WRAP_MD5=\`md5sum /bin/sys_wrapper.sh | cut -d' ' -f1\`

mount -o remount,rw /

cd /etc/persistent-scripts
mkdir -p patch-storage
cd patch-storage

if [ -f sys_wrapper.sh ] ; then
    cat sys_wrapper.sh > /bin/sys_wrapper.sh
else
    cat /bin/sys_wrapper.sh > sys_wrapper.sh
fi
cat <<EOF >support
<support-list>
	<support zd-serial-number="\`cat /bin/SERIAL\`" service-purchased="904" date-start="`date +%s`" date-end="1835369940" ap-support-number="licensed" DELETABLE="false"></support>
</support-list>
EOF
sed 's/<support-list/<support-list status="1"/' support >/writable/etc/airespider/support-list.xml
rm -f support.spt
tar -czf support.spt support

cat <<EOF >/etc/airespider-images/license-list.xml
<license-list name="50 AP Management" max-ap="50" max-client="1250" value="0x0000000f">
</license-list>
EOF

sed -i -e '/verify-upload-support)/a \\
        cd \/tmp\\
        cat \/etc\/persistent-scripts\/patch-storage\/support > support\\
        echo "OK"\\
        ;;\\
    verify-upload-support-unpatched)' -e '/wget-support-entitlement)/a \\
        cat \/etc\/persistent-scripts\/patch-storage\/support\.spt > "\/tmp\/\$1"\\
        echo "OK"\\
        ;;\\
    wget-support-entitlement-unpatched)' /bin/sys_wrapper.sh
NEW_WRAP_MD5=\`md5sum /bin/sys_wrapper.sh | cut -d' ' -f1\`
sed -i -e "s/\$CUR_WRAP_MD5/\$NEW_WRAP_MD5/" /file_list.txt

bsp set model ZD1150 > /dev/null 2>&1
bsp commit > /dev/null 2>&1

mount -o remount,ro /

echo "Added Upgrade Entitlement.\n<br />"
echo "Added AP Licenses.\n<br />"

END

chmod +x upgrade_check.sh
rm -f zd.patch.tgz
tar czf zd.patch.tgz metadata all_files upgrade_check.sh
rks_encrypt zd.patch.tgz zd1100.licenses.patch.img
rm all_files metadata upgrade_check.sh zd.patch.tgz
bash
#!/bin/bash

# Create a ZoneDirector Upgrade Image which adds 450 AP Licenses and Upgrade Entitlement until August 2027.

function rks_encrypt {
RUCKUS_SRC="$1" RUCKUS_DEST="$2" python3 - <<END
import os
import struct

input_path = os.environ['RUCKUS_SRC']
output_path = os.environ['RUCKUS_DEST']

(xor_int, xor_flip) = struct.unpack('QQ', b')\x1aB\x05\xbd,\xd6\xf25\xad\xb8\xe0?T\xc58')
structInt8 = struct.Struct('Q')

with open(input_path, "rb") as input_file:
    with open(output_path, "wb") as output_file:
        input_len = os.path.getsize(input_path)
        input_blocks = input_len // 8
        output_int = 0
        input_data = input_file.read(input_blocks * 8)
        for input_int in struct.unpack_from(str(input_blocks) + "Q", input_data):
            output_int ^= xor_int ^ input_int
            xor_int ^= xor_flip
            output_file.write(structInt8.pack(output_int))
        
        input_block = input_file.read()
        input_padding = 8 - len(input_block)
        input_int = structInt8.unpack(input_block.ljust(8, bytes([input_padding | input_padding << 4])))[0]
        output_int ^= xor_int ^ input_int
        output_file.write(structInt8.pack(output_int))
END
}

cat <<END >metadata
PURPOSE=upgrade
VERSION=10.99.99.99
BUILD=999
REQUIRE_SIZE=1000
REQUIRE_VERSIONS=9.1.0.0 9.1.1.0 9.1.2.0 9.3.0.0 9.3.1.0 9.3.2.0 9.3.4.0 9.4.0.0 9.4.2.0 9.4.3.0 9.5.1.0 9.5.2.0 9.5.3.0 9.6.0.0 9.6.1.0 9.6.2.0 9.7.0.0 9.7.1.0 9.7.2.0 9.8.0.0 9.8.1.0 9.8.2.0 9.8.3.0 9.9.0.0 9.10.0.0 9.10.1.0 9.10.2.0 9.12.0.0 9.12.1.0 9.12.2.0 9.12.3.0 9.13.0.0 9.13.1.0 9.13.2.0 9.13.3.0 10.0.0.0 10.1.0.0 10.1.1.0 10.1.2.0 10.2.0.0 10.2.1.0
REQUIRE_PLATFORM=nar5520
REQUIRE_SUBPLATFORM=nar5520
END

cat <<END >all_files
*
END

cat <<END >upgrade_check.sh
#!/bin/sh

CUR_WRAP_MD5=\`md5sum /bin/sys_wrapper.sh | cut -d' ' -f1\`

mount -o remount,rw /

cd /etc/persistent-scripts

mkdir -p patch-storage
cd patch-storage

if [ -f sys_wrapper.sh ] ; then
    cat sys_wrapper.sh > /bin/sys_wrapper.sh
else
    cat /bin/sys_wrapper.sh > sys_wrapper.sh
fi
cat <<EOF >support
<support-list>
	<support zd-serial-number="\`cat /bin/SERIAL\`" service-purchased="904" date-start="`date +%s`" date-end="1835369940" ap-support-number="licensed" DELETABLE="false"></support>
</support-list>
EOF
sed 's/<support-list/<support-list status="1"/' support >/writable/etc/airespider/support-list.xml
rm -f support.spt
tar -czf support.spt support

cat <<EOF >/tmp/airespider-license-list-new.xml
<license-list name="500 AP Management" max-ap="500" max-client="8000" value="0x0000000f" urlfiltering-ap-license="500" is_url="1" is-clean="true">
    <license id="1" name="450 AP Management" inc-ap="450" generated-by="264556" serial-number="\`cat /bin/SERIAL\`" status="0" detail="" />
    <license id="2" name="URL Filtering License" feature-id="38" ap-num="500" generated-by="264556" serial-number="\`cat /bin/SERIAL\`" end-time="1835369940" start-time="`date +%s`" status="0" detail="" />
</license-list>
EOF
cat /tmp/airespider-license-list-new.xml > /etc/airespider-images/license-list.xml
cat /tmp/airespider-license-list-new.xml > /etc/airespider/license-list.xml
cat /tmp/airespider-license-list-new.xml > /etc/airespider/license-list.bak.xml

sed -i -e '/verify-upload-support)/a \\
        cd \/tmp\\
        cat \/etc\/persistent-scripts\/patch-storage\/support > support\\
        echo "OK"\\
        ;;\\
    verify-upload-support-unpatched)' -e '/wget-support-entitlement)/a \\
        cat \/etc\/persistent-scripts\/patch-storage\/support\.spt > "\/tmp\/\$1"\\
        echo "OK"\\
        ;;\\
    wget-support-entitlement-unpatched)' /bin/sys_wrapper.sh
NEW_WRAP_MD5=\`md5sum /bin/sys_wrapper.sh | cut -d' ' -f1\`
sed -i -e "s/\$CUR_WRAP_MD5/\$NEW_WRAP_MD5/" /file_list.txt

bsp set model ZD3050 > /dev/null 2>&1
bsp commit > /dev/null 2>&1

mount -o remount,ro /

echo "Added Upgrade Entitlement.\n<br />"
echo "Added AP Licenses.\n<br />"
END

chmod +x upgrade_check.sh
rm -f zd.patch.tgz
tar czf zd.patch.tgz metadata all_files upgrade_check.sh
rks_encrypt zd.patch.tgz zd3000.licenses.patch.img
rm all_files metadata upgrade_check.sh zd.patch.tgz

ZoneDirector releases after 31 Aug 2023 (e.g. 10.2.1.0.236+)

Ruckus implemented firmware signing in ZoneDirector 10.2.1.0 build 236.
So you will need to download an older 10.2.1.0 build from https://support.ruckuswireless.com/software (e.g. I used 10.1.2.0 build 232) and do an 'upgrade' (Administer > Upgrade).

TIP

Your support entitlement isn't checked if you're just installing a different build of the currently installed ZoneDirector version.

Once you've followed the procedure, above, for older ZoneDirector releases, then you can re-upgrade your ZoneDirector.