The Netgear ReadyNAS 3138 is a 1U rack-mounted NAS server with 4 3.5” SATA drive slots. I have recently purchased such a device in order to use it as a small home fileserver and decided to play with it a small bit before placing it in production use on the network. The manufacturer part number on the sticker that I got was RN31843E which indicates, that the NAS was originally sold with 4 x 3TB disks inside (https://www.cdw.com/product/NETGEAR-ReadyNAS-Rackmount-4x3TB-Enterprise-Drives-RN31843E/3921155). I got it empty however so it’s just a plain RN3138.
All of the currently available information about the device has been moved to wikidevi.
Designator | Footprint | Pinout | Description | Notes |
---|---|---|---|---|
J1 | 1x3 2.54mm Dupont | Unknown | Unknown (possibly CMOS reset jumper) | Unpopulated |
J2 | 1x4 2.54mm Dupont | 1-3.3V, 2-RXD, 3-TXD, 4-GND | Serial console | |
J3 | 2x2 2mm Dupont | Documented on Wikidevi | Serial console | |
J4, J5 | 1x4 2.54mm Dupont | Unknown | Unknown | Unpopulated |
LED1 | LED | Unknown | UI LED (back) | |
S4 | microswitch | Wired to IT8732F pin 13 (GP35?) | Unknown | Unpopulated |
S5 | microswitch | Wired to IT8732F pin 75 (GP43?) | Unknown | Unpopulated |
S6 | microswitch | Unknown | UI button (back) | |
J13 | 2x5 2mm Dupont | documented below | internal USB port | |
J18,J19,J20 | JST-XH 3 pin | 3-wire PC fan | Chassis fans | |
J21 | 1x2 2.54mm Dupont | Unknown | Unknown | Unpopulated |
J22 | 2x5 2.54mm Dupont | documented below | LPC connector | Unpopulated |
CN1 | 2x5 JST | documented below | Front panel | |
J15 | 1x5 JST | Unknown | Front USB connector |
The mainboard contains an unpopulated 2x5 Dupont connector wired to the CPU and to the IT8732F Super I/O chip. Based on some trace routing together with a pinout of the IT8732F chip this looks to be an LPC connector. The pinout is the following:
J22 Pin | IT8732F Pin | Pin Function (based on a related IT8782F chip pinout) | Notes |
---|---|---|---|
1 | |||
2 | 42 | LAD1 | |
3 | 49 | CLKIN | LCLK |
4 | 41 | LAD0 | |
5 | 40 | LFRAME# | |
6 | |||
7 | 44 | LAD3 | |
8 | GND | ||
9 | 43 | LAD2 | |
10 | GND |
One mandatory LPC pin missing is LRESET# but according to Wikipedia this can be connected to the PCIRST# so might not be wired directly to the Super I/O chip. Unfortunately, my logic analyzer is too slow to gather a trace of the signals on this connector (LCLK is 33.3 MHz).
Pin number | Front board side | Mainboard side | Notes |
---|---|---|---|
1 | +3.3V | ||
2 | UI LED anode | ||
3 | PWR button | short to GND when pressed | |
4 | ⚠ LED | IT8732F pin 79 (GP40?) | cathode, anode wired to +3.3V |
5 | Reset button | IT8732F pin 14 (GP34?) | short to GND when pressed |
6 | UI LED cathode | ||
7 | UI button | Connected to S6 on the back | short to GND when pressed, can be wired to IT8732F pin 57 |
8 | 🖧 LAN LED | cathode, anode wired to +3.3V | |
9 | GND | ||
10 | ⏻ Power LED |
The NAS operating system contains an automatic software update mechanism which can be triggered from the Admin UI. The below is the documentation of reverse engineering efforts for this mechanism.
The update starts with a HTTPS GET request to the https://update.readynas.com/download/ReadyNASOS-x86_64/index URL in order to check the information about new firmware versions available. An example request observed is show below:
This request has a number of parameters:
Parameter | Value | Notes |
---|---|---|
key | SCRUBBED | This looks to be a “license key” assigned to the particular NAS |
model | ReadyNAS | Self-explanatory |
model_num | 3138 | Self-explanatory |
current_version | 6.9.1 | Current version of the firmware installed on the device |
channel | lts | Indicates whether we are interested in the LTS (Long-Term Support) channel or other channel names |
From playing with the parameters is seems that only the ‘key’ and ‘channel’ change anything in the returned data at the moment which means that the logic behind the update selection on the backend is likely very simple. First, when the ‘key’ value is changed an empty HTTP response is returned which means, that this value is checked for validity. Next, when the ‘channel’ value is set to anything else than ‘lts’ a different software descriptor is returned:
This response describes a different version of the firmware - 6.10.5 which is currently the most recent version of ReadyNAS OS. The reception of this meassage shows a popup dialog box in the admin UI where the user can confirm software update. If confirmed, the update proceeds to a “license verification” request which looks like this:
Again, like in the previous requests only the ‘key’ parameter seems to be checked, you can put anything you like in the serial number and model number and the verification will always be successful. With the status there is also a URL returned which is where the actual firmware content will be downloaded in the next step:
The response is the firmware update blob. Here, the ‘key’ parameter is also checked, the ‘serial_number’ is not and the ‘requested_version’ needs to be correct, if it’s not a 404 error is returned. Now that we have the firmware file downloaded let’s see what is inside it.
We can see that the first 0x4000 bytes in the file is a kind of header followed by a tar file likely with the firmware contents. When we extract this tar file and calculate its MD5 hash we will find out that it matches the hash in the first “information” line confirming we are on the right track:
The tar file contains 4 files which are also present on the internal NAS USB drive serving as the boot device:
There is a kernel, initramfs as well as the rootfs which gets extracted onto the hard disks when the storage array is initialized. Before that happens all of these files are stored on an internal USB device from which the BIOS boots.
The knowledge and access we gained on the serial console allows us to boot an alternative operating system on the NAS. We will use Alpine Linux x86_64 as a proof of concept as it’s one of the smallest Linux distributions out there (the internal USB drive is only 256 MB).
First we need to change the SYSLINUX configuration as the prompt is currently disabled unless we press one of the designated keys (Shift, Alt, Caps Lock or Scroll Lock). As the NAS has no keyboard we need the prompt to appear every time. We need to boot the NAS without any disks attached so that we end up in the “Emergency Mode” boot where the internal USB device is mounted on /media/boot. Then, we remount it read-write and edit the syslinux.cfg file:
By changing the default ‘prompt 0’ to ‘prompt 1’ the SYSLINUX prompt should appear after rebooting:
As we haven’t sent any characters through the serial console there will be a timeout after 3 seconds and SYSLINUX will boot the default entry landing us back in “Emergency Mode”. Now we will put Alpine Linux on the internal USB device and make an entry to boot it. First, we need to download a bootable Alpine Linux ISO for the x86_64 CPU architecture:
Now, in order to transfer the files needed we want to start an SSH server on the NAS:
We need the kernel and initramfs as a minimum:
Now we can stop dropbear on the serial console by pressing Ctrl-C and edit syslinux.cfg in order to create an entry for Alpine Linux:
The last ‘alpine’ entry was added referencing our kernel (alpine-v) and initramfs (alpine-i). The file names are different because the internal USB has an old-school MS-DOS filesystem with a limit of 8 characters file names. Now we can attempt to boot:
As you can see we have successfully booted Alpine Linux as an alternative OS on the device.
The NAS enclosure contains place for 3 additional 2.5” drives inside, the mainboard has 2 unused SATA connectors. The power supply also has 2 unused SATA power plugs. This setup is perfect for including ZFS L2ARC SSD drives or extra drives for the operating system. A setup like this is visible below:
The NAS is designed to boot from an internal USB storage device plugged directly into the mainboard using a 2mm pitch 9 pin male header. The pinout of this header is identical to the USB2.0 9-pin header found on many mainboards, with only port 1 wired. The header also uses a less standard 2mm pitch instead of the typical IDC (“dupont”) 2.54mm pitch.
Based on this a simple breakout board can be built to provide a USB-A socket to plug in a different USB storage device. This can be used to quickly swap out different operating systems or boot arrangements when maintaining or fixing the device. What you need to keep in mind however is that the connector has a 2mm pitch not the typical 2.54mm. This makes it tricky to use a pre-made perfboard but it’s still possible to stick in a 2mm female header forming what is termed a “hedgehog pattern” by electronics professionals 😉.
After some drilling, n USB-A connector and jumper wire the following result can be obtained:
The voltage rails, chassis fans and chassis temperature sensor seem to be monitored in the IT8732F chip on board. The BIOS Setup Utility can report the following readings:
When the it87 module is loaded into the linux kernel these stats are represented by files under /sys/class/hwmon/hwmon1. The fan and temperature inputs are pretty easy to figure out however the voltage rail to IT87 input mapping is currently unknown.
The IT87 chip provides PWM outputs for fan speed control. These are driven a bit differently than what pwmconfig and fancontrol assume. This is likely due to the fan driving circuitry granting us the following quirks:
- the pwm<n>_enable file does not enable or disable just the PWM like pwmconfig assumes but enables or disables the fan entirely
- the pwm<n> values are inverted, writing 0 spins up the fan to maximum speed, writing 255 stops the fan entirely
The chassis contains a number of status indicator LEDs as well as “Unit Identification” and “Reset” buttons. These are used by the original firmware in order to execute factory reset, recovery and other special actions. There are also two leds per disk on the chassis. The dmesg of the original firmware hints that all of this can be driven using GPIOs or other device-specific kernel code:
The kernel code responsible for the handling of these has not been located yet.