From: Michael Rash Date: Sun, 12 Aug 2012 19:44:13 +0000 (-0400) Subject: [server] iptables 'comment' match check X-Git-Tag: fwknop-2.0.2~18 X-Git-Url: http://www.cipherdyne.com/cgi-bin/gitweb.cgi?p=fwknop.git;a=commitdiff_plain;h=543de16613b89723ef1350df3e59df126586800e [server] iptables 'comment' match check Implemented a new check to ensure that the iptables 'comment' match exists to ensure the proper environment for fwknopd operations. This check is controlled by the new ENABLE_IPT_COMMENT_CHECK variable, and was suggested by Hank Leininger. --- diff --git a/CREDITS b/CREDITS index 0e1ba85..ab6edd0 100644 --- a/CREDITS +++ b/CREDITS @@ -48,3 +48,8 @@ Geoff Carstairs This allows for better access control for multple users requiring access to multiple internal systems, in a manner that is transparent to the user. The result was the FORCE_NAT mode. + +Hank Leininger + - For iptables firewalls, suggested a check for the 'comment' match to + ensure the local environment will properly support fwknopd operations. + The result is the new ENABLE_IPT_COMMENT_CHECK functionality. diff --git a/ChangeLog b/ChangeLog index dc0027e..326a23e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -58,6 +58,10 @@ fwknop-2.0.2 (08//2012): - [test suite] Added GPG tests for keyrings that have no associated passphrases. + - [server] Implemented a new check to ensure that the iptables 'comment' + match exists to ensure the proper environment for fwknopd operations. + This check is controlled by the new ENABLE_IPT_COMMENT_CHECK variable, + and was suggested by Hank Leininger. fwknop-2.0.1 (07/23/2012): - [server] Bug fix where the same encryption key used for two stanzas in diff --git a/server/cmd_opts.h b/server/cmd_opts.h index 05dc9ca..0abe85d 100644 --- a/server/cmd_opts.h +++ b/server/cmd_opts.h @@ -78,6 +78,7 @@ static char *config_map[NUMBER_OF_CONFIG_ENTRIES] = { "IPT_DNAT_ACCESS", "IPT_SNAT_ACCESS", "IPT_MASQUERADE_ACCESS", + "ENABLE_IPT_COMMENT_CHECK", #elif FIREWALL_IPFW "FLUSH_IPFW_AT_INIT", "FLUSH_IPFW_AT_EXIT", diff --git a/server/config_init.c b/server/config_init.c index f83ce20..2ac667a 100644 --- a/server/config_init.c +++ b/server/config_init.c @@ -458,6 +458,12 @@ validate_options(fko_srv_options_t *opts) set_config_entry(opts, CONF_IPT_MASQUERADE_ACCESS, DEF_IPT_MASQUERADE_ACCESS); + /* Check for the iptables 'comment' match at init time + */ + if(opts->config[CONF_ENABLE_IPT_COMMENT_CHECK] == NULL) + set_config_entry(opts, CONF_ENABLE_IPT_COMMENT_CHECK, + DEF_ENABLE_IPT_COMMENT_CHECK); + #elif FIREWALL_IPFW /* Flush ipfw rules at init. diff --git a/server/fw_util.h b/server/fw_util.h index 1f520fe..f958388 100644 --- a/server/fw_util.h +++ b/server/fw_util.h @@ -37,6 +37,7 @@ #define STANDARD_CMD_OUT_BUFSIZE 4096 #define EXPIRE_COMMENT_PREFIX "_exp_" +#define TMP_COMMENT "__TMPCOMMENT__" #if FIREWALL_IPTABLES #include "fw_util_iptables.h" diff --git a/server/fw_util_iptables.c b/server/fw_util_iptables.c index 8e11470..ad1648a 100644 --- a/server/fw_util_iptables.c +++ b/server/fw_util_iptables.c @@ -53,6 +53,70 @@ zero_cmd_buffers(void) } static int +comment_match_exists(const fko_srv_options_t *opts) +{ + int res = 1; + char *ndx = NULL; + struct fw_chain *in_chain = &(opts->fw_config->chain[IPT_INPUT_ACCESS]); + + zero_cmd_buffers(); + + /* Add a harmless rule to the iptables OUTPUT chain that uses the comment + * match and make sure it exists. If not, return zero. Otherwise, delete + * the rule and return true. + */ + snprintf(cmd_buf, CMD_BUFSIZE-1, "%s " IPT_TMP_COMMENT_ARGS, + opts->fw_config->fw_command, + in_chain->table, + in_chain->to_chain, + 1, /* first rule */ + in_chain->target + ); + + res = run_extcmd(cmd_buf, err_buf, CMD_BUFSIZE, 0); + + if (opts->verbose) + log_msg(LOG_INFO, "comment_match_exists() CMD: '%s' (res: %d, err: %s)", + cmd_buf, res, err_buf); + + zero_cmd_buffers(); + + snprintf(cmd_buf, CMD_BUFSIZE-1, "%s " IPT_LIST_RULES_ARGS, + opts->fw_config->fw_command, + in_chain->table, + in_chain->to_chain + ); + + res = run_extcmd(cmd_buf, cmd_out, STANDARD_CMD_OUT_BUFSIZE, 0); + + if(!EXTCMD_IS_SUCCESS(res)) + log_msg(LOG_ERR, "Error %i from cmd:'%s': %s", res, cmd_buf, cmd_out); + + ndx = strstr(cmd_out, TMP_COMMENT); + if(ndx == NULL) + res = 0; /* did not find the tmp comment */ + else + res = 1; + + if(res == 1) + { + /* Delete the tmp comment rule + */ + zero_cmd_buffers(); + + snprintf(cmd_buf, CMD_BUFSIZE-1, "%s " IPT_DEL_RULE_ARGS, + opts->fw_config->fw_command, + in_chain->table, + in_chain->to_chain, + 1 + ); + run_extcmd(cmd_buf, err_buf, CMD_BUFSIZE, 0); + } + + return res; +} + +static int add_jump_rule(const fko_srv_options_t *opts, const int chain_num) { int res = 0; @@ -205,7 +269,7 @@ fw_dump_rules(const fko_srv_options_t *opts) /* 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); + log_msg(LOG_ERR, "Error %i from cmd:'%s': %s", res, cmd_buf, err_buf); got_err++; } } @@ -466,6 +530,15 @@ fw_initialize(const fko_srv_options_t *opts) fprintf(stderr, "Warning: Errors detected during fwknop custom chain creation.\n"); exit(EXIT_FAILURE); } + + /* Make sure that the 'comment' match is available + */ + if((strncasecmp(opts->config[CONF_ENABLE_IPT_COMMENT_CHECK], "Y", 1) == 0) + && (comment_match_exists(opts) != 1)) + { + fprintf(stderr, "Warning: Could not use the 'comment' match.\n"); + exit(EXIT_FAILURE); + } } int diff --git a/server/fw_util_iptables.h b/server/fw_util_iptables.h index d8ef36b..9c706e5 100644 --- a/server/fw_util_iptables.h +++ b/server/fw_util_iptables.h @@ -40,6 +40,7 @@ #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_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" #define IPT_FLUSH_CHAIN_ARGS "-t %s -F %s 2>&1" diff --git a/server/fwknopd.conf b/server/fwknopd.conf index 6aed85e..c8afc08 100644 --- a/server/fwknopd.conf +++ b/server/fwknopd.conf @@ -264,6 +264,15 @@ #IPT_SNAT_ACCESS SNAT, nat, POSTROUTING, 1, FWKNOP_POSTROUTING, 1; #IPT_MASQUERADE_ACCESS MASQUERADE, nat, POSTROUTING, 1, FWKNOP_POSTROUTING, 1; +# The ENABLE_COMMENT_MATCH_CHECK variable instructs fwknopd to check for the +# iptables 'comment' match at start up. If it's not found, then fwknopd will +# exit and throw an error. This variable is enabled by default, but can be +# disabled if you want fwknopd to run without being sure that the comment match +# if available (not recommended, since the comment match enables new SPA rules +# to be timed out). +# +#ENABLE_IPT_COMMENT_CHECK Y; + ############################################################################## # Parameters specific to ipfw: # diff --git a/server/fwknopd_common.h b/server/fwknopd_common.h index 3ba797d..a6f0655 100644 --- a/server/fwknopd_common.h +++ b/server/fwknopd_common.h @@ -104,18 +104,19 @@ */ #if FIREWALL_IPTABLES - #define DEF_FLUSH_IPT_AT_INIT "Y" - #define DEF_FLUSH_IPT_AT_EXIT "Y" - #define DEF_ENABLE_IPT_FORWARDING "N" - #define DEF_ENABLE_IPT_LOCAL_NAT "Y" - #define DEF_ENABLE_IPT_SNAT "N" - #define DEF_ENABLE_IPT_OUTPUT "N" - #define DEF_IPT_INPUT_ACCESS "ACCEPT, filter, INPUT, 1, FWKNOP_INPUT, 1" - #define DEF_IPT_OUTPUT_ACCESS "ACCEPT, filter, OUTPUT, 1, FWKNOP_OUTPUT, 1" - #define DEF_IPT_FORWARD_ACCESS "ACCEPT, filter, FORWARD, 1, FWKNOP_FORWARD, 1" - #define DEF_IPT_DNAT_ACCESS "DNAT, nat, PREROUTING, 1, FWKNOP_PREROUTING, 1" - #define DEF_IPT_SNAT_ACCESS "SNAT, nat, POSTROUTING, 1, FWKNOP_POSTROUTING, 1" - #define DEF_IPT_MASQUERADE_ACCESS "MASQUERADE, nat, POSTROUTING, 1, FWKNOP_POSTROUTING, 1" + #define DEF_FLUSH_IPT_AT_INIT "Y" + #define DEF_FLUSH_IPT_AT_EXIT "Y" + #define DEF_ENABLE_IPT_FORWARDING "N" + #define DEF_ENABLE_IPT_LOCAL_NAT "Y" + #define DEF_ENABLE_IPT_SNAT "N" + #define DEF_ENABLE_IPT_OUTPUT "N" + #define DEF_ENABLE_IPT_COMMENT_CHECK "Y" + #define DEF_IPT_INPUT_ACCESS "ACCEPT, filter, INPUT, 1, FWKNOP_INPUT, 1" + #define DEF_IPT_OUTPUT_ACCESS "ACCEPT, filter, OUTPUT, 1, FWKNOP_OUTPUT, 1" + #define DEF_IPT_FORWARD_ACCESS "ACCEPT, filter, FORWARD, 1, FWKNOP_FORWARD, 1" + #define DEF_IPT_DNAT_ACCESS "DNAT, nat, PREROUTING, 1, FWKNOP_PREROUTING, 1" + #define DEF_IPT_SNAT_ACCESS "SNAT, nat, POSTROUTING, 1, FWKNOP_POSTROUTING, 1" + #define DEF_IPT_MASQUERADE_ACCESS "MASQUERADE, nat, POSTROUTING, 1, FWKNOP_POSTROUTING, 1" /* Ipfw-specific defines */ @@ -201,6 +202,7 @@ enum { CONF_IPT_DNAT_ACCESS, CONF_IPT_SNAT_ACCESS, CONF_IPT_MASQUERADE_ACCESS, + CONF_ENABLE_IPT_COMMENT_CHECK, #elif FIREWALL_IPFW CONF_FLUSH_IPFW_AT_INIT, CONF_FLUSH_IPFW_AT_EXIT, diff --git a/todo.org b/todo.org index 78ca683..322b01d 100644 --- a/todo.org +++ b/todo.org @@ -1,6 +1,9 @@ * fwknop tasks This is the main todo org mode file for the fwknop project -** fwknopd iptables comment match detection +** COMPLETED + This bucket is for completed tasks. +*** fwknopd iptables comment match detection + :CLOSED: <2012-08-12 Sun> Hank Leininger suggested that fwknopd do better detection for the iptables comment match since it is required for the expiration of SPA rules. ** Include files for access.conf