1import ./make-test-python.nix (
2 { pkgs, lib, ... }:
3 let
4 tls-cert = pkgs.runCommand "selfSignedCerts" { buildInputs = [ pkgs.openssl ]; } ''
5 openssl req \
6 -x509 -newkey rsa:4096 -sha256 -days 365 \
7 -nodes -out cert.pem -keyout key.pem \
8 -subj '/CN=headscale' -addext "subjectAltName=DNS:headscale"
9
10 mkdir -p $out
11 cp key.pem cert.pem $out
12 '';
13 in
14 {
15 name = "headscale";
16 meta.maintainers = with lib.maintainers; [
17 kradalby
18 misterio77
19 ];
20
21 nodes =
22 let
23 headscalePort = 8080;
24 stunPort = 3478;
25 peer = {
26 services.tailscale.enable = true;
27 security.pki.certificateFiles = [ "${tls-cert}/cert.pem" ];
28 };
29 in
30 {
31 peer1 = peer;
32 peer2 = peer;
33
34 headscale = {
35 services = {
36 headscale = {
37 enable = true;
38 port = headscalePort;
39 settings = {
40 server_url = "https://headscale";
41 ip_prefixes = [ "100.64.0.0/10" ];
42 derp.server = {
43 enabled = true;
44 region_id = 999;
45 stun_listen_addr = "0.0.0.0:${toString stunPort}";
46 };
47 dns.base_domain = "tailnet";
48 };
49 };
50 nginx = {
51 enable = true;
52 virtualHosts.headscale = {
53 addSSL = true;
54 sslCertificate = "${tls-cert}/cert.pem";
55 sslCertificateKey = "${tls-cert}/key.pem";
56 locations."/" = {
57 proxyPass = "http://127.0.0.1:${toString headscalePort}";
58 proxyWebsockets = true;
59 };
60 };
61 };
62 };
63 networking.firewall = {
64 allowedTCPPorts = [
65 80
66 443
67 ];
68 allowedUDPPorts = [ stunPort ];
69 };
70 environment.systemPackages = [ pkgs.headscale ];
71 };
72 };
73
74 testScript = ''
75 start_all()
76 headscale.wait_for_unit("headscale")
77 headscale.wait_for_open_port(443)
78
79 # Create headscale user and preauth-key
80 headscale.succeed("headscale users create test")
81 authkey = headscale.succeed("headscale preauthkeys -u test create --reusable")
82
83 # Connect peers
84 up_cmd = f"tailscale up --login-server 'https://headscale' --auth-key {authkey}"
85 peer1.execute(up_cmd)
86 peer2.execute(up_cmd)
87
88 # Check that they are reachable from the tailnet
89 peer1.wait_until_succeeds("tailscale ping peer2")
90 peer2.wait_until_succeeds("tailscale ping peer1.tailnet")
91 '';
92 }
93)