* Avoid duplicate rules with the same timestamp.

This commit is contained in:
Franck Joncourt
2013-01-17 21:46:13 +01:00
parent 10c19063df
commit 0fda88cfca
2 changed files with 163 additions and 148 deletions
+158 -143
View File
@@ -592,6 +592,66 @@ fw_cleanup(const fko_srv_options_t *opts)
return(0);
}
static int
rule_exists(const fko_srv_options_t *opts, const char *fw_chain, const char *fw_rule)
{
int rule_exists = 0;
int res = 0;
zero_cmd_buffers();
snprintf(cmd_buf, CMD_BUFSIZE-1, "%s -C %s %s", opts->fw_config->fw_command, fw_chain, fw_rule);
res = run_extcmd(cmd_buf, err_buf, CMD_BUFSIZE, 0);
if (opts->verbose)
log_msg(LOG_INFO, "rule_exists() CMD: '%s' (res: %d, err: %s)",
cmd_buf, res, err_buf);
if(EXTCMD_IS_SUCCESS(res) && strlen(err_buf))
{
rule_exists = 0;
log_msg(LOG_INFO, "rule_exists() Rule : '%s' in %s does not exist.", fw_rule, fw_chain);
}
else
{
rule_exists = 1;
if (opts->verbose)
log_msg(LOG_INFO, "rule_exists() Rule : '%s' in %s already exist.", fw_rule, fw_chain);
}
return rule_exists;
}
static int create_rule(const fko_srv_options_t *opts, const char *fw_chain, const char *fw_rule)
{
int res;
zero_cmd_buffers();
snprintf(cmd_buf, CMD_BUFSIZE-1, "%s -A %s %s", opts->fw_config->fw_command, fw_chain, fw_rule);
res = run_extcmd(cmd_buf, err_buf, CMD_BUFSIZE, 0);
if (opts->verbose)
log_msg(LOG_INFO, "create_rule() CMD: '%s' (res: %d, err: %s)",
cmd_buf, res, err_buf);
if(EXTCMD_IS_SUCCESS(res))
{
res = 0;
if (opts->verbose)
log_msg(LOG_INFO, "create_rule() Rule: '%s' added to %s", fw_rule, fw_chain);
}
else
{
res = 1;
log_msg(LOG_ERR, "Error %i from cmd:'%s': %s", res, cmd_buf, err_buf);
}
return res;
}
/****************************************************************************/
/* Rule Processing - Create an access request...
@@ -602,6 +662,7 @@ process_spa_request(const fko_srv_options_t *opts, const acc_stanza_t *acc, spa_
char nat_ip[MAX_IPV4_STR_LEN] = {0};
char snat_target[SNAT_TARGET_BUFSIZE] = {0};
char *ndx;
char rule_buf[CMD_BUFSIZE];
unsigned int nat_port = 0;
@@ -670,12 +731,10 @@ process_spa_request(const fko_srv_options_t *opts, const acc_stanza_t *acc, spa_
*/
while(ple != NULL)
{
zero_cmd_buffers();
memset(rule_buf, 0, CMD_BUFSIZE);
snprintf(cmd_buf, CMD_BUFSIZE-1, "%s " IPT_ADD_RULE_ARGS,
opts->fw_config->fw_command,
snprintf(rule_buf, CMD_BUFSIZE-1, IPT_RULE_ARGS,
in_chain->table,
in_chain->to_chain,
ple->proto,
spadat->use_src_ip,
ple->port,
@@ -683,41 +742,34 @@ process_spa_request(const fko_srv_options_t *opts, const acc_stanza_t *acc, spa_
in_chain->target
);
res = run_extcmd(cmd_buf, err_buf, CMD_BUFSIZE, 0);
if (opts->verbose)
log_msg(LOG_INFO, "process_spa_request() CMD: '%s' (res: %d, err: %s)",
cmd_buf, res, err_buf);
if(EXTCMD_IS_SUCCESS(res))
if(rule_exists(opts, in_chain->to_chain, rule_buf) == 0)
{
log_msg(LOG_INFO, "Added Rule to %s for %s, %s expires at %u",
in_chain->to_chain, spadat->use_src_ip,
spadat->spa_message_remain, exp_ts
);
if (create_rule(opts, in_chain->to_chain, rule_buf) == 0)
{
log_msg(LOG_INFO, "Added Rule to %s for %s, %s expires at %u",
in_chain->to_chain, spadat->use_src_ip,
spadat->spa_message_remain, exp_ts
);
in_chain->active_rules++;
in_chain->active_rules++;
/* Reset the next expected expire time for this chain if it
* is warranted.
*/
if(in_chain->next_expire < now || exp_ts < in_chain->next_expire)
in_chain->next_expire = exp_ts;
/* Reset the next expected expire time for this chain if it
* is warranted.
*/
if(in_chain->next_expire < now || exp_ts < in_chain->next_expire)
in_chain->next_expire = exp_ts;
}
}
else
log_msg(LOG_ERR, "Error %i from cmd:'%s': %s", res, cmd_buf, err_buf);
/* If we have to make an corresponding OUTPUT rule if out_chain target
* is not NULL.
*/
if(out_chain->to_chain != NULL && strlen(out_chain->to_chain))
{
zero_cmd_buffers();
memset(rule_buf, 0, CMD_BUFSIZE);
snprintf(cmd_buf, CMD_BUFSIZE-1, "%s " IPT_ADD_OUT_RULE_ARGS,
opts->fw_config->fw_command,
snprintf(rule_buf, CMD_BUFSIZE-1, IPT_OUT_RULE_ARGS,
out_chain->table,
out_chain->to_chain,
ple->proto,
spadat->use_src_ip,
ple->port,
@@ -725,30 +777,24 @@ process_spa_request(const fko_srv_options_t *opts, const acc_stanza_t *acc, spa_
out_chain->target
);
res = run_extcmd(cmd_buf, err_buf, CMD_BUFSIZE, 0);
if (opts->verbose)
log_msg(LOG_INFO, "process_spa_request() CMD: '%s' (res: %d, err: %s)",
cmd_buf, res, err_buf);
if(EXTCMD_IS_SUCCESS(res))
if(rule_exists(opts, out_chain->to_chain, rule_buf) == 0)
{
log_msg(LOG_INFO, "Added OUTPUT Rule to %s for %s, %s expires at %u",
out_chain->to_chain, spadat->use_src_ip,
spadat->spa_message_remain, exp_ts
);
if (create_rule(opts, out_chain->to_chain, rule_buf) == 0)
{
log_msg(LOG_INFO, "Rule in %s for %s, %s expires at %u, does not exist.",
out_chain->to_chain, spadat->use_src_ip,
spadat->spa_message_remain, exp_ts
);
out_chain->active_rules++;
out_chain->active_rules++;
/* Reset the next expected expire time for this chain if it
* is warranted.
*/
if(out_chain->next_expire < now || exp_ts < out_chain->next_expire)
out_chain->next_expire = exp_ts;
/* Reset the next expected expire time for this chain if it
* is warranted.
*/
if(out_chain->next_expire < now || exp_ts < out_chain->next_expire)
out_chain->next_expire = exp_ts;
}
}
else
log_msg(LOG_ERR, "Error %i from cmd:'%s': %s", res, cmd_buf, err_buf);
}
ple = ple->next;
@@ -780,14 +826,10 @@ process_spa_request(const fko_srv_options_t *opts, const acc_stanza_t *acc, spa_
if(spadat->message_type == FKO_LOCAL_NAT_ACCESS_MSG)
{
/* Need to add an ACCEPT rule into the INPUT chain
*/
zero_cmd_buffers();
memset(rule_buf, 0, CMD_BUFSIZE);
snprintf(cmd_buf, CMD_BUFSIZE-1, "%s " IPT_ADD_RULE_ARGS,
opts->fw_config->fw_command,
snprintf(rule_buf, CMD_BUFSIZE-1, IPT_RULE_ARGS,
in_chain->table,
in_chain->to_chain,
fst_proto,
spadat->use_src_ip,
nat_port,
@@ -795,29 +837,24 @@ process_spa_request(const fko_srv_options_t *opts, const acc_stanza_t *acc, spa_
in_chain->target
);
res = run_extcmd(cmd_buf, err_buf, CMD_BUFSIZE, 0);
if (opts->verbose)
log_msg(LOG_INFO, "process_spa_request() CMD: '%s' (res: %d, err: %s)",
cmd_buf, res, err_buf);
if(EXTCMD_IS_SUCCESS(res))
if(rule_exists(opts, in_chain->to_chain, rule_buf) == 0)
{
log_msg(LOG_INFO, "Added Rule to %s for %s, %s expires at %u",
in_chain->to_chain, spadat->use_src_ip,
spadat->spa_message_remain, exp_ts
);
if (create_rule(opts, in_chain->to_chain, rule_buf) == 0)
{
log_msg(LOG_INFO, "Added Rule to %s for %s, %s expires at %u",
in_chain->to_chain, spadat->use_src_ip,
spadat->spa_message_remain, exp_ts
);
in_chain->active_rules++;
in_chain->active_rules++;
/* Reset the next expected expire time for this chain if it
* is warranted.
*/
if(in_chain->next_expire < now || exp_ts < in_chain->next_expire)
in_chain->next_expire = exp_ts;
/* Reset the next expected expire time for this chain if it
* is warranted.
*/
if(in_chain->next_expire < now || exp_ts < in_chain->next_expire)
in_chain->next_expire = exp_ts;
}
}
else
log_msg(LOG_ERR, "Error %i from cmd:'%s': %s", res, cmd_buf, err_buf);
}
else if(fwd_chain->to_chain != NULL && strlen(fwd_chain->to_chain))
@@ -831,12 +868,10 @@ process_spa_request(const fko_srv_options_t *opts, const acc_stanza_t *acc, spa_
if (jump_rule_exists(IPT_FORWARD_ACCESS) == 0)
add_jump_rule(opts, IPT_FORWARD_ACCESS);
zero_cmd_buffers();
memset(rule_buf, 0, CMD_BUFSIZE);
snprintf(cmd_buf, CMD_BUFSIZE-1, "%s " IPT_ADD_FWD_RULE_ARGS,
opts->fw_config->fw_command,
snprintf(rule_buf, CMD_BUFSIZE-1, IPT_FWD_RULE_ARGS,
fwd_chain->table,
fwd_chain->to_chain,
fst_proto,
spadat->use_src_ip,
nat_ip,
@@ -845,34 +880,28 @@ process_spa_request(const fko_srv_options_t *opts, const acc_stanza_t *acc, spa_
fwd_chain->target
);
res = run_extcmd(cmd_buf, err_buf, CMD_BUFSIZE, 0);
if (opts->verbose)
log_msg(LOG_INFO, "process_spa_request() CMD: '%s' (res: %d, err: %s)",
cmd_buf, res, err_buf);
if(EXTCMD_IS_SUCCESS(res))
if(rule_exists(opts, fwd_chain->to_chain, rule_buf) == 0)
{
log_msg(LOG_INFO, "Added FORWARD Rule to %s for %s, %s expires at %u",
fwd_chain->to_chain, spadat->use_src_ip,
spadat->spa_message_remain, exp_ts
);
if (create_rule(opts, fwd_chain->to_chain, rule_buf) == 0)
{
log_msg(LOG_INFO, "Added FORWARD Rule to %s for %s, %s expires at %u",
fwd_chain->to_chain, spadat->use_src_ip,
spadat->spa_message_remain, exp_ts
);
fwd_chain->active_rules++;
fwd_chain->active_rules++;
/* Reset the next expected expire time for this chain if it
* is warranted.
*/
if(fwd_chain->next_expire < now || exp_ts < fwd_chain->next_expire)
fwd_chain->next_expire = exp_ts;
/* Reset the next expected expire time for this chain if it
* is warranted.
*/
if(fwd_chain->next_expire < now || exp_ts < fwd_chain->next_expire)
fwd_chain->next_expire = exp_ts;
}
}
else
log_msg(LOG_ERR, "Error %i from cmd:'%s': %s", res, cmd_buf, err_buf);
}
if(dnat_chain->to_chain != NULL && strlen(dnat_chain->to_chain))
{
/* Make sure the required chain and jump rule exists
*/
if(chain_exists(opts, IPT_DNAT_ACCESS) == 0)
@@ -881,12 +910,10 @@ process_spa_request(const fko_srv_options_t *opts, const acc_stanza_t *acc, spa_
if (jump_rule_exists(IPT_DNAT_ACCESS) == 0)
add_jump_rule(opts, IPT_DNAT_ACCESS);
zero_cmd_buffers();
memset(rule_buf, 0, CMD_BUFSIZE);
snprintf(cmd_buf, CMD_BUFSIZE-1, "%s " IPT_ADD_DNAT_RULE_ARGS,
opts->fw_config->fw_command,
snprintf(rule_buf, CMD_BUFSIZE-1, IPT_DNAT_RULE_ARGS,
dnat_chain->table,
dnat_chain->to_chain,
fst_proto,
spadat->use_src_ip,
fst_port,
@@ -896,37 +923,30 @@ process_spa_request(const fko_srv_options_t *opts, const acc_stanza_t *acc, spa_
nat_port
);
res = run_extcmd(cmd_buf, err_buf, CMD_BUFSIZE, 0);
if (opts->verbose)
log_msg(LOG_INFO, "process_spa_request() CMD: '%s' (res: %d, err: %s)",
cmd_buf, res, err_buf);
if(EXTCMD_IS_SUCCESS(res))
if(rule_exists(opts, dnat_chain->to_chain, rule_buf) == 0)
{
log_msg(LOG_INFO, "Added DNAT Rule to %s for %s, %s expires at %u",
dnat_chain->to_chain, spadat->use_src_ip,
spadat->spa_message_remain, exp_ts
);
if (create_rule(opts, dnat_chain->to_chain, rule_buf) == 0)
{
log_msg(LOG_INFO, "Added DNAT Rule to %s for %s, %s expires at %u",
dnat_chain->to_chain, spadat->use_src_ip,
spadat->spa_message_remain, exp_ts
);
dnat_chain->active_rules++;
dnat_chain->active_rules++;
/* Reset the next expected expire time for this chain if it
* is warranted.
*/
if(dnat_chain->next_expire < now || exp_ts < dnat_chain->next_expire)
dnat_chain->next_expire = exp_ts;
/* Reset the next expected expire time for this chain if it
* is warranted.
*/
if(dnat_chain->next_expire < now || exp_ts < dnat_chain->next_expire)
dnat_chain->next_expire = exp_ts;
}
}
else
log_msg(LOG_ERR, "Error %i from cmd:'%s': %s", res, cmd_buf, err_buf);
}
/* If SNAT (or MASQUERADE) is wanted, then we add those rules here as well.
*/
if(strncasecmp(opts->config[CONF_ENABLE_IPT_SNAT], "Y", 1) == 0)
{
zero_cmd_buffers();
/* Setup some parameter depending on whether we are using SNAT
* or MASQUERADE.
*/
@@ -946,10 +966,10 @@ process_spa_request(const fko_srv_options_t *opts, const acc_stanza_t *acc, spa_
"--to-ports %i", fst_port);
}
snprintf(cmd_buf, CMD_BUFSIZE-1, "%s " IPT_ADD_SNAT_RULE_ARGS,
opts->fw_config->fw_command,
memset(rule_buf, 0, CMD_BUFSIZE);
snprintf(rule_buf, CMD_BUFSIZE-1, IPT_SNAT_RULE_ARGS,
snat_chain->table,
snat_chain->to_chain,
fst_proto,
nat_ip,
nat_port,
@@ -958,29 +978,24 @@ process_spa_request(const fko_srv_options_t *opts, const acc_stanza_t *acc, spa_
snat_target
);
res = run_extcmd(cmd_buf, err_buf, CMD_BUFSIZE, 0);
if (opts->verbose)
log_msg(LOG_INFO, "process_spa_request() CMD: '%s' (res: %d, err: %s)",
cmd_buf, res, err_buf);
if(EXTCMD_IS_SUCCESS(res))
if(rule_exists(opts, snat_chain->to_chain, rule_buf) == 0)
{
log_msg(LOG_INFO, "Added Source NAT Rule to %s for %s, %s expires at %u",
snat_chain->to_chain, spadat->use_src_ip,
spadat->spa_message_remain, exp_ts
);
if(create_rule(opts, snat_chain->to_chain, rule_buf) == 0)
{
log_msg(LOG_INFO, "Added Source NAT Rule to %s for %s, %s expires at %u",
snat_chain->to_chain, spadat->use_src_ip,
spadat->spa_message_remain, exp_ts
);
snat_chain->active_rules++;
snat_chain->active_rules++;
/* Reset the next expected expire time for this chain if it
* is warranted.
*/
if(snat_chain->next_expire < now || exp_ts < snat_chain->next_expire)
snat_chain->next_expire = exp_ts;
/* Reset the next expected expire time for this chain if it
* is warranted.
*/
if(snat_chain->next_expire < now || exp_ts < snat_chain->next_expire)
snat_chain->next_expire = exp_ts;
}
}
else
log_msg(LOG_ERR, "Error %i from cmd:'%s': %s", res, cmd_buf, err_buf);
}
}
+5 -5
View File
@@ -35,11 +35,11 @@
/* iptables command args
*/
#define IPT_ADD_RULE_ARGS "-t %s -A %s -p %i -s %s --dport %i -m comment --comment " EXPIRE_COMMENT_PREFIX "%u -j %s 2>&1"
#define IPT_ADD_OUT_RULE_ARGS "-t %s -A %s -p %i -d %s --sport %i -m comment --comment " EXPIRE_COMMENT_PREFIX "%u -j %s 2>&1"
#define IPT_ADD_FWD_RULE_ARGS "-t %s -A %s -p %i -s %s -d %s --dport %i -m comment --comment " EXPIRE_COMMENT_PREFIX "%u -j %s 2>&1"
#define IPT_ADD_DNAT_RULE_ARGS "-t %s -A %s -p %i -s %s --dport %i -m comment --comment " EXPIRE_COMMENT_PREFIX "%u -j %s --to-destination %s:%i 2>&1"
#define IPT_ADD_SNAT_RULE_ARGS "-t %s -A %s -p %i -d %s --dport %i -m comment --comment " EXPIRE_COMMENT_PREFIX "%u -j %s %s 2>&1"
#define IPT_RULE_ARGS "-t %s -p %i -s %s --dport %i -m comment --comment " EXPIRE_COMMENT_PREFIX "%u -j %s 2>&1"
#define IPT_OUT_RULE_ARGS "-t %s -p %i -d %s --sport %i -m comment --comment " EXPIRE_COMMENT_PREFIX "%u -j %s 2>&1"
#define IPT_FWD_RULE_ARGS "-t %s -p %i -s %s -d %s --dport %i -m comment --comment " EXPIRE_COMMENT_PREFIX "%u -j %s 2>&1"
#define IPT_DNAT_RULE_ARGS "-t %s -p %i -s %s --dport %i -m comment --comment " EXPIRE_COMMENT_PREFIX "%u -j %s --to-destination %s:%i 2>&1"
#define IPT_SNAT_RULE_ARGS "-t %s -p %i -d %s --dport %i -m comment --comment " EXPIRE_COMMENT_PREFIX "%u -j %s %s 2>&1"
#define IPT_TMP_COMMENT_ARGS "-t %s -I %s %i -s 127.0.0.2 -m comment --comment " TMP_COMMENT " -j %s 2>&1"
#define IPT_DEL_RULE_ARGS "-t %s -D %s %i 2>&1"
#define IPT_NEW_CHAIN_ARGS "-t %s -N %s 2>&1"