When hosting a website in a private network (e.g., a home network), to make it publicly accessible, a common method is to expose the port 80 or 443 of the router. This will make the private network vulnerable. A more secure approach is to utilize the Cloudflare tunnel.
Suppose the hostname of the website to be hosted is www.smartopia.ai
. The first thing is to add the domain smartopia.ai
to Cloudflare by following the instructions here. This also requires you to choose a plan for the added domain. For personal or hobby projects, the free plan offered by Cloudflare is sufficient.
Next, we install cloudflared
to a server located in the same private network of the web server (.e.g, the web server itself), by following the instructions here. Then we authenticate cloudflared by runing the following command, and also follow the instructions here to complete the authentication.
cloudflared tunnel login
Now we can create a tunnel by running the following command:
cloudflared tunnel create smartopia
In the above, smartopia
is the name of the tunnel, and can be replaced with a name of your choice. According to the Cloudflare docs, this command does the following things.
- It creates a tunnel by establishing a persistent relationship between the name
smartopia
(or the name you provide) and a UUID for the tunnel. - It also generates tunnel credientials file (a
json
file and apem
file) in the default cloudflared directory (e.g.,~/.cloudflared
).
Next, we create a configuration file config.yml
for the tunnel. Below is an example.
tunnel: <UUID>
credentials-file: <PATH>
ingress:
- hostname: www.smartopia.ai
service: https://localhost
originRequest:
noTLSVerify: true
- service: http_status:404
In the above example, <UUID> is replaced with the UUID of your tunnel, and <PATH> is replaced with the actual path to the json
file from the previous step. The service https://localhost
is replaced with the local address of your web site, e.g., https://10.0.0.1
. The setting noTLSVerify: true
is a workaround for an error “Unable to reach the origin service … because it doesn’t contain any IP SANs” of using https
without setting up the right certificate (in either the Cloudfalre side or the apache server side).
Next, we start to route traffic by assigning a CNAME record that points traffic to the tunnel.
cloudflared tunnel route dns smartopia www.smartopia.ai
In the above, smartopia
is the tunnel name (replaced with your tunnel name), and www.smartopia.ai
is the hostname (replaced with your hostname), so that people will access your website via https://www.smartopia.ai
.
Finally, we can run the tunnel by
cloudflared tunnel run smartopia
To run the tunnel as a service, so that it also automatically starts when the system reboots, we can first install the service and then start it:
cloudflared service install
systemctl start cloudflared
If some error accurs, then we might check the file /etc/systemd/system/cloudflared.service
to see whether it has the correct the path the config.yml
file we created in the previous steps.
Now, you should be able to access your website (e.g., https://10.0.0.1
, which is assumed to be accessible already in the private network) from the public network via the hostname linked to the tunnel (e.g., https://www.smartopia.ai
).
If we want to redirect the http
traffic to https
, then we can go to the dashboard of Cloudflare, and turn on the options “Always Use HTTPS
” and “Automatic HTTPS Rewrites
” under the section Edge Certificates
of SSL/TLS
. Then, we can also access the website via http://www.smartopia.ai
.