Toggle menu
Toggle personal menu
Not logged in
Your IP address will be publicly visible if you make any edits.

Configuring Headscale: Difference between revisions

From Thibble Wiki
Created page with "== Headscale Settup and Usage == ==== Summary ==== Tailscale is a free to use VPN service which is build upon Wireguard, is a fast HTTPS based VPN service which removes the server role in a traditional Wireguard setup, and replaces it with a Peer 2 Peer protocol, and a Authentication server. This allows you to connect multiple devices directly, providing device to device connection, via IP and dynamic/magic DNS. Headscale is a open source port of the service, which all..."
 
No edit summary
Line 90: Line 90:


First we are going to download and run the installser script on our two clients
First we are going to download and run the installser script on our two clients
<pre>
curl -fsSL https://tailscale.com/install.sh | sh
</pre>
It will prompt for sudo password, and then install. Once installed enable and start the service like we did with Headscale:
<pre>
sudo systemctl enable tailscaled.service
sudo systemctl start tailscaled.service
</pre>
Now we need to connect our new Client device to the Headscale server, so it can authenticate the device, and direct it to the other nodes on the Headscale network:
<pre>
sudo tailscale ip --login-server=http://xxx.xxx.xxx.xxx:8080
</pre>
When you do this you will be prompted with a URL. We arent going click the URL but we need the key generated, this is the section at the end starting with "mkey:" Including all of the numbers and letters which is the key for authentication. Copy this key and then on the headscale server run the following command to register and accept the client:
<pre>
sudo headscale nodes register --user <USER> --key <KEY>
</pre>
Example Screenshot:
[[File:Tailscale Client Key.png|800px]]
Once this is run the device will be accepted and connected. Confirm this my running <pre> sudo tailscale status </pre> on the client. This should return the new node, and its status in the TTY:
[[File:Tailscale Status.png|800px]]
On the server we can confirm the connected device with <pre> sudo headscale nodes list</pre> Which gives good status info of all nodes:
[[File:Headscale Node Status.png|800px]]
We can see the nodes on my server are "Online" and no expired.
==== Exit Node ====
Up until this point the setup for a exit node, or regular client is the same, but we need to do a few more things to setup a node as a exit node to allow other clients to access the node and its local subnets.
Now that we have the node authenticated we are going to reconnect it to the headscale server, with a few flags to advertise as an exit node, and to advertise the subnets that are allowed locally:
<pre>
sudo tailscale set --advertise-exit-node --advertise- routes=10.0.1.0/24
</pre>
In the "Advertise Routes" Flag make sure to update to the Subnet you want to share.
Now we need to run the following to allow routing to work correctly on the exit node.
<pre>
echo 'net.ipv4.ip_forward = 1' | sudo tee -a /etc/sysctl.d/99-tailscale.conf
echo 'net.ipv6.conf.all.forwarding = 1' | sudo tee -a /etc/sysctl.d/99-tailscale.conf
sudo sysctl -p /etc/sysctl.d/99-tailscale.conf
</pre>
Now the node is advertising this subnet. Now we need to go "Approve" the advertisement on the headscale server. From the server run the following:
<pre>
sudo headscale routes list
</pre>
This will list all the routes available on the server, in my case the 10.0.1.0/24 route got the "ID" of 3. Now we run the Following to accept the route "3":
<pre>
sudo headscale routes enable -r 3
</pre>
Now if we run the list command from above we should see that the "Enabled" and "Primary" field should be "true":
[[File:Route Status.png|800px]]
==== Client Connection ====
Finally we just have to go to our mobile client, and configure it to connect to the exit node. To do this simply reconnect to the headscale server with the following command:
<pre>
sudo tasilscale up --login-server=http://xxx.xxx.xxx.xxx:8080 --accept-routes --exit-node=<EXIT NODE NAME>
</pre>
Now you should be connected, and able to ping devices and access services on that subnet.
==== Conclusion ====
Headscale takes a powerful free to use tool and drops control into you own hands, allowing the creation and use of a powerful networking system. All of the client configuration for this setup uses the same syntax and commands as tail-scale clients, and can be changed, tweaked, and modified using the information found in tail-scales official documentation.
[https://tailscale.com/kb/1017/install Offical Tailscale Documents]
Also thanks to "europecafe" on Reddit for their post providing some clarification of the process, and of Liam DiFalco

Revision as of 02:56, 24 January 2025

Headscale Settup and Usage

Summary

Tailscale is a free to use VPN service which is build upon Wireguard, is a fast HTTPS based VPN service which removes the server role in a traditional Wireguard setup, and replaces it with a Peer 2 Peer protocol, and a Authentication server. This allows you to connect multiple devices directly, providing device to device connection, via IP and dynamic/magic DNS. Headscale is a open source port of the service, which allows you to host your own authentication server removing limits on speeds, and improving reliability.

In this setup I will be outlining the configuration of the Client and server for Headscale, as well as configuring a client as a "Exit Node" allowing it to forward traffic to local Subnets to other nodes connected to it, for remote network access without the need of a static public address, allowing the traversal of Carrier grade NAT, and port forwarding.

Headscale server Installation

First we are going to set up our server and install Headscale. The server is recommend by Headscale to be a Apt based Distro, in this example I used Debian 12 Latest. After initial setup I installed firewalld as a firewall appliance which I recommend especially if you are using a VPS that has a public address assigned. Once that is done make sure the following ports are open on the server:

80/tcp required for initial request 443/tcp used for traffic 8080/tcp used by the authentication server

41641/udp used for the relay functionality 3478/udp used for the relay functionality

If using Firewalld like i was these can be opened with:

sudo firewall-cmd --permanent --allow-port=80/tcp \
sudo firewall-cmd --permanent --allow-port=443/tcp \
sudo firewall-cmd --permanent --allow-port=8080/tcp \
sudo firewall-cmd --permanent --allow-port=41641/udp \
sudo firewall-cmd --permanent --allow-port=3478/udp

Once those ports are open the following link to get the latest release of headscale's .deb file for amd64.

Latest Headscale Release

Copy the URL of the .deb file and use wget to download it to the server:

wget https://github.com/juanfont/headscale/releases/download/v0.24.1/headscale_0.24.1_linux_amd64.deb

Once this is downloaded install it with dpkg:

sudo dpkg -i headscale_0.24.1_linux_amd64.deb

Now we need to update the IP address of the server in the config before we start it.

Edit the config with the following:

sudo nano /etc/headscale/config.yaml

In the section Highlighted change the blacked out part to the your public address, also change the "Listen Addr" Section to be 0.0.0.0:8080 to allow authentication requests from any IP.

After this save and close the config file, and then enable and start the headscale service.

sudo systemctl enable headscale.service
sudo systemctl start headscale.service

Then check that is is running with

sudo systemctl status headscale.service

You should see a active and started service, without errors or warnings in the dmesg output:

Finally we need to create a user to tie out devices together:

headscale users create <USER>

Now we have configured and started our Headscale server, which is ready for authentication requests. Keep a session open with the server, as we will need access to accept and import the keys for out clients, and have created a use for our devices.

Client Configuration

Now we will outline the configuration of the clients, as they are going to be using the standard Railscale client to access our own server, giving us the advantaged of cross compatibility.

In my example i will be connecting two Linux devices one as the client and one as the "Exit Node". Additonal documentation for other platforms and OS's can be found here:

Tailscale Documentation Page

First we are going to download and run the installser script on our two clients

curl -fsSL https://tailscale.com/install.sh | sh

It will prompt for sudo password, and then install. Once installed enable and start the service like we did with Headscale:

sudo systemctl enable tailscaled.service
sudo systemctl start tailscaled.service

Now we need to connect our new Client device to the Headscale server, so it can authenticate the device, and direct it to the other nodes on the Headscale network:

sudo tailscale ip --login-server=http://xxx.xxx.xxx.xxx:8080

When you do this you will be prompted with a URL. We arent going click the URL but we need the key generated, this is the section at the end starting with "mkey:" Including all of the numbers and letters which is the key for authentication. Copy this key and then on the headscale server run the following command to register and accept the client:

sudo headscale nodes register --user <USER> --key <KEY>

Example Screenshot:

Once this is run the device will be accepted and connected. Confirm this my running

 sudo tailscale status 

on the client. This should return the new node, and its status in the TTY:

On the server we can confirm the connected device with

 sudo headscale nodes list

Which gives good status info of all nodes:

We can see the nodes on my server are "Online" and no expired.

Exit Node

Up until this point the setup for a exit node, or regular client is the same, but we need to do a few more things to setup a node as a exit node to allow other clients to access the node and its local subnets.

Now that we have the node authenticated we are going to reconnect it to the headscale server, with a few flags to advertise as an exit node, and to advertise the subnets that are allowed locally:

sudo tailscale set --advertise-exit-node --advertise- routes=10.0.1.0/24

In the "Advertise Routes" Flag make sure to update to the Subnet you want to share.

Now we need to run the following to allow routing to work correctly on the exit node.

echo 'net.ipv4.ip_forward = 1' | sudo tee -a /etc/sysctl.d/99-tailscale.conf
echo 'net.ipv6.conf.all.forwarding = 1' | sudo tee -a /etc/sysctl.d/99-tailscale.conf
sudo sysctl -p /etc/sysctl.d/99-tailscale.conf

Now the node is advertising this subnet. Now we need to go "Approve" the advertisement on the headscale server. From the server run the following:

sudo headscale routes list

This will list all the routes available on the server, in my case the 10.0.1.0/24 route got the "ID" of 3. Now we run the Following to accept the route "3":

sudo headscale routes enable -r 3

Now if we run the list command from above we should see that the "Enabled" and "Primary" field should be "true":

Client Connection

Finally we just have to go to our mobile client, and configure it to connect to the exit node. To do this simply reconnect to the headscale server with the following command:

sudo tasilscale up --login-server=http://xxx.xxx.xxx.xxx:8080 --accept-routes --exit-node=<EXIT NODE NAME>

Now you should be connected, and able to ping devices and access services on that subnet.

Conclusion

Headscale takes a powerful free to use tool and drops control into you own hands, allowing the creation and use of a powerful networking system. All of the client configuration for this setup uses the same syntax and commands as tail-scale clients, and can be changed, tweaked, and modified using the information found in tail-scales official documentation.

Offical Tailscale Documents

Also thanks to "europecafe" on Reddit for their post providing some clarification of the process, and of Liam DiFalco