Added chain_exists() check to fwknopd SPA rule creation

Added chain_exists() check to SPA rule creation so that if any
of the fwknop chains are deleted out from under fwknopd they will be
recreated on the fly.  This mitigates scenarios where fwknopd might be
started before a system level firewall policy is applied due to init
script ordering, or if an iptables policy is re-applied without
restarting fwknopd.
This commit is contained in:
Michael Rash
2012-11-12 21:48:26 -05:00
parent c0349a20a3
commit bc58b3a15f
3 changed files with 92 additions and 32 deletions
+6
View File
@@ -66,6 +66,12 @@ fwknop-2.0.4 (11//2012):
- [server] Added a new '--pcap-file <file>' option to allow pcap files to
be processed directly by fwknopd instead of sniffing an interface. This
feature is mostly intended for debugging purposes.
- [server] Added chain_exists() check to SPA rule creation so that if any
of the fwknop chains are deleted out from under fwknopd they will be
recreated on the fly. This mitigates scenarios where fwknopd might be
started before a system level firewall policy is applied due to init
script ordering, or if an iptables policy is re-applied without
restarting fwknopd.
fwknop-2.0.3 (09/03/2012):
- [server] Fernando Arnaboldi from IOActive found several DoS/code
+85 -32
View File
@@ -147,6 +147,35 @@ add_jump_rule(const fko_srv_options_t *opts, const int chain_num)
return res;
}
static int
chain_exists(const fko_srv_options_t *opts, const int chain_num)
{
int res = 0;
zero_cmd_buffers();
snprintf(cmd_buf, CMD_BUFSIZE-1, "%s " IPT_CHAIN_EXISTS_ARGS,
fwc.fw_command,
fwc.chain[chain_num].table,
fwc.chain[chain_num].to_chain
);
res = run_extcmd(cmd_buf, err_buf, CMD_BUFSIZE, 0);
if (opts->verbose)
log_msg(LOG_INFO, "chain_exists() CMD: '%s' (res: %d, err: %s)",
cmd_buf, res, err_buf);
if(EXTCMD_IS_SUCCESS(res))
log_msg(LOG_INFO, "'%s' table '%s' chain exists",
fwc.chain[chain_num].table,
fwc.chain[chain_num].to_chain);
else
log_msg(LOG_ERR, "Error %i from cmd:'%s': %s", res, cmd_buf, err_buf);
return res;
}
static int
jump_rule_exists(const int chain_num)
{
@@ -344,49 +373,59 @@ delete_all_chains(const fko_srv_options_t *opts)
}
}
static int
create_chain(const fko_srv_options_t *opts, const int chain_num)
{
int res = 0;
zero_cmd_buffers();
/* Create the custom chain.
*/
snprintf(cmd_buf, CMD_BUFSIZE-1, "%s " IPT_NEW_CHAIN_ARGS,
fwc.fw_command,
fwc.chain[chain_num].table,
fwc.chain[chain_num].to_chain
);
res = run_extcmd(cmd_buf, err_buf, CMD_BUFSIZE, 0);
if (opts->verbose)
log_msg(LOG_INFO, "create_chain() CMD: '%s' (res: %d, err: %s)",
cmd_buf, res, err_buf);
/* Expect full success on this */
if(! EXTCMD_IS_SUCCESS(res))
log_msg(LOG_ERR, "Error %i from cmd:'%s': %s", res, cmd_buf, err_buf);
return res;
}
/* Create the fwknop custom chains (at least those that are configured).
*/
static int
create_fw_chains(const fko_srv_options_t *opts)
{
int i;
int res, got_err = 0;
int i, got_err = 0;
for(i=0; i<(NUM_FWKNOP_ACCESS_TYPES); i++)
{
if(fwc.chain[i].target[0] == '\0')
continue;
zero_cmd_buffers();
/* Create the custom chain.
*/
snprintf(cmd_buf, CMD_BUFSIZE-1, "%s " IPT_NEW_CHAIN_ARGS,
fwc.fw_command,
fwc.chain[i].table,
fwc.chain[i].to_chain
);
res = run_extcmd(cmd_buf, err_buf, CMD_BUFSIZE, 0);
if (opts->verbose)
log_msg(LOG_INFO, "create_fw_chains() CMD: '%s' (res: %d, err: %s)",
cmd_buf, res, err_buf);
/* Expect full success on this */
if(! EXTCMD_IS_SUCCESS(res))
if(chain_exists(opts, i) == 0)
{
log_msg(LOG_ERR, "Error %i from cmd:'%s': %s", res, cmd_buf, err_buf);
got_err++;
/* Create the chain
*/
if(! EXTCMD_IS_SUCCESS(create_chain(opts, i)))
got_err++;
/* Then create the jump rule to that chain.
*/
if(! EXTCMD_IS_SUCCESS(add_jump_rule(opts, i)))
got_err++;
}
/* Then create the jump rule to that chain.
*/
res = add_jump_rule(opts, i);
/* Expect full success on this */
if(! EXTCMD_IS_SUCCESS(res))
got_err++;
}
return(got_err);
@@ -612,12 +651,20 @@ process_spa_request(const fko_srv_options_t *opts, const acc_stanza_t *acc, spa_
/* Check to make sure that the jump rules exist for each
* required chain
*/
if(chain_exists(opts, IPT_INPUT_ACCESS) == 0)
create_chain(opts, IPT_INPUT_ACCESS);
if(jump_rule_exists(IPT_INPUT_ACCESS) == 0)
add_jump_rule(opts, IPT_INPUT_ACCESS);
if(out_chain->to_chain != NULL && strlen(out_chain->to_chain))
{
if(chain_exists(opts, IPT_OUTPUT_ACCESS) == 0)
create_chain(opts, IPT_OUTPUT_ACCESS);
if(jump_rule_exists(IPT_OUTPUT_ACCESS) == 0)
add_jump_rule(opts, IPT_OUTPUT_ACCESS);
}
/* Create an access command for each proto/port for the source ip.
*/
@@ -776,8 +823,11 @@ process_spa_request(const fko_srv_options_t *opts, const acc_stanza_t *acc, spa_
else if(fwd_chain->to_chain != NULL && strlen(fwd_chain->to_chain))
{
/* Make our FORWARD and NAT rules, and make sure the
* required jump rule exists
* required chain and jump rule exists
*/
if(chain_exists(opts, IPT_FORWARD_ACCESS) == 0)
create_chain(opts, IPT_FORWARD_ACCESS);
if (jump_rule_exists(IPT_FORWARD_ACCESS) == 0)
add_jump_rule(opts, IPT_FORWARD_ACCESS);
@@ -823,8 +873,11 @@ process_spa_request(const fko_srv_options_t *opts, const acc_stanza_t *acc, spa_
if(dnat_chain->to_chain != NULL && strlen(dnat_chain->to_chain))
{
/* Make sure the required jump rule exists
/* Make sure the required chain and jump rule exists
*/
if(chain_exists(opts, IPT_DNAT_ACCESS) == 0)
create_chain(opts, IPT_DNAT_ACCESS);
if (jump_rule_exists(IPT_DNAT_ACCESS) == 0)
add_jump_rule(opts, IPT_DNAT_ACCESS);
+1
View File
@@ -44,6 +44,7 @@
#define IPT_DEL_RULE_ARGS "-t %s -D %s %i 2>&1"
#define IPT_NEW_CHAIN_ARGS "-t %s -N %s 2>&1"
#define IPT_FLUSH_CHAIN_ARGS "-t %s -F %s 2>&1"
#define IPT_CHAIN_EXISTS_ARGS "-t %s -L %s -n 2>&1"
#define IPT_DEL_CHAIN_ARGS "-t %s -X %s 2>&1"
#define IPT_ADD_JUMP_RULE_ARGS "-t %s -I %s %i -j %s 2>&1"
#define IPT_LIST_RULES_ARGS "-t %s -L %s --line-numbers -n 2>&1"