From fc5535f38fb7bba873806492f34850ff131d33a7 Mon Sep 17 00:00:00 2001 From: Neutron Soutmun Date: Thu, 7 May 2015 01:09:43 +0700 Subject: [PATCH 1/2] Add MarkOffsetBits to support the qos-scripts to work together * The qos-scripts using 8 bits marks (0x01 - 0xff) for their classification purpose which it has overlapped with the wifidog marks. Therefore, MarkOffsetBits should be specified in the config file for the proper offset, in this case of the qos-scripts is 8 bits and the wifidog mark then left shifted as below, 0x1 => 0x100 0x2 => 0x200 0xfe => 0xfe00 The default value of MarkOffsetBits is 0 that is no offset. --- src/conf.c | 7 ++++++ src/conf.h | 3 +++ src/fw_iptables.c | 54 ++++++++++++++++++++++++++++++++--------------- 3 files changed, 47 insertions(+), 17 deletions(-) diff --git a/src/conf.c b/src/conf.c index e5012961..dcd71a45 100644 --- a/src/conf.c +++ b/src/conf.c @@ -102,6 +102,7 @@ typedef enum { oSSLPeerVerification, oSSLCertPath, oSSLAllowedCipherList, + oMarkOffsetBits, } OpCodes; /** @internal @@ -147,6 +148,7 @@ static const struct { "sslpeerverification", oSSLPeerVerification}, { "sslcertpath", oSSLCertPath}, { "sslallowedcipherlist", oSSLAllowedCipherList}, { + "markoffsetbits", oMarkOffsetBits}, { NULL, oBadOption},}; static void config_notnull(const void *, const char *); @@ -201,6 +203,7 @@ config_init(void) config.ssl_verify = DEFAULT_AUTHSERVSSLPEERVER; config.ssl_cipher_list = NULL; config.arp_table_path = safe_strdup(DEFAULT_ARPTABLE); + config.markoffsetbits = DEFAULT_MARKOFFSETBITS; debugconf.log_stderr = 1; debugconf.debuglevel = DEFAULT_DEBUGLEVEL; @@ -785,6 +788,10 @@ config_read(const char *filename) debug(LOG_WARNING, "SSLAllowedCipherList is set but no SSL compiled in. Ignoring!"); #endif break; + case oMarkOffsetBits: + sscanf(p1, "%u", &config.markoffsetbits); + config.markoffsetbits = config.markoffsetbits > 31 ? 0 : config.markoffsetbits; + break; case oBadOption: /* FALL THROUGH */ default: diff --git a/src/conf.h b/src/conf.h index 6200cd68..6316ba6c 100644 --- a/src/conf.h +++ b/src/conf.h @@ -67,6 +67,7 @@ #define DEFAULT_AUTHSERVSSLPEERVER 1 /* 0 means: Enable peer verification */ #define DEFAULT_ARPTABLE "/proc/net/arp" /*@}*/ +#define DEFAULT_MARKOFFSETBITS 0 /*@{*/ /** Defines for firewall rule sets. */ @@ -192,6 +193,8 @@ typedef struct { char *arp_table_path; /**< @brief Path to custom ARP table, formatted like /proc/net/arp */ t_popular_server *popular_servers; /**< @brief list of popular servers */ + unsigned int markoffsetbits; /**< @brief bits, left shifted mark values + for n bits */ } s_config; /** @brief Get the current gateway configuration */ diff --git a/src/fw_iptables.c b/src/fw_iptables.c index f526aa8a..943a7a15 100644 --- a/src/fw_iptables.c +++ b/src/fw_iptables.c @@ -287,8 +287,8 @@ iptables_fw_init(void) iptables_do_command("-t mangle -I POSTROUTING 1 -o %s -j " CHAIN_INCOMING, config->gw_interface); for (p = config->trustedmaclist; p != NULL; p = p->next) - iptables_do_command("-t mangle -A " CHAIN_TRUSTED " -m mac --mac-source %s -j MARK --set-mark %d", p->mac, - FW_MARK_KNOWN); + iptables_do_command("-t mangle -A " CHAIN_TRUSTED " -m mac --mac-source %s -j MARK --set-mark 0x%x", p->mac, + FW_MARK_KNOWN << config->markoffsetbits); /* * @@ -317,22 +317,32 @@ iptables_fw_init(void) if ((proxy_port = config_get_config()->proxy_port) != 0) { debug(LOG_DEBUG, "Proxy port set, setting proxy rule"); iptables_do_command("-t nat -A " CHAIN_TO_INTERNET - " -p tcp --dport 80 -m mark --mark 0x%u -j REDIRECT --to-port %u", FW_MARK_KNOWN, + " -p tcp --dport 80 -m mark --mark 0x%x/0x%x -j REDIRECT --to-port %u", + FW_MARK_KNOWN << config->markoffsetbits, + FW_MARK_KNOWN << config->markoffsetbits, proxy_port); iptables_do_command("-t nat -A " CHAIN_TO_INTERNET - " -p tcp --dport 80 -m mark --mark 0x%u -j REDIRECT --to-port %u", FW_MARK_PROBATION, + " -p tcp --dport 80 -m mark --mark 0x%x/0x%x -j REDIRECT --to-port %u", + FW_MARK_PROBATION << config->markoffsetbits, + FW_MARK_PROBATION << config->markoffsetbits, proxy_port); } - iptables_do_command("-t nat -A " CHAIN_TO_INTERNET " -m mark --mark 0x%u -j ACCEPT", FW_MARK_KNOWN); - iptables_do_command("-t nat -A " CHAIN_TO_INTERNET " -m mark --mark 0x%u -j ACCEPT", FW_MARK_PROBATION); + iptables_do_command("-t nat -A " CHAIN_TO_INTERNET " -m mark --mark 0x%x/0x%x -j ACCEPT", + FW_MARK_KNOWN << config->markoffsetbits, + FW_MARK_KNOWN << config->markoffsetbits); + iptables_do_command("-t nat -A " CHAIN_TO_INTERNET " -m mark --mark 0x%x/0x%x -j ACCEPT", + FW_MARK_PROBATION << config->markoffsetbits, + FW_MARK_PROBATION << config->markoffsetbits); iptables_do_command("-t nat -A " CHAIN_TO_INTERNET " -j " CHAIN_UNKNOWN); iptables_do_command("-t nat -A " CHAIN_UNKNOWN " -j " CHAIN_AUTHSERVERS); iptables_do_command("-t nat -A " CHAIN_UNKNOWN " -j " CHAIN_GLOBAL); if (got_authdown_ruleset) { iptables_do_command("-t nat -A " CHAIN_UNKNOWN " -j " CHAIN_AUTH_IS_DOWN); - iptables_do_command("-t nat -A " CHAIN_AUTH_IS_DOWN " -m mark --mark 0x%u -j ACCEPT", FW_MARK_AUTH_IS_DOWN); + iptables_do_command("-t nat -A " CHAIN_AUTH_IS_DOWN " -m mark --mark 0x%x/0x%x -j ACCEPT", + FW_MARK_AUTH_IS_DOWN << config->markoffsetbits, + FW_MARK_AUTH_IS_DOWN << config->markoffsetbits); } iptables_do_command("-t nat -A " CHAIN_UNKNOWN " -p tcp --dport 80 -j REDIRECT --to-ports %d", gw_port); @@ -374,22 +384,29 @@ iptables_fw_init(void) iptables_do_command("-t filter -A " CHAIN_TO_INTERNET " -j " CHAIN_AUTHSERVERS); iptables_fw_set_authservers(); - iptables_do_command("-t filter -A " CHAIN_TO_INTERNET " -m mark --mark 0x%u -j " CHAIN_LOCKED, FW_MARK_LOCKED); + iptables_do_command("-t filter -A " CHAIN_TO_INTERNET " -m mark --mark 0x%x/0x%x -j " CHAIN_LOCKED, + FW_MARK_LOCKED << config->markoffsetbits, + FW_MARK_LOCKED << config->markoffsetbits); iptables_load_ruleset("filter", FWRULESET_LOCKED_USERS, CHAIN_LOCKED); iptables_do_command("-t filter -A " CHAIN_TO_INTERNET " -j " CHAIN_GLOBAL); iptables_load_ruleset("filter", FWRULESET_GLOBAL, CHAIN_GLOBAL); iptables_load_ruleset("nat", FWRULESET_GLOBAL, CHAIN_GLOBAL); - iptables_do_command("-t filter -A " CHAIN_TO_INTERNET " -m mark --mark 0x%u -j " CHAIN_VALIDATE, FW_MARK_PROBATION); + iptables_do_command("-t filter -A " CHAIN_TO_INTERNET " -m mark --mark 0x%x/0x%x -j " CHAIN_VALIDATE, + FW_MARK_PROBATION << config->markoffsetbits, + FW_MARK_PROBATION << config->markoffsetbits); iptables_load_ruleset("filter", FWRULESET_VALIDATING_USERS, CHAIN_VALIDATE); - iptables_do_command("-t filter -A " CHAIN_TO_INTERNET " -m mark --mark 0x%u -j " CHAIN_KNOWN, FW_MARK_KNOWN); + iptables_do_command("-t filter -A " CHAIN_TO_INTERNET " -m mark --mark 0x%x/0x%x -j " CHAIN_KNOWN, + FW_MARK_KNOWN << config->markoffsetbits, + FW_MARK_KNOWN << config->markoffsetbits); iptables_load_ruleset("filter", FWRULESET_KNOWN_USERS, CHAIN_KNOWN); if (got_authdown_ruleset) { - iptables_do_command("-t filter -A " CHAIN_TO_INTERNET " -m mark --mark 0x%u -j " CHAIN_AUTH_IS_DOWN, - FW_MARK_AUTH_IS_DOWN); + iptables_do_command("-t filter -A " CHAIN_TO_INTERNET " -m mark --mark 0x%x/0x%x -j " CHAIN_AUTH_IS_DOWN, + FW_MARK_AUTH_IS_DOWN << config->markoffsetbits, + FW_MARK_AUTH_IS_DOWN << config->markoffsetbits); iptables_load_ruleset("filter", FWRULESET_AUTH_IS_DOWN, CHAIN_AUTH_IS_DOWN); } @@ -554,20 +571,21 @@ iptables_fw_destroy_mention(const char *table, const char *chain, const char *me int iptables_fw_access(fw_access_t type, const char *ip, const char *mac, int tag) { + const s_config *config = config_get_config (); int rc; fw_quiet = 0; switch (type) { case FW_ACCESS_ALLOW: - iptables_do_command("-t mangle -A " CHAIN_OUTGOING " -s %s -m mac --mac-source %s -j MARK --set-mark %d", ip, - mac, tag); + iptables_do_command("-t mangle -A " CHAIN_OUTGOING " -s %s -m mac --mac-source %s -j MARK --set-mark 0x%x", ip, + mac, tag << config->markoffsetbits); rc = iptables_do_command("-t mangle -A " CHAIN_INCOMING " -d %s -j ACCEPT", ip); break; case FW_ACCESS_DENY: /* XXX Add looping to really clear? */ - iptables_do_command("-t mangle -D " CHAIN_OUTGOING " -s %s -m mac --mac-source %s -j MARK --set-mark %d", ip, - mac, tag); + iptables_do_command("-t mangle -D " CHAIN_OUTGOING " -s %s -m mac --mac-source %s -j MARK --set-mark 0x%x", ip, + mac, tag << config->markoffsetbits); rc = iptables_do_command("-t mangle -D " CHAIN_INCOMING " -d %s -j ACCEPT", ip); break; default: @@ -606,9 +624,11 @@ iptables_fw_access_host(fw_access_t type, const char *host) int iptables_fw_auth_unreachable(int tag) { + const s_config *config = config_get_config (); int got_authdown_ruleset = NULL == get_ruleset(FWRULESET_AUTH_IS_DOWN) ? 0 : 1; if (got_authdown_ruleset) - return iptables_do_command("-t mangle -A " CHAIN_AUTH_IS_DOWN " -j MARK --set-mark 0x%u", tag); + return iptables_do_command("-t mangle -A " CHAIN_AUTH_IS_DOWN " -j MARK --set-mark 0x%x", + tag << config->markoffsetbits); else return 1; } From a29ba7176a2191e5c1f0f5decc116381049e5aaf Mon Sep 17 00:00:00 2001 From: Neutron Soutmun Date: Mon, 11 May 2015 17:47:13 +0700 Subject: [PATCH 2/2] Add warning log for a large value of MarkOffsetBits configuration * The MarkOffsetBits should be in the range of 0 to 31, the large value should be logged with warning message. Thanks to Michael Haas (mhaas) for comment. --- src/conf.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/conf.c b/src/conf.c index dcd71a45..87a2fb78 100644 --- a/src/conf.c +++ b/src/conf.c @@ -790,7 +790,11 @@ config_read(const char *filename) break; case oMarkOffsetBits: sscanf(p1, "%u", &config.markoffsetbits); - config.markoffsetbits = config.markoffsetbits > 31 ? 0 : config.markoffsetbits; + if (config.markoffsetbits > 31) { + config.markoffsetbits = 0; + debug(LOG_WARNING, "MarkOffsetBits is invalid. It should be in the range of 0 to 31. " + "Fallback to no offset!"); + } break; case oBadOption: /* FALL THROUGH */