]> git.ipfire.org Git - ipfire-2.x.git/blobdiff - src/misc-progs/captivectrl.c
IDS: Rename sourcefire VRT rulesets to Talos VRT rulesets
[ipfire-2.x.git] / src / misc-progs / captivectrl.c
index 1ca2a59117d110ba4843a93af0fd4b0768688303..56dd78db0542e48c2df7b880904485430b51a7a7 100644 (file)
@@ -71,6 +71,10 @@ static client_t* read_clients(char* filename) {
                if (line[strlen(line) - 1] == '\n')
                        line[strlen(line) - 1] = '\0';
 
+               // Skip all commented lines
+               if (*line == '#')
+                       continue;
+
                client_curr = (client_t*)malloc(sizeof(client_t));
                memset(client_curr, 0, sizeof(client_t));
 
@@ -138,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];
@@ -208,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);
@@ -231,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;
 }
 
@@ -260,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;
 
@@ -288,17 +305,20 @@ int main(int argc, char** argv) {
        char* intf = NULL;
        client_t* clients = NULL;
 
+       struct keyvalue* captive_portal_settings = NULL;
+       struct keyvalue* ethernet_settings = NULL;
+
        if (!(initsetuid()))
                exit(2);
 
-       struct keyvalue* ethernet_settings = initkeyvalues();
+       ethernet_settings = initkeyvalues();
        if (!readkeyvalues(ethernet_settings, ETHERNET_SETTINGS)) {
                fprintf(stderr, "Could not read %s\n", ETHERNET_SETTINGS);
                r = 1;
                goto END;
        }
 
-       struct keyvalue* captive_portal_settings = initkeyvalues();
+       captive_portal_settings = initkeyvalues();
        if (!readkeyvalues(captive_portal_settings, CAPTIVE_PORTAL_SETTINGS)) {
                fprintf(stderr, "Could not read %s\n", CAPTIVE_PORTAL_SETTINGS);
                r = 1;