Thursday, March 24, 2011

Using BASH on the Synology DS210j

The default shell installed on the Synology NAS is "ASH", which I believe is short for "almost shell". Okay, that's not actually true, but ASH is definitely geared towards constrained environments While functional, it's pretty sparse when compared to something like BASH, which has fantastic functionality like brace-expansion and career coaching.

So, let's install BASH, because it's an aweseome shell, and installing it is super-easy. This assumes you've already bootstrapped your NAS with the IPKG installation.

First we will install the BASH package using IPKG
ipkg install bash

Next we will tell the system that we prefer BASH over ASH, thank you very much. We will do this by editing the /etc/passwd file. Be very very very careful editing this file, as if you muff it up then you might not be able to log into your system!

So, let's be super extra careful and make a back-up of the file, just in case.
cp /etc/passwd ~/just-in-case

Now we'll edit the file
vi /etc/passwd

Look for a line like this:
root:x:0:0:root:/root:/opt/bin/ash

We want to change the end bit to point to bash, so we change "/bin/ash" to "/opt/bin/bash". When you're done it will look like this (!!see 'update' below!!):
root:x:0:0:root:/root:/opt/bin/bash

Save the file, but DO NOT exit your ssh session! First, test our modification by attempting to log in again from another ssh window. If you cannot log in for whatever reason, then restore the file and try again
cp ~/just-in-case /etc/passwd

If you can login, then you delete the backup file and Bob's yer uncle.
rm ~/just-in-case

The man page for BASH is a fantastic wealth of information.
Read it. Know it. Love it.

Update:

As mentioned above, if you muff things up here you might end up unable to log into your Synology.  Well just that happened to me when I updated the DSM and somehow lost my bash binary.  Login attempts now result in "/opt/bin/bash: No such file or directory".

If you fall into this trap as well, you can try reseting your firmware by following these instructions.

To prevent this in the future, a user in the Synology forum suggested leaving the /etc/passwd file as-is and adding this to your .profile.  I heartily agree.

if [ -x /opt/bin/bash ]; then
  exec /opt/bin/bash
fi                     

Also, you should fix the SUID permission on the "su" binary (which just links to "busybox" so you can execute fix other issues should your root user become corrupt.

Plus, if your NAS is visible to the internet, consider disabling the "root" user altogether and creating a different user for root access.  I've detailed that in this post.


Enabling SCP on Synology DS210j

If you followed my previous guide on bootstrapping your Synology NAS by installing the IPKG management system, you might have noticed at some point that while ssh works a charm, scp is not available. Well, that's very easy to fix!

This assumes you've have IPKG installed on your Synology.
  1. ssh into your Synology's root account
    ssh root@hushhush
  2. Install the zlib package
    ipkg install zlib
  3. Install the openssh packageipkg install openssh
  4. Create a symlink to the scp executable in /bin
    (Note: In later DSM's you can just comment out the two PATH lines in your .profile instead.  The path is set to include /opt/bin automatically in /etc/profile)
    ln -s /opt/bin/scp /bin/scp

You should now be able to scp files to your NAS using your normal credentials.

NOTE: Please read this post regarding root & admin passwords before proceeding!!

Timezones and Servlets

When setting up a new servlet/database application, an often overlooked configuration item is the timezone, especially if dealing with a geographically distributed server installation (ie. Amazon AWS_

Database DATETIME Ambiguity
Without timezone consideration, the exact meaning of a DATETIME field in your MySQL database becomes ambiguous, as there is no timezone information embedded in that data-type. Consider that a DATETIME field is ultimately just recorded as a Unix timestamp of type LONG, which is just the number of seconds since the epoch. The epoch, of course, is midnight of January 1, 1970. But midnight where? The epoch changes depenending on which timezone you're in! This makes all your timestamp values dependent upon the system's current timezone, which could yield large differences if you have servers in different timezones.

Daylight Savings
Another consideration is the dreaded Daylight Savings. Aside from providing a moving target when trying to do translate timestamps from one timezone to another, it also provides an interesting wrinkle in that some DATETIMEs exist twice, while others do not exist at all. When we "spring forward", all the DATETIME values between 0200 and 0300 do not exist! If you try to declare a Java Date object, for example, you'll get an exception. Similarly, when we "fall back" then all the DATETIME values between 0100 and 0200 exist twice. This can cause double-counting on reports and sorting issues.

Coordinated Universal Time
Luckily a ready solution exists to these issues, which is to run all your servers in the "UTC" timezone, which is that of Coordinated Universal Time. UTC has two characteristics which make it ideal for server time:
  1. There are no Daylight Savings Time adjustments.
  2. It has an offset of 0000 from GMT, meaning we can calculate display time in any region simply by applying the applicable offset from GMT. By example, Pacific Standard Time (PST) is 8 hours behind GMT (GMT-0800) so it is also eight hours behind UTC (UTC-0800). In the summer, Pacific Daylight Savings Time (PDT) is seven hours behind, so we would use (UTC-0700).
Server Configuration
Setting your server's timezone is dependent upon the OS and distribution, but CentOS and most modern Linux flavours use the same pattern.
  1. Find the timezone you desire in /usr/share/zoneinfo
  2. Create a symlink from "/etc/localtime" to that timezone file
So, to set to UTC, we would use:
sudo rm /etc/localtime
sudo ln -s /usr/share/zoneinfo/UTC /etc/localtime

You can verify the change with the "date" command, which displays the date in the local format.
Thu Mar 24 20:40:17 UTC 2011

Tomcat Configuration
If you cannot change the timezone for the entire server, you can also change it for your specific Tomcat (or any Java application). Normally Java will use the default timezone of the server, but you can change this via the JAVA_OPTS variable. Just add this argument:
-Duser.timezone=UTC

Trust But Verify
As a developer, you likely have little control over the environment on which your code will eventually be run. Despite best efforts by you and your Ops team, mistakes do happen. So, it is a wise idea to verify your timezone during application initialization to avoid doing any processing while in an incorrect timezone.
TimeZone tz = TimeZone.getDefault();
if (!tz.equals(TimeZone.getTimeZone("UTC"))) {
throw new ServletException(
"Server TimeZone set to '"
+ tz.getDisplayName()
+ "' but should be 'UTC'."
+ " Add '-Duser.timezone=UTC' to Tomcat VM launch parameters.");
}

Wednesday, March 23, 2011

Synology DS210j IPKG Bootstrap

The Synology DiskStation series of NAS devices offers some pretty sophisticated machinery for quite affordable prices. In order to take advantage of the true potential of this miniature Linux file server, though, you need access to the rich set of open-source software already built for it. The easiest way to do this is via the IPKG package management system.

There's an excellent wiki article by Synology on how to install IPKG on your NAS. I found it very easy to do on my DS210j. Note that modifying your NAS in this manner could potentially leave it in an unstable state. You can always restore your device to factory settings, but that might necessitate a full reformat of your drives. Always ensure you have a backup plan should things to horribly horribly wrong.

First you should verify which CPU your NAS has. For example, the DS210j uses the Marvel Kirkwood mv6281 ARM processor. This determines which of the bootstrap packages to use. In our case we want this one. The easiest thing is to copy that link to your clipboard.

Next we'll connect to the NAS via SSH. Ensure you have SSH enabled by connecting to the browser interface and going to Control Panel -> Network Services -> Terminal and make sure the "Enable SSH service" is checked.

Of course, you'll also need SSH software on your computer. If you have a Mac, it's already available in the Terminal application. If you're in Windows, then install Cygwin with the OpenSSH package, or PuTTY.

Connect to your NAS with a username of "root". The password will be the same as your "admin" password. Once connected you should be presented with a command temrinal, similar to this. In this case, my NAS is called 'hushhush' (in memory of a great SF bar long since closed):

hushhush>

We want to download the bootstrap package from above, using the 'wget' command. Be sure to substitute the link you found above that corresponds to your model's CPU.

wget http://ipkg.nslu2-linux.org/feeds/optware/cs08q1armel/cross/unstable/syno-mvkw-bootstrap_1.2-7_arm.xsh

Once downloaded, we will execute the bootstrap code. Once executed, we can also delete it.

sh syno-mvkw-bootstrap_1.2-7_arm.xsh
rm syno-mvkw-bootstrap_1.2-7_arm.xsh

Now reboot your NAS, and login again via SSH. We will now update IPKG lists:

ipkg update
ipkg upgrade

And now you're done! You now have access to literally thousands of packages from the IPKG distributions. You can get a list of available packages via:

ipkg list

And to install a package, it's as simple as:

ipkg install <package>

Notes


  • If 'ipkg' can't be found, be sure "/opt/bin" is in your $PATH variable as exported in ~/.profile
  • After recent DSM updates some of the installation seems to have disappeared so you'll need to reinstall.
    1. Download the .xsh file as above and run it
    2. It will instruct you to delete some folders, reboot and re-run the script.
    3. !!BEFORE YOU DO THIS, BE SURE YOU DO NOT RELY ON BASH OR OTHER IPKG BINARIES TO LOG INTO ROOT ACCOUNT!!
    4. If your root user is cofigured to use bash via the /etc/passwd file then revert it to use ash before rebooting or you will not be able to log into your system!
    5. See my other post for info on how to safely use BASH for your ssh users.