From 7f1abe50ce0989d96c3d275a4d0481962848714f Mon Sep 17 00:00:00 2001
From: tv <tv@krebsco.de>
Date: Thu, 18 Feb 2016 00:50:10 +0100
Subject: [PATCH] xu-qemu0 host: setup iptables

---
 tv/2configs/xu-qemu0.nix | 18 ++++++++++++------
 tv/3modules/iptables.nix | 22 ++++++++++++++++++++++
 2 files changed, 34 insertions(+), 6 deletions(-)

diff --git a/tv/2configs/xu-qemu0.nix b/tv/2configs/xu-qemu0.nix
index 2b67a8b84..5be4899c8 100644
--- a/tv/2configs/xu-qemu0.nix
+++ b/tv/2configs/xu-qemu0.nix
@@ -15,17 +15,23 @@ in
 #
 #   make [install] system=xu-qemu0 target_host=10.56.0.101
 
-# TODO iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
-# TODO iptables -A FORWARD -i qemubr0 -s 10.56.0.1/24 -m conntrack --ctstate NEW -j ACCEPT
-# TODO iptables -A POSTROUTING -t nat -j MASQUERADE
-# TODO iptables -A INPUT -i qemubr0 -p udp -m udp --dport bootps -j ACCEPT
-# TODO iptables -A INPUT -i qemubr0 -p udp -m udp --dport domain -j ACCEPT
-
 with config.krebs.lib;
 
 {
   networking.dhcpcd.denyInterfaces = [ "qemubr0" ];
 
+  tv.iptables.extra = {
+    nat.POSTROUTING = ["-j MASQUERADE"];
+    filter.FORWARD = [
+      "-m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT"
+      "-i qemubr0 -s 10.56.0.1/24 -m conntrack --ctstate NEW -j ACCEPT"
+    ];
+    filter.INPUT = [
+      "-i qemubr0 -p udp -m udp --dport bootps -j ACCEPT"
+      "-i qemubr0 -p udp -m udp --dport domain -j ACCEPT"
+    ];
+  };
+
   systemd.network.enable = true;
   systemd.services.systemd-networkd-wait-online.enable = false;
 
diff --git a/tv/3modules/iptables.nix b/tv/3modules/iptables.nix
index c0fd7ec12..c0e71f24d 100644
--- a/tv/3modules/iptables.nix
+++ b/tv/3modules/iptables.nix
@@ -26,6 +26,21 @@ let
       type = with types; listOf (either int str);
       default = [];
     };
+
+    extra = {
+      nat.POSTROUTING = mkOption {
+        type = with types; listOf str;
+        default = [];
+      };
+      filter.FORWARD = mkOption {
+        type = with types; listOf str;
+        default = [];
+      };
+      filter.INPUT = mkOption {
+        type = with types; listOf str;
+        default = [];
+      };
+    };
   };
 
   imp = {
@@ -57,6 +72,11 @@ let
     };
   };
 
+  formatTable = table:
+    (concatStringsSep "\n"
+      (mapAttrsToList
+        (chain: concatMapStringsSep "\n" (rule: "-A ${chain} ${rule}"))
+        table));
 
   rules = iptables-version: let
     accept-echo-request = {
@@ -79,6 +99,7 @@ let
       ${concatMapStringsSep "\n" (rule: "-A OUTPUT ${rule}") [
         "-o lo -p tcp -m tcp --dport 11423 -j REDIRECT --to-ports 22"
       ]}
+      ${formatTable cfg.extra.nat}
       COMMIT
       *filter
       :INPUT DROP [0:0]
@@ -94,6 +115,7 @@ let
         ++ map accept-new-tcp (unique (map toString cfg.input-internet-accept-new-tcp))
         ++ ["-i retiolum -j Retiolum"]
       )}
+      ${formatTable cfg.extra.filter}
       ${concatMapStringsSep "\n" (rule: "-A Retiolum ${rule}") ([]
         ++ optional (cfg.accept-echo-request == "retiolum") accept-echo-request
         ++ map accept-new-tcp (unique (map toString cfg.input-retiolum-accept-new-tcp))