Skip to content

Commit cd99952

Browse files
committed
Merge pull request #96 from acv/auth-down-rule
Open firewall when auth server are down
2 parents bad4a7e + 88c0fee commit cd99952

File tree

7 files changed

+130
-9
lines changed

7 files changed

+130
-9
lines changed

src/conf.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,16 @@
7373
#define DEFAULT_AUTHSERVSSLPEERVER 1 /* 0 means: Enable peer verification */
7474
/*@}*/
7575

76+
/*@{*/
77+
/** Defines for firewall rule sets. */
78+
#define FWRULESET_GLOBAL "global"
79+
#define FWRULESET_VALIDATING_USERS "validating-users"
80+
#define FWRULESET_KNOWN_USERS "known-users"
81+
#define FWRULESET_AUTH_IS_DOWN "auth-is-down"
82+
#define FWRULESET_UNKNOWN_USERS "unknown-users"
83+
#define FWRULESET_LOCKED_USERS "locked-users"
84+
/*@}*/
85+
7686
/**
7787
* Information about the authentication server
7888
*/

src/firewall.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,26 @@ fw_deny(const char *ip, const char *mac, int fw_connection_state)
116116
return iptables_fw_access(FW_ACCESS_DENY, ip, mac, fw_connection_state);
117117
}
118118

119+
/** Passthrough for clients when auth server is down */
120+
int
121+
fw_set_authdown(void)
122+
{
123+
debug(LOG_DEBUG, "Marking auth server down");
124+
125+
return iptables_fw_auth_unreachable(FW_MARK_AUTH_IS_DOWN);
126+
}
127+
128+
/** Remove passthrough for clients when auth server is up */
129+
int
130+
fw_set_authup(void)
131+
{
132+
debug(LOG_DEBUG, "Marking auth server up again");
133+
134+
return iptables_fw_auth_reachable();
135+
}
136+
137+
138+
119139
/* XXX DCY */
120140
/**
121141
* Get an IP's MAC address from the ARP cache.

src/firewall.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ typedef enum _t_fw_marks {
3737
FW_MARK_PROBATION = 1, /**< @brief The client is in probation period and must be authenticated
3838
@todo: VERIFY THAT THIS IS ACCURATE*/
3939
FW_MARK_KNOWN = 2, /**< @brief The client is known to the firewall */
40+
FW_MARK_AUTH_IS_DOWN = 253, /**< @brief The auth servers are down */
4041
FW_MARK_LOCKED = 254 /**< @brief The client has been locked out */
4142
} t_fw_marks;
4243

@@ -61,6 +62,12 @@ int fw_allow_host(const char *host);
6162
/** @brief Deny a client access through the firewall*/
6263
int fw_deny(const char *ip, const char *mac, int profile);
6364

65+
/** @brief Passthrough for clients when auth server is down */
66+
int fw_set_authdown(void);
67+
68+
/** @brief Remove passthrough for clients when auth server is up */
69+
int fw_set_authup(void);
70+
6471
/** @brief Refreshes the entire client list */
6572
void fw_sync_with_authserver(void);
6673

src/fw_iptables.c

Lines changed: 63 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,7 @@ iptables_fw_init(void)
258258
t_trusted_mac *p;
259259
int proxy_port;
260260
fw_quiet = 0;
261+
int got_authdown_ruleset = NULL == get_ruleset(FWRULESET_AUTH_IS_DOWN) ? 0 : 1;
261262

262263
LOCK_CONFIG();
263264
config = config_get_config();
@@ -283,10 +284,14 @@ iptables_fw_init(void)
283284
iptables_do_command("-t mangle -N " CHAIN_TRUSTED);
284285
iptables_do_command("-t mangle -N " CHAIN_OUTGOING);
285286
iptables_do_command("-t mangle -N " CHAIN_INCOMING);
287+
if (got_authdown_ruleset)
288+
iptables_do_command("-t mangle -N " CHAIN_AUTH_IS_DOWN);
286289

287290
/* Assign links and rules to these new chains */
288291
iptables_do_command("-t mangle -I PREROUTING 1 -i %s -j " CHAIN_OUTGOING, config->gw_interface);
289-
iptables_do_command("-t mangle -I PREROUTING 1 -i %s -j " CHAIN_TRUSTED, config->gw_interface);//this rule will be inserted before the prior one
292+
iptables_do_command("-t mangle -I PREROUTING 1 -i %s -j " CHAIN_TRUSTED, config->gw_interface); //this rule will be inserted before the prior one
293+
if (got_authdown_ruleset)
294+
iptables_do_command("-t mangle -I PREROUTING 1 -i %s -j " CHAIN_AUTH_IS_DOWN, config->gw_interface); //this rule must be last in the chain
290295
iptables_do_command("-t mangle -I POSTROUTING 1 -o %s -j " CHAIN_INCOMING, config->gw_interface);
291296

292297
for (p = config->trustedmaclist; p != NULL; p = p->next)
@@ -305,6 +310,8 @@ iptables_fw_init(void)
305310
iptables_do_command("-t nat -N " CHAIN_GLOBAL);
306311
iptables_do_command("-t nat -N " CHAIN_UNKNOWN);
307312
iptables_do_command("-t nat -N " CHAIN_AUTHSERVERS);
313+
if (got_authdown_ruleset)
314+
iptables_do_command("-t nat -N " CHAIN_AUTH_IS_DOWN);
308315

309316
/* Assign links and rules to these new chains */
310317
iptables_do_command("-t nat -A PREROUTING -i %s -j " CHAIN_OUTGOING, config->gw_interface);
@@ -326,7 +333,11 @@ iptables_fw_init(void)
326333

327334
iptables_do_command("-t nat -A " CHAIN_UNKNOWN " -j " CHAIN_AUTHSERVERS);
328335
iptables_do_command("-t nat -A " CHAIN_UNKNOWN " -j " CHAIN_GLOBAL);
329-
iptables_do_command("-t nat -A " CHAIN_UNKNOWN " -p tcp --dport 80 -j REDIRECT --to-ports %d", gw_port);
336+
if (got_authdown_ruleset) {
337+
iptables_do_command("-t nat -A " CHAIN_UNKNOWN " -j " CHAIN_AUTH_IS_DOWN);
338+
iptables_do_command("-t nat -A " CHAIN_AUTH_IS_DOWN " -m mark --mark 0x%u -j ACCEPT", FW_MARK_AUTH_IS_DOWN);
339+
}
340+
iptables_do_command("-t nat -A " CHAIN_UNKNOWN " -p tcp --dport 80 -j REDIRECT --to-ports %d", gw_port);
330341

331342

332343
/*
@@ -343,6 +354,8 @@ iptables_fw_init(void)
343354
iptables_do_command("-t filter -N " CHAIN_VALIDATE);
344355
iptables_do_command("-t filter -N " CHAIN_KNOWN);
345356
iptables_do_command("-t filter -N " CHAIN_UNKNOWN);
357+
if (got_authdown_ruleset)
358+
iptables_do_command("-t filter -N " CHAIN_AUTH_IS_DOWN);
346359

347360
/* Assign links and rules to these new chains */
348361

@@ -366,20 +379,25 @@ iptables_fw_init(void)
366379
iptables_fw_set_authservers();
367380

368381
iptables_do_command("-t filter -A " CHAIN_TO_INTERNET " -m mark --mark 0x%u -j " CHAIN_LOCKED, FW_MARK_LOCKED);
369-
iptables_load_ruleset("filter", "locked-users", CHAIN_LOCKED);
382+
iptables_load_ruleset("filter", FWRULESET_LOCKED_USERS, CHAIN_LOCKED);
370383

371384
iptables_do_command("-t filter -A " CHAIN_TO_INTERNET " -j " CHAIN_GLOBAL);
372-
iptables_load_ruleset("filter", "global", CHAIN_GLOBAL);
373-
iptables_load_ruleset("nat", "global", CHAIN_GLOBAL);
385+
iptables_load_ruleset("filter", FWRULESET_GLOBAL, CHAIN_GLOBAL);
386+
iptables_load_ruleset("nat", FWRULESET_GLOBAL, CHAIN_GLOBAL);
374387

375388
iptables_do_command("-t filter -A " CHAIN_TO_INTERNET " -m mark --mark 0x%u -j " CHAIN_VALIDATE, FW_MARK_PROBATION);
376-
iptables_load_ruleset("filter", "validating-users", CHAIN_VALIDATE);
389+
iptables_load_ruleset("filter", FWRULESET_VALIDATING_USERS, CHAIN_VALIDATE);
377390

378391
iptables_do_command("-t filter -A " CHAIN_TO_INTERNET " -m mark --mark 0x%u -j " CHAIN_KNOWN, FW_MARK_KNOWN);
379-
iptables_load_ruleset("filter", "known-users", CHAIN_KNOWN);
392+
iptables_load_ruleset("filter", FWRULESET_KNOWN_USERS, CHAIN_KNOWN);
393+
394+
if (got_authdown_ruleset) {
395+
iptables_do_command("-t filter -A " CHAIN_TO_INTERNET " -m mark --mark 0x%u -j " CHAIN_AUTH_IS_DOWN, FW_MARK_AUTH_IS_DOWN);
396+
iptables_load_ruleset("filter", FWRULESET_AUTH_IS_DOWN, CHAIN_AUTH_IS_DOWN);
397+
}
380398

381399
iptables_do_command("-t filter -A " CHAIN_TO_INTERNET " -j " CHAIN_UNKNOWN);
382-
iptables_load_ruleset("filter", "unknown-users", CHAIN_UNKNOWN);
400+
iptables_load_ruleset("filter", FWRULESET_UNKNOWN_USERS, CHAIN_UNKNOWN);
383401
iptables_do_command("-t filter -A " CHAIN_UNKNOWN " -j REJECT --reject-with icmp-port-unreachable");
384402

385403
UNLOCK_CONFIG();
@@ -395,6 +413,7 @@ iptables_fw_init(void)
395413
int
396414
iptables_fw_destroy(void)
397415
{
416+
int got_authdown_ruleset = NULL == get_ruleset(FWRULESET_AUTH_IS_DOWN) ? 0 : 1;
398417
fw_quiet = 1;
399418

400419
debug(LOG_DEBUG, "Destroying our iptables entries");
@@ -407,12 +426,18 @@ iptables_fw_destroy(void)
407426
debug(LOG_DEBUG, "Destroying chains in the MANGLE table");
408427
iptables_fw_destroy_mention("mangle", "PREROUTING", CHAIN_TRUSTED);
409428
iptables_fw_destroy_mention("mangle", "PREROUTING", CHAIN_OUTGOING);
429+
if (got_authdown_ruleset)
430+
iptables_fw_destroy_mention("mangle", "PREROUTING", CHAIN_AUTH_IS_DOWN);
410431
iptables_fw_destroy_mention("mangle", "POSTROUTING", CHAIN_INCOMING);
411432
iptables_do_command("-t mangle -F " CHAIN_TRUSTED);
412433
iptables_do_command("-t mangle -F " CHAIN_OUTGOING);
434+
if (got_authdown_ruleset)
435+
iptables_do_command("-t mangle -F " CHAIN_AUTH_IS_DOWN);
413436
iptables_do_command("-t mangle -F " CHAIN_INCOMING);
414437
iptables_do_command("-t mangle -X " CHAIN_TRUSTED);
415438
iptables_do_command("-t mangle -X " CHAIN_OUTGOING);
439+
if (got_authdown_ruleset)
440+
iptables_do_command("-t mangle -X " CHAIN_AUTH_IS_DOWN);
416441
iptables_do_command("-t mangle -X " CHAIN_INCOMING);
417442

418443
/*
@@ -424,12 +449,16 @@ iptables_fw_destroy(void)
424449
iptables_fw_destroy_mention("nat", "PREROUTING", CHAIN_OUTGOING);
425450
iptables_do_command("-t nat -F " CHAIN_AUTHSERVERS);
426451
iptables_do_command("-t nat -F " CHAIN_OUTGOING);
452+
if (got_authdown_ruleset)
453+
iptables_do_command("-t nat -F " CHAIN_AUTH_IS_DOWN);
427454
iptables_do_command("-t nat -F " CHAIN_TO_ROUTER);
428455
iptables_do_command("-t nat -F " CHAIN_TO_INTERNET);
429456
iptables_do_command("-t nat -F " CHAIN_GLOBAL);
430457
iptables_do_command("-t nat -F " CHAIN_UNKNOWN);
431458
iptables_do_command("-t nat -X " CHAIN_AUTHSERVERS);
432459
iptables_do_command("-t nat -X " CHAIN_OUTGOING);
460+
if (got_authdown_ruleset)
461+
iptables_do_command("-t nat -X " CHAIN_AUTH_IS_DOWN);
433462
iptables_do_command("-t nat -X " CHAIN_TO_ROUTER);
434463
iptables_do_command("-t nat -X " CHAIN_TO_INTERNET);
435464
iptables_do_command("-t nat -X " CHAIN_GLOBAL);
@@ -449,13 +478,17 @@ iptables_fw_destroy(void)
449478
iptables_do_command("-t filter -F " CHAIN_VALIDATE);
450479
iptables_do_command("-t filter -F " CHAIN_KNOWN);
451480
iptables_do_command("-t filter -F " CHAIN_UNKNOWN);
481+
if (got_authdown_ruleset)
482+
iptables_do_command("-t filter -F " CHAIN_AUTH_IS_DOWN);
452483
iptables_do_command("-t filter -X " CHAIN_TO_INTERNET);
453484
iptables_do_command("-t filter -X " CHAIN_AUTHSERVERS);
454485
iptables_do_command("-t filter -X " CHAIN_LOCKED);
455486
iptables_do_command("-t filter -X " CHAIN_GLOBAL);
456487
iptables_do_command("-t filter -X " CHAIN_VALIDATE);
457488
iptables_do_command("-t filter -X " CHAIN_KNOWN);
458489
iptables_do_command("-t filter -X " CHAIN_UNKNOWN);
490+
if (got_authdown_ruleset)
491+
iptables_do_command("-t filter -X " CHAIN_AUTH_IS_DOWN);
459492

460493
return 1;
461494
}
@@ -571,6 +604,28 @@ iptables_fw_access_host(fw_access_t type, const char *host)
571604
return rc;
572605
}
573606

607+
/** Set a mark when auth server is not reachable */
608+
int
609+
iptables_fw_auth_unreachable(int tag)
610+
{
611+
int got_authdown_ruleset = NULL == get_ruleset(FWRULESET_AUTH_IS_DOWN) ? 0 : 1;
612+
if (got_authdown_ruleset)
613+
return iptables_do_command("-t mangle -A " CHAIN_AUTH_IS_DOWN " -j MARK --set-mark 0x%u", tag);
614+
else
615+
return 1;
616+
}
617+
618+
/** Remove mark when auth server is reachable again */
619+
int
620+
iptables_fw_auth_reachable(void)
621+
{
622+
int got_authdown_ruleset = NULL == get_ruleset(FWRULESET_AUTH_IS_DOWN) ? 0 : 1;
623+
if (got_authdown_ruleset)
624+
return iptables_do_command("-t mangle -F " CHAIN_AUTH_IS_DOWN);
625+
else
626+
return 1;
627+
}
628+
574629
/** Update the counters of all the clients in the client list */
575630
int
576631
iptables_fw_counters_update(void)

src/fw_iptables.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
#define CHAIN_UNKNOWN "WiFiDog_$ID$_Unknown"
4343
#define CHAIN_LOCKED "WiFiDog_$ID$_Locked"
4444
#define CHAIN_TRUSTED "WiFiDog_$ID$_Trusted"
45+
#define CHAIN_AUTH_IS_DOWN "WiFiDog_$ID$_AuthIsDown"
4546
/*@}*/
4647

4748
/** Used by iptables_fw_access to select if the client should be granted of denied access */
@@ -71,6 +72,12 @@ int iptables_fw_access(fw_access_t type, const char *ip, const char *mac, int ta
7172
/** @brief Define the access of a host */
7273
int iptables_fw_access_host(fw_access_t type, const char *host);
7374

75+
/** @brief Set a mark when auth server is not reachable */
76+
int iptables_fw_auth_unreachable(int tag);
77+
78+
/** @brief Remove mark when auth server is reachable again */
79+
int iptables_fw_auth_reachable(void);
80+
7481
/** @brief All counters in the client list */
7582
int iptables_fw_counters_update(void);
7683

src/ping_thread.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
#include "ping_thread.h"
5252
#include "util.h"
5353
#include "centralserver.h"
54+
#include "firewall.h"
5455

5556
#include "simple_http.h"
5657

@@ -103,6 +104,7 @@ ping(void)
103104
float sys_load = 0;
104105
t_auth_serv *auth_server = NULL;
105106
auth_server = get_auth_server();
107+
static int authdown = 0;
106108

107109
debug(LOG_DEBUG, "Entering ping()");
108110
memset(request, 0, sizeof(request));
@@ -117,6 +119,10 @@ ping(void)
117119
/*
118120
* No auth servers for me to talk to
119121
*/
122+
if (!authdown) {
123+
fw_set_authdown();
124+
authdown = 1;
125+
}
120126
return;
121127
}
122128

@@ -184,10 +190,17 @@ ping(void)
184190

185191
if (strstr(request, "Pong") == 0) {
186192
debug(LOG_WARNING, "Auth server did NOT say Pong!");
187-
/* FIXME */
193+
if (!authdown) {
194+
fw_set_authdown();
195+
authdown = 1;
196+
}
188197
}
189198
else {
190199
debug(LOG_DEBUG, "Auth Server Says: Pong");
200+
if (authdown) {
201+
fw_set_authup();
202+
authdown = 0;
203+
}
191204
}
192205

193206
return;

wifidog.conf

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,15 @@ FirewallRuleSet known-users {
299299
FirewallRule allow to 0.0.0.0/0
300300
}
301301

302+
# Rule Set: auth-is-down
303+
#
304+
# Does nothing when not configured.
305+
#
306+
# Used when auth server is down
307+
#FirewallRuleSet auth-is-down {
308+
# FirewallRule allow to 0.0.0.0/0
309+
#}
310+
302311
# Rule Set: unknown-users
303312
#
304313
# Used for unvalidated users, this is the ruleset that gets redirected.

0 commit comments

Comments
 (0)