提交 45e7e9f6 编辑于 作者: Michael Rash's avatar Michael Rash
浏览文件

Merge branch 'master' into 3.0_devel

Conflicts:
	client/config_init.c
	client/fwknop.c
	lib/fko_decode.c
	lib/fko_rand_value.c
	server/incoming_spa.c
	test/test-fwknop.pl
无相关合并请求
显示 2188 个添加2017 个删除
+2188 -2017
# built application files
*.apk
*.ap_
# files for the dex VM
*.dex
# Java class files
*.class
# generated files
bin/
gen/
# Local configuration file (sdk path, etc)
local.properties
# Eclipse project files
.classpath
.project
# Proguard folder generated by Eclipse
proguard/
# Intellij project files
*.iml
*.ipr
*.iws
.idea/
# CMake files
CMakeCache.txt
CMakeFiles
Makefile
cmake_install.cmake
install_manifest.txt
# C, C++
*.o
*.lo
#project generated files
autom4te.cache/
*.m4
client/.deps/
client/Makefile.in
common/libfko_util.a
common/Makefile.in
config.h
config.h.in
config.log
config.status
config/
configure
doc/libfko.info
doc/Makefile.in
doc/stamp-vti
doc/version.texi
lib/libfko.la
lib/.deps/
lib/.dirstamp
lib/.libs/
lib/Makefile.in
libtool
Makefile.in
server/.deps/
server/.libs/
server/fwknopd
server/fwknopd.8
server/Makefile.in
stamp-h1
android/project/libs
android/project/obj
android/project/jni/fwknop/fko.h
android/project/jni/libfwknop/*.h
android/project/jni/libfwknop/*.c
......@@ -143,6 +143,7 @@ Ryman
http://www.mail-archive.com/debian-bugs-rc@lists.debian.org/msg320402.html
Blair Zajac
- MacPorts fwknop package maintainer for Mac OS X systems.
- Contributed patches to handle endian issues on PPC systems.
- Reported an issue where strndup() is not available on some PPC systems
and the fix is to use the local lib/fko_util.c implementation similarly
......@@ -174,3 +175,27 @@ Gerry Reno
- Provided guidance on Android client issues along with testing candidate
patches to update various things - this work is being tracked in the
android4.4_support branch.
- Implemented support for firewalld in the fwknopd daemon running on RHEL 7
and CentOS 7 systems. This is a major addition to handle yet another
firewall architecture.
Tim Heckman
- Homebrew fwknop package maintainer for Mac OS X systems.
- Suggested that fwknop support nftables when it is integrated into the
mainline Linux kernel.
Barry Allard
- Reported bug in PF support on FreeBSD systems where ALTQ is not available
would cause new PF rules to not be added (github issue #121).
- Suggested the abiliy to specify the HTTP User-Agent when wget is used to
resolve the external IP via SSL (github issue #134).
Bill Stubbs
- Submitted a patch to fix a bug where fwknopd could not handle Ethernet
frames that include the Frame Check Sequence (FCS) header. This header is
four bytes long, and is placed at the end of each Ethernet frame.
Normally the FCS header is not visible to libpcap, but some card/driver
combinations result in it being included. Bill noticed this on the
following platform:
BeagleBone Black rev C running 3.8.13-bone50 #1 SMP Tue May 13
13:24:52 UTC 2014 armv7l GNU/Linux
fwknop-2.6.1 (//2014):
fwknop-2.6.4 (11/16/2014):
- [server] Added a UDP server mode so that SPA packets can be acquired via
UDP directly without having to use libpcap. This is an optional feature
since it opens a UDP port (and therefore requires the local firewall be
opened for communications to this port), but fwknopd is careful to never
send anything back to a client that sends data to this port. So, from the
perspective of an attacker or scanner, fwknopd remains invisible. This
feature is enabled in fwknopd either with a new command line argument
--udp-server or in the fwknopd.conf file with the ENABLE_UDP_SERVER
variable. When deployed in this mode, it is advisable to recompile fwknop
beforehand with './configure --enable-udp-server' so that fwknopd does
not link against libpcap.
- [server] Replaced all popen() and system() calls with execvpe() with no
usage of the environment. This is a defensive measure to not make use of
the shell for firewall command execution, and is supported on systems
where execvpe() is available.
- (Gerry Reno) Added support for firewalld to the fwknopd daemon on RHEL 7
and CentOS 7. This is implemented using the current firewalld '--direct
--passthrough' capability which accepts raw iptables commands. More
information on firewalld can be found here:
https://fedoraproject.org/wiki/FirewallD
- [server] Added support for the 'American Fuzzy Lop' (AFL) fuzzer from
Michal Zalewski. This requires that fwknop is compiled with the
'--enable-afl-fuzzing' argument to the configure script as this allows
encryption/digest short circuiting in a manner necessary for AFL to
function properly. The benefit of this strategy is that AFL can fuzz the
SPA packet decoding routines implemented by libfko. See the test/afl/
directory for some automation around AFL fuzzing.
- (Bill Stubbs) submitted a patch to fix a bug where fwknopd could not
handle Ethernet frames that include the Frame Check Sequence (FCS)
header. This header is four bytes long, and is placed at the end of each
Ethernet frame. Normally the FCS header is not visible to libpcap, but
some card/driver combinations result in it being included. Bill noticed
this on the following platform:
BeagleBone Black rev C running 3.8.13-bone50 #1 SMP Tue May 13
13:24:52 UTC 2014 armv7l GNU/Linux
- [client] Bug fix to ensure that a User-Agent string can be specified
when the fwknop client uses wget via SSL to resolve the external IP
address. This closes issue #134 on github reported by Barry Allard. The
fwknop client now uses the wget '-U' option to specify the User-Agent
string with a default of "Fwknop/<version>". In addition, a new command
line argument "--use-wget-user-agent" to allow the default wget
User-Agent string to apply instead.
- [python module] When an HMAC key is passed to spa_data_final() then
default to HMAC SHA256 if no HMAC mode was specified.
fwknop-2.6.3 (07/28/2014):
- [client] External IP resolution via '-R' (or '--resolve-ip-http') is now
done via SSL by default. The IP resolution URL is now
'https://www.cipherdyne.org/cgi-gin/myip', and a warning is generated
in '-R' mode whenever a non-HTTPS URL is specified (it is safer just to
use the default). The fwknop client leverages 'wget' for this operation
since that is cleaner than having fwknop link against an SSL library.
- Integrated the 'libfiu' fault injection library available from
http://blitiri.com.ar/p/libfiu/ This feature is disabled by default,
and requires the --enable-libfiu-support argument to the 'configure'
script in order to enable it. With fwknop compiled against libfiu, fault
injections are done at various locations within the fwknop sources and
the test suite verifies that the faults are properly handled at run time
via test/fko-wrapper/fko_fault_injection.c. In addition, the libfiu tool
'fiu-run' is used against the fwknop binaries to ensure they handle
faults that libfiu introduces into libc functions. For example, fiu-run
can force malloc() to fail even without huge memory pressure on the
local system, and the test suite ensures the fwknop binaries properly
handle this.
- [test suite] Integrated a new python fuzzer for fwknop SPA packets (see
test/spa_fuzzing.py). This greatly extends the ability of the test suite
to validate libfko operations since SPA fuzzing packets are sent through
libfko routines directly (indendepently of encryption and
authentication) with a special 'configure' option
--enable-fuzzing-interfaces. The python fuzzer generates over 300K SPA
packets, and when used by the test suite consumes about 400MB of disk.
For reference, to use both the libfiu fault injection feature mentioned
above and the python fuzzer, use the --enable-complete option to the
test suite.
- [test suite] With the libfiu fault injection support and the new python
fuzzer, automated testing of fwknop achieves 99.7% function coverage and
90.2% line coverage as determined by 'gcov'. The full report may be
viewed here: http://www.cipherdyne.org/fwknop/lcov-results/
- [server] Add a new GPG_FINGERPRINT_ID variable to the access.conf file
so that full GnuPG fingerprints can be required for incoming SPA packets
in addition to the appreviated GnuPG signatures listed in GPG_REMOTE_ID.
From the test suite, an example fingerprint is
GPG_FINGERPRINT_ID 00CC95F05BC146B6AC4038C9E36F443C6A3FAD56
- [server] When validating access.conf stanzas make sure that one of
GPG_REMOTE_ID or GPG_FINGERPRINT_ID is specified whenever GnuPG
signatures are to be verified for incoming SPA packets. Signature
verification is the default, and can only be disabled with
GPG_DISABLE_SIG but this is NOT recommended.
- [server] Bug fix for PF firewalls without ALTQ support on FreeBSD. With
this fix it doesn't matter whether ALTQ support is available or not.
Thanks to Barry Allard for discovering and reporting this issue.
Closes issue #121 on github.
- [server] Bug fix discovered with the libfiu fault injection tag
"fko_get_username_init" combined with valgrind analysis. This bug is
only triggered after a valid authenticated and decrypted SPA packet is
sniffed by fwknopd:
==11181== Conditional jump or move depends on uninitialised value(s)
==11181== at 0x113B6D: incoming_spa (incoming_spa.c:707)
==11181== by 0x11559F: process_packet (process_packet.c:211)
==11181== by 0x5270857: ??? (in /usr/lib/x86_64-linux-gnu/libpcap.so.1.4.0)
==11181== by 0x114BCC: pcap_capture (pcap_capture.c:270)
==11181== by 0x10F32C: main (fwknopd.c:195)
==11181== Uninitialised value was created by a stack allocation
==11181== at 0x113476: incoming_spa (incoming_spa.c:294)
- [server] Bug fix to handle SPA packets over HTTP by making sure to honor
the ENABLE_SPA_OVER_HTTP fwknopd.conf variable and to properly account
for SPA packet lengths when delivered via HTTP.
- [server] Add --test mode to instruct fwknopd to acquire and process
SPA packets, but not manipulate firewall rules or execute commands that
are provided by SPA clients. This option is mostly useful for the fuzzing
tests in the test suite to ensure broad code coverage under adverse
conditions.
fwknop-2.6.2 (04/28/2014):
- [libfko] fix double free bug in SPA parser discovered with the new
python SPA payload fuzzer (see the 'spa_encoding_fuzzing' branch which
is not merged into the master branch yet). This bug could be triggered
in fwknopd with a malicious SPA payload, but only when GnuPG is used and
when an attacker is in possession of valid GnuPG keys listed in the
access.conf file. In other words, an arbitrary attacker cannot trigger
this bug. Further, when Rijndael is used for SPA packet encryption, this
bug cannot be triggered at all due to an length/format check towards the
end of _rijndael_decrypt(). This bug was introduced in the 2.6.1
development series, and no previous versions of fwknop are affected.
fwknop-2.6.1 (04/12/2014):
- Updated copyright and authorship information to include a standard
header which references both the AUTHORS and CREDITS files. The
specific language in this header was created by the Debian legal team at
......@@ -28,6 +162,9 @@ fwknop-2.6.1 (//2014):
- [libfko] Better SPA packet dumping output to include GnuPG specifics
whenever SPA packets are encrypted/authenticated via GnuPG.
- [server] Validate SPA packet GnuPG signatures with the libfko
fko_gpg_signature_id_match() function instead of server code doing this
independently.
- [client+server] Add --gpg-exe command line argument and GPG_EXE config
variable to ~/.fwknoprc and the access.conf file so that the path to
GnuPG can be changed from the default /usr/bin/gpg path.
......@@ -42,8 +179,9 @@ fwknop-2.6.1 (//2014):
length field of the UDP header.
- [test suite] Added valgrind suppressions for gpgme library function
calls.
- [test suite] Added Rijndael+HMAC command execution test.
- [test suite] Added Rijndael+HMAC NAT rand port via client rc file test.
- [test suite] Added the ability to run the 'lcov' tool against fwknop
when compiled in --enable-profile-coverage mode. This enabled lots of
new tests to be developed for better code coverage.
fwknop-2.6.0 (01/12/2014):
- (Radostan Riedel) Added an AppArmor policy for fwknopd that is known to
......
此差异已折叠。
......@@ -135,12 +135,16 @@ EXTRA_DIST = \
test/conf/base64_key_access.conf \
test/conf/cfb_mode_access.conf \
test/conf/cmd_access.conf \
test/conf/cmd_setuid_access.conf \
test/conf/cmd_giduid_access.conf \
test/conf/ctr_mode_access.conf \
test/conf/default_access.conf \
test/conf/default_fwknopd.conf \
test/conf/portrange_fwknopd.conf \
test/conf/custom_input_chain_fwknopd.conf \
test/conf/custom_nat_chain_fwknopd.conf \
test/conf/ipt_custom_input_chain_fwknopd.conf \
test/conf/firewd_custom_input_chain_fwknopd.conf \
test/conf/ipt_custom_nat_chain_fwknopd.conf \
test/conf/firewd_custom_nat_chain_fwknopd.conf \
test/conf/gpg_invalid_exe_access.conf \
test/conf/disable_aging_fwknopd.conf \
test/conf/disable_aging_nat_fwknopd.conf \
......@@ -155,20 +159,41 @@ EXTRA_DIST = \
test/conf/fuzzing_open_ports_access.conf \
test/conf/fuzzing_restrict_ports_access.conf \
test/conf/fuzzing_source_access.conf \
test/conf/hmac_fuzzing_access.conf \
test/conf/gpg_access.conf \
test/conf/gpg_hmac_access.conf \
test/conf/gpg_no_pw_access.conf \
test/conf/gpg_no_pw_hmac_access.conf \
test/conf/gpg_no_pw_hmac_clientdir_access.conf \
test/conf/gpg_no_pw_hmac_serverdir_access.conf \
test/conf/gpg_no_pw_fpr_access.conf \
test/conf/gpg_no_pw_bad_fpr_access.conf \
test/conf/gpg_no_pw_no_fpr_access.conf \
test/conf/gpg_no_sig_no_fpr_access.conf \
test/conf/gpg_no_sig_verify_access.conf \
test/conf/gpg_invalid_sig_id_access.conf \
test/conf/fwknoprc_gpg_invalid_exe \
test/conf/fwknoprc_hmac_defaults \
test/conf/fwknoprc_hmac_time_offset_mins \
test/conf/fwknoprc_hmac_time_offset_hours \
test/conf/fwknoprc_hmac_time_offset_days \
test/conf/fwknoprc_hmac_http_resolve \
test/conf/fwknoprc_hmac_https_resolve \
test/conf/fwknoprc_hmac_http_only_resolve \
test/conf/fwknoprc_gpg_hmac_sha512_key \
test/conf/gpg_hmac_sha512_access.conf \
test/conf/fwknoprc_hmac_sha512_base64_key \
test/conf/gpg_no_pw_hmac_sha512_access.conf \
test/conf/no_flush_init_fwknopd.conf \
test/conf/no_flush_exit_fwknopd.conf \
test/conf/no_flush_init_or_exit_fwknopd.conf \
test/conf/ipt_no_flush_init_fwknopd.conf \
test/conf/ipt_no_flush_exit_fwknopd.conf \
test/conf/ipt_no_flush_init_or_exit_fwknopd.conf \
test/conf/firewd_no_flush_init_fwknopd.conf \
test/conf/firewd_no_flush_exit_fwknopd.conf \
test/conf/firewd_no_flush_init_or_exit_fwknopd.conf \
test/conf/hmac_access.conf \
test/conf/hmac_cmd_access.conf \
test/conf/hmac_cmd_setuid_access.conf \
test/conf/hmac_cmd_giduid_access.conf \
test/conf/hmac_get_key_access.conf \
test/conf/hmac_no_b64_access.conf \
test/conf/hmac_equal_keys_access.conf \
......@@ -238,12 +263,21 @@ EXTRA_DIST = \
test/conf/icmp_pcap_filter_fwknopd.conf \
test/conf/invalid_expire_access.conf \
test/conf/invalid_source_access.conf \
test/conf/ipt_output_chain_fwknopd.conf \
test/conf/firewd_output_chain_fwknopd.conf \
test/conf/invalid_ipt_input_chain_fwknopd.conf \
test/conf/invalid_ipt_input_chain_2_fwknopd.conf \
test/conf/invalid_ipt_input_chain_3_fwknopd.conf \
test/conf/invalid_ipt_input_chain_4_fwknopd.conf \
test/conf/invalid_ipt_input_chain_5_fwknopd.conf \
test/conf/invalid_ipt_input_chain_6_fwknopd.conf \
test/conf/invalid_firewd_input_chain_fwknopd.conf \
test/conf/invalid_firewd_input_chain_2_fwknopd.conf \
test/conf/invalid_firewd_input_chain_3_fwknopd.conf \
test/conf/invalid_firewd_input_chain_4_fwknopd.conf \
test/conf/invalid_firewd_input_chain_5_fwknopd.conf \
test/conf/invalid_firewd_input_chain_6_fwknopd.conf \
test/conf/invalid_run_dir_path_fwknopd.conf \
test/conf/ipfw_active_expire_equal_fwknopd.conf \
test/conf/ip_source_match_access.conf \
test/conf/legacy_iv_access.conf \
......@@ -251,7 +285,8 @@ EXTRA_DIST = \
test/conf/legacy_rand_hmac_access.conf \
test/conf/legacy_iv_long_key_access.conf \
test/conf/legacy_iv_long_key2_access.conf \
test/conf/local_nat_fwknopd.conf \
test/conf/ipt_local_nat_fwknopd.conf \
test/conf/firewd_local_nat_fwknopd.conf \
test/conf/mismatch_open_ports_access.conf \
test/conf/mismatch_user_access.conf \
test/conf/multi_gpg_access.conf \
......@@ -259,25 +294,37 @@ EXTRA_DIST = \
test/conf/multi_source_match_access.conf \
test/conf/multi_stanzas_access.conf \
test/conf/multi_stanzas_with_broken_keys.conf \
test/conf/nat_fwknopd.conf \
test/conf/ipt_nat_fwknopd.conf \
test/conf/firewd_nat_fwknopd.conf \
test/conf/no_multi_source_match_access.conf \
test/conf/no_source_match_access.conf \
test/conf/no_subnet_source_match_access.conf \
test/conf/ofb_mode_access.conf \
test/conf/open_ports_access.conf \
test/conf/override_fwknopd.conf \
test/conf/override2_fwknopd.conf \
test/conf/var_expansion_fwknopd.conf \
test/conf/var_expansion_invalid_fwknopd.conf \
test/conf/require_src_access.conf \
test/conf/require_user_access.conf \
test/conf/subnet_source_match_access.conf \
test/conf/tcp_pcap_filter_fwknopd.conf \
test/conf/tcp_server_fwknopd.conf \
test/conf/snat_fwknopd.conf \
test/conf/snat_no_translate_ip_fwknopd.conf \
test/conf/udp_server_fwknopd.conf \
test/conf/spa_over_http_fwknopd.conf \
test/conf/spa_over_http.pcap \
test/conf/ipt_snat_fwknopd.conf \
test/conf/firewd_snat_fwknopd.conf \
test/conf/ipt_snat_no_translate_ip_fwknopd.conf \
test/conf/firewd_snat_no_translate_ip_fwknopd.conf \
test/conf/spa_replay.pcap \
test/conf/fcs_spa.pcap \
test/fko-wrapper/Makefile \
test/fko-wrapper/fko_wrapper.c \
test/fko-wrapper/fko_basic.c \
test/fko-wrapper/run.sh \
test/fko-wrapper/run_valgrind.sh \
test/fko-wrapper/run_no_valgrind.sh \
test/spa_fuzzing.py \
test/fuzzing/patches/enable_perl_fko_bogus_packets.patch \
test/fuzzing/patches/encoding_append_b64_modified_byte_eq.patch \
test/fuzzing/patches/encoding_append_b64_modified_byte.patch \
......@@ -298,14 +345,30 @@ EXTRA_DIST = \
test/fuzzing/patches/invalid_long_proto_define_rijndael_trigger.patch \
test/fuzzing/patches/long_ip.patch \
test/fuzzing/patches/non_b64_user_char.patch \
test/misc/freebsd_rc.conf \
test/misc/pf.rules \
test/misc/pf.sh \
test/afl/README \
test/afl/afl-compile.sh \
test/afl/afl-compile-code-coverage.sh \
test/afl/afl-gen-code-coverage.sh \
test/afl/afl-run.sh \
test/afl/fwknopd-stdin-test.sh \
test/afl/afl-fuzzing.in/spa.start \
test/afl/afl-fuzzing.in/spa2.start \
test/afl/afl-fuzzing.in/spa3.start \
test/tests/build_security.pl \
test/tests/preliminaries.pl \
test/tests/code_structure.pl \
test/tests/configure_args.pl \
test/tests/basic_operations.pl \
test/tests/rijndael_hmac.pl \
test/tests/rijndael_hmac_fuzzing.pl \
test/tests/rijndael_hmac_cmd_exec.pl \
test/tests/rijndael_backwards_compatibility.pl \
test/tests/os_compatibility.pl \
test/tests/fault_injection.pl \
test/tests/afl_fuzzing.pl \
test/tests/gpg_hmac.pl \
test/tests/gpg_no_pw.pl \
test/tests/gpg_no_pw_hmac.pl \
......@@ -318,10 +381,20 @@ EXTRA_DIST = \
test/tests/rijndael_cmd_exec.pl \
test/hardening-check \
test/local_spa.key \
test/invalid.key \
test/invalid2.key \
test/invalid3.key \
test/long_spa.key \
test/invalid.args \
test/test-fwknop.pl \
test/generate_cores.sh \
test/fko-python.py \
test/run-test-suite.sh \
test/valgrind_suppressions \
test/configure_max_coverage.sh \
test/rm-coverage-files.sh \
test/gen-coverage-report.sh \
test/configure_max_coverage.sh \
test/README \
VERSION \
win32/config.h \
......
This is the top-level directory for the fwknop project.
INTRODUCTION
============
fwknop implements an authorization scheme known as Single Packet Authorization
(SPA) for strong service concealment. SPA requires only a single packet which
is encrypted, non-replayable, and authenticated via an HMAC in order to
communicate desired access to a service that is hidden behind a firewall in a
default-drop filtering stance. The main application of SPA is to use a firewall
to drop all attempts to connect to services such as SSH in order to make the
exploitation of vulnerabilities (both 0-day and unpatched code) more difficult.
Because there are no open ports, any service that is concealed by SPA naturally
cannot be scanned for with Nmap. The fwknop project supports three different
firewalls: iptables on Linux systems, pf on OpenBSD, and ipfw on FreeBSD and
Mac OS X.
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 possible to reliably support, 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 standard cryptographic operations for
SPA packet authentication and encryption/decryption.
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 (enabled via the --use-hmac command line switch), it is highly
recommended for three reasons: 1) without an HMAC, cryptographically strong
authentication is not possible with fwknop unless GnuPG is used, but even then
an HMAC should still be applied, 2) an HMAC applied after encryption protects
against cryptanalytic CBC-mode padding oracle attacks such as the Vaudenay
attack and related trickery (like 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.
Reason 3) is why an HMAC should still be used even when SPA packets are
encrypted with GnuPG due to the fact that SPA data is not sent through libgpgme
functions unless the HMAC checks out first. GnuPG and libgpgme are relatively
complex bodies of code, and therefore limiting the ability of a potential
attacker to interact with this code through an HMAC operation helps to maintain
a stronger security stance. Generating an HMAC for SPA communications requires
a dedicated key in addition to the normal encryption key, and both can be
generated with the --key-gen option.
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 /etc/fwknop/access.conf file for details). The actual encryption key used
for Rijndael encryption is generated via the standard PBKDF1 key derivation
algorithm, and CBC mode is set. If the GnuPG method is chosen, then the
encryption keys are derived from GnuPG key rings.
A comprehensive tutorial on fwknop can be found here:
http://www.cipherdyne.org/fwknop/docs/fwknop-tutorial.html
LICENSE
=======
The fwknop project is released as open source software under the terms of the
GNU General Public License (GPL v2). The latest release can be found at
http://www.cipherdyne.org/fwknop/
CURRENT STATE
=============
This README file describes the present state of the fwknop project as of the
2.5 release made in July, 2013. At present, we have an implementation of the
Firewall Knock Operator library; `libfko', as well as the fwknop client and
server applications. The library provides the API and back-end functionality
for managing the Single Packet Authorization (SPA) data that the other fwknop
components employ. It also can be used by other programs that need SPA
functionality (see the `perl' directory for the FKO perl module as an example,
and there are python bindings as well in the 'python' directory).
UPGRADING
=========
If you are upgrading from an older version of fwknop (and this includes the
original perl implementation as well), then you will want to read the
following link to ensure a smooth transition to fwknop-2.5:
http://www.cipherdyne.org/fwknop/docs/fwknop-tutorial.html#backwards-compatibility
BUILDING fwknop
===============
This distribution uses GNU autoconf for setting up the build. Please see
the `INSTALL' file for the general basics on using autoconf.
There are some "configure" options that are specific to fwknop. They are
(extracted from ./configure --help):
--disable-client Do not build the fwknop client component. The
default is to build the client.
--disable-server Do not build the fwknop server component. The
default is to build the server.
--with-gpgme support for gpg encryption using libgpgme
[default=check]
--with-gpgme-prefix=PFX prefix where GPGME is installed (optional)
--with-gpg=/path/to/gpg Specify path to the gpg executable that gpgme will
use [default=check path]
--with-iptables=/path/to/iptables
Specify path to the iptables executable
[default=check path]
--with-ipfw=/path/to/ipfw
Specify path to the ipfw executable [default=check
path]
--with-pf=/path/to/pfctl
Specify path to the pf executable [default=check
path]
--with-ipf=/path/to/ipf Specify path to the ipf executable [default=check
path]
NOTE to those who may be migrating from the Perl version of fwknop
==================================================================
For those of you who are currently using the Perl version and plan to
migrate to this version, there are some things to be aware of:
- Not all of the features and functionality of the Perl-based
fwknop were ported to this implementation. We felt it important
to keep the C version as lean and lightweight as possible. Most
of the omitted feature/functions (like email alerts) can be
accomplished through other means (i.e. use an external script
to monitor log files and alert based on appropriate log messages).
- There are some differences in the fwknop configuration and access
file directives and values. Some of these are fairly subtle. You
should pay careful attention to the documentation and comments in
those files.
NOTE FOR DEVELOPERS
===================
If you are pulling this distribution from git, you should run the
"autogen.sh" script to generate the autoconf files. If you get errors about
missing directories or files, try running "autogen.sh" again. After that
you can run the "autoreconf -i" when you want to regenerate the configuration.
If, for some reason, autoreconf does not work for you, the "autogen.sh"
script should suffice.
The fwknop and fwknopd man page nroff sources are included in their
respective directories (client and server). These nroff files are derived
from the asciidoc sources in the 'docs' directory. See the README in docs
for details.
README 0 → 120000
README.md
\ No newline at end of file
# fwknop - Single Packet Authorization
## Introduction
fwknop implements an authorization scheme known as Single Packet Authorization
(SPA) for strong service concealment. SPA requires only a single packet which
is encrypted, non-replayable, and authenticated via an HMAC in order to
communicate desired access to a service that is hidden behind a firewall in a
default-drop filtering stance. The main application of SPA is to use a firewall
to drop all attempts to connect to services such as SSH in order to make the
exploitation of vulnerabilities (both 0-day and unpatched code) more difficult.
Because there are no open ports, any service that is concealed by SPA naturally
cannot be scanned for with Nmap. The fwknop project supports four different
firewalls: firewalld and iptables on Linux systems, pf on OpenBSD, and ipfw on
FreeBSD and Mac OS X.
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 possible to reliably support, 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 standard cryptographic operations for
SPA packet authentication and encryption/decryption.
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 (enabled via the `--use-hmac` command line switch), it is highly
recommended for three reasons:
1. Without an HMAC, cryptographically strong authentication is not possible
with fwknop unless GnuPG is used, but even then an HMAC should still be
applied.
2. An HMAC applied after encryption protects against cryptanalytic CBC-mode
padding oracle attacks such as the Vaudenay attack and related trickery (like
the more recent "Lucky 13" attack against SSL).
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.
The final reason above is why an HMAC should still be used even when SPA
packets are encrypted with GnuPG due to the fact that SPA data is not sent
through libgpgme functions unless the HMAC checks out first. GnuPG and libgpgme
are relatively complex bodies of code, and therefore limiting the ability of a
potential attacker to interact with this code through an HMAC operation helps
to maintain a stronger security stance. Generating an HMAC for SPA
communications requires a dedicated key in addition to the normal encryption
key, and both can be generated with the `--key-gen` option.
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 `/etc/fwknop/access.conf` file for details). The actual encryption key used
for Rijndael encryption is generated via the standard PBKDF1 key derivation
algorithm, and CBC mode is set. If the GnuPG method is chosen, then the
encryption keys are derived from GnuPG key rings.
A comprehensive tutorial on fwknop can be found here:
[http://www.cipherdyne.org/fwknop/docs/fwknop-tutorial.html](http://www.cipherdyne.org/fwknop/docs/fwknop-tutorial.html)
## License
The fwknop project is released as open source software under the terms of
the **GNU General Public License (GPL v2)**. The latest release can be found
at [http://www.cipherdyne.org/fwknop/](http://www.cipherdyne.org/fwknop/)
## Current State
This README file describes the present state of the fwknop project as of the
2.5 release made in July, 2013. At present, we have an implementation of the
Firewall Knock Operator library; `libfko`, as well as the fwknop client and
server applications. The library provides the API and back-end functionality
for managing the Single Packet Authorization (SPA) data that the other fwknop
components employ. It also can be used by other programs that need SPA
functionality (see the `perl` directory for the FKO perl module as an example,
and there are python bindings as well in the `python` directory).
## Upgrading
If you are upgrading from an older version of fwknop (and this includes the
original perl implementation as well), then you will want to read the
following link to ensure a smooth transition to fwknop-2.5:
[http://www.cipherdyne.org/fwknop/docs/fwknop-tutorial.html#backwards-compatibility](http://www.cipherdyne.org/fwknop/docs/fwknop-tutorial.html#backwards-compatibility)
## Building fwknop
This distribution uses GNU autoconf for setting up the build. Please see
the `INSTALL` file for the general basics on using autoconf.
There are some "configure" options that are specific to fwknop. They are
(extracted from ./configure --help):
--disable-client Do not build the fwknop client component. The
default is to build the client.
--disable-server Do not build the fwknop server component. The
default is to build the server.
--with-gpgme support for gpg encryption using libgpgme
[default=check]
--with-gpgme-prefix=PFX prefix where GPGME is installed (optional)
--with-gpg=/path/to/gpg Specify path to the gpg executable that gpgme will
use [default=check path]
--with-firewalld=/path/to/firewalld
Specify path to the firewalld executable
[default=check path]
--with-iptables=/path/to/iptables
Specify path to the iptables executable
[default=check path]
--with-ipfw=/path/to/ipfw
Specify path to the ipfw executable [default=check
path]
--with-pf=/path/to/pfctl
Specify path to the pf executable [default=check
path]
--with-ipf=/path/to/ipf Specify path to the ipf executable [default=check
path]
Examples:
./configure --disable-client --with-firewalld=/bin/firewall-cmd
./configure --disable-client --with-iptables=/sbin/iptables --with-firewalld=no
## Notes
### Migrating from the Perl version of fwknop
For those of you who are currently using the Perl version and plan to
migrate to this version, there are some things to be aware of:
- Not all of the features and functionality of the Perl-based
fwknop were ported to this implementation. We felt it important
to keep the C version as lean and lightweight as possible. Most
of the omitted feature/functions (like email alerts) can be
accomplished through other means (i.e. use an external script
to monitor log files and alert based on appropriate log messages).
- There are some differences in the fwknop configuration and access
file directives and values. Some of these are fairly subtle. You
should pay careful attention to the documentation and comments in
those files.
## For fwknop developers
If you are pulling this distribution from git, you should run the
`autogen.sh` script to generate the autoconf files. If you get errors about
missing directories or files, try running `autogen.sh` again. After that
you can run the `autoreconf -i` when you want to regenerate the configuration.
If, for some reason, autoreconf does not work for you, the `autogen.sh`
script should suffice.
The fwknop and fwknopd man page nroff sources are included in their
respective directories (client and server). These nroff files are derived
from the asciidoc sources in the 'docs' directory. See the README in docs
for details.
2.6.0
2.6.4
......@@ -25,20 +25,20 @@
android:textSize="20dip"
/>
</LinearLayout>
<LinearLayout android:id="@+id/accessProtol"
<LinearLayout android:id="@+id/tcpAccessPortsl"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
>
<TextView
android:id="@+id/accessProtoStr"
android:id="@+id/tcpAccessPortsStr"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Access Protocol: "
android:text="TCP Access Ports: "
android:textSize="20dip"
/>
<Spinner
android:id="@+id/accessProto"
<EditText
android:id="@+id/tcpAccessPorts"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text=""
......@@ -46,24 +46,23 @@
android:textSize="20dip"
/>
</LinearLayout>
<LinearLayout android:id="@+id/accessPortl"
<LinearLayout android:id="@+id/udpAccessPortsl"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
>
<TextView
android:id="@+id/accessPortStr"
android:id="@+id/udpAccessPortsStr"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Access Port: "
android:text="UDP Access Ports: "
android:textSize="20dip"
/>
<EditText
android:id="@+id/accessPort"
android:id="@+id/udpAccessPorts"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text=""
android:inputType="numberDecimal"
android:singleLine="true"
android:textSize="20dip"
/>
......
......@@ -98,8 +98,8 @@ public class Fwknop extends Activity {
private EditText mPasswd;
private EditText mHmac;
private EditText mDestip;
private Spinner mAccessProto;
private EditText mAccessPort;
private EditText mTCPAccessPorts;
private EditText mUDPAccessPorts;
private EditText mFwTimeout;
private ImageButton mUnlock;
private String access_str;
......@@ -264,28 +264,48 @@ public class Fwknop extends Activity {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
SharedPreferences.Editor edit = prefs.edit();
//
if (this.mAccessProto != null
&& (this.mAccessProto.getSelectedItem().toString().trim().toLowerCase().equals("tcp")
|| this.mAccessProto.getSelectedItem().toString().trim().toLowerCase().equals("udp"))) {
this.access_str = mAccessProto.getSelectedItem().toString().toLowerCase() + "";
edit.putString("accessProto_str", mAccessProto.getSelectedItem().toString());
} else {
this.UIAlert("Input error", "Please enter a valip protocol (tcp/udp)", this);
return;
this.access_str = "";
if (this.mTCPAccessPorts != null) {
if(!this.mTCPAccessPorts.getText().toString().equals("")){
String[] ports = this.mTCPAccessPorts.getText().toString().split(",");
for(int i = 0; i < ports.length; i++){
try {
int port = Integer.parseInt(ports[i]);
if(i > 0)
this.access_str = this.access_str + ",";
this.access_str = this.access_str + "tcp/" + port;
} catch (Exception e) {
this.UIAlert("Input error", ports[i] + " is not a valid port number", this);
return;
}
}
}
edit.putString("tcpAccessPorts_str", mTCPAccessPorts.getText().toString());
}
if (this.mAccessPort != null) {
int port;
try {
Integer.parseInt(this.mAccessPort.getText().toString());
} catch (Exception e) {
this.UIAlert("Input error", "Please enter a valid port number", this);
return;
if (this.mUDPAccessPorts != null) {
if(!this.mUDPAccessPorts.getText().toString().equals("")){
String[] ports = this.mUDPAccessPorts.getText().toString().split(",");
for(int i = 0; i < ports.length; i++){
try {
int port = Integer.parseInt(ports[i]);
if(this.access_str != null && !this.access_str.equals(""))
this.access_str = this.access_str + ",";
this.access_str = this.access_str + "udp/" + port;
} catch (Exception e) {
this.UIAlert("Input error", ports[i] + " is not a valid port number", this);
return;
}
}
}
this.access_str = this.access_str + "/" + mAccessPort.getText();
edit.putString("accessPort_str", mAccessPort.getText().toString());
edit.putString("udpAccessPorts_str", mUDPAccessPorts.getText().toString());
}
if(this.access_str.equals("")){
this.UIAlert("Input error", "Please enter a TCP or UDP port", this);
return;
}
if (this.mAllowip != null && this.mAllowip.getSelectedItem() != null && !this.mAllowip.getSelectedItem().toString().trim().equals("")) {
if(mAllowip.getSelectedItem().toString().trim().equals("Source IP")) {
this.allowip_str = "0.0.0.0";
......@@ -351,20 +371,10 @@ public class Fwknop extends Activity {
public void setupWidgets() {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
this.mAccessPort = (EditText) findViewById(R.id.accessPort);
this.mAccessPort.setText(prefs.getString("accessPort_str", "22"));
this.mAccessProto = (Spinner) findViewById(R.id.accessProto);
String[] arraySpinner = new String[]{"tcp", "udp"};
ArrayAdapter adapter = new ArrayAdapter(this, android.R.layout.simple_spinner_item, arraySpinner);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
this.mAccessProto.setAdapter(adapter);
if (prefs.getString("accessProto_str", "tcp").equals("tcp")) {
this.mAccessProto.setSelection(0);
}
if (prefs.getString("accessProto_str", "tcp").equals("udp")) {
this.mAccessProto.setSelection(1);
}
this.mTCPAccessPorts = (EditText) findViewById(R.id.tcpAccessPorts);
this.mTCPAccessPorts.setText(prefs.getString("tcpAccessPorts_str", "22"));
this.mUDPAccessPorts = (EditText) findViewById(R.id.udpAccessPorts);
this.mUDPAccessPorts.setText(prefs.getString("udpAccessPorts_str", null));
this.mAllowip = (Spinner) findViewById(R.id.allowip);
......@@ -378,9 +388,12 @@ public class Fwknop extends Activity {
this.mCheck.setChecked(prefs.getBoolean("app_start", false));
this.mPasswd = (EditText) findViewById(R.id.passwd);
this.mPasswd.setText(prefs.getString("passwd_str", ""));
this.mOutput = (TextView) findViewById(R.id.output);
this.mHmac = (EditText) findViewById(R.id.hmac);
this.mHmac.setText(prefs.getString("hmac_str", ""));
mUnlock = (ImageButton) findViewById(R.id.unlock);
mUnlock.setOnClickListener(new OnClickListener() {
......
......@@ -47,9 +47,11 @@ enum {
NO_SAVE_ARGS,
SHOW_LAST_ARGS,
RC_FILE_PATH,
RESOLVE_HTTP_ONLY,
RESOLVE_URL,
RAND_MODE_LEGACY,
USE_HMAC,
USE_WGET_USER_AGENT,
SPA_ICMP_TYPE,
SPA_ICMP_CODE,
KEY_LEN,
......@@ -62,6 +64,8 @@ enum {
KEY_HMAC,
FD_SET_STDIN,
FD_SET_ALT,
FAULT_INJECTION_TAG,
/* Put GPG-related items below the following line */
GPG_ENCRYPTION = 0x200,
GPG_RECIP_KEY,
......@@ -76,7 +80,7 @@ enum {
/* Our getopt_long options string.
*/
#define GETOPTS_OPTION_STRING "a:A:bB:C:D:E:f:gG:hH:kK:lm:M:n:N:p:P:Q:rRsS:Tu:U:vV"
#define GETOPTS_OPTION_STRING "a:A:bB:C:D:E:f:gG:hH:kK:lm:M:n:N:p:P:Q:rRsS:Tu:U:vVw:"
/* Our program command-line options...
*/
......@@ -97,6 +101,7 @@ static struct option cmd_opts[] =
{"encryption-mode", 1, NULL, ENCRYPTION_MODE},
{"fd", 1, NULL, FD_SET_ALT},
{"fw-timeout", 1, NULL, 'f'},
{"fault-injection-tag", 1, NULL, FAULT_INJECTION_TAG },
{"gpg-encryption", 0, NULL, 'g'},
{"gpg-recipient-key", 1, NULL, GPG_RECIP_KEY },
{"gpg-signer-key", 1, NULL, GPG_SIGNER_KEY },
......@@ -133,6 +138,8 @@ static struct option cmd_opts[] =
{"rand-port", 0, NULL, 'r'},
{"rand-mode-legacy", 0, NULL, RAND_MODE_LEGACY},
{"resolve-ip-http", 0, NULL, 'R'},
{"resolve-ip-https", 0, NULL, 'R'}, /* synonym, default is HTTPS */
{"resolve-http-only", 0, NULL, RESOLVE_HTTP_ONLY},
{"resolve-url", 1, NULL, RESOLVE_URL},
{"show-last", 0, NULL, SHOW_LAST_ARGS},
{"source-ip", 0, NULL, 's'},
......@@ -143,9 +150,11 @@ static struct option cmd_opts[] =
{"time-offset-minus", 1, NULL, TIME_OFFSET_MINUS},
{"user-agent", 1, NULL, 'u'},
{"use-hmac", 0, NULL, USE_HMAC},
{"use-wget-user-agent", 0, NULL, USE_WGET_USER_AGENT},
{"spoof-user", 1, NULL, 'U'},
{"verbose", 0, NULL, 'v'},
{"version", 0, NULL, 'V'},
{"wget-cmd", 1, NULL, 'w'},
{0, 0, 0, 0}
};
......
此差异已折叠。
......@@ -2,12 +2,12 @@
.\" Title: fwknop
.\" Author: [see the "AUTHORS" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
.\" Date: 01/02/2014
.\" Date: 11/15/2014
.\" Manual: Fwknop Client
.\" Source: Fwknop Client
.\" Language: English
.\"
.TH "FWKNOP" "8" "01/02/2014" "Fwknop Client" "Fwknop Client"
.TH "FWKNOP" "8" "11/15/2014" "Fwknop Client" "Fwknop Client"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
......@@ -101,7 +101,7 @@ daemon/service when it decrypts and parses the authentication packet\&.
.RS 4
One of these options (see below) is required to tell the remote
\fBfwknopd\fR
daemon what IP should be allowed through the local firewall\&. It is recommend to use the
daemon what IP should be allowed through the firewall\&. It is recommend to use the
\fB\-R\fR
or
\fB\-a\fR
......@@ -117,8 +117,8 @@ file\&. Note that the most secure option is
\fB\-a\fR
so that
\fBfwknop\fR
does not have to issue an HTTP request to
\fIhttp://www\&.cipherdyne\&.org/cgi\-bin/myip\fR
does not have to issue any HTTPS request to
\fIhttps://www\&.cipherdyne\&.org/cgi\-bin/myip\fR
in order to resolve the externally routable IP address\&. Using
\fB\-a\fR
requires that the user already knows what the external IP is for the network where fwknop is running\&.
......@@ -299,6 +299,14 @@ Append the generated packet data to the file specified with the
option\&.
.RE
.PP
\fB\-\-fault\-injection\-tag\fR=\fI<tag>\fR
.RS 4
This option is only used for fault injection testing when
\fBfwknop\fR
is compiled to support the libfiu library (see:
\fIhttp://blitiri\&.com\&.ar/p/libfiu/\fR)\&. Under normal circumstances this option is not used, and any packaged version of fwknop will not have code compiled in so this capability is not enabled at run time\&. It is documented here for completeness\&.
.RE
.PP
\fB\-v, \-\-verbose\fR
.RS 4
Run the
......@@ -337,7 +345,8 @@ option\&. Another related option is
\fB\-R\fR
(see below) which instructs the
\fBfwknop\fR
client to automatically resolve the externally routable IP address the local system is connected to by querying a website that returns the actual IP address it sees from the calling system\&.
client to automatically resolve the externally routable IP address the local system is connected to by querying
\fIhttps://www\&.cipherdyne\&.org/cgi\-bin/myip\fR\&. This returns the actual IP address it sees from the calling system\&.
.RE
.PP
\fB\-g, \-\-gpg\-encryption\fR
......@@ -478,23 +487,28 @@ variable that is configured to accept such packets\&. For example, the
variable could be set to: \(lq+udp dst portrange 10000\-65535+\(rq\&.
.RE
.PP
\fB\-R, \-\-resolve\-ip\-http\fR
\fB\-R, \-\-resolve\-ip\-https\fR
.RS 4
This is an important option, and instructs the
\fBfwknop\fR
client and the
client to issue an HTTPS request to a script running on
\fIcipherdyne\&.org\fR
that returns the client\(cqs IP address (as seen by the web server)\&. In some cases, this is needed to determine the IP address that should be allowed through the firewall policy at the remote
\fBfwknopd\fR
daemon/service to query a web server that returns the caller\(cqs IP address (as seen by the web server)\&. In some cases, this is needed to determine the IP address that should be allowed through the iptables policy at the remote fwknopd server side\&. This is useful if the
server side\&. This option is useful if the
\fBfwknop\fR
client is being used on a system that is behind an obscure NAT address\&. Presently,
client is being used on a system that is behind an obscure NAT address, and the external Internet facing IP is not known to the user\&. The full resolution URL is:
\fIhttps://www\&.cipherdyne\&.org/cgi\-bin/myip\fR, and is accessed by
\fBfwknop\fR
uses the URL:
\fIhttp://www\&.cipherdyne\&.org/cgi\-bin/myip\fR
to resolve the caller IP\&. Note that it is generally more secure to use the
via
\fIwget\fR
in
\fB\-\-secure\-protocol\fR
mode\&. Note that it is generally more secure to use the
\fB\-a\fR
option if the externally routable IP address for the client is already known to the user since this elminates the need for
\fBfwknop\fR
to issue an HTTP request\&.
to issue any sort of HTTPS request\&.
.RE
.PP
\fB\-\-resolve\-url\fR \fI<url>\fR
......@@ -502,6 +516,29 @@ to issue an HTTP request\&.
Override the default URL used for resolving the source IP address\&. For best results, the URL specified here should point to a web service that provides just an IP address in the body of the HTTP response\&.
.RE
.PP
\fB\-\-resolve\-http\-only\fR
.RS 4
This option forces the
\fBfwknop\fR
client to resolve the external IP via HTTP instead of HTTPS\&. There are some circumstances where this might be necessary such as when
\fIwget\fR
is not available (or hasn\(cqt been compiled with SSL support), but generally this is not recommeded since it opens the possibility of a MITM attack through manipulation of the IP resolution HTTP response\&. Either specify the IP manually with
\fB\-a\fR, or use
\fB\-R\fR
and omit this option\&.
.RE
.PP
\fB\-w, \-\-wget\-cmd\fR=\fI<wget full path>\fR
.RS 4
Manually set the full path to the
\fIwget\fR
command\&. Normally the
\fIconfigure\fR
script finds the
\fIwget\fR
command, but this option can be used to specify the path if it is located in a non\-standard place\&.
.RE
.PP
\fB\-s, \-\-source\-ip\fR
.RS 4
Instruct the
......@@ -600,6 +637,22 @@ Set the HTTP User\-Agent for resolving the external IP via
\fB\-R\fR, or for sending SPA packets over HTTP\&.
.RE
.PP
\fB\-\-use\-wget\-user\-agent\fR
.RS 4
By default when the
\fBfwknop\fR
client resolves the external IP with
\fBwget\fR
via SSL, it sets the User\-Agent to \(lqFwknop/<version>\(rq unless it was already manually specified with the
\fB\-\-user\-agent\fR
option mentioned above\&. However, the
\fB\-\-user\-wget\-user\-agent\fR
option lets the default
\fBwget\fR
User\-Agent string apply without influence from
\fBfwknop\fR\&.
.RE
.PP
\fB\-U, \-\-spoof\-user\fR=\fI<user>\fR
.RS 4
Specify the username that is included within SPA packet\&. This allows the
......@@ -785,9 +838,44 @@ Set the source port to use for sending the SPA packet (\fI\-S, \-\-source\-port\
Set the firewall rule timeout value (\fI\-f, \-\-fw\-timeout\fR)\&.
.RE
.PP
\fBRESOLVE_IP_HTTPS\fR \fI<Y/N>\fR
.RS 4
Set to
\fIY\fR
to automatically resolve the externally routable IP associated with the
\fBfwknop\fR
client\&. This is done over SSL via
\fIwget\fR
in
\fI\-\-secure\-protocol\fR
mode against the IP resolution service available at
\fIhttps://www\&.cipherdyne\&.org/cgi\-bin/myip\fR\&.
.RE
.PP
\fBRESOLVE_HTTP_ONLY\fR \fI<Y/N>\fR
.RS 4
When the
\fBfwknop\fR
client is instructed to resolve the external client IP, this option can be used to force an
\fIHTTP\fR
connection instead of an
\fIHTTPS\fR
connection when set to
\fIY\fR\&. This option is useful when
\fIwget\fR
is not installed on the local OS, or when it is not compiled against an SSL library\&.
.RE
.PP
\fBRESOLVE_URL\fR \fI<url>\fR
.RS 4
Set to a URL that will be used for resolving the source IP address (\-\-resolve\-url)\&.
Set to a URL that will be used for resolving the source IP address (\fI\-\-resolve\-url\fR)\&.
.RE
.PP
\fBWGET_CMD\fR \fI<wget full path>\fR
.RS 4
Set the full path to the
\fIwget\fR
command (used for client IP resolution)\&.
.RE
.PP
\fBTIME_OFFSET\fR \fI<time>\fR
......@@ -863,6 +951,12 @@ Specify the GPG home directory (\fI\-\-gpg\-home\-dir\fR)\&. Defaults to
\fI~/\&.gnupg\fR\&.
.RE
.PP
\fBGPG_EXE\fR \fI<path>\fR
.RS 4
Specify the path to GPG (\fI\-\-gpg\-exe\fR)\&. Defaults to
\fI/usr/bin/gpg\fR\&.
.RE
.PP
\fBSPOOF_USER\fR \fI<user>\fR
.RS 4
Set the username in the SPA data to the specified value (\fI\-U, \-\-spoof\-user\fR)\&.
......@@ -888,6 +982,15 @@ Load an encryption key/password from a file (\fI\-G, \-\-get\-key\fR)\&.
Set the HTTP User\-Agent for resolving the external IP via \-R, or for sending SPA packets over HTTP (\fI\-u, \-\-user\-agent\fR)\&.
.RE
.PP
\fBUSE_WGET_USER_AGENT\fR \fI<Y/N>\fR
.RS 4
Allow default
\fBwget\fR
User\-Agent string to be used when resolving the external IP instead of a User\-Agent supplied by the
\fBfwknop\fR
client\&.
.RE
.PP
\fBNAT_ACCESS\fR \fI<internalIP:forwardPort>\fR
.RS 4
Gain NAT access to an internal service protected by the fwknop server (\fI\-N, \-\-nat\-access\fR)\&.
......@@ -947,7 +1050,7 @@ With the access request arguments and encryption and HMAC keys generated and sav
HMAC_KEY_BASE64 DLeLf93a3yBT2vhEpM+dWlirGta5GU+jdyG5uXp4461HgOtbqMem4gX0Bp2PJGzYZlbbcavcOM00UPm+0GqkXA==
USE_HMAC Y
VERBOSE Y
RESOLVE_IP_HTTP Y
RESOLVE_IP_HTTPS Y
.fi
.if n \{\
.RE
......@@ -1043,7 +1146,7 @@ Simultaneous access to multiple services is also supported, and here is an examp
.RE
.\}
.sp
There are many cases where an \fBfwknop\fR 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 \fIhttp://www\&.cipherdyne\&.org/cgi\-bin/myip\fR via the \fB\-R\fR 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 \fB\-s\fR option mentioned earlier in this manual page because the source IP is put within the encrypted packet instead of having the \fBfwknopd\fR daemon grant the requested access from whatever IP address the SPA packet originates (i\&.e\&. using \fB\-s\fR opens the possibility of a MITM attack):
There are many cases where an \fBfwknop\fR 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 \fIhttps://www\&.cipherdyne\&.org/cgi\-bin/myip\fR via the \fB\-R\fR 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 \fB\-s\fR option mentioned earlier in this manual page because the source IP is put within the encrypted packet instead of having the \fBfwknopd\fR daemon grant the requested access from whatever IP address the SPA packet originates (i\&.e\&. using \fB\-s\fR opens the possibility of a MITM attack):
.sp
.if n \{\
.RS 4
......@@ -1128,7 +1231,7 @@ For GPG functionality, GnuPG must also be correctly installed and configured alo
To take advantage of all of the authentication and access management features of the \fBfwknopd\fR daemon/service a functioning \fIiptables\fR, \fIipfw\fR, or \fIpf\fR firewall is required on the underlying operating system\&.
.SH "DIAGNOSTICS"
.sp
The most comprehensive way to gain diagnostic information on \fBfwknop\fR is to run the test suite \fItest\-fwknop\&.pl\fR script located in the \fItest/\fR directory in the fwknop sources\&. The test suite sends fwknop through a large number of run time tests, has \fIvalgrind\fR 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, \fBfwknop\fR can be executed with the \fB\-T\fR (or \fB\-\-test\fR) command line option\&. This will have \fBfwknop\fR simply create and print the SPA packet information, then run it through a decrypt/decode cycle and print it again\&. In addition, the \fB\-\-verbose\fR command line switch is useful to see various SPA packet specifics printed to stdout\&.
The most comprehensive way to gain diagnostic information on \fBfwknop\fR is to run the test suite \fItest\-fwknop\&.pl\fR script located in the \fItest/\fR directory in the fwknop sources\&. The test suite sends fwknop through a large number of run time tests, has \fIvalgrind\fR support, validates both SPA encryption and HMAC results against OpenSSL, and even has its own built in fuzzer for SPA communications (and fwknop in version 2\&.6\&.4 supports the \fIAmerican Fuzzy Lop\fR (AFL) from Michal Zalewski as well)\&. For more basic diagnostic information, \fBfwknop\fR can be executed with the \fB\-T\fR (or \fB\-\-test\fR) command line option\&. This will have \fBfwknop\fR simply create and print the SPA packet information, then run it through a decrypt/decode cycle and print it again\&. In addition, the \fB\-\-verbose\fR command line switch is useful to see various SPA packet specifics printed to stdout\&.
.SH "SEE ALSO"
.sp
fwknopd(8), iptables(8), pf(4), pfctl(8), ipfw(8), gpg(1), libfko documentation\&.
......
......@@ -52,6 +52,7 @@ static int set_nat_access(fko_ctx_t ctx, fko_cli_options_t *options,
static int set_access_buf(fko_ctx_t ctx, fko_cli_options_t *options,
char *access_buf);
static int get_rand_port(void);
int resolve_ip_https(fko_cli_options_t *options);
int resolve_ip_http(fko_cli_options_t *options);
static void clean_exit(fko_ctx_t ctx, fko_cli_options_t *opts,
char *key, int *key_len, char *hmac_key, int *hmac_key_len,
......@@ -59,8 +60,10 @@ static void clean_exit(fko_ctx_t ctx, fko_cli_options_t *opts,
static void zero_buf_wrapper(char *buf, int len);
static int is_hostname_str_with_port(const char *str,
char *hostname, size_t hostname_bufsize, int *port);
#if HAVE_LIBFIU
static void enable_fault_injections(fko_cli_options_t * const opts);
#endif
#define MAX_CMDLINE_ARGS 50 /*!< should be way more than enough */
#define NAT_ACCESS_STR_TEMPLATE "%s,%d" /*!< Template for a nat access string ip,port with sscanf*/
#define HOSTNAME_BUFSIZE 64 /*!< Maximum size of a hostname string */
#define CTX_DUMP_BUFSIZE 4096 /*!< Maximum size allocated to a FKO context dump */
......@@ -167,6 +170,12 @@ main(int argc, char **argv)
*/
config_init(&options, argc, argv);
#if HAVE_LIBFIU
/* Set any fault injection points early
*/
enable_fault_injections(&options);
#endif
/* Handle previous execution arguments if required
*/
if(prev_exec(&options, argc, argv) != 1)
......@@ -259,12 +268,24 @@ main(int argc, char **argv)
/* Resolve the client's public facing IP address if requestesd.
* if this fails, consider it fatal.
*/
if (options.resolve_ip_http)
if (options.resolve_ip_http_https)
{
if(resolve_ip_http(&options) < 0)
if(options.resolve_http_only)
{
clean_exit(ctx, &options, key, &key_len,
hmac_key, &hmac_key_len, EXIT_FAILURE);
if(resolve_ip_http(&options) < 0)
{
clean_exit(ctx, &options, key, &key_len,
hmac_key, &hmac_key_len, EXIT_FAILURE);
}
}
else
{
/* Default to HTTPS */
if(resolve_ip_https(&options) < 0)
{
clean_exit(ctx, &options, key, &key_len,
hmac_key, &hmac_key_len, EXIT_FAILURE);
}
}
}
......@@ -549,10 +570,10 @@ main(int argc, char **argv)
if(res != FKO_SUCCESS)
{
errmsg("fko_get_spa_encryption_mode", res);
if(fko_destroy(ctx2) == FKO_ERROR_ZERO_OUT_DATA)
if(fko_destroy(ctx) == FKO_ERROR_ZERO_OUT_DATA)
log_msg(LOG_VERBOSITY_ERROR,
"[*] Could not zero out sensitive data buffer.");
ctx2 = NULL;
ctx = NULL;
clean_exit(ctx, &options, key, &orig_key_len,
hmac_key, &hmac_key_len, EXIT_FAILURE);
}
......@@ -644,7 +665,10 @@ main(int argc, char **argv)
* expected, return 0 instead of an error condition (so calling
* programs like the fwknop test suite don't interpret this as
* an unrecoverable error), but print the error string for
debugging purposes. */
* debugging purposes. The test suite does run a series of
* tests that use a single key pair for encryption and
* authentication, so decryption become possible for these
* tests. */
log_msg(LOG_VERBOSITY_ERROR, "GPG ERR: %s\n%s", fko_gpg_errstr(ctx2),
"No access to recipient private key?");
}
......@@ -679,6 +703,8 @@ free_configs(fko_cli_options_t *opts)
{
if (opts->resolve_url != NULL)
free(opts->resolve_url);
if (opts->wget_bin != NULL)
free(opts->wget_bin);
zero_buf_wrapper(opts->key, MAX_KEY_LEN+1);
zero_buf_wrapper(opts->key_base64, MAX_B64_KEY_LEN+1);
zero_buf_wrapper(opts->hmac_key, MAX_KEY_LEN+1);
......@@ -961,9 +987,13 @@ show_last_command(const char * const args_save_file)
}
if ((fgets(args_str, MAX_LINE_LEN, args_file_ptr)) != NULL) {
log_msg(LOG_VERBOSITY_NORMAL, "Last fwknop client command line: %s", args_str);
log_msg(LOG_VERBOSITY_NORMAL,
"Last fwknop client command line: %s", args_str);
} else {
log_msg(LOG_VERBOSITY_NORMAL, "Could not read line from file: %s", args_save_file);
log_msg(LOG_VERBOSITY_NORMAL,
"Could not read line from file: %s", args_save_file);
fclose(args_file_ptr);
return 0;
}
fclose(args_file_ptr);
......@@ -976,15 +1006,12 @@ static int
run_last_args(fko_cli_options_t *options, const char * const args_save_file)
{
FILE *args_file_ptr = NULL;
int current_arg_ctr = 0;
int argc_new = 0;
int i = 0;
int argc_new = 0, args_broken = 0;
char args_str[MAX_LINE_LEN] = {0};
char arg_tmp[MAX_LINE_LEN] = {0};
char *argv_new[MAX_CMDLINE_ARGS]; /* should be way more than enough */
memset(argv_new, 0x0, sizeof(argv_new));
if(verify_file_perms_ownership(args_save_file) != 1)
return 0;
......@@ -999,37 +1026,16 @@ run_last_args(fko_cli_options_t *options, const char * const args_save_file)
args_str[MAX_LINE_LEN-1] = '\0';
if (options->verbose)
log_msg(LOG_VERBOSITY_NORMAL, "Executing: %s", args_str);
for (i=0; i < (int)strlen(args_str); i++)
if(strtoargv(args_str, argv_new, &argc_new, options) != 1)
{
if (!isspace(args_str[i]))
{
arg_tmp[current_arg_ctr] = args_str[i];
current_arg_ctr++;
}
else
{
arg_tmp[current_arg_ctr] = '\0';
argv_new[argc_new] = calloc(1, strlen(arg_tmp)+1);
if (argv_new[argc_new] == NULL)
{
log_msg(LOG_VERBOSITY_ERROR, "[*] calloc failure for cmd line arg.");
fclose(args_file_ptr);
return 0;
}
strlcpy(argv_new[argc_new], arg_tmp, strlen(arg_tmp)+1);
current_arg_ctr = 0;
argc_new++;
if(argc_new >= MAX_CMDLINE_ARGS)
{
log_msg(LOG_VERBOSITY_ERROR, "[*] max command line args exceeded.");
fclose(args_file_ptr);
return 0;
}
}
args_broken = 1;
}
}
fclose(args_file_ptr);
if(args_broken)
return 0;
/* Reset the options index so we can run through them again.
*/
optind = 0;
......@@ -1038,13 +1044,7 @@ run_last_args(fko_cli_options_t *options, const char * const args_save_file)
/* Since we passed in our own copies, free up malloc'd memory
*/
for (i=0; i < argc_new; i++)
{
if(argv_new[i] == NULL)
break;
else
free(argv_new[i]);
}
free_argv(argv_new, &argc_new);
return 1;
}
......@@ -1321,6 +1321,19 @@ zero_buf_wrapper(char *buf, int len)
return;
}
#if HAVE_LIBFIU
static void
enable_fault_injections(fko_cli_options_t * const opts)
{
if(opts->fault_injection_tag[0] != 0x0)
{
fiu_init(0);
fiu_enable(opts->fault_injection_tag, 1, NULL, 0);
}
return;
}
#endif
/* free up memory and exit
*/
static void
......@@ -1328,6 +1341,11 @@ clean_exit(fko_ctx_t ctx, fko_cli_options_t *opts,
char *key, int *key_len, char *hmac_key, int *hmac_key_len,
unsigned int exit_status)
{
#if HAVE_LIBFIU
if(opts->fault_injection_tag[0] != 0x0)
fiu_disable(opts->fault_injection_tag);
#endif
if(fko_destroy(ctx) == FKO_ERROR_ZERO_OUT_DATA)
log_msg(LOG_VERBOSITY_ERROR,
"[*] Could not zero out sensitive data buffer.");
......
......@@ -55,17 +55,14 @@
#define TIME_OFFSET_HOURS 3600
#define TIME_OFFSET_DAYS 86400
/* For resolving the allow IP via HTTP and sending SPA packets over
* HTTP - http://www.whatismyip.com/automation/n09230945.asp
#define HTTP_RESOLVE_HOST "www.whatismyip.com"
#define HTTP_RESOLVE_URL "/automation/n09230945.asp"
* --DSS Note: The whatismyip.com site has some usage restrictions.
* so we will make the default run on cipherdyne website
* for now.
/* For resolving allow IP - the default is to do this via HTTPS with
* wget to https://www.cipherdyne.org/cgi-bin/myip, and if the user
* permit it, to fall back to the same URL but via HTTP.
*/
#define HTTP_RESOLVE_HOST "www.cipherdyne.org"
#define HTTP_BACKUP_RESOLVE_HOST "www.cipherdyne.com"
#define HTTP_RESOLVE_URL "/cgi-bin/myip"
#define WGET_RESOLVE_URL_SSL "https://" HTTP_RESOLVE_HOST HTTP_RESOLVE_URL
#define HTTP_MAX_REQUEST_LEN 2000
#define HTTP_MAX_RESPONSE_LEN 2000
#define HTTP_MAX_USER_AGENT_LEN 100
......@@ -103,6 +100,9 @@ typedef struct fko_cli_options
char gpg_signer_key[MAX_GPG_KEY_ID];
char gpg_home_dir[MAX_PATH_LEN];
char gpg_exe[MAX_PATH_LEN];
#if HAVE_LIBFIU
char fault_injection_tag[MAX_FAULT_TAG_LEN];
#endif
/* Encryption keys read from a .fwknoprc stanza
*/
......@@ -127,9 +127,12 @@ typedef struct fko_cli_options
/* External IP resolution via HTTP
*/
int resolve_ip_http;
int resolve_ip_http_https;
int resolve_http_only;
char *resolve_url;
char http_user_agent[HTTP_MAX_USER_AGENT_LEN];
unsigned char use_wget_user_agent;
char *wget_bin;
/* HTTP proxy support
*/
......
此差异已折叠。
......@@ -56,11 +56,11 @@ log_new(void)
*
* This function is not used at the moment since the module does not open file
* which would require to be closed;
*/
void
log_free(void)
{
}
*/
/**
* Set the verbosity level for the current context of the log module.
......
......@@ -86,8 +86,8 @@ static int
send_spa_packet_tcp_or_udp(const char *spa_data, const int sd_len,
const fko_cli_options_t *options)
{
int sock, res=0, error;
struct addrinfo *result, *rp, hints;
int sock=-1, sock_success=0, res=0, error;
struct addrinfo *result=NULL, *rp, hints;
char port_str[MAX_PORT_STR_LEN+1] = {0};
if (options->test)
......@@ -134,24 +134,29 @@ send_spa_packet_tcp_or_udp(const char *spa_data, const int sd_len,
continue;
if ((error = (connect(sock, rp->ai_addr, rp->ai_addrlen) != -1)))
{
sock_success = 1;
break; /* made it */
}
else /* close the open socket if there was a connect error */
{
#ifdef WIN32
closesocket(sock);
closesocket(sock);
#else
close(sock);
close(sock);
#endif
}
}
if(result != NULL)
freeaddrinfo(result);
if (rp == NULL) {
if (! sock_success) {
log_msg(LOG_VERBOSITY_ERROR,
"send_spa_packet_tcp_or_udp: Could not create socket: ",
strerror(errno));
return -1;
}
freeaddrinfo(result);
res = send(sock, spa_data, sd_len, 0);
if(res < 0)
......@@ -597,7 +602,7 @@ send_spa_packet(fko_ctx_t ctx, fko_cli_options_t *options)
char *spa_data;
struct sockaddr_in saddr, daddr;
char ip_str[INET_ADDRSTRLEN] = {0}; /* String used to contain the ip addres of an hostname */
struct addrinfo hints; /* Structure used to set hints to reslove hostname */
struct addrinfo hints; /* Structure used to set hints to resolve hostname */
#ifdef WIN32
WSADATA wsa_data;
#endif
......@@ -675,7 +680,7 @@ send_spa_packet(fko_ctx_t ctx, fko_cli_options_t *options)
*/
daddr.sin_port = htons(options->spa_dst_port);
/* Set destination address. We use the default protocol to reslove
/* Set destination address. We use the default protocol to resolve
* the ip address */
hints.ai_family = AF_INET;
......
此差异已折叠。
支持 Markdown
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册