NSLU2-Linux
view · edit · print · history

Enabling Telnet on the DS-101(g+)

Warning: Telnet is an inherently insecure protocol. Do not attach a telnet-enabled DS-101(g+) to the internet.

The Easy Way To Gain Telnet Access

You can download two patch files to enable and disable, respectively, the telnet daemon (server) on the DS. The patch files are available at http://oinkzwurgl.org/diskstation (file syno-telnet-r3.zip). To activate the telnet daemon and allow telnet connections on port 23 upload the the patch file enable-telnet.pat to the DS using the update routine in the administrative interface. The patch file disable-telnet.pat will revert these changes and disables the telnet server. Both patches apply the changes immediately and without a reboot. The changes are persistent over a reboot.

For all current firmware revisions (since around autumn 2006) the supplementary syno password is no longer necessary. One can login as user admin or any other user created in the administrative interface. root logins are possible as well. The password for the super user is kept in sync with the admin password. But it is recommended to use sudo instead of logging in as root to issue administrative commands.

The patch files work on all Diskstations (and Cubestations and the Rackstation) with all known firmware revisions. As these patches are more or less officially recommended by Synology it is expected that the procedure will not change in the nearer future.

The routine used to enable and disable the telnet server only modify the "telnet" line in /etc/inetd.conf and does not touch other entries in it. Original, unmodified firmwares only have the telnet line but users might want to add their own stuff to the inetd configuration file.

The Hard Way To Gain Telnet Access

  • Enable the DS-101(g+) web-server service
  • Create a enabletelnet.php3, which contains this:
 
<?php
system('echo "telnet stream tcp nowait root /usr/sbin/telnetd telnetd" > /etc/inetd.conf');
system('killall -HUP inetd');
?>

  • For good measure, create a disabletelnet.php3 containing this:
 
<?php
system('echo "#telnet stream tcp nowait root /usr/sbin/telnetd telnetd" > /etc/inetd.conf');
system('killall -HUP inetd');
?>

  • DS-101 owners: Create a synopass.php3 file containing this:
 
<?php
   $synopass = array();
   $tmOutput = localtime(time(),'1');
   $tmOutput['tm_mon']++;
   $synopass[0] = dechex($tmOutput['tm_mon']);
   $synopass[1] = floor($tmOutput['tm_mon']/10);
   $synopass[2] = $tmOutput['tm_mon'] % 10;
   $synopass[3] = '-';
   $synopass[4] = floor($tmOutput['tm_mday'] / 16);
   $synopass[5] = dechex($tmOutput['tm_mday'] % 16);
   for ($i = 12; $i > 0; $i--)
   {
      if (!($tmOutput['tm_mon'] % $i) && !($tmOutput['tm_mday'] % $i))
      {
         break;
      }
   }
   $synopass[6] =  floor($i/10);
   $synopass[7] = $i % 10;
   $password = implode("",$synopass);
   echo "SynoPassword for today is : $password";
?>

  • Upload above files to the web share.
  • Fire up your browser, point it to http://ds101-ip/enabletelnet.php3 (You should get a blank page)
  • DS-101 owners: Point your browser to the synopass.php3 file to get todays password.
  • Telnet to the DS-101(g+) IP.
  • The login is root, the default password is synopass
  • DS-101 owners: You will then be presented with a "SynoPassword:" prompt. This password changes daily. This is the password you got from the synopass.php3 file.
  • Once in you can change the root password (Not the SynoPassword) from synopass to something a tad more secure by running "passwd"

For DS-101(g+) New firmware 2.0.1 - 3.0240 as above but files are

enabletelnet.php

disabletelnet.php

and add a /x on access

http://ds101-ip/enabletelnet.php/x

DS-101g+ with Firmware Version: 2.0.1 - 3.0280 The method used to gain telnet last time and the time before is broken...:(

DS-101g+ with Firmware Version: 2.0.1 - 3.0284 Same procedure as above but use an enabletelnet-g284.php script instead, which contains this:

 
<?php
if ( FALSE == file_exists( "/volume1/web/main.cgi" ) ) {
  echo "Saving /usr/syno/synoman/main.cgi<br>\n";
  $f = popen( "cp -p /usr/syno/synoman/main.cgi /volume1/web/", "r" );
  pclose( $f );
}
if ( TRUE == file_exists( "/volume1/web/main.cgi" ) ) {
  $f = fopen( "/usr/syno/synoman/main.cgi", "w" );
  fwrite( $f, '#!/bin/sh' . "\n" );
  fwrite( $f, 'echo "telnet stream tcp nowait root /usr/sbin/telnetd telnetd" > /etc/inetd.conf' . "\n" );
  fwrite( $f, 'killall -HUP inetd' . "\n" );
  fclose( $f );

  echo "ENABLING telnet in /etc/inetd.conf<br>\n";
  echo "Note: It is normal that you get a 'Warning ... 500 Internal Server Error' message below<br>\n";

  $str = file_get_contents( "http://localhost:5000/" );

  echo "Restoring /usr/syno/synoman/main.cgi<br>\n";
  $f = popen( "cat /volume1/web/main.cgi > /usr/syno/synoman/main.cgi", "r" );
  pclose( $f );
}
?>

Why/how does it work?
With this firmware release, there are 2 apache instances running: the user one that serves the user-made web pages and can run php scripts with limited privileges, and the system one that runs the system management CGI pages with root privileges.
The web pages that you can create are run by the user instance that has too few privileges to setup telnet so the original script won't work.
But ... it happens that the main.cgi file (system admin main page) is "world writable" so the trick is to replace it with a shell script containing what you want to execute as root (thanks to a user php script) and invoke the admin page to run the shell script as root.
And that's what the above php page does: save the original main.cgi, replace it with the instructions to enable telnet, invoke the admin site once (which will run the instructions as root) and restore the saved main.cgi.
Obviously if something goes terribly wrong, you'll end up with a DS-101g+ with non-functioning management pages so try this only on a g+ with firmware 2.0.1 - 3.0284 and a backup of your data in hand.

Note: php scripts that use popen() (such as that above) don't even seem to run on DS-101g+ firmware 2.0.1 - 3.0284. See the Files area of http://groups.yahoo.com/group/ds101-linux/ for a .pat file you can apply that only adds the telnet line to /etc/inetd.conf.

DS-101j with Firmware Version: 2.0.1 - 3.0280 The only method that I found working is to connect the HDD to another PC, mount it as ext3 filesystem, and modify the /etc/inetd.conf file directly. (I used http://www.fs-driver.org/ under Windows XP).

There is an alternative solution for DS101j? FW 3.0280,3.0281. Basically you first have to downgrade to 3.0240 - see http://www.nslu2-linux.org/wiki/DS101/DowngradeFw. Afterwards copy a small script to any of your shares retelnet.sh:

 
#! /bin/sh
while [ 1 = 1 ] ; do
echo 'telnet stream tcp nowait root /usr/sbin/telnetd telnetd' > /etc/inetd.conf
done

Within telnet:

 
chmod 755 /volume1/myShare/retelnet.sh
/volume1/myShare/retelnet.sh &

Now start the FW upgrade. Afterwards you should be able to telnet again. Use the synopass.php (not php3!) to get the synopassword.


Synopass Routine In Shell Script

Works with busybox commands (i.e. runs on a DS).

 
#!/bin/sh
#
# Shell version of synopass.php from www.nslu2-linux.org#
# by Philippe Kehl <phkehl at gmx dot net>
#
# Returns the current syno password on stdout.
#
# N.B. that the validity of the output has not been checked thoroughly!
# The code seems to work, though.
#
# Needs date, expr, printf, test/[
#

mon=`date +%m`
mday=`date +%d`

a=`printf "%x" ${mon}`

b=`expr ${mon} / 10`

c=`expr ${mon} % 10`

d=`expr ${mday} / 16`

e=`expr ${mday} % 16`
e=`printf "%x" ${e}`

i=12
while test ${i} -gt 0; do
    [ `expr ${mon} % ${i}` = 0 ] && [ `expr ${mday} % ${i}` = 0 ] && break
    i=`expr ${i} - 1`
done

f=`expr ${i} / 10`

g=`expr ${i} % 10`

synopass=${a}${b}${c}-${d}${e}${f}${g}

echo ${synopass}

# eof


Alternate Way To Gain Telnet Access

N.B. This procedure has been tested on a DS-101j, firmware version 2.0-3.0281. It is expected but not yet confirmed to work with other DS and firmwares as well.

Background

The procedures described on this page and elsewhere are rather complicated and depend on certain firmware bugs or need to manipulate the DS in some way. As the update feature of the DS allows to install an operating system to the harddisk, it should be possible to use that feature to load our own stuff to the DS.

Looking at a firmware .pat file reveals that it is a normal POSIX tar archive. It contains some files with rather obvious names. The famous telnet.pat and the output found in /var/log/messages confirm that the DS update routine extracts the archive to /volume1/upd@te and runs the updater programme. This routine is contained in /usr/syno/synoman/main.cgi (the strings inside are quite meaningful!).

In the .pat, there are two more interesting files: VERSION and checksum.syno. As some other postings in the net suggests, the latter contains crc32 numbers, filesizes, filenames and two more unknow numbers. Well, the point is, it does not matter at all! :-). Nor is the VERSION file of any importance for this stage of the upgrade routine.

In the following a way to run a script (or likely any other DS compatible binary) through the updater routine of the DS. There is not even a need to reboot to do that.

Proof Of Concept

You need an editor and tar.

1. Create a file updater containing the following. It should have the executable bit(s) (not checked).

 
#!/bin/sh

echo "C:0:" > /tmp/update.progress

/bin/date > /volume1/public/hello_hello.txt
chmod a+rw /volume1/public/hello_hello.txt

echo "C:-42" > /tmp/update.progress

exit 42

# eof
 

2. Create an empty (!) file checksum.syno, e.g. using the following command.

 
echo -n > checksum.syno
 

3. Create the .pat file.

 
tar -cvf hello_hello.pat updater checksum.syno
 

4. Upload the hello_hello.pat using the firmware update function in the DS admin interface.

Result: The update should fail with a message like unknow error and the error code/number 42.

In the public share on the DS you shuld find a file hello_hello.txt containing the epoch when the updater script has been run.

Script To Enable Telnet

The following updater script will enable telnet in /etc/inetd.conf and restart inetd.

 
#!/bin/sh

echo "C:0:" > /tmp/update.progress

/bin/echo -e "telnet\tstream\ttcp\tnowait\troot\t/usr/sbin/telnetd\ttelnetd\n" \
  > /etc/inetd.conf

/bin/kill `/bin/pidof inetd`

/usr/sbin/inetd

echo "C:-42" > /tmp/update.progress

exit 42

# eof
 

Create an enable_telnet.pat analogously to the above procedure and install it. Remember to set the executable bit!

Does It Work?

Please add confirmations of success or failure for other DS here:

DS-101
working (240) working (371)
DS-101j
unknow, (240), working (281), working (2.0.1 - 3.0385), working (2.0.1 - 3.0428)
DS-101g+
unknow (280), unknow (284), working (2.0.3.0460)
DS-101e
unknow (318)
DS-106x
working
CS-406
work with disk station 2.0 + firmware 598
RS-406
working
DS-407
working

Page last modified on April 19, 2008, at 12:37 PM