Merge branch 'spa_destination_ip'
This commit is contained in:
@@ -199,3 +199,13 @@ Bill Stubbs
|
||||
following platform:
|
||||
BeagleBone Black rev C running 3.8.13-bone50 #1 SMP Tue May 13
|
||||
13:24:52 UTC 2014 armv7l GNU/Linux
|
||||
|
||||
Grant Pannell
|
||||
- Submitted a patch to add a new access.conf variable "DESTINATION" in
|
||||
order to define the destination address for which an SPA packet will be
|
||||
accepted. The string "ANY" is also accepted if a valid SPA packet should
|
||||
be honored to any destination IP. Similarly to the "SOURCE" variable,
|
||||
networks should be specified in CIDR notation (e.g. "192.168.10.0/24"),
|
||||
and individual IP addresses can be specified as well. Also, multiple IP's
|
||||
and/or networks can be defined as a comma separated list (e.g.
|
||||
"192.168.10.0/24,10.1.1.123").
|
||||
|
||||
@@ -1,4 +1,12 @@
|
||||
fwknop-2.6.5 (11//2014):
|
||||
- [server] (Grant Pannell) Added a new access.conf variable "DESTINATION"
|
||||
to define the destination address for which an SPA packet will be
|
||||
accepted. The string "ANY" is also accepted if a valid SPA packet should
|
||||
be honored to any destination IP. Similarly to the "SOURCE" variable,
|
||||
networks should be specified in CIDR notation (e.g. "192.168.10.0/24"),
|
||||
and individual IP addresses can be specified as well. Also, multiple IP's
|
||||
and/or networks can be defined as a comma separated list (e.g.
|
||||
"192.168.10.0/24,10.1.1.123").
|
||||
- [server] Bug fix to ensure that proper bounds are enforced when
|
||||
importing digest cache files from previous fwknopd executions. This bug
|
||||
was discovered through fuzzing with American Fuzzy Lop (AFL) as driven
|
||||
|
||||
@@ -314,6 +314,12 @@ EXTRA_DIST = \
|
||||
test/conf/firewd_snat_fwknopd.conf \
|
||||
test/conf/ipt_snat_no_translate_ip_fwknopd.conf \
|
||||
test/conf/firewd_snat_no_translate_ip_fwknopd.conf \
|
||||
test/conf/destination_rule_fwknopd.conf \
|
||||
test/conf/hmac_spa_destination_access.conf \
|
||||
test/conf/hmac_spa_destination2_access.conf \
|
||||
test/conf/hmac_spa_destination3_access.conf \
|
||||
test/conf/hmac_spa_destination4_access.conf \
|
||||
test/conf/hmac_spa_destination5_access.conf \
|
||||
test/conf/spa_replay.pcap \
|
||||
test/conf/fcs_spa.pcap \
|
||||
test/fko-wrapper/Makefile \
|
||||
|
||||
@@ -384,6 +384,15 @@ See the '@sysconfdir@/fwknop/fwknopd.conf' file for the full list and correspond
|
||||
*SYSLOG_FACILITY* '<facility>'::
|
||||
Override syslog facility. The ``SYSLOG_FACILITY'' variable can be set to
|
||||
one of ``LOG_LOCAL{0-7}'' or ``LOG_DAEMON'' (the default).
|
||||
|
||||
*ENABLE_DESTINATION_RULE* '<Y/N>'::
|
||||
Controls whether *fwknopd* will set the destination field on the firewall
|
||||
rule to the destination address specified on the incoming SPA packet.
|
||||
This is useful for interfaces with multiple IP addresses hosting separate
|
||||
services. If ``ENABLE_IPT_OUTPUT'' is set to ``Y'', the source field of
|
||||
the firewall rule is set. FORWARD and SNAT rules are not affected however,
|
||||
DNAT rules will also have their destination field set. The default is
|
||||
``N'', which sets the destination field to 0.0.0.0/0 (any).
|
||||
|
||||
*FWKNOP_RUN_DIR* '<path>'::
|
||||
Specify the directory where *fwknopd* writes run time state files. The
|
||||
@@ -411,6 +420,15 @@ directive starts a new stanza.
|
||||
and individual IP addresses can be specified as well. Also, multiple
|
||||
IP's and/or networks can be defined as a comma separated list (e.g.
|
||||
``192.168.10.0/24,10.1.1.123'')
|
||||
|
||||
*DESTINATION* '<IP,..,IP/NET,..,NET/ANY>'::
|
||||
This defines the destination address for which the SPA packet will be
|
||||
accepted. The string ``ANY'' is also accepted if a valid SPA packet
|
||||
should be honored to any destination IP.
|
||||
Networks should be specified in CIDR notation (e.g. ``192.168.10.0/24''),
|
||||
and individual IP addresses can be specified as well. Also, multiple
|
||||
IP's and/or networks can be defined as a comma separated list (e.g.
|
||||
``192.168.10.0/24,10.1.1.123'')
|
||||
|
||||
*OPEN_PORTS* '<proto/port>,...,<proto/port>'::
|
||||
Define a set of ports and protocols (tcp or udp) that will be
|
||||
|
||||
+42
-17
@@ -229,7 +229,7 @@ add_acc_force_snat(fko_srv_options_t *opts, acc_stanza_t *curr_acc, const char *
|
||||
* comparisons of incoming source IPs against this mask.
|
||||
*/
|
||||
static int
|
||||
add_source_mask(fko_srv_options_t *opts, acc_stanza_t *acc, const char *ip)
|
||||
add_int_ent(acc_int_list_t **ilist, const char *ip)
|
||||
{
|
||||
char *ndx;
|
||||
char ip_str[MAX_IPV4_STR_LEN] = {0};
|
||||
@@ -247,7 +247,7 @@ add_source_mask(fko_srv_options_t *opts, acc_stanza_t *acc, const char *ip)
|
||||
log_msg(LOG_ERR,
|
||||
"[*] Fatal memory allocation error adding stanza source_list entry"
|
||||
);
|
||||
clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Convert the IP data into the appropriate IP + (optional) mask
|
||||
@@ -370,13 +370,13 @@ add_source_mask(fko_srv_options_t *opts, acc_stanza_t *acc, const char *ip)
|
||||
/* If this is not the first entry, we walk our pointer to the
|
||||
* end of the list.
|
||||
*/
|
||||
if(acc->source_list == NULL)
|
||||
if(*ilist == NULL)
|
||||
{
|
||||
acc->source_list = new_sle;
|
||||
*ilist = new_sle;
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp_sle = acc->source_list;
|
||||
tmp_sle = *ilist;
|
||||
|
||||
do {
|
||||
last_sle = tmp_sle;
|
||||
@@ -391,13 +391,13 @@ add_source_mask(fko_srv_options_t *opts, acc_stanza_t *acc, const char *ip)
|
||||
/* Expand the access SOURCE string to a list of masks.
|
||||
*/
|
||||
static int
|
||||
expand_acc_source(fko_srv_options_t *opts, acc_stanza_t *acc)
|
||||
expand_acc_int_list(acc_int_list_t **ilist, char *ip)
|
||||
{
|
||||
char *ndx, *start;
|
||||
char buf[ACCESS_BUF_LEN] = {0};
|
||||
int res = 1;
|
||||
|
||||
start = acc->source;
|
||||
start = ip;
|
||||
|
||||
for(ndx = start; *ndx; ndx++)
|
||||
{
|
||||
@@ -413,7 +413,7 @@ expand_acc_source(fko_srv_options_t *opts, acc_stanza_t *acc)
|
||||
|
||||
strlcpy(buf, start, (ndx-start)+1);
|
||||
|
||||
res = add_source_mask(opts, acc, buf);
|
||||
res = add_int_ent(ilist, buf);
|
||||
if(res == 0)
|
||||
return res;
|
||||
|
||||
@@ -431,7 +431,7 @@ expand_acc_source(fko_srv_options_t *opts, acc_stanza_t *acc)
|
||||
|
||||
strlcpy(buf, start, (ndx-start)+1);
|
||||
|
||||
res = add_source_mask(opts, acc, buf);
|
||||
res = add_int_ent(ilist, buf);
|
||||
|
||||
return res;
|
||||
}
|
||||
@@ -504,7 +504,7 @@ add_port_list_ent(acc_port_list_t **plist, char *port_str)
|
||||
if((new_plist = calloc(1, sizeof(acc_port_list_t))) == NULL)
|
||||
{
|
||||
log_msg(LOG_ERR,
|
||||
"[*] Fatal memory allocation error adding stanza source_list entry"
|
||||
"[*] Fatal memory allocation error adding stanza port_list entry"
|
||||
);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
@@ -677,7 +677,7 @@ expand_acc_string_list(acc_string_list_t **stlist, char *stlist_str)
|
||||
/* Free the acc source_list
|
||||
*/
|
||||
static void
|
||||
free_acc_source_list(acc_int_list_t *sle)
|
||||
free_acc_int_list(acc_int_list_t *sle)
|
||||
{
|
||||
acc_int_list_t *last_sle;
|
||||
|
||||
@@ -747,7 +747,13 @@ free_acc_stanza_data(acc_stanza_t *acc)
|
||||
if(acc->source != NULL)
|
||||
{
|
||||
free(acc->source);
|
||||
free_acc_source_list(acc->source_list);
|
||||
free_acc_int_list(acc->source_list);
|
||||
}
|
||||
|
||||
if(acc->destination != NULL)
|
||||
{
|
||||
free(acc->destination);
|
||||
free_acc_int_list(acc->destination_list);
|
||||
}
|
||||
|
||||
if(acc->open_ports != NULL)
|
||||
@@ -839,11 +845,20 @@ expand_acc_ent_lists(fko_srv_options_t *opts)
|
||||
{
|
||||
/* Expand the source string to 32-bit integer IP + masks for each entry.
|
||||
*/
|
||||
if(expand_acc_source(opts, acc) == 0)
|
||||
if(expand_acc_int_list(&(acc->source_list), acc->source) == 0)
|
||||
{
|
||||
log_msg(LOG_ERR, "[*] Fatal invalid SOURCE in access stanza");
|
||||
clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if(acc->destination != NULL && strlen(acc->destination))
|
||||
{
|
||||
if(expand_acc_int_list(&(acc->destination_list), acc->destination) == 0)
|
||||
{
|
||||
log_msg(LOG_ERR, "[*] Fatal invalid DESTINATION in access stanza");
|
||||
clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
/* Now expand the open_ports string.
|
||||
*/
|
||||
@@ -1290,6 +1305,14 @@ parse_access_file(fko_srv_options_t *opts)
|
||||
*/
|
||||
continue;
|
||||
}
|
||||
else if(CONF_VAR_IS(var, "DESTINATION"))
|
||||
{
|
||||
if(add_acc_string(&(curr_acc->destination), val) != SUCCESS)
|
||||
{
|
||||
fclose(file_ptr);
|
||||
clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
else if(CONF_VAR_IS(var, "OPEN_PORTS"))
|
||||
{
|
||||
if(add_acc_string(&(curr_acc->open_ports), val) != SUCCESS)
|
||||
@@ -1729,19 +1752,19 @@ parse_access_file(fko_srv_options_t *opts)
|
||||
}
|
||||
|
||||
int
|
||||
compare_addr_list(acc_int_list_t *source_list, const uint32_t ip)
|
||||
compare_addr_list(acc_int_list_t *ip_list, const uint32_t ip)
|
||||
{
|
||||
int match = 0;
|
||||
|
||||
while(source_list)
|
||||
while(ip_list)
|
||||
{
|
||||
if((ip & source_list->mask) == (source_list->maddr & source_list->mask))
|
||||
if((ip & ip_list->mask) == (ip_list->maddr & ip_list->mask))
|
||||
{
|
||||
match = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
source_list = source_list->next;
|
||||
ip_list = ip_list->next;
|
||||
}
|
||||
|
||||
return(match);
|
||||
@@ -1898,6 +1921,7 @@ dump_access_list(const fko_srv_options_t *opts)
|
||||
fprintf(stdout,
|
||||
"SOURCE (%i): %s\n"
|
||||
"==============================================================\n"
|
||||
" DESTINATION: %s\n"
|
||||
" OPEN_PORTS: %s\n"
|
||||
" RESTRICT_PORTS: %s\n"
|
||||
" KEY: %s\n"
|
||||
@@ -1928,6 +1952,7 @@ dump_access_list(const fko_srv_options_t *opts)
|
||||
" GPG_FINGERPRINT_ID: %s\n",
|
||||
++i,
|
||||
acc->source,
|
||||
(acc->destination == NULL) ? "<not set>" : acc->destination,
|
||||
(acc->open_ports == NULL) ? "<not set>" : acc->open_ports,
|
||||
(acc->restrict_ports == NULL) ? "<not set>" : acc->restrict_ports,
|
||||
(acc->key == NULL) ? "<not set>" : "<see the access.conf file>",
|
||||
|
||||
@@ -36,6 +36,19 @@
|
||||
# be honored from any source IP.
|
||||
#
|
||||
|
||||
# DESTINATION <IP,..,IP/NET,..,NET/ANY>
|
||||
#
|
||||
# This defines the destination address for which a SPA packet will be accepted.
|
||||
# Networks should be specified in CIDR (e.g. "192.168.10.0/24") notation.
|
||||
# Individual IP addresses can be specified as well.
|
||||
#
|
||||
# Also, multiple IP’s and/or networks can be defined as a comma-separated
|
||||
# list (e.g. "192.168.10.0/24,10.1.1.123").
|
||||
#
|
||||
# The string "ANY" is also accepted if a valid authorization packet should
|
||||
# be honored to any destination IP.
|
||||
#
|
||||
|
||||
# OPEN_PORTS <proto/port>, ..., <proto/port
|
||||
#
|
||||
# Define a set of ports and protocols (tcp or udp) that are allowed to be
|
||||
|
||||
@@ -69,6 +69,7 @@ static char *config_map[NUMBER_OF_CONFIG_ENTRIES] = {
|
||||
//"EXTERNAL_CMD_ALARM",
|
||||
//"ENABLE_EXT_CMD_PREFIX",
|
||||
//"EXT_CMD_PREFIX",
|
||||
"ENABLE_DESTINATION_RULE",
|
||||
#if FIREWALL_FIREWALLD
|
||||
"ENABLE_FIREWD_FORWARDING",
|
||||
"ENABLE_FIREWD_LOCAL_NAT",
|
||||
|
||||
@@ -427,6 +427,12 @@ validate_options(fko_srv_options_t *opts)
|
||||
if(opts->config[CONF_ENABLE_DIGEST_PERSISTENCE] == NULL)
|
||||
set_config_entry(opts, CONF_ENABLE_DIGEST_PERSISTENCE,
|
||||
DEF_ENABLE_DIGEST_PERSISTENCE);
|
||||
|
||||
/* Enable destination rule.
|
||||
*/
|
||||
if(opts->config[CONF_ENABLE_DESTINATION_RULE] == NULL)
|
||||
set_config_entry(opts, CONF_ENABLE_DESTINATION_RULE,
|
||||
DEF_ENABLE_DESTINATION_RULE);
|
||||
|
||||
/* Max sniff bytes.
|
||||
*/
|
||||
|
||||
+38
-20
@@ -70,14 +70,15 @@ chop_newline(char *str)
|
||||
static int
|
||||
rule_exists_no_chk_support(const fko_srv_options_t * const opts,
|
||||
const struct fw_chain * const fwc, const unsigned int proto,
|
||||
const char * const ip, const unsigned int port,
|
||||
const unsigned int exp_ts)
|
||||
const char * const srcip, const char * const dstip,
|
||||
const unsigned int port, const unsigned int exp_ts)
|
||||
{
|
||||
int rule_exists=0, rule_num=0, rtmp=0;
|
||||
char cmd_buf[CMD_BUFSIZE] = {0};
|
||||
char target_search[CMD_BUFSIZE] = {0};
|
||||
char proto_search[CMD_BUFSIZE] = {0};
|
||||
char ip_search[CMD_BUFSIZE] = {0};
|
||||
char srcip_search[CMD_BUFSIZE] = {0};
|
||||
char dstip_search[CMD_BUFSIZE] = {0};
|
||||
char port_search[CMD_BUFSIZE] = {0};
|
||||
char exp_ts_search[CMD_BUFSIZE] = {0};
|
||||
|
||||
@@ -98,7 +99,11 @@ rule_exists_no_chk_support(const fko_srv_options_t * const opts,
|
||||
|
||||
snprintf(port_search, CMD_BUFSIZE-1, ":%u ", port);
|
||||
snprintf(target_search, CMD_BUFSIZE-1, " %s ", fwc->target);
|
||||
snprintf(ip_search, CMD_BUFSIZE-1, " %s ", ip);
|
||||
snprintf(srcip_search, CMD_BUFSIZE-1, " %s ", srcip);
|
||||
if (dstip != NULL)
|
||||
{
|
||||
snprintf(dstip_search, CMD_BUFSIZE-1, " %s ", dstip);
|
||||
}
|
||||
snprintf(exp_ts_search, CMD_BUFSIZE-1, "%u ", exp_ts);
|
||||
|
||||
/* search for each of the substrings, and require the returned
|
||||
@@ -114,25 +119,28 @@ rule_exists_no_chk_support(const fko_srv_options_t * const opts,
|
||||
NO_TIMEOUT, proto_search, &pid_status, opts);
|
||||
if(rtmp == rule_num)
|
||||
rtmp = search_extcmd(cmd_buf, WANT_STDERR,
|
||||
NO_TIMEOUT, ip_search, &pid_status, opts);
|
||||
NO_TIMEOUT, srcip_search, &pid_status, opts);
|
||||
if(rtmp == rule_num)
|
||||
rtmp = search_extcmd(cmd_buf, WANT_STDERR,
|
||||
NO_TIMEOUT, target_search, &pid_status, opts);
|
||||
rtmp = (dstip == NULL) ? rtmp : search_extcmd(cmd_buf, WANT_STDERR,
|
||||
NO_TIMEOUT, dstip_search, &pid_status, opts);
|
||||
if(rtmp == rule_num)
|
||||
rtmp = search_extcmd(cmd_buf, WANT_STDERR,
|
||||
NO_TIMEOUT, port_search, &pid_status, opts);
|
||||
NO_TIMEOUT, target_search, &pid_status, opts);
|
||||
if(rtmp == rule_num)
|
||||
rule_exists = 1;
|
||||
rtmp = search_extcmd(cmd_buf, WANT_STDERR,
|
||||
NO_TIMEOUT, port_search, &pid_status, opts);
|
||||
if(rtmp == rule_num)
|
||||
rule_exists = 1;
|
||||
}
|
||||
|
||||
if(rule_exists)
|
||||
log_msg(LOG_DEBUG,
|
||||
"rule_exists_no_chk_support() %s %u -> %s expires: %u rule (already exists",
|
||||
proto_search, port, ip, exp_ts);
|
||||
proto_search, port, srcip, exp_ts);
|
||||
else
|
||||
log_msg(LOG_DEBUG,
|
||||
"rule_exists_no_chk_support() %s %u -> %s expires: %u rule does not exist",
|
||||
proto_search, port, ip, exp_ts);
|
||||
proto_search, port, srcip, exp_ts);
|
||||
|
||||
return(rule_exists);
|
||||
}
|
||||
@@ -174,15 +182,16 @@ rule_exists_chk_support(const fko_srv_options_t * const opts,
|
||||
static int
|
||||
rule_exists(const fko_srv_options_t * const opts,
|
||||
const struct fw_chain * const fwc, const char * const rule,
|
||||
const unsigned int proto, const char * const ip,
|
||||
const unsigned int port, const unsigned int exp_ts)
|
||||
const unsigned int proto, const char * const srcip,
|
||||
const char * const dstip, const unsigned int port,
|
||||
const unsigned int exp_ts)
|
||||
{
|
||||
int rule_exists = 0;
|
||||
|
||||
if(have_firewd_chk_support == 1)
|
||||
rule_exists = rule_exists_chk_support(opts, fwc->to_chain, rule);
|
||||
else
|
||||
rule_exists = rule_exists_no_chk_support(opts, fwc, proto, ip, port, exp_ts);
|
||||
rule_exists = rule_exists_no_chk_support(opts, fwc, proto, srcip, (opts->fw_config->use_destination ? dstip : NULL), port, exp_ts);
|
||||
|
||||
if(rule_exists == 1)
|
||||
log_msg(LOG_DEBUG, "rule_exists() Rule : '%s' in %s already exists",
|
||||
@@ -857,6 +866,11 @@ fw_config_init(fko_srv_options_t * const opts)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(strncasecmp(opts->config[CONF_ENABLE_DESTINATION_RULE], "Y", 1)==0)
|
||||
{
|
||||
fwc.use_destination = 1;
|
||||
}
|
||||
|
||||
/* Let us find it via our opts struct as well.
|
||||
*/
|
||||
@@ -1042,13 +1056,14 @@ process_spa_request(const fko_srv_options_t * const opts,
|
||||
in_chain->table,
|
||||
ple->proto,
|
||||
spadat->use_src_ip,
|
||||
(fwc.use_destination ? spadat->pkt_destination_ip : FIREWD_ANY_IP)
|
||||
ple->port,
|
||||
exp_ts,
|
||||
in_chain->target
|
||||
);
|
||||
|
||||
if(rule_exists(opts, in_chain, rule_buf,
|
||||
ple->proto, spadat->use_src_ip, ple->port, exp_ts) == 0)
|
||||
ple->proto, spadat->use_src_ip, spadat->pkt_destination_ip, ple->port, exp_ts) == 0)
|
||||
{
|
||||
if(create_rule(opts, in_chain->to_chain, rule_buf))
|
||||
{
|
||||
@@ -1078,13 +1093,14 @@ process_spa_request(const fko_srv_options_t * const opts,
|
||||
out_chain->table,
|
||||
ple->proto,
|
||||
spadat->use_src_ip,
|
||||
(fwc.use_destination ? spadat->pkt_destination_ip : FIREWD_ANY_IP),
|
||||
ple->port,
|
||||
exp_ts,
|
||||
out_chain->target
|
||||
);
|
||||
|
||||
if(rule_exists(opts, out_chain, rule_buf,
|
||||
ple->proto, spadat->use_src_ip, ple->port, exp_ts) == 0)
|
||||
ple->proto, spadat->use_src_ip, spadat->pkt_destination_ip, ple->port, exp_ts) == 0)
|
||||
{
|
||||
if(create_rule(opts, out_chain->to_chain, rule_buf))
|
||||
{
|
||||
@@ -1151,6 +1167,7 @@ process_spa_request(const fko_srv_options_t * const opts,
|
||||
in_chain->table,
|
||||
fst_proto,
|
||||
spadat->use_src_ip,
|
||||
(fwc.use_destination ? spadat->pkt_destination_ip : FIREWD_ANY_IP),
|
||||
nat_port,
|
||||
exp_ts,
|
||||
in_chain->target
|
||||
@@ -1166,7 +1183,7 @@ process_spa_request(const fko_srv_options_t * const opts,
|
||||
add_jump_rule(opts, FIREWD_INPUT_ACCESS);
|
||||
|
||||
if(rule_exists(opts, in_chain, rule_buf,
|
||||
fst_proto, spadat->use_src_ip, nat_port, exp_ts) == 0)
|
||||
fst_proto, spadat->use_src_ip, spadat->pkt_destination_ip, nat_port, exp_ts) == 0)
|
||||
{
|
||||
if(create_rule(opts, in_chain->to_chain, rule_buf))
|
||||
{
|
||||
@@ -1209,7 +1226,7 @@ process_spa_request(const fko_srv_options_t * const opts,
|
||||
);
|
||||
|
||||
if(rule_exists(opts, fwd_chain, rule_buf, fst_proto,
|
||||
spadat->use_src_ip, nat_port, exp_ts) == 0)
|
||||
spadat->use_src_ip, nat_ip, nat_port, exp_ts) == 0)
|
||||
{
|
||||
if(create_rule(opts, fwd_chain->to_chain, rule_buf))
|
||||
{
|
||||
@@ -1245,6 +1262,7 @@ process_spa_request(const fko_srv_options_t * const opts,
|
||||
dnat_chain->table,
|
||||
fst_proto,
|
||||
spadat->use_src_ip,
|
||||
(fwc.use_destination ? spadat->pkt_destination_ip : FIREWD_ANY_IP),
|
||||
fst_port,
|
||||
exp_ts,
|
||||
dnat_chain->target,
|
||||
@@ -1253,7 +1271,7 @@ process_spa_request(const fko_srv_options_t * const opts,
|
||||
);
|
||||
|
||||
if(rule_exists(opts, dnat_chain, rule_buf, fst_proto,
|
||||
spadat->use_src_ip, fst_port, exp_ts) == 0)
|
||||
spadat->use_src_ip, spadat->pkt_destination_ip, fst_port, exp_ts) == 0)
|
||||
{
|
||||
if(create_rule(opts, dnat_chain->to_chain, rule_buf))
|
||||
{
|
||||
@@ -1333,7 +1351,7 @@ process_spa_request(const fko_srv_options_t * const opts,
|
||||
);
|
||||
|
||||
if(rule_exists(opts, snat_chain, rule_buf, fst_proto,
|
||||
spadat->use_src_ip, nat_port, exp_ts) == 0)
|
||||
spadat->use_src_ip, NULL, nat_port, exp_ts) == 0)
|
||||
{
|
||||
if(create_rule(opts, snat_chain->to_chain, rule_buf))
|
||||
{
|
||||
|
||||
@@ -42,10 +42,10 @@
|
||||
/* firewalld command args
|
||||
*/
|
||||
#define FIREWD_CHK_RULE_ARGS "-C %s %s" /* the other macros add SH_REDIR if necessary */
|
||||
#define FIREWD_RULE_ARGS "-t %s -p %i -s %s --dport %i -m comment --comment " EXPIRE_COMMENT_PREFIX "%u -j %s" SH_REDIR
|
||||
#define FIREWD_OUT_RULE_ARGS "-t %s -p %i -d %s --sport %i -m comment --comment " EXPIRE_COMMENT_PREFIX "%u -j %s" SH_REDIR
|
||||
#define FIREWD_RULE_ARGS "-t %s -p %i -s %s -d %s --dport %i -m comment --comment " EXPIRE_COMMENT_PREFIX "%u -j %s" SH_REDIR
|
||||
#define FIREWD_OUT_RULE_ARGS "-t %s -p %i -d %s -s %s --sport %i -m comment --comment " EXPIRE_COMMENT_PREFIX "%u -j %s" SH_REDIR
|
||||
#define FIREWD_FWD_RULE_ARGS "-t %s -p %i -s %s -d %s --dport %i -m comment --comment " EXPIRE_COMMENT_PREFIX "%u -j %s" SH_REDIR
|
||||
#define FIREWD_DNAT_RULE_ARGS "-t %s -p %i -s %s --dport %i -m comment --comment " EXPIRE_COMMENT_PREFIX "%u -j %s --to-destination %s:%i" SH_REDIR
|
||||
#define FIREWD_DNAT_RULE_ARGS "-t %s -p %i -s %s -d %s --dport %i -m comment --comment " EXPIRE_COMMENT_PREFIX "%u -j %s --to-destination %s:%i" SH_REDIR
|
||||
#define FIREWD_SNAT_RULE_ARGS "-t %s -p %i -d %s --dport %i -m comment --comment " EXPIRE_COMMENT_PREFIX "%u -j %s %s" SH_REDIR
|
||||
#define FIREWD_TMP_COMMENT_ARGS "-t %s -I %s %i -s 127.0.0.2 -m comment --comment " TMP_COMMENT " -j %s" SH_REDIR
|
||||
#define FIREWD_TMP_CHK_RULE_ARGS "-t %s -I %s %i -s 127.0.0.2 -p udp -j %s" SH_REDIR
|
||||
@@ -60,6 +60,7 @@
|
||||
#define FIREWD_DEL_JUMP_RULE_ARGS "-t %s -D %s -j %s" SH_REDIR /* let firewalld work out the rule number */
|
||||
#define FIREWD_LIST_RULES_ARGS "-t %s -L %s --line-numbers -n" SH_REDIR
|
||||
#define FIREWD_LIST_ALL_RULES_ARGS "-t %s -v -n -L --line-numbers" SH_REDIR
|
||||
#define FIREWD_ANY_IP "0.0.0.0/0"
|
||||
|
||||
int validate_firewd_chain_conf(const char * const chain_str);
|
||||
|
||||
|
||||
@@ -72,7 +72,11 @@ fw_config_init(fko_srv_options_t *opts)
|
||||
/* Set our firewall exe command path (iptables in most cases).
|
||||
*/
|
||||
strlcpy(fwc.fw_command, opts->config[CONF_FIREWALL_EXE], sizeof(fwc.fw_command));
|
||||
|
||||
|
||||
if(strncasecmp(opts->config[CONF_ENABLE_DESTINATION_RULE], "Y", 1)==0)
|
||||
{
|
||||
fwc.use_destination = 1;
|
||||
}
|
||||
|
||||
/* Let us find it via our opts struct as well.
|
||||
*/
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
#define IPF_ADD_SNAT_RULE_ARGS ""
|
||||
#define IPF_DEL_RULE_ARGS ""
|
||||
#define IPF_LIST_RULES_ARGS ""
|
||||
#define IPF_ANY_IP ""
|
||||
|
||||
#endif /* FW_UTIL_IPF_H */
|
||||
|
||||
|
||||
@@ -238,6 +238,11 @@ fw_config_init(fko_srv_options_t * const opts)
|
||||
RCHK_MAX_IPFW_PURGE_INTERVAL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(strncasecmp(opts->config[CONF_ENABLE_DESTINATION_RULE], "Y", 1)==0)
|
||||
{
|
||||
fwc.use_destination = 1;
|
||||
}
|
||||
|
||||
/* Let us find it via our opts struct as well.
|
||||
*/
|
||||
@@ -532,6 +537,7 @@ process_spa_request(const fko_srv_options_t * const opts,
|
||||
fwc.active_set_num,
|
||||
ple->proto,
|
||||
spadat->use_src_ip,
|
||||
(fwc.use_destination ? spadat->pkt_destination_ip : IPFW_ANY_IP),
|
||||
ple->port,
|
||||
exp_ts
|
||||
);
|
||||
|
||||
@@ -40,13 +40,14 @@ enum {
|
||||
|
||||
/* ipfw command args
|
||||
*/
|
||||
#define IPFW_ADD_RULE_ARGS "add %u set %u pass %u from %s to me dst-port %u setup keep-state // " EXPIRE_COMMENT_PREFIX "%u"
|
||||
#define IPFW_ADD_RULE_ARGS "add %u set %u pass %u from %s to %s dst-port %u setup keep-state // " EXPIRE_COMMENT_PREFIX "%u"
|
||||
#define IPFW_ADD_CHECK_STATE_ARGS "add %u set %u check-state"
|
||||
#define IPFW_MOVE_RULE_ARGS "set move rule %u to %u"
|
||||
#define IPFW_MOVE_SET_ARGS "set move %u to %u"
|
||||
#define IPFW_DISABLE_SET_ARGS "set disable %u"
|
||||
#define IPFW_LIST_ALL_RULES_ARGS "list"
|
||||
#define IPFW_DEL_RULE_SET_ARGS "delete set %u"
|
||||
#define IPFW_ANY_IP "me"
|
||||
|
||||
#ifdef __APPLE__
|
||||
#define IPFW_DEL_RULE_ARGS "delete %u" //--DSS diff args
|
||||
|
||||
+38
-20
@@ -70,14 +70,15 @@ chop_newline(char *str)
|
||||
static int
|
||||
rule_exists_no_chk_support(const fko_srv_options_t * const opts,
|
||||
const struct fw_chain * const fwc, const unsigned int proto,
|
||||
const char * const ip, const unsigned int port,
|
||||
const unsigned int exp_ts)
|
||||
const char * const srcip, const char * const dstip,
|
||||
const unsigned int port, const unsigned int exp_ts)
|
||||
{
|
||||
int rule_exists=0, rule_num=0, rtmp=0;
|
||||
char cmd_buf[CMD_BUFSIZE] = {0};
|
||||
char target_search[CMD_BUFSIZE] = {0};
|
||||
char proto_search[CMD_BUFSIZE] = {0};
|
||||
char ip_search[CMD_BUFSIZE] = {0};
|
||||
char srcip_search[CMD_BUFSIZE] = {0};
|
||||
char dstip_search[CMD_BUFSIZE] = {0};
|
||||
char port_search[CMD_BUFSIZE] = {0};
|
||||
char exp_ts_search[CMD_BUFSIZE] = {0};
|
||||
|
||||
@@ -109,7 +110,11 @@ rule_exists_no_chk_support(const fko_srv_options_t * const opts,
|
||||
|
||||
snprintf(port_search, CMD_BUFSIZE-1, ":%u ", port);
|
||||
snprintf(target_search, CMD_BUFSIZE-1, " %s ", fwc->target);
|
||||
snprintf(ip_search, CMD_BUFSIZE-1, " %s ", ip);
|
||||
snprintf(srcip_search, CMD_BUFSIZE-1, " %s ", srcip);
|
||||
if (dstip != NULL)
|
||||
{
|
||||
snprintf(dstip_search, CMD_BUFSIZE-1, " %s ", dstip);
|
||||
}
|
||||
snprintf(exp_ts_search, CMD_BUFSIZE-1, "%u ", exp_ts);
|
||||
|
||||
/* search for each of the substrings, and require the returned
|
||||
@@ -125,25 +130,28 @@ rule_exists_no_chk_support(const fko_srv_options_t * const opts,
|
||||
NO_TIMEOUT, proto_search, &pid_status, opts);
|
||||
if(rtmp == rule_num)
|
||||
rtmp = search_extcmd(cmd_buf, WANT_STDERR,
|
||||
NO_TIMEOUT, ip_search, &pid_status, opts);
|
||||
NO_TIMEOUT, srcip_search, &pid_status, opts);
|
||||
if(rtmp == rule_num)
|
||||
rtmp = search_extcmd(cmd_buf, WANT_STDERR,
|
||||
NO_TIMEOUT, target_search, &pid_status, opts);
|
||||
rtmp = (dstip == NULL) ? rtmp : search_extcmd(cmd_buf, WANT_STDERR,
|
||||
NO_TIMEOUT, dstip_search, &pid_status, opts);
|
||||
if(rtmp == rule_num)
|
||||
rtmp = search_extcmd(cmd_buf, WANT_STDERR,
|
||||
NO_TIMEOUT, port_search, &pid_status, opts);
|
||||
NO_TIMEOUT, target_search, &pid_status, opts);
|
||||
if(rtmp == rule_num)
|
||||
rule_exists = 1;
|
||||
rtmp = search_extcmd(cmd_buf, WANT_STDERR,
|
||||
NO_TIMEOUT, port_search, &pid_status, opts);
|
||||
if(rtmp == rule_num)
|
||||
rule_exists = 1;
|
||||
}
|
||||
|
||||
if(rule_exists)
|
||||
log_msg(LOG_DEBUG,
|
||||
"rule_exists_no_chk_support() %s %u -> %s expires: %u rule (already exists",
|
||||
proto_search, port, ip, exp_ts);
|
||||
proto_search, port, srcip, exp_ts);
|
||||
else
|
||||
log_msg(LOG_DEBUG,
|
||||
"rule_exists_no_chk_support() %s %u -> %s expires: %u rule does not exist",
|
||||
proto_search, port, ip, exp_ts);
|
||||
proto_search, port, srcip, exp_ts);
|
||||
|
||||
return(rule_exists);
|
||||
}
|
||||
@@ -185,15 +193,16 @@ rule_exists_chk_support(const fko_srv_options_t * const opts,
|
||||
static int
|
||||
rule_exists(const fko_srv_options_t * const opts,
|
||||
const struct fw_chain * const fwc, const char * const rule,
|
||||
const unsigned int proto, const char * const ip,
|
||||
const unsigned int port, const unsigned int exp_ts)
|
||||
const unsigned int proto, const char * const srcip,
|
||||
const char * const dstip, const unsigned int port,
|
||||
const unsigned int exp_ts)
|
||||
{
|
||||
int rule_exists = 0;
|
||||
|
||||
if(have_ipt_chk_support == 1)
|
||||
rule_exists = rule_exists_chk_support(opts, fwc->to_chain, rule);
|
||||
else
|
||||
rule_exists = rule_exists_no_chk_support(opts, fwc, proto, ip, port, exp_ts);
|
||||
rule_exists = rule_exists_no_chk_support(opts, fwc, proto, srcip, (opts->fw_config->use_destination ? dstip : NULL), port, exp_ts);
|
||||
|
||||
if(rule_exists == 1)
|
||||
log_msg(LOG_DEBUG, "rule_exists() Rule : '%s' in %s already exists",
|
||||
@@ -859,6 +868,11 @@ fw_config_init(fko_srv_options_t * const opts)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(strncasecmp(opts->config[CONF_ENABLE_DESTINATION_RULE], "Y", 1)==0)
|
||||
{
|
||||
fwc.use_destination = 1;
|
||||
}
|
||||
|
||||
/* Let us find it via our opts struct as well.
|
||||
*/
|
||||
@@ -1044,13 +1058,14 @@ process_spa_request(const fko_srv_options_t * const opts,
|
||||
in_chain->table,
|
||||
ple->proto,
|
||||
spadat->use_src_ip,
|
||||
(fwc.use_destination ? spadat->pkt_destination_ip : IPT_ANY_IP),
|
||||
ple->port,
|
||||
exp_ts,
|
||||
in_chain->target
|
||||
);
|
||||
|
||||
if(rule_exists(opts, in_chain, rule_buf,
|
||||
ple->proto, spadat->use_src_ip, ple->port, exp_ts) == 0)
|
||||
ple->proto, spadat->use_src_ip, spadat->pkt_destination_ip, ple->port, exp_ts) == 0)
|
||||
{
|
||||
if(create_rule(opts, in_chain->to_chain, rule_buf))
|
||||
{
|
||||
@@ -1080,13 +1095,14 @@ process_spa_request(const fko_srv_options_t * const opts,
|
||||
out_chain->table,
|
||||
ple->proto,
|
||||
spadat->use_src_ip,
|
||||
(fwc.use_destination ? spadat->pkt_destination_ip : IPT_ANY_IP),
|
||||
ple->port,
|
||||
exp_ts,
|
||||
out_chain->target
|
||||
);
|
||||
|
||||
if(rule_exists(opts, out_chain, rule_buf,
|
||||
ple->proto, spadat->use_src_ip, ple->port, exp_ts) == 0)
|
||||
ple->proto, spadat->use_src_ip, spadat->pkt_destination_ip, ple->port, exp_ts) == 0)
|
||||
{
|
||||
if(create_rule(opts, out_chain->to_chain, rule_buf))
|
||||
{
|
||||
@@ -1153,6 +1169,7 @@ process_spa_request(const fko_srv_options_t * const opts,
|
||||
in_chain->table,
|
||||
fst_proto,
|
||||
spadat->use_src_ip,
|
||||
(fwc.use_destination ? spadat->pkt_destination_ip : IPT_ANY_IP),
|
||||
nat_port,
|
||||
exp_ts,
|
||||
in_chain->target
|
||||
@@ -1168,7 +1185,7 @@ process_spa_request(const fko_srv_options_t * const opts,
|
||||
add_jump_rule(opts, IPT_INPUT_ACCESS);
|
||||
|
||||
if(rule_exists(opts, in_chain, rule_buf,
|
||||
fst_proto, spadat->use_src_ip, nat_port, exp_ts) == 0)
|
||||
fst_proto, spadat->use_src_ip, spadat->pkt_destination_ip, nat_port, exp_ts) == 0)
|
||||
{
|
||||
if(create_rule(opts, in_chain->to_chain, rule_buf))
|
||||
{
|
||||
@@ -1211,7 +1228,7 @@ process_spa_request(const fko_srv_options_t * const opts,
|
||||
);
|
||||
|
||||
if(rule_exists(opts, fwd_chain, rule_buf, fst_proto,
|
||||
spadat->use_src_ip, nat_port, exp_ts) == 0)
|
||||
spadat->use_src_ip, nat_ip, nat_port, exp_ts) == 0)
|
||||
{
|
||||
if(create_rule(opts, fwd_chain->to_chain, rule_buf))
|
||||
{
|
||||
@@ -1247,6 +1264,7 @@ process_spa_request(const fko_srv_options_t * const opts,
|
||||
dnat_chain->table,
|
||||
fst_proto,
|
||||
spadat->use_src_ip,
|
||||
(fwc.use_destination ? spadat->pkt_destination_ip : IPT_ANY_IP),
|
||||
fst_port,
|
||||
exp_ts,
|
||||
dnat_chain->target,
|
||||
@@ -1255,7 +1273,7 @@ process_spa_request(const fko_srv_options_t * const opts,
|
||||
);
|
||||
|
||||
if(rule_exists(opts, dnat_chain, rule_buf, fst_proto,
|
||||
spadat->use_src_ip, fst_port, exp_ts) == 0)
|
||||
spadat->use_src_ip, spadat->pkt_destination_ip, fst_port, exp_ts) == 0)
|
||||
{
|
||||
if(create_rule(opts, dnat_chain->to_chain, rule_buf))
|
||||
{
|
||||
@@ -1335,7 +1353,7 @@ process_spa_request(const fko_srv_options_t * const opts,
|
||||
);
|
||||
|
||||
if(rule_exists(opts, snat_chain, rule_buf, fst_proto,
|
||||
spadat->use_src_ip, nat_port, exp_ts) == 0)
|
||||
spadat->use_src_ip, NULL, nat_port, exp_ts) == 0)
|
||||
{
|
||||
if(create_rule(opts, snat_chain->to_chain, rule_buf))
|
||||
{
|
||||
|
||||
@@ -42,10 +42,10 @@
|
||||
/* iptables command args
|
||||
*/
|
||||
#define IPT_CHK_RULE_ARGS "-C %s %s" /* the other macros add SH_REDIR if necessary */
|
||||
#define IPT_RULE_ARGS "-t %s -p %i -s %s --dport %i -m comment --comment " EXPIRE_COMMENT_PREFIX "%u -j %s" SH_REDIR
|
||||
#define IPT_OUT_RULE_ARGS "-t %s -p %i -d %s --sport %i -m comment --comment " EXPIRE_COMMENT_PREFIX "%u -j %s" SH_REDIR
|
||||
#define IPT_RULE_ARGS "-t %s -p %i -s %s -d %s --dport %i -m comment --comment " EXPIRE_COMMENT_PREFIX "%u -j %s" SH_REDIR
|
||||
#define IPT_OUT_RULE_ARGS "-t %s -p %i -d %s -s %s --sport %i -m comment --comment " EXPIRE_COMMENT_PREFIX "%u -j %s" SH_REDIR
|
||||
#define IPT_FWD_RULE_ARGS "-t %s -p %i -s %s -d %s --dport %i -m comment --comment " EXPIRE_COMMENT_PREFIX "%u -j %s" SH_REDIR
|
||||
#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" SH_REDIR
|
||||
#define IPT_DNAT_RULE_ARGS "-t %s -p %i -s %s -d %s --dport %i -m comment --comment " EXPIRE_COMMENT_PREFIX "%u -j %s --to-destination %s:%i" SH_REDIR
|
||||
#define IPT_SNAT_RULE_ARGS "-t %s -p %i -d %s --dport %i -m comment --comment " EXPIRE_COMMENT_PREFIX "%u -j %s %s" SH_REDIR
|
||||
#define IPT_TMP_COMMENT_ARGS "-t %s -I %s %i -s 127.0.0.2 -m comment --comment " TMP_COMMENT " -j %s" SH_REDIR
|
||||
#define IPT_TMP_CHK_RULE_ARGS "-t %s -I %s %i -s 127.0.0.2 -p udp -j %s" SH_REDIR
|
||||
@@ -60,6 +60,7 @@
|
||||
#define IPT_DEL_JUMP_RULE_ARGS "-t %s -D %s -j %s" SH_REDIR /* let iptables work out the rule number */
|
||||
#define IPT_LIST_RULES_ARGS "-t %s -L %s --line-numbers -n" SH_REDIR
|
||||
#define IPT_LIST_ALL_RULES_ARGS "-t %s -v -n -L --line-numbers" SH_REDIR
|
||||
#define IPT_ANY_IP "0.0.0.0/0"
|
||||
|
||||
int validate_ipt_chain_conf(const char * const chain_str);
|
||||
|
||||
|
||||
@@ -151,6 +151,11 @@ fw_config_init(fko_srv_options_t * const opts)
|
||||
/* Set the PF anchor name
|
||||
*/
|
||||
strlcpy(fwc.anchor, opts->config[CONF_PF_ANCHOR_NAME], sizeof(fwc.anchor));
|
||||
|
||||
if(strncasecmp(opts->config[CONF_ENABLE_DESTINATION_RULE], "Y", 1)==0)
|
||||
{
|
||||
fwc.use_destination = 1;
|
||||
}
|
||||
|
||||
/* Let us find it via our opts struct as well.
|
||||
*/
|
||||
@@ -243,6 +248,7 @@ process_spa_request(const fko_srv_options_t * const opts,
|
||||
snprintf(new_rule, MAX_PF_NEW_RULE_LEN-1, PF_ADD_RULE_ARGS "\n",
|
||||
ple->proto,
|
||||
spadat->use_src_ip,
|
||||
(fwc.use_destination ? spadat->pkt_destination_ip : PF_ANY_IP),
|
||||
ple->port,
|
||||
exp_ts
|
||||
);
|
||||
|
||||
+3
-2
@@ -32,7 +32,7 @@
|
||||
#define FW_UTIL_PF_H
|
||||
|
||||
#define MAX_PF_ANCHOR_SEARCH_LEN (MAX_PF_ANCHOR_LEN+11) /* room for 'anchor "' string */
|
||||
#define MAX_PF_NEW_RULE_LEN 120
|
||||
#define MAX_PF_NEW_RULE_LEN 140
|
||||
|
||||
#if HAVE_EXECVPE
|
||||
#define SH_REDIR "" /* the shell is not used when execvpe() is available */
|
||||
@@ -42,7 +42,7 @@
|
||||
|
||||
/* pf command args
|
||||
*/
|
||||
#define PF_ADD_RULE_ARGS "pass in quick proto %u from %s to any port %u keep state label " EXPIRE_COMMENT_PREFIX "%u"
|
||||
#define PF_ADD_RULE_ARGS "pass in quick proto %u from %s to %s port %u keep state label " EXPIRE_COMMENT_PREFIX "%u"
|
||||
#define PF_WRITE_ANCHOR_RULES_ARGS "-a %s -f -"
|
||||
#if HAVE_EXECVPE
|
||||
#define PF_LIST_ANCHOR_RULES_ARGS "-a %s -s rules"
|
||||
@@ -51,6 +51,7 @@
|
||||
#endif
|
||||
#define PF_ANCHOR_CHECK_ARGS "-s Anchor" SH_REDIR /* to check for fwknop anchor */
|
||||
#define PF_DEL_ALL_ANCHOR_RULES "-a %s -F all" SH_REDIR
|
||||
#define PF_ANY_IP "any"
|
||||
|
||||
#endif /* FW_UTIL_PF_H */
|
||||
|
||||
|
||||
@@ -526,6 +526,13 @@ Specify the directory where
|
||||
writes run time state files\&. The default is
|
||||
\fI@localstatedir@/run\fR\&.
|
||||
.RE
|
||||
.PP
|
||||
\fBENABLE_DESTINATION_RULE\fR \fI<Y/N>\fR
|
||||
.RS 4
|
||||
Controls whether
|
||||
\fBfwknopd\fR
|
||||
will set the destination field on the firewall rule to the destination address specified on the incoming SPA packet\&. This is useful for interfaces with multiple IP addresses hosting separate services\&. If \(lqENABLE_IPT_OUTPUT\(rq is set to \(lqY\(rq, the source field of the firewall rule is set\&. FORWARD and SNAT rules are not affected however, DNAT rules will also have their destination field set\&. The default is \(lqN\(rq, which sets the destination field to 0\&.0\&.0\&.0/0 (any)\&.
|
||||
.RE
|
||||
.SS "ACCESS\&.CONF VARIABLES"
|
||||
.sp
|
||||
This section describes the access control directives in the \fI@sysconfdir@/fwknop/access\&.conf\fR file\&. Theses directives define encryption keys and level of access that is granted to \fBfwknop\fR clients that have generated the appropriate encrypted message\&.
|
||||
@@ -539,6 +546,11 @@ This defines the source address from which the SPA packet will be accepted\&. Th
|
||||
definition must start with the \(lqSOURCE\(rq keyword\&. Networks should be specified in CIDR notation (e\&.g\&. \(lq192\&.168\&.10\&.0/24\(rq), and individual IP addresses can be specified as well\&. Also, multiple IP\(cqs and/or networks can be defined as a comma separated list (e\&.g\&. \(lq192\&.168\&.10\&.0/24,10\&.1\&.1\&.123\(rq)
|
||||
.RE
|
||||
.PP
|
||||
\fBDESTINATION\fR \fI<IP,\&.\&.,IP/NET,\&.\&.,NET/ANY>\fR
|
||||
.RS 4
|
||||
This defines the destination address for which the SPA packet will be accepted\&. The string \(lqANY\(rq is also accepted if a valid SPA packet should be honored to any destination IP\&. Networks should be specified in CIDR notation (e\&.g\&. \(lq192\&.168\&.10\&.0/24\(rq), and individual IP addresses can be specified as well\&. Also, multiple IP\(cqs and/or networks can be defined as a comma separated list (e\&.g\&. \(lq192\&.168\&.10\&.0/24,10\&.1\&.1\&.123\(rq)
|
||||
.RE
|
||||
.PP
|
||||
\fBOPEN_PORTS\fR \fI<proto/port>,\&...,<proto/port>\fR
|
||||
.RS 4
|
||||
Define a set of ports and protocols (tcp or udp) that will be opened if a valid knock sequence is seen\&. If this entry is not set,
|
||||
|
||||
@@ -152,6 +152,16 @@
|
||||
#
|
||||
# ENABLE_PCAP_ANY_DIRECTION N;
|
||||
|
||||
# Controls whether fwknopd will set the destination field on the firewall
|
||||
# rule to the destination address specified on the incoming SPA packet.
|
||||
# This is useful for interfaces with multiple IP addresses hosting separate
|
||||
# services. If ENABLE_IPT_OUTPUT is set to "Y", the source field of
|
||||
# the firewall rule is set. FORWARD and SNAT rules are not affected however,
|
||||
# DNAT rules will also have their destination field set. The default is
|
||||
# "N", which sets the destination field to 0.0.0.0/0 (any).
|
||||
#
|
||||
# ENABLE_DESTINATION_RULE Y;
|
||||
|
||||
##############################################################################
|
||||
# NOTE: The following EXTERNAL_CMD functionality is not yet implemented.
|
||||
# This is a possible future feature of fwknopd.
|
||||
|
||||
@@ -110,6 +110,7 @@
|
||||
#define DEF_UDPSERV_SELECT_TIMEOUT "500000" /* half a second (in microseconds) */
|
||||
#define DEF_SYSLOG_IDENTITY MY_NAME
|
||||
#define DEF_SYSLOG_FACILITY "LOG_DAEMON"
|
||||
#define DEF_ENABLE_DESTINATION_RULE "N"
|
||||
|
||||
#define DEF_FW_ACCESS_TIMEOUT 30
|
||||
|
||||
@@ -247,6 +248,7 @@ enum {
|
||||
//CONF_EXTERNAL_CMD_ALARM,
|
||||
//CONF_ENABLE_EXT_CMD_PREFIX,
|
||||
//CONF_EXT_CMD_PREFIX,
|
||||
CONF_ENABLE_DESTINATION_RULE,
|
||||
#if FIREWALL_FIREWALLD
|
||||
CONF_ENABLE_FIREWD_FORWARDING,
|
||||
CONF_ENABLE_FIREWD_LOCAL_NAT,
|
||||
@@ -348,6 +350,8 @@ typedef struct acc_stanza
|
||||
{
|
||||
char *source;
|
||||
acc_int_list_t *source_list;
|
||||
char *destination;
|
||||
acc_int_list_t *destination_list;
|
||||
char *open_ports;
|
||||
acc_port_list_t *oport_list;
|
||||
char *restrict_ports;
|
||||
@@ -449,6 +453,9 @@ typedef struct acc_stanza
|
||||
/* Flag for firewalld SNAT vs. MASQUERADE usage
|
||||
*/
|
||||
unsigned char use_masquerade;
|
||||
/* Flag for setting destination field in rule
|
||||
*/
|
||||
unsigned char use_destination;
|
||||
};
|
||||
|
||||
#elif FIREWALL_IPTABLES
|
||||
@@ -496,6 +503,9 @@ typedef struct acc_stanza
|
||||
/* Flag for iptables SNAT vs. MASQUERADE usage
|
||||
*/
|
||||
unsigned char use_masquerade;
|
||||
/* Flag for setting destination field in rule
|
||||
*/
|
||||
unsigned char use_destination;
|
||||
};
|
||||
|
||||
#elif FIREWALL_IPFW
|
||||
@@ -512,6 +522,7 @@ typedef struct acc_stanza
|
||||
time_t next_expire;
|
||||
time_t last_purge;
|
||||
char fw_command[MAX_PATH_LEN];
|
||||
unsigned char use_destination;
|
||||
};
|
||||
|
||||
#elif FIREWALL_PF
|
||||
@@ -523,6 +534,7 @@ typedef struct acc_stanza
|
||||
time_t next_expire;
|
||||
char anchor[MAX_PF_ANCHOR_LEN];
|
||||
char fw_command[MAX_PATH_LEN];
|
||||
unsigned char use_destination;
|
||||
};
|
||||
|
||||
#elif FIREWALL_IPF
|
||||
@@ -555,6 +567,7 @@ typedef struct spa_data
|
||||
char *spa_message;
|
||||
char spa_message_src_ip[MAX_IPV4_STR_LEN];
|
||||
char pkt_source_ip[MAX_IPV4_STR_LEN];
|
||||
char pkt_destination_ip[MAX_IPV4_STR_LEN];
|
||||
char spa_message_remain[1024]; /* --DSS FIXME: arbitrary bounds */
|
||||
char *nat_access;
|
||||
char *server_auth;
|
||||
|
||||
@@ -321,6 +321,9 @@ incoming_spa(fko_srv_options_t *opts)
|
||||
inet_ntop(AF_INET, &(spa_pkt->packet_src_ip),
|
||||
spadat.pkt_source_ip, sizeof(spadat.pkt_source_ip));
|
||||
|
||||
inet_ntop(AF_INET, &(spa_pkt->packet_dst_ip),
|
||||
spadat.pkt_destination_ip, sizeof(spadat.pkt_destination_ip));
|
||||
|
||||
/* At this point, we want to validate and (if needed) preprocess the
|
||||
* SPA data and/or to be reasonably sure we have a SPA packet (i.e
|
||||
* try to eliminate obvious non-spa packets).
|
||||
@@ -405,10 +408,14 @@ incoming_spa(fko_srv_options_t *opts)
|
||||
ctx = NULL;
|
||||
}
|
||||
|
||||
/* Check for a match for the SPA source IP and the access stanza
|
||||
/* Check for a match for the SPA source and destination IP and the access stanza
|
||||
*/
|
||||
if(! compare_addr_list(acc->source_list, ntohl(spa_pkt->packet_src_ip)))
|
||||
if(! compare_addr_list(acc->source_list, ntohl(spa_pkt->packet_src_ip)) ||
|
||||
(acc->destination_list != NULL && ! compare_addr_list(acc->destination_list, ntohl(spa_pkt->packet_dst_ip))))
|
||||
{
|
||||
log_msg(LOG_DEBUG,
|
||||
"(stanza #%d) SPA packet (%s -> %s) filtered by SOURCE and/or DESTINATION criteria",
|
||||
stanza_num, spadat.pkt_source_ip, spadat.pkt_destination_ip);
|
||||
acc = acc->next;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
ENABLE_DESTINATION_RULE Y;
|
||||
@@ -0,0 +1,5 @@
|
||||
SOURCE ANY
|
||||
DESTINATION 1.2.3.4, 127.0.0.1, 123.0.0.0/24
|
||||
KEY_BASE64 wzNP62oPPgEc+kXDPQLHPOayQBuNbYUTPP+QrErNDmg=
|
||||
HMAC_KEY_BASE64 Yh+xizBnl6FotC5ec7FanVGClRMlsOAPh2u6eovnerfBVKwaVKzjGoblFMHMc593TNyi0dWn4opLoTIV9q/ttg==
|
||||
FW_ACCESS_TIMEOUT 3
|
||||
@@ -0,0 +1,5 @@
|
||||
SOURCE ANY
|
||||
DESTINATION 1.2.3.4, 123.0.0.0/24, 127.0.0.1/32
|
||||
KEY_BASE64 wzNP62oPPgEc+kXDPQLHPOayQBuNbYUTPP+QrErNDmg=
|
||||
HMAC_KEY_BASE64 Yh+xizBnl6FotC5ec7FanVGClRMlsOAPh2u6eovnerfBVKwaVKzjGoblFMHMc593TNyi0dWn4opLoTIV9q/ttg==
|
||||
FW_ACCESS_TIMEOUT 3
|
||||
@@ -0,0 +1,5 @@
|
||||
SOURCE ANY
|
||||
DESTINATION 1.2.3.4
|
||||
KEY_BASE64 wzNP62oPPgEc+kXDPQLHPOayQBuNbYUTPP+QrErNDmg=
|
||||
HMAC_KEY_BASE64 Yh+xizBnl6FotC5ec7FanVGClRMlsOAPh2u6eovnerfBVKwaVKzjGoblFMHMc593TNyi0dWn4opLoTIV9q/ttg==
|
||||
FW_ACCESS_TIMEOUT 3
|
||||
@@ -0,0 +1,5 @@
|
||||
SOURCE ANY
|
||||
DESTINATION 1.2.3.4, 123.0.0.0/24
|
||||
KEY_BASE64 wzNP62oPPgEc+kXDPQLHPOayQBuNbYUTPP+QrErNDmg=
|
||||
HMAC_KEY_BASE64 Yh+xizBnl6FotC5ec7FanVGClRMlsOAPh2u6eovnerfBVKwaVKzjGoblFMHMc593TNyi0dWn4opLoTIV9q/ttg==
|
||||
FW_ACCESS_TIMEOUT 3
|
||||
@@ -0,0 +1,5 @@
|
||||
SOURCE ANY
|
||||
DESTINATION ANY
|
||||
KEY_BASE64 wzNP62oPPgEc+kXDPQLHPOayQBuNbYUTPP+QrErNDmg=
|
||||
HMAC_KEY_BASE64 Yh+xizBnl6FotC5ec7FanVGClRMlsOAPh2u6eovnerfBVKwaVKzjGoblFMHMc593TNyi0dWn4opLoTIV9q/ttg==
|
||||
FW_ACCESS_TIMEOUT 3
|
||||
@@ -388,6 +388,12 @@ our %cf = (
|
||||
'hmac_simple_keys_access' => "$conf_dir/hmac_simple_keys_access.conf",
|
||||
'hmac_invalid_type_access' => "$conf_dir/hmac_invalid_type_access.conf",
|
||||
'hmac_cygwin_access' => "$conf_dir/hmac_no_b64_cygwin_access.conf",
|
||||
'spa_destnation' => "$conf_dir/destination_rule_fwknopd.conf",
|
||||
'hmac_spa_destination_access' => "$conf_dir/hmac_spa_destination_access.conf",
|
||||
'hmac_spa_destination2_access' => "$conf_dir/hmac_spa_destination2_access.conf",
|
||||
'hmac_spa_destination3_access' => "$conf_dir/hmac_spa_destination3_access.conf",
|
||||
'hmac_spa_destination4_access' => "$conf_dir/hmac_spa_destination4_access.conf",
|
||||
'hmac_spa_destination5_access' => "$conf_dir/hmac_spa_destination5_access.conf",
|
||||
'exp_access' => "$conf_dir/expired_stanza_access.conf",
|
||||
'future_exp_access' => "$conf_dir/future_expired_stanza_access.conf",
|
||||
'exp_epoch_access' => "$conf_dir/expired_epoch_stanza_access.conf",
|
||||
|
||||
@@ -3335,6 +3335,38 @@
|
||||
'positive_output_matches' => [qr/No\skeys\sfound/],
|
||||
},
|
||||
|
||||
{
|
||||
'category' => 'basic operations',
|
||||
'subcategory' => 'server',
|
||||
'detail' => 'access DESTINATION missing SOURCE',
|
||||
'function' => \&server_conf_files,
|
||||
'fwknopd_cmdline' => $server_rewrite_conf_files,
|
||||
'exec_err' => $YES,
|
||||
'server_access_file' => [
|
||||
'DESTINATION 1.1.1.1',
|
||||
],
|
||||
'server_conf_file' => [
|
||||
'### comment line'
|
||||
],
|
||||
'positive_output_matches' => [qr/not\sfind\svalid\sSOURCE/],
|
||||
},
|
||||
{
|
||||
'category' => 'basic operations',
|
||||
'subcategory' => 'server',
|
||||
'detail' => 'missing access DESTINATION key',
|
||||
'function' => \&server_conf_files,
|
||||
'fwknopd_cmdline' => $server_rewrite_conf_files,
|
||||
'exec_err' => $YES,
|
||||
'server_access_file' => [
|
||||
'SOURCE 1.1.1.1',
|
||||
'DESTINATION 1.2.3.4',
|
||||
],
|
||||
'server_conf_file' => [
|
||||
'### comment line'
|
||||
],
|
||||
'positive_output_matches' => [qr/No\skeys\sfound/],
|
||||
},
|
||||
|
||||
{
|
||||
'category' => 'basic operations',
|
||||
'subcategory' => 'server',
|
||||
|
||||
@@ -83,7 +83,74 @@
|
||||
'key_file' => $cf{'rc_hmac_b64_key'},
|
||||
'client_cycles_per_server_instance' => 3,
|
||||
},
|
||||
|
||||
{
|
||||
'category' => 'Rijndael+HMAC',
|
||||
'subcategory' => 'client+server',
|
||||
'detail' => 'cycle DESTINATION accepted (1)',
|
||||
'function' => \&spa_cycle,
|
||||
'cmdline' => $default_client_hmac_args,
|
||||
'fwknopd_cmdline' => "$fwknopdCmd -c $cf{'spa_destnation'} " .
|
||||
"-a $cf{'hmac_spa_destination_access'} " .
|
||||
"-d $default_digest_file -p $default_pid_file $intf_str",
|
||||
'fw_rule_created' => $NEW_RULE_REQUIRED,
|
||||
'fw_rule_removed' => $NEW_RULE_REMOVED,
|
||||
'key_file' => $cf{'rc_hmac_b64_key'},
|
||||
'server_positive_output_matches' => [qr/\b$fake_ip\s.*$loopback_ip\b/],
|
||||
},
|
||||
{
|
||||
'category' => 'Rijndael+HMAC',
|
||||
'subcategory' => 'client+server',
|
||||
'detail' => 'cycle DESTINATION accepted (2)',
|
||||
'function' => \&spa_cycle,
|
||||
'cmdline' => $default_client_hmac_args,
|
||||
'fwknopd_cmdline' => "$fwknopdCmd -c $cf{'spa_destnation'} " .
|
||||
"-a $cf{'hmac_spa_destination2_access'} " .
|
||||
"-d $default_digest_file -p $default_pid_file $intf_str",
|
||||
'fw_rule_created' => $NEW_RULE_REQUIRED,
|
||||
'fw_rule_removed' => $NEW_RULE_REMOVED,
|
||||
'key_file' => $cf{'rc_hmac_b64_key'},
|
||||
},
|
||||
{
|
||||
'category' => 'Rijndael+HMAC',
|
||||
'subcategory' => 'client+server',
|
||||
'detail' => 'cycle DESTINATION accepted (3)',
|
||||
'function' => \&spa_cycle,
|
||||
'cmdline' => $default_client_hmac_args,
|
||||
'fwknopd_cmdline' => "$fwknopdCmd -c $cf{'spa_destnation'} " .
|
||||
"-a $cf{'hmac_spa_destination3_access'} " .
|
||||
"-d $default_digest_file -p $default_pid_file $intf_str",
|
||||
'fw_rule_created' => $NEW_RULE_REQUIRED,
|
||||
'fw_rule_removed' => $NEW_RULE_REMOVED,
|
||||
'key_file' => $cf{'rc_hmac_b64_key'},
|
||||
},
|
||||
{
|
||||
'category' => 'Rijndael+HMAC',
|
||||
'subcategory' => 'client+server',
|
||||
'detail' => 'cycle DESTINATION filtered (1)',
|
||||
'function' => \&spa_cycle,
|
||||
'cmdline' => $default_client_hmac_args,
|
||||
'fwknopd_cmdline' => "$fwknopdCmd -c $cf{'spa_destnation'} " .
|
||||
"-a $cf{'hmac_spa_destination4_access'} " .
|
||||
"-d $default_digest_file -p $default_pid_file $intf_str",
|
||||
'fw_rule_created' => $REQUIRE_NO_NEW_RULE,
|
||||
'client_pkt_tries' => 2,
|
||||
'server_receive_re' => qr/SPA\spacket\s.*filtered\sby\sSOURCE.*DEST/,
|
||||
'key_file' => $cf{'rc_hmac_b64_key'},
|
||||
},
|
||||
{
|
||||
'category' => 'Rijndael+HMAC',
|
||||
'subcategory' => 'client+server',
|
||||
'detail' => 'cycle DESTINATION filtered (2)',
|
||||
'function' => \&spa_cycle,
|
||||
'cmdline' => $default_client_hmac_args,
|
||||
'fwknopd_cmdline' => "$fwknopdCmd -c $cf{'spa_destnation'} " .
|
||||
"-a $cf{'hmac_spa_destination5_access'} " .
|
||||
"-d $default_digest_file -p $default_pid_file $intf_str",
|
||||
'fw_rule_created' => $REQUIRE_NO_NEW_RULE,
|
||||
'client_pkt_tries' => 2,
|
||||
'server_receive_re' => qr/SPA\spacket\s.*filtered\sby\sSOURCE.*DEST/,
|
||||
'key_file' => $cf{'rc_hmac_b64_key'},
|
||||
},
|
||||
{
|
||||
'category' => 'Rijndael+HMAC',
|
||||
'subcategory' => 'client+server',
|
||||
|
||||
Reference in New Issue
Block a user