Making a local server public with pagekite.py

From XPUB & Lens-Based wiki

So you want to make your Raspberry Pi web server accessible publically? You can use pagekite.py to create a tunnel. The way it works is that you actually run pagekite in two places: (1) on the pi (known as the "backend") and (2) on a public server (such as pzwart1 -- this is then known as the "frontend"). Web traffic is configured to point to the public part of the tunnel (pzwart1), when the pi is running, the backend connects to the frontend and web requests to the frontend will be served via the tunnel.

What you need:

  • A public server where you can run pagekite
  • Access to the webserver (Apache/nginx) on the server to create a Proxy -- this isn't strictly necessary, but it hides the fact that the proxy is running on a "high" port.

. Here are my notes for it's setup.

DIRECT DOWNLOAD LINK TO SCRIPT: https://pagekite.net/pk/pagekite.py

pagekite.py on the Server (front-end)

Run pagekite (in my case using screen)...

./pagekite.py --clean --isfrontend --ports=9999 --protos=http,https --domain=http,https:foo.activearchives.org:SECRET

BONUS: configure apache to reverse proxy on a CNAME (to have available as http://foo.activearchives.org instead of http://activearchives.org:9999).

/etc/apache/sites-available/foo.activearchives.org

<VirtualHost *:80>
	ServerName   foo.activearchives.org:80
	UseCanonicalName Off

	ProxyVia On
	ProxyRequests Off
	ProxyPreserveHost on
	<Location />
        ProxyPass http://localhost:9999/ retry=0 timeout=30
        ProxyPassReverse http://localhost:9999/
	</Location>
</VirtualHost>

pagekite.py on the Pi

./pagekite.py --clean --frontend=foo.activearchives.org:9999 --service_on=http://foo.activearchives.org:localhost:80:SECRET

/etc/systemd/system/pagekite.service

[Unit]
Description=pagekite
After=syslog.target network.target

[Service]
Type=simple
User=pi
Group=pi
ExecStart=/home/pi/pk/pagekite.py --clean --frontend=foo.activearchives.org:9999 --service_on=http://foo.activearchives.org:loc
alhost:80:SECRET

[Install]
WantedBy=multi-user.target

Test with:

 sudo service etherpad start
 sudo service etherpad status

and add to startup automatically with:

 sudo systemctl enable pagekite

Configuring ssh

So I wanted to have a Raspberry Pi's webserver public, and also be able to ssh to the machine. This via a public virtual server which has it's own SSH service (running on the standard port 22). In the end I used Apache reverseproxy to make the web available without the visibility of the high port (10107 in this example). NB however the reverseproxy is *not* necessary for the ssh access to work as this is handled by client configuration (to use an http proxy directly on 10107).

NB: "SECRETFOO" is my "secret" (since changed in private ;) ... and "foo.activearchives.org" is the public CNAME registered domain. NB: My apache reverse proxy is only setup for port 80 (doesn't do SSL). SSH still seems to work via 10107.

front end (public server)

./pagekite.py --clean \
    --isfrontend \
    --rawports=virtual \
     --ports=10107 \
     --protos=http,https,raw \
     --domain=http,https,raw:foo.activearchives.org:SECRETFOO

back end / PI

./pagekite.py --clean \
    --frontend=foo.activearchives.org:10107 \
    --service_on=http:foo.activearchives.org:localhost:80:SECRETFOO \
    --service_on=raw-22:foo.activearchives.org:localhost:22:SECRETFOO

On my laptop (where I will try to ssh via the frontend to the PI, the key was that the proxy port is 10107. I needed to install corkscrew (via apt) to make this work on Debian (the netcat examples elsewhere work on Mac OSX / FreeBSD).

~/.ssh/config

Host foo.activearchives.org
     CheckHostIP no
     ProxyCommand /usr/bin/corkscrew %h 10107 %h %p

So in the end you can visit http://foo.activearchives.org/ and also:

   ssh pi@foo.activearchives.org


some links used in getting here:

extended notes

Initially I was using "port 2222" but it seems completely unnecessary. the "service_on=raw-2222" and I configured my laptop's ssh to use the non-standard 2222. So apparently whatever PORT ssh tries to use translates into a request on the backend for raw-PORT. In the case of 2222 the backend still ended up connecting it to the Pi's sshd on port 22. In any case, none of this had any effect on the front end which (happily) remains quite simple to configure, basically I just needed to add "raw" to the protocols and the "rawports=virtual" option.

Host foo.activearchives.org
     CheckHostIP no
     ProxyCommand /usr/bin/corkscrew %h 10107 %h %p
     Port 2222

(old -- still based on service_on=raw-2222) When this starts it says:

>>> Hello! This is pagekite.py v0.5.9.0.                        [CTRL+C = Stop]
    Connecting to front-end relay 91.250.115.23:10107 ...                      
     - Protocols: http https raw                                               
     - Ports: 10107                                                            
     - Raw ports: virtual                                                      
~<> Flying localhost:22 as raw://foo.activearchives.org:2222/ (HTTP proxied)   
~<> Flying localhost:80 as http://foo.activearchives.org/                      
    ::1 < http://foo.activearchives.org:10107 (localhost:80)                   
    212.71.13.114 < raw://foo.activearchives.org:2222 (localhost:22)           
 << pagekite.py [connect]  Front-end connect: 91.250.115.23:10107