The main reason I got this NAS is that it wasn’t too expensive and the full GPL source code was available. This is because I want to set up an OpenVPN server on my NAS which can route my internet connection. For this I need Iptables and OpenVPN. This tutorial is my notes on getting it all working on the EX2
WARNING: Usual disclaimer, Custom Firmware VOIDs your WD warranty. If you brick your NAS as a result of these instructions, don’t come crying to me, I won’t have any sympathy, nor do I bare any responsibility for any loss of data, hardware, anything, as a result of, or indirectly related to following these instructions. You are soley responsible for what happens next!
Ok, so, the release notes are mostly useless in trying to explain the process of building the firmware, so here goes some more explanatory notes. These are based on looking at the release notes for 4 different versions of the firmware and then lots of experimentation. WD seem to remove information from the ReadMe’s as each release goes on. But anyway…
Firstly you will need the source code from the WD website (Here at time of writing: http://support.wdc.com/product/download.asp?groupid=906&sid=220&lang=en))
The latest GPL Source at the time I wrote this is 1.05.30_20141210, so I am basing my instructions on that.
I am using Ubuntu 14.04LTS x86_64 as a build environment as that is what I have installed - given that I have a Windows 8 Laptop with UEFI and what-not, 14.04 is what I had to use to get any form of Linux installed at the time
PART 1 - Getting Ready
(1a) On your build machine (not the NAS), download the source code.
( b) In Terminal, log in as root
sudo su
( c) Extract the files using:
tar zxvf WDMyCloud_EX2_GPL_v1.05.25_20141110.tar.gz
I then renamed the directory to WDMyCloud, but isn’t really neessary, just reduced the length of the terminal prompt
mv WDMyCloud_EX2_GPL_v1.05.25_20141110/ WDMyCloud/
( d) Change to the directory
cd WDMyCloud
( e) Set the HOME_DIR variable to the current directory (it is used by the tools to find the root folder).
export HOME_DIR=`pwd`
( f) Next we need to extract the build toolchain. This is supplied as part of the download and is located in the $HOME_DIR/toolchain folder.
cd $HOME_DIR/toolchain
tar zxvf armv7-marvell-linux-gnueabi-softfp_i686_64K_Dev_20131002.tar.gz
IMPORTANT NOTE: If while doing the next steps you come across any script which won’t execute (e.g. xBuild.sh), don’t even consider trying to manually change the file permissions. This happened to me once and little did I know it was because all of the file permissions had been accidentally lost when I extracted the firmware. This meant the ENTIRE file system in the firmware had been marked as read-only and non-executable and it bricked my NAS. If you come across the same permissions issue, STOP IMMEDIATELY, and reextract the firmware making sure to keep file permissions!
PART 2 - Preparing the Kernel
(2a) First step is to extract the kernel source code which is included with the download.
cd $HOME_DIR/kernel
tar zxvf linux-3.2.40.tar.gz
( b) Now set up the environment to cross compile using the supplied toolchain. Fortunately this is one thing WD made easy as they included a setup file.
source source.me
( c) And move into the kernel source directory
cd linux-3.2.40
( d) Do a build of the kernel to make sure everything is working (correct toolchain is being used, etc.)
./xbuild.sh build
Hopefully the build will work - for me it worked without any faffing around, so if it doesn’t work for you, make sure you followed the above steps carefully. The build took about 5 minutes on my computer - a few warnings from various modules, but that seems to be par for the course for this sort of thing.
( e) The next part is customising the modules you want. The xBuild.sh file doesn’t have an option for this, but it is not needed, just run
make menuconfig
( f) This should load a grey box on a blue background which is titled “.config - Linux/arm 3.2.40 Kernel Configuration”. Using this wizard we can select which packages we need. For OpenVPN network bridging, we need IPTABLES with NAT capability which is the purpose of this build. So lets go ahead and select all the required packages.
I couldn’t find anywhere a complete list of exactly which packages were required. There were some which were obviously required, so I selected those, but I also selected some others just in case - save having the build it over and over again. If someone wants to let me know which options aren’t required, I will remove them from the list. Some of the options were enabled by default, so didn’t change those.
Networking Support -->
Networking Options -->
<*> advanced router
<*> Netfilter --> (select this then enter the submenu)
Practically everything in Netfilter except debugging and IPV6 - you can include IPV6 if you want, but I didn't. Remember to enter submenu's after select things indicated by a --> in menuconfig
<*> L2TP
I also selected to include the kernel config in /proc, as I thought it may prove useful in debugging.
General Setup →
[*] Kernel .config support
#######################################################
I also have the following as I thought I might find them useful, but they are not needed for iptables/OpenVPN
Networking Support -->
Wireless
Device Drivers -->
Network Device Support -->
Wireless LAN
USB Support -->
USB Modem
USB Printer Support
Filesystems -->
Misc Filesystems -->
Squashfs4 include LZO and ZLIB
#######################################################’
( h) Now escape back up to the top of the menu and go to the Exit button. Press Enter, then select yes to save changes.
( i) Rebuild the kernel using the same command as earlier:
./xbuild.sh build
Fingers crossed the build will go OK, and with a bit of luck in a couple of minutes you should have the kernel compiled with netfilter support.
( j) once done, copy the compiled kernel into the merge folder:
cp -f arch/arm/boot/uImage $HOME_DIR/firmware/merge/
( k) finally, copy all the the driver modules that were produced into the crfs driver modules folder:
find . -name '*.ko' -exec cp -afv \{\} $HOME_DIR/firmware/module/crfs/driver \;
PART 3 - Compiling iptables
Now that we have kernel support for iptables, we also need to build its binary files and included them in the root filesystem so we can use them.
I am also going to include the ‘nano’ text editor because I am fed up of only having ‘vi’. Lets start with that.
Unless you are familiar with using ‘vi’, Don’t skip building nano as I will be using it later when setting up OpenVPN.
(3a) First set up our environment for building the open source packages. Move to the open source packages directory and source the source.me file like we did for the kernel.
cd $HOME_DIR/Open_Source_packages/
source source.me
( b) To build nano, we are going to need the nano source files, so lets grab them
wget http://ftp.gnu.org/gnu/nano/nano-2.3.6.tar.gz
tar -xzf nano-2.3.6.tar.gz
( c) now that we have the nano source, we need to make a xbuild script for it.
cd nano-2.3.6
echo "" > xbuild.sh
chmod +x xbuild.sh
nano xbuild.sh
Add the following lines to the file, then save and exit.
#!/bin/bash
unset CFLAGS
unset LDFLAGS
unset LIBS
source ../xcp.sh
MY_PREFIX=$PWD/../_xinstall/${PROJECT_NAME}
xbuild()
{
XINSTDIR=$(readlink -f ../_xinstall/${PROJECT_NAME})
if [! -e ${XINSTDIR}/include/ncurses]; then
echo "ERROR: You should build ncurses first"
exit 1
fi
export CFLAGS="${CFLAGS} -I${MY_PREFIX}/include -I${MY_PREFIX}/include/ncurses"
export CPPFLAGS="${CFLAGS} -I${MY_PREFIX}/include -I${MY_PREFIX}/include/ncurses"
export LDFLAGS="${LDFLAGS} -L${MY_PREFIX}/lib"
./configure --host=${TARGET_HOST}
make clean
make
}
xinstall()
{
echo "install"
${CROSS_COMPILE}strip -s ./src/nano
xcp ./src/nano ${ROOT_FS}/bin/
}
xclean()
{
make clean
}
if ["$1" = "build"]; then
xbuild
elif ["$1" = "install"]; then
xinstall
elif ["$1" = "clean"]; then
xclean
else
echo "Usage : [xbuild.sh build] or [xbuild.sh install] or [xbuild.sh clean]"
fi
( d) Now we hit a minor snag. In order to build nano, we need the curses library to link with. Fortunately the source for this is already included with the EX2’s GPL source code. Lets make it:
cd ..
tar -xzf ncurses-5.7.tar.gz
cd ncurses-5.7
./xbuild.sh build
./xbuild.sh install
That should progress smoothly and will build the curses library for us to link nano against.
( e) Now lets build and install nano
cd ../nano-2.3.6
./xbuild.sh build
./xbuild.sh install
( f) Ok then, next up, lets build the iptables. First fetch its source code and extract it:
cd $HOME_DIR/Open_Source_packages/
wget http://www.netfilter.org/projects/iptables/files/iptables-1.4.21.tar.bz2
tar -xf iptables-1.4.21.tar.bz2
( g) Now once again we need to add an xbuild script:
cd iptables-1.4.21
echo "" > xbuild.sh
chmod +x xbuild.sh
nano xbuild.sh
Add the following lines into the xbuild.sh file, then save it and close nano.
#!/bin/bash
unset CFLAGS
unset LDFLAGS
unset LIBS
source ../xcp.sh
MY_PREFIX=$PWD/../_xinstall/${PROJECT_NAME}
xbuild()
{
XINSTDIR=$(readlink -f ../_xinstall/${PROJECT_NAME})
export CFLAGS="${CFLAGS} -I${MY_PREFIX}/include"
export CPPFLAGS="${CFLAGS} -I${MY_PREFIX}/include"
export LDFLAGS="${LDFLAGS} -L${MY_PREFIX}/lib"
./configure --host=${TARGET_HOST} --prefix=
make clean
make
}
xinstall()
{
echo "install"
make install DESTDIR=${ROOT_FS}
}
xclean()
{
make clean
}
if ["$1" = "build"]; then
xbuild
elif ["$1" = "install"]; then
xinstall
elif ["$1" = "clean"]; then
xclean
else
echo "Usage : [xbuild.sh build] or [xbuild.sh install] or [xbuild.sh clean]"
fi
( h) Now build and install iptables
./xbuild.sh build
./xbuild.sh install
PART 4 - Building the Firmware
The next step is the build the firmware for uploading the the My Cloud EX2.
(4a) First, we need to build the root file system. So, change to the ramdisk directory:
cd $HOME_DIR/firmware/ramdisk
( b) We also need to make sure the pax command is available by installing the pax package:
apt-get install pax
( c) Now run the build script
./create_ramdisk.sh
( d) This should produce a new uRamdisk file in the ramdisk directory. This needs to be copied to the merge folder:
cp -f uRamdisk $HOME_DIR/firmware/merge/
( e) Next we need to pack in all the precompiled binaries from WD and all of the driver modules build earlier. These are located in the module folder.
cd $HOME_DIR/firmware/module
( f) Now we should make sure there are no old images lying around, and then create the new one:
rm my-image.cfs
./create_image.sh
( g) This should complete after a minute or so. Once done, copy the output to the merge folder as well:
cp -f my-image.cfs $HOME_DIR/firmware/merge/image.cfs
( h) Finally, lets build our custom firmware. First move into the merge directory where all of the parts of our firmware should now be located:
cd $HOME_DIR/firmware/merge
There should be at least the following files in this folder (run ls to see):
default.tar.gz image.cfs
merge
uImage
uP.bin
uRamdisk
( i) Next run the merge tool.
./merge
( j) And that is it, you should now find that the firmware file has been created.
ls
Should reveal a file called “WD-NAS-firmware” has been created.
( l) Lets just move it to your user area and adjust its file ownership so you have access.
cp WD-NAS-firmware /home/yourUsername/Desktop/
chown yourUsername:yourUsername /home/yourUsername/Desktop/WD-NAS-firmware
( m) And finally it is time to leave your root console.
exit
Now you just have to upload the new firmware using the web utility, and hope to **bleep** that you don’t brick your EX2!!