📄 fw_iptables.c.svn-base
字号:
/********************************************************************\ * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License as * * published by the Free Software Foundation; either version 2 of * * the License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License* * along with this program; if not, contact: * * * * Free Software Foundation Voice: +1-617-542-5942 * * 59 Temple Place - Suite 330 Fax: +1-617-542-2652 * * Boston, MA 02111-1307, USA gnu@gnu.org * * * \********************************************************************//* $Id$ *//** @internal @file fw_iptables.c @brief Firewall iptables functions @author Copyright (C) 2004 Philippe April <papril777@yahoo.com> */#define _GNU_SOURCE#include <stdio.h>#include <stdlib.h>#include <stdarg.h>#include <syslog.h>#include <errno.h>#include <string.h>#include <pthread.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include "common.h"#include "safe.h"#include "conf.h"#include "fw_iptables.h"#include "firewall.h"#include "debug.h"#include "util.h"#include "client_list.h"static int iptables_do_command(char *format, ...);static char *iptables_compile(char *, char *, t_firewall_rule *);static void iptables_load_ruleset(char *, char *, char *);extern pthread_mutex_t client_list_mutex;extern pthread_mutex_t config_mutex;/**Used to supress the error output of the firewall during destruction */ static int fw_quiet = 0;/** @internal * */static intiptables_do_command(char *format, ...){ va_list vlist; char *fmt_cmd, *cmd; int rc; va_start(vlist, format); safe_vasprintf(&fmt_cmd, format, vlist); va_end(vlist); safe_asprintf(&cmd, "iptables %s", fmt_cmd); free(fmt_cmd); debug(LOG_DEBUG, "Executing command: %s", cmd); rc = execute(cmd, fw_quiet); free(cmd); return rc;}/** * @internal * Compiles a struct definition of a firewall rule into a valid iptables * command. * @arg table Table containing the chain. * @arg chain Chain that the command will be (-A)ppended to. * @arg rule Definition of a rule into a struct, from conf.c. */static char *iptables_compile(char * table, char *chain, t_firewall_rule *rule){ char command[MAX_BUF], *mode; memset(command, 0, MAX_BUF); if (rule->block_allow == 1) { mode = safe_strdup("ACCEPT"); } else { mode = safe_strdup("REJECT"); } snprintf(command, sizeof(command), "-t %s -A %s ",table, chain); if (rule->mask != NULL) { snprintf((command + strlen(command)), (sizeof(command) - strlen(command)), "-d %s ", rule->mask); } if (rule->protocol != NULL) { snprintf((command + strlen(command)), (sizeof(command) - strlen(command)), "-p %s ", rule->protocol); } if (rule->port != NULL) { snprintf((command + strlen(command)), (sizeof(command) - strlen(command)), "--dport %s ", rule->port); } snprintf((command + strlen(command)), (sizeof(command) - strlen(command)), "-j %s", mode); free(mode); /* XXX The buffer command, an automatic variable, will get cleaned * off of the stack when we return, so we strdup() it. */ return(safe_strdup(command));}/** * @internal * Load all the rules in a rule set. * @arg ruleset Name of the ruleset * @arg table Table containing the chain. * @arg chain IPTables chain the rules go into */static voidiptables_load_ruleset(char * table, char *ruleset, char *chain){ t_firewall_rule *rule; char *cmd; debug(LOG_DEBUG, "Load ruleset %s into table %s, chain %s", ruleset, table, chain); for (rule = get_ruleset(ruleset); rule != NULL; rule = rule->next) { cmd = iptables_compile(table, chain, rule); debug(LOG_DEBUG, "Loading rule \"%s\" into table %s, chain %s", cmd, table, chain); iptables_do_command(cmd); free(cmd); } debug(LOG_DEBUG, "Ruleset %s loaded into table %s, chain %s", ruleset, table, chain);}voidiptables_fw_clear_authservers(void){ iptables_do_command("-t filter -F " TABLE_WIFIDOG_AUTHSERVERS); iptables_do_command("-t nat -F " TABLE_WIFIDOG_AUTHSERVERS);}voidiptables_fw_set_authservers(void){ s_config *config; t_auth_serv *auth_server; config = config_get_config(); for (auth_server = config->auth_servers; auth_server != NULL; auth_server = auth_server->next) { if (auth_server->last_ip && strcmp(auth_server->last_ip, "0.0.0.0") != 0) { iptables_do_command("-t filter -A " TABLE_WIFIDOG_AUTHSERVERS " -d %s -j ACCEPT", auth_server->last_ip); iptables_do_command("-t nat -A " TABLE_WIFIDOG_AUTHSERVERS " -d %s -j ACCEPT", auth_server->last_ip); } }}/** Initialize the firewall rules */intiptables_fw_init(void){ s_config *config; char * gw_interface = NULL; char * gw_address = NULL; char * ext_interface = NULL; int gw_port = 0; t_trusted_mac *p; fw_quiet = 0; LOCK_CONFIG(); config = config_get_config(); gw_interface = safe_strdup(config->gw_interface); gw_address = safe_strdup(config->gw_address); gw_port = config->gw_port; if (config->external_interface) { ext_interface = safe_strdup(config->external_interface); } else { ext_interface = get_ext_iface(); } UNLOCK_CONFIG(); /* * * Everything in the MANGLE table * */ /* Create new chains */ iptables_do_command("-t mangle -N " TABLE_WIFIDOG_TRUSTED); iptables_do_command("-t mangle -N " TABLE_WIFIDOG_OUTGOING); iptables_do_command("-t mangle -N " TABLE_WIFIDOG_INCOMING); /* Assign links and rules to these new chains */ iptables_do_command("-t mangle -I PREROUTING 1 -i %s -j " TABLE_WIFIDOG_OUTGOING, gw_interface); iptables_do_command("-t mangle -I PREROUTING 1 -i %s -j " TABLE_WIFIDOG_TRUSTED, gw_interface);//this rule will be inserted before the prior one iptables_do_command("-t mangle -I POSTROUTING 1 -o %s -j " TABLE_WIFIDOG_INCOMING, gw_interface); for (p = config->trustedmaclist; p != NULL; p = p->next) iptables_do_command("-t mangle -A " TABLE_WIFIDOG_TRUSTED " -m mac --mac-source %s -j MARK --set-mark %d", p->mac, FW_MARK_KNOWN); /* * * Everything in the NAT table * */ /* Create new chains */ iptables_do_command("-t nat -N " TABLE_WIFIDOG_OUTGOING); iptables_do_command("-t nat -N " TABLE_WIFIDOG_WIFI_TO_ROUTER); iptables_do_command("-t nat -N " TABLE_WIFIDOG_WIFI_TO_INTERNET); iptables_do_command("-t nat -N " TABLE_WIFIDOG_GLOBAL); iptables_do_command("-t nat -N " TABLE_WIFIDOG_UNKNOWN); iptables_do_command("-t nat -N " TABLE_WIFIDOG_AUTHSERVERS); /* Assign links and rules to these new chains */ iptables_do_command("-t nat -A PREROUTING -i %s -j " TABLE_WIFIDOG_OUTGOING, gw_interface); iptables_do_command("-t nat -A " TABLE_WIFIDOG_OUTGOING " -d %s -j " TABLE_WIFIDOG_WIFI_TO_ROUTER, gw_address); iptables_do_command("-t nat -A " TABLE_WIFIDOG_WIFI_TO_ROUTER " -j ACCEPT"); iptables_do_command("-t nat -A " TABLE_WIFIDOG_OUTGOING " -j " TABLE_WIFIDOG_WIFI_TO_INTERNET); iptables_do_command("-t nat -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -m mark --mark 0x%u -j ACCEPT", FW_MARK_KNOWN); iptables_do_command("-t nat -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -m mark --mark 0x%u -j ACCEPT", FW_MARK_PROBATION); iptables_do_command("-t nat -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -j " TABLE_WIFIDOG_UNKNOWN); iptables_do_command("-t nat -A " TABLE_WIFIDOG_UNKNOWN " -j " TABLE_WIFIDOG_AUTHSERVERS); iptables_do_command("-t nat -A " TABLE_WIFIDOG_UNKNOWN " -j " TABLE_WIFIDOG_GLOBAL); iptables_do_command("-t nat -A " TABLE_WIFIDOG_UNKNOWN " -p tcp --dport 80 -j REDIRECT --to-ports %d", gw_port); /* * * Everything in the FILTER table * */ /* Create new chains */ iptables_do_command("-t filter -N " TABLE_WIFIDOG_WIFI_TO_INTERNET); iptables_do_command("-t filter -N " TABLE_WIFIDOG_AUTHSERVERS); iptables_do_command("-t filter -N " TABLE_WIFIDOG_LOCKED); iptables_do_command("-t filter -N " TABLE_WIFIDOG_GLOBAL); iptables_do_command("-t filter -N " TABLE_WIFIDOG_VALIDATE); iptables_do_command("-t filter -N " TABLE_WIFIDOG_KNOWN); iptables_do_command("-t filter -N " TABLE_WIFIDOG_UNKNOWN); /* Assign links and rules to these new chains */ /* Insert at the beginning */ iptables_do_command("-t filter -I FORWARD -i %s -j " TABLE_WIFIDOG_WIFI_TO_INTERNET, gw_interface); iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -m state --state INVALID -j DROP");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -