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
- Your services, typically one or more HTTP servers, run on localhost.
- You run pagekite as a back-end connector, on the same machine.
- Another instance of pagekite runs as a front-end relay on a machine with a public IP address, in “the cloud”.
- The back-end pagekite connects to the front-end, and creates a tunnel for the configured services.
- 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.
Then PageKit will prompt you to sign up for a PageKite.net account using your email address.
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.
Now PageKite will connect to the front end.
And you should be able to access your local web server using a domain name.
name.pagekite.me
or
https://name.pagekite.me
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.
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.
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.
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
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.
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
If I visit http://site2.csmage.com
, I get
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.
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 🙂
Following this is great except when doing the cerbot install.
Home server i need to access is using linux mint
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:
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.
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
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,
Hello Alouis,
You can subscribe to this blog here: https://newsletter.linuxbabe.com/subscription/wkeY5d6pg
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 ..