photo by Daniel Leininger
Remote access to your phone might seem a bit odd, but being able to access my NexusOne from a computer with a real keyboard is nice when you need to poke around inside the internals. It also makes updating the photos, music, or movies possible without additional apps or cabling the phone to my PC. Today I forgot my phone at home, and was able to verify that I had “lost” it at home vs. somewhere else by ssh‘ing into my home network, then connecting over the local network to my phone using ssh.
There were 3 main steps:
- set the phone hostname on boot
- configure sshd
- make it start on boot
Step one was really easy, turns out it is a supported feature of CyanogenMod 7 (CM7). Enter the Settings menu, choose Applications then Development, now select Device Host Name. That’s it, I didn’t even need to reboot (the setting is persistent across reboots).
Step two is the most involved, the cyanogenmod wiki has some instructions as does this tutorial. I’ll attempt to provide a guided walk-through here.
a) Let’s assume you’ve got a linux desktop machine. First we’ll create some ssh client keys. We’re going to do this as the dropbear in CM7 doesn’t support key passphrases, so passwords are not an option. The other benefit to ssh client keys is that we can automate connecting to the phone.
So on the linux destop we’ll execute:
$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/youruser/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/youruser/.ssh/id_rsa.
Your public key has been saved in /home/youruser/.ssh/id_rsa.pub.
For the passphrase we left it empty. In very simple terms – the id_rsa is the private part of the key, the id_rsa.pub is the public one. We’re going to put the public key file onto the phone later. The private one will stay safe and secure on your desktop.
b) I’ll also assume you’ve got adb installed. By connecting the phone to the desktop machine via USB we can push the key file using adb.
$ sudo platform-tools/adb push /home/youruser/.ssh/id_rsa.pub /sdcard/authorized_keys
c) Now we’ll use adb to execute a shell on the phone. This is how I used to get in with a keyboard, but doing so without a wire hook up is very convenient.
$ sudo platform-tools/adb shell
d) Time to configure dropbear, these are all executed within the shell we just created on the phone. You’ll find this is pretty much exactly what the CM wiki describes.
# mkdir /data/dropbear
# mkdir /data/dropbear/.ssh
# cp /sdcard/authorized_keys /data/dropbear/.ssh/
Initially I had thought I could avoid running dropbear-keygen, but it turns out this is a required step. [Edit: In CM 7.1.0 RC1 dropbear-keygen is not installed, nor does it appear to be required] Now we initialize the keys.
# dropbearkey -t rsa -f /data/dropbear/dropbear_rsa_host_key
# dropbearkey -t dss -f /data/dropbear/dropbear_dss_host_key
And set permissions to keep things happy.
# chmod 755 /data/dropbear /data/dropbear/.ssh
# chmod 644 /data/dropbear/dropbear*host_key
# chmod 600 /data/dropbear/.ssh/authorized_keys
e) Now we get to try it.
# dropbear -v -s -g
The -v option tells it to be verbose, handy if something has gone wrong. You should now be able to connect via ssh from the linux desktop machine, but only from the user id that created the public/private key combination (of which we’ve moved the public key to the phone). Since in step 1 we set the hostname, we can do:
$ ssh myphone
The authenticity of host 'myphone (192.168.1.174)' can't be established.
RSA key fingerprint is 00:c0:b2:78:2b:af:04:72:90:bb:0d:46:f9:14:cc:3f.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'myphone' (RSA) to the list of known hosts.
dropbear.pid dropbear_dss_host_key dropbear_rsa_host_key
[edit: CM 7.1.0 seems to be causing me some trouble, in two areas. a) it requires the username matches, so use “ssh root@myphone” b) it doesn’t like rsa public keys but dsa works, so use “ssh-keygen -t dsa”. You’ll know you have the problem as you get a “permission denied (publickey)” error.]
f) Bonus step. We’ll add more keys from other systems we want to be able to connect to the phone from. We repeat (a) on each machine / user id we want to connect from and append the public key to the authorized_keys file.
cat /sdcard/newmachineid.pub >> /data/.ssh/authorized_keys
Now on to step three – making sshd start on boot. I’ll assume you don’t already have a /data/local/userinit.sh file yet for some other modification, if you do I’m sure you can sort this out.
[Edit – as was pointed out by Devon, the original version had !# instead of #! in the userinit.sh script, I’ve fixed the post to reflect the correct code – no worries, the wrong way still works fine as my comment indicates]
On the phone (using ssh or adb to access the shell) you run the following commands:
# echo -e '#!/system/bin/sh\n\ndropbear -s -g' > /data/local/userinit.sh
# chmod +rx /data/local/userinit.sh
You can even run vi if you want (it works!). We can check the resulting file with cat:
# cat /data/local/userinit.sh
dropbear -s -g
That’s it, we’re done. The next logical step is to start including your phone as part of your nightly rsnapshot backups, or building some scripts to make updating music on the phone easy (and wireless).
6 thoughts on “Cyanogenmod 7 and sshd”
Thanks for your walkthrough. It’s more clearer than others. I must say that I did not have ‘dropbear-keygen’ available on my CM7, but for me it did not seem to be nessasary to have run that. It worked without it.
I’ll point out that the last step should be:
# echo -e ‘#!/system/bin/sh\n\ndropbear -s -g’ > /data/local/userinit.sh
# chmod +rx /data/local/userinit.sh
That is, #! vs !#
Devon, you’re correct with your correction.
What is really weird, is that I just verified what’s been working just fine on my phone for weeks – and it is the !# order. Either the system is ignoring the line, or handling the ! followed by a comment character as nonsense and moving on. It is still wrong, but works.
Oh and Chris – I’m not Daniel – that’s just the person who took the nice photo that I’ve used from Flickr.
Thanks! This helped after I did a bit of floundering with the old instructions. I am another one that did not have ‘dropbear-keygen’ on cm7, I received a not found error when I ran it. Luckily, everything still went fine, I am now happily copying mp3s to my nook w WinSCP!
Thanks! this works great. Unfortunately after I got it all working and could ssh in to my phone while on my home lan/wifi I discovered that Verizon has it’s 3g network behind a NAT. So no access when i’m on the cell network 🙁
Ras, you can still ssh into it from behind the NAT you just need to do some port redirection within ssh. For example:
If you have dyndns on a server at home port forward a specific port to the system for the port you will use and run command:
ssh -R port specified:localhost:22 user@dynserver
If you setup keypairs this is easily scripted. Now when you ssh you can ssh to your root@dynserver -p portspecified and you will ssh to your phone.
If you’re like me and had a couple issues with dyn and this you can easily script: ssh -L whateverport:localhost:portonserverfromphone user@dynserver
That way you can ssh whateverport from localhost and connect to your phone.