diff --git a/server/cmd_opts.h b/server/cmd_opts.h index 724f1db8..b0b6646d 100644 --- a/server/cmd_opts.h +++ b/server/cmd_opts.h @@ -80,6 +80,7 @@ static char *config_map[NUMBER_OF_CONFIG_ENTRIES] = { //"ENABLE_EXT_CMD_PREFIX", //"EXT_CMD_PREFIX", "ENABLE_DESTINATION_RULE", + "ENABLE_RULE_PREPEND", "ENABLE_NAT_DNS", #if FIREWALL_FIREWALLD "ENABLE_FIREWD_FORWARDING", diff --git a/server/config_init.c b/server/config_init.c index c4ded34d..a7c436d1 100644 --- a/server/config_init.c +++ b/server/config_init.c @@ -879,6 +879,10 @@ validate_options(fko_srv_options_t *opts) #endif /* FIREWALL type */ + /* Prepend firewall rules*/ + if(opts->config[CONF_ENABLE_PREPEND] == NULL) + set_config_entry(opts, CONF_ENABLE_PREPEND, DEF_ENABLE_PREPEND); + /* NAT DNS enabled*/ if(opts->config[CONF_ENABLE_NAT_DNS] == NULL) set_config_entry(opts, CONF_ENABLE_NAT_DNS, DEF_ENABLE_NAT_DNS); diff --git a/server/fw_util_firewalld.c b/server/fw_util_firewalld.c index 7e5733a6..b5f2d2f7 100644 --- a/server/fw_util_firewalld.c +++ b/server/fw_util_firewalld.c @@ -1166,8 +1166,13 @@ create_rule(const fko_srv_options_t * const opts, zero_cmd_buffers(); - snprintf(cmd_buf, CMD_BUFSIZE-1, "%s -A %s %s", - opts->fw_config->fw_command, fw_chain, fw_rule); + if (strncasecmp(opts->config[CONF_ENABLE_PREPEND], "Y", 1) == 0) { + snprintf(cmd_buf, CMD_BUFSIZE-1, "%s -I %s %s", + opts->fw_config->fw_command, fw_chain, fw_rule); + } else { + 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, WANT_STDERR, NO_TIMEOUT, &pid_status, opts); diff --git a/server/fw_util_iptables.c b/server/fw_util_iptables.c index 5f7be375..68d1235a 100644 --- a/server/fw_util_iptables.c +++ b/server/fw_util_iptables.c @@ -1154,9 +1154,13 @@ create_rule(const fko_srv_options_t * const opts, zero_cmd_buffers(); - snprintf(cmd_buf, CMD_BUFSIZE-1, "%s -A %s %s", - opts->fw_config->fw_command, fw_chain, fw_rule); - + if (strncasecmp(opts->config[CONF_ENABLE_PREPEND], "Y", 1) == 0) { + snprintf(cmd_buf, CMD_BUFSIZE-1, "%s -I %s %s", + opts->fw_config->fw_command, fw_chain, fw_rule); + } else { + 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, WANT_STDERR, NO_TIMEOUT, &pid_status, opts); chop_newline(err_buf); diff --git a/server/fwknopd.conf b/server/fwknopd.conf index 178b6718..d788c48e 100644 --- a/server/fwknopd.conf +++ b/server/fwknopd.conf @@ -147,6 +147,12 @@ # Allow fwknopd to resolve hostnames in NAT access messages #ENABLE_NAT_DNS Y; +# Instead of appending new firewall rules to the bottom of the chain, this +# option inserts rules at the top of the chain. This causes later rules +# to have precedence over earlier rules. +# +#ENABLE_RULE_PREPEND N; + # Enable the fwknopd TCP server. This is a "dummy" TCP server that will # accept TCP connection requests on the specified TCPSERV_PORT. # If set to "Y", fwknopd will fork off a child process to listen for and diff --git a/server/fwknopd_common.h b/server/fwknopd_common.h index 2906710f..8814cb4e 100644 --- a/server/fwknopd_common.h +++ b/server/fwknopd_common.h @@ -94,6 +94,7 @@ #define DEF_RULES_CHECK_THRESHOLD "20" #define DEF_MAX_SNIFF_BYTES "1500" #define DEF_GPG_HOME_DIR "/root/.gnupg" +#define DEF_ENABLE_PREPEND "N" #define DEF_ENABLE_NAT_DNS "Y" #ifdef GPG_EXE #define DEF_GPG_EXE GPG_EXE @@ -279,6 +280,7 @@ enum { //CONF_ENABLE_EXT_CMD_PREFIX, //CONF_EXT_CMD_PREFIX, CONF_ENABLE_DESTINATION_RULE, + CONF_ENABLE_PREPEND, CONF_ENABLE_NAT_DNS, #if FIREWALL_FIREWALLD CONF_ENABLE_FIREWD_FORWARDING,