[Tutorial] Getting a SSH client and server working on CyanogenMod

I’ve had to do this a few times already on my Nexus One, so I thought I’d tutorialize it for the greater good. Basically, if you haven’t heard already, CyanogenMod is like the greatest thing to ever happen to Android. It provides a ton of goodies and really nice things that make your phone more powerful by an order of magnitude. It includes BusyBox, which is basically a really lightweight version of all of the core Linux/Unix utilities like “cp,” “mv,” “gcc,” and more. Importantly, CyanogenMod includes the DropBear SSH client and server.

Simply put, this means you can connect to and from your phone over SSH. Imagine being able to wirelessly push files from your phone over your home network. Imagine being able to tunnel VNC over SSH from your home computer to your phone so you can securely control your home computer even though you’re a hundred miles away. Yeah, pretty cool, right? Let’s get to it.

First things first. You must be running CyanogenMod 7 or later to do this. If you’re not, this isn’t the post for you. Move along. Second, this is going to take a little terminal trickery, so if you’re averse to working in a shell, go take some Pepto Bismol and come back. Also, if you’re new to SSH, you can do this, but you should probably read this book so you can understand how SSH works and how to set it up on your machine. Setting up a SSH server and client on your computer is way outside the scope here.

Let’s start by talking briefly about SSH security, specifically about using SSH keys rather than passwords. Keys are far more secure than passwords, and so we’re going to set up a key-based login system here. If you want to use passwords instead of keys, ignore the steps of this tutorial that read like “copy your key to …” and so and and so forth. DropBear can handle both passwords and keyfiles (so long as they’re generated by the DropBear key client), so you should be good either way. An important security problem to note up front is that DropBear currently does NOT support key passphrases! This may not seem like too big of a deal, but here’s what you need to know: if someone obtains access to your phone and your phone uses keys to authenticate with your machine(s), the person with your phone will have instant access to all devices which approve of your phone’s key. Let’s set up a scenario in which this would really, really suck:

Bob’s got a kickin-rad Android phone which is running CM7. He follows this tutorial like a true hacker and makes it so that he can connect to 3 public-facing computers over SSH using keys for authentication. Since DropBear keys don’t support passwords, Bob can literally connect to any of these computers without typing in any passwords. Bob likes this.

Bob goes to sleep that night, unaware that Jack Bauer is about to break into his house and steal his phone. Jack Bauer does so. Jack Bauer takes Bob’s phone. Jack Bauer now has complete access to those 3 computers. Jack Bauer connects to each computer and runs the following command: “rm -fr /home/$USER/”. This deletes the music, pictures, videos, and documents from all of the computers. Jack Bauer has pwned Bob’s computers.

Bob wakes up, but it’s too late.

Don’t let what happened to Bob happen to you. If you’re going to use DropBear keys, know what you’re getting yourself into. Guard your phone like Jack Bauer is going to break into your house at any given moment.

That being said, here we go. Make sure your phone is able to debug over USB, plug it in, and make sure it’s connected by running `adb devices`. If you can see your device’s id listed out, you’re ready to go. If you don’t know what “adb” is or how to install it, let me Google that for you. Next, run `adb remount`, then connect to your device using `adb shell`. You’ll now be dropped into a shell on the actual Android device. (*Note: if you want to do all of this stuff from your actual device, be my guest. It’s just much easier to type on a big physical keyboard in my opinion.) Next, type the following commands in order:

cd / 
mkdir /data/dropbear/.ssh
ln -s /data/dropbear/.ssh /data/.ssh

Now, we’ve created an important directory and have also made a symbolic link to it at “/data/.ssh” which is easier and shorter to type than “/data/dropbear/.ssh”. Now, let’s create the server keys for the DropBear server:

dropbearkey -t rsa -f /data/dropbear/dropbear_rsa_host_key
dropbearkey -t dss -f /data/dropbear/dropbear_dss_host_key

Cool. So, we created the server keys. Something very, very important to note is that for some reason, DropBear is very picky about file permissions. If the permissions aren’t set right, it will not work. I repeat, it will not work. Let’s take care of that now:

chmod 755 /data/dropbear /data/dropbear/.ssh /data/.ssh
chmod 644 /data/dropbear/dropbear_*_host_key

Ok. Now, we should be able to run our server properly. Now, let’s generate a client key:

dropbearkey -t rsa -f /data/.ssh/id_rsa
dropbearkey -y -f /data/.ssh/id_rsa | grep "^ssh-rsa" > /data/.ssh/id_rsa.pub
cat /data/.ssh/id_rsa.pub > /data/.ssh/authorized_keys
chmod 600 /data/.ssh/authorized_keys

Now, we have a way to identify ourselves to other machines when connecting. Now, let’s add some SSH keys to our device’s authorized keys so they can connect using SSH keys. This is assuming that your SSH key lives at ~/.ssh/id_rsa.pub. First, exit the shell by typing `exit`. Then run `adb push ~/.ssh/id_rsa.pub /sdcard/`. Now, connect to the device again via `adb shell`. Now run the following:

cat /sdcard/id_rsa.pub >> /data/.ssh/authorized_keys
chmod 600 /data/.ssh/authorized_keys
rm -f /sdcard/id_rsa.pub

This added the public key of your machine to the authorized keys of the DropBear server. You’ll now be able to connect to your Android device, after you’ve started the server of course. You can rinse and repeat the above commands to copy more keys to your authorized key file, just remember to set the permissions right or you’ll end up wasting a lot of time like I did.

Now, let’s make it so your machines can connect to your phone properly. Again, get out of the phone’s shell via `exit`, then run `adb pull /data/.ssh/id_rsa.pub .` then `cat /data/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys`. You’re all set.

The final step in all of this is to get your DropBear server working. First, `adb shell` into your phone and run the following:

dropbear -s -g -v

This will start the server in verbose mode (-v), only accepting keyed logins. Otherwise, anyone can connect to your phone as root with no password. Now, try connecting to your phone from another machine via `ssh ip-of-phone`. If you can connect, you’re good to go. Return to the open shell to your phone, run `killall dropbear` to stop the server. We’re going to get it to automatically start on boot, saving you time. Run the following on the phone:

echo -e '#!/system/bin/sh\n\ndropbear -s -g' > /data/local/userinit.sh
chmod +rx /data/local/userinit.sh

Restart your phone, try connecting, and if it works, we’re all done!

Oh, one more thing. If you want to connect from your phone to a computer using the key we generated earlier, run the following:

ssh -i /data/.ssh/id_rsa ip-of-machine

Hit up the comments if you run into any problems.

21 thoughts on “[Tutorial] Getting a SSH client and server working on CyanogenMod

  1. Pingback: TK Kocheran

  2. Pingback: Diane

  3. Pingback: Roo’s View » Blog Archive » Cyanogenmod 7 and sshd

  4. I’ve installed the current CM7 nightly and been trying to get dropbear to work as sshd – unfortunately it seems that after reading up from adb shell & trying a few market apps (quicksshd,…) I’m stuck at the same error all the time (second to last line in the log below). When connecting with puTTY I get a connection timed out error. Any and all help appreciated.

    [code]
    dropbear -v -s -g
    TRACE (5389): enter loadhostkeys
    TRACE (5389): enter buf_get_priv_key
    TRACE (5389): enter rsa_key_free
    TRACE (5389): leave rsa_key_free: key == NULL
    TRACE (5389): enter buf_get_rsa_priv_key
    TRACE (5389): enter buf_get_rsa_pub_key
    TRACE (5389): leave buf_get_rsa_pub_key: success
    TRACE (5389): leave buf_get_rsa_priv_key
    TRACE (5389): leave buf_get_priv_key
    TRACE (5389): enter buf_get_priv_key
    TRACE (5389): enter dsa_key_free
    TRACE (5389): enter dsa_key_free: key == NULL
    TRACE (5389): enter buf_get_dss_pub_key
    TRACE (5389): leave buf_get_dss_pub_key: success
    TRACE (5389): leave buf_get_priv_key
    TRACE (5389): leave loadhostkeys
    TRACE (5389): listensockets: 1 to try

    TRACE (5389): listening on ':22'
    TRACE (5389): enter dropbear_listen
    TRACE (5389): dropbear_listen: all interfaces
    TRACE (5389): bind(22) failed
    TRACE (5389): leave dropbear_listen: success, 1 socks bound
    [/code]

    netstat:
    [code]

    Proto Recv-Q Send-Q Local Address Foreign Address State
    tcp 0 0 127.0.0.1:7777 0.0.0.0:* LISTEN
    tcp 0 0 127.0.0.1:7203 0.0.0.0:* LISTEN
    tcp 0 0 127.0.0.1:5037 0.0.0.0:* LISTEN
    tcp 0 0 127.0.0.1:7777 127.0.0.1:50897 ESTABLISHED
    tcp 0 0 127.0.0.1:50897 127.0.0.1:7777 ESTABLISHED
    tcp 0 0 127.0.0.1:50896 127.0.0.1:7777 ESTABLISHED
    tcp 0 0 127.0.0.1:7777 127.0.0.1:50896 ESTABLISHED
    tcp6 0 0 :::22 :::* LISTEN
    tcp6 0 0 ::ffff:192.168.1.102:49539
    [/code]

    • I have the same problem. I start setup and start dropbear (as described above) and all my connection attempts hang in ‘syn_recv’. I can start and connect to telnetd. My netstat looks like yours. My telnetd shows up as listening on tcp6, also.

      One interesting thing I found is that I could locally connect to dropbear using ssh 127.0.0.1. I was even able to use an ssh client to forward my local ssh port to a remote box and ssh to dropbear through that forwarded port!

      It seems as though dropbear is listening but will only accept connections from the local loopback. SSHdroid and QuickSSh appeared to have the same problem. ConnectBot was not able to forward local ports. It’s like there’s something not right when it comes to apps listening on local ports. (Except for good ‘ol telnetd…)

      • :cry: same problem here. syn_recv if from network, connects fine if localhost. there is something wrong dudes. SGS2, Cyanogenmod (both 7.1 and nightly 116). Sometimes, it just works for a few days. wtf

      • Weird. I haven’t had this problem here yet. I recently reinstalled from scratch and wiped my SSH setup on the phone, so I’ll have to start over from my tutorial :) I’ll let you know what I find.

      • Just tried following the guide from scratch and things are still working for me. Are you guys trying to access your devices over the cellular network or something?

  5. Have you made sure to uninstall all SSH apps on your phone? It appears that something might be listening on port 22 which is preventing Dropbear from binding to that port.

    Also, why is it binding to a IPv6 protocol rather than IPv4? Unless you have an IPv6 network (very unlikely), you’re going to have problems trying to connect because of this. I think that something else is using port 22, make sure you’ve uninstalled all SSH server apps from your phone, reboot it, then try starting Dropbear again.

  6. Hello, regarding the syn_recv issue, it seems related to the wifi access point. I’ve encoutered the same issue with dropbear, and using another AP has made the whole thing working.

  7. Pingback: Luca Postregna

  8. To use password for SSH login instead of the keys, use the -Y option of dropbear to specify the master password to allow connection. Then, use this password when prompted for a password upon SSH login.

  9. I see you share interesting stuff here, you can earn some extra money, your website
    has big potential, for the monetizing method, just search in google – K2
    advices how to monetize a website

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>