Expose Localhost to Internet with PageKite on Ubuntu

This tutorial will be showing you how to expose localhost to Internet with PageKit on Ubuntu.

Normally if you want to visit your home web server from outside, you need to set up dynamic DNS because your ISP doesn’t give you a static public IP address. But some ISPs in the world don’t even assign a dynamic public IP address to each subscriber. Many subscribers share a single public IP address. In this scenario, dynamic DNS won’t work and that’s where PageKite comes in.

PageKite is an open-source tunneled reverse proxy that is capable of bypassing NATs (network address translation), firewalls and making local web servers and SSH servers visible to the public Internet. If you are a web developer or have some self-hosted services like NextCloud on your home network, then PageKite can help you access them remotely over the Internet. PageKite is written in Python, so it can run on many kind of devices.

Note: Making your web server/SSH server visible to the Internet also expose them to hackers.

How Pagekite works

  1. Your services, typically one or more HTTP servers, run on localhost.
  2. You run pagekite as a back-end connector, on the same machine.
  3. Another instance of pagekite runs as a front-end relay on a machine with a public IP address, in “the cloud”.
  4. The back-end pagekite connects to the front-end, and creates a tunnel for the configured services.
  5. Clients, typically web browsers, connect to the front-end and request service. The front-end relays the request over the appropriate tunnel, where the back-end forwards it to the actual server. Responses travel back the same way.

Running your own front-end relay costs a little money, but PageKite developers offer a 31 days free account for you to try it out. Let’s see how to use PageKite with a free account. This tutorial will only show how to expose local web server. Exposing local SSH server will be discussed in another tutorial.

Expose Localhost to Internet with PageKite on Ubuntu

First, install a web server, such as Apache, on your local Linux computer. On Debian/Ubuntu based Linux distro, run the following command to install Apache web server.

sudo apt install apache2

Start the web server

sudo systemctl start apache2

Now Apache is listening on port 80. We use PageKite to make it visible to the Internet. Install PageKit on your Linux computer using the following command.

Debian 8/9, Ubuntu 16.04/18.04,  Raspbian and derivatives

sudo apt install pagekite

Next, run the following command. Replace name with your desired subdomain.

pagekite name.pagekite.me

It will first ask you if you want to use the free PageKite.net service. Since you don’t have your own PageKite server yet, choose Y.
pagekite tutorial

Then PageKit will prompt you to sign up for a PageKite.net account using your email address.

pagekite ubuntu

You account details including password will be sent to your email address. Open the email and click the link in it to activate your account. Then enter Y to continue and save your settings.

Expose Localhost to Internet

Now PageKite will connect to the front end.

pagekite localhost

And you should be able to access your local web server using a domain name.

name.pagekite.me

or

https://name.pagekite.me

pagekite tutorial tunneled reverse proxy

To stop PageKite, press Ctrl+C in the terminal window. If you want to run PageKite in the background, use --daemonize option.

pagekite --daemonize name.pagekite.me

To stop daemonized PageKite, run

pkill pagekite

You can password protect your web page with HTTP basic authentication like below.

pagekite name.pagekite.me +password/username=pass

Pagekite.net allows paid members to use their own domain names by setting up CNAME record. Instructions can be found on its website.

How to Run Your Own PageKite Server

The free trial of pagekite.net is very limited. However, we can run our own PageKite server (aka the front end) on a public-facing Linux VPS (Virtual Private Server). Although this costs money, but running your own PageKite server is well worth it. If you choose to pay PageKite.net service, then for 5 USD a month, you get only 4GB of transfer quota.

pagekite pricing

If you buy a Linux VPS from TurnkeyInternet and run your own PageKite server on it, then for 4.99 USD per month, you get a Gigabit network port and unmetered bandwidth. Besides, you can do other interesting projects on your VPS like setting up your own VPN.

turnkeyinternet vps

You will also need a domain name. You may have heard of GoDaddy, but you want to buy domain names from Namecheap because their price is lower than GoDaddy and they give you whois privacy protection free of charge.

Now, suppose you have bought a VPS and a domain name, here’s how to run the front end pagekite server. Install Ubuntu 18.04 OS on your VPS in Linode control panel. Then SSH into your VPS and install Pagekite with the commands below.

sudo apt update

sudo apt install pagekite

The pagekite.net website also has instructions on installing RPM packages on CentOS. Once pagekite is installed, the configuration directory is located at /etc/pagekite.d/ . We need to edit 20_frontends.rc file.

sudo nano /etc/pagekite.d/20_frontends.rc

Comment out the line that reads defaults because we don’t want to use the pagekite.net service. Next, add the following lines at the end of the file. Replace kite.your-domain.com with your own domain name and your-secret-key with your preferred secret key. I use my domain name kite.csmage.com as an example.

isfrontend
runas=nobody:nogroup
ports=80,443
protos=http,https
domain=http,https:kite.your-domain.com:your-secret-key

Save and close the file. Then start Pagekite server with the command below, specifying the option file. Because PageKite server needs TCP port 80 and 443 to work, so we need to prefix the command with sudo.  Also make sure no other process on your VPS are using these two ports.

sudo pagekite --optfile=/etc/pagekite.d/20_frontends.rc

To run Pagekite server in the background, use --daemonize option.

sudo pagekite --optfile=/etc/pagekite.d/20_frontends.rc --daemonize

In your DNS manager, create a sub-domain for pagekite with A record pointing to the IP address of your VPS like below.

A     kite.your-domain.com    12.34.56.78

Create a Systemd Service Unit for PageKite Server

The default systemd service file /lib/systemd/system/pagekite.service is intended for use as a client. We can create a separate systemd service file for PageKite server.

sudo nano /etc/systemd/system/pagekite.service

Copy and paste the following lines into the file.

[Unit]
Description=PageKite
After=network.target

[Service]
Type=simple
ExecStart=/usr/bin/pagekite --clean --optdir=/etc/pagekite.d/
TimeoutStopSec=5
KillMode=mixed

PermissionsStartOnly=true
Restart=on-abnormal
RestartSec=2s
LimitNOFILE=65536
WorkingDirectory=/tmp

# Hardening
SystemCallFilter=~@clock @debug @cpu-emulation @debug @keyring @module @mount @obsolete @raw-io @reboot @swap
NoNewPrivileges=yes
PrivateDevices=yes
PrivateTmp=yes
ProtectHome=yes
ProtectSystem=strict
ProtectKernelModules=yes
ProtectKernelTunables=yes

[Install]
WantedBy=multi-user.target

Save and close the file. Then reload systemd for the change to take effect.

sudo systemctl daemon-reload

Next, open 10_account.rc file

sudo nano /etc/pagekite.d/10_account.rc

This is a configuration file used by PageKite client. The PageKite systemd service will read every .rc file in /etc/pagekite.d/ directory in lexicographical order, so we need to comment out everything in this file. After that, you can kill the daemonized pagekite server process.

sudo pkill pagekite

Restart it with systemctl.

sudo systemctl start pagekite

To enable auto start at system boot time, run

sudo systemctl enable pagekite

To disable auto start, run

sudo systemctl disable pagekite

Check its status.

systemctl status pagekite

Configure Pagekite Client to Use Your Own Server

On your local computer where the Pagekite client is installed, edit the 10_account.rc file.

sudo nano /etc/pagekite.d/10_account.rc

Replace the value of kitename and kitesecret with the domain name and secret key you specified on your Pagekite server, respectively. And comment out the last line.

run pagekite server

Save and close the file. Then edit 20_frontends.rc file.

sudo nano /etc/pagekite.d/20_frontends.rc

Comment out the line that reads defaults. Then add the following line.

frontend = your-pagekite-server-IP:80

run pagekite front end

Save and close the file. Next, rename 80_httpd.rc.sample to 80_httpd.rc

sudo mv /etc/pagekite.d/80_httpd.rc.sample /etc/pagekite.d/80_httpd.rc

Restart Pagekite service on the local computer.

sudo systemctl restart pagekite

Your local Pagekite client should now be connected to your own Pagekite server. You can check the connection details by running:

sudo systemctl status pagekite

And your local web server is now exposed to the Internet. If the connection to the Pagekite server is lost, the Pagekite service will attempt to re-establish a connection.

how to use pagekite

Note: If you run command pagekite name.pagekite.me on your local computer, it will use the ~/.pagekite.rc user configuration file, which defaults to using pagekite.net service.

Multiple Virtual Hosts

This section explains how to make multiple Apache virtual hosts on your home network visible to the Internet. First, let me create two example Apache virtual hosts.

First virtual host

sudo nano /etc/apache2/sites-available/site1.csmage.com.conf

Content in this file:

<VirtualHost *:80>
       ServerName site1.csmage.com
       DocumentRoot /var/www/site1.csmage.com/
</VirtualHost>

Create the document root directory.

sudo mkdir /var/www/site1.csmage.com/

Then create an index.html file.

echo "This is site #1." | sudo tee /var/www/site1.csmage.com/index.html

Second virtual host

sudo nano /etc/apache2/sites-available/site2.csmage.com.conf

Content in this file:

<VirtualHost *:80>
       ServerName site2.csmage.com
       DocumentRoot /var/www/site2.csmage.com/
</VirtualHost>

Create the document root directory.

sudo mkdir /var/www/site2.csmage.com/

Then create an index.html file.

echo "This is site #2." | sudo tee /var/www/site2.csmage.com/index.html

Enable these two virtual hosts.

sudo a2ensite site1.csmage.com

sudo a2ensite site2.csmage.com

Reload Apache web server for the changes to take effect.

sudo systemctl reload apache2

PageKite Server Configuration

Edit the 20_frontends.rc file on the PageKite server.

sudo nano /etc/pagekite.d/20_frontends.rc

Add two domain definitions like below.

domain=http,https:site1.csmage.com:secret-key
domain=http,https:site2.csmage.com:secret-key

Save and close the file. Then restart PageKite.

sudo systemctl restart pagekite

PageKite Client Configuration

Edit the 80_httpd.rc file on local computer.

sudo nano /etc/pagekite.d/80_httpd.rc

Add two back-end defintions like below.

service_on = http:site1.csmage.com : localhost:80 : secret-key
service_on = http:site2.csmage.com : localhost:80 : secret-key

Save and close the file. Then restart PageKite.

sudo systemctl restart pagekite

Finally, add DNS A record for each subdomain. Now if I visit http://site1.csmage.com, I get

install pagekite ubuntu

If I visit http://site2.csmage.com, I get

pagekite debian

As you can see, Pagekite correctly responded to each HTTP request. If it’s not working for you, check if your secret keys match or if there’s typo in your configuration file.

How to Enable HTTPS

We can terminate TLS either at the back-end or at the front-end. The former is easier and more convenient. So I will show you how to install TLS certificate on the local computer. We can obtain free Let’s Encrypt TLS certificate for each subdomain. First, install Let’s Encrypt client (certbot) and the Apache plugin on the local computer.

sudo apt install certbot python3-certbot-apache

Then obtain and install TLS certificate for each subdomain with the commands below.

sudo certbot --apache --agree-tos --redirect --hsts --staple-ocsp --must-staple --email your-email-address -d site1.your-domain.com

sudo certbot --apache --agree-tos --redirect --hsts --staple-ocsp --must-staple --email your-email-address -d site2.your-domain.com

Explanation:

  • --agree-tos: Agree to terms of service.
  • --redirect: Redirect HTTP to HTTPS
  • --hsts: Enable strict transport security header.
  • --staple-ocsp: Enable OCSP stapling
  • --must-staple: Adds the OCSP Must Staple extension to the certificate.

After certificates are successfully obtained and installed, edit the 80_httpd.rc file on the local computer.

sudo nano /etc/pagekite.d/80_httpd.rc

Add two HTTPS back-end definition like below. Notice that HTTPS requests will be sent to port 443 on localhost.

service_on = https://site1.your-domain.com : localhost:443: your-secret-key
service_on = https://site2.your-domain.com : localhost:443: your-secret-key

Save and close the file. Then restart pagekite client.

sudo systemctl restart pagekite

Now my sites are automatically redirected to HTTPS.

how pagekite works

run your own pagekite server

Auto Renew TLS Certificate

The certbot debian package ships with its own cron job (/etc/cron.d/certbot) and a systemd timer (/lib/systemd/system/certbot.timer) to automatically renew TLS certificate. So you don’t need to manually add cron job or systemd timer. The timer runs certbot.service twice a day. You can check its status with:

systemctl status certbot.timer

If the certbot cron job detects that there’s also a systemd timer, then it won’t run the renew command.

Wrapping Up

That’s it! I hope this PageKite tutorial helped you expose localhost to Internet with PageKite on Ubuntu. As always, if you found this post useful,  subscribe to our free newsletter to get more tips and tricks 🙂

Rate this tutorial
[Total: 6 Average: 4.5]

13 Responses to “Expose Localhost to Internet with PageKite on Ubuntu

  • Following this is great except when doing the cerbot install.

    Error while running apache2ctl graceful.
    httpd not running, trying to start
    Action 'graceful' failed.
    The Apache error log may have more information.
    
    AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 127.0.1.1. Set the 'ServerName' directive globally to suppress this message
    (98)Address already in use: AH00072: make_sock: could not bind to address [::]:80
    (98)Address already in use: AH00072: make_sock: could not bind to address 0.0.0.0:80
    no listening sockets available, shutting down
    AH00015: Unable to open logs

    Home server i need to access is using linux mint

    • Xiao Guo An (Admin)
      5 years ago

      Another process is using port 80, that’s why Apache can’t bind to port 80. Maybe you are using Nginx web server. You can check if Nginx is running with the following command:

      systemctl status nginx

      You can continue using Nginx, instead of installing Apache.

  • I finally found which was binding to it. Thank you so much. Your site has really helped me and learned alot. I didn’t expect a response so fast either. Sending you btc to buy lunch today. Again thank you for all you do.

    • Xiao Guo An (Admin)
      5 years ago

      Glad to know you fixed the error and thanks for your donation 🙂

  • Hi,

    Can you share us how to exposed local webserver to the internet using Dynamic DNS on Cent OS 7.

  • Hey brother, thanks for all the wonderful tutorials. I have built an email server on my homelab setup following your tutorials. I have a static ip from my isp which is configured on my router and port 80and 443 is forwarded to my mail server for publishing webmail. I would like to run a wordpress website on a separate server, unfortunately unable to publish the webiste since my port 80 and 443 is in use by my mail server. Is it possible to build a new pagekite server behind my firewall with port 80 and 443 redirected to this server and tunnel all my sites (website and webmail) through pagekite?

    Thanks
    Vivek

  • creeksidenine
    4 years ago

    try it, `rein`, it creates a tunnel from a public endpoint to a locally running service.
    https://github.com/firstboot/rein

  • Hi Xiao,

    How to configure the pagekite server to accept subdomain automatically? For example, I configure the server part to domain=http,https:csmage.com:secret-key.

    In the client, I just need to configure
    service_on = https://site1.your-domain.com : localhost:443: your-secret-key
    service_on = https://site2.your-domain.com : localhost:443: your-secret-key

    The server side will automatically load the site1 and site2 accordingly

  • Thanks for all the great sharing. Learn a lot here. Too bad the BF2 Cloud VPS offer has ended

    p/s – Would be great to have a subscription or something to let us know when there is new post or updates on your site

    cheers,

  • Seth Cocking
    3 years ago

    This got me most of the way to a working solution. I had to contact Pagekite for some more details:
    1) Get it working the way you want using command lines
    2 Ask pagekite to print out a working configuration file by adding –settings to the command
    so pagekite –settings yourkite.pagekite.me +password/user=secret
    3) This gives two lines (service_on… and service_cfg….) these lines need to be in /etc/pagekite.d/80_httpd.rc
    4) You can, if you are root, test your settings in /etc/pagekite.d by running pagekite like this on the terminal: pagekite –clean –optdir=/etc/pagekite.d

  • @Xiao

    How can configure Pagkite server with VPN server? I followed your instruction to configure “setting up your own VPN”. But I got an error message that said the port already in use. Please let know how can override the port issue for PagKite and VPN ..

Leave a Comment

  • Comments with links are moderated by admin before published.
  • Your email address will not be published.
  • Use <pre> ... </pre> HTML tag to quote the output from your terminal/console.
  • Please use the community (https://community.linuxbabe.com) for questions unrelated to this article.
  • I don't have time to answer every question. Making a donation would incentivize me to spend more time answering questions.

The maximum upload file size: 2 MB. You can upload: image. Links to YouTube, Facebook, Twitter and other services inserted in the comment text will be automatically embedded. Drop file here