[server] Bug fix for SPA NAT modes on iptables firewalls for chain re-creation

For SPA NAT modes this commit ensures that custom fwknop chains are re-created
if they get deleted out from under the running fwknopd instance.
This commit is contained in:
Michael Rash 2013-12-03 21:42:23 -05:00
parent bd73ceb5bd
commit d7aa820e33
5 changed files with 139 additions and 28 deletions

View File

@ -26,6 +26,9 @@ fwknop-2.5.2 (//2013):
recommended to use HMAC authenticated encryption whenever possible even
for GPG modes since this also provides a work around even for libfko
prior to this fix.
- [server] Bug fix for SPA NAT modes on iptables firewalls to ensure that
custom fwknop chains are re-created if they get deleted out from under
the running fwknopd instance.
- [test suite] added --gdb-test to allow a previously executed fwknop
or fwknopd command to be sent through gdb with the same command line
args as the test suite used. This is for convenience to rapidly allow

View File

@ -1141,6 +1141,15 @@ process_spa_request(const fko_srv_options_t * const opts,
in_chain->target
);
/* Check to make sure that the jump rules exist for each
* required chain
*/
if(chain_exists(opts, IPT_INPUT_ACCESS) == 0)
create_chain(opts, IPT_INPUT_ACCESS);
if(jump_rule_exists(opts, IPT_INPUT_ACCESS) == 0)
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)
{
@ -1207,7 +1216,7 @@ process_spa_request(const fko_srv_options_t * const opts,
if(strlen(dnat_chain->to_chain))
{
/* Make sure the required chain and jump rule exists
/* Make sure the required chain and jump rule exist
*/
if(chain_exists(opts, IPT_DNAT_ACCESS) == 0)
create_chain(opts, IPT_DNAT_ACCESS);
@ -1264,6 +1273,16 @@ process_spa_request(const fko_srv_options_t * const opts,
snprintf(snat_target, SNAT_TARGET_BUFSIZE-1,
"--to-source %s:%i", opts->config[CONF_SNAT_TRANSLATE_IP],
fst_port);
/* Check to make sure that the jump rules exist for each
* required chain
*/
if(chain_exists(opts, IPT_SNAT_ACCESS) == 0)
create_chain(opts, IPT_SNAT_ACCESS);
if(jump_rule_exists(opts, IPT_SNAT_ACCESS) == 0)
add_jump_rule(opts, IPT_SNAT_ACCESS);
}
else
{
@ -1271,6 +1290,15 @@ process_spa_request(const fko_srv_options_t * const opts,
snat_chain = &(opts->fw_config->chain[IPT_MASQUERADE_ACCESS]);
snprintf(snat_target, SNAT_TARGET_BUFSIZE-1,
"--to-ports %i", fst_port);
/* Check to make sure that the jump rules exist for each
* required chain
*/
if(chain_exists(opts, IPT_MASQUERADE_ACCESS) == 0)
create_chain(opts, IPT_MASQUERADE_ACCESS);
if(jump_rule_exists(opts, IPT_MASQUERADE_ACCESS) == 0)
add_jump_rule(opts, IPT_MASQUERADE_ACCESS);
}
memset(rule_buf, 0, CMD_BUFSIZE);

View File

@ -613,6 +613,7 @@ my %test_keys = (
'mv_and_restore_replay_cache' => $OPTIONAL,
'server_positive_output_matches' => $OPTIONAL,
'server_negative_output_matches' => $OPTIONAL,
'iptables_rm_chains_after_server_start' => $OPTIONAL,
);
&validate_test_hashes();
@ -4497,6 +4498,31 @@ sub client_server_interaction() {
$cmd_out_tmp, $curr_test_file);
}
if ($test_hr->{'iptables_rm_chains_after_server_start'}) {
### this deletes fwknop chains out from under the running fwknopd
### instance (tests whether it is able to recover with
### chain_exists(), etc.)
if ($test_hr->{'fwknopd_cmdline'}
=~ /LD_LIBRARY_PATH=(\S+)\s.*\s\-c\s(\S+)\s\-a\s(\S+)/) {
my $lib_path = $1;
my $fwknopd_conf = $2;
my $access_conf = $3;
&write_test_file("[+] fwknopd iptables policy before flush:\n",
$curr_test_file);
&run_cmd("LD_LIBRARY_PATH=$lib_path $fwknopdCmd -c " .
"$fwknopd_conf -a $access_conf --fw-list",
$cmd_out_tmp, $curr_test_file);
&run_cmd("LD_LIBRARY_PATH=$lib_path $fwknopdCmd -c " .
"$fwknopd_conf -a $access_conf --fw-flush",
$cmd_out_tmp, $curr_test_file);
&write_test_file("[+] fwknopd iptables policy after flush:\n",
$curr_test_file);
&run_cmd("LD_LIBRARY_PATH=$lib_path $fwknopdCmd -c " .
"$fwknopd_conf -a $access_conf --fw-list",
$cmd_out_tmp, $curr_test_file);
}
}
### send the SPA packet(s) to the server either manually using IO::Socket or
### with the fwknopd client
if ($spa_client_flag == $USE_CLIENT) {

View File

@ -699,7 +699,7 @@
"-d $default_digest_file -p $default_pid_file $intf_str",
'server_positive_output_matches' => [
qr/FWKNOP_FORWARD\s.*dport\s22\s/,
qr/to\:$internal_nat_host\:22/i],
qr/\*\/\sto\:$internal_nat_host\:22/i],
'fw_rule_created' => $NEW_RULE_REQUIRED,
'fw_rule_removed' => $NEW_RULE_REMOVED,
'server_conf' => $cf{'nat'},
@ -714,7 +714,7 @@
"-d $default_digest_file -p $default_pid_file $intf_str",
'server_positive_output_matches' => [
qr/FWKNOP_FORWARD\s.*dport\s22\s/,
qr/to\:$internal_nat_host\:22/i],
qr/\*\/\sto\:$internal_nat_host\:22/i],
'no_ip_check' => 1,
'fw_rule_created' => $NEW_RULE_REQUIRED,
'fw_rule_removed' => $NEW_RULE_REMOVED,
@ -730,7 +730,7 @@
"-d $default_digest_file -p $default_pid_file $intf_str",
'server_positive_output_matches' => [
qr/FWKNOP_FORWARD\s.*dport\s22\s/,
qr/to\:$internal_nat_host\:22/i,
qr/\*\/\sto\:$internal_nat_host\:22/i,
qr/MASQUERADE\s.*to\-ports/,
],
'no_ip_check' => 1,
@ -749,7 +749,7 @@
"-d $default_digest_file -p $default_pid_file $intf_str",
'server_positive_output_matches' => [
qr/FWKNOP_FORWARD\s.*dport\s22\s/,
qr/to\:127.0.0.1\:22/i],
qr/\*\/\sto\:127.0.0.1\:22/i],
'fw_rule_created' => $NEW_RULE_REQUIRED,
'fw_rule_removed' => $NEW_RULE_REMOVED,
'server_conf' => $cf{'nat'},
@ -766,7 +766,7 @@
"-d $default_digest_file -p $default_pid_file $intf_str",
'server_positive_output_matches' => [
qr/FWKNOP_FORWARD\s.*dport\s22\s/,
qr/to\:$internal_nat_host\:22/i],
qr/\*\/\sto\:$internal_nat_host\:22/i],
'fw_rule_created' => $NEW_RULE_REQUIRED,
'fw_rule_removed' => $NEW_RULE_REMOVED,
'server_conf' => $cf{'nat'},
@ -803,9 +803,9 @@
'cmdline' => "$default_client_args --nat-local",
'fwknopd_cmdline' => "$fwknopdCmd -c $cf{'local_nat'} -a $cf{'force_nat_access'} " .
"-d $default_digest_file -p $default_pid_file $intf_str",
'server_positive_output_matches' => [qr/to\:$force_nat_host\:22/i,
'server_positive_output_matches' => [qr/\*\/\sto\:$force_nat_host\:22/i,
qr/FWKNOP_INPUT.*dport\s22.*\sACCEPT/],
'server_negative_output_matches' => [qr/to\:$internal_nat_host\:22/i],
'server_negative_output_matches' => [qr/\*\/\sto\:$internal_nat_host\:22/i],
'fw_rule_created' => $NEW_RULE_REQUIRED,
'fw_rule_removed' => $NEW_RULE_REMOVED,
'server_conf' => $cf{'local_nat'},
@ -819,9 +819,9 @@
"--get-key $local_key_file --no-save-args $verbose_str",
'fwknopd_cmdline' => "$fwknopdCmd -c $cf{'local_nat'} -a $cf{'force_nat_access'} " .
"-d $default_digest_file -p $default_pid_file $intf_str",
'server_positive_output_matches' => [qr/to\:$force_nat_host\:22/i,
'server_positive_output_matches' => [qr/\*\/\sto\:$force_nat_host\:22/i,
qr/FWKNOP_INPUT.*dport\s22.*\sACCEPT/],
'server_negative_output_matches' => [qr/to\:$internal_nat_host\:22/i],
'server_negative_output_matches' => [qr/\*\/\sto\:$internal_nat_host\:22/i],
'fw_rule_created' => $NEW_RULE_REQUIRED,
'fw_rule_removed' => $NEW_RULE_REMOVED,
'server_conf' => $cf{'local_nat'},
@ -835,9 +835,9 @@
'cmdline' => "$default_client_args --nat-local --nat-rand-port",
'fwknopd_cmdline' => "$fwknopdCmd -c $cf{'local_nat'} -a $cf{'def_access'} " .
"-d $default_digest_file -p $default_pid_file $intf_str",
'server_positive_output_matches' => [qr/to\:$loopback_ip\:22/i,
'server_positive_output_matches' => [qr|\s\*\/\sto\:$loopback_ip\:22|i,
qr/FWKNOP_INPUT.*dport\s22.*\sACCEPT/],
'server_negative_output_matches' => [qr/to\:$internal_nat_host\:22/i],
'server_negative_output_matches' => [qr/\*\/\sto\:$internal_nat_host\:22/i],
'fw_rule_created' => $NEW_RULE_REQUIRED,
'fw_rule_removed' => $NEW_RULE_REMOVED,
'server_conf' => $cf{'local_nat'},
@ -885,9 +885,9 @@
"$local_key_file $verbose_str --nat-local --nat-port 80",
'fwknopd_cmdline' => "$fwknopdCmd -c $cf{'local_nat'} -a $cf{'def_access'} " .
"-d $default_digest_file -p $default_pid_file $intf_str",
'server_positive_output_matches' => [qr/to\:$loopback_ip\:22/i,
'server_positive_output_matches' => [qr|\s\*\/\sto\:$loopback_ip\:22|i,
qr/FWKNOP_INPUT.*dport\s22.*\sACCEPT/],
'server_negative_output_matches' => [qr/to\:$internal_nat_host\:22/i],
'server_negative_output_matches' => [qr/\*\/\sto\:$internal_nat_host\:22/i],
'fw_rule_created' => $NEW_RULE_REQUIRED,
'fw_rule_removed' => $NEW_RULE_REMOVED,
'server_conf' => $cf{'local_nat'},

View File

@ -747,7 +747,7 @@
"-d $default_digest_file -p $default_pid_file $intf_str",
'server_positive_output_matches' => [
qr/FWKNOP_FORWARD\s.*dport\s22\s/,
qr/to\:$internal_nat_host\:22/i],
qr/\*\/\sto\:$internal_nat_host\:22/i],
'fw_rule_created' => $NEW_RULE_REQUIRED,
'fw_rule_removed' => $NEW_RULE_REMOVED,
'key_file' => $cf{'rc_hmac_b64_key'},
@ -764,7 +764,7 @@
"-d $default_digest_file -p $default_pid_file $intf_str",
'server_positive_output_matches' => [
qr/FWKNOP_FORWARD\s.*dport\s22\s/,
qr/to\:$internal_nat_host\:22/i],
qr/\*\/\sto\:$internal_nat_host\:22/i],
'no_ip_check' => 1,
'fw_rule_created' => $NEW_RULE_REQUIRED,
'fw_rule_removed' => $NEW_RULE_REMOVED,
@ -782,7 +782,7 @@
"-d $default_digest_file -p $default_pid_file $intf_str",
'server_positive_output_matches' => [
qr/FWKNOP_FORWARD\s.*dport\s22\s/,
qr/to\:$internal_nat_host\:22/i,
qr/\*\/\sto\:$internal_nat_host\:22/i,
qr/MASQUERADE\s.*to\-ports/,
],
'no_ip_check' => 1,
@ -802,7 +802,7 @@
"-d $default_digest_file -p $default_pid_file $intf_str",
'server_positive_output_matches' => [
qr/FWKNOP_FORWARD_TEST\s.*dport\s22\s/,
qr/to\:$internal_nat_host\:22/i],
qr/\*\/\sto\:$internal_nat_host\:22/i],
'fw_rule_created' => $NEW_RULE_REQUIRED,
'fw_rule_removed' => $NEW_RULE_REMOVED,
'key_file' => $cf{'rc_hmac_b64_key'},
@ -820,7 +820,7 @@
"-d $default_digest_file -p $default_pid_file $intf_str",
'server_positive_output_matches' => [
qr/FWKNOP_FORWARD\s.*dport\s22\s/,
qr/to\:$internal_nat_host\:22/i],
qr/\*\/\sto\:$internal_nat_host\:22/i],
'fw_rule_created' => $NEW_RULE_REQUIRED,
'fw_rule_removed' => $NEW_RULE_REMOVED,
'server_conf' => $cf{'nat'},
@ -853,6 +853,24 @@
'server_conf' => $cf{'nat'},
'key_file' => $cf{'rc_hmac_b64_key'},
},
{
'category' => 'Rijndael+HMAC',
'subcategory' => 'client+server',
'detail' => "force NAT (iptables flush)",
'function' => \&spa_cycle,
'cmdline' => $default_client_args,
'cmdline' => "$default_client_args_no_get_key --rc-file " .
$cf{'rc_hmac_b64_key'},
'fwknopd_cmdline' => "$fwknopdCmd -c $cf{'nat'} -a $cf{'hmac_force_nat_access'} " .
"-d $default_digest_file -p $default_pid_file $intf_str",
'server_positive_output_matches' => [qr/\sto\:$force_nat_host\:22/i],
'server_negative_output_matches' => [qr/\sto\:$internal_nat_host\:22/i],
'fw_rule_created' => $NEW_RULE_REQUIRED,
'fw_rule_removed' => $NEW_RULE_REMOVED,
'server_conf' => $cf{'nat'},
'key_file' => $cf{'rc_hmac_b64_key'},
'iptables_rm_chains_after_server_start' => $YES,
},
{
'category' => 'Rijndael+HMAC',
'subcategory' => 'client+server',
@ -862,9 +880,9 @@
"$cf{'rc_hmac_b64_key'} --nat-local",
'fwknopd_cmdline' => "$fwknopdCmd -c $cf{'local_nat'} -a $cf{'hmac_force_nat_access'} " .
"-d $default_digest_file -p $default_pid_file $intf_str",
'server_positive_output_matches' => [qr/to\:$force_nat_host\:22/i,
'server_positive_output_matches' => [qr/\*\/\sto\:$force_nat_host\:22/i,
qr/FWKNOP_INPUT.*dport\s22.*\sACCEPT/],
'server_negative_output_matches' => [qr/to\:$internal_nat_host\:22/i],
'server_negative_output_matches' => [qr/\*\/\sto\:$internal_nat_host\:22/i],
'fw_rule_created' => $NEW_RULE_REQUIRED,
'fw_rule_removed' => $NEW_RULE_REMOVED,
'server_conf' => $cf{'local_nat'},
@ -873,20 +891,56 @@
{
'category' => 'Rijndael+HMAC',
'subcategory' => 'client+server',
'detail' => "local NAT non-FORCE_NAT",
'detail' => "local NAT (iptables flush)",
'function' => \&spa_cycle,
'cmdline' => "$default_client_args_no_get_key --rc-file " .
"$cf{'rc_hmac_b64_key'} --nat-local",
'fwknopd_cmdline' => "$fwknopdCmd -c $cf{'local_nat'} -a $cf{'hmac_force_nat_access'} " .
"-d $default_digest_file -p $default_pid_file $intf_str",
'server_positive_output_matches' => [qr/\*\/\sto\:$force_nat_host\:22/i,
qr/FWKNOP_INPUT.*dport\s22.*\sACCEPT/],
'server_negative_output_matches' => [qr/\*\/\sto\:$internal_nat_host\:22/i],
'fw_rule_created' => $NEW_RULE_REQUIRED,
'fw_rule_removed' => $NEW_RULE_REMOVED,
'server_conf' => $cf{'local_nat'},
'key_file' => $cf{'rc_hmac_b64_key'},
'iptables_rm_chains_after_server_start' => $YES,
},
{
'category' => 'Rijndael+HMAC',
'subcategory' => 'client+server',
'detail' => "local (non-force) NAT",
'function' => \&spa_cycle,
'cmdline' => "$fwknopCmd -A tcp/22 -a $fake_ip -D $loopback_ip --rc-file " .
"$cf{'rc_hmac_b64_key'} $verbose_str --nat-local --nat-port 80",
'fwknopd_cmdline' => "$fwknopdCmd -c $cf{'local_nat'} -a $cf{'hmac_access'} " .
"-d $default_digest_file -p $default_pid_file $intf_str",
'server_positive_output_matches' => [qr/to\:$loopback_ip\:22/i,
qr/FWKNOP_INPUT.*dport\s22.*\sACCEPT/],
'server_negative_output_matches' => [qr/to\:$internal_nat_host\:22/i],
'server_positive_output_matches' => [qr|\s\*\/\sto\:$loopback_ip\:22|i,
qr/ACCEPT\s{2}.*\s0\.0\.0\.0\/0\s+tcp\sdpt\:22\s/],
'server_negative_output_matches' => [qr/\*\/\sto\:$internal_nat_host\:22/i],
'fw_rule_created' => $NEW_RULE_REQUIRED,
'fw_rule_removed' => $NEW_RULE_REMOVED,
'server_conf' => $cf{'local_nat'},
'key_file' => $cf{'rc_hmac_b64_key'},
},
{
'category' => 'Rijndael+HMAC',
'subcategory' => 'client+server',
'detail' => "local (non-force) NAT (ipt flush)",
'function' => \&spa_cycle,
'cmdline' => "$fwknopCmd -A tcp/22 -a $fake_ip -D $loopback_ip --rc-file " .
"$cf{'rc_hmac_b64_key'} $verbose_str --nat-local --nat-port 80",
'fwknopd_cmdline' => "$fwknopdCmd -c $cf{'local_nat'} -a $cf{'hmac_access'} " .
"-d $default_digest_file -p $default_pid_file $intf_str",
'server_positive_output_matches' => [qr|\s\*\/\sto\:$loopback_ip\:22|i,
qr/ACCEPT\s{2}.*\s0\.0\.0\.0\/0\s+tcp\sdpt\:22\s/],
'server_negative_output_matches' => [qr/\*\/\sto\:$internal_nat_host\:22/i],
'fw_rule_created' => $NEW_RULE_REQUIRED,
'fw_rule_removed' => $NEW_RULE_REMOVED,
'server_conf' => $cf{'local_nat'},
'key_file' => $cf{'rc_hmac_b64_key'},
'iptables_rm_chains_after_server_start' => $YES,
},
{
'category' => 'Rijndael+HMAC',
@ -897,9 +951,9 @@
"$cf{'rc_hmac_b64_key'} $verbose_str --nat-local --nat-rand-port",
'fwknopd_cmdline' => "$fwknopdCmd -c $cf{'local_nat'} -a $cf{'hmac_access'} " .
"-d $default_digest_file -p $default_pid_file $intf_str",
'server_positive_output_matches' => [qr/to\:$loopback_ip\:22/i,
qr/FWKNOP_INPUT.*dport\s22.*\sACCEPT/],
'server_negative_output_matches' => [qr/to\:$internal_nat_host\:22/i],
'server_positive_output_matches' => [qr|\s\*\/\sto\:$loopback_ip\:22|i,
qr/ACCEPT\s{2}.*\s0\.0\.0\.0\/0\s+tcp\sdpt\:22\s/],
'server_negative_output_matches' => [qr/\*\/\sto\:$internal_nat_host\:22/i],
'fw_rule_created' => $NEW_RULE_REQUIRED,
'fw_rule_removed' => $NEW_RULE_REMOVED,
'server_conf' => $cf{'local_nat'},