Add Hetzner Cloud firewall auto-sync from clan config
control runs a oneshot on each deploy that creates each firewall if missing and replaces its rules via the Hetzner API set_rules action, using a Read/Write token stored as a clan secret. Public SSH is not exposed; admin access rides the ZeroTier mesh, with emergency-access as the console fallback.
This commit is contained in:
@@ -1,8 +1,46 @@
|
||||
let
|
||||
world = [ "0.0.0.0/0" "::/0" ];
|
||||
|
||||
zerotier = {
|
||||
direction = "in";
|
||||
protocol = "udp";
|
||||
port = "9993";
|
||||
source_ips = world;
|
||||
description = "ZeroTier";
|
||||
};
|
||||
|
||||
ping = {
|
||||
direction = "in";
|
||||
protocol = "icmp";
|
||||
source_ips = world;
|
||||
description = "ICMP (ping / PMTUD)";
|
||||
};
|
||||
|
||||
dnsRules = [
|
||||
{ direction = "in"; protocol = "udp"; port = "53"; source_ips = world; description = "DNS (UDP)"; }
|
||||
{ direction = "in"; protocol = "tcp"; port = "53"; source_ips = world; description = "DNS (TCP)"; }
|
||||
zerotier
|
||||
ping
|
||||
];
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
|
||||
../../modules/hetzner-firewall.nix
|
||||
];
|
||||
|
||||
time.timeZone = "Etc/GMT-3"; # UTC+3 (fixed offset, no DST)
|
||||
services.timesyncd.enable = true;
|
||||
|
||||
# Public Hetzner Cloud firewalls, kept in sync from this config on every
|
||||
# deploy. Admin SSH is intentionally not exposed publicly: it rides the
|
||||
# ZeroTier mesh (inside UDP 9993), with emergency-access as the console
|
||||
# fallback if the mesh is ever unreachable.
|
||||
cnx.hetznerFirewall = {
|
||||
enable = true;
|
||||
firewalls = {
|
||||
"clan-control" = [ zerotier ping ];
|
||||
"clan-ns1" = dnsRules;
|
||||
"clan-ns2" = dnsRules;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user