How to implement NAT traversal using STUN/ICE on my Raspberry Pi
Asked Answered
T

1

7

I am trying to setup an implementation on my raspberry pi that is able to break through behind NAT routers so that I can connect to it remotely regardless of which network it is residing behind.

I've tried out pagekite.me which is great as a relay/reverse tunnel solution but I feel it is still a little bit clunky (with latency issues as there's an additional server which needs to be connected in between).

I've read up about STUN and ICE but I do not know of any solutions that I can implement on my raspberry pi.

The goal is that I can SSH into my PI regardless of its network configuration (router/network) and network firewall.

Can someone point me in the right direction as to where or what I should be looking for?

Tempestuous answered 11/8, 2014 at 12:17 Comment(1)
I would also like to use STUN/TURN/ICE for SSH.... any progress on this?Cycloparaffin
D
2

I'm not answering your STUN/ICE question directly, but am answering your goal, which is how to break through NAT and ssh to your pi remotely.

The easiest way to solve this problem is to use a reverse ssh tunnel, especially one using autossh and key based authentication.

This requires you to have your own server with an ssh port somewhere for the pi to call in to (I use one just sitting on my home network, find out your public IP address, and register a free ddns account if you want to use a memorable URL).

Prepare your raspberry pi, ideally when on your own home network with the server you'll keep on and use (just connect an old desktop running linux or another pi to your router and leave it on. I'm going to assume you have forwarded external port 30022 to port 22 on your server, from your home router for this example). You're going to use key based authentication too.

On your pi:

sudo apt-get install autossh
# Generate key
sudo -u pi ssh-keygen
# Copy key to your server (while you're on your home network with the server is easiest, but not necessary)
sudo -u pi ssh-copy-id -i /home/pi/.ssh/id_rsa.pub [serverUser]@[serverIP]

You then want another 'configuration file', on your pi in the home directory if you like. Call it myConf.sh if you like

#!/bin/bash
rSSHPort=31001 # you'll use a different port for each pi you connect to your server.  Make sure all these ports are forwarded on your home router to the server (port forward the range e.g. 31000-31100 would let you do 100 pi's)
# Phone Home
USER=pi # or whatever your pi user is named
KEY=/home/pi/.ssh/id_rsa
HOST=myServer.ddns.net # or whatever your server URL or public IP address is 
REMOTE_USER=serverUser # or the user you want your pi to connect to the server as
REMOTE_PORT=30022 # or whatever port you have forwarded to your server for ssh (don't use 22 as its even more of a security vulnerability). 

You then have one final script that's going to implement the actual ssh call back to your server. Call it connectServer.sh if you like, and put it in /home/pi/

#!/bin/bash
# Reverse Tunnel SSH in to server
# -f detach script from terminal
# -N no commands can be executed on server side
# -R reverse tunnel
# -p using server ssh port
# -i path to key file
# Source the Config File
source '/home/pi/myConf.sh'

connect()
{
        # TODO need to check that autoSSH isn't already in process list
        autoSSHProc=$( ps ax | grep autossh | wc -l )
        if [ "$autoSSHProc" -le "1" ]
        then
                log
                su -c "autossh -f -N -q -i ${KEY} -p ${REMOTE_PORT} -R ${rSSHPort}:localhost:22 ${REMOTE_USER}@${HOST} -oControlMaster=no -oUserKnownHostsFile=/dev/null -oStrictHostKeyChecking=no" $USER
        fi
}

# Log connection details
log()
{
        datStr=$(date)
        echo "Connected system using autossh at " "$datStr" >> connection.log
}

connect

now run that on your pi

sudo ./connectServer

Now you want to ssh in to your server from your laptop or whatever device you connect in from.

ssh [serverUser]@[serverIP] -p 30022

Once in to your server, you can link up with the reverse tunnel

ssh pi@localhost -p 31001

Voila!

Here's the references I used to get this far:

Reverse ssh forwarding: https://www.howtoforge.com/reverse-ssh-tunneling

Set up Server with ssh key, pass to pi units: http://www.thegeekstuff.com/2008/11/3-steps-to-perform-ssh-login-without-password-using-ssh-keygen-ssh-copy-id/ and http://jmatthews.us/blog/2013/02/18/rpi-dorm/

Set up autodial home: https://www.raspberrypi.org/forums/viewtopic.php?f=36&t=32077

Drink answered 2/5, 2015 at 21:15 Comment(3)
The OP has already mentioned using reverse tunnelling, but doesn't want to have the extra route there because of latency. Perhaps this question on SU helps: superuser.com/questions/827623/…Tatouay
Sure, but pagekite itself apparently was part of the latency problem. I'm still using a variant of the above solution now 5 years later, on 100+ devices. Your linked answers may be helpful, but there wasn't a clear working example provided. Perhaps you could write one up @Tatouay sharing the benefits?Drink
Actually I'm looking for a solution too. My search so far tells me to try UDP tunnelling or something similar, potentially IETF ICE (as a standard). However, I didn't find any application to try out directly. The other question I mentioned above seems to be a dedicated solution for ssh only (I didn't try it out yet), but I'm thinking of something more general (otherwise I'll fallback to my current reverse tunnelling, actually the same way as yours).Tatouay

© 2022 - 2024 — McMap. All rights reserved.