blob: 7f08e7aa20ce777b8cdf6046b06589c9248848f7 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
|
# Configuration for the coordination server for net.tvl.fyi, a
# tailscale network run using headscale.
#
# All TVL members can join this network, which provides several exit
# nodes through which traffic can be routed.
#
# The coordination server is currently run on sanduny.tvl.su. It is
# managed manually, ping somebody with access ... for access.
#
# Servers should join using approximately this command:
# tailscale up --login-server https://net.tvl.fyi --accept-dns --advertise-exit-node --advertise-tags="tag:tvl"
#
# Clients should join using approximately this command:
# tailscale up --login-server https://net.tvl.fyi --accept-dns=false
{ config, pkgs, ... }:
let
accept = src: dst: {
action = "accept";
src = [ src ];
dst = [ dst ];
};
acl = with builtins; toFile "headscale-acl.json" (toJSON {
acls = [
# allow any tailnet traffic to TVL machines
(accept "*" "tag:tvl:*")
# allow any tailnet node to use any exit node
(accept "*" "autogroup:internet:*")
# builders can talk to each other
(accept "tag:builders" "tag:builders:*")
# anything goes inside tazjin's net
(accept "group:taznet" "group:taznet:*")
];
# TVL is ... TVL
groups."group:tvl" = [ "tvl@" ];
tagOwners."tag:tvl" = [ "group:tvl" ];
# TVL builder machines (talking to each other through builderball)
groups."group:builders" = [ "tvl@" "tvl-builders@" ];
tagOwners."tag:builders" = [ "group:builders" ];
# tazjin's personal home group
groups."group:taznet" = [ "tazjin@" "varia@" ];
tagOwners."tag:taznet" = [ "group:taznet" ];
});
in
{
# TODO(tazjin): run embedded DERP server
services.headscale = {
enable = true;
port = 4725; # hscl
settings = {
server_url = "https://net.tvl.fyi";
policy.path = acl;
dns = {
# assign DNS names within tail.tvl.fyi (delegated to sanduny)
magic_dns = true;
base_domain = "tail.tvl.fyi";
override_local_dns = false;
nameservers.global = [
"8.8.8.8"
"77.88.8.8"
"2001:4860:4860::8888"
"2a02:6b8::feed:0ff"
];
search_domains = [ "tvl.fyi" ];
};
# TLS is handled by nginx
tls_cert_path = null;
tls_key_path = null;
};
};
environment.systemPackages = [ pkgs.headscale ]; # admin CLI
services.nginx.virtualHosts."net.tvl.fyi" = {
serverName = "net.tvl.fyi";
enableACME = true;
forceSSL = true;
# See https://github.com/juanfont/headscale/blob/v0.22.3/docs/reverse-proxy.md#nginx
extraConfig = ''
location / {
proxy_pass http://localhost:${toString config.services.headscale.port};
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $server_name;
proxy_redirect http:// https://;
proxy_buffering off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto;
add_header Strict-Transport-Security "max-age=15552000; includeSubDomains" always;
}
'';
};
}
|