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