diff --git a/flake.lock b/flake.lock index 7107e1f..a0528d3 100644 --- a/flake.lock +++ b/flake.lock @@ -2,11 +2,11 @@ "nodes": { "nixpkgs": { "locked": { - "lastModified": 1717144377, - "narHash": "sha256-F/TKWETwB5RaR8owkPPi+SPJh83AQsm6KrQAlJ8v/uA=", + "lastModified": 1718208800, + "narHash": "sha256-US1tAChvPxT52RV8GksWZS415tTS7PV42KTc2PNDBmc=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "805a384895c696f802a9bf5bf4720f37385df547", + "rev": "cc54fb41d13736e92229c21627ea4f22199fee6b", "type": "github" }, "original": { diff --git a/pastila/configuration.nix b/pastila/configuration.nix index 0d9c854..0c1836f 100644 --- a/pastila/configuration.nix +++ b/pastila/configuration.nix @@ -15,6 +15,7 @@ in ./srv.nix ./weechat-relay.nix ./prosody.nix + ./headscale.nix ]; # Use the GRUB 2 boot loader. diff --git a/pastila/headscale.nix b/pastila/headscale.nix new file mode 100644 index 0000000..c504cca --- /dev/null +++ b/pastila/headscale.nix @@ -0,0 +1,116 @@ +{ config, lib, pkgs, ... }: + +let + localListenPort = 4443; +in +{ + services.headscale = { + enable = true; + address = "127.0.0.1"; + port = localListenPort; + settings = { + server_url = "https://scale.isomorphis.me:443"; + + dns_config = { + override_local_dns = true; + base_domain = "infracoll.su"; + }; + + derp = { + urls = []; + server = { + # If enabled, runs the embedded DERP server and merges it into the rest of the DERP config + # The Headscale server_url defined above MUST be using https, DERP requires TLS to be in place + enabled = true; + + # Region ID to use for the embedded DERP server. + # The local DERP prevails if the region ID collides with other region ID coming from + # the regular DERP config. + region_id = 999; + + # Region code and name are displayed in the Tailscale UI to identify a DERP region + region_code = "headscale"; + region_name = "Headscale Embedded DERP"; + + # Listens over UDP at the configured address for STUN connections - to help with NAT traversal. + # When the embedded DERP server is enabled stun_listen_addr MUST be defined. + # + # For more details on how this works, check this great article: https://tailscale.com/blog/how-tailscale-works/ + stun_listen_addr = "0.0.0.0:3478"; + }; + }; + + # List of IP prefixes to allocate tailaddresses from. + # Each prefix consists of either an IPv4 or IPv6 address, + # and the associated prefix length, delimited by a slash. + # It must be within IP ranges supported by the Tailscale + # client - i.e., subnets of 100.64.0.0/10 and fd7a:115c:a1e0::/48. + # See below: + # IPv6: https://github.com/tailscale/tailscale/blob/22ebb25e833264f58d7c3f534a8b166894a89536/net/tsaddr/tsaddr.go#LL81C52-L81C71 + # IPv4: https://github.com/tailscale/tailscale/blob/22ebb25e833264f58d7c3f534a8b166894a89536/net/tsaddr/tsaddr.go#L33 + # Any other range is NOT supported, and it will cause unexpected issues. + ip_prefixes = [ + "fd7a:115c:a1e0::/48" + "100.64.0.0/10" + ]; + + # Address to listen for gRPC. + # gRPC is used for controlling a headscale server + # remotely with the CLI + # Note: Remote access _only_ works if you have + # valid certificates. + grpc_listen_addr = "127.0.0.1:50442"; + + # Allow the gRPC admin interface to run in INSECURE + # mode. This is not recommended as the traffic will + # be unencrypted. Only enable if you know what you + # are doing. + grpc_allow_insecure = true; # we're behind a reverse proxy + + logtail = { + enabled = false; + }; + }; + }; + + services.nginx.enable = true; + services.nginx.virtualHosts."scale.isomorphis.me" = { + useACMEHost = "scale.isomorphis.me"; + onlySSL = true; + locations."/" = { + proxyPass = "http://127.0.0.1:" + builtins.toString localListenPort; + recommendedProxySettings = false; + extraConfig = '' + 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; + ''; + }; + }; + + services.nginx.virtualHosts."headscale-grpc" = { + serverName = "scale.isomorphis.me"; + useACMEHost = "scale.isomorphis.me"; + onlySSL = true; + listen = [ + { addr = "0.0.0.0"; port = 50443; ssl = true; } + { addr = "[::]"; port = 50443; ssl = true; } + ]; + locations."/" = { + extraConfig = '' + grpc_pass grpc://127.0.0.1:50442; + ''; + }; + }; + + security.acme.certs."scale.isomorphis.me" = { + group = config.services.nginx.group; + }; +} \ No newline at end of file diff --git a/pastila/weechat-relay.nix b/pastila/weechat-relay.nix index e5cfafc..70ff5f3 100644 --- a/pastila/weechat-relay.nix +++ b/pastila/weechat-relay.nix @@ -9,7 +9,6 @@ let proxyWebsockets = true; extraConfig = '' proxy_read_timeout 604800; # Prevent idle disconnects - proxy_set_header X-Real-IP $remote_addr; # Let WeeChat see the client's IP ''; }; }; diff --git a/vars.nix b/vars.nix index 7bbf962..f3b4de1 100644 --- a/vars.nix +++ b/vars.nix @@ -25,8 +25,11 @@ { num = 51413; proto = "udp"; } # mosh # see ad-hoc config in oven/configuration.nix + # Headscale RPC + { num = 50443; proto = "tcp"; } ]; }; + onlineNetDNS = [ "51.159.47.28" "51.159.47.26"