[server] added the ability to use FORCE_MASQUERADE to access.conf stanzas
authorMichael Rash <mbr@cipherdyne.org>
Fri, 6 Dec 2013 04:00:19 +0000 (23:00 -0500)
committerMichael Rash <mbr@cipherdyne.org>
Fri, 6 Dec 2013 04:00:19 +0000 (23:00 -0500)
Makefile.am
server/access.c
server/fw_util_iptables.c
server/fwknopd_common.h
test/test-fwknop.pl
test/tests/rijndael_hmac.pl

index eb9218d..89e4a4d 100644 (file)
@@ -145,7 +145,6 @@ EXTRA_DIST = \
     test/conf/expired_epoch_stanza_access.conf \
     test/conf/expired_stanza_access.conf \
     test/conf/force_nat_access.conf \
-    test/conf/force_nat_access.conf \
     test/conf/future_expired_stanza_access.conf \
     test/conf/fuzzing_open_ports_access.conf \
     test/conf/fuzzing_restrict_ports_access.conf \
@@ -186,6 +185,8 @@ EXTRA_DIST = \
     test/conf/hmac_simple_keys_access.conf \
     test/conf/hmac_sha256_open_ports_access.conf \
     test/conf/hmac_force_nat_access.conf \
+    test/conf/hmac_force_snat_access.conf \
+    test/conf/hmac_force_masq_access.conf \
     test/conf/hmac_no_b64_cygwin_access.conf \
     test/conf/fwknoprc_default_hmac_base64_key \
     test/conf/fwknoprc_hmac_key2 \
index 88699f7..d504a3d 100644 (file)
@@ -992,6 +992,15 @@ acc_data_is_valid(acc_stanza_t * const acc)
         return(0);
     }
 
+    if(acc->force_masquerade == 1 && acc->force_nat == 0)
+    {
+        log_msg(LOG_ERR,
+                "[*] FORCE_MASQUERADE implies FORCE_NAT must also be used for access stanza source: '%s'",
+                acc->source
+        );
+        return(0);
+    }
+
     if(acc->require_source_address == 0)
     {
         log_msg(LOG_INFO,
@@ -1395,6 +1404,11 @@ parse_access_file(fko_srv_options_t *opts)
             clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
 #endif
         }
+        else if(CONF_VAR_IS(var, "FORCE_MASQUERADE"))
+        {
+            add_acc_bool(&(curr_acc->force_masquerade), val);
+            add_acc_bool(&(curr_acc->force_snat), val);
+        }
         else
         {
             log_msg(LOG_ERR,
@@ -1643,6 +1657,8 @@ dump_access_list(const fko_srv_options_t *opts)
             "             FORCE_NAT (ip):  %s\n"
             "          FORCE_NAT (proto):  %s\n"
             "           FORCE_NAT (port):  %d\n"
+            "            FORCE_SNAT (ip):  %s\n"
+            "           FORCE_MASQUERADE:  %s\n"
             "              ACCESS_EXPIRE:  %s"  /* asctime() adds a newline */
             "               GPG_HOME_DIR:  %s\n"
             "             GPG_DECRYPT_ID:  %s\n"
@@ -1669,6 +1685,8 @@ dump_access_list(const fko_srv_options_t *opts)
             acc->force_nat ? acc->force_nat_ip : "<not set>",
             acc->force_nat && acc->force_nat_proto != NULL ? acc->force_nat_proto : "<not set>",
             acc->force_nat ? acc->force_nat_port : 0,
+            acc->force_snat ? acc->force_snat_ip : "<not set>",
+            acc->force_masquerade ? "Yes" : "No",
             (acc->access_expire_time > 0) ? asctime(localtime(&acc->access_expire_time)) : "<not set>\n",
             (acc->gpg_home_dir == NULL) ? "<not set>" : acc->gpg_home_dir,
             (acc->gpg_decrypt_id == NULL) ? "<not set>" : acc->gpg_decrypt_id,
index 5460430..2770276 100644 (file)
@@ -1272,6 +1272,14 @@ process_spa_request(const fko_srv_options_t * const opts,
                     "--to-source %s:%i", acc->force_snat_ip, fst_port);
                 snat_chain_num = IPT_SNAT_ACCESS;
             }
+            else if(acc->force_snat && acc->force_masquerade)
+            {
+                /* Using MASQUERADE */
+                snat_chain = &(opts->fw_config->chain[IPT_MASQUERADE_ACCESS]);
+                snprintf(snat_target, SNAT_TARGET_BUFSIZE-1,
+                    "--to-ports %i", fst_port);
+                snat_chain_num = IPT_MASQUERADE_ACCESS;
+            }
             else if((opts->config[CONF_SNAT_TRANSLATE_IP] != NULL)
                 && is_valid_ipv4_addr(opts->config[CONF_SNAT_TRANSLATE_IP]))
             {
index b06c849..fffb89e 100644 (file)
@@ -333,6 +333,7 @@ typedef struct acc_stanza
     */
     unsigned char        force_snat;
     char                *force_snat_ip;
+    unsigned char        force_masquerade;
 
     struct acc_stanza   *next;
 } acc_stanza_t;
index 0a6905c..b2c886e 100755 (executable)
@@ -80,6 +80,7 @@ our %cf = (
     'force_nat_access'             => "$conf_dir/force_nat_access.conf",
     'hmac_force_nat_access'        => "$conf_dir/hmac_force_nat_access.conf",
     'hmac_force_snat_access'       => "$conf_dir/hmac_force_snat_access.conf",
+    'hmac_force_masq_access'       => "$conf_dir/hmac_force_masq_access.conf",
     'cmd_access'                   => "$conf_dir/cmd_access.conf",
     'local_nat'                    => "$conf_dir/local_nat_fwknopd.conf",
     'no_flush_init'                => "$conf_dir/no_flush_init_fwknopd.conf",
index 3d65639..c3003d1 100644 (file)
     {
         'category' => 'Rijndael+HMAC',
         'subcategory' => 'client+server',
+        'detail'   => "force MASQ $force_snat_host (tcp/22)",
+        '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{'snat_no_translate_ip'} -a $cf{'hmac_force_masq_access'} " .
+            "-d $default_digest_file -p $default_pid_file $intf_str",
+        'server_positive_output_matches' => [qr/DNAT\s.*\*\/\sto\:$force_nat_host2\:22/i,
+            qr/MASQUERADE\s.*\s$force_nat_host2\s.*\smasq\sports\:\s22/],
+        'server_negative_output_matches' => [qr/\*\/\sto\:$internal_nat_host\:22/i,
+            qr/\*\/\sto\:$force_nat_host\:22/i],
+        'fw_rule_created' => $NEW_RULE_REQUIRED,
+        'fw_rule_removed' => $NEW_RULE_REMOVED,
+        'server_conf' => $cf{'snat_no_translate_ip'},
+        'key_file' => $cf{'rc_hmac_b64_key'},
+    },
+    {
+        'category' => 'Rijndael+HMAC',
+        'subcategory' => 'client+server',
+        'detail'   => "force MASQ $force_snat_host (ipt 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{'snat_no_translate_ip'} -a $cf{'hmac_force_masq_access'} " .
+            "-d $default_digest_file -p $default_pid_file $intf_str",
+        'server_positive_output_matches' => [qr/DNAT\s.*\*\/\sto\:$force_nat_host2\:22/i,
+            qr/MASQUERADE\s.*\s$force_nat_host2\s.*\smasq\sports\:\s22/],
+        'server_negative_output_matches' => [qr/\*\/\sto\:$internal_nat_host\:22/i,
+            qr/\*\/\sto\:$force_nat_host\:22/i],
+        'fw_rule_created' => $NEW_RULE_REQUIRED,
+        'fw_rule_removed' => $NEW_RULE_REMOVED,
+        'server_conf' => $cf{'snat_no_translate_ip'},
+        'key_file' => $cf{'rc_hmac_b64_key'},
+        'iptables_rm_chains_after_server_start' => $YES,
+    },
+    {
+        'category' => 'Rijndael+HMAC',
+        'subcategory' => 'client+server',
         'detail'   => "force NAT (iptables flush)",
         'function' => \&spa_cycle,
         'cmdline'  => $default_client_args,