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/
# dropbear-keygen
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.
# ls
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
#!/system/bin/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).