]> git.ipfire.org Git - ipfire-2.x.git/blobdiff - src/misc-progs/captivectrl.c
general-functions.pl: Add formatBytes() function.
[ipfire-2.x.git] / src / misc-progs / captivectrl.c
index 4d0059290b38bca1d365d84dd3b9df8d8c82c11d..56dd78db0542e48c2df7b880904485430b51a7a7 100644 (file)
@@ -142,6 +142,31 @@ static void flush_chains() {
        safe_system(IPTABLES " -t nat -F CAPTIVE_PORTAL");
 }
 
+static int setup_dns_filters() {
+       const char* protos[] = { "udp", "tcp", NULL };
+
+       // Limits the number of DNS requests to 3 kByte/s
+       // A burst of 1MB is permitted at the start
+       const char* limiter = "-m hashlimit --hashlimit-name dns-filter"
+               " --hashlimit-mode srcip --hashlimit-upto 3kb/sec --hashlimit-burst 1024kb";
+
+       char command[STRING_SIZE];
+
+       const char** proto = protos;
+       while (*proto) {
+               snprintf(command, sizeof(command), IPTABLES " -A CAPTIVE_PORTAL_CLIENTS -p %s"
+                       " --dport 53 %s -j RETURN", *proto, limiter);
+
+               int r = safe_system(command);
+               if (r)
+                       return r;
+
+               proto++;
+       }
+
+       return 0;
+}
+
 static int add_client_rules(const client_t* clients) {
        char command[STRING_SIZE];
        char match[STRING_SIZE];
@@ -212,14 +237,6 @@ static int add_interface_rule(const char* intf, int allow_webif_access) {
        if (r)
                return r;
 
-#if 0
-       snprintf(command, sizeof(command), IPTABLES " -A CAPTIVE_PORTAL -o %s"
-               " -j CAPTIVE_PORTAL_CLIENTS", intf);
-       r = safe_system(command);
-       if (r)
-               return r;
-#endif
-
        if (allow_webif_access) {
                snprintf(command, sizeof(command), IPTABLES " -A CAPTIVE_PORTAL_CLIENTS"
                        " -i %s -p tcp --dport 444 -j RETURN", intf);
@@ -235,6 +252,13 @@ static int add_interface_rule(const char* intf, int allow_webif_access) {
        if (r)
                return r;
 
+       // Allow access to captive portal site
+       snprintf(command, sizeof(command), IPTABLES " -A CAPTIVE_PORTAL_CLIENTS"
+               " -i %s -p tcp --dport %d -j RETURN", intf, REDIRECT_PORT);
+       r = safe_system(command);
+       if (r)
+               return r;
+
        return 0;
 }
 
@@ -264,18 +288,7 @@ static int add_interface_rules(struct keyvalue* captive_portal_settings, struct
        }
 
        // Always pass DNS packets through all firewall rules
-       r = safe_system(IPTABLES " -A CAPTIVE_PORTAL_CLIENTS -p udp --dport 53 -j RETURN");
-       if (r)
-               return r;
-
-       r = safe_system(IPTABLES " -A CAPTIVE_PORTAL_CLIENTS -p tcp --dport 53 -j RETURN");
-       if (r)
-               return r;
-
-       char command[STRING_SIZE];
-       snprintf(command, sizeof(command), IPTABLES " -A CAPTIVE_PORTAL_CLIENTS"
-               " -p tcp --dport %d -j RETURN", REDIRECT_PORT);
-       r = safe_system(command);
+       r = setup_dns_filters();
        if (r)
                return r;