Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
130 changes: 82 additions & 48 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -676,6 +676,24 @@ dnl
]
)

dnl Check for nftables
dnl
AC_ARG_WITH([nftables],
[AS_HELP_STRING([--with-nftables=/path/to/nft],
[Specify path to the nft executable @<:@default=check path@:>@])],
[
AS_IF([ test "x$withval" = xno ], [],
AS_IF([ test "x$withval" = x -o "x$withval" = xyes ],
[AC_MSG_ERROR([--with-nftables requires an argument specifying a path to nft])],
[ FORCE_NFTABLES_EXE=$withval ]
)
)
],
[
AC_PATH_PROG(NFT_EXE, [nft], [], [$APP_PATH])
]
)

dnl Check for ipfw
dnl
AC_ARG_WITH([ipfw],
Expand Down Expand Up @@ -734,78 +752,94 @@ dnl If a firewall was forced. set the appropriate _EXE var and clear the others.
dnl
AS_IF([test "x$FORCE_FIREWALLD_EXE" != x], [
FIREWALLD_EXE="$FORCE_FIREWALLD_EXE"
],[
AS_IF([test "x$FORCE_IPTABLES_EXE" != x], [
IPTABLES_EXE="$FORCE_IPTABLES_EXE"
FIREWALLD_EXE=""
],[
AS_IF([test "x$FORCE_IPFW_EXE" != x], [
IPFW_EXE="$FORCE_IPFW_EXE"
IPTABLES_EXE=""
AS_IF([test "x$FORCE_IPTABLES_EXE" != x], [
IPTABLES_EXE="$FORCE_IPTABLES_EXE"
FIREWALLD_EXE=""
],[
AS_IF([test "x$FORCE_PF_EXE" != x], [
PF_EXE="$FORCE_PF_EXE"
IPFW_EXE=""
AS_IF([test "x$FORCE_NFTABLES_EXE" != x], [
NFT_EXE="$FORCE_NFTABLES_EXE"
IPTABLES_EXE=""
FIREWALLD_EXE=""
],[
AS_IF([test "x$FORCE_IPF_EXE" != x], [
IPF_EXE="$FORCE_IPF_EXE"
PF_EXE=""
IPFW_EXE=""
AS_IF([test "x$FORCE_IPFW_EXE" != x], [
IPFW_EXE="$FORCE_IPFW_EXE"
NFT_EXE=""
IPTABLES_EXE=""
FIREWALLD_EXE=""
],[:]
],[
AS_IF([test "x$FORCE_PF_EXE" != x], [
PF_EXE="$FORCE_PF_EXE"
IPFW_EXE=""
NFT_EXE=""
IPTABLES_EXE=""
FIREWALLD_EXE=""
],[
AS_IF([test "x$FORCE_IPF_EXE" != x], [
IPF_EXE="$FORCE_IPF_EXE"
PF_EXE=""
IPFW_EXE=""
NFT_EXE=""
IPTABLES_EXE=""
FIREWALLD_EXE=""
],[:]
]
]
]
]
]
]
)))))
))))))

dnl Determine which firewall exe we use (if we have one).
dnl If firewalld was found or specified, it wins, then we fallback to iptables,
dnl then ipfw, pf, and otherwise we try ipf.
dnl
AS_IF([test "x$FIREWALLD_EXE" != x], [
FW_DEF="FW_FIREWALLD"
FIREWALL_TYPE="firewalld"
FIREWALL_EXE=$FIREWALLD_EXE
AC_DEFINE_UNQUOTED([FIREWALL_FIREWALLD], [1], [The firewall type: firewalld.])
],[
AS_IF([test "x$IPTABLES_EXE" != x], [
FW_DEF="FW_IPTABLES"
FIREWALL_TYPE="iptables"
FIREWALL_EXE=$IPTABLES_EXE
AC_DEFINE_UNQUOTED([FIREWALL_IPTABLES], [1], [The firewall type: iptables.])
],[
AS_IF([test "x$IPFW_EXE" != x], [
FW_DEF="FW_IPFW"
FIREWALL_TYPE="ipfw"
FIREWALL_EXE=$IPFW_EXE
AC_DEFINE_UNQUOTED([FIREWALL_IPFW], [1], [The firewall type: ipfw.])
AS_IF([test "x$FIREWALLD_EXE" != x], [
FW_DEF="FW_FIREWALLD"
FIREWALL_TYPE="firewalld"
FIREWALL_EXE=$FIREWALLD_EXE
AC_DEFINE_UNQUOTED([FIREWALL_FIREWALLD], [1], [The firewall type: firewalld.])
],[
AS_IF([test "x$PF_EXE" != x], [
FW_DEF="FW_PF"
FIREWALL_TYPE="pf"
FIREWALL_EXE=$PF_EXE
AC_DEFINE_UNQUOTED([FIREWALL_PF], [1], [The firewall type: pf.])
AS_IF([test "x$IPTABLES_EXE" != x], [
FW_DEF="FW_IPTABLES"
FIREWALL_TYPE="iptables"
FIREWALL_EXE=$IPTABLES_EXE
AC_DEFINE_UNQUOTED([FIREWALL_IPTABLES], [1], [The firewall type: iptables.])
],[
AS_IF([test "x$NFT_EXE" != x], [
FW_DEF="FW_NFTABLES"
FIREWALL_TYPE="nftables"
FIREWALL_EXE=$NFT_EXE
AC_DEFINE_UNQUOTED([FIREWALL_NFTABLES], [1], [The firewall type: nftables.])
],[
AS_IF([test "x$IPF_EXE" != x], [
AC_MSG_ERROR([Sorry - ipf was specified or the only one found, however, it is not supported yet.])
FIREWALL_TYPE="ipf"
FIREWALL_EXE=$IPF_EXE
AC_DEFINE_UNQUOTED([FIREWALL_IPF], [1], [The firewall type: ipf.])
], [AC_MSG_ERROR([No firewall program was found or specified.]) ]
]
AS_IF([test "x$IPFW_EXE" != x], [
FW_DEF="FW_IPFW"
FIREWALL_TYPE="ipfw"
FIREWALL_EXE=$IPFW_EXE
AC_DEFINE_UNQUOTED([FIREWALL_IPFW], [1], [The firewall type: ipfw.])
],[
AS_IF([test "x$PF_EXE" != x], [
FW_DEF="FW_PF"
FIREWALL_TYPE="pf"
FIREWALL_EXE=$PF_EXE
AC_DEFINE_UNQUOTED([FIREWALL_PF], [1], [The firewall type: pf.])
],[
AS_IF([test "x$IPF_EXE" != x], [
AC_MSG_ERROR([Sorry - ipf was specified or the only one found, however, it is not supported yet.])
FIREWALL_TYPE="ipf"
FIREWALL_EXE=$IPF_EXE
AC_DEFINE_UNQUOTED([FIREWALL_IPF], [1], [The firewall type: ipf.])
], [AC_MSG_ERROR([No firewall program was found or specified.]) ]
]
]
]
]
]
)))))
))))))

AC_DEFINE_UNQUOTED([FIREWALL_EXE], ["$FIREWALL_EXE"],
[Path to firewall command executable (it should match the firewall type).])

AM_CONDITIONAL([FIREWALL_NFTABLES], [test "x$NFT_EXE" != x])
],
[test "$want_server" = no], [
use_ndbm=no
Expand Down
4 changes: 4 additions & 0 deletions server/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ BASE_SOURCE_FILES = fwknopd.h config_init.c config_init.h \
fw_util_iptables.c fw_util_iptables.h \
fw_util_ipfw.c fw_util_ipfw.h \
fw_util_pf.c fw_util_pf.h cmd_opts.h \
fw_util_nftables.c fw_util_nftables_json.c fw_util_nftables.h fw_util_nftables_json.h \
extcmd.c extcmd.h cmd_cycle.c cmd_cycle.h

fwknopd_SOURCES = fwknopd.c $(BASE_SOURCE_FILES)
Expand Down Expand Up @@ -47,6 +48,9 @@ if !UDP_SERVER
endif
endif

if FIREWALL_NFTABLES
fwknopd_LDADD += -ljansson
endif

if !CONFIG_FILE_CACHE
if USE_NDBM
Expand Down
15 changes: 15 additions & 0 deletions server/cmd_opts.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,21 @@ static char *config_map[NUMBER_OF_CONFIG_ENTRIES] = {
"IPT_SNAT_ACCESS",
"IPT_MASQUERADE_ACCESS",
"ENABLE_IPT_COMMENT_CHECK",
#elif FIREWALL_NFTABLES
// "ENABLE_IPT_FORWARDING", /* not implemented yet */
// "ENABLE_IPT_LOCAL_NAT", /* not implemented yet */
// "ENABLE_IPT_SNAT", /* not implemented yet */
// "SNAT_TRANSLATE_IP", /* not implemented yet */
"ENABLE_IPT_OUTPUT",
"FLUSH_IPT_AT_INIT",
"FLUSH_IPT_AT_EXIT",
"IPT_INPUT_ACCESS",
"IPT_OUTPUT_ACCESS",
// "IPT_FORWARD_ACCESS", /* not implemented yet */
// "IPT_DNAT_ACCESS", /* not implemented yet */
// "IPT_SNAT_ACCESS", /* not implemented yet */
// "IPT_MASQUERADE_ACCESS", /* not implemented yet */
"NFT_IPV4_USE_INET_FAMILY",
#elif FIREWALL_IPFW
"FLUSH_IPFW_AT_INIT",
"FLUSH_IPFW_AT_EXIT",
Expand Down
147 changes: 147 additions & 0 deletions server/config_init.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@
#include "fw_util_firewalld.h"
#elif FIREWALL_IPTABLES
#include "fw_util_iptables.h"
#elif FIREWALL_NFTABLES
#include "fw_util_nftables.h"
#endif

/* Check to see if an integer variable has a value that is within a
Expand Down Expand Up @@ -812,6 +814,151 @@ validate_options(fko_srv_options_t *opts)
set_config_entry(opts, CONF_ENABLE_IPT_COMMENT_CHECK,
DEF_ENABLE_IPT_COMMENT_CHECK);

#elif FIREWALL_NFTABLES
#if 0
/* Enable IPT forwarding.
*/
if(opts->config[CONF_ENABLE_IPT_FORWARDING] == NULL)
set_config_entry(opts, CONF_ENABLE_IPT_FORWARDING,
DEF_ENABLE_IPT_FORWARDING);

/* Enable IPT local NAT.
*/
if(opts->config[CONF_ENABLE_IPT_LOCAL_NAT] == NULL)
set_config_entry(opts, CONF_ENABLE_IPT_LOCAL_NAT,
DEF_ENABLE_IPT_LOCAL_NAT);

/* Enable IPT SNAT.
*/
if(opts->config[CONF_ENABLE_IPT_SNAT] == NULL)
set_config_entry(opts, CONF_ENABLE_IPT_SNAT,
DEF_ENABLE_IPT_SNAT);

/* Make sure we have a valid IP if SNAT is enabled
*/
if(strncasecmp(opts->config[CONF_ENABLE_IPT_SNAT], "Y", 1) == 0)
{
/* Note that fw_config_init() will set use_masquerade if necessary
*/
if(opts->config[CONF_SNAT_TRANSLATE_IP] != NULL)
{
if(! is_valid_ipv4_addr(opts->config[CONF_SNAT_TRANSLATE_IP], strlen(opts->config[CONF_SNAT_TRANSLATE_IP])))
{
log_msg(LOG_ERR,
"Invalid IPv4 addr for SNAT_TRANSLATE_IP"
);
clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
}
}
}
#endif

/* Enable IPT OUTPUT.
*/
if(opts->config[CONF_ENABLE_IPT_OUTPUT] == NULL)
set_config_entry(opts, CONF_ENABLE_IPT_OUTPUT,
DEF_ENABLE_IPT_OUTPUT);

/* Flush IPT at init.
*/
if(opts->config[CONF_FLUSH_IPT_AT_INIT] == NULL)
set_config_entry(opts, CONF_FLUSH_IPT_AT_INIT, DEF_FLUSH_IPT_AT_INIT);

/* Flush IPT at exit.
*/
if(opts->config[CONF_FLUSH_IPT_AT_EXIT] == NULL)
set_config_entry(opts, CONF_FLUSH_IPT_AT_EXIT, DEF_FLUSH_IPT_AT_EXIT);

/* IPT input access.
*/
if(opts->config[CONF_IPT_INPUT_ACCESS] == NULL)
set_config_entry(opts, CONF_IPT_INPUT_ACCESS,
DEF_IPT_INPUT_ACCESS);

if(validate_ipt_chain_conf(opts->config[CONF_IPT_INPUT_ACCESS]) != 1)
{
log_msg(LOG_ERR,
"Invalid IPT_INPUT_ACCESS specification, see fwknopd.conf comments"
);
clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
}

/* IPT output access.
*/
if(opts->config[CONF_IPT_OUTPUT_ACCESS] == NULL)
set_config_entry(opts, CONF_IPT_OUTPUT_ACCESS,
DEF_IPT_OUTPUT_ACCESS);

if(validate_ipt_chain_conf(opts->config[CONF_IPT_OUTPUT_ACCESS]) != 1)
{
log_msg(LOG_ERR,
"Invalid IPT_OUTPUT_ACCESS specification, see fwknopd.conf comments"
);
clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
}

#if 0
/* IPT forward access.
*/
if(opts->config[CONF_IPT_FORWARD_ACCESS] == NULL)
set_config_entry(opts, CONF_IPT_FORWARD_ACCESS,
DEF_IPT_FORWARD_ACCESS);

if(validate_ipt_chain_conf(opts->config[CONF_IPT_FORWARD_ACCESS]) != 1)
{
log_msg(LOG_ERR,
"Invalid IPT_FORWARD_ACCESS specification, see fwknopd.conf comments"
);
clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
}

/* IPT dnat access.
*/
if(opts->config[CONF_IPT_DNAT_ACCESS] == NULL)
set_config_entry(opts, CONF_IPT_DNAT_ACCESS,
DEF_IPT_DNAT_ACCESS);

if(validate_ipt_chain_conf(opts->config[CONF_IPT_DNAT_ACCESS]) != 1)
{
log_msg(LOG_ERR,
"Invalid IPT_DNAT_ACCESS specification, see fwknopd.conf comments"
);
clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
}

/* IPT snat access.
*/
if(opts->config[CONF_IPT_SNAT_ACCESS] == NULL)
set_config_entry(opts, CONF_IPT_SNAT_ACCESS,
DEF_IPT_SNAT_ACCESS);

if(validate_ipt_chain_conf(opts->config[CONF_IPT_SNAT_ACCESS]) != 1)
{
log_msg(LOG_ERR,
"Invalid IPT_SNAT_ACCESS specification, see fwknopd.conf comments"
);
clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
}

/* IPT masquerade access.
*/
if(opts->config[CONF_IPT_MASQUERADE_ACCESS] == NULL)
set_config_entry(opts, CONF_IPT_MASQUERADE_ACCESS,
DEF_IPT_MASQUERADE_ACCESS);

if(validate_ipt_chain_conf(opts->config[CONF_IPT_MASQUERADE_ACCESS]) != 1)
{
log_msg(LOG_ERR,
"Invalid IPT_MASQUERADE_ACCESS specification, see fwknopd.conf comments"
);
clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
}
#endif

/* add IPv4 rules to inet family */
if(opts->config[CONF_NFT_IPV4_USE_INET_FAMILY] == NULL)
set_config_entry(opts, CONF_NFT_IPV4_USE_INET_FAMILY,
DEF_NFT_IPV4_USE_INET_FAMILY);
#elif FIREWALL_IPFW

/* Flush ipfw rules at init.
Expand Down
2 changes: 2 additions & 0 deletions server/fw_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@
#include "fw_util_firewalld.h"
#elif FIREWALL_IPTABLES
#include "fw_util_iptables.h"
#elif FIREWALL_NFTABLES
#include "fw_util_nftables.h"
#elif FIREWALL_IPFW
#include "fw_util_ipfw.h"
#elif FIREWALL_PF
Expand Down
Loading