2008/12/22

WMU-6500FS - dropbear-0.52



Introduction

It seems to me that dropbear ssh daemon from JoKeR's package is configured so it does not support public key authentication. It is possible that I am doing something wrong but I was trying hard to make it work and did not succeed.
Finally I decided to build dropbear on my own, since the publickey authentication feature is essential for me (I am using the box for hosting of git repositories and I really do not want to type my password every time I commit a code).

Build result

[binary] [file list]

Installation

box# cd /mnt/C
box# ./filopack.sh --download dropbear-0.52
Configuration file .filopack/.config file found and used
Retrieving package index... (Connecting to http://filodej.ic.cz)
Downloading package dropbear-0.52 from http://filodej.ic.cz ...
connected!

Length: 502 [text/plain]
connected!

Length: 177,869 [application/x-tar]
box# ./filopack.sh --install dropbear-0.52
Configuration file .filopack/.config file found and used
Retrieving package index... (Connecting to http://filodej.ic.cz)
Sure to unpack dropbear-0.52 locally at /mnt/C (y/n)?y
sys/bin/dbclient
sys/bin/dropbearmulti
sys/bin/dropbearkey
sys/bin/dropbearconvert
sys/bin/scp
sys/sbin/dropbear
box# killall dropbear
box# dropbear
In this post I am going to describe how I built the dropbear package and diagnosed and solved (or worked around) problems which arose during the whole process.

JoKeR's dropbear

Let's try co connect to the box:
If ssh daemon (dropbear in our case) is not running on the box, the error message will likely look as follows:
deb# ssh root@storage
ssh: connect to host storage port 22: Connection refused
If everything is ok, it should look similar to following:
deb# ssh root@storage
root@storage's password: < type a password > 

  [    FW 4.00b4.C009-M[NG]    ]
  [ http://mgb111.pradnik.net/ ]

box#
Now we are trying to get rid of typing the password. We use the RSA public authentication for it.

Publickey authentication

If we do not have a RSA key generated yet, we can generate it as follows:
deb# cd ~
deb# ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/filodej/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/filodej/.ssh/id_rsa.
Your public key has been saved in /home/filodej/.ssh/id_rsa.pub.
The key fingerprint is:
89:...:b4... filodej@debian
Deploy the public key to the box:
deb# scp .ssh/id_rsa.pub root@storage:/mnt/C/sys/root/.ssh/
root@storage's password:
id_rsa.pub                                                              100%  393     0.4KB/s   00:00
Now, on the box, append the public key to the list of authorized keys:
box# cd /mnt/C/sys/root/.ssh/
box# cat id_rsa.pub >> authorized_keys
From now on, the ssh client should not ask for anything (more precisely, it should not ask for password, it should ask for publickey passphrase if we did not leave it empty - for someone it can look similar as password, but it is completely different thing).

Let's try:
deb# ssh root@storage
root@storage's password:

Simple diagnostics

Ooops, it seems we did not succeed. Let's do some diagnostics (we can use either of "-v", "-vv", "-vvv" verbose modes, one "v" is sufficiend here):
dev# ssh -v root@storage
OpenSSH_4.3p2 Debian-9, OpenSSL 0.9.8c 05 Sep 2006
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: Applying options for *
debug1: Connecting to storage [192.168.1.104] port 22.
debug1: Connection established.
debug1: identity file /home/filodej/.ssh/identity type -1
debug1: identity file /home/filodej/.ssh/id_rsa type 1
debug1: identity file /home/filodej/.ssh/id_dsa type -1
debug1: Remote protocol version 2.0, remote software version dropbear_0.50
debug1: no match: dropbear_0.50
...
debug1: Host 'storage' is known and matches the RSA host key.
debug1: Found key in /home/filodej/.ssh/known_hosts:4
debug1: ssh_rsa_verify: signature correct
debug1: SSH2_MSG_NEWKEYS sent
debug1: expecting SSH2_MSG_NEWKEYS
debug1: SSH2_MSG_NEWKEYS received
debug1: SSH2_MSG_SERVICE_REQUEST sent
debug1: SSH2_MSG_SERVICE_ACCEPT received
debug1: Authentications that can continue: password
debug1: Next authentication method: password
root@storage's password:
Let's try to connect to another machine and compare the trace:
deb# ssh -v root@notasw
OpenSSH_4.3p2 Debian-9, OpenSSL 0.9.8c 05 Sep 2006
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: Applying options for *
debug1: Connecting to notasw [192.168.1.103] port 22.
debug1: Connection established.
debug1: identity file /home/filodej/.ssh/identity type -1
debug1: identity file /home/filodej/.ssh/id_rsa type 1
debug1: identity file /home/filodej/.ssh/id_dsa type -1
debug1: Remote protocol version 2.0, remote software version OpenSSH_4.7p1 Debian-8ubuntu1.2
debug1: match: OpenSSH_4.7p1 Debian-8ubuntu1.2 pat OpenSSH*
...
debug1: Host 'notasw' is known and matches the RSA host key.
debug1: Found key in /home/filodej/.ssh/known_hosts:8
debug1: ssh_rsa_verify: signature correct
debug1: SSH2_MSG_NEWKEYS sent
debug1: expecting SSH2_MSG_NEWKEYS
debug1: SSH2_MSG_NEWKEYS received
debug1: SSH2_MSG_SERVICE_REQUEST sent
debug1: SSH2_MSG_SERVICE_ACCEPT received
debug1: Authentications that can continue: publickey,password
debug1: Next authentication method: publickey
debug1: Trying private key: /home/filodej/.ssh/identity
debug1: Offering public key: /home/filodej/.ssh/id_rsa
debug1: Authentications that can continue: publickey,password
debug1: Trying private key: /home/filodej/.ssh/id_dsa
debug1: Next authentication method: password
root@notasw's password:
We can diff the logs to easily see the differences:
deb# ssh -v root@storage 2> storage.txt
root@storage's password:
<Ctrl-D>
deb# ssh -v root@notasw 2> notas.txt
root@notasw's password:
<Ctrl-D>
deb# diff storage.txt notas.txt
4c4
< debug1: Connecting to storage [192.168.1.104] port 22.
---
> debug1: Connecting to notasw [192.168.1.103] port 22.
9,10c9,10
< debug1: Remote protocol version 2.0, remote software version dropbear_0.50
< debug1: no match: dropbear_0.50
---
> debug1: Remote protocol version 2.0, remote software version OpenSSH_4.7p1 Debian-8ubuntu1.2
> debug1: match: OpenSSH_4.7p1 Debian-8ubuntu1.2 pat OpenSSH*
23,26c23,28
...
< debug1: Host 'storage' is known and matches the RSA host key.
< debug1: Found key in /home/filodej/.ssh/known_hosts:4
---
...
> debug1: Host 'notasw' is known and matches the RSA host key.
> debug1: Found key in /home/filodej/.ssh/known_hosts:8
33c35,40
< debug1: Authentications that can continue: password
---
> debug1: Authentications that can continue: publickey,password
> debug1: Next authentication method: publickey
> debug1: Trying private key: /home/filodej/.ssh/identity
> debug1: Offering public key: /home/filodej/.ssh/id_rsa
> debug1: Authentications that can continue: publickey,password
> debug1: Trying private key: /home/filodej/.ssh/id_dsa
It seems that the JoKeR's daemon is not configured for publickey authentication at all. Ok, let's build our own.

Build process

First we have to download, extract and configure the build:
dev# cd /usr/local/src/
dev# wget http://matt.ucc.asn.au/dropbear/dropbear-0.52.tar.

bz2
dev# tar xjvf dropbear-0.52.tar.bz2 
dev# cd dropbear-0.52
dev# ./configure --prefix /mnt/C/sys
...
configure: Now edit options.h to choose features.
As the message suggests, now we can set up some additional build options:
dev# nano options.h

change:
  #define RSA_PRIV_FILENAME "/etc/dropbear/dropbear_rsa_host_key"
to:
  #define RSA_PRIV_FILENAME "/mnt/C/sys/etc/dropbear_rsa_host_key"

and possibly comment out:
  #define DROPBEAR_DSS
or change:
  #define DSS_PRIV_FILENAME "/etc/dropbear/dropbear_dss_host_key"
to:
  #define DSS_PRIV_FILENAME "/mnt/C/sys/etc/dropbear_dss_host_key"

leave following unchanged:
  #define ENABLE_SVR_PASSWORD_AUTH
  /* PAM requires ./configure --enable-pam */
  /*#define ENABLE_SVR_PAM_AUTH*/
  #define ENABLE_SVR_PUBKEY_AUTH

  /* Wether to ake public key options in authorized_keys file into account */
  #ifdef ENABLE_SVR_PUBKEY_AUTH
  #define ENABLE_SVR_PUBKEY_OPTIONS
  #endif

  #define ENABLE_CLI_PASSWORD_AUTH
  #define ENABLE_CLI_PUBKEY_AUTH
  #define ENABLE_CLI_INTERACT_AUTH
... and make:
dev# make PROGRAMS="dropbear dbclient dropbearkey dropbearconvert scp"
...
It compiled successfully, but I have realized that I prefer to link the dependencies statically:
dev# make PROGRAMS="dropbear dbclient dropbearkey dropbearconvert scp" clean
dev# make STATIC=1 PROGRAMS="dropbear dbclient dropbearkey dropbearconvert scp"
...
/mnt/C/sys/lib/gcc/i386-linux-uclibc/4.1.2/../../../../i386-linux-uclibc/bin/ld: cannot find -lz
collect2: ld returned 1 exit status
... the error means that linker is unable to find a static version of zlib library.
When we investigate that we see taht there is just a dynamic version of the library on the system:
dev# ls /lib/libz*
/lib/libz.so.1  /lib/libz.so.1.2.2
dev# ls /mnt/C/sys/lib/libz*
/mnt/C/sys/lib/libz*: No such file or directory
We could pick the sources and build a static version of zlib library, but for now I decided to re-configure the dropbear build and disable the zlib support:
dev# make STATIC=1 PROGRAMS="dropbear dbclient dropbearkey dropbearconvert scp" clean
dev# ./configure --prefix /mnt/C/sys --disable-zlib STATIC=1 
dev# make STATIC=1 PROGRAMS="dropbear dbclient dropbearkey dropbearconvert scp"
... now it compiled without problems, we can try to install it and upload to the box:
dev# make STATIC=1 PROGRAMS="dropbear dbclient dropbearkey dropbearconvert scp" install
...
dev# scp /mnt/C/sys/sbin/dropbear root@storage:/tmp/
Now we can start the brand new version of dropbear daemon on the box:
box# killall dropbear
box# /tmp/dropbear
And try to log in over ssh client (from my debian system):
deb# ssh -vvv root@storage -i ~/.ssh/id_rsa.pub
...
debug2: key: /home/filodej/.ssh/id_rsa.pub (0xb7f7b480)
debug2: key:  (0xb7f7c8e0)
debug1: Authentications that can continue: publickey,password
debug1: Next authentication method: publickey
debug1: Trying private key: /home/filodej/.ssh/identity
debug1: Offering public key: /home/filodej/.ssh/id_rsa
debug1: Authentications that can continue: publickey,password
debug1: Trying private key: /home/filodej/.ssh/id_dsa
debug1: Next authentication method: password
root@storage's password:
debug1: Authentications that can continue: publickey,password
Permission denied, please try again.
root@storage's password:
debug1: Authentications that can continue: publickey,password
Permission denied, please try again.
root@storage's password:
It seems we have done some progress here, but still are not able to authenticate via publickey. And even if we are using the correct password, permission is denied.

List of valid shells

Let's restart the daemon, but now not forking to the background and logging to the stderr rather that syslog:
box# dropbear -E -F
[4456] Nov 30 23:59:30 Not backgrounding
[4462] Nov 30 23:59:56 Child connection from 192.168.1.103:49013
[4462] Dec 01 00:00:08 user 'root' has invalid shell, rejected
Ok, there is something wrong with the shell settings, let's investigate that:
box# cat /var/config/passwd
root: ... :0:0:root:/mnt/C/sys/root:/mnt/C/sys/bin/bash
...
box# ls /mnt/C/sys/bin/bash
/mnt/C/sys/bin/bash
User root has /mnt/C/sys/bin/bash in his settings, the file exists and is at correct place. Let's look at the list of valid shells:
box# cat /etc/shells
/bin/sh
/sbin/nologin
/bin/nologin
/bin/ash
/sbin/ash
/bin/false
/sbin/false
/mnt/C/sys/bash
/bin/bash
/usr/bin/bash
The path /mnt/C/sys/bash is wrong since the bash executable is in /mnt/C/sys/bin directory, but the /usr/bin/bash path should be ok, since the /usr/bin is just a symlink to /mnt/C/sys/bin:
box# ls -l /usr/bin
lrwxrwxrwx    1 root     root           14 May 21  2008 /usr/bin -> /mnt/C/sys/bin
We have to look at the problem in more detail. Since there is no verbose mode available in dropbear by default, we can enable it in code (I got the inspiration from this post):
dev# nano debug.h
    uncomment:
        #define DEBUG_TRACE
Now when we rebuilt and re-deployed the dropbear, we can run in in verbose mode:
box# dropbear -v -E -F 
...
TRACE (4848): shell is /mnt/C/sys/bin/bash
TRACE (4848): test shell is '/bin/sh'
TRACE (4848): test shell is '/sbin/nologin'
TRACE (4848): test shell is '/bin/nologin'
TRACE (4848): test shell is '/bin/ash'
TRACE (4848): test shell is '/sbin/ash'
TRACE (4848): test shell is '/bin/false'
TRACE (4848): test shell is '/sbin/false'
TRACE (4848): test shell is '/mnt/C/sys/bash'
TRACE (4848): test shell is '/bin/bash'
TRACE (4848): test shell is '/usr/bin/bash'
As can be seen in the svr-auth.c source code:
00273       while ((listshell = getusershell()) != NULL) {
00274             TRACE(("test shell is '%s'", listshell))
00275             if (strcmp(listshell, usershell) == 0) {
00276                   /* have a match */
00277                   goto goodshell;
00278             }
00279       }
... the shell path is compared as plain strings and so /usr/bin/bash and /mnt/C/sys/bin/bash are two different things.

Since the /etc/shells file is placed on read-only file system we have to make a change in /var/config/passwd file:
box# sed -i 's|/mnt/C/sys/bin/|/usr/bin/|g' /var/config/passwd
Since it is overwritten on every boot, we have to make the correction in our rc.cfg file, to make it permanent:
nano /mnt/C/sys/etc/rc.d/rc.cfg
   add the following line:
    sed -i 's|/mnt/C/sys/bin/|/usr/bin/|g' /var/config/passwd 
Now when we try to connect again, we can see that the problem is solved:
[394] Dec 01 01:32:25 pubkey auth succeeded for 'root' with key md5 

3a:...:05 from 192.168.1.103:44521

Read only file system

There is another problem:
[394] Dec 01 01:32:25 chown(/dev/ttyp2, 0, 0) failed: Read-only file system
[394] Dec 01 01:32:26 exit after auth (root): chmod(/dev/ttyp2, 0622) failed: Read-only file system
The problem seems to be in the file sshpty.c in function pty_setowner but I am not sure what exactly is wrong. We can try to debug it remotely in order to find out what is going on. One option in debug.h can be handy - we can disable the forking the sub-processes - then there is just one dropbear process to attach.
/* To debug with GDB it is easier to run with no forking of child processes.
   You will need to pass "-F" as well. */
/* #define DEBUG_NOFORK */
Let's rebuild it with debug info:
dev# nano Makefile
...
CFLAGS=-I. -I$(srcdir) -I$(srcdir)/libtomcrypt/src/headers/ $(CPPFLAGS) -I/mnt/C/sys/include 

-I/mnt/C/sys/X11/include -g
...
Rebuild and redeploy the dropbear binary.

Now we can run the dropbear process on the box:
box# dropbear -E -F
box# [4498] Dec 21 23:50:01 Running in background
...
On another console connected to the box we start the gdbserver:
box# gdbserver colinux:2345 --attach 4498
Attached; pid = 4498
Listening on port 2345
...
Now on the mirror system we can start the gdb:
dev# gdb dropbear
GNU gdb 6.3
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i386-linux-uclibc"...Using host libthread_db library "/lib/libthread_db.so.1".

(gdb) target remote 192.168.1.104:2345
Remote debugging using 192.168.1.104:2345
0x0806d7ad in fast_s_mp_sqr (a=0xbfffe348, b=0xbfffe348) at bn_fast_s_mp_sqr.c:73
73               _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--);
(gdb) break pty_setowner
Breakpoint 1 at 0x805bfcc: file sshpty.c, line 364.
(gdb) cont
Continuing.
Now we are ready to connect over ssh:
dev# ssh root@storage
root@storage's password:
... and debugger stops on the breakpoint:
Breakpoint 1, pty_setowner (pw=0x80dd480, tty_name=0x80e1578 "/dev/ttyp3") at sshpty.c:364
364             grp = getgrnam("tty");
(gdb) step
365             if (grp) {
(gdb) step
369                     gid = pw->pw_gid;
(gdb) step
370                     mode = S_IRUSR | S_IWUSR | S_IWGRP | S_IWOTH;
(gdb) step
378             if (stat(tty_name, &st)) {
(gdb) step
382             dropbear_log(LOG_ERR, "stat: %u", (unsigned int)st.st_uid );
(gdb) print st
$1 = {st_dev = 7936, __pad1 = 45352, __st_ino = 363, st_mode = 8630, st_nlink = 1, st_uid = 0, st_gid = 5,
  st_rdev = 771, __pad2 = 0, st_size = 0, st_blksize = 4096, st_blocks = 0, st_atime = 1206970720,
  st_atimensec = 134760895, st_mtime = 1206970720, st_mtimensec = 134691188, st_ctime = 1206970720,
  st_ctimensec = 135124096, st_ino = 363}
(gdb) print tty_name
$2 = 0x80e1578 "/dev/ttyp3"
(gdb) next
383             if (st.st_uid != pw->pw_uid || st.st_gid != gid) {
(gdb) print *pw
$3 = {pw_name = 0x80dd380 "root", pw_passwd = 0x80dd385 "...", pw_uid = 0, pw_gid = 0, pw_gecos = 

0x80dd3a4 "root", pw_dir = 0x80dd3a9 "/mnt/C/sys/root", pw_shell = 0x80dd3b9 "/usr/bin/bash"}
...
(gdb) step
401 if ((st.st_mode & (S_IRWXU|S_IRWXG|S_IRWXO)) != mode) {
(gdb) print /o st.st_mode
$4 = 020666
(gdb) step
402                     if (chmod(tty_name, mode) < 0) {
(gdb) step
403                             if (errno == EROFS &&
(gdb) step
409                                     dropbear_exit("chmod(%.100s, 0%o) failed: %.100s",
Ok, we have analyzed the situation. The pty_setowner function is trying to initialize the device file representing the terminal we are trying to connect to. Device file is on read only file system and so the attribute changes do not succeed.

If changing the tty owner does not succeed, the code at (1) activates more relaxed mode in case the file system is read only and tty is owned by root or the uids match. In our case the relaxed mode is activated and the server just writes the warning chown(/dev/ttyp2, 0, 0) failed: Read-only file system and continues.

Then there is code changing tty read mode. This code tries to prevent unauthorized users from reading tty content. In order to get just a warning, the reading by group and reading by others must be prohibited. In our case the st.st_mode is 020666 (read/write by everyone) and so we get the error chmod(/dev/ttyp2, 0622) failed: Read-only file system.

 /*
  * Change owner and mode of the tty as required.
  * Warn but continue if filesystem is read-only and the uids match/
  * tty is owned by root.
  */
 if (stat(tty_name, &st)) {
  dropbear_exit("pty_setowner: stat(%.101s) failed: %.100s",
    tty_name, strerror(errno));
 }

 if (st.st_uid != pw->pw_uid || st.st_gid != gid) {
  if (chown(tty_name, pw->pw_uid, gid) < 0) {
   if (errno == EROFS &&
       (st.st_uid == pw->pw_uid || st.st_uid == 0)) {
(1)    dropbear_log(LOG_ERR,
     "chown(%.100s, %u, %u) failed: %.100s",
      tty_name, (unsigned int)pw->pw_uid, (unsigned int)gid,
      strerror(errno));
   } else {
    dropbear_exit("chown(%.100s, %u, %u) failed: %.100s",
        tty_name, (unsigned int)pw->pw_uid, (unsigned int)gid,
        strerror(errno));
   }
  }
 }

 if ((st.st_mode & (S_IRWXU|S_IRWXG|S_IRWXO)) != mode) {

  if (chmod(tty_name, mode) < 0) {
   if (errno == EROFS &&
(2)       (st.st_mode & (S_IRGRP | S_IROTH)) == 0) {
    dropbear_log(LOG_ERR,
     "chmod(%.100s, 0%o) failed: %.100s",
     tty_name, mode, strerror(errno));
   } else {
    dropbear_exit("chmod(%.100s, 0%o) failed: %.100s",
        tty_name, mode, strerror(errno));
   }
  }
 }
Some discussions (for example here and here) recommended to configure build in order to disable openpty:
dev# make STATIC=1 PROGRAMS="dropbear dbclient dropbearkey dropbearconvert scp" clean
dev# ./configure --prefix /mnt/C/sys --disable-zlib --disable-openpty STATIC=1 
dev# make STATIC=1 PROGRAMS="dropbear dbclient dropbearkey dropbearconvert scp"
dev# make STATIC=1 PROGRAMS="dropbear dbclient dropbearkey dropbearconvert scp" install
But it did not help in this case.

Nowadays I do not know a better workaround in order to make it work than change the dropbear_exit to dropbear_log. I have found a discussion about this on Web and the following rationale seems reasonable:
Ah. If it's a single user system, the easiest solution might just be to disable the chown() and chmod() call - it's not like there're any other users who might be sniffing :)
(sshpty.c is where you'll find those chown/chmods).
... but be careful, you were warned ;-)

Minor issues

There were also two another problems (just warnings). The first was wtmp problem:
[2398] Dec 01 12:13:04 wtmp_write: problem writing /var/log/wtmp: No such file or directory
It was solved by adding the --disable-wtmp to the configure command line.

The second was logging problem:
dev# ssh root@storage
root@storage's password:
[2719] Dec 01 13:25:53 lastlog_perform_login: Couldn't stat /var/log/lastlog: No such file or directory
[2719] Dec 01 13:25:53 lastlog_openseek: /var/log/lastlog is not a file or directory!

  [    FW 4.00b4.C009-M[NG]    ]
  [ http://mgb111.pradnik.net/ ]
We are not alone on this (see this post or OpenWrt ticket, also this archive served as a source of information).

It was solved by adding the --disable-lastlog to the configure command line.

Final build

As a result we have the following configure command line:
dev# ./configure --prefix /mnt/C/sys --disable-zlib --disable-openpty --disable-wtmp --disable-lastlog
Now we can modify the Makefile in order to generate code optimized for size:
dev# nano Makefile
...
CFLAGS=-I. -I$(srcdir) -I$(srcdir)/libtomcrypt/src/headers/ $(CPPFLAGS) -I/mnt/C/sys/include -I/mnt/C/sys/X11/include -Os
If we want to create multi-application instead of individual applications, we can use MULTI variable on the make command line:
dev# make STATIC=1 PROGRAMS="dropbear dbclient dropbearkey dropbearconvert scp" clean
dev# make STATIC=1 MULTI=1 PROGRAMS="dropbear dbclient dropbearkey dropbearconvert scp"
We can strip the sources to spare some space:
dev# make STATIC=1 MULTI=1 PROGRAMS="dropbear dbclient dropbearkey dropbearconvert scp" strip
And are ready to install and create the package:
dev# make STATIC=1 MULTI=1 PROGRAMS="dropbear dbclient dropbearkey dropbearconvert scp" install
dev# cd /mnt/C
dev# ./filopack.sh --pack dropbear-0.52

Test

Start the dropbear server (logging to strerr, not forking to background):
box# dropbear -E -F
[902] Dec 22 02:14:49 Not backgrounding
This is output when I was connecting from a machine without a registered public key:
[906] Dec 22 02:14:52 Child connection from 192.168.1.102:44241
[906] Dec 22 02:15:02 password auth succeeded for 'root' from 192.168.1.102:44241
[906] Dec 22 02:15:02 chown(/dev/ttyp3, 0, 0) failed: Read-only file system
[906] Dec 22 02:15:02 !!! Filodej is warning you. Be sure you are the only user !!!
[906] Dec 22 02:15:02 chmod(/dev/ttyp3, 0622) failed: Read-only file system
[906] Dec 22 02:15:47 chown /dev/ttyp3 0 0 failed: Read-only file system
[906] Dec 22 02:15:47 chmod /dev/ttyp3 0666 failed: Read-only file system
[906] Dec 22 02:15:47 exit after auth (root): Exited normally
This is output when I was connecting from a machine with registered public key:
[913] Dec 22 02:15:59 Child connection from 192.168.1.102:44242
[913] Dec 22 02:16:06 pubkey auth succeeded for 'root' with key md5 f1:...:3b from 192.168.1.102:44242
[913] Dec 22 02:16:06 chown(/dev/ttyp3, 0, 0) failed: Read-only file system
[913] Dec 22 02:16:06 !!! Filodej is warning you. Be sure you are the only user !!!
[913] Dec 22 02:16:06 chmod(/dev/ttyp3, 0622) failed: Read-only file system
[913] Dec 22 02:16:21 chown /dev/ttyp3 0 0 failed: Read-only file system
[913] Dec 22 02:16:21 chmod /dev/ttyp3 0666 failed: Read-only file system
[913] Dec 22 02:16:21 exit after auth (root): Exited normally

16 comments:

Anonymous said...

I have set up your dropbear and it works fine. However, I have another problem with public key authentication.
I can not permanently change root home dir to /mnt/C/sys/root. I set up RCNG and ROOTDIR variables to 1 in env-ng, but after reboot root home dir in passwd file stays /root. I am using fw c009m2.
I tried to debug the problem with putting line cat /var/config/passwd >> /var/log/messages in rc-local script and I see that passwd file is changed correctly by rc.nextgen script, but later it is changed back to original one. It seems to me that rc.nextgen script is executed too early or some other process (probably "ed") works after rc.nextgen and rc-local scripts. Am I the only one with this problem?

Anonymous said...

Funny; last week I more or less followed the same process in getting dropbear to run after experiencing problems with the version from http://mgb111.pradnik.net/en.htm; it took me ages to come to the conclusion it doesn't support private/public key authentication.

Thanks for your description. One remark; why do you mention to compile with --disable-syslog? Not needed to get rid of the lastlog problems and no logging at all is not to be recommended; you will never find out whether people are 'knocking on your door'.

Ernst

filodej said...

Hello Ernst,
I also spent a lot of time trying to configure the pubkey auth before I finally realized that (exceptionally) the problem was not between my chair and keyboard ;-)

Regarding the --disable-syslog issue:

I have looked to the configuration log and of course syslog-ing is enabled.
Before I have found the solution of the lastlog warning I tried to disable syslog, but later on re-enabled it again. But I forgot to update my notes and later blindly copied that part to the post.
This is the (part of) config.log from the final build which is published as the binary package:

This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.

It was created by configure, which was
generated by GNU Autoconf 2.61. Invocation command line was

$ ./configure --prefix /mnt/C/sys --disable-zlib --disable-wtmp --disable-lastlog

## --------- ##
## Platform. ##
## --------- ##

hostname = debian
uname -m = i686
uname -r = 2.6.22-co-0.7.2
uname -s = Linux
uname -v = #1 PREEMPT Fri Jan 18 21:44:04 UTC 2008
...

I have also made sure that the logging is actually performed (what you probably realized as well), so there is nothing to be afraid of, in this respect. It was just the text of the post what was wrong.

Thank you very much for letting me know.

Regards,
Filodej

filodej said...

Hello Ivan,
sorry for the delay.

Unfortunately I do not know how to help you. I have briefly looked at the scripts but do not know how the boot-up sequence exactly runs. In any case in my case everything works fine (of course I have RCNG and ROOTDIR enabled and root's home directory is being changed properly).

I just wonder, don't you have some scripts/links in /mnt/C/sys/etc/rc.d//mnt/C/sys/etc/start.d directories which are doing a bad job?

I am for example doing some /etc/passwd postprocessing in /mnt/C/sys/etc/rc.d/rc.cfg script:


box# cat /mnt/C/sys/etc/rc.d/rc.cfg

# place user dirs at /home directory
sed -i 's|/tmp/Virtual/|/home/|g' /var/config/passwd
sed -i 's|nobody:/share|nobody:/home/nobody|g' /var/config/passwd
sed -i 's|FTP USER:/share|FTP USER:/home/ftp|g' /var/config/passwd
sed -i 's|/mnt/C/sys/bin/|/usr/bin/|g' /var/config/passwd


Alternatively you could similarly make some script using sed to workaround the problem you have (the question is WHEN your passwd file is being changed back, whether it is before or after these scripts).

I am just guessing here. Maybe you could rather ask JoKeR's, since he is the author of the scripts (I think so) and also a details in the sequence can vary from version to version.

Please, let me know how you proceed.

Kind regards,
Filodej

Anonymous said...

I played with some settings in WebIf, changed DHCP from auto to client, changed time settings, switched from wireless client to cable connection with my router, in the meantime few reboots occured.
After a while I noticed that the problem disappeared, but I don't have a clue how it happened. Now it works as expected.
But, I found another problem, my HDD never goes to sleep mode, it always works. I killed dropbear to check if it will go to sleep mode, but no luck. I noticed that today because I moved WMU to the living room, it was in the hall before. So, I don't know if sleep mode ever worked. Does it work on your device?

Anonymous said...

I wasn't succeed in enabling rsa key authentication. I've put authorized_keys in /mnt/C/root/.ssh/ and /mnt/C/sys/etc/
No effect. putty says "Server refused our key".

filodej said...

Hi,
Did you try to connect in verbose mode?
You can try -v, -vv, or -vvv (whatever will suffice - for ssh command line details see this page) and look at the console output.

Let me know how you proceed.
Regards,
Filodej

filodej said...

Sorry, at first I did not notice you are using putty. Then you can use plink.exe with -v command line switch (see this page for command line reference). From the Putty Download page yout can also get the pageant.exe.

Just to make sure you have your authentication configured properly look at this or this page).

F.

Anonymous said...

Thanks for the quick answer, but still I had no luck. I had some experience configuring RSA keys authentication, I've done it for router with DD-WRT on it.

Here is what I've got from plink.exe:


Looking up host "172.16.1.151"
Connecting to 172.16.1.151 port 22
Server version: SSH-2.0-dropbear_0.52
We claim version: SSH-2.0-PuTTY_Release_0.60
Using SSH protocol version 2
Using Diffie-Hellman with standard group "group1"
Doing Diffie-Hellman key exchange with hash SHA-1
Host key fingerprint is:
ssh-rsa 1039 00:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx
Initialised AES-256 SDCTR client->server encryption
Initialised HMAC-SHA1 client->server MAC algorithm
Initialised AES-256 SDCTR server->client encryption
Initialised HMAC-SHA1 server->client MAC algorithm
Reading private key file "D:\Docs\Private\media.ppk"
Using username "root".
Offered public key
Server refused our key
Server refused public key


authorized_keys placed in a dir /mnt/C/sys/root/.ssh

Owner is root.root, access rights are 0600 for files and 0700 for .ssh folder.

Looks like authorized_keys aren't picked up for some reason. But I don't know the way to find out why.

filodej said...

Hi,
By default the dropbear server is logging to the standard log and so you can look at the log via Web interface or from the console:

box# tail /var/log/messages
...
Feb 10 22:25:17 dropbear[23535]: Running in background
Feb 10 22:31:43 dropbear[23535]: Child connection from <IP>:<port>
Feb 10 22:31:48 dropbear[23535]: pubkey auth succeeded for 'root' with key md5 <key> from <IP>:<port>
...

If you are experimenting with it, you can try not to demonize the dropbear server, and make it print messages to stdout rather than to system log.

Important note: If you choose to kill the dropbear server, make sure you have the telnet server running and that you are connected through it (rather than via ssh ;-)

box# killall dropbear
box# dropbear -F -E
[23448] Feb 10 22:10:00 Not backgrounding

-- connect (via ssh or plink) --

[23448] Feb 10 22:10:31 Child connection from <IP>:<port>
[23448] Feb 10 22:10:35 pubkey auth succeeded for 'root' with key md5 <key> from <IP>:<port>
...


If this does not help you can try system trace:

box# killall dropbear
box# strace -f -o db.log dropbear -F -E
...

... and look where it tries to find the file containing authorized keys:

box# cat db.log | grep authorized_keys
23404 stat64("/mnt/C/sys/root/.ssh/authorized_keys", {st_mode=S_IFREG|0600, st_size=1798, ...}) = 0
23404 open("/mnt/C/sys/root/.ssh/authorized_keys", O_RDONLY|O_LARGEFILE) = 7
23404 stat64("/mnt/C/sys/root/.ssh/authorized_keys", {st_mode=S_IFREG|0600, st_size=1798, ...}) = 0
23404 open("/mnt/C/sys/root/.ssh/authorized_keys", O_RDONLY|O_LARGEFILE) = 7


I wish this helps you to find the cause.

Regards,
Filodej

Anonymous said...

Thanks for suggestions. I did all of this yesterday. The problem is that strace log does not contain any traces of 'authorized_keys' at all.

I have downloaded sources and saw that at first it checks for for ~/.ssh/ dir permission. And, I think the problem is exactly here because here's what I've got:

27069 stat64("/root/.ssh", 0xbffff50c) = -1 ENOENT (No such file or directory)

For some reason home dir is /root rather than /mnt/C/sys/root.

I am not linux expert, I don't know why it is so. My knowledge is beyond this. I've done basic checks:


$ set | grep HOME
HOME='/mnt/C/sys/root'
$ cd ~
$ pwd
/mnt/C/sys/root
$

Anonymous said...

Sorry, filodej, I solved the problem. The very first Ivan's post helped me. I did not know anything about rc.nextgen.
After I edited it, everything went fine.

Anyway, thanks for the great WMU-6500FS support!

Unknown said...

I have dropbear working fine per your instructions, but only when I log on from my linux box. auth_keys are in /mnt/C/root/.ssh/ and contains the public key from my linux box. The problem is that I cannot seem to add another public key so that I can log in from another box (mgb111, dropbear client) or from a windows box using putty. I extract the public key (in the case of mgb111) using dropbearkey -y -f dropbear_rsa_host_key. Am I overlooking something?

filodej said...

Hi,
sorry for the late reply.

Did you try the verbose mode on the client side? Did you look at the syslog on the sever side?

It probably is not your case, but one thing which comes into my mind is a possible public key incompatibility. I have encountered a problem once, when I installed msysgit on Windows machine and also had the CopSSH installed on the same machine. Then when I was connecting with msys ssh client to another machine having my CopSSH generated pubkey, I was not able to authenticate. Before this experience I had (naively) thought that the key is interchangeable.

Another story is the putty's incompatible key format, but I presume you have converted it properly.

Sorry, I do not know what the problem could be, please, let me know if you succeed.

Regards,
Filodej

Unknown said...

Ok, so it was me not fully comprehending public/private key pairs. I was under the assumption that the key pair I generated using dropbearkey -t rsa -f /mnt/C/sys/etc/dropbear_rsa_host_key would work for dbclient as well. It was only after reviewing dropbear readme for the umpteenth time that I realized the error of my ways. All is fine now, and thank you for your response.

Unknown said...

thanks, that patching fixed my /dev/ permission problem! (finally!)