firewall: fix generation of outgoing rules on webserver
[hcoop/domtool2.git] / src / plugins / firewall.sml
index 2561f1c..1131f20 100644 (file)
@@ -104,12 +104,12 @@ fun dnsExists dnsRR dnsRecord =
          | (_, NONE) => false
     end
 
+fun fermVariable x = String.isPrefix "$" x
 fun filterHosts (hosts, ipv6) =
-    List.filter (fn host => if (Domain.validIpv6 host orelse Domain.validIp host)
-                           then
-                               true
-                           else
-                               dnsExists ipv6 host)
+    List.filter (fn host => fermVariable host
+                           orelse (case ipv6 of FwIPv6 => Domain.validIpv6 host
+                                              | FwIPv4 =>  Domain.validIp host)
+                           orelse dnsExists ipv6 host)
                hosts
 
 
@@ -158,17 +158,23 @@ fun generateNodeFermRules rules  =
        fun confLine_out_v6 (uname, rule) = confLine outputLines_v6 (uname, formatOutputRule (rule, FwIPv6))
 
        fun insertConfLine (uname, ruleNode, rule) =
-           case rule of
-               Client (ports, hosts) => (confLine_out (uname, rule); confLine_out_v6 (uname, rule))
-             | Server (ports, hosts) => (confLine_in (uname, rule); confLine_in_v6 (uname, rule))
-             | LocalServer ports => (insertConfLine (uname, ruleNode, Client (ports, ["127.0.0.1/8", ":::1"]));
-                                     insertConfLine (uname, ruleNode, Server (ports, ["127.0.0.1/8", ":::1"])))
-             | ProxiedServer ports => if (fn FirewallNode r => r) ruleNode = Slave.hostname () then
-                                          (insertConfLine (uname, ruleNode, Server (ports, ["$WEBNODES"]));
-                                           insertConfLine (uname, ruleNode, Client (ports, [(fn FirewallNode r => r) ruleNode])))
-                                      else (* we are a web server *)
-                                          (insertConfLine (uname, ruleNode, Client (ports, [(fn FirewallNode r => r) ruleNode]));
-                                           insertConfLine (User "www-data", ruleNode, Client (ports, [(fn FirewallNode r => r) ruleNode])))
+           let
+               val fwnode_domain = fn FirewallNode node => node ^ "." ^ Config.defaultDomain
+           in
+               case rule of
+                   Client (ports, hosts) => (confLine_out (uname, rule); confLine_out_v6 (uname, rule))
+                 | Server (ports, hosts) => (confLine_in (uname, rule); confLine_in_v6 (uname, rule))
+                 | LocalServer ports => (insertConfLine (uname, ruleNode, Client (ports, ["127.0.0.1/8"]));
+                                         insertConfLine (uname, ruleNode, Server (ports, ["127.0.0.1/8"]));
+                                         insertConfLine (uname, ruleNode, Client (ports, [":::1"]));
+                                         insertConfLine (uname, ruleNode, Server (ports, [":::1"])))
+                 | ProxiedServer ports => if (fn FirewallNode r => r) ruleNode = Slave.hostname () then
+                                              (insertConfLine (uname, ruleNode, Server (ports, ["$WEBNODES"]));
+                                               insertConfLine (uname, ruleNode, Client (ports, [fwnode_domain ruleNode])))
+                                          else (* we are a web server *)
+                                              (insertConfLine (uname, ruleNode, Client (ports, [fwnode_domain ruleNode]));
+                                               insertConfLine (User "www-data", ruleNode, Client (ports, [fwnode_domain ruleNode])))
+           end
 
        val _ = map insertConfLine (filter_node_rules rules)
     in
@@ -187,11 +193,9 @@ fun generateFirewallConfig rules =
     let
        val users_tcp_out_conf = TextIO.openOut (Config.Firewall.firewallDir ^ "/users_tcp_out.conf")
        val users_tcp_in_conf = TextIO.openOut (Config.Firewall.firewallDir ^ "/users_tcp_in.conf")
-       val user_chains_conf = TextIO.openOut (Config.Firewall.firewallDir ^ "/user_chains.conf")
 
        val users_tcp6_out_conf = TextIO.openOut (Config.Firewall.firewallDir ^ "/users_tcp6_out.conf")
        val users_tcp6_in_conf = TextIO.openOut (Config.Firewall.firewallDir ^ "/users_tcp6_in.conf")
-       val user_chains6_conf = TextIO.openOut (Config.Firewall.firewallDir ^ "/user_chains6.conf")
 
        val nodeFermRules = generateNodeFermRules rules
 
@@ -210,45 +214,39 @@ fun generateFirewallConfig rules =
            let
                val _ = SysWord.toInt (Posix.ProcEnv.uidToWord (Posix.SysDB.Passwd.uid (Posix.SysDB.getpwnam uname)))
            in
-               TextIO.output (tcp_inf, "proto tcp {\n");
+               TextIO.output (tcp_inf, "proto tcp mod comment comment \"user:" ^ uname ^ "\" {\n");
                TextIO.output (tcp_inf, concat lines);
                TextIO.output (tcp_inf, "\n}\n\n")
            end handle OS.SysErr _ => print "Invalid user in firewall config, skipping.\n" (* no sense in opening ports for bad users *)
 
-       fun writeUserOutRules tcp_outf chains_outf (uname, lines) =
+       fun writeUserOutRules tcp_outf (uname, lines) =
            let
                val uid = SysWord.toInt (Posix.ProcEnv.uidToWord (Posix.SysDB.Passwd.uid (Posix.SysDB.getpwnam uname)))
            in
-               TextIO.output (tcp_outf, "mod owner uid-owner " ^ (Int.toString uid)
-                                                  ^ " { jump user_" ^ uname ^ "_tcp_out"
-                                                  ^ "; DROP; }\n");
-
-               TextIO.output (chains_outf, "chain user_" ^ uname ^ "_tcp_out"
-                                                ^ " proto tcp {\n");
-               TextIO.output (chains_outf, concat lines);
-               TextIO.output (chains_outf, "\n}\n\n")
+               TextIO.output (tcp_outf, "mod owner uid-owner " ^ (Int.toString uid) ^ " mod comment comment \"user:" ^ uname ^ "\" proto tcp {\n");
+               TextIO.output (tcp_outf, concat lines);
+               TextIO.output (tcp_outf, "\nDROP;\n}\n\n")
            end handle OS.SysErr _ => print "Invalid user in firewall config, skipping.\n"
 
     in
        write_tcp_in_conf_preamble (users_tcp_in_conf);
-       StringMap.appi (writeUserOutRules users_tcp_out_conf user_chains_conf) (#output_rules nodeFermRules);
+       StringMap.appi (writeUserOutRules users_tcp_out_conf) (#output_rules nodeFermRules);
        StringMap.appi (writeUserInRules users_tcp_in_conf) (#input_rules nodeFermRules);
 
        write_tcp_in_conf_preamble (users_tcp6_in_conf);
-       StringMap.appi (writeUserOutRules users_tcp6_out_conf user_chains6_conf) (#output6_rules nodeFermRules);
+       StringMap.appi (writeUserOutRules users_tcp6_out_conf) (#output6_rules nodeFermRules);
        StringMap.appi (writeUserInRules users_tcp6_in_conf) (#input6_rules nodeFermRules);
 
-       TextIO.closeOut user_chains_conf;
        TextIO.closeOut users_tcp_out_conf;
        TextIO.closeOut users_tcp_in_conf;
 
-       TextIO.closeOut user_chains6_conf;
        TextIO.closeOut users_tcp6_out_conf;
        TextIO.closeOut users_tcp6_in_conf;
 
        true
     end
 
+
 fun publishConfig _ =
     Slave.shell [Config.Firewall.reload]
 end