How to Run a Pagekite Server to Expose Your Raspberry Pi

Last time I showed you how to expose a web service on a Raspberry Pi (or, actually, any kind of device) by using a reverse proxy from Pagekite. On your Pi, you just need a simple Python script. However, it also depends on the Pagekite server, which isn’t always convenient. There are limits to the free service, and you don’t control the entire thing. The good news is twofold: the same Python script you use to set up the client-side can also set up a server. The other good news is the entire thing is open source.

In practical terms, then, if you have a computer that is always on and has an IP address that can be found on the public internet, you can run your own Pagekite server (they call it a front end) and service your own backends.

Initial Setup

As I mentioned, you are going to need a computer visible on the Internet. Well, technically a computer that is visible to all the clients you expect to use including the backend. It needs a few tools on it, including Python, but nothing exotic. You’ll also need control of your DNS–exactly how you do that will depend on how your server is set up. In my case, I have a server sitting in a rack in a data center so I have my own DNS server (named) running on it.

The Pagekite website has installation packages for RPM and deb packages. I suggest you start by installing that on your server, using the method that matches your packaging system. This will put a new directory called /etc/pagekite.d and also installs a startup script (/etc/init.d/pagekite).

However, the default setting is to exit and not start anything up. What’s more is that the example files are set up as though the computer wants to talk to the Pagekite frontend provided (pagekite.me). If you want to run your own, you are going to have to make some changes.

Named Party

If you have a server on the Internet, there is some way to get names (like hackaday.com) into the DNS system to point to a specific IP address. In my case, I own the domain name hotsolder.com so I decided to make dyn.hotsolder.com be my Pagekite front end. I also wanted to be able to create subdomains like 3dprinter.dyn.hotsolder.com.

To do this, I needed a few configuration changes in my DNS:

dyn           IN        A 173.201.49.198 
*.dyn         IN        A 173.201.49.198

Obviously, my IP address is the one shown. All the names are relative to hotsolder.com, so there’s no need to specify that on those two lines. If your hosting company handles your DNS, you’ll have to determine how to make similar changes. Or you can tell them you need two “A” records put in and they ought to know what that means. The upshot is that your host name (dyn.hotsolder.com or anything.dyn.hotsolder.com) goes to your server (the Pagekite server in the diagram below).

Host Setup

The Pagekite package will leave two important files in /etc/pagekite.d: 10_account.rc and 20_frontends.rc. The first file is why the service won’t start. The reality is, for using the script as a frontend, you don’t need this file at all. Just in case, I commented out all the lines, but you could just as well remove it. The line that prevents it from starting is the one that reads:

abort_not_configured

The other lines set up your connection to the pagekite.me servers. We aren’t going to do that, so you can remove those lines or the whole file.

The 20_frontends.rc file is supposed to connect to the remote frontend. In this case, we want to be the front end, so here’s what I put in there:

isfrontend
ports=8080,80,443,2222
rawports=virtual
protos=http,https,raw
domain=http,https,http-8080,raw-2222:*.dyn.hotsolder.com:$$$SECRET$$$
domain=http,https,http-8080,raw-2222:dyn.hotsolder.com:$$$SECRET$$$

You can also set up a certificate file and point to it here, but if you want to do that, you can read the documentation (look for the –tl_default and –tls_endpoint options along with –fe_certname and –ca_certs). In fact, that same documentation is where you can learn about all the options like isfrontend and ports.

Client Setup

By default, the Pagekite script looks in ~/.pagekite.rc for settings. If you plan on using the Pagekite server, you are better off leaving this file alone and creating a new configuration. You can install the same package on the Pi or other client computer — remember, the same script is used on the frontend (the Internet-facing computer) and the backend (the computer running the server).

If you want to run from the command line, consider using:

pagekite --clean --optfile=/home/YOURUSERID/.pagekite.CUSTOM.rc

Obviously, you need to replace YOURUSERID and CUSTOM to suit your purposes. If you are using a package and having Pagekite start automatically, you need to look at /etc/pagekite.d. The 20_frontends.rc is where you can configure each frontend server you want to talk to.

Here’s part of my file:

webpath = dyn.hotsolder.com/8080:/:default:/tmp/httpd
webpath = dyn.hotsolder.com/80:/:default:/home/alw/Photos
frontend=dyn.hotsolder.com:443
service_on=http:dyn.hotsolder.com:localhost:builtin:@kitesecret
service_cfg=dyn.hotsolder.com/80:indexes:True
service_on=raw-2222:dyn.hotsolder.com:localhost:22:@kitesecret

The @kitesecret references a line further up (or in the 10_accounts file):

kitesecret=$$$SECRET$$$

This has to match what is set up on the frontend, of course.

Funny Business

For http requests, everything works like you would expect. The service_on and service_cfg lines set up the built-in Web server (you don’t have to use it) and the documentation says these are subject to change. Otherwise, it is pretty simple to set up things.

The issue arises when you want to do a raw port. In my case, I want to expose the ssh server on port 22 to the outside world. Of course, my public computer already has an ssh server on that port. That’s no problem. Pagekite can convert incoming traffic on port 2222 to port 22 on the backend. Kind of.

The raw ports actually come through on an http port. To make ssh work (for example) you need to proxy from port 443 with netcat. The details are in the documentation, but the short version is you need the following configuration in ~/.ssh/config:

Host dyn.hotsolder.com
   CheckHostIP no
   ProxyCommand /bin/nc -X connect -x %h:443 %h %p

The Internet of Pi

If you control every network you connect to, this probably isn’t that interesting. If you don’t mind setting up VPNs on both sides, you also don’t need this sort of thing. However, if you need to deploy solutions behind firewalls or even on dynamic IP addresses, you might find the reverse proxy approach is just what you need.

There are always other ways to solve the problem, of course. You can use a dynamic IP provider to address dynamic IPs, for example. Tunneling through unknown firewalls is a bit more difficult, though.

9 thoughts on “How to Run a Pagekite Server to Expose Your Raspberry Pi

  1. Thnx for sharing this awesome script! i was just making a tunnel like these for my devices :) now im setting it up, i noticed you have a typo on the 20_frontends.rc file took me like 30 minutes to searching what i was doing wrong

    domain=http,https,http-8080,raw-2222:*.dyn.hotsolder.com;$$$SECRET$$$ the typo its the ; before $$$SECRET$$$ it should be domain=http,https,http-8080,raw-2222:*.dyn.hotsolder.com:$$$SECRET$$$

    Anyway really thnx for these.

  2. ssh tunnels can also be used for this. Many people are aware that you can use the -L switch to make a remote service available on a local port, but you can also use the -R switch to make a local service available at a remote port on a remote VPS or server under your control. No need to have any special software. The sshd config might need a change however to enable the remote forwarding:
    GatewayPorts clientspecified

    The syntax is something like:

    ssh -T -i yourkeyhere -R remoteip:remoteport:localip:localport user@remotehost

    1. GatewayPorts is needed to allow any host connect to the forwarded port, but if you have SSH access to the VPS, you can use it as a proxy while still maintaining end-to-end encryption to your Raspberry Pi. ProxyCommand would then be something like:
      ssh -W localhost:remoteport remotehost

      I’m maintaining my SSH tunnel with sidedoor, a little wrapper package for Debian/Raspbian/Ubuntu, if it’s of any use to you, let me know:
      https://github.com/daradib/sidedoor

  3. Hi there,

    Thanks for your very informative posts.

    I have deployed a web server using NGinx and my Pi 3, hosting a temperature-logging web app on it. Now, I want to make this web app public. I have my own public domain name hosted on a different web server. Will I achieve this using the Pagekite guide you have posted here? I don’t entirely understand the whole thing, but I don’t mind reading up on it. A response pointing me to the right direction would be highly appreciated.

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 )

Google+ photo

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

Connecting to %s