Change Unleashed / ZoneDirector SSH Host Key Algorithm to ECDSA
Ruckus Unleashed / ZoneDirector use 2048 bit RSA SSH host keys.
This algorithm is deprecated, so most SSH clients will refuse to connect unless you explicitly specify -oHostKeyAlgorithms=+ssh-rsa
on your ssh
commandline.
(If your AP / ZoneDirector is really old, you will need to specify -oKexAlgorithms=+diffie-hellman-group1-sha1 -oHostKeyAlgorithms=+ssh-rsa -oCiphers=+aes256-cbc
).
Sure, you can permanently add HostKeyAlgorithms +ssh-rsa
to your ~/.ssh/config
file.
But you might prefer to tweak your Unleashed or ZoneDirector to use (secure, non-deprecated) ECDSA instead...
Unleashed ECDSA SSH Host Key Procedure
WARNING
This procedure changes only the Master AP - you will need to follow the same procedure again if another AP begins acting as Master.
This patch should be uploaded as a Preload Image
(Admin & Services
> Administration
> Upgrade
> Local Upgrade
> Preload Image
).
The upload process completes the change; no upgrade will be offered.
Creating the Patch Image yourself (from Linux or WSL)
#!/bin/bash
# Create an Unleashed Upgrade Image which generates new SSH ECDSA keys.
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 >upgrade_tool.sh
exit 1
END
cat <<END >upgrade_tool
cp -f /tmp/unleashed_upgrade/upgrade_tool.sh /tmp/unleashed_upgrade/upgrade_tool
killall dropbear > /dev/null 2>&1
rm -f /writable/data/dropbear/dropbear_rsa_key > /dev/null 2>&1
dropbearkey -t ecdsa -f /writable/data/dropbear/dropbear_rsa_key > /dev/null 2>&1
dropbearkey -y -f /writable/data/dropbear/dropbear_rsa_key | sed -e'1 d' -e'3 d' > /writable/data/dropbear/dropbear_rsa_key.pub
dropbearkey -y -f /writable/data/dropbear/dropbear_rsa_key | sed -e'1,2 d' -e's/.* .* \(.*\)/\1/' > /writable/data/dropbear/dropbear_rsa_key.md5.fingerprint
/usr/sbin/dropbear -e /var/run/-login -I 900 -p 22 -r /writable/data/dropbear/dropbear_rsa_key -j -k -A none
echo Patched ECDSA
exit 1
END
chmod +x upgrade_tool
chmod +x upgrade_tool.sh
cp upgrade_tool.sh upgrade_download_tool.sh
rm -f unleashed.patch.tgz
tar czf unleashed.patch.tgz upgrade_tool upgrade_tool.sh upgrade_download_tool.sh
rks_encrypt unleashed.patch.tgz unleashed.ecdsa.patch.dbg
rm unleashed.patch.tgz upgrade_tool upgrade_tool.sh upgrade_download_tool.sh
TIP
If you run into problems and need to go back to using an RSA host key for SSH then you can apply this patch to generate a new RSA key.
Creating the Patch Image yourself (from Linux or WSL)
#!/bin/bash
# Create an Unleashed Upgrade Image which generates new SSH RSA keys.
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 >upgrade_tool.sh
exit 1
END
cat <<END >upgrade_tool
cp -f /tmp/unleashed_upgrade/upgrade_tool.sh /tmp/unleashed_upgrade/upgrade_tool
killall dropbear > /dev/null 2>&1
rm -f /writable/data/dropbear/dropbear_rsa_key > /dev/null 2>&1
dropbearkey -t rsa -s 2048 -f /writable/data/dropbear/dropbear_rsa_key > /dev/null 2>&1
dropbearkey -y -f /writable/data/dropbear/dropbear_rsa_key | sed -e'1 d' -e'3 d' > /writable/data/dropbear/dropbear_rsa_key.pub
dropbearkey -y -f /writable/data/dropbear/dropbear_rsa_key | sed -e'1,2 d' -e's/.* .* \(.*\)/\1/' > /writable/data/dropbear/dropbear_rsa_key.md5.fingerprint
/usr/sbin/dropbear -e /var/run/-login -I 900 -p 22 -r /writable/data/dropbear/dropbear_rsa_key -j -k -A none
echo Patched RSA
exit 1
END
chmod +x upgrade_tool
chmod +x upgrade_tool.sh
cp upgrade_tool.sh upgrade_download_tool.sh
rm -f unleashed.patch.tgz
tar czf unleashed.patch.tgz upgrade_tool upgrade_tool.sh upgrade_download_tool.sh
rks_encrypt unleashed.patch.tgz unleashed.restore_rsa.patch.dbg
rm unleashed.patch.tgz upgrade_tool upgrade_tool.sh upgrade_download_tool.sh
Unleashed releases after 30 Aug 2023 (e.g. 200.7.10.202.145+, 200.14.6.1.203+)
Patching is disabled on newer AP firmwares.
If your AP was released before mid-2022 then you can backup your configuration, temporarily downgrade to an older Unleashed firmware, apply the patch, and then re-upgrade.
Make a note of your current software version - you'll need to upgrade to this exact version to restore your configuration backup.
ZoneDirector 1200 ECDSA SSH Host Key Procedure
This 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.
Creating the Patch Image yourself (from Linux or WSL)
#!/bin/bash
# Create a ZoneDirector Upgrade Image which generates new SSH ECDSA keys.
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.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 10.3.0.0 10.3.1.0 10.4.0.0 10.4.1.0 10.5.0
REQUIRE_PLATFORM=nar5520
REQUIRE_SUBPLATFORM=cob7402
END
cat <<END >all_files
*
END
cat <<END >upgrade_check.sh
#!/bin/sh
killall dropbear > /dev/null 2>&1
rm -f /etc/airespider/dropbear/dropbear_host_rsa_key > /dev/null 2>&1
dropbearkey -t ecdsa -f /etc/airespider/dropbear/dropbear_host_rsa_key > /dev/null 2>&1
/etc/init.d/dropbear > /dev/null 2>&1
echo "SSH is now using ECDSA.\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 zd1200.ecdsa.patch.img
rm all_files metadata upgrade_check.sh zd.patch.tgz
TIP
If you run into problems and need to go back to using an RSA host key for SSH then you can apply this patch to generate a new RSA key.
Creating the Patch Image yourself (from Linux or WSL)
#!/bin/bash
# Create a ZoneDirector Upgrade Image which generates new SSH RSA keys.
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.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 10.3.0.0 10.3.1.0 10.4.0.0 10.4.1.0 10.5.0
REQUIRE_PLATFORM=nar5520
REQUIRE_SUBPLATFORM=cob7402
END
cat <<END >all_files
*
END
cat <<END >upgrade_check.sh
#!/bin/sh
killall dropbear > /dev/null 2>&1
rm -f /etc/airespider/dropbear/dropbear_host_rsa_key > /dev/null 2>&1
dropbearkey -t rsa -f /etc/airespider/dropbear/dropbear_host_rsa_key > /dev/null 2>&1
/etc/init.d/dropbear > /dev/null 2>&1
echo "SSH is now using RSA.\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 zd1200.restore_rsa.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+, 10.5.1.0.265+)
Ruckus implemented firmware signing in ZoneDirector 10.2.1.0 build 236 and 10.5.1.0 build 265.
So you will need to download an older 10.2.1.0 or 10.5.1.0 build from https://support.ruckuswireless.com/software (e.g. I used 10.5.1.0 build 255) 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.