Cloudflared
Cloudflared is a command line client that can be used to establish a network tunnel from the Cloudflare network to a server.
Cloudflare Tunnel
Prerequisites
- A Cloudflare account
- A domain registered on Cloudflare (see https://developers.cloudflare.com/fundamentals/manage-domains/add-site/)
If you do not wish to install cloudflared you may use a nix-shell to use it for the following steps without adding it to your configuration.
$ nix-shell -p cloudflared
You will need to log in to your Cloudflare account through the command line, the following command will open a web browser to allow you to log in:
$ cloudflared -- tunnel login
You can use the link it provides on any machine that has a browser in order to get the needed cert.pem file. Afterwards you will need to create the tunnel from the machine.
$ cloudflared tunnel create <tunnel-name-of-choice>
The command will output the tunnel ID in the format 00000000-0000-0000-0000-000000000000, which will be needed for setting up the tunnel service. The following example uses flakes and sops-nix to hide the credentials file secret.
{
inputs,
config,
...
}: {
imports = [
inputs.sops-nix.nixosModules.sops
];
sops = {
age.keyFile = "/home/username/.config/sops/age/keys.txt";
defaultSopsFile = secrets/secrets.yaml;
secrets."cloudflared-creds" = {
owner = "username";
group = "users";
mode = "0400";
};
};
services.cloudflared = {
enable = true;
tunnels = {
"00000000-0000-0000-0000-000000000000" = {
credentialsFile = "${config.sops.secrets.cloudflared-creds.path}";
default = "http_status:404";
};
};
};
}
You can now use the Cloudflare dashboard to add your public hosts.
However, if you would instead like to do so in your configuration file you may specify ingress rules in your configuration file.
{
inputs,
config,
...
}: {
imports = [
inputs.sops-nix.nixosModules.sops
];
sops = {
age.keyFile = "/home/username/.config/sops/age/keys.txt";
defaultSopsFile = secrets/secrets.yaml;
secrets."cloudflared-creds" = {
owner = "username";
group = "users";
mode = "0400";
};
};
services.cloudflared = {
enable = true;
tunnels = {
"00000000-0000-0000-0000-000000000000" = {
credentialsFile = "${config.sops.secrets.cloudflared-creds.path}";
ingress = {
"your-registered-domain.com" = "http://localhost:PORT";
};
default = "http_status:404";
};
};
};
}
Troubleshooting
At the moment (2025), for support of browser rendering of the tunnels, this line is required:
services.openssh.settings.Macs = [
# Current defaults:
"hmac-sha2-512-etm@openssh.com"
"hmac-sha2-256-etm@openssh.com"
"umac-128-etm@openssh.com"
# Added:
"hmac-sha2-256"
];
The issue has been reported on Github