Merge remote-tracking branch 'upstream/master'
This commit is contained in:
@@ -124,3 +124,7 @@ Shawn Wilson
|
||||
- Added better SPA source IP logging for various fwknopd logging messages.
|
||||
This helps to make it more clear why certain SPA packets are rejected
|
||||
from some systems.
|
||||
|
||||
Dan Lauber
|
||||
- Suggested a check for fwknopd to ensure that the jump rule on systems
|
||||
running iptables is not duplicated if it already exists.
|
||||
|
||||
@@ -2,10 +2,14 @@ fwknop-2.5 (//2013):
|
||||
- Major release of new functionality - HMAC authenticated encryption
|
||||
support in the encrypt-then-authenticate model for SPA communications.
|
||||
Supported HMAC digests include MD5, SHA1, SHA256, SHA384, and SHA512.
|
||||
The default is HMAC-SHA256 when HMAC is used. HMAC is supported for both
|
||||
Rijndael and GPG encrypted SPA packet data, and provides a significant
|
||||
security benefit since the HMAC verification is more simplisitic than
|
||||
decryption operations (particularly for GPG).
|
||||
The default is HMAC-SHA256 when an HMAC is used. The HMAC mode is
|
||||
supported for both Rijndael and GPG encrypted SPA packet data, and
|
||||
provides a significant security benefit for the fwknopd server since the
|
||||
HMAC verification is more simplisitic than decryption operations. This
|
||||
is particularly true for GPG. Beyond this, HMAC authenticated
|
||||
encryption in the encrypt-then-authenticate mode does not suffer from
|
||||
things like CBC-mode padding oracle attacks (see the Vaudenay attack and
|
||||
the more recent "Lucky 13" attack against SSL).
|
||||
- [libfko] Significant bug fix to honor the full encryption key length for
|
||||
user-supplied Rijndael keys > 16 bytes long. Previous to this fix,
|
||||
only the first 16 bytes of a key were actually used in the encryption/
|
||||
@@ -13,13 +17,15 @@ fwknop-2.5 (//2013):
|
||||
a weakening of expected security for users that had keys > 16 bytes,
|
||||
although this is probably not too common. Note that "passphrase" is
|
||||
perhaps technically a better word for "user-supplied key" in this
|
||||
context since Rijndael in CBC mode derives a real encryption/decryption
|
||||
key from the passphrase through a series of applications of md5 against
|
||||
the passphrase and a random salt. This issue was reported by Michael T.
|
||||
Dean. Closes issue #18 on github.
|
||||
context since the actual key is generated with the PBKDF1 key derivation
|
||||
algorithm. This issue was reported by Michael T. Dean. Closes issue #18
|
||||
on github.
|
||||
- [libfko] Added the ability to maintain backwards compatibility with the
|
||||
now deprecated "zero padding" key derivation strategy in AES mode that
|
||||
was a hold over from the old perl fwknop implementation.
|
||||
was a hold over from the old perl fwknop implementation. This is NOT
|
||||
compliant with PBKDF1 and is only brought forward into fwknop-2.5 for
|
||||
backwards compatibility. Future versions of fwknop will remove this
|
||||
code altogether since PBKDF1 is now implemented.
|
||||
- [test suite] Added --enable-openssl-checks to send all SPA packets
|
||||
encrypted via libfko through the OpenSSL library to ensure that the
|
||||
libfko usage of AES is always compatible with OpenSSL. This ensures
|
||||
|
||||
@@ -151,6 +151,7 @@ EXTRA_DIST = \
|
||||
test/conf/hmac_access.conf \
|
||||
test/conf/hmac_get_key_access.conf \
|
||||
test/conf/hmac_no_b64_access.conf \
|
||||
test/conf/hmac_equal_keys_access.conf \
|
||||
test/conf/hmac_dual_key_usage_access.conf \
|
||||
test/conf/hmac_invalid_type_access.conf \
|
||||
test/conf/hmac_md5_access.conf \
|
||||
@@ -176,6 +177,7 @@ EXTRA_DIST = \
|
||||
test/conf/fwknoprc_default_hmac_base64_key \
|
||||
test/conf/fwknoprc_hmac_key2 \
|
||||
test/conf/fwknoprc_gpg_hmac_key \
|
||||
test/conf/fwknoprc_hmac_equal_keys \
|
||||
test/conf/fwknoprc_hmac_invalid_type \
|
||||
test/conf/fwknoprc_hmac_md5_key \
|
||||
test/conf/fwknoprc_hmac_md5_long_key \
|
||||
|
||||
+43
-26
@@ -507,13 +507,15 @@ create_fwknoprc(const char *rcfile)
|
||||
"#\n"
|
||||
"# Each section (or stanza) is identified and started by a line in this\n"
|
||||
"# file that contains a single identifier surrounded by square brackets.\n"
|
||||
"# It is this identifier (or name) that is used from the fwknop command line\n"
|
||||
"# via the '-n <name>' argument to reference the corresponding stanza.\n"
|
||||
"#\n"
|
||||
"# The parameters within the stanza typicaly match corresponding client \n"
|
||||
"# command-line parameters.\n"
|
||||
"#\n"
|
||||
"# The first one should always be `[default]' as it defines the global\n"
|
||||
"# default settings for the user. These override the program defaults\n"
|
||||
"# for these parameter. If a named stanza is used, its entries will\n"
|
||||
"# for these parameters. If a named stanza is used, its entries will\n"
|
||||
"# override any of the default. Command-line options will trump them\n"
|
||||
"# all.\n"
|
||||
"#\n"
|
||||
@@ -1285,6 +1287,26 @@ update_rc(fko_cli_options_t *options, uint32_t args_bitmask)
|
||||
static void
|
||||
validate_options(fko_cli_options_t *options)
|
||||
{
|
||||
|
||||
if ( (options->use_rc_stanza[0] != 0x0)
|
||||
&& (options->got_named_stanza == 0)
|
||||
&& (options->save_rc_stanza == 0) )
|
||||
{
|
||||
log_msg(LOG_VERBOSITY_ERROR,
|
||||
"Named configuration stanza: [%s] was not found.",
|
||||
options->use_rc_stanza);
|
||||
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if ( (options->save_rc_stanza == 1) && (options->use_rc_stanza[0] == 0) )
|
||||
{
|
||||
log_msg(LOG_VERBOSITY_ERROR,
|
||||
"The option --save-rc-stanza must be used with the "
|
||||
"--named-config option to specify the stanza to update.");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Gotta have a Destination unless we are just testing or getting the
|
||||
* the version, and must use one of [-s|-R|-a].
|
||||
*/
|
||||
@@ -1304,33 +1326,23 @@ validate_options(fko_cli_options_t *options)
|
||||
if (options->resolve_url != NULL)
|
||||
options->resolve_ip_http = 1;
|
||||
|
||||
if (!options->resolve_ip_http && options->allow_ip_str[0] == 0x0)
|
||||
if (!options->resolve_ip_http)
|
||||
{
|
||||
log_msg(LOG_VERBOSITY_ERROR,
|
||||
"Must use one of [-s|-R|-a] to specify IP for SPA access.");
|
||||
exit(EXIT_FAILURE);
|
||||
if(options->allow_ip_str[0] == 0x0)
|
||||
{
|
||||
log_msg(LOG_VERBOSITY_ERROR,
|
||||
"Must use one of [-s|-R|-a] to specify IP for SPA access.");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
else if(options->verbose
|
||||
&& strncmp(options->allow_ip_str, "0.0.0.0", strlen("0.0.0.0")) == 0)
|
||||
{
|
||||
log_msg(LOG_VERBOSITY_WARNING,
|
||||
"[-] WARNING: Should use -a or -R to harden SPA against potential MITM attacks");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( (options->use_rc_stanza[0] != 0x0)
|
||||
&& (options->got_named_stanza == 0)
|
||||
&& (options->save_rc_stanza == 0) )
|
||||
{
|
||||
log_msg(LOG_VERBOSITY_ERROR,
|
||||
"Named configuration stanza: [%s] was not found.",
|
||||
options->use_rc_stanza);
|
||||
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if ( (options->save_rc_stanza == 1) && (options->use_rc_stanza[0] == 0) )
|
||||
{
|
||||
log_msg(LOG_VERBOSITY_ERROR,
|
||||
"The option --save-rc-stanza must be used with the "
|
||||
"--named-config option to specify the stanza to update.");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if(options->resolve_ip_http || options->spa_proto == FKO_PROTO_HTTP)
|
||||
if (options->http_user_agent[0] == '\0')
|
||||
snprintf(options->http_user_agent, HTTP_MAX_USER_AGENT_LEN,
|
||||
@@ -1360,6 +1372,9 @@ validate_options(fko_cli_options_t *options)
|
||||
if(options->use_hmac && options->hmac_type == FKO_HMAC_UNKNOWN)
|
||||
options->hmac_type = FKO_DEFAULT_HMAC_MODE;
|
||||
|
||||
if(options->key_gen && options->hmac_type == FKO_HMAC_UNKNOWN)
|
||||
options->hmac_type = FKO_DEFAULT_HMAC_MODE;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1410,8 +1425,10 @@ config_init(fko_cli_options_t *options, int argc, char **argv)
|
||||
case 'h':
|
||||
usage();
|
||||
exit(EXIT_SUCCESS);
|
||||
case 'n':
|
||||
case NO_SAVE_ARGS:
|
||||
options->no_save_args = 1;
|
||||
break;
|
||||
case 'n':
|
||||
strlcpy(options->use_rc_stanza, optarg, sizeof(options->use_rc_stanza));
|
||||
break;
|
||||
case SAVE_RC_STANZA:
|
||||
@@ -1492,7 +1509,7 @@ config_init(fko_cli_options_t *options, int argc, char **argv)
|
||||
strlcpy(options->get_key_file, optarg, sizeof(options->get_key_file));
|
||||
cli_arg_bitmask |= FWKNOP_CLI_ARG_BM(FWKNOP_CLI_ARG_KEY_FILE);
|
||||
break;
|
||||
case GET_HMAC_KEY:
|
||||
case GET_HMAC_KEY:
|
||||
strlcpy(options->get_hmac_key_file, optarg,
|
||||
sizeof(options->get_hmac_key_file));
|
||||
options->use_hmac = 1;
|
||||
|
||||
+22
-1
@@ -205,10 +205,19 @@ main(int argc, char **argv)
|
||||
*/
|
||||
if(options.key_gen)
|
||||
{
|
||||
fko_key_gen(options.key_base64, options.key_len,
|
||||
memset(options.key_base64, 0x00, MAX_B64_KEY_LEN+1);
|
||||
memset(options.hmac_key_base64, 0x00, MAX_B64_KEY_LEN+1);
|
||||
|
||||
res = fko_key_gen(options.key_base64, options.key_len,
|
||||
options.hmac_key_base64, options.hmac_key_len,
|
||||
options.hmac_type);
|
||||
|
||||
if(res != FKO_SUCCESS)
|
||||
{
|
||||
errmsg("fko_key_gen", res);
|
||||
return(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if(options.key_gen_file[0] != '\0')
|
||||
{
|
||||
if ((key_gen_file_ptr = fopen(options.key_gen_file, "w")) == NULL)
|
||||
@@ -1263,6 +1272,18 @@ get_keys(fko_ctx_t ctx, fko_cli_options_t *options,
|
||||
clean_exit(ctx, options, EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Make sure the same key is not used for both encryption and the HMAC
|
||||
*/
|
||||
if(*hmac_key_len == *key_len)
|
||||
{
|
||||
if(memcmp(hmac_key, key, *key_len) == 0)
|
||||
{
|
||||
log_msg(LOG_VERBOSITY_ERROR,
|
||||
"[*] The encryption passphrase and HMAC key should not be identical, no SPA packet sent. Exiting.");
|
||||
clean_exit(ctx, options, EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
res = fko_set_spa_hmac_type(ctx, options->hmac_type);
|
||||
if(res != FKO_SUCCESS)
|
||||
{
|
||||
|
||||
+343
-191
@@ -16,40 +16,56 @@ SYNOPSIS
|
||||
DESCRIPTION
|
||||
-----------
|
||||
*fwknop* implements an authorization scheme known as Single Packet
|
||||
Authorization (SPA) for Linux systems running iptables. This mechanism
|
||||
requires only a single encrypted and non-replayed packet to communicate
|
||||
various pieces of information including desired access through an iptables
|
||||
or ipfw policy. The main application of this program is to use iptables
|
||||
in a default-drop stance to protect services such as 'SSH' with an
|
||||
Authorization (SPA) for passive service protection. SPA requires only a single
|
||||
non-replayed encrypted packet together with an HMAC in order to communicate
|
||||
various pieces of information including desired access to a service that is
|
||||
otherwise blocked by a firewall. The main application of SPA is to use a
|
||||
firewall in a default-drop stance to protect services such as 'SSH' with an
|
||||
additional layer of security in order to make the exploitation of
|
||||
vulnerabilities (both 0-day and unpatched code) much more difficult.
|
||||
vulnerabilities (both 0-day and unpatched code) more difficult. In
|
||||
addition, services that are protected in this fashion naturally cannot be
|
||||
scanned for with 'Nmap'.
|
||||
|
||||
An authorization server *fwknopd* passively monitors authorization packets
|
||||
via 'libpcap' and hence there is no ``server'' to which to connect in the
|
||||
traditional sense. Any service protected by *fwknop* is inaccessible (by
|
||||
using 'iptables' or 'ipfw' to intercept packets within the kernel) before
|
||||
authenticating; anyone scanning for the service will not be able to detect
|
||||
that it is even listening. Single Packet Authorization offers many
|
||||
advantages over port knocking, including non-replayability of SPA packets,
|
||||
ability to use asymmetric ciphers (such as Elgamal), and SPA cannot be
|
||||
broken by simply spoofing packets to duplicate ports within the knock
|
||||
sequence on the server to break port knocking authentication.
|
||||
SPA is essentially next generation Port Knocking (PK), but solves many of the
|
||||
limitations exhibited by PK while retaining its core benefits. PK limitations
|
||||
include a general difficulty in protecting against replay attacks, asymmetric
|
||||
ciphers and HMAC schemes are not usually supported, and it is trivially easy
|
||||
to mount a DoS attack against a PK server just by spoofing an additional
|
||||
packet into a PK sequence as it traverses the network (thereby convincing the
|
||||
PK server that the client doesn't know the proper sequence). All of these
|
||||
limitation are solved by SPA. At the same time, SPA hides services behind a
|
||||
default-drop firewall policy, acquires SPA data passively (usually via
|
||||
libpcap or other means), and implements lightweight cryptographic operations
|
||||
for SPA packet authentication and encryption/decryption.
|
||||
|
||||
SPA packets can easily be spoofed as well (this is a good thing in this
|
||||
context), and this makes it possible to make it appear as though, say,
|
||||
www.yahoo.com is trying to authenticate to a target system but in reality
|
||||
the actual connection will come from a seemingly unrelated IP.
|
||||
This is the manual page for the *fwknop* client which is responsible for
|
||||
constructing SPA packets and sending them over the network. The server side is
|
||||
implemented by the *fwknopd* daemon which sniffs the network for SPA packets,
|
||||
and it is recommended to read the 'fwknopd(8)' manual page as well.
|
||||
|
||||
Authorization packets are either encrypted with the 'Rijndael' block cipher
|
||||
or via 'GnuPG' and associated asymmetric ciphers. If the symmetric encryption
|
||||
method is chosen, then the encryption key is shared between the client and
|
||||
server (see the fwknopd 'access.conf' file for details). If the GnuPG method
|
||||
SPA packets generated by *fwknop* leverage HMAC for authenticated encryption
|
||||
in the encrypt-then-authenticate model. Although the usage of an HMAC is
|
||||
currently optional, it is highly recommended for three reasons: '1)' without
|
||||
an HMAC, cryptographically strong authentication is not possible with *fwknop*
|
||||
unless GnuPG is used, '2)' an HMAC applied after encryption protects against
|
||||
CBC-mode padding oracle attacks such as the Vaudenay attack and the more recent
|
||||
"Lucky 13" attack against SSL, and '3)' the code required by the *fwknopd*
|
||||
daemon to verify an HMAC is much more simplistic than the code required to
|
||||
decrypt an SPA packet, so an SPA packet without a proper HMAC isn't even
|
||||
sent through the decryption routines. Generating an HMAC for SPA
|
||||
communications requires a dedicated key in addition to the normal encryption
|
||||
key.
|
||||
|
||||
*fwknop* encrypts SPA packets either with the 'Rijndael' block cipher or via
|
||||
'GnuPG' and associated asymmetric cipher. If the symmetric encryption method
|
||||
is chosen, then as usual the encryption key is shared between the client and
|
||||
server (see the *fwknopd* 'access.conf' file for details). If the GnuPG method
|
||||
is chosen, then the encryption keys are derived from GnuPG key rings. SPA
|
||||
packets generated by fwknop running as a client adhere to the following
|
||||
format (before they are encrypted):
|
||||
format (before encryption and the HMAC is applied):
|
||||
|
||||
..........................
|
||||
random number (16 bytes)
|
||||
random data (16 bytes)
|
||||
username
|
||||
timestamp
|
||||
software version
|
||||
@@ -59,38 +75,37 @@ format (before they are encrypted):
|
||||
message digest (SHA512 / SHA384 / SHA256 / SHA1 / MD5)
|
||||
..........................
|
||||
|
||||
Each of the above fields are separated by a ":" character due to the
|
||||
variable length of several of the fields, and those that might contain
|
||||
":" characters are base64 encoded. The message digest (*SHA256* by
|
||||
default in all versions of *fwknop* greater than 1.9.1) allows the server
|
||||
to check message integrity after decryption, and the 16 bytes of random data
|
||||
ensures (with high probability) that no two messages are identical. This
|
||||
ensures that replay attacks are not possible against *fwknop*.
|
||||
|
||||
For each packet coming from an *fwknop* client, the *fwknopd* server can
|
||||
cache the digest calculated over the entire packet and compares against
|
||||
previous packet digests in order to detect attempted replay attacks. Syslog
|
||||
Each of the above fields are separated by a ":" character due to the variable
|
||||
length of several of the fields, and those that might contain ":" characters
|
||||
are base64 encoded. The message digest (*SHA256* by default) is part of the
|
||||
data to be encrypted and is independent of the HMAC which is appended to the
|
||||
SPA packet data after encryption. The 16 bytes of random data ensures that no
|
||||
two SPA packets are identical, and this is in addition to and independent of
|
||||
using PBKDF1 for key derivation for Rijndael in CBC mode. Because *fwknopd*
|
||||
tracks the SHA256 digest of all incoming valid SPA packets and throws out
|
||||
duplicates, replay attacks are not feasible against *fwknop*. Syslog
|
||||
alerts are generated if a replay is detected.
|
||||
|
||||
By default, the *fwknop* client sends authorization packets over UDP port
|
||||
62201, but this can be altered with the *--server-port* argument. The server
|
||||
must first be configured to acquire the SPA data on the changed protocol-port.
|
||||
62201, but this can be altered with the *--server-port* argument (this requires
|
||||
*fwknopd* to be configured to acquire SPA data over the selected port).
|
||||
Also, *fwknop* can send the SPA packet over a random port via the
|
||||
*--rand-port* argument. See 'fwknopd(8)' for further details. See the
|
||||
*EXAMPLES* section for example invocations of the *fwknop* client.
|
||||
|
||||
The *fwknop* client is quite portable, and is known to run on various Linux
|
||||
distributions (all major distros and embedded ones as well such as OpenWRT),
|
||||
FreeBSD, OpenBSD, and Cygwin on Windows. There is also a library *libfko*
|
||||
that both *fwknop* and *fwknopd* use for SPA packet encryption/decryption
|
||||
and HMAC authentication operations. This library can be used to allow
|
||||
third party applications to use SPA.
|
||||
|
||||
|
||||
REQUIRED ARGUMENTS
|
||||
------------------
|
||||
These required arguments can be specified via command-line or from within
|
||||
the '.fwknoprc' file (see '-n, --named-config' option and the FWKNOPRC FILE
|
||||
section below.
|
||||
|
||||
*-D, --destination*='<IP-address>'::
|
||||
Direct the *fwknop* client to authenticate with the *fwknopd*
|
||||
daemon/service at the specified destination hostname or IP address. The
|
||||
connection mode is discovered by the *fwknopd* daemon/service when it
|
||||
decrypts and parses the authentication packet.
|
||||
section below).
|
||||
|
||||
*-A, --access*='<port list>'::
|
||||
Provide a list of ports and protocols to access on a remote computer
|
||||
@@ -100,9 +115,15 @@ section below.
|
||||
sending full commands with the *--server-cmd* argument via an SPA
|
||||
packet to be executed by *fwknopd* does not require this argument.
|
||||
|
||||
*-D, --destination*='<IP-address>'::
|
||||
Direct the *fwknop* client to authenticate with the *fwknopd*
|
||||
daemon/service at the specified destination hostname or IP address. The
|
||||
connection mode is discovered by the *fwknopd* daemon/service when it
|
||||
decrypts and parses the authentication packet.
|
||||
|
||||
*-R|-a|-s*::
|
||||
One of these options (see below) is required to tell the remote
|
||||
*fwknopd* daemon what IP should be let through the local firewall. It
|
||||
*fwknopd* daemon what IP should be allowed through the local firewall. It
|
||||
is recommend to use the *-R* or *-a* options instead of *-s* in order
|
||||
to harden SPA communications against possible 'Man-In-The-Middle' (MITM)
|
||||
attacks.
|
||||
@@ -113,25 +134,17 @@ GENERAL OPTIONS
|
||||
*-h, --help*::
|
||||
Print a usage summary message and exit.
|
||||
|
||||
*-B, --save-packet*='<file>'::
|
||||
Instruct the *fwknop* client to write a newly created SPA packet out
|
||||
to the specified file so that it can be examined off-line.
|
||||
|
||||
*-b, --save-packet-append*::
|
||||
Append the generated packet data to the file specified with the -B
|
||||
option.
|
||||
|
||||
*-G, --get-key*='<file>'::
|
||||
Load an encryption key/password from the specified file. The key file
|
||||
contains a line for each destination hostname or IP address, a colon
|
||||
(":"), optional space and the password, followed by a newline. Note
|
||||
that the last line has to have a terminating newline character.
|
||||
Also note: though this is a convenience, having a file on your system
|
||||
with cleartext passwords is not a good idea and is not recommended.
|
||||
with clear text passwords is not a good idea and is not recommended.
|
||||
Having the *fwknop* client prompt you for the key is generally more
|
||||
secure. Note also that if a key is stored on disk, the *fwknop* rc
|
||||
file is a more powerful mechanism for specifying the key but other
|
||||
options as well.
|
||||
file is a more powerful mechanism for specifying not only the key but
|
||||
other options as well.
|
||||
|
||||
*--get-hmac-key*='<file>'::
|
||||
Load an HMAC key/password from the specified file. Similarly to the
|
||||
@@ -139,36 +152,18 @@ GENERAL OPTIONS
|
||||
each destination hostname or IP address, a colon (":"), optional space
|
||||
and the password, followed by a newline. Note that the last line has
|
||||
to have a terminating newline character. Also note: though this is a
|
||||
convenience, having a file on your system with cleartext passwords is
|
||||
convenience, having a file on your system with clear text passwords is
|
||||
not a good idea and is not recommended. Having the *fwknop* client
|
||||
prompt you for the HMAC key is generally more secure. Note also that
|
||||
if a key is stored on disk, the *fwknop* rc file is a more powerful
|
||||
mechanism for specifying the key but other options as well.
|
||||
mechanism for specifying not only the HMAC key but other options as
|
||||
well.
|
||||
|
||||
*--key-rijndael*='<key>'::
|
||||
Specify the Rijndael key. Since the key may be visible to utilities
|
||||
such as 'ps' under Unix, this form should only be used where security is
|
||||
not critical. Having the *fwknop* client prompt you for the key is
|
||||
generally more secure.
|
||||
|
||||
*--key-base64-rijndael*='<key>'::
|
||||
Specify the base64 encoded Rijndael key. Since the key may be visible
|
||||
to utilities such as 'ps' under Unix, this form should only be used where
|
||||
security is not critical. Having the *fwknop* client prompt you for the
|
||||
key is generally more secure.
|
||||
|
||||
*--key-base64-hmac*='<key>'::
|
||||
Specify the base64 encoded HMAC key. Since the key may be visible
|
||||
to utilities such as 'ps' under Unix, this form should only be used where
|
||||
security is not critical. Having the *fwknop* client prompt you for the
|
||||
key is generally more secure.
|
||||
|
||||
|
||||
*--key-hmac*='<key>'::
|
||||
Specify the raw HMAC key (not base64 encoded). Since the key may be visible
|
||||
to utilities such as 'ps' under Unix, this form should only be used where
|
||||
security is not critical. Having the *fwknop* client prompt you for the
|
||||
key is generally more secure.
|
||||
*--key-gen*::
|
||||
Have *fwknop* generate both Rijndael and HMAC keys that can be used for SPA
|
||||
packet encryption. These keys are derived from /dev/random and then base64
|
||||
encoded before being printed to stdout, and are meant to be included within
|
||||
the ``$HOME/.fwknoprc'' file (or the file referenced by *--get-key*).
|
||||
|
||||
*-l, --last-cmd*::
|
||||
Execute *fwknop* with the command-line arguments from the previous
|
||||
@@ -183,6 +178,34 @@ GENERAL OPTIONS
|
||||
FWKNOPRC FILE below for a list of the valid configuration directives in
|
||||
the '.fwknoprc' file.
|
||||
|
||||
*--key-rijndael*='<key>'::
|
||||
Specify the Rijndael key on the command line. Since the key may be visible
|
||||
to utilities such as 'ps' under Unix, this form should only be used where
|
||||
security is not critical. Having the *fwknop* client either prompt you for
|
||||
the key or acquire via the ``$HOME/.fwknoprc'' file is generally more
|
||||
secure.
|
||||
|
||||
*--key-base64-rijndael*='<key>'::
|
||||
Specify the base64 encoded Rijndael key. Since the key may be visible
|
||||
to utilities such as 'ps' under Unix, this form should only be used where
|
||||
security is not critical. Having the *fwknop* client either prompt you for
|
||||
the key or acquire via the ``$HOME/.fwknoprc'' file is generally more
|
||||
secure.
|
||||
|
||||
*--key-base64-hmac*='<key>'::
|
||||
Specify the base64 encoded HMAC key. Since the key may be visible
|
||||
to utilities such as 'ps' under Unix, this form should only be used where
|
||||
security is not critical. Having the *fwknop* client either prompt you for
|
||||
the key or acquire via the ``$HOME/.fwknoprc'' file is generally more
|
||||
secure.
|
||||
|
||||
*--key-hmac*='<key>'::
|
||||
Specify the raw HMAC key (not base64 encoded). Since the key may be visible
|
||||
to utilities such as 'ps' under Unix, this form should only be used where
|
||||
security is not critical. Having the *fwknop* client either prompt you for
|
||||
the key or acquire via the ``$HOME/.fwknoprc'' file is generally more
|
||||
secure.
|
||||
|
||||
*--rc-file*='<file>'::
|
||||
Specify path to the fwknop rc file (default is $HOME/.fwknoprc).
|
||||
|
||||
@@ -211,6 +234,14 @@ GENERAL OPTIONS
|
||||
the decryption and decoding process and print the break-down again.
|
||||
This is primarily a debugging feature.
|
||||
|
||||
*-B, --save-packet*='<file>'::
|
||||
Instruct the *fwknop* client to write a newly created SPA packet out
|
||||
to the specified file so that it can be examined off-line.
|
||||
|
||||
*-b, --save-packet-append*::
|
||||
Append the generated packet data to the file specified with the -B
|
||||
option.
|
||||
|
||||
*-v, --verbose*::
|
||||
Run the *fwknop* client in verbose mode. This causes *fwknop* to print
|
||||
some extra information about the current command and the resulting SPA
|
||||
@@ -222,6 +253,11 @@ GENERAL OPTIONS
|
||||
|
||||
SPA OPTIONS
|
||||
-----------
|
||||
*--use-hmac*::
|
||||
Set HMAC mode for authenticated encryption of SPA communications. As of
|
||||
*fwknop* 2.5, this is an optional feature, but this will become the
|
||||
default in a future release.
|
||||
|
||||
*-a, --allow-ip*='<IP-address>'::
|
||||
Specify IP address that should be permitted through the destination
|
||||
*fwknopd* server firewall (this IP is encrypted within the SPA packet
|
||||
@@ -238,48 +274,15 @@ SPA OPTIONS
|
||||
system is connected to by querying a website that returns the actual
|
||||
IP address it sees from the calling system.
|
||||
|
||||
*-C, --server-cmd*='<command to execute>'::
|
||||
Instead of requesting access to a service with an SPA packet, the
|
||||
*--server-cmd* argument specifies a command that will be executed by
|
||||
the *fwknopd* server. The command is encrypted within the SPA packet
|
||||
and sniffed off the wire (as usual) by the *fwknopd* server.
|
||||
|
||||
*-g, --gpg-encryption*::
|
||||
Use GPG encryption on the SPA packet (default if not specified is
|
||||
Rijndael). *Note:* Use of this option will require the specification of
|
||||
a GPG recipient (see *--gpg-recipient* along with other GPG-related
|
||||
options below).
|
||||
|
||||
*-H, --http-proxy*='<proxy-host>[:port]'::
|
||||
Specify an HTTP proxy that the *fwknop* client will use to send the SPA
|
||||
packet through. Using this option will automatically set the SPA packet
|
||||
transmission mode (usually set via the *--server-proto* argument) to
|
||||
"http". You can also specify the proxy port by adding ":<port>" to
|
||||
the proxy host name or ip.
|
||||
|
||||
*-m, --digest-type*='<digest>'::
|
||||
Specify the message digest algorithm to use in the SPA data. Choices
|
||||
are: *MD5*, *SHA1*, *SHA256* (the default), *SHA384*, and *SHA512*.
|
||||
|
||||
*-M, --encryption-mode*='<mode>'::
|
||||
Specify the encryption mode when AES is used for encrypting SPA packets.
|
||||
The default is CBC mode, but others can be chosen such as CFB or OFB
|
||||
as long as this is also specified in the 'access.conf' file on the
|
||||
server side via the ENCRYPTION_MODE variable. In general, it is
|
||||
recommended to not use this argument and just use the default. Note that
|
||||
the string ``legacy'' can be specified in order to generate SPA packets
|
||||
with the old initialization vector strategy used by versions of *fwknop*
|
||||
before 2.5. With the 2.5 release, *fwknop* generates initialization
|
||||
vectors in a manner that is compatible with OpenSSL.
|
||||
|
||||
*--hmac-digest-type*='<digest>'::
|
||||
Set the HMAC digest algorithm (default is sha256). Options are md5, sha1,
|
||||
sha256, sha384, or sha512.
|
||||
|
||||
*--use-hmac*::
|
||||
Set HMAC mode for authenticated encryption of SPA communications. As of
|
||||
*fwknop* 2.5, this is an optional feature, but this will become the
|
||||
default in a future release.
|
||||
Set the HMAC digest algorithm for authenticated encryption of SPA packets.
|
||||
Choices are: *MD5*, *SHA1*, *SHA256* (the default), *SHA384*, and *SHA512*.
|
||||
|
||||
*-N, --nat-access*='<internalIP:forwardPort>'::
|
||||
The *fwknopd* server offers the ability to provide SPA access through
|
||||
@@ -368,13 +371,44 @@ SPA OPTIONS
|
||||
*fwknopd* SPA server to use the source IP address from which the
|
||||
SPA packet originates as the IP that will be allowed through upon
|
||||
modification of the firewall ruleset. This option is useful if the
|
||||
*fwknop* client is deployed on a machine that is behind a NAT device.
|
||||
*fwknop* client is deployed on a machine that is behind a NAT device and
|
||||
the external IP is not known. However, usage of this option is not
|
||||
recommended, and either the *-a* or *-R* options should be used instead.
|
||||
The permit-address options *-s*, *-R* and *-a* are mutually
|
||||
exclusive.
|
||||
|
||||
*-S, --source-port*='<port>'::
|
||||
Set the source port for outgoing SPA packet.
|
||||
|
||||
*-C, --server-cmd*='<command to execute>'::
|
||||
Instead of requesting access to a service with an SPA packet, the
|
||||
*--server-cmd* argument specifies a command that will be executed by
|
||||
the *fwknopd* server. The command is encrypted within the SPA packet
|
||||
and sniffed off the wire (as usual) by the *fwknopd* server.
|
||||
|
||||
*-H, --http-proxy*='<proxy-host>[:port]'::
|
||||
Specify an HTTP proxy that the *fwknop* client will use to send the SPA
|
||||
packet through. Using this option will automatically set the SPA packet
|
||||
transmission mode (usually set via the *--server-proto* argument) to
|
||||
"http". You can also specify the proxy port by adding ":<port>" to
|
||||
the proxy host name or ip.
|
||||
|
||||
*-m, --digest-type*='<digest>'::
|
||||
Specify the message digest algorithm to use in the SPA data. Choices
|
||||
are: *MD5*, *SHA1*, *SHA256* (the default), *SHA384*, and *SHA512*.
|
||||
|
||||
*-M, --encryption-mode*='<mode>'::
|
||||
Specify the encryption mode when AES is used for encrypting SPA packets.
|
||||
The default is CBC mode, but others can be chosen such as CFB or OFB
|
||||
as long as this is also specified in the 'access.conf' file on the
|
||||
server side via the ENCRYPTION_MODE variable. In general, it is
|
||||
recommended to not use this argument and just use the default (CBC).
|
||||
Note that the string ``legacy'' can be specified in order to generate SPA
|
||||
packets with the old initialization vector strategy used by versions of
|
||||
*fwknop* prior to 2.5. With the 2.5 release, *fwknop* generates
|
||||
initialization vectors in a manner that is compatible with OpenSSL via the
|
||||
PBKDF1 algorithm.
|
||||
|
||||
*--time-offset-plus*='<time>'::
|
||||
By default, the *fwknopd* daemon on the server side enforces time
|
||||
synchronization between the clocks running on client and server
|
||||
@@ -414,6 +448,24 @@ SPA OPTIONS
|
||||
|
||||
GPG-RELATED OPTIONS
|
||||
-------------------
|
||||
Note that the usage of GPG for SPA encryption/decryption can and should involve
|
||||
GPG keys that are signed by each side (client and server). The basic procedure
|
||||
for this involves the following steps after the client key has been transferred
|
||||
the server and vice-versa:
|
||||
|
||||
..........................
|
||||
[spaserver]# gpg --import client.asc
|
||||
[spaserver]# gpg --edit-key 1234ABCD
|
||||
Command> sign
|
||||
|
||||
[spaclient]$ gpg --import server.asc
|
||||
[spaclient]$ gpg --edit-key ABCD1234
|
||||
Command> sign
|
||||
..........................
|
||||
|
||||
More comprehensive information on this can be found here:
|
||||
'http://www.cipherdyne.org/fwknop/docs/gpghowto.html'.
|
||||
|
||||
*--gpg-agent*::
|
||||
Instruct *fwknop* to acquire GnuPG key password from a running gpg-agent
|
||||
instance (if available).
|
||||
@@ -464,24 +516,9 @@ There are directives to match most of the command-line parameters *fwknop*
|
||||
supports. Here is the current list of each directive along with a brief
|
||||
description and its matching command-line option(s):
|
||||
|
||||
*DIGEST_TYPE*::
|
||||
Set the SPA message digest type ('-m, --digest-type').
|
||||
|
||||
*SPA_SERVER_PROTO*::
|
||||
Set the protocol to use for sending the SPA packet ('-P, --server-proto').
|
||||
|
||||
*SPA_SERVER*::
|
||||
Specify the IP or hostname of the destination (*fwknopd*) server
|
||||
('-D, --destination).
|
||||
|
||||
*SPA_SERVER_PORT*::
|
||||
Set the server port to use for sending the SPA packet ('-p, --server-port').
|
||||
|
||||
*SPA_SOURCE_PORT*::
|
||||
Set the source port to use for sending the SPA packet ('-S, --source-port').
|
||||
|
||||
*FW_TIMEOUT*::
|
||||
Set the firewall rule timeout value ('-f, --fw-timeout').
|
||||
('-D, --destination').
|
||||
|
||||
*ALLOW_IP*::
|
||||
Specify the address to allow within the SPA data. Note: This parameter
|
||||
@@ -491,6 +528,49 @@ description and its matching command-line option(s):
|
||||
to allow (the *-s* option), or use the word "resolve" to have *fwknop*
|
||||
resolve the external network IP via HTTP request (the *-R* option).
|
||||
|
||||
*ACCESS*::
|
||||
Set the one or more protocol/ports to open on the firewall ('-A, --access').
|
||||
|
||||
*SPA_SERVER_PORT*::
|
||||
Set the server port to use for sending the SPA packet ('-p, --server-port').
|
||||
|
||||
*SPA_SERVER_PROTO*::
|
||||
Set the protocol to use for sending the SPA packet ('-P, --server-proto').
|
||||
|
||||
*KEY*::
|
||||
This is the passphrase that is used for SPA packet encryption and applies
|
||||
to both Rijndael or GPG encryption modes. The actual encryption key that
|
||||
is used for Rijndael is derived from the PBKDF1 algorithm, and the GPG key
|
||||
is derived from the specified GPG key ring.
|
||||
|
||||
*KEY_BASE64*::
|
||||
Specify the encryption passphrase as a base64 encoded string. This allows
|
||||
non-ascii characters to be included.
|
||||
|
||||
*USE_HMAC*::
|
||||
Set HMAC mode for authenticated encryption of SPA packets. This will have
|
||||
*fwknop* prompt the user for a dedicated HMAC key that is independent of
|
||||
the encryption key. Alternatively, the HMAC key can be specified with the
|
||||
'HMAC_KEY' or 'HMAC_KEY_BASE64' directives (see below).
|
||||
|
||||
*HMAC_KEY*::
|
||||
Specify the HMAC key for authenticated encryption of SPA packets.
|
||||
|
||||
*HMAC_KEY_BASE64*::
|
||||
Specify the HMAC key as a base64 encoded string. This allows non-ascii
|
||||
characters to be included.
|
||||
|
||||
*HMAC_DIGEST_TYPE*::
|
||||
Set the HMAC digest algorithm used for authenticated encryption of SPA
|
||||
packets. Choices are: *MD5*, *SHA1*, *SHA256* (the default), *SHA384*,
|
||||
and *SHA512*.
|
||||
|
||||
*SPA_SOURCE_PORT*::
|
||||
Set the source port to use for sending the SPA packet ('-S, --source-port').
|
||||
|
||||
*FW_TIMEOUT*::
|
||||
Set the firewall rule timeout value ('-f, --fw-timeout').
|
||||
|
||||
*RESOLVE_URL*::
|
||||
Set to a URL that will be used for resolving the source IP address
|
||||
(--resolve-url).
|
||||
@@ -503,9 +583,17 @@ description and its matching command-line option(s):
|
||||
Specify the encryption mode when AES is used. This variable is a synonym
|
||||
for the '--encryption-mode' command line argument.
|
||||
|
||||
*DIGEST_TYPE*::
|
||||
Set the SPA message digest type ('-m, --digest-type').
|
||||
|
||||
*USE_GPG*::
|
||||
Set to 'Y' to specify the use of GPG for encryption ('--gpg-encryption').
|
||||
|
||||
*USE_GPG*::
|
||||
Set to 'Y' to have *fwknop* interface with a GPG agent instance for the GPG
|
||||
key password ('--gpg-agent'). Agent information itself is specified with
|
||||
the 'GPG_AGENT_INFO' environmental variable.
|
||||
|
||||
*GPG_SIGNER*::
|
||||
Specify the GPG key name or ID for signing the GPG-encrypted SPA data
|
||||
('--gpg-signer-key').
|
||||
@@ -525,9 +613,6 @@ description and its matching command-line option(s):
|
||||
Set the source IP of the outgoing SPA packet to the specified value
|
||||
('-Q, --spoof-source').
|
||||
|
||||
*ACCESS*::
|
||||
Set the one or more protocol/ports to open on the firewall ('-A, --access').
|
||||
|
||||
*RAND_PORT*::
|
||||
Send the SPA packet over a randomly assigned port ('-r, --rand-port').
|
||||
|
||||
@@ -536,7 +621,7 @@ description and its matching command-line option(s):
|
||||
|
||||
*HTTP_USER_AGENT*::
|
||||
Set the HTTP User-Agent for resolving the external IP via -R, or for
|
||||
sending SPA packets over HTTP ('-u, --user-agent').
|
||||
sending SPA packets over HTTP ('-u, --user-agent').
|
||||
|
||||
*NAT_ACCESS*::
|
||||
Gain NAT access to an internal service protected by the fwknop server
|
||||
@@ -558,6 +643,19 @@ ENVIRONMENT
|
||||
-----------
|
||||
*SPOOF_USER*, *GPG_AGENT_INFO* (only used in *--gpg-agent* mode).
|
||||
|
||||
SPA PACKET SPOOFING
|
||||
-------------------
|
||||
Because *fwknop* places the IP to be allowed through the firewall within the
|
||||
encrypted SPA payload (unless *-s* is used which is not recommended and can be
|
||||
prohibited in the *fwknopd* server configuration), SPA packets can easily be
|
||||
spoofed, and this is a good thing in this context. That is, the source IP of
|
||||
an SPA packet is ignored by the *fwknopd* daemon and only the IP that is
|
||||
contained within an authenticated and properly decrypted SPA packet is granted
|
||||
access through the firewall. This makes it possible to make it appear as
|
||||
though, say, www.yahoo.com is trying to authenticate to a target system but in
|
||||
reality the actual connection will come from a seemingly unrelated IP.
|
||||
|
||||
|
||||
EXAMPLES
|
||||
--------
|
||||
The following examples illustrate the command line arguments that could
|
||||
@@ -565,89 +663,143 @@ be supplied to the fwknop client in a few situations:
|
||||
|
||||
Access mode examples
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
Packet contents printed to stdout at the fwknop client when creating
|
||||
an ``access mode'' SPA packet:
|
||||
The most common usage of *fwknop* is to gain access to 'SSH' running on a
|
||||
remote system that has the *fwknopd* daemon deployed along with a default-drop
|
||||
firewall policy. The following command illustrates this where IP '1.1.1.1' is
|
||||
the IP to be allowed through the firewall running on '2.2.2.2' (note that the
|
||||
'access.conf' file consumed by *fwknopd* will need to have matching encryption
|
||||
and HMAC keys, and configuration specifics can be found in the 'fwknopd(8)'
|
||||
manual page):
|
||||
|
||||
..........................
|
||||
Random data: 6565240948266426
|
||||
Username: mbr
|
||||
Timestamp: 1203863233
|
||||
Version: 1.9.2
|
||||
Type: 1 (access mode)
|
||||
Access: 127.0.0.2,tcp/22
|
||||
SHA256 sum: gngquSL8AuM7r27XsR4qPmJhuBo9pG2PYwII06AaJHw
|
||||
$ fwknop -A tcp/22 --use-hmac -a 1.1.1.1 -D 2.2.2.2
|
||||
Enter encryption key:
|
||||
Enter HMAC key:
|
||||
$ ssh -l user 2.2.2.2
|
||||
user@2.2.2.2's password:
|
||||
..........................
|
||||
|
||||
Use the Single Packet Authorization mode to gain access to
|
||||
tcp/22 (ssh) and udp/53 running on the system 10.0.0.123 from
|
||||
the IP 192.168.10.4:
|
||||
If the *--verbose* flag is added to the command line, then some SPA packet
|
||||
specifics are printed to stdout (not all output is shown for brevity):
|
||||
|
||||
..........................
|
||||
$ fwknop -A "tcp/22,udp/53" -a 192.168.10.4 -D 10.0.0.123
|
||||
$ fwknop -A tcp/22 --use-hmac -a 1.1.1.1 -D 2.2.2.2 --verbose
|
||||
Enter encryption key:
|
||||
Enter HMAC key:
|
||||
|
||||
Random Value: 1916307060193417
|
||||
Username: mbr
|
||||
Timestamp: 1368498909
|
||||
FKO Version: 2.5.0
|
||||
Message Type: 1 (Access msg)
|
||||
Message String: 1.1.1.1,tcp/22
|
||||
Nat Access: <NULL>
|
||||
Server Auth: <NULL>
|
||||
Client Timeout: 0 (seconds)
|
||||
Digest Type: 3 (SHA256)
|
||||
HMAC Type: 3 (SHA256)
|
||||
Encryption Type: 1 (Rijndael)
|
||||
Encryption Mode: 2 (CBC)
|
||||
..........................
|
||||
|
||||
Same as above example, but gain access from whatever source IP
|
||||
is seen by the fwknop server (useful if the fwknop client is
|
||||
behind a NAT device):
|
||||
Simultaneous access to multiple services is also supported, and here is an
|
||||
example of requesting access to both 'SSH' and 'OpenVPN' on '2.2.2.2':
|
||||
|
||||
..........................
|
||||
$ fwknop -A "tcp/22,udp/53" -s -D 10.0.0.123
|
||||
$ fwknop -A "tcp/22,tcp/1194" --use-hmac -a 1.1.1.1 -D 2.2.2.2
|
||||
..........................
|
||||
|
||||
Same as above example, but use an IP identification website to derive
|
||||
the client IP address. This is a safer method of acquiring the client
|
||||
IP address than using the *-s* option because the source IP is put within
|
||||
the encrypted packet instead of having the *fwknopd* daemon grant the
|
||||
requested access from whatever IP address the SPA packet originates:
|
||||
There are many cases where an *fwknop* client is deployed on a network behind
|
||||
a NAT device and the externally routable IP is not known to the user. In this
|
||||
case, use the IP resolution service available at
|
||||
'http://www.cipherdyne.org/cgi-bin/myip' via the *-R* command line switch in
|
||||
order to derive the external client IP address. This is a safer method of
|
||||
acquiring the client IP address than using the *-s* option mentioned earlier
|
||||
in this manual page because the source IP is put within the encrypted packet
|
||||
instead of having the *fwknopd* daemon grant the requested access from whatever
|
||||
IP address the SPA packet originates (i.e. using *-s* opens the possibility of
|
||||
a MITM attack):
|
||||
|
||||
..........................
|
||||
$ fwknop -A "tcp/22,udp/53" -R -D 10.0.0.123
|
||||
$ fwknop -A tcp/22 --use-hmac -R -D 2.2.2.2
|
||||
..........................
|
||||
|
||||
Use the Single Packet Authorization mode to gain access to tcp/22
|
||||
(ssh) and udp/53 running on the system 10.0.0.123, and use GnuPG keys
|
||||
to encrypt and decrypt:
|
||||
Use the Single Packet Authorization mode to gain access to 'SSH' and this time
|
||||
use GnuPG keys to encrypt and decrypt:
|
||||
|
||||
..........................
|
||||
$ fwknop -A "tcp/22,udp/53" --gpg-sign ABCD1234 --gpg--recipient
|
||||
1234ABCD -R -D 10.0.0.123
|
||||
$ fwknop -A tcp/22 --use-hmac --gpg-sign ABCD1234 --gpg--recipient 1234ABCD -R -D 2.2.2.2
|
||||
..........................
|
||||
|
||||
Instruct the fwknop server running at 10.0.0.123 to allow 172.16.5.4
|
||||
to connect to TCP/22, but spoof the authorization packet from an IP
|
||||
associated with www.yahoo.com:
|
||||
Instruct the fwknop server running at 2.2.2.2 to allow 1.1.1.1 to connect to
|
||||
'SSH', but spoof the authorization packet from an IP associated with
|
||||
'www.yahoo.com' (requires root on the *fwknop* client OS):
|
||||
|
||||
..........................
|
||||
# fwknop --Spoof-src ’www.yahoo.com’ -A tcp/22 -a 172.16.5.4 -D
|
||||
10.0.0.123
|
||||
# fwknop --spoof-src "www.yahoo.com" -A tcp/22 --use-hmac -a 1.1.1.1 -D 2.2.2.2
|
||||
..........................
|
||||
|
||||
When *fwknopd* is running on an iptables firewall with systems deployed behind
|
||||
it, it is possible to take advantage of the 'NAT' capabilities offered by
|
||||
iptables in order to transparently reach systems behind the firewall via SPA.
|
||||
Here is an example where the *fwknop* client is used to gain access to 'SSH'
|
||||
running on the non-routable IP '192.168.10.23' that is deployed on the network
|
||||
behind '2.2.2.2'. In this case, the 'SSH' connection made to '2.2.2.2' is
|
||||
translated into the '192.168.10.2' system automatically:
|
||||
|
||||
..........................
|
||||
$ fwknop -A tcp/22 -N 192.168.10.2:22 -R -D 2.2.2.2
|
||||
..........................
|
||||
|
||||
|
||||
DEPENDENCIES
|
||||
------------
|
||||
*fwknop* requires 'libfko' (which is normally included with both source and
|
||||
binary distributions).
|
||||
The *fwknop* client requires 'libfko' which is normally included with both source
|
||||
and binary distributions, and is a dedicated library developed by the fwknop
|
||||
project. Whenever the *fwknopd* server is used, libpcap is a required dependency.
|
||||
|
||||
For GPG functionality, GnuPG must also be correctly installed and configured.
|
||||
For GPG functionality, GnuPG must also be correctly installed and configured
|
||||
along with the libgpgme library.
|
||||
|
||||
To take advantage of all of the authentication and access management
|
||||
features of the *fwknopd* daemon/service a functioning iptables firewall
|
||||
is required on the underlying operating system.
|
||||
To take advantage of all of the authentication and access management
|
||||
features of the *fwknopd* daemon/service a functioning iptables, ipfw, or pf
|
||||
firewall is required on the underlying operating system.
|
||||
|
||||
|
||||
DIAGNOSTICS
|
||||
-----------
|
||||
fwknop can be run with the *-T* (or *--test*) command line option.
|
||||
This will have *fwknop* simply create and print the SPA packet information,
|
||||
then run it through a decrypt/decode cycle and print it again.
|
||||
The most comprehensive way to gain diagnostic information on *fwknop* is to run
|
||||
the test suite 'test-fwknop.pl' script located in the 'test/' directory in the fwknop
|
||||
sources. The test suite runs sends fwknop through a large number of run time
|
||||
tests, has 'valgrind' support, validates both SPA encryption and HMAC results
|
||||
against OpenSSL, and even has its own built in fuzzer for SPA communications.
|
||||
For more basic diagnostic information, *fwknop* can be executed with the *-T*
|
||||
(or *--test*) command line option. This will have *fwknop* simply create and
|
||||
print the SPA packet information, then run it through a decrypt/decode cycle
|
||||
and print it again. In addition, the *--verbose* command line switch is useful
|
||||
to see various SPA packet specifics printed to stdout.
|
||||
|
||||
|
||||
SEE ALSO
|
||||
--------
|
||||
fwknopd(8), iptables(8), gpg(1), libfko documentation.
|
||||
fwknopd(8), iptables(8), pf(4), pfctl(8), ipfw(8), gpg(1), libfko documentation.
|
||||
|
||||
More information on Single Packet Authorization can be found in the paper
|
||||
``Single Packet Authorization with fwknop'' available at
|
||||
'http://www.cipherdyne.org/fwknop/docs/SPA.html'.
|
||||
'http://www.cipherdyne.org/fwknop/docs/SPA.html'. A comprehensive tutorial
|
||||
on *fwknop* operations and theory can be found at
|
||||
'http://www.cipherdyne.org/fwknop/docs/fwknop-tutorial.html'. This tutorial
|
||||
also includes information about the design of *fwknop* that may be worth
|
||||
reading for those interested in why fwknop is different from other SPA
|
||||
implementations.
|
||||
|
||||
*fwknop* uses the 'git' versioning system as its source code repository
|
||||
along with 'Github' for tracking of issues and milestones:
|
||||
|
||||
..........................
|
||||
$ git clone https://github.com/mrash/fwknop.git fwknop.git
|
||||
..........................
|
||||
|
||||
|
||||
AUTHORS
|
||||
-------
|
||||
@@ -660,19 +812,19 @@ This ``C'' version of fwknop was derived from the original Perl-based version
|
||||
on which many people who are active in the open source community have
|
||||
contributed. See the CREDITS file in the fwknop sources, or visit
|
||||
'http://www.cipherdyne.org/fwknop/docs/contributors.html' to view the online
|
||||
list of contributors.
|
||||
list of contributors. A few contributors deserve to be singled out including:
|
||||
Franck Joncourt, Max Kastanas, Vlad Glagolev, Sean Greven, Hank Leininger,
|
||||
Fernando Arnaboldi, and Erik Gomez.
|
||||
|
||||
The phrase ``Single Packet Authorization'' was coined by MadHat and Simple
|
||||
Nomad at the BlackHat Briefings of 2005 (see: 'http://www.nmrc.org').
|
||||
Nomad at the BlackHat Briefings of 2005.
|
||||
|
||||
BUGS
|
||||
----
|
||||
Send bug reports to dstuart@dstuart.org or mbr@cipherdyne.org. Suggestions
|
||||
Send bug reports to dstuart@dstuart.org or mbr@cipherdyne.org. Suggestions
|
||||
and/or comments are always welcome as well.
|
||||
|
||||
DISTRIBUTION
|
||||
------------
|
||||
*fwknop* is distributed under the GNU General Public License (GPL), and
|
||||
the latest version may be downloaded from 'http://www.cipherdyne.org'.
|
||||
|
||||
|
||||
*fwknop* is distributed under the GNU General Public License (GPL) version 2,
|
||||
and the latest version may be downloaded from 'http://www.cipherdyne.org'.
|
||||
|
||||
+53
-16
@@ -19,12 +19,15 @@ DESCRIPTION
|
||||
*fwknopd* is the server component for the FireWall Knock Operator, and
|
||||
is responsible for monitoring and processing Single Packet Authorization
|
||||
(SPA) packets that are generated by *fwknop* clients, modifying a firewall
|
||||
or ACL policy to allow the desired access after decrypting a valid SPA packet,
|
||||
and removing access after a configurable timeout.
|
||||
or ACL policy to allow the desired access after authenticating and
|
||||
decrypting a valid SPA packet (in that order), and removing access after a
|
||||
configurable timeout.
|
||||
|
||||
The main application of this program is to protect services such as 'SSH'
|
||||
with an additional layer of security in order to make the exploitation of
|
||||
vulnerabilities (both 0-day and unpatched code) much more difficult.
|
||||
vulnerabilities (both 0-day and unpatched code) much more difficult. In
|
||||
addition, services that are protected in this fashion naturally cannot be
|
||||
scanned for with 'Nmap'.
|
||||
|
||||
The main configuration for *fwknopd* is maintained within two files:
|
||||
'fwknopd.conf' and 'access.conf'. The default location for these files
|
||||
@@ -461,9 +464,19 @@ Defines all knock sequences and access control directives.
|
||||
|
||||
DEPENDENCIES
|
||||
------------
|
||||
The *fwknopd* daemon requires a functioning firewall on the underlying
|
||||
operating system. Supported firewalls as of the fwknop-2.0 release are
|
||||
iptables, ipfw, and pf.
|
||||
*fwknopd* requires 'libfko' which is normally included with both source and
|
||||
binary distributions, and is a dedicated library developed by the fwknop
|
||||
project.
|
||||
|
||||
For packet sniffing, *fwknopd* currently requires libpcap, but future versions
|
||||
still remove this as a dependency.
|
||||
|
||||
For GPG functionality, GnuPG must also be correctly installed and configured
|
||||
along with the libgpgme library.
|
||||
|
||||
To take advantage of all of the authentication and access management
|
||||
features of the *fwknopd* daemon/service a functioning iptables, ipfw, or pf
|
||||
firewall is required on the underlying operating system.
|
||||
|
||||
|
||||
DIAGNOSTICS
|
||||
@@ -473,28 +486,52 @@ the *-v, --verbose* command line options. This will disable daemon mode
|
||||
execution, and print verbose information to the screen on stderr as packets
|
||||
are received.
|
||||
|
||||
The most comprehensive way to gain diagnostic information on *fwknopd* is to run
|
||||
the test suite 'test-fwknop.pl' script located in the 'test/' directory in the fwknop
|
||||
sources. The test suite runs sends fwknop through a large number of run time
|
||||
tests, has 'valgrind' support, validates both SPA encryption and HMAC results
|
||||
against OpenSSL, and even has its own built in fuzzer for SPA communications.
|
||||
|
||||
|
||||
SEE ALSO
|
||||
--------
|
||||
fwknop(8), iptables(8), libfko documentation.
|
||||
fwknopd(8), iptables(8), pf(4), pfctl(8), ipfw(8), gpg(1), libfko documentation.
|
||||
|
||||
More information on Single Packet Authorization can be found in the paper
|
||||
``Single Packet Authorization with fwknop'' available at
|
||||
'http://www.cipherdyne.org/fwknop/docs/SPA.html'. A comprehensive tutorial
|
||||
on *fwknop* operations and theory can be found at
|
||||
'http://www.cipherdyne.org/fwknop/docs/fwknop-tutorial.html'. This tutorial
|
||||
also includes information about the design of *fwknop* that may be worth
|
||||
reading for those interested in why fwknop is different from other SPA
|
||||
implementations.
|
||||
|
||||
*fwknop* uses the 'git' versioning system as its source code repository
|
||||
along with 'Github' for tracking of issues and milestones:
|
||||
|
||||
..........................
|
||||
$ git clone https://github.com/mrash/fwknop.git fwknop.git
|
||||
..........................
|
||||
|
||||
|
||||
AUTHOR
|
||||
------
|
||||
AUTHORS
|
||||
-------
|
||||
Damien Stuart <dstuart@dstuart.org>,
|
||||
Michael Rash <mbr@cipherdyne.org>
|
||||
|
||||
|
||||
CREDITS
|
||||
-------
|
||||
This ``C'' version of *fwknopd* was derived from the original Perl-based
|
||||
version on which many people who are active in the open source community
|
||||
have contributed. See the 'CREDITS' file in the fwknop sources, or visit
|
||||
CONTRIBUTORS
|
||||
------------
|
||||
This ``C'' version of fwknop was derived from the original Perl-based version
|
||||
on which many people who are active in the open source community have
|
||||
contributed. See the CREDITS file in the fwknop sources, or visit
|
||||
'http://www.cipherdyne.org/fwknop/docs/contributors.html' to view the online
|
||||
list of contributors.
|
||||
list of contributors. A few contributors deserve to be singled out including:
|
||||
Franck Joncourt, Max Kastanas, Vlad Glagolev, Sean Greven, Hank Leininger,
|
||||
Fernando Arnaboldi, and Erik Gomez.
|
||||
|
||||
The phrase ``Single Packet Authorization'' was coined by MadHat and Simple
|
||||
Nomad at the BlackHat Briefings of 2005 (see: 'http://www.nmrc.org').
|
||||
Nomad at the BlackHat Briefings of 2005.
|
||||
|
||||
|
||||
BUGS
|
||||
|
||||
+8
-2
@@ -381,6 +381,7 @@ fko_key_gen(char * const key_base64, const int key_len,
|
||||
unsigned char hmac_key[SHA512_BLOCK_LEN];
|
||||
int klen = key_len;
|
||||
int hmac_klen = hmac_key_len;
|
||||
int b64_len = 0;
|
||||
|
||||
if(key_len == FKO_DEFAULT_KEY_LEN)
|
||||
klen = RIJNDAEL_MAX_KEYSIZE;
|
||||
@@ -409,8 +410,13 @@ fko_key_gen(char * const key_base64, const int key_len,
|
||||
get_random_data(key, klen);
|
||||
get_random_data(hmac_key, hmac_klen);
|
||||
|
||||
b64_encode(key, key_base64, klen);
|
||||
b64_encode(hmac_key, hmac_key_base64, hmac_klen);
|
||||
b64_len = b64_encode(key, key_base64, klen);
|
||||
if(b64_len < klen)
|
||||
return(FKO_ERROR_INVALID_DATA);
|
||||
|
||||
b64_len = b64_encode(hmac_key, hmac_key_base64, hmac_klen);
|
||||
if(b64_len < hmac_klen)
|
||||
return(FKO_ERROR_INVALID_DATA);
|
||||
|
||||
return(FKO_SUCCESS);
|
||||
}
|
||||
|
||||
+29
-1
@@ -860,7 +860,7 @@ set_acc_defaults(fko_srv_options_t *opts)
|
||||
static int
|
||||
acc_data_is_valid(const acc_stanza_t *acc)
|
||||
{
|
||||
if(((acc->key == NULL || !strlen(acc->key))
|
||||
if(((acc->key == NULL || acc->key_len == 0)
|
||||
&& ((acc->gpg_decrypt_pw == NULL || !strlen(acc->gpg_decrypt_pw))
|
||||
&& acc->gpg_allow_no_pw == 0))
|
||||
|| (acc->use_rijndael == 0 && acc->use_gpg == 0 && acc->gpg_allow_no_pw == 0))
|
||||
@@ -871,6 +871,34 @@ acc_data_is_valid(const acc_stanza_t *acc)
|
||||
return(0);
|
||||
}
|
||||
|
||||
if(acc->hmac_key_len != 0)
|
||||
{
|
||||
if(((acc->key_len != 0) && (acc->key_len == acc->hmac_key_len)))
|
||||
{
|
||||
if(memcmp(acc->key, acc->hmac_key, acc->hmac_key_len) == 0)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"[*] The encryption passphrase and HMAC key should not be identical for access stanza source: '%s'\n",
|
||||
acc->source
|
||||
);
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
else if((acc->gpg_allow_no_pw == 0)
|
||||
&& acc->gpg_decrypt_pw != NULL
|
||||
&& (strlen(acc->gpg_decrypt_pw) == acc->hmac_key_len))
|
||||
{
|
||||
if(memcmp(acc->gpg_decrypt_pw, acc->hmac_key, acc->hmac_key_len) == 0)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"[*] The encryption passphrase and HMAC key should not be identical for access stanza source: '%s'\n",
|
||||
acc->source
|
||||
);
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
+49
-17
@@ -52,6 +52,14 @@ zero_cmd_buffers(void)
|
||||
memset(cmd_out, 0x0, STANDARD_CMD_OUT_BUFSIZE);
|
||||
}
|
||||
|
||||
static void
|
||||
chop_newline(char *str)
|
||||
{
|
||||
if(str[0] != 0x0 && str[strlen(str)-1] == 0x0a)
|
||||
str[strlen(str)-1] = 0x0;
|
||||
return;
|
||||
}
|
||||
|
||||
static int
|
||||
comment_match_exists(const fko_srv_options_t * const opts)
|
||||
{
|
||||
@@ -61,7 +69,7 @@ comment_match_exists(const fko_srv_options_t * const opts)
|
||||
|
||||
zero_cmd_buffers();
|
||||
|
||||
/* Add a harmless rule to the iptables OUTPUT chain that uses the comment
|
||||
/* Add a harmless rule to the iptables INPUT chain that uses the comment
|
||||
* match and make sure it exists. If not, return zero. Otherwise, delete
|
||||
* the rule and return true.
|
||||
*/
|
||||
@@ -74,6 +82,7 @@ comment_match_exists(const fko_srv_options_t * const opts)
|
||||
);
|
||||
|
||||
res = run_extcmd(cmd_buf, err_buf, CMD_BUFSIZE, 0);
|
||||
chop_newline(err_buf);
|
||||
|
||||
if (opts->verbose)
|
||||
log_msg(LOG_INFO, "comment_match_exists() CMD: '%s' (res: %d, err: %s)",
|
||||
@@ -88,6 +97,7 @@ comment_match_exists(const fko_srv_options_t * const opts)
|
||||
);
|
||||
|
||||
res = run_extcmd(cmd_buf, cmd_out, STANDARD_CMD_OUT_BUFSIZE, 0);
|
||||
chop_newline(cmd_out);
|
||||
|
||||
if(!EXTCMD_IS_SUCCESS(res))
|
||||
log_msg(LOG_ERR, "Error %i from cmd:'%s': %s", res, cmd_buf, cmd_out);
|
||||
@@ -161,6 +171,7 @@ chain_exists(const fko_srv_options_t * const opts, const int chain_num)
|
||||
);
|
||||
|
||||
res = run_extcmd(cmd_buf, err_buf, CMD_BUFSIZE, 0);
|
||||
chop_newline(err_buf);
|
||||
|
||||
if (opts->verbose)
|
||||
log_msg(LOG_INFO, "chain_exists() CMD: '%s' (res: %d, err: %s)",
|
||||
@@ -177,7 +188,7 @@ chain_exists(const fko_srv_options_t * const opts, const int chain_num)
|
||||
}
|
||||
|
||||
static int
|
||||
jump_rule_exists(const int chain_num)
|
||||
jump_rule_exists(const fko_srv_options_t * const opts, const int chain_num)
|
||||
{
|
||||
int num, pos = 0;
|
||||
char cmd_buf[CMD_BUFSIZE] = {0};
|
||||
@@ -220,6 +231,14 @@ jump_rule_exists(const int chain_num)
|
||||
|
||||
pclose(ipt);
|
||||
|
||||
if (opts->verbose)
|
||||
{
|
||||
if(pos > 0)
|
||||
log_msg(LOG_INFO, "jump_rule_exists() jump rule position: %d", pos);
|
||||
else
|
||||
log_msg(LOG_INFO, "jump_rule_exists() jump rule not found");
|
||||
}
|
||||
|
||||
return(pos);
|
||||
}
|
||||
|
||||
@@ -325,7 +344,7 @@ delete_all_chains(const fko_srv_options_t * const opts)
|
||||
/* First look for a jump rule to this chain and remove it if it
|
||||
* is there.
|
||||
*/
|
||||
if((jump_rule_num = jump_rule_exists(i)) > 0)
|
||||
if((jump_rule_num = jump_rule_exists(opts, i)) > 0)
|
||||
{
|
||||
zero_cmd_buffers();
|
||||
|
||||
@@ -337,6 +356,7 @@ delete_all_chains(const fko_srv_options_t * const opts)
|
||||
);
|
||||
|
||||
res = run_extcmd(cmd_buf, err_buf, CMD_BUFSIZE, 0);
|
||||
chop_newline(err_buf);
|
||||
|
||||
if (opts->verbose)
|
||||
log_msg(LOG_INFO, "delete_all_chains() CMD: '%s' (res: %d, err: %s)",
|
||||
@@ -362,6 +382,7 @@ delete_all_chains(const fko_srv_options_t * const opts)
|
||||
);
|
||||
|
||||
res = run_extcmd(cmd_buf, err_buf, CMD_BUFSIZE, 0);
|
||||
chop_newline(err_buf);
|
||||
|
||||
if (opts->verbose)
|
||||
log_msg(LOG_INFO, "delete_all_chains() CMD: '%s' (res: %d, err: %s)",
|
||||
@@ -389,6 +410,7 @@ create_chain(const fko_srv_options_t * const opts, const int chain_num)
|
||||
);
|
||||
|
||||
res = run_extcmd(cmd_buf, err_buf, CMD_BUFSIZE, 0);
|
||||
chop_newline(err_buf);
|
||||
|
||||
if (opts->verbose)
|
||||
log_msg(LOG_INFO, "create_chain() CMD: '%s' (res: %d, err: %s)",
|
||||
@@ -421,10 +443,12 @@ create_fw_chains(const fko_srv_options_t * const opts)
|
||||
if(! EXTCMD_IS_SUCCESS(create_chain(opts, i)))
|
||||
got_err++;
|
||||
|
||||
/* Then create the jump rule to that chain.
|
||||
/* Then create the jump rule to that chain if it
|
||||
* doesn't already exist (which is possible)
|
||||
*/
|
||||
if(! EXTCMD_IS_SUCCESS(add_jump_rule(opts, i)))
|
||||
got_err++;
|
||||
if(jump_rule_exists(opts, i) == 0)
|
||||
if(! EXTCMD_IS_SUCCESS(add_jump_rule(opts, i)))
|
||||
got_err++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -603,7 +627,8 @@ fw_initialize(const fko_srv_options_t * const opts)
|
||||
int
|
||||
fw_cleanup(const fko_srv_options_t * const opts)
|
||||
{
|
||||
if(strncasecmp(opts->config[CONF_FLUSH_IPT_AT_EXIT], "N", 1) == 0)
|
||||
if(strncasecmp(opts->config[CONF_FLUSH_IPT_AT_EXIT], "N", 1) == 0
|
||||
&& opts->fw_flush == 0)
|
||||
return(0);
|
||||
|
||||
delete_all_chains(opts);
|
||||
@@ -619,9 +644,11 @@ rule_exists(const fko_srv_options_t * const opts,
|
||||
|
||||
zero_cmd_buffers();
|
||||
|
||||
snprintf(cmd_buf, CMD_BUFSIZE-1, "%s -C %s %s", opts->fw_config->fw_command, fw_chain, fw_rule);
|
||||
snprintf(cmd_buf, CMD_BUFSIZE-1, "%s -C %s %s",
|
||||
opts->fw_config->fw_command, fw_chain, fw_rule);
|
||||
|
||||
res = run_extcmd(cmd_buf, err_buf, CMD_BUFSIZE, 0);
|
||||
chop_newline(err_buf);
|
||||
|
||||
if (opts->verbose)
|
||||
log_msg(LOG_INFO, "rule_exists() CMD: '%s' (res: %d, err: %s)",
|
||||
@@ -630,13 +657,15 @@ rule_exists(const fko_srv_options_t * const opts,
|
||||
if(EXTCMD_IS_SUCCESS(res) && strlen(err_buf))
|
||||
{
|
||||
rule_exists = 0;
|
||||
log_msg(LOG_INFO, "rule_exists() Rule : '%s' in %s does not exist.", fw_rule, fw_chain);
|
||||
log_msg(LOG_INFO, "rule_exists() Rule : '%s' in %s does not exist.",
|
||||
fw_rule, fw_chain);
|
||||
}
|
||||
else
|
||||
{
|
||||
rule_exists = 1;
|
||||
if (opts->verbose)
|
||||
log_msg(LOG_INFO, "rule_exists() Rule : '%s' in %s already exist.", fw_rule, fw_chain);
|
||||
log_msg(LOG_INFO, "rule_exists() Rule : '%s' in %s already exist.",
|
||||
fw_rule, fw_chain);
|
||||
}
|
||||
|
||||
return rule_exists;
|
||||
@@ -653,6 +682,7 @@ create_rule(const fko_srv_options_t * const opts,
|
||||
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, 0);
|
||||
chop_newline(err_buf);
|
||||
|
||||
if (opts->verbose)
|
||||
log_msg(LOG_INFO, "create_rule() CMD: '%s' (res: %d, err: %s)",
|
||||
@@ -744,7 +774,7 @@ process_spa_request(const fko_srv_options_t * const opts,
|
||||
if(chain_exists(opts, IPT_INPUT_ACCESS) == 0)
|
||||
create_chain(opts, IPT_INPUT_ACCESS);
|
||||
|
||||
if(jump_rule_exists(IPT_INPUT_ACCESS) == 0)
|
||||
if(jump_rule_exists(opts, IPT_INPUT_ACCESS) == 0)
|
||||
add_jump_rule(opts, IPT_INPUT_ACCESS);
|
||||
|
||||
if(strlen(out_chain->to_chain))
|
||||
@@ -752,7 +782,7 @@ process_spa_request(const fko_srv_options_t * const opts,
|
||||
if(chain_exists(opts, IPT_OUTPUT_ACCESS) == 0)
|
||||
create_chain(opts, IPT_OUTPUT_ACCESS);
|
||||
|
||||
if(jump_rule_exists(IPT_OUTPUT_ACCESS) == 0)
|
||||
if(jump_rule_exists(opts, IPT_OUTPUT_ACCESS) == 0)
|
||||
add_jump_rule(opts, IPT_OUTPUT_ACCESS);
|
||||
}
|
||||
|
||||
@@ -899,7 +929,7 @@ process_spa_request(const fko_srv_options_t * const opts,
|
||||
if(chain_exists(opts, IPT_FORWARD_ACCESS) == 0)
|
||||
create_chain(opts, IPT_FORWARD_ACCESS);
|
||||
|
||||
if (jump_rule_exists(IPT_FORWARD_ACCESS) == 0)
|
||||
if (jump_rule_exists(opts, IPT_FORWARD_ACCESS) == 0)
|
||||
add_jump_rule(opts, IPT_FORWARD_ACCESS);
|
||||
|
||||
memset(rule_buf, 0, CMD_BUFSIZE);
|
||||
@@ -941,7 +971,7 @@ process_spa_request(const fko_srv_options_t * const opts,
|
||||
if(chain_exists(opts, IPT_DNAT_ACCESS) == 0)
|
||||
create_chain(opts, IPT_DNAT_ACCESS);
|
||||
|
||||
if (jump_rule_exists(IPT_DNAT_ACCESS) == 0)
|
||||
if (jump_rule_exists(opts, IPT_DNAT_ACCESS) == 0)
|
||||
add_jump_rule(opts, IPT_DNAT_ACCESS);
|
||||
|
||||
memset(rule_buf, 0, CMD_BUFSIZE);
|
||||
@@ -1081,10 +1111,11 @@ check_firewall_rules(const fko_srv_options_t * const opts)
|
||||
);
|
||||
|
||||
res = run_extcmd(cmd_buf, cmd_out, STANDARD_CMD_OUT_BUFSIZE, 0);
|
||||
chop_newline(cmd_out);
|
||||
|
||||
if (opts->verbose)
|
||||
log_msg(LOG_INFO, "check_firewall_rules() CMD: '%s' (res: %d, err: %s)",
|
||||
cmd_buf, res, err_buf);
|
||||
log_msg(LOG_INFO, "check_firewall_rules() CMD: '%s' (res: %d, cmd_out: %s)",
|
||||
cmd_buf, res, cmd_out);
|
||||
|
||||
if(!EXTCMD_IS_SUCCESS(res))
|
||||
{
|
||||
@@ -1190,6 +1221,7 @@ check_firewall_rules(const fko_srv_options_t * const opts)
|
||||
);
|
||||
|
||||
res = run_extcmd(cmd_buf, err_buf, CMD_BUFSIZE, 0);
|
||||
chop_newline(err_buf);
|
||||
|
||||
if (opts->verbose)
|
||||
log_msg(LOG_INFO, "check_firewall_rules() CMD: '%s' (res: %d, err: %s)",
|
||||
@@ -1207,7 +1239,7 @@ check_firewall_rules(const fko_srv_options_t * const opts)
|
||||
ch[i].active_rules--;
|
||||
}
|
||||
else
|
||||
log_msg(LOG_ERR, "Error %i from cmd:'%s': %s", res, cmd_buf, err_buf);
|
||||
log_msg(LOG_ERR, "Error %i from cmd:'%s': %s", res, cmd_buf, err_buf);
|
||||
|
||||
}
|
||||
else
|
||||
|
||||
+6
-2
@@ -97,9 +97,13 @@ init_logging(fko_srv_options_t *opts) {
|
||||
else
|
||||
strlcpy(log_name, my_name, strlen(MY_NAME)+1);
|
||||
|
||||
/* If we are running in the foreground, all logging will go to stderr.
|
||||
/* If we are running in the foreground or performing firewall operations,
|
||||
* all logging will go to stderr.
|
||||
*/
|
||||
if(opts->foreground != 0)
|
||||
if(opts->foreground != 0
|
||||
|| opts->fw_flush != 0
|
||||
|| opts->fw_list != 0
|
||||
|| opts->fw_list_all != 0)
|
||||
static_log_flag = LOG_STDERR | LOG_STDERR_ONLY;
|
||||
|
||||
/* Parse the log facility as specified in the config struct. If, for some
|
||||
|
||||
+30
-15
@@ -40,6 +40,7 @@ our %cf = (
|
||||
'def_access' => "$conf_dir/default_access.conf",
|
||||
'hmac_access' => "$conf_dir/hmac_access.conf",
|
||||
'hmac_get_key_access' => "$conf_dir/hmac_get_key_access.conf",
|
||||
'hmac_equal_keys_access' => "$conf_dir/hmac_equal_keys_access.conf",
|
||||
'hmac_no_b64_access' => "$conf_dir/hmac_no_b64_access.conf",
|
||||
'hmac_md5_access' => "$conf_dir/hmac_md5_access.conf",
|
||||
'hmac_md5_short_key_access' => "$conf_dir/hmac_md5_short_key_access.conf",
|
||||
@@ -108,6 +109,7 @@ our %cf = (
|
||||
'rc_def_key' => "$conf_dir/fwknoprc_with_default_key",
|
||||
'rc_def_b64_key' => "$conf_dir/fwknoprc_with_default_base64_key",
|
||||
'rc_named_key' => "$conf_dir/fwknoprc_named_key",
|
||||
'rc_hmac_equal_keys' => "$conf_dir/fwknoprc_hmac_equal_keys",
|
||||
'rc_invalid_b64_key' => "$conf_dir/fwknoprc_invalid_base64_key",
|
||||
'rc_hmac_b64_key' => "$conf_dir/fwknoprc_default_hmac_base64_key",
|
||||
'rc_hmac_b64_key2' => "$conf_dir/fwknoprc_hmac_key2",
|
||||
@@ -228,7 +230,8 @@ my $diff_dir1 = '';
|
||||
my $diff_dir2 = '';
|
||||
my $loopback_intf = '';
|
||||
my $anonymize_results = 0;
|
||||
my $curr_test_file = "$output_dir/init";
|
||||
my $curr_test_file = 'init';
|
||||
my $init_file = $curr_test_file;
|
||||
my $tarfile = 'test_fwknop.tar.gz';
|
||||
our $key_gen_file = "$output_dir/key_gen";
|
||||
my $fuzzing_pkts_file = 'fuzzing/fuzzing_spa_packets';
|
||||
@@ -346,6 +349,7 @@ exit 1 unless GetOptions(
|
||||
### can set the following to "output.last/valgrind-coverage" if
|
||||
### a full test suite run has already been executed with --enable-valgrind
|
||||
'valgrind-prev-cov-dir=s' => \$previous_valgrind_coverage_dir,
|
||||
'openssl-path=s' => \$openssl_path,
|
||||
'output-dir=s' => \$output_dir,
|
||||
'diff' => \$diff_mode,
|
||||
'diff-dir1=s' => \$diff_dir1,
|
||||
@@ -521,6 +525,8 @@ if ($saved_last_results) {
|
||||
"to: ${output_dir}.last/\n\n");
|
||||
}
|
||||
|
||||
copy $init_file, "$output_dir/init" if -e $init_file;
|
||||
|
||||
if ($enable_valgrind) {
|
||||
if ($previous_valgrind_coverage_dir) {
|
||||
die "[*] $previous_valgrind_coverage_dir does not exist"
|
||||
@@ -4307,8 +4313,11 @@ sub key_gen_uniqueness() {
|
||||
my %rijndael_keys = ();
|
||||
my %hmac_keys = ();
|
||||
|
||||
my $rv = 1;
|
||||
|
||||
### collect key information
|
||||
my $found_dup = 0;
|
||||
|
||||
for (my $i=0; $i < $uniq_keys; $i++) {
|
||||
open CMD, "$test_hr->{'cmdline'} | " or die $!;
|
||||
while (<CMD>) {
|
||||
@@ -4324,7 +4333,12 @@ sub key_gen_uniqueness() {
|
||||
last if $found_dup;
|
||||
}
|
||||
|
||||
return ! $found_dup;
|
||||
$rv = 0 if $found_dup;
|
||||
|
||||
$rv = 0 unless keys %rijndael_keys == $uniq_keys;
|
||||
$rv = 0 unless keys %hmac_keys == $uniq_keys;
|
||||
|
||||
return $rv;
|
||||
}
|
||||
|
||||
### check for PIE
|
||||
@@ -4469,12 +4483,12 @@ sub openssl_hmac_verification() {
|
||||
|
||||
### for HMAC SHA512 this output will span two lines
|
||||
my $openssl_hmac_line = '';
|
||||
open F, "< $openssl_cmd_tmp" or die $!;
|
||||
while (<F>) {
|
||||
$openssl_hmac_line .= $_;
|
||||
chomp $openssl_hmac_line;
|
||||
{
|
||||
local $/ = undef;
|
||||
open F, "< $openssl_cmd_tmp" or die $!;
|
||||
$openssl_hmac_line = <F>;
|
||||
close F;
|
||||
}
|
||||
close F;
|
||||
|
||||
if ($base64_path) {
|
||||
$openssl_hmac = $openssl_hmac_line;
|
||||
@@ -5062,11 +5076,11 @@ sub init() {
|
||||
}
|
||||
|
||||
if ($enable_openssl_compatibility_tests) {
|
||||
$openssl_path = &find_command('openssl');
|
||||
$openssl_path = &find_command('openssl') unless $openssl_path;
|
||||
if ($openssl_path) {
|
||||
require MIME::Base64;
|
||||
MIME::Base64->import(qw(encode_base64 decode_base64));
|
||||
$base64_path = &find_command('base64');
|
||||
$base64_path = &find_command('base64') unless $base64_path;
|
||||
|
||||
### check for hmac openssl support
|
||||
&openssl_hmac_style_check();
|
||||
@@ -5079,7 +5093,7 @@ sub init() {
|
||||
}
|
||||
|
||||
if ($enable_valgrind) {
|
||||
$valgrind_path = &find_command('valgrind');
|
||||
$valgrind_path = &find_command('valgrind') unless $valgrind_path;
|
||||
unless ($valgrind_path) {
|
||||
print "[-] --enable-valgrind mode requested ",
|
||||
"but valgrind not found, disabling.\n";
|
||||
@@ -5123,7 +5137,7 @@ sub init() {
|
||||
die "[*] The python test script: $python_script doesn't exist ",
|
||||
"or is not executable."
|
||||
unless -e $python_script and -x $python_script;
|
||||
$python_path = &find_command('python');
|
||||
$python_path = &find_command('python') unless $python_path;
|
||||
unless ($python_path) {
|
||||
push @tests_to_exclude, qr/python fko extension/
|
||||
}
|
||||
@@ -5142,16 +5156,16 @@ sub init() {
|
||||
push @tests_to_exclude, qr/perl FKO module.*FUZZING/;
|
||||
}
|
||||
|
||||
$sudo_path = &find_command('sudo');
|
||||
$killall_path = &find_command('killall');
|
||||
$pgrep_path = &find_command('pgrep');
|
||||
$sudo_path = &find_command('sudo') unless $sudo_path;
|
||||
$killall_path = &find_command('killall') unless $killall_path;
|
||||
$pgrep_path = &find_command('pgrep') unless $pgrep_path;
|
||||
|
||||
unless ((&find_command('cc') or &find_command('gcc')) and &find_command('make')) {
|
||||
### disable compilation checks
|
||||
push @tests_to_exclude, qr/recompilation/;
|
||||
}
|
||||
|
||||
$gcov_path = &find_command('gcov');
|
||||
$gcov_path = &find_command('gcov') unless $gcov_path;
|
||||
|
||||
if ($gcov_path) {
|
||||
if ($enable_profile_coverage_check) {
|
||||
@@ -5730,6 +5744,7 @@ sub file_find_regex() {
|
||||
}
|
||||
|
||||
sub remove_permissions_warnings() {
|
||||
return unless -e "$output_dir/1.test";
|
||||
system qq|perl -p -i -e 's/.*not owned by current effective.*\n//' $output_dir/*.test|;
|
||||
system qq|perl -p -i -e 's/.*permissions should only be user.*\n//' $output_dir/*.test|;
|
||||
return;
|
||||
|
||||
@@ -325,7 +325,8 @@
|
||||
'function' => \&generic_exec,
|
||||
'cmdline' => "LD_LIBRARY_PATH=$lib_dir " .
|
||||
"$valgrind_str $fwknopCmd --key-gen",
|
||||
'positive_output_matches' => [qr/BASE64/, qw/HMAC/, qw/KEY/],
|
||||
'positive_output_matches' => [qr/^KEY_BASE64\:?\s\S{10}/,
|
||||
qw/HMAC_KEY_BASE64\:?\s\S{10}/],
|
||||
'fatal' => $NO
|
||||
},
|
||||
{
|
||||
|
||||
@@ -29,6 +29,30 @@
|
||||
'exec_err' => $YES,
|
||||
'fatal' => $NO
|
||||
},
|
||||
{
|
||||
'category' => 'Rijndael+HMAC',
|
||||
'subcategory' => 'client',
|
||||
'detail' => 'rc file HMAC+encryption keys not equal',
|
||||
'function' => \&generic_exec,
|
||||
'cmdline' => "$default_client_args_no_get_key " .
|
||||
"--rc-file $cf{'rc_hmac_equal_keys'}",
|
||||
'positive_output_matches' => [qr/should\snot\sbe\sidentical/i],
|
||||
'exec_err' => $YES,
|
||||
'fatal' => $NO
|
||||
},
|
||||
{
|
||||
'category' => 'Rijndael+HMAC',
|
||||
'subcategory' => 'server',
|
||||
'detail' => 'rc file HMAC+encryption keys not equal',
|
||||
'function' => \&generic_exec,
|
||||
'cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
|
||||
"$fwknopdCmd -c $cf{'def'} -a $cf{'hmac_equal_keys_access'} " .
|
||||
"-d $default_digest_file -p $default_pid_file $intf_str",
|
||||
'positive_output_matches' => [qr/should\snot\sbe\sidentical/i],
|
||||
'exec_err' => $YES,
|
||||
'fatal' => $NO
|
||||
},
|
||||
|
||||
{
|
||||
'category' => 'Rijndael+HMAC',
|
||||
'subcategory' => 'server',
|
||||
|
||||
Reference in New Issue
Block a user