ADB over SSH – Fun with port forwards

So last week one of my coworkers and I were discussing a VPN configuration to allow adb shells over 3G. Just tonight I realized that a VPN isn’t even required, SSH can do the same job with relatively little effort. Here’s how I rigged my setup.

Prerequisites:

  • A functional SSH server, accessible from outside your network.
  • Connectbot on your phone with a connection configured for your home computer.
  • A functional ADB over USB install with correct PATH variables set. When you open a new command prompt and type “adb shell” you should see a prompt from your phone.

Configuration of the above items are well documented elsewhere and will be outside the scope of this article.

So, having the prerequisites in order, you start by modifying your Connectbot connection as follows:

  • Long-press your connection in the list and choose “Edit host”.
  • Press “Post-login automation”.
  • In the box type “adb connect localhost:5555[ENTER]” the new line here ([ENTER] key) is necessary to automatically run the command.
  • Press “OK”.
  • Press back to return to the connection list.
  • Long-press your connection in the list and choose “Edit port forwards”.
  • Press Menu, then “Add port forward” and enter the following:
    • Nickname: “ADB”.
    • Type: “Remote”.
    • Source port: “5555”
    • Destination: “localhost:5555”
  • Press “Create port forward”.

Your connection is now configured to tunnel the ADB protocol over port 5555 from your computer to the phone via reverse SSH tunnelling. The next step is to configure ADB on the phone to listen over tcp/ip:

  • On your computer, with the phone connected via USB, type “adb tcpip 5555”.

That’s it! You can now disconnect your USB cable, take your phone on a car ride, etc. If you need to use adb with it, simply use Connectbot to connect to your home computer, after the connection is authenticated (you can use password or public-key) the adb connection will be made automatically, so you simply have to use adb as you normally would!

Remember that over 3G you’re going to have some delay for commands, here’s an example push:


redkrieg@h4xt0p:~$ time adb push Downloads/UniversalAndroot-1.6.2-beta5.apk /sdcard/
11 KB/s (964401 bytes in 83.041s)
redkrieg@h4xt0p:~$ ls -hal Downloads/UniversalAndroot-1.6.2-beta5.apk
-rw-r--r-- 1 redkrieg redkrieg 942K 2010-10-08 15:08 Downloads/UniversalAndroot-1.6.2-beta5.apk
redkrieg@h4xt0p:~$

So yeah, it’s slow as dirt, but I totally pushed a file from my home computer to my phone from across the city.

To undo this and restore normal USB ADB functionality, you must first connect with Connectbot using the instructions above, then from your computer run “adb usb” to return the phone to USB mode. If you’re unable to do this, you’ll need to run the following from a local shell on the phone:


su
setprop service.adb.tcp.port -1
stop adbd
start adbd

That’s it. Have fun!

Update: I’ve just thought things through and realized that this leaves root wide open to remote exploit if someone knows your IP. Probably best to switch back to USB adb once you’re done until I figure out a good way to block non-localhost connections to 5555 in iptables on boot. If you know how to do this, please post a comment, otherwise it’ll be my project for the night.

Update 2:
After some testing, it seems like T-mo blocks inbound connections like this, so iptables shouldn’t be necessary. That being said, the following rules should take care of any lingering doubt:


iptables -A INPUT -p tcp --dport 5555 -s 127.0.0.1 -j ACCEPT
iptables -A INPUT -p tcp --dport 5555 -j DROP