diff --git a/server/fw_util_firewalld.c b/server/fw_util_firewalld.c index d93bf7bb..96da72db 100644 --- a/server/fw_util_firewalld.c +++ b/server/fw_util_firewalld.c @@ -685,7 +685,7 @@ mk_chain(const fko_srv_options_t * const opts, const int chain_num) if(! create_chain(opts, chain_num)) err++; - if (jump_rule_exists(opts, chain_num)) + if (! jump_rule_exists(opts, chain_num)) if(! add_jump_rule(opts, chain_num)) err++; @@ -815,7 +815,7 @@ fw_config_init(fko_srv_options_t * const opts) #if FIREWALL_FIREWALLD char cmd_passthru[512]; snprintf(cmd_passthru, sizeof cmd_passthru, "%s %s ", - opts->config[CONF_FIREWALL_EXE], " --direct --passthrough ipv4 "); + opts->config[CONF_FIREWALL_EXE], FIREWD_CMD_PREFIX); strlcpy(fwc.fw_command, cmd_passthru, sizeof(fwc.fw_command)); #else strlcpy(fwc.fw_command, opts->config[CONF_FIREWALL_EXE], sizeof(fwc.fw_command)); @@ -852,6 +852,9 @@ fw_config_init(fko_srv_options_t * const opts) */ if(strncasecmp(opts->config[CONF_ENABLE_FIREWD_SNAT], "Y", 1)==0) { + /* Support both SNAT and MASQUERADE - this will be controlled + * via the access.conf configuration for individual rules + */ if(set_fw_chain_conf(FIREWD_MASQUERADE_ACCESS, opts->config[CONF_FIREWD_MASQUERADE_ACCESS]) != 1) return 0; @@ -1296,27 +1299,36 @@ process_spa_request(const fko_srv_options_t * const opts, if(spadat->message_type == FKO_LOCAL_NAT_ACCESS_MSG || spadat->message_type == FKO_CLIENT_TIMEOUT_LOCAL_NAT_ACCESS_MSG || spadat->message_type == FKO_NAT_ACCESS_MSG - || spadat->message_type == FKO_CLIENT_TIMEOUT_NAT_ACCESS_MSG) + || spadat->message_type == FKO_CLIENT_TIMEOUT_NAT_ACCESS_MSG + || acc->force_nat) { - ndx = strchr(spadat->nat_access, ','); - if(ndx != NULL) + if(acc->force_nat) { - strlcpy(nat_ip, spadat->nat_access, (ndx-spadat->nat_access)+1); - if (! is_valid_ipv4_addr(nat_ip)) + strlcpy(nat_ip, acc->force_nat_ip, sizeof(nat_ip)); + nat_port = acc->force_nat_port; + } + else + { + ndx = strchr(spadat->nat_access, ','); + if(ndx != NULL) { - log_msg(LOG_INFO, "Invalid NAT IP in SPA message"); - free_acc_port_list(port_list); - return res; - } + strlcpy(nat_ip, spadat->nat_access, (ndx-spadat->nat_access)+1); + if (! is_valid_ipv4_addr(nat_ip)) + { + log_msg(LOG_INFO, "Invalid NAT IP in SPA message"); + free_acc_port_list(port_list); + return res; + } - nat_port = strtol_wrapper(ndx+1, 0, MAX_PORT, - NO_EXIT_UPON_ERR, &is_err); - if(is_err != FKO_SUCCESS) - { - log_msg(LOG_INFO, "Invalid NAT port in SPA message"); - free_acc_port_list(port_list); - res = is_err; - return res; + nat_port = strtol_wrapper(ndx+1, 0, MAX_PORT, + NO_EXIT_UPON_ERR, &is_err); + if(is_err != FKO_SUCCESS) + { + log_msg(LOG_INFO, "Invalid NAT port in SPA message"); + free_acc_port_list(port_list); + res = is_err; + return res; + } } } @@ -1335,35 +1347,13 @@ process_spa_request(const fko_srv_options_t * const opts, nat_port, fst_proto, fst_port, spadat, exp_ts, now); } - /* DNAT rule - */ - if(strlen(dnat_chain->to_chain)) - dnat_rule(opts, acc, dnat_chain, nat_ip, - nat_port, fst_proto, fst_port, spadat, exp_ts, now); - - if(acc->force_snat) - snat_rule(opts, acc, nat_ip, nat_port, - fst_proto, fst_port, spadat, exp_ts, now); - } - else if(acc->force_nat) /* handle force NAT scenarios */ - { - strlcpy(nat_ip, acc->force_nat_ip, sizeof(nat_ip)); - nat_port = acc->force_nat_port; - - /* FORWARD access rule - */ - if(strlen(fwd_chain->to_chain)) - forward_access_rule(opts, acc, fwd_chain, nat_ip, - nat_port, fst_proto, fst_port, spadat, exp_ts, now); - /* DNAT rule */ if(strlen(dnat_chain->to_chain) && !acc->disable_dnat) dnat_rule(opts, acc, dnat_chain, nat_ip, - nat_port, fst_proto, fst_port, spadat, exp_ts, now); + nat_port, fst_proto, fst_port, spadat, exp_ts, now); - /* SNAT rule if required - we only allow this for FORCE_NAT - * access stanzas for now until a new SPA packet type is added. + /* SNAT rule */ if(acc->force_snat || strncasecmp(opts->config[CONF_ENABLE_FIREWD_SNAT], "Y", 1) == 0) snat_rule(opts, acc, nat_ip, nat_port, diff --git a/server/fw_util_firewalld.h b/server/fw_util_firewalld.h index 9b2534e7..fdac0dcb 100644 --- a/server/fw_util_firewalld.h +++ b/server/fw_util_firewalld.h @@ -34,6 +34,7 @@ #define SNAT_TARGET_BUFSIZE 64 #define FIREWD_CMD_FAIL_STR "COMMAND_FAILED" /* returned by firewall-cmd */ +#define FIREWD_CMD_PREFIX "--direct --passthrough ipv4" #if HAVE_EXECVPE #define SH_REDIR "" /* the shell is not used when execvpe() is available */ diff --git a/server/fw_util_iptables.c b/server/fw_util_iptables.c index f20cf98b..e355c04c 100644 --- a/server/fw_util_iptables.c +++ b/server/fw_util_iptables.c @@ -844,6 +844,9 @@ fw_config_init(fko_srv_options_t * const opts) */ if(strncasecmp(opts->config[CONF_ENABLE_IPT_SNAT], "Y", 1)==0) { + /* Support both SNAT and MASQUERADE - this will be controlled + * via the access.conf configuration for individual rules + */ if(set_fw_chain_conf(IPT_MASQUERADE_ACCESS, opts->config[CONF_IPT_MASQUERADE_ACCESS]) != 1) return 0; @@ -1290,27 +1293,36 @@ process_spa_request(const fko_srv_options_t * const opts, if(spadat->message_type == FKO_LOCAL_NAT_ACCESS_MSG || spadat->message_type == FKO_CLIENT_TIMEOUT_LOCAL_NAT_ACCESS_MSG || spadat->message_type == FKO_NAT_ACCESS_MSG - || spadat->message_type == FKO_CLIENT_TIMEOUT_NAT_ACCESS_MSG) + || spadat->message_type == FKO_CLIENT_TIMEOUT_NAT_ACCESS_MSG + || acc->force_nat) { - ndx = strchr(spadat->nat_access, ','); - if(ndx != NULL) + if(acc->force_nat) { - strlcpy(nat_ip, spadat->nat_access, (ndx-spadat->nat_access)+1); - if (! is_valid_ipv4_addr(nat_ip)) + strlcpy(nat_ip, acc->force_nat_ip, sizeof(nat_ip)); + nat_port = acc->force_nat_port; + } + else + { + ndx = strchr(spadat->nat_access, ','); + if(ndx != NULL) { - log_msg(LOG_INFO, "Invalid NAT IP in SPA message"); - free_acc_port_list(port_list); - return res; - } + strlcpy(nat_ip, spadat->nat_access, (ndx-spadat->nat_access)+1); + if (! is_valid_ipv4_addr(nat_ip)) + { + log_msg(LOG_INFO, "Invalid NAT IP in SPA message"); + free_acc_port_list(port_list); + return res; + } - nat_port = strtol_wrapper(ndx+1, 0, MAX_PORT, - NO_EXIT_UPON_ERR, &is_err); - if(is_err != FKO_SUCCESS) - { - log_msg(LOG_INFO, "Invalid NAT port in SPA message"); - free_acc_port_list(port_list); - res = is_err; - return res; + nat_port = strtol_wrapper(ndx+1, 0, MAX_PORT, + NO_EXIT_UPON_ERR, &is_err); + if(is_err != FKO_SUCCESS) + { + log_msg(LOG_INFO, "Invalid NAT port in SPA message"); + free_acc_port_list(port_list); + res = is_err; + return res; + } } } @@ -1331,33 +1343,11 @@ process_spa_request(const fko_srv_options_t * const opts, /* DNAT rule */ - if(strlen(dnat_chain->to_chain)) + if(strlen(dnat_chain->to_chain) && !acc->disable_nat) dnat_rule(opts, acc, dnat_chain, nat_ip, nat_port, fst_proto, fst_port, spadat, exp_ts, now); - if(acc->force_snat) - snat_rule(opts, acc, nat_ip, nat_port, - fst_proto, fst_port, spadat, exp_ts, now); - } - else if(acc->force_nat) /* handle force NAT scenarios */ - { - strlcpy(nat_ip, acc->force_nat_ip, sizeof(nat_ip)); - nat_port = acc->force_nat_port; - - /* FORWARD access rule - */ - if(strlen(fwd_chain->to_chain)) - forward_access_rule(opts, acc, fwd_chain, nat_ip, - nat_port, fst_proto, fst_port, spadat, exp_ts, now); - - /* DNAT rule - */ - if(strlen(dnat_chain->to_chain) && !acc->disable_dnat) - dnat_rule(opts, acc, dnat_chain, nat_ip, - nat_port, fst_proto, fst_port, spadat, exp_ts, now); - - /* SNAT rule if required - we only allow this for FORCE_NAT - * access stanzas for now until a new SPA packet type is added. + /* SNAT rule */ if(acc->force_snat || strncasecmp(opts->config[CONF_ENABLE_IPT_SNAT], "Y", 1) == 0) snat_rule(opts, acc, nat_ip, nat_port, diff --git a/server/fwknopd.conf b/server/fwknopd.conf index 1c2621a2..f406acc5 100644 --- a/server/fwknopd.conf +++ b/server/fwknopd.conf @@ -303,7 +303,7 @@ # FIREWD_MASQUERADE_ACCESS variable. # #FIREWD_SNAT_ACCESS SNAT, nat, POSTROUTING, 1, FWKNOP_POSTROUTING, 1; -#FIREWD_MASQUERADE_ACCESS MASQUERADE, nat, POSTROUTING, 1, FWKNOP_POSTROUTING, 1; +#FIREWD_MASQUERADE_ACCESS MASQUERADE, nat, POSTROUTING, 1, FWKNOP_MASQUERADE, 1; # The ENABLE_COMMENT_MATCH_CHECK variable instructs fwknopd to check for the # firewalld 'comment' match at start up. If it's not found, then fwknopd will @@ -411,7 +411,7 @@ # IPT_MASQUERADE_ACCESS variable. # #IPT_SNAT_ACCESS SNAT, nat, POSTROUTING, 1, FWKNOP_POSTROUTING, 1; -#IPT_MASQUERADE_ACCESS MASQUERADE, nat, POSTROUTING, 1, FWKNOP_POSTROUTING, 1; +#IPT_MASQUERADE_ACCESS MASQUERADE, nat, POSTROUTING, 1, FWKNOP_MASQUERADE, 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 diff --git a/server/fwknopd_common.h b/server/fwknopd_common.h index 7b191041..dc6f5160 100644 --- a/server/fwknopd_common.h +++ b/server/fwknopd_common.h @@ -141,7 +141,7 @@ #define DEF_FIREWD_FORWARD_ACCESS "ACCEPT, filter, FORWARD, 1, FWKNOP_FORWARD, 1" #define DEF_FIREWD_DNAT_ACCESS "DNAT, nat, PREROUTING, 1, FWKNOP_PREROUTING, 1" #define DEF_FIREWD_SNAT_ACCESS "SNAT, nat, POSTROUTING, 1, FWKNOP_POSTROUTING, 1" - #define DEF_FIREWD_MASQUERADE_ACCESS "MASQUERADE, nat, POSTROUTING, 1, FWKNOP_POSTROUTING, 1" + #define DEF_FIREWD_MASQUERADE_ACCESS "MASQUERADE, nat, POSTROUTING, 1, FWKNOP_MASQUERADE, 1" #define RCHK_MAX_FIREWD_RULE_NUM (2 << 15) @@ -161,7 +161,7 @@ #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_IPT_MASQUERADE_ACCESS "MASQUERADE, nat, POSTROUTING, 1, FWKNOP_MASQUERADE, 1" #define RCHK_MAX_IPT_RULE_NUM (2 << 15)