mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-01-10 14:00:18 +01:00
firewall: merge branch 'th/firewall'
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/841
This commit is contained in:
commit
661934e48e
9 changed files with 420 additions and 257 deletions
|
|
@ -2569,6 +2569,8 @@ src_core_libNetworkManager_la_SOURCES = \
|
|||
src/core/nm-dhcp-config.h \
|
||||
src/core/nm-dispatcher.c \
|
||||
src/core/nm-dispatcher.h \
|
||||
src/core/nm-firewall-utils.c \
|
||||
src/core/nm-firewall-utils.h \
|
||||
src/core/nm-firewalld-manager.c \
|
||||
src/core/nm-firewalld-manager.h \
|
||||
src/core/nm-proxy-config.c \
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
#include "libnm-glib-aux/nm-c-list.h"
|
||||
|
||||
#include "libnm-glib-aux/nm-uuid.h"
|
||||
#include "libnm-glib-aux/nm-str-buf.h"
|
||||
#include "libnm-base/nm-net-aux.h"
|
||||
#include "libnm-core-aux-intern/nm-common-macros.h"
|
||||
#include "nm-utils.h"
|
||||
|
|
@ -1637,206 +1638,6 @@ nm_utils_ip_routes_to_dbus(int addr_family,
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
char *table;
|
||||
char *rule;
|
||||
} ShareRule;
|
||||
|
||||
struct _NMUtilsShareRules {
|
||||
GArray *rules;
|
||||
};
|
||||
|
||||
static void
|
||||
_share_rule_clear(gpointer data)
|
||||
{
|
||||
ShareRule *rule = data;
|
||||
|
||||
g_free(rule->table);
|
||||
g_free(rule->rule);
|
||||
}
|
||||
|
||||
NMUtilsShareRules *
|
||||
nm_utils_share_rules_new(void)
|
||||
{
|
||||
NMUtilsShareRules *self;
|
||||
|
||||
self = g_slice_new(NMUtilsShareRules);
|
||||
*self = (NMUtilsShareRules){
|
||||
.rules = g_array_sized_new(FALSE, FALSE, sizeof(ShareRule), 10),
|
||||
};
|
||||
|
||||
g_array_set_clear_func(self->rules, _share_rule_clear);
|
||||
return self;
|
||||
}
|
||||
|
||||
void
|
||||
nm_utils_share_rules_free(NMUtilsShareRules *self)
|
||||
{
|
||||
if (!self)
|
||||
return;
|
||||
|
||||
g_array_unref(self->rules);
|
||||
nm_g_slice_free(self);
|
||||
}
|
||||
|
||||
void
|
||||
nm_utils_share_rules_add_rule_take(NMUtilsShareRules *self, const char *table, char *rule_take)
|
||||
{
|
||||
ShareRule *rule;
|
||||
|
||||
g_return_if_fail(self);
|
||||
g_return_if_fail(table);
|
||||
g_return_if_fail(rule_take);
|
||||
|
||||
rule = nm_g_array_append_new(self->rules, ShareRule);
|
||||
*rule = (ShareRule){
|
||||
.table = g_strdup(table),
|
||||
.rule = g_steal_pointer(&rule_take),
|
||||
};
|
||||
}
|
||||
|
||||
void
|
||||
nm_utils_share_rules_apply(NMUtilsShareRules *self, gboolean shared)
|
||||
{
|
||||
guint i;
|
||||
|
||||
g_return_if_fail(self);
|
||||
|
||||
if (self->rules->len == 0)
|
||||
return;
|
||||
|
||||
/* depending on whether we share or unshare, we add/remote the rules
|
||||
* in opposite order. */
|
||||
if (shared)
|
||||
i = self->rules->len - 1;
|
||||
else
|
||||
i = 0;
|
||||
|
||||
for (;;) {
|
||||
gs_free_error GError *error = NULL;
|
||||
ShareRule * rule;
|
||||
gs_free const char ** argv = NULL;
|
||||
gs_free char * cmd = NULL;
|
||||
int status;
|
||||
|
||||
rule = &g_array_index(self->rules, ShareRule, i);
|
||||
|
||||
cmd = g_strdup_printf("%s --table %s %s %s",
|
||||
IPTABLES_PATH,
|
||||
rule->table,
|
||||
shared ? "--insert" : "--delete",
|
||||
rule->rule);
|
||||
argv = nm_utils_strsplit_set(cmd, " ");
|
||||
|
||||
nm_log_info(LOGD_SHARING, "Executing: %s", cmd);
|
||||
if (!g_spawn_sync("/",
|
||||
(char **) argv,
|
||||
(char **) NM_PTRARRAY_EMPTY(const char *),
|
||||
G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&status,
|
||||
&error)) {
|
||||
nm_log_warn(LOGD_SHARING, "Error executing command: %s", error->message);
|
||||
goto next;
|
||||
}
|
||||
if (WEXITSTATUS(status)) {
|
||||
nm_log_warn(LOGD_SHARING, "** Command returned exit status %d.", WEXITSTATUS(status));
|
||||
}
|
||||
|
||||
next:
|
||||
if (shared) {
|
||||
if (i == 0)
|
||||
break;
|
||||
i--;
|
||||
} else {
|
||||
i++;
|
||||
if (i >= self->rules->len)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nm_utils_share_rules_add_all_rules(NMUtilsShareRules *self,
|
||||
const char * ip_iface,
|
||||
in_addr_t addr,
|
||||
guint plen)
|
||||
{
|
||||
in_addr_t netmask;
|
||||
in_addr_t network;
|
||||
char str_mask[NM_UTILS_INET_ADDRSTRLEN];
|
||||
char str_addr[NM_UTILS_INET_ADDRSTRLEN];
|
||||
|
||||
nm_assert(self);
|
||||
|
||||
netmask = _nm_utils_ip4_prefix_to_netmask(plen);
|
||||
_nm_utils_inet4_ntop(netmask, str_mask);
|
||||
|
||||
network = addr & netmask;
|
||||
_nm_utils_inet4_ntop(network, str_addr);
|
||||
|
||||
nm_utils_share_rules_add_rule_v(
|
||||
self,
|
||||
"nat",
|
||||
"POSTROUTING --source %s/%s ! --destination %s/%s --jump MASQUERADE",
|
||||
str_addr,
|
||||
str_mask,
|
||||
str_addr,
|
||||
str_mask);
|
||||
nm_utils_share_rules_add_rule_v(
|
||||
self,
|
||||
"filter",
|
||||
"FORWARD --destination %s/%s --out-interface %s --match state --state "
|
||||
"ESTABLISHED,RELATED --jump ACCEPT",
|
||||
str_addr,
|
||||
str_mask,
|
||||
ip_iface);
|
||||
nm_utils_share_rules_add_rule_v(self,
|
||||
"filter",
|
||||
"FORWARD --source %s/%s --in-interface %s --jump ACCEPT",
|
||||
str_addr,
|
||||
str_mask,
|
||||
ip_iface);
|
||||
nm_utils_share_rules_add_rule_v(self,
|
||||
"filter",
|
||||
"FORWARD --in-interface %s --out-interface %s --jump ACCEPT",
|
||||
ip_iface,
|
||||
ip_iface);
|
||||
nm_utils_share_rules_add_rule_v(self,
|
||||
"filter",
|
||||
"FORWARD --out-interface %s --jump REJECT",
|
||||
ip_iface);
|
||||
nm_utils_share_rules_add_rule_v(self,
|
||||
"filter",
|
||||
"FORWARD --in-interface %s --jump REJECT",
|
||||
ip_iface);
|
||||
nm_utils_share_rules_add_rule_v(
|
||||
self,
|
||||
"filter",
|
||||
"INPUT --in-interface %s --protocol udp --destination-port 67 --jump ACCEPT",
|
||||
ip_iface);
|
||||
nm_utils_share_rules_add_rule_v(
|
||||
self,
|
||||
"filter",
|
||||
"INPUT --in-interface %s --protocol tcp --destination-port 67 --jump ACCEPT",
|
||||
ip_iface);
|
||||
nm_utils_share_rules_add_rule_v(
|
||||
self,
|
||||
"filter",
|
||||
"INPUT --in-interface %s --protocol udp --destination-port 53 --jump ACCEPT",
|
||||
ip_iface);
|
||||
nm_utils_share_rules_add_rule_v(
|
||||
self,
|
||||
"filter",
|
||||
"INPUT --in-interface %s --protocol tcp --destination-port 53 --jump ACCEPT",
|
||||
ip_iface);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/* Singleton NMPlatform subclass instance and cached class object */
|
||||
NM_DEFINE_SINGLETON_INSTANCE(NMPlatform);
|
||||
|
||||
|
|
|
|||
|
|
@ -224,33 +224,6 @@ NM_AUTO_DEFINE_FCN(NMDhcpLease *, _nm_auto_unref_dhcplease, nm_dhcp_lease_unref)
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef struct _NMUtilsShareRules NMUtilsShareRules;
|
||||
|
||||
NMUtilsShareRules *nm_utils_share_rules_new(void);
|
||||
|
||||
void nm_utils_share_rules_free(NMUtilsShareRules *self);
|
||||
|
||||
void
|
||||
nm_utils_share_rules_add_rule_take(NMUtilsShareRules *self, const char *table, char *rule_take);
|
||||
|
||||
static inline void
|
||||
nm_utils_share_rules_add_rule(NMUtilsShareRules *self, const char *table, const char *rule)
|
||||
{
|
||||
nm_utils_share_rules_add_rule_take(self, table, g_strdup(rule));
|
||||
}
|
||||
|
||||
#define nm_utils_share_rules_add_rule_v(self, table, ...) \
|
||||
nm_utils_share_rules_add_rule_take((self), (table), g_strdup_printf(__VA_ARGS__))
|
||||
|
||||
void nm_utils_share_rules_add_all_rules(NMUtilsShareRules *self,
|
||||
const char * ip_iface,
|
||||
in_addr_t addr,
|
||||
guint plen);
|
||||
|
||||
void nm_utils_share_rules_apply(NMUtilsShareRules *self, gboolean shared);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void nm_platform_setup(NMPlatform *instance);
|
||||
NMPlatform *nm_platform_get(void);
|
||||
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@
|
|||
#include "dnsmasq/nm-dnsmasq-manager.h"
|
||||
#include "nm-dhcp-config.h"
|
||||
#include "nm-rfkill-manager.h"
|
||||
#include "nm-firewall-utils.h"
|
||||
#include "nm-firewalld-manager.h"
|
||||
#include "settings/nm-settings-connection.h"
|
||||
#include "settings/nm-settings.h"
|
||||
|
|
@ -11571,7 +11572,7 @@ start_sharing(NMDevice *self, NMIP4Config *config, GError **error)
|
|||
NMConnection * conn;
|
||||
NMSettingConnection * s_con;
|
||||
gboolean announce_android_metered;
|
||||
NMUtilsShareRules * share_rules;
|
||||
NMFirewallConfig * firewall_config;
|
||||
|
||||
g_return_val_if_fail(config, FALSE);
|
||||
|
||||
|
|
@ -11596,13 +11597,9 @@ start_sharing(NMDevice *self, NMIP4Config *config, GError **error)
|
|||
req = nm_device_get_act_request(self);
|
||||
g_return_val_if_fail(req, FALSE);
|
||||
|
||||
share_rules = nm_utils_share_rules_new();
|
||||
firewall_config = nm_firewall_config_new(ip_iface, ip4_addr->address, ip4_addr->plen);
|
||||
|
||||
nm_utils_share_rules_add_all_rules(share_rules, ip_iface, ip4_addr->address, ip4_addr->plen);
|
||||
|
||||
nm_utils_share_rules_apply(share_rules, TRUE);
|
||||
|
||||
nm_act_request_set_shared(req, share_rules);
|
||||
nm_act_request_set_shared(req, firewall_config);
|
||||
|
||||
conn = nm_act_request_get_applied_connection(req);
|
||||
s_con = nm_connection_get_setting_connection(conn);
|
||||
|
|
|
|||
|
|
@ -163,6 +163,7 @@ libNetworkManager = static_library(
|
|||
'nm-dcb.c',
|
||||
'nm-dhcp-config.c',
|
||||
'nm-dispatcher.c',
|
||||
'nm-firewall-utils.c',
|
||||
'nm-firewalld-manager.c',
|
||||
'nm-hostname-manager.c',
|
||||
'nm-keep-alive.c',
|
||||
|
|
|
|||
|
|
@ -13,17 +13,19 @@
|
|||
#include <unistd.h>
|
||||
|
||||
#include "c-list/src/c-list.h"
|
||||
|
||||
#include "nm-setting-wireless-security.h"
|
||||
#include "nm-setting-8021x.h"
|
||||
#include "devices/nm-device.h"
|
||||
#include "nm-active-connection.h"
|
||||
#include "settings/nm-settings-connection.h"
|
||||
#include "libnm-core-aux-intern/nm-auth-subject.h"
|
||||
|
||||
#include "nm-setting-8021x.h"
|
||||
#include "nm-setting-wireless-security.h"
|
||||
|
||||
#include "devices/nm-device.h"
|
||||
#include "nm-active-connection.h"
|
||||
#include "nm-firewall-utils.h"
|
||||
#include "settings/nm-settings-connection.h"
|
||||
|
||||
typedef struct {
|
||||
CList call_ids_lst_head;
|
||||
NMUtilsShareRules *share_rules;
|
||||
CList call_ids_lst_head;
|
||||
NMFirewallConfig *firewall_config;
|
||||
} NMActRequestPrivate;
|
||||
|
||||
struct _NMActRequest {
|
||||
|
|
@ -248,31 +250,31 @@ nm_act_request_clear_secrets(NMActRequest *self)
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
NMUtilsShareRules *
|
||||
NMFirewallConfig *
|
||||
nm_act_request_get_shared(NMActRequest *req)
|
||||
{
|
||||
g_return_val_if_fail(NM_IS_ACT_REQUEST(req), FALSE);
|
||||
|
||||
return NM_ACT_REQUEST_GET_PRIVATE(req)->share_rules;
|
||||
return NM_ACT_REQUEST_GET_PRIVATE(req)->firewall_config;
|
||||
}
|
||||
|
||||
void
|
||||
nm_act_request_set_shared(NMActRequest *req, NMUtilsShareRules *rules)
|
||||
nm_act_request_set_shared(NMActRequest *req, NMFirewallConfig *rules)
|
||||
{
|
||||
NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE(req);
|
||||
|
||||
g_return_if_fail(NM_IS_ACT_REQUEST(req));
|
||||
|
||||
if (priv->share_rules == rules)
|
||||
if (priv->firewall_config == rules)
|
||||
return;
|
||||
|
||||
if (priv->share_rules) {
|
||||
nm_utils_share_rules_apply(priv->share_rules, FALSE);
|
||||
priv->share_rules = NULL;
|
||||
if (priv->firewall_config) {
|
||||
nm_firewall_config_apply(priv->firewall_config, FALSE);
|
||||
priv->firewall_config = NULL;
|
||||
}
|
||||
if (rules) {
|
||||
priv->share_rules = rules;
|
||||
nm_utils_share_rules_apply(priv->share_rules, TRUE);
|
||||
priv->firewall_config = rules;
|
||||
nm_firewall_config_apply(priv->firewall_config, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -506,9 +508,9 @@ dispose(GObject *object)
|
|||
c_list_for_each_entry_safe (call_id, call_id_safe, &priv->call_ids_lst_head, call_ids_lst)
|
||||
_do_cancel_secrets(self, call_id, TRUE);
|
||||
|
||||
if (priv->share_rules) {
|
||||
nm_utils_share_rules_apply(priv->share_rules, FALSE);
|
||||
nm_clear_pointer(&priv->share_rules, nm_utils_share_rules_free);
|
||||
if (priv->firewall_config) {
|
||||
nm_firewall_config_apply(priv->firewall_config, FALSE);
|
||||
nm_clear_pointer(&priv->firewall_config, nm_firewall_config_free);
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS(nm_act_request_parent_class)->dispose(object);
|
||||
|
|
|
|||
|
|
@ -38,11 +38,11 @@ NMConnection *nm_act_request_get_applied_connection(NMActRequest *req);
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
struct _NMUtilsShareRules;
|
||||
struct _NMFirewallConfig;
|
||||
|
||||
struct _NMUtilsShareRules *nm_act_request_get_shared(NMActRequest *req);
|
||||
struct _NMFirewallConfig *nm_act_request_get_shared(NMActRequest *req);
|
||||
|
||||
void nm_act_request_set_shared(NMActRequest *req, struct _NMUtilsShareRules *rules);
|
||||
void nm_act_request_set_shared(NMActRequest *req, struct _NMFirewallConfig *rules);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
|
|
|
|||
369
src/core/nm-firewall-utils.c
Normal file
369
src/core/nm-firewall-utils.c
Normal file
|
|
@ -0,0 +1,369 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/*
|
||||
* Copyright (C) 2004 - 2016 Red Hat, Inc.
|
||||
* Copyright (C) 2005 - 2008 Novell, Inc.
|
||||
*/
|
||||
|
||||
#include "src/core/nm-default-daemon.h"
|
||||
|
||||
#include "nm-firewall-utils.h"
|
||||
|
||||
#include "libnm-glib-aux/nm-str-buf.h"
|
||||
#include "libnm-platform/nm-platform.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#define _SHARE_IPTABLES_SUBNET_TO_STR_LEN (INET_ADDRSTRLEN + 1 + 2 + 1)
|
||||
|
||||
static const char *
|
||||
_share_iptables_subnet_to_str(char buf[static _SHARE_IPTABLES_SUBNET_TO_STR_LEN],
|
||||
in_addr_t addr,
|
||||
guint8 plen)
|
||||
{
|
||||
char buf_addr[INET_ADDRSTRLEN];
|
||||
in_addr_t netmask;
|
||||
int l;
|
||||
|
||||
netmask = _nm_utils_ip4_prefix_to_netmask(plen);
|
||||
|
||||
l = g_snprintf(buf,
|
||||
_SHARE_IPTABLES_SUBNET_TO_STR_LEN,
|
||||
"%s/%u",
|
||||
_nm_utils_inet4_ntop(addr & netmask, buf_addr),
|
||||
plen);
|
||||
nm_assert(l < _SHARE_IPTABLES_SUBNET_TO_STR_LEN);
|
||||
return buf;
|
||||
}
|
||||
|
||||
static char *
|
||||
_share_iptables_get_name(gboolean is_comment, const char *prefix, const char *ip_iface)
|
||||
{
|
||||
NMStrBuf strbuf = NM_STR_BUF_INIT(NM_UTILS_GET_NEXT_REALLOC_SIZE_40, FALSE);
|
||||
gsize ip_iface_len;
|
||||
|
||||
nm_assert(prefix);
|
||||
nm_assert(ip_iface);
|
||||
|
||||
/* This function is used to generate iptables chain names and comments.
|
||||
* Chain names must be shorter than 29 chars. Comments don't have this
|
||||
* limitation.
|
||||
*
|
||||
* Below we sanitize the ip_iface. If it's all benign, we use
|
||||
* - either "-$IP_IFACE" (at most 16 chars)
|
||||
* - otherwise, we base64 encode the name as "$(base64 $IP_IFACE)", at
|
||||
* most 20 chars.
|
||||
*
|
||||
* Since for benign names we already add a '-', prefix probably should not
|
||||
* contain a '-'. The '-' is necessary to distinguish between base64 encoding
|
||||
* an plain name.
|
||||
*
|
||||
* That means, for chain names the prefix must be at most 8 chars long. */
|
||||
nm_assert(is_comment || (strlen(prefix) <= 8));
|
||||
|
||||
nm_str_buf_append(&strbuf, prefix);
|
||||
|
||||
ip_iface_len = strlen(ip_iface);
|
||||
G_STATIC_ASSERT_EXPR(NMP_IFNAMSIZ == 16);
|
||||
if (ip_iface_len >= NMP_IFNAMSIZ) {
|
||||
nm_assert_not_reached();
|
||||
ip_iface_len = NMP_IFNAMSIZ - 1;
|
||||
}
|
||||
|
||||
if (NM_STRCHAR_ALL(ip_iface,
|
||||
ch,
|
||||
(ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'z')
|
||||
|| (ch >= 'A' && ch <= 'Z') || NM_IN_SET(ch, '.', '_', '-', '+'))) {
|
||||
nm_str_buf_append_c(&strbuf, '-');
|
||||
nm_str_buf_append(&strbuf, ip_iface);
|
||||
} else {
|
||||
gs_free char *s = NULL;
|
||||
|
||||
s = g_base64_encode((const guchar *) ip_iface, ip_iface_len);
|
||||
nm_str_buf_append(&strbuf, s);
|
||||
}
|
||||
|
||||
return nm_str_buf_finalize(&strbuf, NULL);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_share_iptables_call_v(const char *const *argv)
|
||||
{
|
||||
gs_free_error GError *error = NULL;
|
||||
gs_free char * argv_str = NULL;
|
||||
int status;
|
||||
|
||||
nm_log_dbg(LOGD_SHARING, "iptables: %s", (argv_str = g_strjoinv(" ", (char **) argv)));
|
||||
|
||||
if (!g_spawn_sync("/",
|
||||
(char **) argv,
|
||||
(char **) NM_PTRARRAY_EMPTY(const char *),
|
||||
G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&status,
|
||||
&error)) {
|
||||
nm_log_warn(LOGD_SHARING,
|
||||
"iptables: error executing command %s: %s",
|
||||
argv[0],
|
||||
error->message);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!g_spawn_check_exit_status(status, &error)) {
|
||||
nm_log_warn(LOGD_SHARING, "iptables: command %s failed: %s", argv[0], error->message);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#define _share_iptables_call(...) _share_iptables_call_v(NM_MAKE_STRV(__VA_ARGS__))
|
||||
|
||||
static gboolean
|
||||
_share_iptables_chain_op(const char *table, const char *chain, const char *op)
|
||||
{
|
||||
return _share_iptables_call("" IPTABLES_PATH "", "--table", table, op, chain);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_share_iptables_chain_delete(const char *table, const char *chain)
|
||||
{
|
||||
_share_iptables_chain_op(table, chain, "--flush");
|
||||
return _share_iptables_chain_op(table, chain, "--delete-chain");
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_share_iptables_chain_add(const char *table, const char *chain)
|
||||
{
|
||||
if (_share_iptables_chain_op(table, chain, "--new-chain"))
|
||||
return TRUE;
|
||||
|
||||
_share_iptables_chain_delete(table, chain);
|
||||
return _share_iptables_chain_op(table, chain, "--new-chain");
|
||||
}
|
||||
|
||||
static void
|
||||
_share_iptables_set_masquerade(gboolean add, const char *ip_iface, in_addr_t addr, guint8 plen)
|
||||
{
|
||||
char str_subnet[_SHARE_IPTABLES_SUBNET_TO_STR_LEN];
|
||||
gs_free char *comment_name = NULL;
|
||||
|
||||
comment_name = _share_iptables_get_name(TRUE, "nm-shared", ip_iface);
|
||||
|
||||
_share_iptables_subnet_to_str(str_subnet, addr, plen);
|
||||
_share_iptables_call("" IPTABLES_PATH "",
|
||||
"--table",
|
||||
"nat",
|
||||
add ? "--insert" : "--delete",
|
||||
"POSTROUTING",
|
||||
"--source",
|
||||
str_subnet,
|
||||
"!",
|
||||
"--destination",
|
||||
str_subnet,
|
||||
"--jump",
|
||||
"MASQUERADE",
|
||||
"-m",
|
||||
"comment",
|
||||
"--comment",
|
||||
comment_name);
|
||||
}
|
||||
|
||||
static void
|
||||
_share_iptables_set_shared_chains_add(const char *chain_input,
|
||||
const char *chain_forward,
|
||||
const char *ip_iface,
|
||||
in_addr_t addr,
|
||||
guint plen)
|
||||
{
|
||||
const char *const input_params[][2] = {
|
||||
{
|
||||
"tcp",
|
||||
"67",
|
||||
},
|
||||
{
|
||||
"udp",
|
||||
"67",
|
||||
},
|
||||
{
|
||||
"tcp",
|
||||
"53",
|
||||
},
|
||||
{
|
||||
"udp",
|
||||
"53",
|
||||
},
|
||||
};
|
||||
char str_subnet[_SHARE_IPTABLES_SUBNET_TO_STR_LEN];
|
||||
int i;
|
||||
|
||||
_share_iptables_subnet_to_str(str_subnet, addr, plen);
|
||||
|
||||
_share_iptables_chain_add("filter", chain_input);
|
||||
|
||||
for (i = 0; i < (int) G_N_ELEMENTS(input_params); i++) {
|
||||
_share_iptables_call("" IPTABLES_PATH "",
|
||||
"--table",
|
||||
"filter",
|
||||
"--append",
|
||||
chain_input,
|
||||
"--protocol",
|
||||
input_params[i][0],
|
||||
"--destination-port",
|
||||
input_params[i][1],
|
||||
"--jump",
|
||||
"ACCEPT");
|
||||
}
|
||||
|
||||
_share_iptables_chain_add("filter", chain_forward);
|
||||
|
||||
_share_iptables_call("" IPTABLES_PATH "",
|
||||
"--table",
|
||||
"filter",
|
||||
"--append",
|
||||
chain_forward,
|
||||
"--destination",
|
||||
str_subnet,
|
||||
"--out-interface",
|
||||
ip_iface,
|
||||
"--match",
|
||||
"state",
|
||||
"--state",
|
||||
"ESTABLISHED,RELATED",
|
||||
"--jump",
|
||||
"ACCEPT");
|
||||
_share_iptables_call("" IPTABLES_PATH "",
|
||||
"--table",
|
||||
"filter",
|
||||
"--append",
|
||||
chain_forward,
|
||||
"--source",
|
||||
str_subnet,
|
||||
"--in-interface",
|
||||
ip_iface,
|
||||
"--jump",
|
||||
"ACCEPT");
|
||||
_share_iptables_call("" IPTABLES_PATH "",
|
||||
"--table",
|
||||
"filter",
|
||||
"--append",
|
||||
chain_forward,
|
||||
"--in-interface",
|
||||
ip_iface,
|
||||
"--out-interface",
|
||||
ip_iface,
|
||||
"--jump",
|
||||
"ACCEPT");
|
||||
_share_iptables_call("" IPTABLES_PATH "",
|
||||
"--table",
|
||||
"filter",
|
||||
"--append",
|
||||
chain_forward,
|
||||
"--out-interface",
|
||||
ip_iface,
|
||||
"--jump",
|
||||
"REJECT");
|
||||
_share_iptables_call("" IPTABLES_PATH "",
|
||||
"--table",
|
||||
"filter",
|
||||
"--append",
|
||||
chain_forward,
|
||||
"--in-interface",
|
||||
ip_iface,
|
||||
"--jump",
|
||||
"REJECT");
|
||||
}
|
||||
|
||||
static void
|
||||
_share_iptables_set_shared_chains_delete(const char *chain_input, const char *chain_forward)
|
||||
{
|
||||
_share_iptables_chain_delete("filter", chain_input);
|
||||
_share_iptables_chain_delete("filter", chain_forward);
|
||||
}
|
||||
|
||||
_nm_unused static void
|
||||
_share_iptables_set_shared(gboolean add, const char *ip_iface, in_addr_t addr, guint plen)
|
||||
{
|
||||
gs_free char *comment_name = NULL;
|
||||
gs_free char *chain_input = NULL;
|
||||
gs_free char *chain_forward = NULL;
|
||||
|
||||
comment_name = _share_iptables_get_name(TRUE, "nm-shared", ip_iface);
|
||||
chain_input = _share_iptables_get_name(FALSE, "nm-sh-in", ip_iface);
|
||||
chain_forward = _share_iptables_get_name(FALSE, "nm-sh-fw", ip_iface);
|
||||
|
||||
if (add)
|
||||
_share_iptables_set_shared_chains_add(chain_input, chain_forward, ip_iface, addr, plen);
|
||||
|
||||
_share_iptables_call("" IPTABLES_PATH "",
|
||||
"--table",
|
||||
"filter",
|
||||
add ? "--insert" : "--delete",
|
||||
"INPUT",
|
||||
"--in-interface",
|
||||
ip_iface,
|
||||
"--jump",
|
||||
chain_input,
|
||||
"-m",
|
||||
"comment",
|
||||
"--comment",
|
||||
comment_name);
|
||||
|
||||
_share_iptables_call("" IPTABLES_PATH "",
|
||||
"--table",
|
||||
"filter",
|
||||
add ? "--insert" : "--delete",
|
||||
"FORWARD",
|
||||
"--jump",
|
||||
chain_forward,
|
||||
"-m",
|
||||
"comment",
|
||||
"--comment",
|
||||
comment_name);
|
||||
|
||||
if (!add)
|
||||
_share_iptables_set_shared_chains_delete(chain_input, chain_forward);
|
||||
}
|
||||
|
||||
struct _NMFirewallConfig {
|
||||
char * ip_iface;
|
||||
in_addr_t addr;
|
||||
guint8 plen;
|
||||
};
|
||||
|
||||
NMFirewallConfig *
|
||||
nm_firewall_config_new(const char *ip_iface, in_addr_t addr, guint8 plen)
|
||||
{
|
||||
NMFirewallConfig *self;
|
||||
|
||||
nm_assert(ip_iface);
|
||||
nm_assert(addr != 0u);
|
||||
nm_assert(plen <= 32);
|
||||
|
||||
self = g_slice_new(NMFirewallConfig);
|
||||
*self = (NMFirewallConfig){
|
||||
.ip_iface = g_strdup(ip_iface),
|
||||
.addr = addr,
|
||||
.plen = plen,
|
||||
};
|
||||
return self;
|
||||
}
|
||||
|
||||
void
|
||||
nm_firewall_config_free(NMFirewallConfig *self)
|
||||
{
|
||||
if (!self)
|
||||
return;
|
||||
|
||||
g_free(self->ip_iface);
|
||||
nm_g_slice_free(self);
|
||||
}
|
||||
|
||||
void
|
||||
nm_firewall_config_apply(NMFirewallConfig *self, gboolean shared)
|
||||
{
|
||||
_share_iptables_set_masquerade(shared, self->ip_iface, self->addr, self->plen);
|
||||
_share_iptables_set_shared(shared, self->ip_iface, self->addr, self->plen);
|
||||
}
|
||||
18
src/core/nm-firewall-utils.h
Normal file
18
src/core/nm-firewall-utils.h
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/*
|
||||
* Copyright (C) 2004 - 2016 Red Hat, Inc.
|
||||
* Copyright (C) 2005 - 2008 Novell, Inc.
|
||||
*/
|
||||
|
||||
#ifndef __NM_FIREWALL_UTILS_H__
|
||||
#define __NM_FIREWALL_UTILS_H__
|
||||
|
||||
typedef struct _NMFirewallConfig NMFirewallConfig;
|
||||
|
||||
NMFirewallConfig *nm_firewall_config_new(const char *ip_iface, in_addr_t addr, guint8 plen);
|
||||
|
||||
void nm_firewall_config_free(NMFirewallConfig *self);
|
||||
|
||||
void nm_firewall_config_apply(NMFirewallConfig *self, gboolean shared);
|
||||
|
||||
#endif /* __NM_FIREWALL_UTILS_H__ */
|
||||
Loading…
Add table
Reference in a new issue