fedora-csb-system-manager
  1{ lib, ... }:
  2
  3{
  4  # Enable IP forwarding for libvirt network
  5  boot.kernel.sysctl = {
  6    "net.ipv4.ip_forward" = lib.mkForce 1;
  7    "net.ipv6.conf.all.forwarding" = lib.mkForce 1;
  8  };
  9
 10  # Use nftables for better performance and cleaner syntax
 11  networking = {
 12    nftables = {
 13      enable = true;
 14
 15      # IMPORTANT: Using tables instead of ruleset to allow libvirt to manage its own table
 16      # If we use ruleset, it completely replaces everything and libvirt can't create its table
 17      tables = {
 18        "nat" = {
 19          family = "ip";
 20          content = ''
 21            chain prerouting {
 22              type nat hook prerouting priority dstnat; policy accept;
 23
 24              # Forward HTTP, HTTPS, and API traffic to OpenShift VM
 25              # Only from interfaces that are NOT virbr1 (to avoid loops)
 26              iifname != "virbr1" tcp dport 80 dnat to 192.168.100.7:80
 27              iifname != "virbr1" tcp dport 443 dnat to 192.168.100.7:443
 28              iifname != "virbr1" tcp dport 6443 dnat to 192.168.100.7:6443
 29            }
 30
 31            chain postrouting {
 32              type nat hook postrouting priority srcnat; policy accept;
 33
 34              # Masquerade traffic from libvirt network to external destinations
 35              ip saddr 192.168.100.0/24 ip daddr != 192.168.100.0/24 masquerade
 36            }
 37
 38            chain output {
 39              type nat hook output priority dstnat; policy accept;
 40
 41              # Forward localhost traffic destined for LAN IP to OpenShift VM
 42              ip daddr 192.168.1.23 tcp dport 80 dnat to 192.168.100.7:80
 43              ip daddr 192.168.1.23 tcp dport 443 dnat to 192.168.100.7:443
 44              ip daddr 192.168.1.23 tcp dport 6443 dnat to 192.168.100.7:6443
 45            }
 46          '';
 47        };
 48        "filter" = {
 49          family = "inet";
 50          content = ''
 51            chain input {
 52              type filter hook input priority filter; policy drop;
 53
 54              # Allow established/related connections
 55              ct state { established, related } accept
 56
 57              # Allow loopback
 58              iifname "lo" accept
 59
 60              # Allow trusted interfaces
 61              iifname { "wg0", "docker0" } accept
 62
 63              # Allow ICMP (ping)
 64              ip protocol icmp accept
 65              ip6 nexthdr ipv6-icmp accept
 66
 67              # Allow SSH
 68              tcp dport 22 accept
 69
 70              # Allow OpenShift ports
 71              tcp dport { 80, 443, 6443 } accept
 72
 73              # Allow Prometheus node exporter
 74              tcp dport 9000 accept
 75
 76              # Allow Docker Prometheus metrics
 77              tcp dport 9323 accept
 78
 79              # Allow Ollama API
 80              tcp dport 11434 accept
 81
 82              # Allow Ollama Prometheus exporter
 83              tcp dport 8000 accept
 84
 85              # Allow Harmonia binary cache
 86              tcp dport 5000 accept
 87
 88              # Allow libvirt
 89              tcp dport 16509 accept
 90
 91              # Allow mDNS
 92              udp dport 5353 accept
 93            }
 94
 95            chain forward {
 96              type filter hook forward priority filter; policy accept;
 97
 98              # Allow established/related connections
 99              ct state { established, related } accept
100
101              # Allow forwarding to/from the libvirt OpenShift network
102              ip daddr 192.168.100.0/24 accept
103              ip saddr 192.168.100.0/24 accept
104            }
105
106            chain output {
107              type filter hook output priority filter; policy accept;
108            }
109          '';
110        };
111      };
112
113      # Old ruleset approach - completely removed
114      # Using ruleset would prevent libvirt from managing its own table
115      # See tables configuration above instead
116    };
117
118    # Disable the default NixOS firewall since we're using custom nftables ruleset
119    firewall.enable = false;
120  };
121}