Add qubes tailscale article
parent
c7f351017f
commit
3912abdc21
Binary file not shown.
After Width: | Height: | Size: 33 KiB |
Binary file not shown.
After Width: | Height: | Size: 25 KiB |
@ -0,0 +1,241 @@
|
||||
+++
|
||||
title = "Setting up a Tailscale ProxyVM on QubesOS"
|
||||
[taxonomies]
|
||||
tags = [ "qubesos","tailscale", "howto" ]
|
||||
+++
|
||||
|
||||
QubesOS and Tailscale are both useful tools to protect your privacy and
|
||||
security. However, QubesOS's unique network structure of many VMs being used on
|
||||
a single host requires additional configuration to be used similarly to
|
||||
Tailscale.
|
||||
|
||||
Once this setup is complete, any AppVM configured to use `sys-tailnet` as its
|
||||
network qube will have access to your Tailscale network ("tailnet"). All AppVMs
|
||||
will be able to utilize Tailscale features such as MagicDNS or custom DNS
|
||||
records to route traffic within your tailnet. The Qubes firewall rules can also
|
||||
be used to restrict traffic to and from a particular AppVM.
|
||||
|
||||
> *Warning*: Tailscale is a unique mesh VPN that doesn't have the same privacy
|
||||
> and security properties as a typical VPN provider. Ensure you understand how
|
||||
> Tailscale works before relying on it to protect your QubesOS network traffic.
|
||||
|
||||
# Potential Strategies
|
||||
|
||||
## A Tailscale AppVM
|
||||
|
||||
If you only need to access your tailnet for a particular purpose, it may be
|
||||
sufficient to simply install Tailscale in the AppVM that needs access it. For
|
||||
example, if you need to access your job's git server from your `work` AppVM,
|
||||
just install Tailscale in `work` and you're good to go -- it will only affect
|
||||
the network traffic from your `work` VM.
|
||||
|
||||
Conveniently, this works around one of the most common Tailscale problems: it
|
||||
allows you to connect to multiple tailnets at once. This is useful if you need
|
||||
your work AppVM to be connected to your employer's tailnet, but you also want to
|
||||
access a personal tailnet.
|
||||
|
||||
However, if you need to connect several AppVMs, or regularly connect DispVMs, to
|
||||
your tailnet, a more complex configuration is needed.
|
||||
|
||||
## One Node per AppVM
|
||||
|
||||
Perhaps the easiest way to configure Tailscale on QubesOS would be to install
|
||||
the Tailscale daemon (`tailscaled`) in your Template VMs, then register each
|
||||
AppVM or DispVM based off of those templates as its own node.
|
||||
|
||||
The one benefit that this method provides is that you have much greater control
|
||||
over what each VM can access on your tailnet. For instance, you could log into
|
||||
different groups of AppVMs with different users, then use Tailscale's Access
|
||||
Control Lists to limit access to network resources.
|
||||
|
||||
However, this method is inconvenient in several ways. For one, Tailscale's
|
||||
pricing model limits you by the number of devices on your tailnet:
|
||||
|
||||
![Screenshot of IRC pricing model.](./tailscale-pricing.png)
|
||||
|
||||
While it would be pretty difficult to use 100 devices, using 100 VMs (especially
|
||||
if you want to use disposable VMs frequently on within your tailnet) isn't. I'm
|
||||
not actually sure how deregistering a device works on Tailscale, but it's not
|
||||
something I would want to think about regularly, especially if I intend to have
|
||||
multiple QubesOS machines or users on my network.
|
||||
|
||||
## `sys-tailnet`
|
||||
|
||||
A better way to connect your QubesOS machine to your tailnet is to create a
|
||||
dedicated network VM, which I call `sys-tailnet`. Following the idioms of
|
||||
QubesOS, you can register `sys-tailnet` as a network provider for other AppVMs.
|
||||
While this is certainly the most complicated way to configure Tailscale on your
|
||||
Qubes machine, it has the benefit of integrating well with the rest of the
|
||||
QubesOS networking stack, including enforcing per-AppVM firewalls and
|
||||
controlling which AppVMs route traffic through your tailnet.
|
||||
|
||||
An additional benefit of this method is that, as far as Tailscale is concerned,
|
||||
your QubesOS machine is only a single device, no matter how many VMs you're
|
||||
running through `sys-tailnet`. This greatly reduces the frequency with which you
|
||||
have to authenticate (at least compared to the previous method).
|
||||
|
||||
# `sys-tailnet` Guide
|
||||
|
||||
You can connect `sys-tailnet` to Tailscale like any other Linux system. Once
|
||||
you're authenticated and connected to your tailnet, configuring `sys-tailnet` is
|
||||
much like configuring any other ProxyVM in QubesOS.
|
||||
|
||||
## Creating `sys-tailnet`
|
||||
|
||||
First, create a new AppVM named `sys-tailnet`. For now, the only requirement for
|
||||
the qube is that you can install `tailscaled`, so it's best to pick a template
|
||||
that Tailscale has a package repository you can get automatic updates from. See
|
||||
Tailscale's [Setting up Tailscale on Linux](https://tailscale.com/kb/1031/install-linux/)
|
||||
guide to check if they publish a repository for your distro.
|
||||
|
||||
![Creating sys-tailnet](./create-sys-tailnet.png)
|
||||
|
||||
If you want to avoiding adding Tailscale's package repository to your
|
||||
TemplateVM, consider making `sys-tailnet` a StandaloneVM or creating a new
|
||||
TemplateVM for it. You should also select a networking qube to route your
|
||||
Tailscale traffic through (you likely want this to be `sys-firewall`).
|
||||
|
||||
![Advanced settings for sys-tailnet](./advanced-sys-tailnet.png)
|
||||
|
||||
Also, in the "Advanced" tab, mark that `sys-tailnet` provides network access to
|
||||
other qubes.
|
||||
|
||||
## Installing `tailscaled`
|
||||
|
||||
Tailscale [provides instructions](https://tailscale.com/kb/1031/install-linux/)
|
||||
for installing `tailscaled` on a large variety of Linux distros. You'll want to
|
||||
perform these instructions in `sys-tailnet` if you configured it as a
|
||||
StandaloneVM, or in your `sys-tailnet`'s TemplateVM if you configured it as an
|
||||
AppVM. For Fedora, for example, you just install the Tailscale repository:
|
||||
|
||||
```bash
|
||||
sudo dnf config-manager --add-repo https://pkgs.tailscale.com/stable/fedora/tailscale.repo
|
||||
```
|
||||
|
||||
And then use `dnf` to install `tailscaled` like any other package:
|
||||
|
||||
```bash
|
||||
sudo dnf install tailscale
|
||||
```
|
||||
|
||||
## Configuring `sys-tailnet`
|
||||
|
||||
### If `sys-tailnet` is a StandaloneVM
|
||||
|
||||
If `sys-tailnet` is a StandaloneVM, you can continue to configure it just like
|
||||
any other Linux system. Enable and start `tailscaled`:
|
||||
```bash
|
||||
sudo systemctl enable --now tailscaled
|
||||
```
|
||||
|
||||
Then log into your Tailscale account:
|
||||
|
||||
```bash
|
||||
sudo tailscale up
|
||||
```
|
||||
|
||||
> Tip: see `tailscale up --help` for additional configuration options.
|
||||
|
||||
Since Tailscale's session will persist in a StandaloneVM, this is all of the
|
||||
configuration you need to log into Tailscale.
|
||||
|
||||
### If `sys-tailnet` is an AppVM
|
||||
In order to start `tailscaled` at launch, you'll need to modify the
|
||||
`/rw/config/rc.local` script within your `sys-tailnet`. This script is run in
|
||||
any AppVM whenever it starts. We'll be using it to initialize Tailscale.
|
||||
|
||||
Run `sudoedit /rw/config/rc.local` inside `sys-tailnet` and add the following
|
||||
line to the end of it:
|
||||
|
||||
```bash
|
||||
systemctl --no-block start tailscaled
|
||||
```
|
||||
|
||||
Before we log into Tailscale, however, we need to tell QubesOS to persist the
|
||||
Tailscale login data on reboot. In general terms, system data usually isn't
|
||||
persisted between reboots of an AppVM. The `/var/lib/tailscale`directory must be
|
||||
persisted for Tailscale to remain logged in.
|
||||
|
||||
QubesOS provides a mechanism for this called
|
||||
["bind-dirs"](https://www.qubes-os.org/doc/bind-dirs/). On AppVM boot, it bind
|
||||
mounts directories in `/rw/bind-dirs`, which is persist across AppVM reboots, to
|
||||
a corresponding location in the filesystem.
|
||||
|
||||
We can persist the Tailscale directory by adding a new configuration file to
|
||||
`/rw/config/qubes-bind-dirs.d/` in our `sys-tailnet`. If it doesn't exist
|
||||
already, create the directory by running the following inside `sys-tailnet`:
|
||||
|
||||
```bash
|
||||
sudo mkdir /rw/config/qubes-bind-dirs.d/
|
||||
```
|
||||
|
||||
Then, run `sudoedit /rw/config/qubes-bind-dirs.d/50_user.conf` and add the
|
||||
following contents to the file:
|
||||
|
||||
```conf
|
||||
binds+=( '/var/lib/tailscale' )
|
||||
```
|
||||
|
||||
Finally, `bind-dirs` won't work correctly if the `/var/lib/tailscale` directory
|
||||
doesn't exist in the template, so we need to manually create it:
|
||||
|
||||
```bash
|
||||
sudo mkdir -p /rw/bind-dirs/var/lib/tailscale
|
||||
```
|
||||
|
||||
Once you've configured persistence for the `/var/lib/tailscale` directory,
|
||||
reboot your `sys-tailnet` AppVM. From here, proceed as you normally would to
|
||||
connect a Linux system to your tailnet:
|
||||
|
||||
```bash
|
||||
sudo tailscale up
|
||||
```
|
||||
|
||||
> Tip: see `tailscale up --help` for additional configuration options.
|
||||
|
||||
# DNS
|
||||
|
||||
Tailscale relies on DNS for [various
|
||||
features](https://tailscale.com/kb/1054/dns/). On Linux, Tailscale modifies
|
||||
`/etc/resolv.conf` to configure the system's DNS resolver. However, these
|
||||
changes within your `sys-tailnet` do not apply to any AppVMs that use
|
||||
`sys-tailnet` as their network qube.
|
||||
|
||||
In order to forward DNS queries to the Tailscale DNS server, we can forward any
|
||||
incoming DNS requests in `sys-tailnet` coming from downstream AppVMs to the
|
||||
Tailscale nameserver. For details on how Tailscale handles DNS traffic, the
|
||||
article [Private DNS with
|
||||
MagicDNS](https://tailscale.com/blog/2021-09-private-dns-with-magicdns/) is a
|
||||
good overview.
|
||||
|
||||
In `sys-tailnet`, add the following `iptables` commands to
|
||||
`/rw/config/qubes-firewall-user-script`:
|
||||
|
||||
```bash
|
||||
#!/bin/sh
|
||||
# Based on https://forum.qubes-os.org/t/how-do-i-setup-a-custom-dns-in-appvm/5207
|
||||
|
||||
# This will Flush PR-QBS chain
|
||||
iptables -F PR-QBS -t nat
|
||||
# Redirects all the DNS traffic to Tailscale DNS server
|
||||
iptables -t nat -I PR-QBS -i vif+ -p udp --dport 53 -j DNAT --to-destination 100.100.100.100
|
||||
# Accepts the traffic coming to Tailscale DNS server from XEN's virtual interfaces on port 53
|
||||
iptables -I INPUT -i vif+ -p udp --dport 53 -d 100.100.100.100 -j ACCEPT
|
||||
```
|
||||
|
||||
> This script will run whenever the AppVM starts, but to avoid restarting
|
||||
> `sys-tailnet`, you can manually trigger it by running `sudo
|
||||
> /rw/config/qubes-firewall-user-script`
|
||||
|
||||
Tailscale's DNS server runs locally on your device and will forward any DNS
|
||||
queries that don't belong to your tailnet to the upstream netvm of your
|
||||
`sys-tailnet` qube, just like any other AppVM.
|
||||
|
||||
> Technically, your tailnet administrator can configure DNS settings, but these
|
||||
> only apply if you include the `--accept-dns` flag in your `tailscale up`
|
||||
> command.
|
||||
|
||||
---
|
||||
|
||||
That's it! Now you can start configuring your AppVMs access your tailnet while
|
||||
maintaining the security benefits of QubesOS's compartmentalization.
|
Binary file not shown.
After Width: | Height: | Size: 34 KiB |
Loading…
Reference in New Issue