tailscale-manager dynamically manages Tailscale subnet route advertisements based on user-configurable discovery sources. It runs alongside tailscaled on the node(s) where you want to advertise routes.
config keyword | example | description |
---|---|---|
routes |
["192.168.0.0/24"] |
Static routes |
hostRoutes |
["private-app.example.com"] |
DNS hostname lookup |
awsManagedPrefixLists |
["pl-02761f4a40454a3c9"] |
AWS Managed Prefix Lists |
hostRoutes
can be used to emulate Tailscale App Connectors by advertising a
set of individual IP address routes that are kept in sync with DNS lookups of a
set of hostnames. This is most useful when using Headscale, which doesn't
normally support App Connectors.
- DNS SRV records
- Extra JSON files on disk
- Generic HTTP service discovery, similar to Prometheus
http_sd
- NetBox lists
- Google Cloud public-advertised-prefixes
- Other cloud providers?
Here is a sample config file, in JSON format:
{
"routes": [
"172.16.0.0/22",
"192.168.0.0/24",
],
"hostRoutes": [
"github.com",
"private-app.example.com"
],
"awsManagedPrefixLists": [
"pl-02761f4a40454a3c9"
]
}
Run tailscale-manager:
tailscale-manager your-config-file.json --interval 300
The above will result in individual /32 (or /128 for ipv6) route advertisements
on your tailnet for the IP addresses that github.com
and
private-app.example.com
resolve to, plus any routes found in the named AWS
managed prefix lists, and any static routes provided in the routes
list.
Every 300 seconds, tailscale-manager will refresh its route discovery sources
and update tailscale route advertisements accordingly.
Usage: tailscale-manager <configfile.json> [--dryrun] [--tailscale PATH]
[--interval INT] [--max-shrink-ratio RATIO]
Tailscale routes manager
Dynamically resolves a list of hostRoutes to IP addresses, then tells tailscale
to advertise them as /32 routes along with any normal CIDR routes.
Config file example:
{
"routes": [
"172.16.0.0/22",
"192.168.0.0/24"
],
"hostRoutes": [
"special-hostname1.example",
"special-hostname2.example",
],
"awsManagedPrefixLists": [
"pl-02761f4a40454a3c9"
],
"extraArgs": ["--webclient"]
}
Available options:
--dryrun Dryrun mode
--tailscale PATH Path to the tailscale executable
(default: "tailscale")
--interval INT Interval (in seconds) between runs. 0 means exit
after running once. (default: 0)
--max-shrink-ratio RATIO Max allowed route shrinkage between consecutive runs,
as a ratio between 0 and 1. 1 means no limit.
(default: 0.33)
-h,--help Show this help text
If you use NixOS, this repository provides a flake with a NixOS module to install and run tailscale-manager as a systemd service. You can incorporate it into your flake.nix like so:
{
description = "my nixos config";
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-24.05";
tailscale-manager = {
url = "github:singlestore-labs/tailscale-manager";
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs = { self, nixpkgs, tailscale-manager }:
{
nixosConfigurations.default = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [
tailscale-manager.nixosModules.x86_64-linux.default
({ config, lib, pkgs, ... }:
{
services.tailscale.enable = true;
services.tailscale-manager = {
enable = true;
routes = [
"172.16.0.0/22"
"192.168.0.0/24"
];
hostRoutes = [
"app1.example.com"
"app2.example.com"
];
interval = 300;
maxShrinkRatio = 0.25;
};
})
];
};
};
}