Mobile Multimedia Lab



P2PWNC: Peer-to-peer Wireless Network Confederation RI - Documentation




In this section, we describe the process of porting Dropbear SSH daemon to the Linksys WRT54GS router platform. For the following, we assume that the user has downloaded the latest version of the source distribution of the Linksys WRT54GS firmware from Linksys FTP site, extracted it to srcpath. and set up a cross compilation toolchain to build the firmware. General instructions on setting up the toolchain and building the router's firmware from sources can be found here.

Following is a list of steps for building Dropbear SSH from sources and bundling it with the Linksys WRT54GS router firmware.
  • Download the latest version of the Dropbear software.

  • Extract the sources and move the directory to release/src/router/dropbear.

  • Have a parallel dropbear build directory so that you can build it for the current platform (e.g i386). This is needed in order to have the key generation utilities which will be used to generate the SSH server access point keys. Server keys must have been generated prior to the firmware image creation, because they'll be included in the firmware. Issue the following commands in this directory:

    ./configure
    make
    ./dropbearkey -t rsa -f dropbear_rsa_host_key
    ./dropbearkey -t dss -f dropbear_dss_host_key


  • Move to release/src/router/dropbear directory, export the appropriate CC variable and configure the package. Also, copy (or maybe ln) the libutil library there, since it is required for the compilation of the Dropbear package:

    cd release/src/router/dropbear
    export CC=mipsel-uclibc-gcc
    ./configure --host=mipsel-unknown-linux-gnu --disable-zlib
    cp /opt/brcm/hndtools-mipsel-uclibc/lib/libutil.so.0 .


  • Copy the server keys here.

    cp <i386_dropbear_build_dir>/dropbear_rsa_host_key .
    cp <i386_dropbear_build_dir>/dropbear_dss_host_key .


  • cd back to release/src/router directory

    cd ..


  • Edit the config/Config file, adding the following record:

    config CONFIG_DROPBEAR
        bool "Dropbear SSHd"
        default y
        help
        Dropbear v0.43


  • Edit Makefile as follows:
    • Add the following line in the "Configuration" section

      obj-$(CONFIG_DROPBEAR) += dropbear


    • Add the following in the "overrides" section:

      dropbear:     $(MAKE) -C dropbear

      dropbear-install:
          install -d -m 755 $(INSTALLDIR)/dropbear/lib
          install -d -m 755 $(INSTALLDIR)/dropbear/etc
          install -d -m 755 $(INSTALLDIR)/dropbear/etc/dropbear

          install -m 755 dropbear/dropbear $(INSTALLDIR)/dropbear/usr/sbin
          install -m 400 dropbear/dropbear_rsa_host_key $(INSTALLDIR)/dropbear/etc/dropbear
          install -m 400 dropbear/dropbear_dss_host_key $(INSTALLDIR)/dropbear/etc/dropbear
          #copy libutil.so.0 to the router/dropbear directory before building the fw
          install -m 755 dropbear/libutil.so.0 $(INSTALLDIR)/dropbear/lib/

          ln -s /tmp/shadow $(INSTALLDIR)/dropbear/etc/shadow
          ln -s /tmp/passwd $(INSTALLDIR)/dropbear/etc/passwd
          ln -s /tmp/group $(INSTALLDIR)/dropbear/etc/group


  • In order for Dropbear SSH daemon to init on router startup, the following function must be put inside router/rc/services.c

    int
    start_dropbear(void)
    {
        int ret = 0;

        //read passwd, shadow, group file contents from nvram
        //if nvram vars are not ste then restore defaults (usr: root, pass: root)
        char *passwd;
        passwd = nvram_safe_get("passwd");
        if (!strlen(passwd)) {
            nvram_set("passwd", "root:x:0:0:root:/tmp:/bin/sh");
            nvram_commit();
            passwd = nvram_safe_get("passwd");
        }

        char *shadow;
        shadow = nvram_safe_get("shadow");
        if (!strlen(shadow)) {
            nvram_set("shadow", "root:$1$EY7zeAhN$TtFD2kKzQf//ncVlSuwNA.:12753:0:99999:7:::");
            nvram_commit();
            shadow = nvram_safe_get("shadow");
        }

        char *group;
        group = nvram_safe_get("group");
        if (!strlen(group)) {
            nvram_set("group", "root:x:0:");
            nvram_commit();
            group = nvram_safe_get("group");
        }

        // these /tmp/... files are symlinked to /ect/...
        //write contents to /tmp/ files
        FILE* fp = fopen("/tmp/passwd", "w");
        fprintf(fp, "%s\n", passwd);
        fclose(fp);
        chmod("/tmp/passwd", 0400);

        fp = fopen("/tmp/shadow", "w");
        fprintf(fp, "%s\n", shadow);
        fclose(fp);
        chmod("/tmp/shadow", 0400);

        fp = fopen("/tmp/group", "w");
        fprintf(fp, "%s\n", group);
        fclose(fp);
        chmod("/tmp/group", 0400);

        //start dropbear
        ret = eval("/usr/sbin/dropbear");

        dprintf("done\n");
        return ret;
    }

    Afterwards, the following line must be placed inside
    start_services()
    function:
    start_dropbear();

    start_services()
    is a function that is called on router startup and is responsible for starting some services, as its name implies. Also, one has to add the following function declaration inside router/rc/rc.h:

    extern int start_dropbear();


    The above routine reads the contents of /etc/passwd, /etc/shadow and /etc/groups from the corresponding nvram variables (Obviously, these files have to be created before the firmware installation on another pc) and starts dropbear. These files are symbolic links to /tmp files which are constructed on router startup. Default values are hardcoded in the firmware code. These values are:

    username:
    root

    passwd:
    root


    It is a good practice to replace these values the first time one operates the router. This can be done as follows:

    • Construst the group, shadow and etc files on another pc.

    • ssh the router using the default user/passwd pair

    • set the new nvram values for the above files. For example:

      # nvram set passwd='root:x:0:0:root:/tmp:/bin/sh'
      # nvram commit
      # nvram set shadow='root:$1$EY7zeAhN$TtFD2kKzQf//ncVlSuwNA.:12753:0:99999:7:::'
      # nvram commit
      # nvram set group='root:x:0:'
      # nvram commit

    • Restart the router for the new values to take effect. Upon restart, the router will read these nvram nariables and construct the correspondent /tmp/... files, which are symlinked by the correspondent /etc/files that are read by the dropbear server.

      The following is a sample /etc/passwd file:

      root:x:0:0:root:/tmp:/bin/sh
      pfrag:x:501:501:pfrag:/tmp:/bin/sh

      The following is a sample /etc/group file:

      root:x:0:
      pfrag:x:501:


  • Edit release/src/cy_conf.h, adding the following:

    #define DROPBEAR_SUPPORT    1
    #define CONFIG_DROPBEAR     y


  • Edit release/src/cy_conf.mak file, adding the following:

    DROPBEAR_SUPPORT=1
    CONFIG_DROPBEAR=y


The above HOWTO is available in txt format here