Friday, March 27th 2015 2 years ago

How to connect your Raspberry PI to the Internet in 3 easy steps

The Raspberry PI is a credit-card sized device. It runs on ARM and it can run Linux. This guide explains to you step-by-step how to reach your Raspberry PI through the internet.

  • I have a VPS running in the cloud. Which runs a NginX[^NGINX] instance which is the front-end proxy to my home server.
  • I have the Raspberry PI 2, but this will work as well on the 1st generation.
  • I'm running Debian on my VPS[^VPS], and Arch[^ARCH] on the PI.

What is my IP?

The Raspberry PI has to do some reflection to determine the WAN IP address of the router. The easiest way I've found is to do a request to a website, like this ip echo service that makes this very easy.

You can also get just the IP as a text, do this with your HTTP library or with curl.

curl http://ipecho.net/plain

Connecting with your server

The next step, is to grab that IP address and send it off to your server. I'm already running some node web applications so I'll write the examples in this language for now.

Here's a very simple, unsecure client example in node.

// client.js
var http = require("http");

var ipecho = {
  host: 'ipecho.net',
  port: 80,
  path: '/plain'
};

var vps = {
  host: 'example.com',  // Your server host
  port: 1234            // The port of the server script
};

// Grab the IP address.
http.get(ipecho, function(res) {
  res.on("data", function(chunk) {

    // Stick the IP address in a HTTP header.
    vps.headers = {
      'client': chunk,
    };

    // Send it.
    var req = http.request(vps);
    req.end();

  });
})

On the server, you grab the client header and log it out for now to see if everything works as it should.

// server.js
var http = require('http');

http.createServer(function (req, res) {
  console.log(req.headers.client);
  res.end();
}).listen(1234);

console.log('Server running at http://127.0.0.1:1234/');

On your server, run node server.js and on the client node client.js. You should see the output on the terminal where you started server.js.

The Proxy

In NginX on your server, set up a site in /etc/nginx/sites-enabled with the following configuration.

This sends every request to server_name to the pi host, the upstream is the important part. This could also be an IP. But a hostname would be more dynamic.

# /etc/nginx/sites-enabled/home

upstream raspberry_pi {
  server pi:8080;
}

server {
  listen 80;
  server_name home.example.com;
    location / {
      access_log off;
      proxy_pass http://raspberry_pi;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header Host $host;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

Afterwards, edit your /etc/hosts file and add the following lines. With your IP substituted.

# /etc/hosts/

# Raspberry PI
123.123.123.123 pi

Then reload your configuration with nginx -s reload and go to home.example.com.

You may need to set up your raspberry pi to listen on port 8080 and port forward it to your router. But this is the basic setup of how to do it.

You can now extend server.js to automatically change your hosts file and set up a cron job to run client.js ever so often.


[^NGINX]: Setting up nginx is out of scope. Here is the documentation. [^ARCH]: Setup guide for Raspberry PI and for Raspberry PI 2. Configuration is found on the Arch wiki. [^VPS]: I'm using ChicagoVPS which are very reliable with awesome pricing. The cheapest option will do for this guide.