Logging in to a Raspberry Pi on IPv6 from an iPhone on IPv4

The magic of IPv6 is that it lets any two IPv6-connected devices talk to each other directly. If this doesn’t sound incredible, consider the state of the IPv4 net: After more than two decades of NAT, it’s virtually impossible to get data between two devices without a (non-NATed) server in between.1 If I want to check the temperature setting on an Internet-connected thermostat, send a message to a friend’s phone, or receive a VoIP call, I need a to use a service that provides a server in the middle for both devices to connect to. And if I’m building a consumer-oriented IoT device company, messaging app, or VoIP service, a client-server model is effectively the only architecture choice I have.2 On a smaller scale, if I have a Raspberry Pi with an IPv6 address I can access it directly from anywhere in the world on the IPv6 Internet without any special configuration. No NAT setup required! Pretty neat, right?

IPv6 is amazing, but depending on your ISP you may not actually have a working IPv6 address by default. In my case, I have IPv6 connectivity with my home ISP (SoftBank), but not with my mobile ISP (also SoftBank). So no using Prompt to ssh to my Raspberry Pis from my iPhone without first sshing to a server in the middle with both IPv4 and IPv6 connectivity. Fortunately this isn’t too difficult, as most VPS providers3 enable IPv4/IPv6 dual-stack connectivity by default.

Security Prelude

This is a toy architecture to demonstrate one way to use a VPS to bridge IPv4 to IPv6. It is not a pattern that I would recommend for production systems or environments where security is a concern. In particular, because access credentials for the Raspberry Pi are stored on the VPS, any compromise of the VPS is also a compromise of the Raspberry Pi. And any compromise of the Raspberry Pi could enable a compromise of the network it is on–particularly a concern because a typical home network may have any number of poorly secured devices on it (old unpatched phones, tablets, computers, and IoT devices that rely on IPv4 NAT as a de facto security perimeter). Caveat emptor.

Step 1: Create a user on the VPS

Create a new user and lock the account to prevent password-based logins:

sudo adduser raspberrypi
sudo passwd -l raspberrypi

Step 2: Set up SSH keys:

Generate a key for the user you created in Step 1:

sudo -u raspberrypi ssh-keygen -o -a 100 -t ed25519


Add the public key you just created to to .ssh/authorized_keys file for your user on the Raspberry Pi. You could do this via copy and paste, or by running a command like this on your dual-stack VPS (assuming piIP is a file with the IPv6 address of your Raspberry Pi in it):

sudo cat /home/raspberrypi/.ssh/id_ed25519.pub | ssh [email protected]$(cat piIP ) "cat >> ~/.ssh/authorized_keys"

Add your phone’s public key to .ssh/authorized_keys for your new user on the VPS (raspberrypi in this case). If there’s an elegant way to do this, I’m not sure what it is. I pasted the public key into (Apple) Notes on my iPhone, then on my MacNook copied and pasted it into the terminal after opening a login session as the raspberrypi user (sudo -i -u raspberrypi) on the VPS:

sudo -i -u raspberrypi
vim .ssh/authorized_keys
chmod 600 .ssh/authorized_keys # sshd complains if this is world readable

Step 3: Configure sshd

Edit /etc/ssh/sshd_config to force logins to our new user on the VPS to run a command, in this case sshing to the Raspberry Pi:

Match User raspberrypi
       ForceCommand ssh -t [email protected]$(cat piIP )


And don’t forget to reload once you’re done:

sudo systemctl reload sshd.service

All Done

And voilĂ ! Now you can log ssh into you IPv6 connected Raspberry Pi from your IPv4-connected phone. It’s been years coming, but hopefully it won’t much longer until all devices are fully IPv6

  1. While UPnP offers a partial solution, in practice it remains unreliable. By contrast, IPv6-capable networks generally offer full connectivity on all ports to all connected devices. [return]
  2. It’s an interesting thought exercise to think of exceptions. Spotify in its original implementation comes to mind, but it seems they phased out their peer-to-peer network in 2014. [return]
  3. I’m using Sakura Internet, a local hosting company in Japan, but the same is true for DigitalOcean, Linode, and AWS. [return]
  4. As of December 2016 Ed25519 keys are being recommended by some. Depending on when you’re reading this a different key type or number of rounds may be preferred. [return]