NFTables make tables name configurable

Right now the table names are hardcoded and do not integrate with an overall
firewall strategy.
NFTables has restrictions on how packets are evaluated against chains.
For example if multiple forward chains are evaluated with different prioity,
all packets that pass the first one will be reevaluated again in the second chain.
To have an overall firewall concept with miniupnpd it is necessary to use existing
tables and hence to configure them in miniupnpd.

Signed-off-by: Sven Auhagen <sven.auhagen@voleatech.de>
This commit is contained in:
Sven Auhagen 2021-08-18 16:46:29 +01:00 committed by Thomas Bernard
parent 9eb826a7eb
commit 0b3f3e4029
No known key found for this signature in database
GPG Key ID: DB511043A31ACAAF
7 changed files with 31 additions and 8 deletions

View File

@ -77,6 +77,7 @@ update_portmapping_desc_timestamp(const char * ifname,
typedef enum {
RDR_TABLE_NAME,
RDR_NAT_TABLE_NAME,
RDR_NAT_PREROUTING_CHAIN_NAME,
RDR_NAT_POSTROUTING_CHAIN_NAME,
RDR_FORWARD_CHAIN_NAME,

View File

@ -1342,6 +1342,12 @@ init(int argc, char * * argv, struct runtime_vars * v)
break;
#endif /* ENABLE_MANUFACTURER_INFO_CONFIGURATION */
#ifdef USE_NETFILTER
case UPNPTABLENAME:
set_rdr_name(RDR_TABLE_NAME, ary_options[i].value);
break;
case UPNPNATTABLENAME:
set_rdr_name(RDR_NAT_TABLE_NAME, ary_options[i].value);
break;
case UPNPFORWARDCHAIN:
set_rdr_name(RDR_FORWARD_CHAIN_NAME, ary_options[i].value);
break;

View File

@ -84,12 +84,16 @@ init_redirect(void)
nft_forward_chain, FILTER_CHAIN_TYPE, NF_INET_FORWARD, NF_IP_PRI_FILTER - 25);
}
if (result == 0 && strcmp(nft_nat_table, nft_table) != 0) {
result = table_op(NFT_MSG_NEWTABLE, NFPROTO_INET, nft_nat_table);
}
if (result == 0) {
result = chain_op(NFT_MSG_NEWCHAIN, NFPROTO_INET, nft_table,
result = chain_op(NFT_MSG_NEWCHAIN, NFPROTO_INET, nft_nat_table,
nft_prerouting_chain, NAT_CHAIN_TYPE, NF_INET_PRE_ROUTING, NF_IP_PRI_NAT_DST);
}
if (result == 0) {
result = chain_op(NFT_MSG_NEWCHAIN, NFPROTO_INET, nft_table,
result = chain_op(NFT_MSG_NEWCHAIN, NFPROTO_INET, nft_nat_table,
nft_postrouting_chain, NAT_CHAIN_TYPE, NF_INET_POST_ROUTING, NF_IP_PRI_NAT_SRC);
}
@ -109,11 +113,14 @@ shutdown_redirect(void)
nft_prerouting_chain, NAT_CHAIN_TYPE, NF_INET_PRE_ROUTING, NF_IP_PRI_NAT_DST);
}
if (result == 0) {
result = chain_op(NFT_MSG_DELCHAIN, NFPROTO_INET, nft_table,
result = chain_op(NFT_MSG_DELCHAIN, NFPROTO_INET, nft_nat_table,
nft_postrouting_chain, NAT_CHAIN_TYPE, NF_INET_POST_ROUTING, NF_IP_PRI_NAT_SRC);
}
if (result == 0) {
result = table_op(NFT_MSG_DELTABLE, NFPROTO_INET, nft_table);
result = table_op(NFT_MSG_DELTABLE, NFPROTO_INET, nft_nat_table);
}
if (result == 0 && strcmp(nft_nat_table, nft_table) != 0) {
result = table_op(NFT_MSG_DELTABLE, NFPROTO_INET, nft_nat_table);
}
nft_mnl_disconnect();
@ -136,6 +143,9 @@ set_rdr_name(rdr_name_type param, const char *string)
case RDR_TABLE_NAME:
nft_table = string;
break;
case RDR_NAT_TABLE_NAME:
nft_nat_table = string;
break;
case RDR_NAT_PREROUTING_CHAIN_NAME:
nft_prerouting_chain = string;
break;

View File

@ -64,6 +64,7 @@
#define RULE_CACHE_VALID 1
const char * nft_table = "miniupnpd";
const char * nft_nat_table = "miniupnpd";
const char * nft_prerouting_chain = "prerouting";
const char * nft_postrouting_chain = "postrouting";
const char * nft_forward_chain = "forward";
@ -629,7 +630,7 @@ int
refresh_nft_cache_peer(void)
{
if (rule_list_peer_validate != RULE_CACHE_VALID) {
if (refresh_nft_cache(&head_peer, nft_table, nft_postrouting_chain, NFPROTO_INET, RULE_NAT) < 0)
if (refresh_nft_cache(&head_peer, nft_nat_table, nft_postrouting_chain, NFPROTO_INET, RULE_NAT) < 0)
return -1;
rule_list_peer_validate = RULE_CACHE_VALID;
}
@ -640,7 +641,7 @@ int
refresh_nft_cache_redirect(void)
{
if (rule_list_redirect_validate != RULE_CACHE_VALID) {
if (refresh_nft_cache(&head_redirect, nft_table, nft_prerouting_chain, NFPROTO_INET, RULE_NAT) < 0)
if (refresh_nft_cache(&head_redirect, nft_nat_table, nft_prerouting_chain, NFPROTO_INET, RULE_NAT) < 0)
return -1;
rule_list_redirect_validate = RULE_CACHE_VALID;
}
@ -877,7 +878,7 @@ rule_set_snat(uint8_t family, uint8_t proto,
}
nftnl_rule_set_u32(r, NFTNL_RULE_FAMILY, family);
nftnl_rule_set_str(r, NFTNL_RULE_TABLE, nft_table);
nftnl_rule_set_str(r, NFTNL_RULE_TABLE, nft_nat_table);
nftnl_rule_set_str(r, NFTNL_RULE_CHAIN, nft_postrouting_chain);
if (descr != NULL && *descr != '\0') {
@ -955,7 +956,7 @@ rule_set_dnat(uint8_t family, const char * ifname, uint8_t proto,
}
nftnl_rule_set_u32(r, NFTNL_RULE_FAMILY, family);
nftnl_rule_set_str(r, NFTNL_RULE_TABLE, nft_table);
nftnl_rule_set_str(r, NFTNL_RULE_TABLE, nft_nat_table);
nftnl_rule_set_str(r, NFTNL_RULE_CHAIN, nft_prerouting_chain);
if (descr != NULL && *descr != '\0') {

View File

@ -11,6 +11,7 @@
#include <sys/queue.h>
extern const char * nft_table;
extern const char * nft_nat_table;
extern const char * nft_prerouting_chain;
extern const char * nft_postrouting_chain;
extern const char * nft_forward_chain;

View File

@ -68,6 +68,8 @@ static const struct {
{ UPNPCLEANTHRESHOLD, "clean_ruleset_threshold"},
{ UPNPCLEANINTERVAL, "clean_ruleset_interval"},
#ifdef USE_NETFILTER
{ UPNPTABLENAME, "upnp_table_name"},
{ UPNPNATTABLENAME, "upnp_nattable_name"},
{ UPNPFORWARDCHAIN, "upnp_forward_chain"},
{ UPNPNATCHAIN, "upnp_nat_chain"},
{ UPNPNATPOSTCHAIN, "upnp_nat_postrouting_chain"},

View File

@ -57,6 +57,8 @@ enum upnpconfigoptions {
UPNPPCPMAXLIFETIME, /* maximum lifetime for PCP mapping */
UPNPPCPALLOWTHIRDPARTY, /* allow third-party requests */
#ifdef USE_NETFILTER
UPNPTABLENAME,
UPNPNATTABLENAME,
UPNPFORWARDCHAIN,
UPNPNATCHAIN,
UPNPNATPOSTCHAIN,