Changeset 457

Show
Ignore:
Timestamp:
02/13/05 20:10:26 (8 years ago)
Author:
minaguib
Message:

Completely re-did the iptables rules. Most of the rules are now in the filter table instead of the nat table. Also DROPs are now replaced with REJECTs to help tell the user connection refused instead of endless pauses

Location:
trunk/wifidog
Files:
3 modified

Legend:

Unmodified
Added
Removed
  • trunk/wifidog/ChangeLog

    r450 r457  
    11# $Header$ 
     2 
     32005-02-13 Mina Naguib <mina@ilesansfil.org> 
     4        * Completely re-did the iptables rules.  Most of the rules are now in the 
     5        filter table instead of the nat table.  Also DROPs are now replaced with 
     6        REJECTs to help tell the user connection refused instead of endless pauses 
    27 
    382005-02-12 Mina Naguib <mina@ilesansfil.org> 
  • trunk/wifidog/src/fw_iptables.c

    r449 r457  
    9999        mode = strdup("ACCEPT"); 
    100100    } else { 
    101         mode = strdup("DROP"); 
    102     } 
    103      
    104     snprintf(command, sizeof(command),  "-t nat -A %s ", chain); 
     101        mode = strdup("REJECT"); 
     102    } 
     103     
     104    snprintf(command, sizeof(command),  "-t filter -A %s ", chain); 
    105105    if (rule->mask != NULL) { 
    106106        snprintf((command + strlen(command)), (sizeof(command) -  
     
    152152iptables_fw_clear_authservers(void) 
    153153{ 
    154     iptables_do_command("-t nat -F " TABLE_WIFIDOG_AUTHSERVERS); 
     154    iptables_do_command("-t filter -F " TABLE_WIFIDOG_AUTHSERVERS); 
    155155} 
    156156 
     
    167167    for (auth_server = config->auth_servers; auth_server != NULL; auth_server = auth_server->next) { 
    168168            if (auth_server->last_ip == NULL || strcmp(auth_server->last_ip, "0.0.0.0") == 0) { 
    169                 iptables_do_command("-t nat -A " TABLE_WIFIDOG_AUTHSERVERS " -d %s -j ACCEPT", auth_server->authserv_hostname); 
     169                iptables_do_command("-t filter -A " TABLE_WIFIDOG_AUTHSERVERS " -d %s -j ACCEPT", auth_server->authserv_hostname); 
    170170            } else { 
    171                 iptables_do_command("-t nat -A " TABLE_WIFIDOG_AUTHSERVERS " -d %s -j ACCEPT", auth_server->last_ip); 
     171                iptables_do_command("-t filter -A " TABLE_WIFIDOG_AUTHSERVERS " -d %s -j ACCEPT", auth_server->last_ip); 
    172172            } 
    173173    } 
     
    182182{ 
    183183    s_config *config; 
     184         char * gw_interface = NULL; 
     185         char * external_interface = NULL; 
     186         int gw_port = 0; 
    184187    
     188    fw_quiet = 0; 
     189 
    185190    config = config_get_config(); 
    186     fw_quiet = 0; 
    187      
    188     /* Create authservers table here instead of in iptables_fw_set_authservers 
    189      * so we only have to flush it and not destroy/create every time */ 
    190     iptables_do_command("-t nat -N " TABLE_WIFIDOG_AUTHSERVERS); 
    191  
    192     iptables_fw_set_authservers(); 
    193  
    194     LOCK_CONFIG(); 
    195      
    196     iptables_do_command("-t nat -N " TABLE_WIFIDOG_VALIDATE); 
    197     iptables_do_command("-t nat -A " TABLE_WIFIDOG_VALIDATE " -j " TABLE_WIFIDOG_AUTHSERVERS); 
    198     iptables_do_command("-t nat -A " TABLE_WIFIDOG_VALIDATE " -d %s -j ACCEPT", config->gw_address); 
    199  
    200     UNLOCK_CONFIG(); 
    201  
    202     /** Insert global rules BEFORE the "defaults" */ 
    203     iptables_load_ruleset("global", TABLE_WIFIDOG_VALIDATE); 
    204     iptables_load_ruleset("validating-users", TABLE_WIFIDOG_VALIDATE); 
    205  
    206     LOCK_CONFIG(); 
    207      
    208     iptables_do_command("-t nat -N " TABLE_WIFIDOG_UNKNOWN); 
    209     iptables_do_command("-t nat -A " TABLE_WIFIDOG_UNKNOWN " -j " TABLE_WIFIDOG_AUTHSERVERS); 
    210     iptables_do_command("-t nat -A " TABLE_WIFIDOG_UNKNOWN " -d %s -j ACCEPT", config->gw_address); 
    211  
    212     UNLOCK_CONFIG(); 
    213      
    214     /** Insert global rules BEFORE the "defaults" */ 
    215     iptables_load_ruleset("global", TABLE_WIFIDOG_UNKNOWN); 
    216     iptables_load_ruleset("unknown-users", TABLE_WIFIDOG_UNKNOWN); 
    217     LOCK_CONFIG(); 
    218  
    219     /* XXX If there's a rule in global for port 80, it overrides this. */ 
    220     iptables_do_command("-t nat -A " TABLE_WIFIDOG_UNKNOWN " -p tcp --dport 80 -j REDIRECT --to-ports %d", config->gw_port); 
    221     UNLOCK_CONFIG(); 
    222     iptables_do_command("-t nat -A " TABLE_WIFIDOG_UNKNOWN " -j DROP"); 
    223  
    224     iptables_do_command("-t nat -N " TABLE_WIFIDOG_KNOWN); 
    225     /* Insert global rules BEFORE the "defaults" */ 
    226     iptables_load_ruleset("global", TABLE_WIFIDOG_KNOWN); 
    227     iptables_load_ruleset("known-users", TABLE_WIFIDOG_KNOWN); 
    228  
    229     iptables_do_command("-t nat -N " TABLE_WIFIDOG_LOCKED); 
    230     iptables_load_ruleset("locked-users", TABLE_WIFIDOG_KNOWN); 
    231      
    232     iptables_do_command("-t nat -N " TABLE_WIFIDOG_CLASS); 
    233     LOCK_CONFIG(); 
    234     iptables_do_command("-t nat -A " TABLE_WIFIDOG_CLASS " -i %s -m mark --mark 0x%u -j " TABLE_WIFIDOG_VALIDATE, config->gw_interface, FW_MARK_PROBATION); 
    235     iptables_do_command("-t nat -A " TABLE_WIFIDOG_CLASS " -i %s -m mark --mark 0x%u -j " TABLE_WIFIDOG_KNOWN, config->gw_interface, FW_MARK_KNOWN); 
    236     iptables_do_command("-t nat -A " TABLE_WIFIDOG_CLASS " -i %s -m mark --mark 0x%u -j " TABLE_WIFIDOG_LOCKED, config->gw_interface, FW_MARK_LOCKED); 
    237     iptables_do_command("-t nat -A " TABLE_WIFIDOG_CLASS " -i %s -j " TABLE_WIFIDOG_UNKNOWN, config->gw_interface); 
    238     iptables_do_command("-t nat -I PREROUTING 1 -i %s -j " TABLE_WIFIDOG_CLASS, config->gw_interface); 
    239  
    240     iptables_do_command("-t mangle -N " TABLE_WIFIDOG_OUTGOING); 
    241     iptables_do_command("-t mangle -I PREROUTING 1 -i %s -j " TABLE_WIFIDOG_OUTGOING, config->gw_interface); 
    242  
    243     iptables_do_command("-t mangle -N " TABLE_WIFIDOG_INCOMING); 
    244     if (config->external_interface) { 
    245         iptables_do_command("-t mangle -I FORWARD 1 -i %s -j " TABLE_WIFIDOG_INCOMING, config->external_interface); 
    246     } else { 
    247         iptables_do_command("-t mangle -I FORWARD 1 -j " TABLE_WIFIDOG_INCOMING); 
    248     } 
    249  
    250     iptables_do_command("-t filter -N " TABLE_WIFIDOG_WIFI_TO_GW); 
    251     iptables_do_command("-t filter -I INPUT 1 -i %s -j " TABLE_WIFIDOG_WIFI_TO_GW, config->gw_interface); 
    252  
    253     UNLOCK_CONFIG(); 
    254      
     191         LOCK_CONFIG(); 
     192         if (config->gw_interface) 
     193                 gw_interface = strdup(config->gw_interface); 
     194         if (config->external_interface) 
     195                 external_interface = strdup(config->external_interface); 
     196         gw_port = config->gw_port; 
     197         UNLOCK_CONFIG(); 
     198     
     199         /* 
     200          * 
     201          * Everything in the MANGLE table 
     202          * 
     203          */ 
     204 
     205                        /* Create new chains */ 
     206                        iptables_do_command("-t mangle -N " TABLE_WIFIDOG_OUTGOING); 
     207                        iptables_do_command("-t mangle -N " TABLE_WIFIDOG_INCOMING); 
     208 
     209                        /* Assign links and rules to these new chains */ 
     210                        iptables_do_command("-t mangle -I PREROUTING 1 -i %s -j " TABLE_WIFIDOG_OUTGOING, gw_interface); 
     211 
     212                        if (external_interface) { 
     213                                iptables_do_command("-t mangle -I FORWARD 1 -i %s -j " TABLE_WIFIDOG_INCOMING, external_interface); 
     214                        } 
     215                        else { 
     216                                iptables_do_command("-t mangle -I FORWARD 1 -j " TABLE_WIFIDOG_INCOMING); 
     217                        } 
     218 
     219 
     220         /* 
     221          * 
     222          * Everything in the NAT table 
     223          * 
     224          */ 
     225 
     226                        /* Create new chains */ 
     227                        iptables_do_command("-t nat -N " TABLE_WIFIDOG_WIFI_TO_INTERNET); 
     228                        iptables_do_command("-t nat -N " TABLE_WIFIDOG_UNKNOWN); 
     229 
     230                        /* Assign links and rules to these new chains */ 
     231                        if (external_interface) { 
     232                                iptables_do_command("-t nat -I PREROUTING 1 -i %s -j " TABLE_WIFIDOG_WIFI_TO_INTERNET, gw_interface); 
     233                        } 
     234                        else { 
     235                                iptables_do_command("-t nat -I PREROUTING 1 -j " TABLE_WIFIDOG_WIFI_TO_INTERNET); 
     236                        } 
     237 
     238                        iptables_do_command("-t nat -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -m mark --mark 0x%u -j RETURN", FW_MARK_KNOWN); 
     239                        iptables_do_command("-t nat -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -m mark --mark 0x%u -j RETURN", FW_MARK_PROBATION); 
     240                        iptables_do_command("-t nat -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -j " TABLE_WIFIDOG_UNKNOWN); 
     241                        iptables_do_command("-t nat -A " TABLE_WIFIDOG_UNKNOWN " -p tcp --dport 80 -j REDIRECT --to-ports %d", gw_port); 
     242 
     243 
     244         /* 
     245          * 
     246          * Everything in the FILTER table 
     247          * 
     248          */ 
     249 
     250                        /* Create new chains */ 
     251                        iptables_do_command("-t filter -N " TABLE_WIFIDOG_WIFI_TO_GW); 
     252                        iptables_do_command("-t filter -N " TABLE_WIFIDOG_WIFI_TO_INTERNET); 
     253                        iptables_do_command("-t filter -N " TABLE_WIFIDOG_AUTHSERVERS); 
     254                        iptables_do_command("-t filter -N " TABLE_WIFIDOG_LOCKED); 
     255                        iptables_do_command("-t filter -N " TABLE_WIFIDOG_GLOBAL); 
     256                        iptables_do_command("-t filter -N " TABLE_WIFIDOG_VALIDATE); 
     257                        iptables_do_command("-t filter -N " TABLE_WIFIDOG_KNOWN); 
     258                        iptables_do_command("-t filter -N " TABLE_WIFIDOG_UNKNOWN); 
     259 
     260                        /* Assign links and rules to these new chains */ 
     261                        iptables_do_command("-t filter -I INPUT 1 -i %s -j " TABLE_WIFIDOG_WIFI_TO_GW, gw_interface); 
     262 
     263                        if (external_interface) { 
     264                                iptables_do_command("-t filter -I FORWARD 1 -i %s -j " TABLE_WIFIDOG_WIFI_TO_INTERNET, gw_interface); 
     265                        } 
     266                        else { 
     267                                iptables_do_command("-t filter -I FORWARD 1 -j " TABLE_WIFIDOG_WIFI_TO_INTERNET); 
     268                        } 
     269 
     270                        iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -j " TABLE_WIFIDOG_AUTHSERVERS); 
     271                        iptables_fw_set_authservers(); 
     272 
     273                        iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -m mark --mark 0x%u -j " TABLE_WIFIDOG_LOCKED, FW_MARK_LOCKED); 
     274                        iptables_load_ruleset("locked-users", TABLE_WIFIDOG_LOCKED); 
     275 
     276                        iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -j " TABLE_WIFIDOG_GLOBAL); 
     277                        iptables_load_ruleset("global", TABLE_WIFIDOG_GLOBAL); 
     278 
     279                        iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -m mark --mark 0x%u -j " TABLE_WIFIDOG_VALIDATE, FW_MARK_PROBATION); 
     280                        iptables_load_ruleset("validating-users", TABLE_WIFIDOG_VALIDATE); 
     281 
     282                        iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -m mark --mark 0x%u -j " TABLE_WIFIDOG_KNOWN, FW_MARK_KNOWN); 
     283                        iptables_load_ruleset("known-users", TABLE_WIFIDOG_KNOWN); 
     284     
     285                        iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -j " TABLE_WIFIDOG_UNKNOWN); 
     286                        iptables_load_ruleset("unknown-users", TABLE_WIFIDOG_UNKNOWN); 
     287                        iptables_do_command("-t filter -A " TABLE_WIFIDOG_UNKNOWN " -j REJECT --reject-with icmp-port-unreachable"); 
     288 
     289        if (gw_interface) 
     290                free(gw_interface); 
     291        if (external_interface) 
     292                free(external_interface); 
     293 
    255294    return 1; 
    256295} 
     
    263302iptables_fw_destroy(void) 
    264303{ 
    265     int rc; 
    266     s_config *config = config_get_config(); 
    267  
    268304    fw_quiet = 1; 
    269     iptables_do_command("-t filter -F " TABLE_WIFIDOG_WIFI_TO_GW); 
    270     iptables_do_command("-t nat -F " TABLE_WIFIDOG_CLASS); 
     305 
     306         /* 
     307          * 
     308          * Everything in the MANGLE table 
     309          * 
     310          */ 
     311         iptables_fw_destroy_mention("mangle", "PREROUTING", TABLE_WIFIDOG_OUTGOING); 
     312         iptables_fw_destroy_mention("mangle", "FORWARD", TABLE_WIFIDOG_INCOMING); 
    271313    iptables_do_command("-t mangle -F " TABLE_WIFIDOG_OUTGOING); 
    272314    iptables_do_command("-t mangle -F " TABLE_WIFIDOG_INCOMING); 
    273  
    274     iptables_do_command("-t nat -F " TABLE_WIFIDOG_AUTHSERVERS); 
    275     iptables_do_command("-t nat -F " TABLE_WIFIDOG_VALIDATE); 
     315    iptables_do_command("-t mangle -X " TABLE_WIFIDOG_OUTGOING); 
     316    iptables_do_command("-t mangle -X " TABLE_WIFIDOG_INCOMING); 
     317 
     318         /* 
     319          * 
     320          * Everything in the NAT table 
     321          * 
     322          */ 
     323         iptables_fw_destroy_mention("nat", "PREROUTING", TABLE_WIFIDOG_WIFI_TO_INTERNET); 
     324    iptables_do_command("-t nat -F " TABLE_WIFIDOG_WIFI_TO_INTERNET); 
    276325    iptables_do_command("-t nat -F " TABLE_WIFIDOG_UNKNOWN); 
    277     iptables_do_command("-t nat -F " TABLE_WIFIDOG_KNOWN); 
    278     iptables_do_command("-t nat -F " TABLE_WIFIDOG_LOCKED); 
    279     iptables_do_command("-t nat -X " TABLE_WIFIDOG_AUTHSERVERS); 
    280     iptables_do_command("-t nat -X " TABLE_WIFIDOG_VALIDATE); 
     326    iptables_do_command("-t nat -X " TABLE_WIFIDOG_WIFI_TO_INTERNET); 
    281327    iptables_do_command("-t nat -X " TABLE_WIFIDOG_UNKNOWN); 
    282     iptables_do_command("-t nat -X " TABLE_WIFIDOG_KNOWN); 
    283     iptables_do_command("-t nat -X " TABLE_WIFIDOG_LOCKED); 
    284  
    285     /* We loop in case wifidog has crashed and left some unwanted rules, 
    286      * maybe we shouldn't loop forever, we'll try anyway 
    287      */ 
    288     rc = 0; 
    289     while (rc == 0) { 
    290         rc = iptables_do_command("-t nat -D PREROUTING -i %s -j " TABLE_WIFIDOG_CLASS, config->gw_interface); 
    291     } 
    292     iptables_do_command("-t nat -X " TABLE_WIFIDOG_CLASS); 
    293  
    294     rc = 0; 
    295     while (rc == 0) { 
    296         rc = iptables_do_command("-t filter -D INPUT -i %s -j " TABLE_WIFIDOG_WIFI_TO_GW, config->gw_interface); 
    297     } 
    298     iptables_do_command("-t filter -X " TABLE_WIFIDOG_WIFI_TO_GW); 
    299  
    300     rc = 0; 
    301     while (rc == 0) { 
    302         rc = iptables_do_command("-t mangle -D PREROUTING -i %s -j " TABLE_WIFIDOG_OUTGOING, config->gw_interface); 
    303     } 
    304     iptables_do_command("-t mangle -X " TABLE_WIFIDOG_OUTGOING); 
    305  
    306     rc = 0; 
    307     while (rc == 0) { 
    308         if (config->external_interface) { 
    309             rc = iptables_do_command("-t mangle -D FORWARD -i %s -j " TABLE_WIFIDOG_INCOMING, config->external_interface); 
    310         } else { 
    311             rc = iptables_do_command("-t mangle -D FORWARD -j " TABLE_WIFIDOG_INCOMING); 
    312         } 
    313     } 
    314     iptables_do_command("-t mangle -X " TABLE_WIFIDOG_INCOMING); 
     328 
     329         /* 
     330          * 
     331          * Everything in the FILTER table 
     332          * 
     333          */ 
     334         iptables_fw_destroy_mention("filter", "INPUT", TABLE_WIFIDOG_WIFI_TO_GW); 
     335         iptables_fw_destroy_mention("filter", "FORWARD", TABLE_WIFIDOG_WIFI_TO_INTERNET); 
     336         iptables_do_command("-t filter -F " TABLE_WIFIDOG_WIFI_TO_GW); 
     337         iptables_do_command("-t filter -F " TABLE_WIFIDOG_WIFI_TO_INTERNET); 
     338         iptables_do_command("-t filter -F " TABLE_WIFIDOG_AUTHSERVERS); 
     339         iptables_do_command("-t filter -F " TABLE_WIFIDOG_LOCKED); 
     340         iptables_do_command("-t filter -F " TABLE_WIFIDOG_GLOBAL); 
     341         iptables_do_command("-t filter -F " TABLE_WIFIDOG_VALIDATE); 
     342         iptables_do_command("-t filter -F " TABLE_WIFIDOG_KNOWN); 
     343         iptables_do_command("-t filter -F " TABLE_WIFIDOG_UNKNOWN); 
     344         iptables_do_command("-t filter -X " TABLE_WIFIDOG_WIFI_TO_GW); 
     345         iptables_do_command("-t filter -X " TABLE_WIFIDOG_WIFI_TO_INTERNET); 
     346         iptables_do_command("-t filter -X " TABLE_WIFIDOG_AUTHSERVERS); 
     347         iptables_do_command("-t filter -X " TABLE_WIFIDOG_LOCKED); 
     348         iptables_do_command("-t filter -X " TABLE_WIFIDOG_GLOBAL); 
     349         iptables_do_command("-t filter -X " TABLE_WIFIDOG_VALIDATE); 
     350         iptables_do_command("-t filter -X " TABLE_WIFIDOG_KNOWN); 
     351         iptables_do_command("-t filter -X " TABLE_WIFIDOG_UNKNOWN); 
    315352 
    316353    return 1; 
     354} 
     355 
     356/* 
     357 * Helper for iptables_fw_destroy 
     358 * @param table The table to search 
     359 * @param chain The chain in that table to search 
     360 * @param mention A word to find and delete in rules in the given table+chain 
     361 */ 
     362int 
     363iptables_fw_destroy_mention( 
     364                char * table, 
     365                char * chain, 
     366                char * mention 
     367) { 
     368        FILE *p = NULL; 
     369        char *command = NULL; 
     370        char *command2 = NULL; 
     371        char line[MAX_BUF]; 
     372        char rulenum[10]; 
     373        int deleted = 0; 
     374 
     375        asprintf(&command, "iptables -t %s -L %s -n --line-numbers -v", table, chain); 
     376 
     377        if ((p = popen(command, "r"))) { 
     378                /* Skip first 2 lines */ 
     379                while (!feof(p) && fgetc(p) != '\n'); 
     380                while (!feof(p) && fgetc(p) != '\n'); 
     381                /* Loop over entries */ 
     382                while (fgets(line, sizeof(line), p)) { 
     383                        /* Look for mention */ 
     384                        if (strstr(line, mention)) { 
     385                                /* Found mention - Get the rule number into rulenum*/ 
     386                                if (sscanf(line, "%9[0-9]", rulenum) == 1) { 
     387                                        /* Delete the rule: */ 
     388                                        asprintf(&command2, "-t %s -D %s %s", table, chain, rulenum); 
     389                                        iptables_do_command(command2); 
     390                                        free(command2); 
     391                                        deleted = 1; 
     392                                        /* Do not keep looping - the captures rulenums will no longer be accurate */ 
     393                                        break; 
     394                                } 
     395                        } 
     396                } 
     397                pclose(p); 
     398        } 
     399 
     400        free(command); 
     401 
     402        if (deleted) { 
     403                /* Recurse just in case there are more in the same table+chain */ 
     404                iptables_fw_destroy_mention(table, chain, mention); 
     405        } 
     406 
     407        return (deleted); 
    317408} 
    318409 
  • trunk/wifidog/src/fw_iptables.h

    r422 r457  
    3232/*@{*/  
    3333/**Iptable table names used by WifiDog */ 
    34 #define TABLE_WIFIDOG_CLASS     "WiFiDog_Class" 
    3534#define TABLE_WIFIDOG_OUTGOING  "WiFiDog_Outgoing" 
    3635#define TABLE_WIFIDOG_WIFI_TO_GW "WiFiDog_WIFI2GW" 
     36#define TABLE_WIFIDOG_WIFI_TO_INTERNET "WiFiDog_WIFI2Internet" 
    3737#define TABLE_WIFIDOG_INCOMING  "WiFiDog_Incoming" 
    3838#define TABLE_WIFIDOG_AUTHSERVERS "WiFiDog_AuthServers" 
     39#define TABLE_WIFIDOG_GLOBAL  "WiFiDog_Global" 
    3940#define TABLE_WIFIDOG_VALIDATE  "WiFiDog_Validate" 
    4041#define TABLE_WIFIDOG_KNOWN     "WiFiDog_Known" 
     
    6162int iptables_fw_destroy(void); 
    6263 
     64/** @brief Helper function for iptables_fw_destroy */ 
     65int iptables_fw_destroy_mention( char * table, char * chain, char * mention); 
     66 
    6367/** @brief Define the access of a specific client */ 
    6468int iptables_fw_access(fw_access_t type, char *ip, char *mac, int tag);