DEV Community

Cover image for Install Cloudflare WARP on any Linux Distro, Thanks to Distrobox!
Archer Allstars
Archer Allstars

Posted on • Edited on

Install Cloudflare WARP on any Linux Distro, Thanks to Distrobox!

Currently, Cloudflare WARP can be installed on Ubuntu, Debian, RHEL, and CentOS. See? Not many Linux distros are supported. Not to mention that the current supported version of RHEL and CentOS has already reached EOL for nearly 2 years now πŸ˜‚

Cloudflare WARP is a very popular free VPN. It's fast since it operates on Cloudflare’s global network through WireGuard connection. There's no limit to bandwidth usage. But it can't spoof your location, and it will not work very well with torrenting, since it doesn't support port-forwarding.

However, we can set up WARP in a container, a Distrobox container to be specific. This method would benefit unsupported system like Arch and openSUSE, for example. Also, immutable OSes like Fedora Silverblue would be able to enjoy WARP connection easily.

Without further ado, let's see how to set this up.

πŸ‘‰οΈ Table of contents:

  1. Install Distrobox
  2. Create a Distrobox Container
  3. Install Cloudflare WARP client in the Container
  4. Running the Client
  5. Register the Client
  6. Turn On Malware Filtering (optional)
  7. Enable the warp+doh Mode
  8. Connect to WARP
  9. Verify the Connection
  10. Automatically Start the Client (warp-svc) on Startup
  11. Creating a Start/Stop Desktop File (create app icons in your app launcher)
  12. Containers Maintenance

1. Install Distrobox

Distrobox is a container manager designed to integrate tightly with the host. Compared to vanilla Docker or Podman, it's a lot easier to use, as most complicated things are set up OOTB. Nevertheless, it still uses Podman or Docker (not recommended) behind the scene.

To install Distrobox on openSUSE Tumbleweed, for example:

sudo zypper install distrobox
Enter fullscreen mode Exit fullscreen mode

On a very old point-release distro, current Ubuntu LTS for example, you might want to install the latest version of Distrobox using Homebrew: brew install distrobox.

On Tumbleweed, this will pull in Docker automatically.

However, I prefer Podman as Docker Desktop is not supported on my system (openSUSE). 😀 But more importantly, Podman runs rootless by default, while Docker doesn't. In fact, Docker has rootless mode. However, it doesn't work as well, see Distrobox issue #223. To lump, if you want to use Distrobox as your apps' compatibility layer, Podman is the way to go. It works great in both rootless and rootful modes.

Therefore, on openSUSE Tumbleweed, for example, I install Podman with sudo zypper install podman, then in ~/.config/distrobox/distrobox.conf, I tell Distrobox to use Podman instead:

container_manager="podman"
Enter fullscreen mode Exit fullscreen mode

If you're on Ubuntu, the only way to get the latest Podman is to build from source. Official Ubuntu support from upstream is not going to happen in the foreseeable future. There's a request for Podman as a Snap package on Snapcraft forum, though. Please consider voting in that thread, so Canonical might release a snapped Podman one day. πŸ’£οΈ


2. Create a Distrobox Container

First, we need to decide which OS image we'll use for this CloudFlare container. See a list of supported containers here. I recommend the latest official Ubuntu image from Docker Hub. So, I create a container with:

distrobox create -i docker.io/library/ubuntu:latest -n cfw-dbx--root -H ~/distrobox/cfw-dbx--root --volume /run/dbus/system_bus_socket:/run/dbus/system_bus_socket --additional-flags "--device=/dev/net/tun --cap-add=NET_ADMIN --cap-add=SYS_ADMIN" -r
Enter fullscreen mode Exit fullscreen mode
  • distrobox create is used to create a Distrobox container. See all options of this command here.
  • -i is used to specify the image we want to use for the container.
  • -n is used to specify the container name. In this case, I use cfw-dbx--root.
  • -H is used to separate the container $HOME from the host (I don't want the container's config files, which could be temporary, to be messed up with my system configs). In this case, I have my host's ~/distrobox/cfw-dbx--root directory to be my container's $HOME. Therefore, all of the container's config files will be in this folder.
  • --volume /run/dbus/system_bus_socket:/run/dbus/system_bus_socket is used to share DBus system daemon with the host. It's usually needed if the app inside the container complained about Failed to connect to the bus: Failed to connect to socket /run/dbus/system_bus_socket: No such file or directory.
  • device=/dev/net/tun, --cap-add=NET_ADMIN, and --cap-add=SYS_ADMIN are basic requirement for every VPN client out there that want to modify your network.
  • And yes, none them works within a rootless container, so we have to tell Distrobox to create a rootful container with -r flag.

After the creation process, enter the container by:

distrobox enter --root cfw-dbx--root
Enter fullscreen mode Exit fullscreen mode

You can simply exit from the container by... running exit command inside the container πŸ˜‚ However, the container will still be running in the background. To stop the container completely, run this command on your host: distrobox stop <container name>.


3. Install Cloudflare WARP client in the Container

You can refer to the official WARP client installation instruction here.

But to complete the instruction without any issue, we need to install these packages first:

sudo apt install curl lsb-release
Enter fullscreen mode Exit fullscreen mode

4. Running the Client

Since we don't use an init container (a container with separated systemd and its user session), we need to enable WARP client manually. Otherwise, we won't be able to use warp-cli to make any connection at all:

sudo warp-svc
Enter fullscreen mode Exit fullscreen mode

Do not close this terminal window. You have to let it run for now.


5. Register the Client

Open a new terminal window, then run:

distrobox enter --root cfw-dbx--root
Enter fullscreen mode Exit fullscreen mode

Or we can simply click on the container's icon, which Distrobox automatically created for us when we created the container:

Containers

Run this command in the container to register the client:

warp-cli registration new
Enter fullscreen mode Exit fullscreen mode

6. Turn On Malware Filtering (optional)

This is completely optional, but it's good to know that WARP uses 1.1.1.1 as its DNS resolver by default. What I always use is 1.1.1.2, which is the same as 1.1.1.1 but with malware filter enabled at DNS level. So, why not? 😎

warp-cli dns families malware
Enter fullscreen mode Exit fullscreen mode

7. Enable the warp+doh Mode

The default value is warp mode. The difference is that warp+doh mode also encrypts your DNS queries. I recommend warp+doh mode over warp+dot mode, as warp+dot mode may be easier to detect or block on restricted networks due to its use of port 853, comparing to warp+doh mode that uses HTTPS on port 443.

warp-cli mode warp+doh
Enter fullscreen mode Exit fullscreen mode

You might wanna ask why don't just use the proxy mode? So, we don't have to add device=/dev/net/tun, --cap-add=NET_ADMIN, and --cap-add=SYS_ADMIN privileges to our container. Well, proxy on Linux always leaks πŸ˜‚ Moreover, if you also use your web browser, etc. in another container or Flatpak, it's not reliable at all. For all major Chromium browsers, you will also need to install a proxy switcher extension to use/enable the proxy connection, of which will make you more fingerprintable, not to mention the unknown security risk from the extension itself.


8. Connect to WARP

warp-cli connect
Enter fullscreen mode Exit fullscreen mode

Now, all your connections are completely secure inside WARP's tunnel!

Check the status of your connection with:

warp-cli status
Enter fullscreen mode Exit fullscreen mode

9. Verify the Connection

You can check your current IP and DNS resolvers that should now change to Cloudflare on dnscheck.tools.


10. Automatically Start the Client (warp-svc) on Startup

It would be very annoying that you have to manually start the client every time in the terminal. So, we will use a systemd service to start the client automatically.

Create a Service File

In the host's terminal:

sudo nano /etc/systemd/system/cfw-dbx-start.service
Enter fullscreen mode Exit fullscreen mode

Inside the file:

[Unit]
Description=Start Cloudflare WARP client
After=network-online.target
Want=network-online.target
RequiresMountsFor=%t/containers

[Service]
Type=exec
ExecStartPre=/bin/podman start cfw-dbx--root
ExecStart=/bin/podman exec cfw-dbx--root bash -c "warp-svc"
RemainAfterExit=yes
Enter fullscreen mode Exit fullscreen mode

Create a Timer File

In the host's terminal:

sudo nano /etc/systemd/system/cfw-dbx-start.timer
Enter fullscreen mode Exit fullscreen mode

Inside the file:

[Unit]
Description=A trigger to start Cloudflare WARP client on startup

[Timer]
OnBootSec=30

[Install]
WantedBy=timers.target
Enter fullscreen mode Exit fullscreen mode

Reload and Enable the Timer

sudo systemctl daemon-reload && sudo systemctl enable cfw-dbx-start.timer
Enter fullscreen mode Exit fullscreen mode

11. Creating a Start/Stop Desktop File (create app icons in your app launcher)

You can use an app like Main Menu to create desktop files easily.

WARP's icon can be grabbed easily on Play Store, for example πŸ˜†

The important part is the launching commands.

Start WARP

distrobox-enter --root cfw-dbx--root -- bash -c 'warp-cli connect'
Enter fullscreen mode Exit fullscreen mode

Stop WARP

distrobox-enter --root cfw-dbx--root -- bash -c 'warp-cli disconnect'
Enter fullscreen mode Exit fullscreen mode

The state of the WARP's connection (connect/disconnect) survives through reboot.


12. Containers Maintenance

To make our setup more robust, it has to be able to upgrade itself daily.

Create a Service File

In your host's terminal:

sudo nano /etc/systemd/system/cfw-dbx-upgrade.service
Enter fullscreen mode Exit fullscreen mode

Inside the file:

[Unit]
Description=Upgrade cfw-dbx--root
After=network-online.target
Want=network-online.target
RequiresMountsFor=%t/containers

[Service]
Type=exec
ExecStartPre=/bin/podman start cfw-dbx--root
ExecStart=/bin/podman exec cfw-dbx--root bash -c "apt update -y && apt full-upgrade -y"
Restart=on-failure
RestartSec=60
RestartCount=5
RemainAfterExit=yes
Enter fullscreen mode Exit fullscreen mode

Create a Timer File

In your host's terminal:

sudo nano /etc/systemd/system/cfw-dbx-upgrade.timer
Enter fullscreen mode Exit fullscreen mode

Inside the file:

[Unit]
Description=Upgrade cfw-dbx--root daily.

[Timer]
OnCalendar=daily
Persistent=true
RandomizeDelaySec=5min

[Install]
WantedBy=timers.target
Enter fullscreen mode Exit fullscreen mode

Reload and Enable the Timer

sudo systemctl daemon-reload && sudo systemctl enable cfw-dbx-upgrade.timer
Enter fullscreen mode Exit fullscreen mode

Alternatives

Why do I recommend you all to set this up instead of all other alternatives out there?

Well, this method use the official Ubuntu image as a base for our container. It also uses the official WARP client from Cloudflare. So, you are not compromising your system security by running random images or scripts.

Therefore, I won't recommend the alternatives.


I hope this helps. If you like this article, please let me know in the comment section below. If you don't, feel free to tell me why. Thanks for reading, bye πŸ’¨


Cover Photo by Pawel Czerwinski on Unsplash

Top comments (3)

Collapse
 
altruista profile image
Altruista

What is benefit if i use Distrobox (on MicroOS) for Jellyfin (but also other containers) server? I am now running it via plain Podman...

Collapse
 
archerallstars profile image
Archer Allstars • Edited

The benefit of Distrobox is that it's a helper script for setting up and managing a Podman or a Docker container (the latter is not recommended for a rootless container).

If you're familiar with Podman, you can use it directly. There's no benefit in terms of performance, space usage, etc. over one another. I use and recommend Distrobox for its user-friendliness.

Collapse
 
altruista profile image
Altruista • Edited

I am just beginner with Podman πŸ˜€. Running the container with Podman run (also with Cockpit). But it is not easy for me to figure out some issues... so if Distrobox could help me, i should maybe try it 😲