llemarie’s weblog

Programming, tinkering – Lionel Lemarié

Tip: Connect to your iPhone using VNC and SSH

Posted by llemarie on September 5, 2009

VNC connection to iPhone

VNC connection to iPhone

After a short hiatus I thought I’d post something short and sweet to ease back into it.

There’s been quite a bit of news of people getting the location of their stolen iPhones via MobileMe. It’s also nice for your own peace of mind to be able to tell the phone to wipe itself so all your precious data doesn’t fall into thieving hands.

MobileMe is $99 a year though. Count me out.

Now I’ve previously talked about how to setup a tunnel to connect to a remote PC securely via Remote Desktop. In the same way it’s possible to connect to your iPhone securely, and, more importantly, wherever it has data access!

Here’s how to setup a persistent SSH tunnel from the iPhone to your home server that gives you SSH and VNC access to the phone.

You need:

– A home SSH server visible from the outside. If you want your phone to phone home, you need something to pick up.

– A jailbroken iPhone. If you don’t want to jailbreak it, there’s always MobileMe.

OpenSSH for iPhone. Install it via Cydia. Make sure you change the default passwd for both ‘root’ and ‘mobile’ users.

VNC server for iPhone. It’s called Veency, install it via Cydia. Go to the Settings and set a connection password.

Autossh. Install it via Cydia.

That’s it, now you just need a script to start the tunnel, another script to start the first script at load time, to register your phone ssh key on your home server and we’re done here.

The tunnel script, via the Terminal or a SFTP application (I recommend the free FileZilla), write it as /bin/autohome.sh:

export HOME=/var/root
autossh -M 20000 -f -2 -N -C -R *:50022:localhost:22 -R *:5901:localhost:5900 USERNAME@HOME

Set the permissions to 755 (chmod 755 /bin/autohome.sh, that’s read/write/execute as root, read/execute for others).

Easy enough. Set your USERNAME and HOME address to your public home SSH server. The only gotcha is the gatetime setting, it must be set to 0 to allow the connection to start at boot time: it will very likely fail a few times until the iPhone finds a data connection (3G or Wifi), but you want autossh to retry until it connects, which is not the default behaviour. Make sure that the file has the Linux end of lines.

The boot script, write it as /System/Library/LaunchDaemons/com.autohome.startup.plist:

<?xml version=”1.0″ encoding=”UTF-8″?>
<!DOCTYPE plist PUBLIC “-//Apple Computer//DTD PLIST 1.0//EN” “http://www.apple.com/DTDs/PropertyList-1.0.dtd”&gt;
<plist version=”1.0″>

Set the permissions to 644 (read/write as root, read only for others).

Now you need to be able to login to your home server from the phone without typing your password. You also don’t want to compromise the security of your home machine, if it can be avoided. For that, you can add a new user specifically for the phone (for instance ‘mobilemoi’), set its login shell to /bin/false (using the chsh command) and remove its password from the /etc/passwd file. Give this user access to nothing. Don’t forget to use this user in the tunnel script.

Login onto the iPhone via SSH as root (using putty.exe for example), run ssh-keygen using the default settings. We’ll need the public key that was just created, so cat ~/.ssh/id_rsa.pub and copy the string in the clipboard.

Login onto the home server as root, go in the ‘mobilemoi’ directory, create a .ssh directory, in there create a file called authorized_keys and paste the public key in there. From the mobilemoi directory, run chown -R mobilemoi.mobilemoi .ssh to set the right permissions.

Test it. On the phone, as root, run autohome.sh. On the home server, run netstat -a. After a short while, you should see the phone’s connections, lines like these:

tcp        0      0 Unknown-xxxx:ssh        xxxx:62595              ESTABLISHED
tcp6       0      0 [::]:20000              [::]:*                  LISTEN
tcp6       0      0 [::]:50022              [::]:*                  LISTEN
tcp6       0      0 [::]:5901               [::]:*                  LISTEN

If the connections look like “localhost:5901” instead of “*:5901” or “[::]:5901” then that’s a problem in the sshd config file. Edit /etc/ssh/sshd_config and add “GatewayPorts yes”. Restart the ssh server.

Now to connect to the iPhone and control it from any PC, install VNC, start the viewer, connect to the VNC server using your home SSH server address (likely on the internal IP) on port 1.

For example:

VNC Viewer settings

VNC Viewer settings

You can also use an SSH client to connect to the iPhone via the tunnel. Point the client to your home server (again the internal IP), on port 50022.

Right. Reboot your iPhone, make sure that the tunnels are created. You’re done.

Now every time you boot your iPhone, a tunnel is created to your home server. This gives you the IP of the phone (via the server logs), SSH access to the phone and VNC control of the phone. The possibilities are limitless!


As of the time of writing, I have not fully verified the drain on the battery that results from the permanent connection. I believe that it should be minimal, but it has yet to be observed. I will update the post with more information when I know for sure one way or the other. The connection parameters may need to be tweaked to minimise the impact on the battery life.

EDIT: After some experimentation, it appears that there is a toll on the battery life after all. I will continue to investigate.

Ideally the connection would start on demand. It would be nice to send a push message to the phone that would trigger the start of autossh. This would essentially be free (or no more costly than push notifications are) and offer the same functionality.

Thanks to Saurik for the most of the software needed for this feature.

28 Responses to “Tip: Connect to your iPhone using VNC and SSH”

  1. Robert said

    I have been following a couple of threads about this topic for weeks. I had some success but I never implemented the entire solution for fear of possibly bricking my phone, but this seemed simple and worked for me on the first try. I was amazed. Great instructions.


  2. Dan said

    Very nice, I’ve been following this topic on various forums as well and glad to see it’s finally been accomplished. I spent all night trying to get this working on my phone without success because I’m a complete noob when it comes to SSH and Terminal. I think I’m going to have to read up on the fundamentals of this stuff before I try again.

  3. alex said

    ok i did the top two scripts but i dont want to make a whole new user file on my pc or anything is there a way to just add a way to enter password on the first script so i can just log on to my home ssh server with a password please

    • llemarie said

      Hi Alex,

      The ssh client does not allow you to add the password as an argument (this would be a serious security concern). Instead ssh using public and private keys. It’s important to do it this way, so as to lower the risk. It doesn’t take long to create the files.


  4. alex said

    export HOME=/var/root
    autossh -M 20000 -f -2 -N -C -R *:50022:localhost:22 -R *:5901:localhost:5900 USERNAME@HOME

    on that scripts is there a way to just make it enter the password for me so it can log on to my ssh server? please help!! also can i use 1201:localhost:5900 because i have gotten it to work with that and i dont want to change anything since i am a complete noob i just want to log on to my phone at all time from my pc please help email me if you can kadafiamafia16@HOtmail.com

  5. alex said

    i know about the security concerns but also i am very stupid and i rather you just help me by making the autohome.sh script log in to ssh -p 22 kadafia@ip -R 1201:localhost:5900 and enter password and also rerun when connection is down please please i stayed up for 3 days straight trying to get the ssh server on my computer thru cygwin i dont know anything about ssh or vnc but i finally got it work.. and the command i use on mobile terminal is ssh -p 22 kadafia@ip -R 1201:localhost:5900 i created the autohome.sh and the System/Library/LaunchDaemons/com.autohome.startup.plist: please please help

  6. alex said

    and if its not possible please email me your number and walk me thru the steps i am so lost and i could use a helping hand…my email is kadafiamafia16@Hotmail.com

  7. Thomas Le Charles said

    This is a highly illegal article… You should be ashamed, Monsieur!

    • Johnny Lee said

      in wat way is accessing a home server via ur iphone illegal? jailbreaking (the process required) may be a breach of warrenty, and maybe your service provider may not like the fact that servers can be accessed remotely via reverse tunnels, but does not defy the at&t firewall… reversed tunnels have been used to personnally bypass routers/firewalls for a long time… just because its on a phone should not affect legality… i even wrote some unix scripts for mac that could be considered a backdoor if used without admin… so please enlighten us…

  8. Awesome stuff! I NEVER would have thought of setting up the reverse tunnel like that, but it now seems so obvious. You’re a genius.

  9. Sean said

    Thanks, llemarie.

    Don’t know about push and the iPhone, but i have a suspicion that Apple holds the gateway to push to handsets and you need an approved app to have a channel to do that…

    I would love to see it, though. With that capability, one could push shell commands, or in this case, the push trigger could include the user@host string autossh executes with!

    Any thoughts on this?

    • llemarie said

      Hi Sean,
      Pushing commands and connection requests is an interesting concept, but I don’t think it’s feasible. It would be a potentially serious security risk. Also, receiving a notification is not enough, you need to process it. The iPhone will display a dialog upon reception, but you still need to open the associated app in order to actually process it. It’s not a big problem as a workflow, but such an app would never get approved.

  10. Great tutorial, and I’m sure my lack of success is my own stupidity!

    Tried as per the above, but when I get down to the netstat command, I see only LISTEN on 50022 (both tcp and tcp6), no mention of ports 20000 or 5901. What did I get wrong?

    • llemarie said

      Hi Ken,

      Make sure that the ssh (or autossh) command was written and executed correctly, that’s what opens the ports. Make sure the spaces are correct, etc… I checked the post, the command is exactly correct, so you can copy/paste it.


      • I think there’s an execute problem somewhere (my error I’m sure). If I run /bin/autohome.sh manually there are no errors, but the HOME and AUTOSSH_GATETIME env-vars are not set afterwards.

        Does the iPhone maintain a system log anywhere? I can’t find the darn thing!

  11. whoops *edit* HOME has been set. No sign of AUTOSSH_GATETIME, though!

  12. egregious said

    I’ve been working with this idea for a while. I’ve come to realize that the -f flag for autossh in the launchdaemon script causes it to not play well with launchctl. Removing this flag allows starts and stops such as:

    launchctl start com.autohome.startup
    launchctl stop com.autohome.startup

    With the -f flag in place (in my experience), autossh only goes away with ‘kill -9 [pid]’ (e.g.)

    I’m not sure why this is, but just an fyi in case someone else runs into this same problem…

  13. egregious said

    Actually, I’m pretty sure I *do* know why this is. In the -f case, our daemon script exits and launchctl doesn’t have its original process to stop. Without the -f flag, the daemon script continues to run until autossh exits. Generally, autossh won’t exit until the phone is powered down or until someone runs:

    launchctl stop com.autohome.startup

    Removing the -f flag makes our daemon run more like it should…

  14. Dear friend,
    thank you for this great tutorial!

    I’ve tried this instruction, and it works!

    By the way I think that there is an error in the .plist file.
    The iPad does not autorun tunnel on startup, so I’ve checked around and found that there is an array tag missing.

    So, the code for com.autohome.startup.plist would be:


    Naturally it have to be in LF endline format.
    I haven’t tried it already, but I will do it soon!

    Thanks again

  15. To the moderator:
    When I’ve sent my comment I have noticed that tags have been removed from text.

    Please let me know if you can fix it or I have to send this information through other ways.

    Thank you for your help!

    • Dmitry said

      Could you, please, find a way to publish your corrections. Maybe, change to [], etc. I’m experiencing troubles running this script.
      Or, just, please, mail it me at dima[at]melodrom.ru

      • Dear Dmitry, friends all…

        I have removed -f command in the autohome.sh script as stated above.

        I have corrected the .plist file this way:

        (?xml version=”1.0″ encoding=”UTF-8″?)
        (!DOCTYPE plist PUBLIC “-//Apple//DTD PLIST 1.0//EN” “http://www.apple.com/DTDs/PropertyList-1.0.dtd”)
        (plist version=”1.0″)

        Please change “(” and “)” to minor and major characters, because this site does not allow tags in posts.
        Notice that the ARRAY tag is completely miss in the original script, also the “true” value was out of KEY tag.

        I have checked the script using plisteditor downloaded from http://www.icopybot.com/download.htm and it results ok
        I have tried this script giving it 755 permissions because on my iPad3 the 644 caused the device not to boot

        By the way, I’ve realized that something missed, because the tunnel does not start automatically, I have to launch it from SSH terminal (putty or somewhat else).
        I have just found this site: http://stackoverflow.com/questions/9832290/start-an-app-on-boot-up-on-an-ipad-which-has-been-jailbroken-ios telling about launchctl command on iPad.

        I want to try this way, but now I haven’t the device ready, let’s have a look at.

        I will be heard by you soon!
        Peace and Serenity (:

      • Dmitry said

        Strange thing is, this script works AS IS on my iPhone, but I failed to run it on other devices.

        Also, one’s got to pay attention to unix-only ends of lines and no utf characters in the script file.

      • Yes, you have to save scripts in UNIX end-of-line format, otherwise you will receive “^M command not found” errors. (^M is text plain for Windows end-of-line character).

        If you have a linux supporting it, you can use dos2uni command. Example: “dos2uni /bin/autohome.sh” will remove ^M characters from file, making it correctly readable by iOS.

        I haven’t already tried the launchctl command yet.
        Cheers from Italy!

      • Uranya said


        the script I have sent above does not work, it does not start tunnel at boot time.

        After some other searches I have found a mistake of mine, and it is the True value to key “RunAtLoad”, the correct script MAY be (because I haven’t tested it yet)

        (?xml version=”1.0″ encoding=”UTF-8″?)
        (!DOCTYPE plist PUBLIC “-//Apple//DTD PLIST 1.0//EN” “http://www.apple.com/DTDs/PropertyList-1.0.dtd”)
        (plist version=”1.0″)

        note the (true/) value in row 14th.

        I will be heard by you soon!
        Serenity to you all

    • Uranya said

      BEWARE: On iPad 3 i have written the script for startup using permissions 644, the result is that iPad hangs on the Apple logo when starting by command “reboot” on SSH. Be careful of this. Someone told about “iPhoneBrowser” program to fix errors on booting, but it have problems running on an italian Windows XP OS. My friend, the owner of iPad has only WinXP, so we have to recover the iPad, now… Remotely because he is 600 KM away from here, and he is now a little scared.

      Plese discover the truth about starting automatically! Thank you

      • Dmitry said

        the provided shellscript will only work if you first ssh from device to server manually so that the server fingerprint is accepted and stored. Otherwise it may be possible to use some switch to override fingerprint check (see ssh manual), thus lowering security, though.

  16. Dmitry said

    Did you find a way to optimize this script in terms of power consumption?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: