Archived
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
997918e2f7 | ||
|
|
2860f750b4 | ||
|
|
781b1d324e | ||
|
|
3014a45936 | ||
|
|
cda2132d6a | ||
|
|
6c1cc821a0 | ||
|
|
4be064572d | ||
|
|
89d506180d |
@@ -77,6 +77,14 @@ creation_rules:
|
|||||||
- *admin
|
- *admin
|
||||||
- *lxc-tor-relay
|
- *lxc-tor-relay
|
||||||
|
|
||||||
|
- path_regex: secrets/tailscale-router\.yaml$
|
||||||
|
key_groups:
|
||||||
|
- age:
|
||||||
|
- *admin
|
||||||
|
- *linode-tailscale-router
|
||||||
|
- *lxc-tailscale-router
|
||||||
|
- *proxmox-tailscale-router
|
||||||
|
|
||||||
# gui-host-specific secrets (currently: wifi-password, see
|
# gui-host-specific secrets (currently: wifi-password, see
|
||||||
# modules/networking/wifi.nix). Only *lxc-gui has a registered key today
|
# modules/networking/wifi.nix). Only *lxc-gui has a registered key today
|
||||||
# -- proxmox-gui/linode-gui/baremetal-gui haven't been provisioned via
|
# -- proxmox-gui/linode-gui/baremetal-gui haven't been provisioned via
|
||||||
|
|||||||
@@ -1,8 +1,19 @@
|
|||||||
_:
|
_:
|
||||||
|
|
||||||
{
|
{
|
||||||
|
imports = [
|
||||||
|
(import ../../modules/beszel/host-token.nix {
|
||||||
|
name = "tailscale-router";
|
||||||
|
sopsFile = ../../secrets/tailscale-router.yaml;
|
||||||
|
})
|
||||||
|
];
|
||||||
|
|
||||||
networking.hostName = "tailscale-router";
|
networking.hostName = "tailscale-router";
|
||||||
|
|
||||||
|
services.beszel.agent.environment = {
|
||||||
|
KEY = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFPR9kwtC4TAeTRu46A7+opZsYpxqkRJ+x/ZyB2GWCeG";
|
||||||
|
};
|
||||||
|
|
||||||
# No networking.hostId: only ZFS-touching hosts (server, docker) need one
|
# No networking.hostId: only ZFS-touching hosts (server, docker) need one
|
||||||
# for pool-import safety, and this host does neither.
|
# for pool-import safety, and this host does neither.
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
{ ... }:
|
{ vars, ... }:
|
||||||
|
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
../tailscale/subnet-router.nix
|
../tailscale/subnet-router.nix
|
||||||
|
../beszel/enable-agent.nix
|
||||||
];
|
];
|
||||||
|
|
||||||
# "server", not "both": this build type advertises LAN subnet routes but
|
# "server", not "both": this build type advertises LAN subnet routes but
|
||||||
@@ -12,8 +13,33 @@
|
|||||||
# own setting) so the intent is clear at the build-type level.
|
# own setting) so the intent is clear at the build-type level.
|
||||||
services.tailscale.useRoutingFeatures = "server";
|
services.tailscale.useRoutingFeatures = "server";
|
||||||
|
|
||||||
|
# Advertise the LAN subnet so Tailscale peers can route back to LAN machines.
|
||||||
|
# Must also be approved in the Tailscale admin console (Machines → Edit route settings).
|
||||||
|
services.tailscale.extraUpFlags = [ "--advertise-routes=${vars.lanCidr}" ];
|
||||||
|
|
||||||
|
networking = {
|
||||||
|
# SNAT traffic from LAN machines going out through Tailscale so the remote
|
||||||
|
# peer sees it sourced from this router's Tailscale IP (100.x.x.x) rather
|
||||||
|
# than a raw LAN IP. Without this, Tailscale drops the forwarded packets
|
||||||
|
# because the source is not a recognised Tailscale address.
|
||||||
|
#
|
||||||
|
# networking.nat.externalInterface alone does not insert a MASQUERADE rule
|
||||||
|
# (it only does so when internalInterfaces is also set). We use
|
||||||
|
# extraCommands to add the rule into the nixos-nat-post chain that
|
||||||
|
# networking.nat.enable creates, and extraStopCommands to clean it up.
|
||||||
|
nat.enable = true;
|
||||||
|
|
||||||
|
firewall = {
|
||||||
# Forwarded subnet-router traffic arrives on tailscale0 already
|
# Forwarded subnet-router traffic arrives on tailscale0 already
|
||||||
# tailscale-authenticated -- the firewall's normal per-port allow-list
|
# tailscale-authenticated -- the firewall's normal per-port allow-list
|
||||||
# would otherwise drop it. Standard NixOS/Tailscale subnet-router guidance.
|
# would otherwise drop it. Standard NixOS/Tailscale subnet-router guidance.
|
||||||
networking.firewall.trustedInterfaces = [ "tailscale0" ];
|
trustedInterfaces = [ "tailscale0" ];
|
||||||
|
extraCommands = ''
|
||||||
|
iptables -t nat -A nixos-nat-post -s ${vars.lanCidr} -o tailscale0 -j MASQUERADE
|
||||||
|
'';
|
||||||
|
extraStopCommands = ''
|
||||||
|
iptables -t nat -D nixos-nat-post -s ${vars.lanCidr} -o tailscale0 -j MASQUERADE 2>/dev/null || true
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
_:
|
{ pkgs, ... }:
|
||||||
|
|
||||||
{
|
{
|
||||||
imports = [ ./enable-service.nix ];
|
imports = [ ./enable-service.nix ];
|
||||||
@@ -12,4 +12,24 @@ _:
|
|||||||
# instead of relaying through DERP.
|
# instead of relaying through DERP.
|
||||||
openFirewall = true;
|
openFirewall = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# Tailscale recommends these ethtool flags on the uplink interface to get
|
||||||
|
# full UDP GRO throughput on subnet routers (https://tailscale.com/s/ethtool-config-udp-gro).
|
||||||
|
# The interface is derived from the default route so it works regardless of
|
||||||
|
# what the NIC is named on a given host.
|
||||||
|
systemd.services.tailscale-udp-gro = {
|
||||||
|
description = "Enable UDP GRO forwarding on uplink for Tailscale subnet router";
|
||||||
|
after = [ "network-online.target" ];
|
||||||
|
wants = [ "network-online.target" ];
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
path = [ pkgs.ethtool pkgs.iproute2 ];
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "oneshot";
|
||||||
|
RemainAfterExit = true;
|
||||||
|
ExecStart = pkgs.writeShellScript "tailscale-udp-gro" ''
|
||||||
|
NETDEV=$(ip -o route get 8.8.8.8 | cut -f 5 -d " ")
|
||||||
|
ethtool -K "$NETDEV" rx-udp-gro-forwarding on rx-gro-list off
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user