Many KVM switches (local and IP) from major companies like Dell, HP or IBM are manufactured by Avocent. Those KVMs use special cables known as SIPs or RIPs to communicate with managed machines.
In normal scenario only OEM and Avocent cables work on particular device, but as I discovered - at least in one case this was simple to bypass and allow any existing SIP to work.
This article summarizes my journey and discoveries while hacking Dell 1082DS IP KVM.
Background (or Why?)
I'm a homelabber with 24U rack half full of devices. Recently I accuired IBM KVM Console for cheap, and quickly got annoyed by reconnecting cables to each device I need to inteact with.
I had old KVM laying around - it had 4 USB + DVI-I ports. After some digging (and disassembly) I found that those should be really DVI-D as inside there's HDMI switch... So quite useless with VGA monitor and all VGA devices in rack.
After researching local classifieds and auctions on our ebay-eqiv. (Allegro) I stumbled across cheap old HP, Dell and IBM KVM Switches, that reminded me one I seen some time ago on local market. With some research I found them all to be made by Avocent, well-known manufacturer of IP-enabled PDUs, KVMs, etc.
Unfortunately this research led me into two important things: First, IP interface uses Java (obviously...), second (and more worrying) those old KVMs has three passwords: console (serial), remote (ip) and for OSCAR, overlay interface for local console. While there are ways to reset first two, last one requires sending device back to manufacturer. I needed mostly local KVM (IP feature would be only a nice addition), but this looked like an gamble, even for $10-$20 equivalent for single device.
Later I found Dell 1082DS which is the subject of this post. It's still an Avocent product, but it's built on newer platform - local interface was visually identical to remote one, so I suspected it runs some kind of embedded *nix device with web browser to access it locally. And there was a seller with asking price of about $25 for a piece in "fully tested and working condition", so in worst case I'd return it, right? And with the right cable those 2nd generation producs can even emulate USB Mass Storage devices, so I really wanted to check them out.
Those KVM switches uses special cables (called SIP in documentation). Those happend to be very expensive in Poland, but I found seller that offered IBM PS/2 SIPs for $1/piece, so I took a chance. Before I even received KVM, I found some HP SIPs on local flea market. Also for $1/piece so I aquired some of those too.
While docs for each of manufacturers mentions only it's own and Avocent cables as compatibile, considering how much I paid for cables - worst case scenario was that I'll return Dell KVM and hunt for IBM/HP one.
1082DS had arrived a couple of days later. A few minutes for powerup, console looks OK, first signs of X11 and GTK widgets are here (as suspected). So it's time to check cables, right? So I plugged IBM one, nothing happend. Second - nothing. HP - ditto.
Digging through options I found that they are visible in Tools -> Diagnostics. In section called suspect devices. Sigh. Can't be that easy.
Quick firmware analysis
As I seen obvious signs of Linux here, I decided to check firmware images. Dell has updates available with .fl extension. HP happens to have almost identical KVM (only visible difference is two PSUs integrated) known as 1X1EX8 KVM IP CONSOLE SWITCH G2, so I grabbed similar file from HP website.
Quick binwalk later I found uboot and linux squashfs embedded inside both files. And some filesystem-digging later, I had even more hopes - firmware stores most of hardware configuration in /config. Well, just look at this excerpt:
(...) #Avocent PDUs USING_AVO_SPC = yes USING_CYCLADES_SPC = yes # must say yes to USING_CYCLADES_SPC if using the following USING_CYCLADES_REBRANDED = no #Third-party PDUs - must use licensing scheme for Avocent branded but not necessarily for OEMs #License requirement is turn off for DELL USING_SERVERTECH_SPC = yes SERVERTECH_LICENSE_REQUIRED = yes SERVERTECH_ACCOUNT_OVERRIDE = no USING_BAYTECH_SPC = no /* Baytech is deprecated and should be removed */ BAYTECH_LICENSE_REQUIRED = no USING_APC_SPC = yes APC_LICENSE_REQUIRED = no USING_DELL_EATON = yes EATON_LICENSE_REQUIRE = no (...) # OEM: 0=AVO 1=CPQ 2=DELL 3=HP 4=IBM 5=FTS 7=BBOX 8=DSR 9=APC 10=LENOVO 11=FCL 12=LCACs # RIP: 1=PS/2 2=Sun 3=USB 7=SRL 20=USB2 21=PS2M 26=MPSRL 27=Pacer 28=Pacer2 29=Pacer2PS2 # 30=Pacer3 31=USBHS 32=USBFS rip.cascade.enabled = yes rip.interop = 0 1 0 2 0 3 0 7 0 20 0 21 0 27 0 28 0 30 0 31 0 32 8 1 8 2 8 3 8 7 8 20 8 21 8 26 8 27 8 28 8 30 8 31 8 32 user.accounts.enabled = yes vmedia.allowed = yes vmedia.enabled = yes vmedia.locked = no vmedia.reserved.allowed = yes vmedia.write.allowed = yes (...)
This is just a part of
/config/app.cfg file in latest firmware for Dell. They were so nice to even leave comments there. They were missing in 1.16.0 that I had in both my KVMs, so they got added later. Anyway, what was seen, cannot be unseen :)
Of course I included
rip.interop in this excerpt for a reason. This is an obvious indication of thing we want to change. And comparing it with HP and APC config (they left APC in Dell firmware too), the most important question was: how to modify it? It's obviously in squashfs, there's probably some kind of checksum on firmware and so on...
But when there's linux, there's probably serial console somewhere, right? So let's start with this and see if I can find any way to modify settings on running device.
Of course this meant I have to find serial connection. 1082DS includes 4 external serial ports - two to communicate with managed PDUs, one for local serial management and one for modem (out-of-bands). I don't have cables or pinouts for those so I had to open device anyway.
There's 4 pin header that grabbed my attention, as it usually indicates debug UART. Not this time! While it was indeed right connector, this is full-blown RS-232 levels serial communication. Quick probing with osciloscope later - Pin 1 is TX, 2 for GND, 4 for RX. So I dug my PL2032 serial cable instead of usual USB-TTLs, powered the device, and...
U-Boot 1.3.0-rc3 (Sep 24 2012 - 09:28:24) Polaris 2.1.20060 CPU: AMCC PowerPC 405EX Rev. D (PVR=12911475) at 400 MHz (PLB=200, OPB=100, EBC=33 MHz) Security support Bootstrap Option F - Boot ROM Location EBC (8 bits) 16 kB I-Cache 16 kB D-Cache Board: Avocent Polaris - AMCC PPC405EX I2C: ready DRAM: Auto calibration - \ | / - \ | / RQFD: 47 - RQS Read Delay RFFD: 460 - Read Feedback Fractional Delay RDSS: T2 sample - Read Sample Cycle Select WDTR: 270 degrees advance - Write Data/DQS/DM Phase Corase timing CLKP: 180 degrees - Write Clock Phase DRAM: 256 MB (ECC not enabled, 400 MHz, CL4) FLASH: 512 kB NAND: NAND device: Manufacturer ID: 0x2c, Chip ID: 0xda (Micron NAND 256MiB 3,3V 8-bit) Scanning device for bad blocks 256 MiB SERIAL: Serial 1 Init Net: ppc_4xx_eth0, ppc_4xx_eth1 Type "bootp" to get an IP address Type "run net_nfs" to boot Linux and mount root filesystem via NFS Hit any key to stop autoboot: 3 2 1 0 mounting system0 Copy /system0/uImage.polaris to 0x00200000... [DONE] ## Booting image at 00200000 ... Image Name: Linux-2.6.23 Image Type: PowerPC Linux Kernel Image (gzip compressed) Data Size: 2916952 Bytes = 2.8 MB Load Address: 00000000 Entry Point: 00000000 Verifying Checksum ... OK Uncompressing Kernel Image ... OK
Some time later noise on serial interface stopped, so I pressed enter. And this followed:
# whoami root # mount rootfs on / type rootfs (rw) /dev/mtdblock3 on /mnt/m3 type yaffs2 (rw) /dev/loop0 on / type squashfs (ro) proc on /proc type proc (rw) sys on /sys type sysfs (rw) /dev/mtdblock5 on /mnt/m5 type yaffs2 (rw) tmpfs on /tmp type tmpfs (rw) none on /etc type unionfs (rw,dirs=/mnt/m5/etc=rw:/etc=ro) none on /var type unionfs (rw,dirs=/mnt/m5/var=rw:/var=ro) none on /user_data type unionfs (rw,dirs=/mnt/m5/user_data=rw) none on /dev type unionfs (rw,dirs=/tmp/dev=rw:/dev=ro) none on /dev/pts type devpts (rw) none on /proc/bus/usb type usbfs (rw) # ls /config app.APC.cfg firmware.cfg redbirdA_hwconfig.cfg app.cfg oem.APC.cfg redbirdD_hwconfig.cfg boards.APC.cfg oem.cfg ripinfo.cfg boards.cfg polaris_hwconfig.cfg syslog edid redbird8_hwconfig.cfg
We are getting there! Have you noticed
rw mtdblock5 and all those
unionfs'es? Indeed, it's 32MB R/W flash partition and they mount some directories R/W this way.
I noticed main application is started from scripts in
/etc/rc.d/. There's even interactive mode implemented when you can skip any of those scripts during boot. There's also
S20-initcfg that loads our app.cfg and using some binaries loads configuration into ASICs.
So I created
config directory in
/mnt/m5, mounted it as overlay and updated
app.cfg to list all possible configurations. Since at this moment I was able to do it after device fully boots, I grabbed commands from
S20-initcfg and... crash. Seems that device doesn't like overwriting ASICs memory on runtime.
Remember when I mentioned it's possible to skip any of init files during boot? Let's look at that:
You have 5 seconds to interupt non-interactive booting (press Enter)... Boot paused. Do you wish to access the [D]ebug menu, Repeat [L]ast Boot Sequence, [C]ontinue Interacitve Boot, or [R]esume Auto-boot? You have 30 seconds to respond... c Do you wish to execute /etc/rc.d/S05-fips_setenv? [y|n|a|q|s] a Executing All Remaining Items Non-Interactively...
This particular exceprt is from another run, but you get an idea. "S" drops into a shell, so before hardware init I did just that, mounted my config overlay and let the init script finish. After that I plugged HP cable... and it was detected!
First success, more digging
Not only cable was detected, but it asked me to upgrade it's internal firmware with one that was stored inside Dell (!) KVM firmware. This took a few minutes and it totally worked. I could connect to my laptop connected with VGA for display, and USB-PS/2 adapters for input.
After that I tried IBM cables. Suspect device. What? I triple checked rip.interop and it seemed fine. But I remembered something I saw before.
Remeber this interactive booting menu? It mentioned Debug menu too. Let's look there again:
You have 5 seconds to interupt non-interactive booting (press Enter)... Boot paused. Do you wish to access the [D]ebug menu, Repeat [L]ast Boot Sequence, [C]ontinue Interacitve Boot, or [R]esume Auto-boot? You have 30 seconds to respond... d Uber Debug Menu 1) OEM Spoofing (Only operates in NFS boot) [Disabled] 2) No Watchdog [Disabled] 3) RIP Firmware Test [Disabled] 4) Full OEM Override [Disabled] 5) FW OEM Override [Disabled] 6) Java Viewers Only [Disabled] 7) Core Dump To Flash [Disabled] 8) NFS Mounting of /tmp/nfs (Only operates in non-NFS boot) [Disabled] 9) ARI Mode Only [Disabled] X) Exit Menu Select Option to Modify or Exit. 4 Uber Debug Menu 1) OEM Spoofing (Only operates in NFS boot) [Disabled] 2) No Watchdog [Disabled] 3) RIP Firmware Test [Disabled] 4) Full OEM Override [Enabled] 5) FW OEM Override [Enabled] 6) Java Viewers Only [Disabled] 7) Core Dump To Flash [Disabled] 8) NFS Mounting of /tmp/nfs (Only operates in non-NFS boot) [Disabled] 9) ARI Mode Only [Disabled] X) Exit Menu Select Option to Modify or Exit. x Do you wish to access the [D]ebug menu, Repeat [L]ast Boot Sequence, [C]ontinue Interacitve Boot, or [R]esume Auto-boot? You have 30 seconds to respond... c Do you wish to execute /etc/rc.d/S05-fips_setenv? [y|n|a|q|s] a Executing All Remaining Items Non-Interactively...
Full OEM Override... What it does is writes empty file /etc/oem_override. With that added to the puzzle, now IBM cables works too!
So to recap: By mounting overlayfs on
/config and overriding list of supported modules I got some cables working. By enabling
OEM Override I was able to fix support for other cables. But this still requires manual interaction into boot progress, via serial port inside device. Far from ideal.
If only we had
/etc in RW and could write something into
Wait, we actually have this!
It required some thinking, as during early boot,
/etc/rc.sh is called. It enumerates all executable scripts from
/etc/rc.d and calls them one by one. At this moment
mtd5 (and all overlays, including
/etc) is not mounted yet, this is responsibility of one of early rc.d scripts. So I can't add file there, but I suspect I can overwrite any of files that are called after
/etc overlay is mounted and before hardware init. So somewhere between
S20-initcfg. I've choosen
S11-initnetwork, as all it does is bringing loopback interface up.
After more digging into init scripts, I found that when u-boot reset to defaults flag is set,
S00-initfs will remove overlay contents for
/etc before mounting it. Thus hack is not permament; it's enough to reset device to it's defaults.
/mnt/m5/config will stay in flash forever, but it won't get loaded anymore.
Complete hack code
So this is all of my research summed up into kind of shell script. You need to execute those commands after device boots fully and you are in root console.
It's tested only on Dell KVM 1082DS with firmware 1.16.0, checked on two devices. Should be similar on different versions of firmware, and for other vendors.
Obviously you do it on your own risk. If it breaks you have to keep both pieces.
If you have different firmware revision or different device with similar firmware, I recommend you to read my findings and adapt them for your case.
#create directory for overlay config mkdir /mnt/m5/config cd /mnt/m5/config #create config copy cp /config/app.cfg app.cfg #replace rip.interop line with all known options sed -i "s/rip.interop.*/rip.interop = 0 1 0 2 0 3 0 7 0 20 0 21 0 26 0 27 0 28 0 29 0 30 0 31 0 32 1 1 1 2 1 3 1 7 1 20 1 21 1 26 1 27 1 28 1 29 1 30 1 31 1 32 2 1 2 2 2 3 2 7 2 20 2 21 2 26 2 27 2 28 2 29 2 30 2 31 2 32 3 1 3 2 3 3 3 7 3 20 3 21 3 26 3 27 3 28 3 29 3 30 3 31 3 32 4 1 4 2 4 3 4 7 4 20 4 21 4 26 4 27 4 28 4 29 4 30 4 31 4 32 5 1 5 2 5 3 5 7 5 20 5 21 5 26 5 27 5 28 5 29 5 30 5 31 5 32 7 1 7 2 7 3 7 7 7 20 7 21 7 26 7 27 7 28 7 29 7 30 7 31 7 32 8 1 8 2 8 3 8 7 8 20 8 21 8 26 8 27 8 28 8 29 8 30 8 31 8 32 9 1 9 2 9 3 9 7 9 20 9 21 9 26 9 27 9 28 9 29 9 30 9 31 9 32 10 1 10 2 10 3 10 7 10 20 10 21 10 26 10 27 10 28 10 29 10 30 10 31 10 32 11 1 11 2 11 3 11 7 11 20 11 21 11 26 11 27 11 28 11 29 11 30 11 31 11 32 12 1 12 2 12 3 12 7 12 20 12 21 12 26 12 27 12 28 12 29 12 30 12 31 12 32/g" app.cfg #enable oem_override. this can be done from debug menu at boot #for some reasons hp cables worked with just interop updated, IBM required override to operate touch /etc/oem_override #install boot-hack cd /etc/rc.d/ ls -lah S11-initnetwork cp /sbin/initnetwork.sh ./S11-initnetwork sed -i '2i#boothack start' ./S11-initnetwork sed -i '3i echo Avocent any-SIP hack' ./S11-initnetwork sed -i '4i echo 2020 kitor.pl' ./S11-initnetwork sed -i '5i echo Reset device to defaults and delete /mnt/m5/config for complete remove.' ./S11-initnetwork sed -i '6i mount -t unionfs -o dirs=/mnt/m5/config=rw:/config=ro none /config' ./S11-initnetwork sed -i '7i#boothack end' ./S11-initnetwork #reboot sync reboot