Initial update for NETFILTER_QUEUE support. These changes are not tested at all as they were edit on a Mac, but are linux-specific.

This commit is contained in:
Damien Stuart
2015-11-28 15:03:39 -05:00
parent 50a5f76080
commit d2cef1746c
10 changed files with 360 additions and 4 deletions
+24 -1
View File
@@ -239,6 +239,16 @@ AC_ARG_ENABLE([udp-server],
[])
AM_CONDITIONAL([UDP_SERVER], [test "$want_udp_server" = yes])
dnl Decide whether or not to enable UDP server mode (no libpcap dependency)
dnl
want_nfq_capture=no
AC_ARG_ENABLE([nfq-server],
[AS_HELP_STRING([--enable-nfq-server],
[Enable NF_QUEUE server mode for no libpcap dependency @<:@default is to disable@:>@])],
[want_nfq_capture=$enableval],
[])
AM_CONDITIONAL([NFQ_CAPTURE], [test "$want_nfq_capture" = yes])
dnl Decide whether or not to enable all warnings with -Wall
dnl
use_wall=yes
@@ -517,7 +527,7 @@ dnl Check for libpcap, gdbm (or ndbm) if we are building the server component
dnl
AS_IF([test "$want_server" = yes], [
AS_IF([test "$want_udp_server" = no], [
AS_IF([test "$want_udp_server" = no -a "$want_nfq_capture" = no], [
# Looking for libpcap
#
AC_CHECK_LIB([pcap],[pcap_open_live],
@@ -526,6 +536,15 @@ AS_IF([test "$want_server" = yes], [
)
])
AS_IF([test "$want_nfq_capture" = yes], [
# Check for libnetfilter_queue
#
AC_CHECK_LIB([netfilter_queue],[nfq_open],
[ AC_DEFINE([USE_LIBNETFILTER_QUEUE], [1], [Define if you have libnetfilter_queue]) ],
[ AC_MSG_ERROR([fwknopd needs libnetfilter_queue])]
)
])
AS_IF([test "$want_digest_cache" = yes], [
use_ndbm=no
have_digest_cache=yes
@@ -785,6 +804,10 @@ if [test "$want_server" = "yes" ]; then
"
if [test "$want_udp_server" = "yes" ]; then
echo " UDP server mode enabled, no libpcap dependency
"
fi
if [test "$want_nfq_capture" = "yes" ]; then
echo " Netfilter Queue server mode enabled, no libpcap dependency
"
fi
+13
View File
@@ -16,6 +16,10 @@ BASE_SOURCE_FILES = fwknopd.h config_init.c config_init.h \
fwknopd_SOURCES = fwknopd.c $(BASE_SOURCE_FILES)
if NFQ_CAPTURE
fwknopd_SOURCES += nfq_capture.c nfq_capture.h
endif
fwknopd_LDADD = $(top_builddir)/lib/libfko.la $(top_builddir)/common/libfko_util.a
if WANT_C_UNIT_TESTS
@@ -25,15 +29,24 @@ if WANT_C_UNIT_TESTS
fwknopd_utests_LDADD = $(top_builddir)/lib/libfko.la $(top_builddir)/common/libfko_util.a
fwknopd_utests_LDFLAGS = -lcunit $(GPGME_LIBS)
if NFQ_CAPTURE
fwknop_utests_LDFLAGS += -lnetfilter_queue
else
if !UDP_SERVER
fwknopd_utests_LDFLAGS += -lpcap
endif
endif
endif
if NFQ_CAPTURE
fwknop_LDADD += -lnetfilter_queue
else
if !UDP_SERVER
fwknopd_LDADD += -lpcap
endif
endif
if !CONFIG_FILE_CACHE
if USE_NDBM
+8 -1
View File
@@ -166,7 +166,11 @@ enum {
/* Our getopt_long options string.
*/
#define GETOPTS_OPTION_STRING "Aa:c:C:d:Dfhi:Kl:O:p:P:Rr:StUvV"
#if USE_LIBNETFILTER_QUEUE
#define GETOPTS_OPTION_STRING "Aa:c:C:d:Dfhi:Kl:nO:p:P:Rr:StUvV"
#else
#define GETOPTS_OPTION_STRING "Aa:c:C:d:Dfhi:Kl:O:p:P:Rr:StUvV"
#endif
/* Our program command-line options...
*/
@@ -200,6 +204,9 @@ static struct option cmd_opts[] =
{"no-firewd-check-support", 0, NULL, FIREWD_DISABLE_CHECK_SUPPORT },
{"no-ipt-check-support", 0, NULL, IPT_DISABLE_CHECK_SUPPORT },
{"locale", 1, NULL, 'l' },
#if USE_LIBNETFILTER_QUEUE
{"nfq-capture", 0, NULL, 'n' },
#endif
{"rotate-digest-cache", 0, NULL, ROTATE_DIGEST_CACHE },
{"override-config", 1, NULL, 'O' },
{"pcap-file", 1, NULL, PCAP_FILE },
+5
View File
@@ -1295,6 +1295,11 @@ config_init(fko_srv_options_t *opts, int argc, char **argv)
case 'l':
set_config_entry(opts, CONF_LOCALE, optarg);
break;
#if USE_LIBNETFILTER_QUEUE
case 'n':
opts->enable_nfq_capture = 1;
break;
#endif
case 'O':
/* This was handled earlier */
break;
+135
View File
@@ -702,6 +702,68 @@ delete_all_chains(const fko_srv_options_t * const opts)
log_msg(LOG_ERR, "delete_all_chains() Error %i from cmd:'%s': %s",
res, cmd_buf, err_buf);
#if USE_LIBNETFILTER_QUEUE
if(opts->enable_nfq_capture)
{
zero_cmd_buffers();
/* Delete the rule to direct traffic to the NFQ chain.
*/
snprintf(cmd_buf, CMD_BUFSIZE-1, "%s " IPT_DEL_RULE_ARGS,
fwc.fw_command,
NFQ_TABLE,
"INPUT",
1
);
res = run_extcmd(cmd_buf, err_buf, CMD_BUFSIZE, 0);
if (opts->verbose)
log_msg(LOG_INFO, "delete_all_chains() CMD: '%s' (res: %d, err: %s)",
cmd_buf, res, err_buf);
/* Expect full success on this */
if(! EXTCMD_IS_SUCCESS(res))
log_msg(LOG_ERR, "Error %i from cmd:'%s': %s", res, cmd_buf, err_buf);
zero_cmd_buffers();
/* Flush the NFQ chain
*/
snprintf(cmd_buf, CMD_BUFSIZE-1, "%s " IPT_FLUSH_CHAIN_ARGS,
fwc.fw_command,
NFQ_TABLE,
NFQ_CHAIN
);
res = run_extcmd(cmd_buf, err_buf, CMD_BUFSIZE, 0);
if (opts->verbose)
log_msg(LOG_INFO, "delete_all_chains() CMD: '%s' (res: %d, err: %s)",
cmd_buf, res, err_buf);
/* Expect full success on this */
if(! EXTCMD_IS_SUCCESS(res))
log_msg(LOG_ERR, "Error %i from cmd:'%s': %s", res, cmd_buf, err_buf);
zero_cmd_buffers();
/* Create the NF_QUEUE chains and rules
*/
snprintf(cmd_buf, CMD_BUFSIZE-1, "%s " IPT_DEL_CHAIN_ARGS,
fwc.fw_command,
NFQ_TABLE,
NFQ_CHAIN
);
res = run_extcmd(cmd_buf, err_buf, CMD_BUFSIZE, 0);
if (opts->verbose)
log_msg(LOG_INFO, "delete_all_chains() CMD: '%s' (res: %d, err: %s)",
cmd_buf, res, err_buf);
/* Expect full success on this */
if(! EXTCMD_IS_SUCCESS(res))
log_msg(LOG_ERR, "Error %i from cmd:'%s': %s", res, cmd_buf, err_buf);
}
#endif
}
return;
}
@@ -770,7 +832,80 @@ create_fw_chains(const fko_srv_options_t * const opts)
got_err += mk_chain(opts, i);
}
#if USE_LIBNETFILTER_QUEUE
if(opts->enable_nfq_capture)
{
zero_cmd_buffers();
/* Create the NF_QUEUE chains and rules
*/
snprintf(cmd_buf, CMD_BUFSIZE-1, "%s " IPT_NEW_CHAIN_ARGS,
fwc.fw_command,
NFQ_TABLE,
NFQ_CHAIN
);
res = run_extcmd(cmd_buf, err_buf, CMD_BUFSIZE, 0);
if (opts->verbose)
log_msg(LOG_INFO, "create_fw_chains() CMD: '%s' (res: %d, err: %s)",
cmd_buf, res, err_buf);
/* Expect full success on this */
if(! EXTCMD_IS_SUCCESS(res))
{
log_msg(LOG_ERR, "Error %i from cmd:'%s': %s", res, cmd_buf, err_buf);
got_err++;
}
zero_cmd_buffers();
/* Create the rule to direct traffic to the NFQ chain.
*/
snprintf(cmd_buf, CMD_BUFSIZE-1, "%s " IPT_ADD_JUMP_RULE_ARGS,
fwc.fw_command,
NFQ_TABLE,
"INPUT",
1,
NFQ_CHAIN
);
res = run_extcmd(cmd_buf, err_buf, CMD_BUFSIZE, 0);
if (opts->verbose)
log_msg(LOG_INFO, "create_fw_chains() CMD: '%s' (res: %d, err: %s)",
cmd_buf, res, err_buf);
/* Expect full success on this */
if(! EXTCMD_IS_SUCCESS(res))
{
log_msg(LOG_ERR, "Error %i from cmd:'%s': %s", res, cmd_buf, err_buf);
got_err++;
}
zero_cmd_buffers();
/* Create the rule to direct SPA packets to the queue.
*/
snprintf(cmd_buf, CMD_BUFSIZE-1, "%s " FIREWD_NFQ_ADD_ARGS,
fwc.fw_command,
NFQ_TABLE,
NFQ_CHAIN,
NFQ_PORT,
NFQ_QUEUE_NUM
);
res = run_extcmd(cmd_buf, err_buf, CMD_BUFSIZE, 0);
if (opts->verbose)
log_msg(LOG_INFO, "create_fw_chains() CMD: '%s' (res: %d, err: %s)",
cmd_buf, res, err_buf);
/* Expect full success on this */
if(! EXTCMD_IS_SUCCESS(res))
{
log_msg(LOG_ERR, "Error %i from cmd:'%s': %s", res, cmd_buf, err_buf);
got_err++;
}
}
#endif
return(got_err);
}
+5
View File
@@ -68,6 +68,11 @@
#define FIREWD_LIST_ALL_RULES_ARGS "-t %s -v -n -L --line-numbers" SH_REDIR
#define FIREWD_ANY_IP "0.0.0.0/0"
#if USE_LIBNETFILTER_QUEUE
#define FIREWD_NFQ_ADD_ARGS "-t %s -A %s -p udp -m udp --dport %i -j NFQUEUE --queue-num %i"
#define FIREWD_NFQ_DEL_ARGS "-t %s -D %s -p udp -m udp --dport %i -j NFQUEUE --queue-num %i"
#endif
int validate_firewd_chain_conf(const char * const chain_str);
#endif /* FW_UTIL_FIREWALLD_H */
+137
View File
@@ -695,6 +695,69 @@ delete_all_chains(const fko_srv_options_t * const opts)
log_msg(LOG_ERR, "delete_all_chains() Error %i from cmd:'%s': %s",
res, cmd_buf, err_buf);
}
#if USE_LIBNETFILTER_QUEUE
if(opts->enable_nfq_capture)
{
zero_cmd_buffers();
/* Delete the rule to direct traffic to the NFQ chain.
*/
snprintf(cmd_buf, CMD_BUFSIZE-1, "%s " IPT_DEL_RULE_ARGS,
fwc.fw_command,
NFQ_TABLE,
"INPUT",
1
);
res = run_extcmd(cmd_buf, err_buf, CMD_BUFSIZE, 0);
if (opts->verbose)
log_msg(LOG_INFO, "delete_all_chains() CMD: '%s' (res: %d, err: %s)",
cmd_buf, res, err_buf);
/* Expect full success on this */
if(! EXTCMD_IS_SUCCESS(res))
log_msg(LOG_ERR, "Error %i from cmd:'%s': %s", res, cmd_buf, err_buf);
zero_cmd_buffers();
/* Flush the NFQ chain
*/
snprintf(cmd_buf, CMD_BUFSIZE-1, "%s " IPT_FLUSH_CHAIN_ARGS,
fwc.fw_command,
NFQ_TABLE,
NFQ_CHAIN
);
res = run_extcmd(cmd_buf, err_buf, CMD_BUFSIZE, 0);
if (opts->verbose)
log_msg(LOG_INFO, "delete_all_chains() CMD: '%s' (res: %d, err: %s)",
cmd_buf, res, err_buf);
/* Expect full success on this */
if(! EXTCMD_IS_SUCCESS(res))
log_msg(LOG_ERR, "Error %i from cmd:'%s': %s", res, cmd_buf, err_buf);
zero_cmd_buffers();
/* Create the NF_QUEUE chains and rules
*/
snprintf(cmd_buf, CMD_BUFSIZE-1, "%s " IPT_DEL_CHAIN_ARGS,
fwc.fw_command,
NFQ_TABLE,
NFQ_CHAIN
);
res = run_extcmd(cmd_buf, err_buf, CMD_BUFSIZE, 0);
if (opts->verbose)
log_msg(LOG_INFO, "delete_all_chains() CMD: '%s' (res: %d, err: %s)",
cmd_buf, res, err_buf);
/* Expect full success on this */
if(! EXTCMD_IS_SUCCESS(res))
log_msg(LOG_ERR, "Error %i from cmd:'%s': %s", res, cmd_buf, err_buf);
}
#endif
return;
}
@@ -763,6 +826,80 @@ create_fw_chains(const fko_srv_options_t * const opts)
got_err += mk_chain(opts, i);
}
#if USE_LIBNETFILTER_QUEUE
if(opts->enable_nfq_capture)
{
zero_cmd_buffers();
/* Create the NF_QUEUE chains and rules
*/
snprintf(cmd_buf, CMD_BUFSIZE-1, "%s " IPT_NEW_CHAIN_ARGS,
fwc.fw_command,
NFQ_TABLE,
NFQ_CHAIN
);
res = run_extcmd(cmd_buf, err_buf, CMD_BUFSIZE, 0);
if (opts->verbose)
log_msg(LOG_INFO, "create_fw_chains() CMD: '%s' (res: %d, err: %s)",
cmd_buf, res, err_buf);
/* Expect full success on this */
if(! EXTCMD_IS_SUCCESS(res))
{
log_msg(LOG_ERR, "Error %i from cmd:'%s': %s", res, cmd_buf, err_buf);
got_err++;
}
zero_cmd_buffers();
/* Create the rule to direct traffic to the NFQ chain.
*/
snprintf(cmd_buf, CMD_BUFSIZE-1, "%s " IPT_ADD_JUMP_RULE_ARGS,
fwc.fw_command,
NFQ_TABLE,
"INPUT",
1,
NFQ_CHAIN
);
res = run_extcmd(cmd_buf, err_buf, CMD_BUFSIZE, 0);
if (opts->verbose)
log_msg(LOG_INFO, "create_fw_chains() CMD: '%s' (res: %d, err: %s)",
cmd_buf, res, err_buf);
/* Expect full success on this */
if(! EXTCMD_IS_SUCCESS(res))
{
log_msg(LOG_ERR, "Error %i from cmd:'%s': %s", res, cmd_buf, err_buf);
got_err++;
}
zero_cmd_buffers();
/* Create the rule to direct SPA packets to the queue.
*/
snprintf(cmd_buf, CMD_BUFSIZE-1, "%s " IPT_NFQ_ADD_ARGS,
fwc.fw_command,
NFQ_TABLE,
NFQ_CHAIN,
NFQ_PORT,
NFQ_QUEUE_NUM
);
res = run_extcmd(cmd_buf, err_buf, CMD_BUFSIZE, 0);
if (opts->verbose)
log_msg(LOG_INFO, "create_fw_chains() CMD: '%s' (res: %d, err: %s)",
cmd_buf, res, err_buf);
/* Expect full success on this */
if(! EXTCMD_IS_SUCCESS(res))
{
log_msg(LOG_ERR, "Error %i from cmd:'%s': %s", res, cmd_buf, err_buf);
got_err++;
}
}
#endif
return(got_err);
}
+5
View File
@@ -65,6 +65,11 @@
#define IPT_LIST_ALL_RULES_ARGS "-t %s -v -n -L --line-numbers" SH_REDIR
#define IPT_ANY_IP "0.0.0.0/0"
#if USE_LIBNETFILTER_QUEUE
#define IPT_NFQ_ADD_ARGS "-t %s -A %s -p udp -m udp --dport %i -j NFQUEUE --queue-num %i"
#define IPT_NFQ_DEL_ARGS "-t %s -D %s -p udp -m udp --dport %i -j NFQUEUE --queue-num %i"
#endif
int validate_ipt_chain_conf(const char * const chain_str);
#endif /* FW_UTIL_IPTABLES_H */
+21 -2
View File
@@ -39,6 +39,9 @@
#include "tcp_server.h"
#include "udp_server.h"
#if USE_LIBNETFILTER_QUEUE
#include "nfq_capture.h"
#endif
#if USE_LIBPCAP
#include "pcap_capture.h"
#endif
@@ -206,6 +209,16 @@ main(int argc, char **argv)
if(!opts.test && opts.enable_fw && (fw_initialize(&opts) != 1))
clean_exit(&opts, FW_CLEANUP, EXIT_FAILURE);
#if USE_LIBNETFILTER_QUEUE
/* If we are to acquire SPA data via a libnetfilter_queue, start it up here.
*/
if(opts.enable_nfq_capture ||
strncasecmp(opts.config[CONF_ENABLE_NFQ_CAPTURE], "Y", 1) == 0)
{
nfq_capture(&opts);
}
else
#endif
/* If we are to acquire SPA data via a UDP socket, start it up here.
*/
if(opts.enable_udp_server ||
@@ -242,11 +255,17 @@ main(int argc, char **argv)
#if USE_LIBPCAP
/* Intiate pcap capture mode...
*/
if(!opts.enable_udp_server
&& strncasecmp(opts.config[CONF_ENABLE_UDP_SERVER], "N", 1) == 0)
if(!opts.enable_udp_server && !opts.enable_nfq_server
&& strncasecmp(opts.config[CONF_ENABLE_UDP_SERVER], "N", 1) == 0
&& strncasecmp(opts.config[CONF_ENABLE_NFQ_SERVER], "N", 1) == 0)
{
pcap_capture(&opts);
}
else
{
log_msg(LOG_ERR, "No available capture mode specified. Aborting.");
clean_exit(&opts, FW_CLEANUP, EXIT_FAILURE);
}
#endif
/* Deal with any signals that we've received and break out
+7
View File
@@ -437,6 +437,13 @@ typedef struct cmd_cycle_list
struct cmd_cycle_list *next;
} cmd_cycle_list_t;
#if USE_LIBNETFILTER_QUEUE
#define NFQ_TABLE "mangle"
#define NFQ_CHAIN "FWKNOP_NFQ"
#define NFQ_QUEUE_NUM 1
#define NFQ_PORT 62201
#endif
/* Firewall-related data and types. */
#if FIREWALL_FIREWALLD