📄 fw_iptables.c.svn-base
字号:
/* XXX: Why this? it means that connections setup after authentication stay open even after the connection is done... iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -m state --state RELATED,ESTABLISHED -j ACCEPT");*/ //Won't this rule NEVER match anyway?!?!? benoitg, 2007-06-23 //iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -i %s -m state --state NEW -j DROP", ext_interface); /* TCPMSS rule for PPPoE */ iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -o %s -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu", ext_interface); iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -j " TABLE_WIFIDOG_AUTHSERVERS); iptables_fw_set_authservers(); iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -m mark --mark 0x%u -j " TABLE_WIFIDOG_LOCKED, FW_MARK_LOCKED); iptables_load_ruleset("filter", "locked-users", TABLE_WIFIDOG_LOCKED); iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -j " TABLE_WIFIDOG_GLOBAL); iptables_load_ruleset("filter", "global", TABLE_WIFIDOG_GLOBAL); iptables_load_ruleset("nat", "global", TABLE_WIFIDOG_GLOBAL); iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -m mark --mark 0x%u -j " TABLE_WIFIDOG_VALIDATE, FW_MARK_PROBATION); iptables_load_ruleset("filter", "validating-users", TABLE_WIFIDOG_VALIDATE); iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -m mark --mark 0x%u -j " TABLE_WIFIDOG_KNOWN, FW_MARK_KNOWN); iptables_load_ruleset("filter", "known-users", TABLE_WIFIDOG_KNOWN); iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -j " TABLE_WIFIDOG_UNKNOWN); iptables_load_ruleset("filter", "unknown-users", TABLE_WIFIDOG_UNKNOWN); iptables_do_command("-t filter -A " TABLE_WIFIDOG_UNKNOWN " -j REJECT --reject-with icmp-port-unreachable"); free(gw_interface); free(gw_address); return 1;}/** Remove the firewall rules * This is used when we do a clean shutdown of WiFiDog and when it starts to make * sure there are no rules left over */intiptables_fw_destroy(void){ fw_quiet = 1; debug(LOG_DEBUG, "Destroying our iptables entries"); /* * * Everything in the MANGLE table * */ debug(LOG_DEBUG, "Destroying chains in the MANGLE table"); iptables_fw_destroy_mention("mangle", "PREROUTING", TABLE_WIFIDOG_TRUSTED); iptables_fw_destroy_mention("mangle", "PREROUTING", TABLE_WIFIDOG_OUTGOING); iptables_fw_destroy_mention("mangle", "POSTROUTING", TABLE_WIFIDOG_INCOMING); iptables_do_command("-t mangle -F " TABLE_WIFIDOG_TRUSTED); iptables_do_command("-t mangle -F " TABLE_WIFIDOG_OUTGOING); iptables_do_command("-t mangle -F " TABLE_WIFIDOG_INCOMING); iptables_do_command("-t mangle -X " TABLE_WIFIDOG_TRUSTED); iptables_do_command("-t mangle -X " TABLE_WIFIDOG_OUTGOING); iptables_do_command("-t mangle -X " TABLE_WIFIDOG_INCOMING); /* * * Everything in the NAT table * */ debug(LOG_DEBUG, "Destroying chains in the NAT table"); iptables_fw_destroy_mention("nat", "PREROUTING", TABLE_WIFIDOG_OUTGOING); iptables_do_command("-t nat -F " TABLE_WIFIDOG_AUTHSERVERS); iptables_do_command("-t nat -F " TABLE_WIFIDOG_OUTGOING); iptables_do_command("-t nat -F " TABLE_WIFIDOG_WIFI_TO_ROUTER); iptables_do_command("-t nat -F " TABLE_WIFIDOG_WIFI_TO_INTERNET); iptables_do_command("-t nat -F " TABLE_WIFIDOG_GLOBAL); iptables_do_command("-t nat -F " TABLE_WIFIDOG_UNKNOWN); iptables_do_command("-t nat -X " TABLE_WIFIDOG_AUTHSERVERS); iptables_do_command("-t nat -X " TABLE_WIFIDOG_OUTGOING); iptables_do_command("-t nat -X " TABLE_WIFIDOG_WIFI_TO_ROUTER); iptables_do_command("-t nat -X " TABLE_WIFIDOG_WIFI_TO_INTERNET); iptables_do_command("-t nat -X " TABLE_WIFIDOG_GLOBAL); iptables_do_command("-t nat -X " TABLE_WIFIDOG_UNKNOWN); /* * * Everything in the FILTER table * */ debug(LOG_DEBUG, "Destroying chains in the FILTER table"); iptables_fw_destroy_mention("filter", "FORWARD", TABLE_WIFIDOG_WIFI_TO_INTERNET); iptables_do_command("-t filter -F " TABLE_WIFIDOG_WIFI_TO_INTERNET); iptables_do_command("-t filter -F " TABLE_WIFIDOG_AUTHSERVERS); iptables_do_command("-t filter -F " TABLE_WIFIDOG_LOCKED); iptables_do_command("-t filter -F " TABLE_WIFIDOG_GLOBAL); iptables_do_command("-t filter -F " TABLE_WIFIDOG_VALIDATE); iptables_do_command("-t filter -F " TABLE_WIFIDOG_KNOWN); iptables_do_command("-t filter -F " TABLE_WIFIDOG_UNKNOWN); iptables_do_command("-t filter -X " TABLE_WIFIDOG_WIFI_TO_INTERNET); iptables_do_command("-t filter -X " TABLE_WIFIDOG_AUTHSERVERS); iptables_do_command("-t filter -X " TABLE_WIFIDOG_LOCKED); iptables_do_command("-t filter -X " TABLE_WIFIDOG_GLOBAL); iptables_do_command("-t filter -X " TABLE_WIFIDOG_VALIDATE); iptables_do_command("-t filter -X " TABLE_WIFIDOG_KNOWN); iptables_do_command("-t filter -X " TABLE_WIFIDOG_UNKNOWN); return 1;}/* * Helper for iptables_fw_destroy * @param table The table to search * @param chain The chain in that table to search * @param mention A word to find and delete in rules in the given table+chain */intiptables_fw_destroy_mention( char * table, char * chain, char * mention) { FILE *p = NULL; char *command = NULL; char *command2 = NULL; char line[MAX_BUF]; char rulenum[10]; int deleted = 0; debug(LOG_DEBUG, "Attempting to destroy all mention of %s from %s.%s", mention, table, chain); safe_asprintf(&command, "iptables -t %s -L %s -n --line-numbers -v", table, chain); if ((p = popen(command, "r"))) { /* Skip first 2 lines */ while (!feof(p) && fgetc(p) != '\n'); while (!feof(p) && fgetc(p) != '\n'); /* Loop over entries */ while (fgets(line, sizeof(line), p)) { /* Look for mention */ if (strstr(line, mention)) { /* Found mention - Get the rule number into rulenum*/ if (sscanf(line, "%9[0-9]", rulenum) == 1) { /* Delete the rule: */ debug(LOG_DEBUG, "Deleting rule %s from %s.%s because it mentions %s", rulenum, table, chain, mention); safe_asprintf(&command2, "-t %s -D %s %s", table, chain, rulenum); iptables_do_command(command2); free(command2); deleted = 1; /* Do not keep looping - the captured rulenums will no longer be accurate */ break; } } } pclose(p); } free(command); if (deleted) { /* Recurse just in case there are more in the same table+chain */ iptables_fw_destroy_mention(table, chain, mention); } return (deleted);}/** Set if a specific client has access through the firewall */intiptables_fw_access(fw_access_t type, char *ip, char *mac, int tag){ int rc; fw_quiet = 0; switch(type) { case FW_ACCESS_ALLOW: iptables_do_command("-t mangle -A " TABLE_WIFIDOG_OUTGOING " -s %s -m mac --mac-source %s -j MARK --set-mark %d", ip, mac, tag); rc = iptables_do_command("-t mangle -A " TABLE_WIFIDOG_INCOMING " -d %s -j ACCEPT", ip); break; case FW_ACCESS_DENY: iptables_do_command("-t mangle -D " TABLE_WIFIDOG_OUTGOING " -s %s -m mac --mac-source %s -j MARK --set-mark %d", ip, mac, tag); rc = iptables_do_command("-t mangle -D " TABLE_WIFIDOG_INCOMING " -d %s -j DROP", ip); break; default: rc = -1; break; } return rc;}/** Update the counters of all the clients in the client list */intiptables_fw_counters_update(void){ FILE *output; char *script, ip[16], rc; unsigned long long int counter; t_client *p1; struct in_addr tempaddr; /* Look for outgoing traffic */ safe_asprintf(&script, "%s %s", "iptables", "-v -n -x -t mangle -L " TABLE_WIFIDOG_OUTGOING); output = popen(script, "r"); free(script); if (!output) { debug(LOG_ERR, "popen(): %s", strerror(errno)); return -1; } /* skip the first two lines */ while (('\n' != fgetc(output)) && !feof(output)) ; while (('\n' != fgetc(output)) && !feof(output)) ; while (output && !(feof(output))) { rc = fscanf(output, "%*s %llu %*s %*s %*s %*s %*s %15[0-9.] %*s %*s %*s %*s %*s 0x%*u", &counter, ip); if (2 == rc && EOF != rc) { /* Sanity*/ if (!inet_aton(ip, &tempaddr)) { debug(LOG_WARNING, "I was supposed to read an IP address but instead got [%s] - ignoring it", ip); continue; } debug(LOG_DEBUG, "Read outgoing traffic for %s: Bytes=%llu", ip, counter); LOCK_CLIENT_LIST(); if ((p1 = client_list_find_by_ip(ip))) { if ((p1->counters.outgoing - p1->counters.outgoing_history) < counter) { p1->counters.outgoing = p1->counters.outgoing_history + counter; p1->counters.last_updated = time(NULL); debug(LOG_DEBUG, "%s - Updated counter.outgoing to %llu bytes. Updated last_updated to %d", ip, counter, p1->counters.last_updated); } } else { debug(LOG_ERR, "Could not find %s in client list", ip); } UNLOCK_CLIENT_LIST(); } } pclose(output); /* Look for incoming traffic */ safe_asprintf(&script, "%s %s", "iptables", "-v -n -x -t mangle -L " TABLE_WIFIDOG_INCOMING); output = popen(script, "r"); free(script); if (!output) { debug(LOG_ERR, "popen(): %s", strerror(errno)); return -1; } /* skip the first two lines */ while (('\n' != fgetc(output)) && !feof(output)) ; while (('\n' != fgetc(output)) && !feof(output)) ; while (output && !(feof(output))) { rc = fscanf(output, "%*s %llu %*s %*s %*s %*s %*s %*s %15[0-9.]", &counter, ip); if (2 == rc && EOF != rc) { /* Sanity*/ if (!inet_aton(ip, &tempaddr)) { debug(LOG_WARNING, "I was supposed to read an IP address but instead got [%s] - ignoring it", ip); continue; } debug(LOG_DEBUG, "Read incoming traffic for %s: Bytes=%llu", ip, counter); LOCK_CLIENT_LIST(); if ((p1 = client_list_find_by_ip(ip))) { if ((p1->counters.incoming - p1->counters.incoming_history) < counter) { p1->counters.incoming = p1->counters.incoming_history + counter; debug(LOG_DEBUG, "%s - Updated counter.incoming to %llu bytes", ip, counter); } } else { debug(LOG_ERR, "Could not find %s in client list", ip); } UNLOCK_CLIENT_LIST(); } } pclose(output); return 1;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -