Cloudflare Access Gateway configuration

Why would you use a Cloudflare "Access" gateway?

When you have a NAS running at home, it would of course be very nice if you could access the files and pictures on the NAS from anywhere in the world. Since Google Drive or iCloud allows you access from anywhere, it shouldn't be too difficult, right? There's only one problem: security. If your router and internet service provider allow it, it is very easy to open up your home network to the outside world. However, this is not a good idea unless you are a networking export, and you know what you are doing. Immich clearly recommends against exposing the program directly to the open internet. 

In the Immich docs, the different options for reaching a NAS in a closed local network are explained very nicely. The safest option is a direct VPN or tunnel connection between your device (the client) and your server. This is possible using openVPN, Wireguard, Tailscale, or Netbird. The issue with these services is that they require an app or a program to run on the client device. This program needs to be running whenever you want to connect to your NAS, and it can drain your phone battery. I personally really like Netbird, so click here for a tutorial on how to set that up as a backup in case your Cloudflare Gateway stops working.

The third option listed in the Immich docs is setting up a reverse proxy. Cloudflare “Access” is a kind of reverse proxy with powerful security options built-in. You can control who can reach the server behind the reverse proxy, and how these users can join the server. If you don't set any restrictions, a reverse proxy allows all traffic to reach the application, since Immich is listening to all traffic on a certain IP address and port. This would be the same as if you open up this port on the router from your internet service provider. In this situation, the safety of your server and home network depends solely on the security of the application. The immich developers indicate that this is a bad idea.

If you configure the access restrictions properly, you get the best of both worlds: you can reach your server from anywhere on the internet, and no-one else can intrude in your server or home network. The diagram below shows how the Cloudflare Gateway allows traffic to reach the server, even though the server itself is not publicly accessible. This arrangement is an example of a reverse proxy.

What you need to get started

In this tutorial, I will explain a safer alternative to port forwarding. I will guide you through the steps of exposing your server to the open internet, while ensuring that only authorized users can access the server. To achieve this, I use Cloudflare Access as a reverse proxy. This can be useful for all kinds of self-hosted servers, such as a Minecraft server, Immich server, or NAS.

Before you can get started, you will need the following:

The first two items are explained in a previous page of this project.  You can use an SSH connection on the local network, or if you have set up Netbird, you can even SSH to your server from anywhere and configure the Gateway while you're away from home.

The last item will cost you around $10 per year, but since I am already hosting this website (www.qluyten.com), I am already paying for a domain name. There are many ways to purchase a domain name, but for this tutorial you will need a domain name which is managed by Cloudflare. I also recommend purchasing .com domain names from Cloudflare, since they don't offer deceiving first-year discounts, where the first year costs you $2 and the next year you are charged $35. Also, Cloudflare charges only a little more than the fixed yearly fee that every .com domain needs to pay to Verisign. Verisign is the .com registrar company managing the top-level-domain root server. Of course, you can also buy your domain elsewhere, and transfer it to Cloudflare.

Once you have access to your Cloudflare dashboard and your server, we can start setting up the reverse proxy.

The process consists of the following steps:

If you have bought a domain name and transferred it to Cloudflare, you should have this domain listed when you click on the Cloudflare logo in the top left. This is the homepage of the Cloudflared dashboard. Now you are ready to set up Cloudflare Access

2. Establish a Cloudflared tunnel

The tunnel will be installed as a systemctl service. This means that the Debian OS of the Raspberry Pi can start the tunnel when the Pi boots up. To manually start the service, use the command: sudo systemctl start cloudflared. You should only need one tunnel, even if you want to proxy multiple services from your home network. If the cloudflared tunnel is running correctly, you will see a Healthy status in the Zero trust dashboard:

3. Configure an application with Cloudflare Access

This step consists of two parts: First, we should tell Cloudflare that you want to have access restrictions on an application. Then, you need to ensure the application is reachable through the tunnel while being protected by these access restrictions. To configure the access restrictions on an application:

You will be forwarded to the Policy page. Here you can configure who can access your server, and how. Unless you are a professional user, there will only be one method your clients can use for authentication: Users can enter their email address, and if your policies allow them access, they will receive a one-time-pin which can be used to access the server behind the Cloudflare Access Gateway. By default, all traffic is blocked unless a policy explicitly allows a client to reach the server.

If you configured the Access correctly, you should see the Application name in the Cloudflare Zero Trust dashboard under Access → Applications. If you edit the application, you can see the access policies you have set up. If you want to host multiple services on your server, you will have to set up an application for each service you want to host.

4. Configure the Access Gateway to allow your traffic to reach the application 

There is one last step we need to do to make the server safely accessible. We need to tell the Cloudflare Gateway that the server should be reachable at the URL we configured in the previous step. We will configure the cloudflared tunnel to route traffic from this URL through the Access authentication page to your server:

If everything is configured correctly, you should now be able to navigate to the publicly accessible URL. You will be prompted to enter an email address and a pin. If your login is successful, you will be redirected to the Immich login page. Below, you can see an example of what the Cloudflare Access authentication page looks like. If you want to host multiple services on your server, you will have to set up a public hostname for each service you want to host.

5. Configure service tokens to allow the Immich app to reach your server

If you want the Immich mobile app to reach your Immich server, even when you are not home, you will have to take an extra step. Since the mobile app can't authenticate itself on the Cloudflare Access authentication page, you need to allow the app to bypass this authentication. You can use service tokens to achieve this:

Watch out! You only get to see the secret once. If you don't safely write it down somewhere, delete the service token and start again.