Răsfoiți Sursa

Enforce encryption at compile time

This patch strictly enforces encryption by completely removing
the ability to run unencrypted configurations from the default
build.

The primary goal is to protect against maliciously crafted packets
that could trigger crashes or undefined behavior. By making
encryption mandatory, we ensure such attacks are only possible
if an attacker has already compromised the private keys.

Because this enforcement happens at compile time, the code to
handle unencrypted traffic is omitted by default. Restoring these
features now requires explicit opt-in via two new configure flags:

--enable-unencrypted: Allows crypto_cipher/hash to be set to 'none'.

--enable-udpu: Restores the legacy totemudp and udpu transports.
(Note: This flag strictly requires --enable-unencrypted).

To help administrators easily verify a binary compile options,
the "Built-in features" list (visible via `corosync -v`) has been
updated to reflect these states. Standard secure builds will now
explicitly display 'enforce_encryption' and 'without_udpu'. If the
legacy flags are used, these are replaced with 'unencrypted' and
'udpu' respectively.

This does not mean we will stop fixing bugs related to malformed
packets. However, it drastically minimizes the unauthenticated
remote attack vector, allowing for a more measured response to
future parsing flaws.

These compile options provide an escape hatch. Package maintainers
or users compiling from source must now consciously opt-in using
these flags if they wish to restore legacy capabilities.

Signed-off-by: Jan Friesse <jfriesse@redhat.com>
Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
Jan Friesse 4 luni în urmă
părinte
comite
65f9450829
9 a modificat fișierele cu 139 adăugiri și 28 ștergeri
  1. 0 8
      conf/corosync.conf.example
  2. 31 0
      configure.ac
  3. 8 0
      corosync.spec.in
  4. 5 2
      exec/Makefile.am
  5. 2 0
      exec/cfg.c
  6. 54 5
      exec/totemconfig.c
  7. 11 1
      exec/totemnet.c
  8. 6 0
      include/corosync/totem/totem.h
  9. 22 12
      man/corosync.conf.5

+ 0 - 8
conf/corosync.conf.example

@@ -4,14 +4,6 @@ totem {
 
 
 	# Set name of the cluster
 	# Set name of the cluster
 	cluster_name: ExampleCluster
 	cluster_name: ExampleCluster
-
-	# crypto_cipher and crypto_hash: Used for mutual node authentication.
-	# If you choose to enable this, then do remember to create a shared
-	# secret with "corosync-keygen".
-	# enabling crypto_cipher, requires also enabling of crypto_hash.
-	# crypto works only with knet transport
-	crypto_cipher: none
-	crypto_hash: none
 }
 }
 
 
 logging {
 logging {

+ 31 - 0
configure.ac

@@ -449,6 +449,17 @@ AC_ARG_ENABLE([nozzle],
 	[  --enable-nozzle                 : Support for nozzle ],,
 	[  --enable-nozzle                 : Support for nozzle ],,
 	[ enable_nozzle="no" ])
 	[ enable_nozzle="no" ])
 
 
+AC_ARG_ENABLE([unencrypted],
+	[  --enable-unencrypted            : Enable running Corosync unencrypted ],,
+	[ default="no" ])
+AM_CONDITIONAL(BUILD_UNENCRYPTED, test x$enable_unencrypted = xyes)
+
+AC_ARG_ENABLE([udpu],
+	[  --enable-udpu                   : Enable UDP and UDPU transports for Corosync (requires unencrypted)],,
+	[ default="no" ])
+AM_CONDITIONAL(BUILD_UDPU, test x$enable_udpu = xyes)
+
+
 # *FLAGS handling goes here
 # *FLAGS handling goes here
 
 
 ENV_CFLAGS="$CFLAGS"
 ENV_CFLAGS="$CFLAGS"
@@ -562,6 +573,26 @@ if test "x${enable_nozzle}" = xyes; then
 	WITH_LIST="$WITH_LIST --with nozzle"
 	WITH_LIST="$WITH_LIST --with nozzle"
 fi
 fi
 
 
+if test "x${enable_unencrypted}" = xyes; then
+	AC_DEFINE([ENABLE_UNENCRYPTED], [1], [Enable running Corosync unencrypted])
+	PACKAGE_FEATURES="$PACKAGE_FEATURES unencrypted"
+	WITH_LIST="$WITH_LIST --with unencrypted"
+else
+	PACKAGE_FEATURES="$PACKAGE_FEATURES enforce_encryption"
+fi
+
+if test "x${enable_udpu}" = xyes; then
+	if test ! "x${enable_unencrypted}" = xyes; then
+		AC_MSG_ERROR([Enabling UDPU requires enabled unencrypted support (--enable-unencrypted)])
+	fi
+
+	AC_DEFINE([ENABLE_UDPU], [1], [Enable UDP/UDPU transports])
+	PACKAGE_FEATURES="$PACKAGE_FEATURES udpu"
+	WITH_LIST="$WITH_LIST --with udpu"
+else
+	PACKAGE_FEATURES="$PACKAGE_FEATURES without_udpu"
+fi
+
 do_snmp=0
 do_snmp=0
 if test "x${enable_snmp}" = xyes; then
 if test "x${enable_snmp}" = xyes; then
 	AC_PATH_PROGS([SNMPCONFIG], [net-snmp-config])
 	AC_PATH_PROGS([SNMPCONFIG], [net-snmp-config])

+ 8 - 0
corosync.spec.in

@@ -15,6 +15,8 @@
 %bcond_with vqsim
 %bcond_with vqsim
 %bcond_with runautogen
 %bcond_with runautogen
 %bcond_with userflags
 %bcond_with userflags
+%bcond_with unencrypted
+%bcond_with udpu
 
 
 %global gitver %{?numcomm:.%{numcomm}}%{?alphatag:.%{alphatag}}%{?dirty:.%{dirty}}
 %global gitver %{?numcomm:.%{numcomm}}%{?alphatag:.%{alphatag}}%{?dirty:.%{dirty}}
 %global gittarver %{?numcomm:.%{numcomm}}%{?alphatag:-%{alphatag}}%{?dirty:-%{dirty}}
 %global gittarver %{?numcomm:.%{numcomm}}%{?alphatag:-%{alphatag}}%{?dirty:-%{dirty}}
@@ -112,6 +114,12 @@ BuildRequires: readline-devel
 %if %{with vqsim}
 %if %{with vqsim}
 	--enable-vqsim \
 	--enable-vqsim \
 %endif
 %endif
+%if %{with unencrypted}
+	--enable-unencrypted \
+%endif
+%if %{with udpu}
+	--enable-udpu \
+%endif
 %if %{with userflags}
 %if %{with userflags}
 	--enable-user-flags \
 	--enable-user-flags \
 %endif
 %endif

+ 5 - 2
exec/Makefile.am

@@ -45,8 +45,7 @@ corosync_SOURCES	= vsf_ykd.c coroparse.c vsf_quorum.c sync.c \
 			  votequorum.c util.c schedwrk.c main.c \
 			  votequorum.c util.c schedwrk.c main.c \
 			  apidef.c quorum.c icmap.c timer.c stats.c \
 			  apidef.c quorum.c icmap.c timer.c stats.c \
 			  ipc_glue.c service.c logconfig.c totemconfig.c \
 			  ipc_glue.c service.c logconfig.c totemconfig.c \
-			  totemip.c totemnet.c totemudp.c \
-			  totemudpu.c totemsrp.c \
+			  totemip.c totemnet.c totemsrp.c \
 			  totempg.c totemknet.c
 			  totempg.c totemknet.c
 
 
 if BUILD_MONITORING
 if BUILD_MONITORING
@@ -57,6 +56,10 @@ if BUILD_WATCHDOG
 corosync_SOURCES	+= wd.c
 corosync_SOURCES	+= wd.c
 endif
 endif
 
 
+if BUILD_UDPU
+corosync_SOURCES	+= totemudp.c totemudpu.c
+endif
+
 corosync_CPPFLAGS	= -DLOGCONFIG_USE_ICMAP=1
 corosync_CPPFLAGS	= -DLOGCONFIG_USE_ICMAP=1
 
 
 corosync_CFLAGS         = $(statgrab_CFLAGS) $(libsystemd_CFLAGS) $(knet_CFLAGS) $(nozzle_CFLAGS)
 corosync_CFLAGS         = $(statgrab_CFLAGS) $(libsystemd_CFLAGS) $(knet_CFLAGS) $(nozzle_CFLAGS)

+ 2 - 0
exec/cfg.c

@@ -776,6 +776,7 @@ static void message_handler_req_exec_cfg_reload_config (
 	assert(new_config.interfaces != NULL);
 	assert(new_config.interfaces != NULL);
 	memset(new_config.interfaces, 0, sizeof (struct totem_interface) * INTERFACE_MAX);
 	memset(new_config.interfaces, 0, sizeof (struct totem_interface) * INTERFACE_MAX);
 
 
+#ifdef ENABLE_UDPU
 	/* For UDP[U] the configuration on link0 is static (apart from the nodelist) and only read at
 	/* For UDP[U] the configuration on link0 is static (apart from the nodelist) and only read at
 	   startup. So preserve it here */
 	   startup. So preserve it here */
 	if ( (new_config.transport_number == TOTEM_TRANSPORT_UDP) ||
 	if ( (new_config.transport_number == TOTEM_TRANSPORT_UDP) ||
@@ -783,6 +784,7 @@ static void message_handler_req_exec_cfg_reload_config (
 		memcpy(&new_config.interfaces[0], &new_config.orig_interfaces[0],
 		memcpy(&new_config.interfaces[0], &new_config.orig_interfaces[0],
 		       sizeof(struct totem_interface));
 		       sizeof(struct totem_interface));
 	}
 	}
+#endif
 
 
 	/* Calculate new node and interface definitions */
 	/* Calculate new node and interface definitions */
 	if (totemconfig_configure_new_params(&new_config, temp_map, &error_string) == -1) {
 	if (totemconfig_configure_new_params(&new_config, temp_map, &error_string) == -1) {

+ 54 - 5
exec/totemconfig.c

@@ -549,8 +549,13 @@ static int totem_get_crypto(struct totem_config *totem_config, icmap_map_t map,
 	char *crypto_model_str;
 	char *crypto_model_str;
 	int res = 0;
 	int res = 0;
 
 
+#ifdef ENABLE_UNENCRYPTED
 	tmp_hash = "none";
 	tmp_hash = "none";
 	tmp_cipher = "none";
 	tmp_cipher = "none";
+#else
+	tmp_hash = "sha256";
+	tmp_cipher = "aes256";
+#endif
 	tmp_model = "none";
 	tmp_model = "none";
 
 
 	crypto_model_str = NULL;
 	crypto_model_str = NULL;
@@ -561,6 +566,9 @@ static int totem_get_crypto(struct totem_config *totem_config, icmap_map_t map,
 	}
 	}
 
 
 	if (icmap_get_string_r(map, "totem.secauth", &str) == CS_OK) {
 	if (icmap_get_string_r(map, "totem.secauth", &str) == CS_OK) {
+		tmp_hash = "none";
+		tmp_cipher = "none";
+
 		if (strcmp(str, "on") == 0) {
 		if (strcmp(str, "on") == 0) {
 			tmp_cipher = "aes256";
 			tmp_cipher = "aes256";
 			tmp_hash = "sha256";
 			tmp_hash = "sha256";
@@ -606,6 +614,7 @@ static int totem_get_crypto(struct totem_config *totem_config, icmap_map_t map,
 		free(str);
 		free(str);
 	}
 	}
 
 
+#ifdef ENABLE_UNENCRYPTED
 	if ((strcmp(tmp_cipher, "none") != 0) &&
 	if ((strcmp(tmp_cipher, "none") != 0) &&
 	    (strcmp(tmp_hash, "none") == 0)) {
 	    (strcmp(tmp_hash, "none") == 0)) {
 		*error_string = "crypto_cipher requires crypto_hash with value other than none";
 		*error_string = "crypto_cipher requires crypto_hash with value other than none";
@@ -613,6 +622,14 @@ static int totem_get_crypto(struct totem_config *totem_config, icmap_map_t map,
 
 
 		goto out_free_crypto_model_str;
 		goto out_free_crypto_model_str;
 	}
 	}
+#else
+	if (strcmp(tmp_cipher, "none") == 0 || strcmp(tmp_hash, "none") == 0) {
+		*error_string = "corosync is compiled to require enabled encryption";
+		res = -1;
+
+		goto out_free_crypto_model_str;
+	}
+#endif
 
 
 	if (strcmp(tmp_model, "none") == 0) {
 	if (strcmp(tmp_model, "none") == 0) {
 		/*
 		/*
@@ -920,9 +937,11 @@ static enum totem_ip_version_enum totem_config_get_ip_version(struct totem_confi
 
 
 	res = TOTEM_IP_VERSION_6_4;
 	res = TOTEM_IP_VERSION_6_4;
 
 
+#ifdef ENABLE_UDPU
 	if (totem_config->transport_number == TOTEM_TRANSPORT_UDP) {
 	if (totem_config->transport_number == TOTEM_TRANSPORT_UDP) {
 		res = TOTEM_IP_VERSION_4;
 		res = TOTEM_IP_VERSION_4;
 	}
 	}
+#endif
 
 
 	if (icmap_get_string("totem.ip_version", &str) == CS_OK) {
 	if (icmap_get_string("totem.ip_version", &str) == CS_OK) {
 		if (strcmp(str, "ipv4") == 0) {
 		if (strcmp(str, "ipv4") == 0) {
@@ -943,6 +962,7 @@ static enum totem_ip_version_enum totem_config_get_ip_version(struct totem_confi
 	return (res);
 	return (res);
 }
 }
 
 
+#ifdef ENABLE_UDPU
 static uint16_t generate_cluster_id (const char *cluster_name)
 static uint16_t generate_cluster_id (const char *cluster_name)
 {
 {
 	int i;
 	int i;
@@ -993,6 +1013,7 @@ static int get_cluster_mcast_addr (
 
 
 	return (err);
 	return (err);
 }
 }
+#endif
 
 
 static unsigned int generate_nodeid(
 static unsigned int generate_nodeid(
 	struct totem_config *totem_config,
 	struct totem_config *totem_config,
@@ -1386,7 +1407,6 @@ static int put_nodelist_members_to_config(struct totem_config *totem_config, icm
 		iter2 = icmap_iter_init_r(map, tmp_key);
 		iter2 = icmap_iter_init_r(map, tmp_key);
 		while ((iter_key2 = icmap_iter_next(iter2, NULL, NULL)) != NULL) {
 		while ((iter_key2 = icmap_iter_next(iter2, NULL, NULL)) != NULL) {
 			unsigned int nodeid;
 			unsigned int nodeid;
-			char *str;
 
 
 			snprintf(tmp_key, ICMAP_KEYNAME_MAXLEN, "nodelist.node.%u.nodeid", node_pos);
 			snprintf(tmp_key, ICMAP_KEYNAME_MAXLEN, "nodelist.node.%u.nodeid", node_pos);
 			if (icmap_get_uint32_r(map, tmp_key, &nodeid) != CS_OK) {
 			if (icmap_get_uint32_r(map, tmp_key, &nodeid) != CS_OK) {
@@ -1412,10 +1432,13 @@ static int put_nodelist_members_to_config(struct totem_config *totem_config, icm
 				continue;
 				continue;
 			}
 			}
 
 
+#ifdef ENABLE_UDPU
 			/* Generate nodeids if they are not provided and transport is UDP/U */
 			/* Generate nodeids if they are not provided and transport is UDP/U */
 			if (!nodeid &&
 			if (!nodeid &&
 			    (totem_config->transport_number == TOTEM_TRANSPORT_UDP ||
 			    (totem_config->transport_number == TOTEM_TRANSPORT_UDP ||
 			     totem_config->transport_number == TOTEM_TRANSPORT_UDPU)) {
 			     totem_config->transport_number == TOTEM_TRANSPORT_UDPU)) {
+				char *str;
+
 				snprintf(tmp_key, ICMAP_KEYNAME_MAXLEN, "nodelist.node.%u.ring0_addr", node_pos);
 				snprintf(tmp_key, ICMAP_KEYNAME_MAXLEN, "nodelist.node.%u.ring0_addr", node_pos);
 				if (icmap_get_string_r(map, tmp_key, &str) == CS_OK) {
 				if (icmap_get_string_r(map, tmp_key, &str) == CS_OK) {
 					nodeid = generate_nodeid(totem_config, str);
 					nodeid = generate_nodeid(totem_config, str);
@@ -1443,6 +1466,7 @@ static int put_nodelist_members_to_config(struct totem_config *totem_config, icm
 					(void)icmap_set_uint32_r(map, tmp_key, nodeid);
 					(void)icmap_set_uint32_r(map, tmp_key, nodeid);
 				}
 				}
 			}
 			}
+#endif
 
 
 			if (!nodeid && totem_config->transport_number == TOTEM_TRANSPORT_KNET) {
 			if (!nodeid && totem_config->transport_number == TOTEM_TRANSPORT_KNET) {
 				sprintf(error_string_response,
 				sprintf(error_string_response,
@@ -1554,7 +1578,6 @@ static int get_interface_params(struct totem_config *totem_config, icmap_map_t m
 	uint32_t u32;
 	uint32_t u32;
 	char *str;
 	char *str;
 	char *cluster_name = NULL;
 	char *cluster_name = NULL;
-	enum totem_ip_version_enum tmp_ip_version = TOTEM_IP_VERSION_4;
 	int ret = 0;
 	int ret = 0;
 
 
 	if (reload) {
 	if (reload) {
@@ -1582,9 +1605,11 @@ static int get_interface_params(struct totem_config *totem_config, icmap_map_t m
 			continue;
 			continue;
 		}
 		}
 
 
+#ifdef ENABLE_UDPU
 		if (strcmp(tmp_key, "bindnetaddr") != 0 && totem_config->transport_number == TOTEM_TRANSPORT_UDP) {
 		if (strcmp(tmp_key, "bindnetaddr") != 0 && totem_config->transport_number == TOTEM_TRANSPORT_UDP) {
 			continue;
 			continue;
 		}
 		}
+#endif
 
 
 		member_count = 0;
 		member_count = 0;
 		linknumber = atoi(linknumber_key);
 		linknumber = atoi(linknumber_key);
@@ -1640,13 +1665,16 @@ static int get_interface_params(struct totem_config *totem_config, icmap_map_t m
 				}
 				}
 
 
 				free(str);
 				free(str);
-			} else if (totem_config->transport_number == TOTEM_TRANSPORT_UDP) {
+			}
+#ifdef ENABLE_UDPU
+			else if (totem_config->transport_number == TOTEM_TRANSPORT_UDP) {
 				/*
 				/*
 				 * User not specified address -> autogenerate one from cluster_name key
 				 * User not specified address -> autogenerate one from cluster_name key
 				 * (if available). Return code is intentionally ignored, because
 				 * (if available). Return code is intentionally ignored, because
 				 * udpu doesn't need mcastaddr and validity of mcastaddr for udp is
 				 * udpu doesn't need mcastaddr and validity of mcastaddr for udp is
 				 * checked later anyway.
 				 * checked later anyway.
 				 */
 				 */
+				enum totem_ip_version_enum tmp_ip_version = TOTEM_IP_VERSION_4;
 
 
 				if (totem_config->interfaces[0].bindnet.family == AF_INET) {
 				if (totem_config->interfaces[0].bindnet.family == AF_INET) {
 					tmp_ip_version = TOTEM_IP_VERSION_4;
 					tmp_ip_version = TOTEM_IP_VERSION_4;
@@ -1659,6 +1687,7 @@ static int get_interface_params(struct totem_config *totem_config, icmap_map_t m
 							      tmp_ip_version,
 							      tmp_ip_version,
 							      &totem_config->interfaces[linknumber].mcast_addr);
 							      &totem_config->interfaces[linknumber].mcast_addr);
 			}
 			}
+#endif
 
 
 			snprintf(tmp_key, ICMAP_KEYNAME_MAXLEN, "totem.interface.%u.broadcast", linknumber);
 			snprintf(tmp_key, ICMAP_KEYNAME_MAXLEN, "totem.interface.%u.broadcast", linknumber);
 			if (icmap_get_string(tmp_key, &str) == CS_OK) {
 			if (icmap_get_string(tmp_key, &str) == CS_OK) {
@@ -1801,7 +1830,6 @@ extern int totem_config_read (
 	int res = 0;
 	int res = 0;
 	char *str, *ring0_addr_str;
 	char *str, *ring0_addr_str;
 	char tmp_key[ICMAP_KEYNAME_MAXLEN];
 	char tmp_key[ICMAP_KEYNAME_MAXLEN];
-	uint16_t u16;
 	int i;
 	int i;
 	int local_node_pos;
 	int local_node_pos;
 	uint32_t u32;
 	uint32_t u32;
@@ -1817,14 +1845,21 @@ extern int totem_config_read (
 
 
 	totem_config->transport_number = TOTEM_TRANSPORT_KNET;
 	totem_config->transport_number = TOTEM_TRANSPORT_KNET;
 	if (icmap_get_string("totem.transport", &str) == CS_OK) {
 	if (icmap_get_string("totem.transport", &str) == CS_OK) {
+#ifdef ENABLE_UDPU
 		if (strcmp (str, "udpu") == 0) {
 		if (strcmp (str, "udpu") == 0) {
 			totem_config->transport_number = TOTEM_TRANSPORT_UDPU;
 			totem_config->transport_number = TOTEM_TRANSPORT_UDPU;
 		} else if (strcmp (str, "udp") == 0) {
 		} else if (strcmp (str, "udp") == 0) {
 			totem_config->transport_number = TOTEM_TRANSPORT_UDP;
 			totem_config->transport_number = TOTEM_TRANSPORT_UDP;
-		} else if (strcmp (str, "knet") == 0) {
+		} else
+#endif
+		if (strcmp (str, "knet") == 0) {
 			totem_config->transport_number = TOTEM_TRANSPORT_KNET;
 			totem_config->transport_number = TOTEM_TRANSPORT_KNET;
 		} else {
 		} else {
+#ifdef ENABLE_UDPU
 			*error_string = "Invalid transport type. Should be udpu, udp or knet";
 			*error_string = "Invalid transport type. Should be udpu, udp or knet";
+#else
+			*error_string = "Invalid transport type. Should be knet";
+#endif
 		        free(str);
 		        free(str);
 			return -1;
 			return -1;
 		}
 		}
@@ -1922,10 +1957,13 @@ extern int totem_config_read (
 	totem_config->ip_dscp = 0;
 	totem_config->ip_dscp = 0;
 	(void)icmap_get_uint8("totem.ip_dscp", &totem_config->ip_dscp);
 	(void)icmap_get_uint8("totem.ip_dscp", &totem_config->ip_dscp);
 
 
+#ifdef ENABLE_UDPU
 	/*
 	/*
 	 * Store automatically generated items back to icmap only for UDP
 	 * Store automatically generated items back to icmap only for UDP
 	 */
 	 */
 	if (totem_config->transport_number == TOTEM_TRANSPORT_UDP) {
 	if (totem_config->transport_number == TOTEM_TRANSPORT_UDP) {
+		uint16_t u16;
+
 		for (i = 0; i < INTERFACE_MAX; i++) {
 		for (i = 0; i < INTERFACE_MAX; i++) {
 			if (!totem_config->interfaces[i].configured) {
 			if (!totem_config->interfaces[i].configured) {
 				continue;
 				continue;
@@ -1944,6 +1982,7 @@ extern int totem_config_read (
 			}
 			}
 		}
 		}
 	}
 	}
+#endif
 
 
 	/*
 	/*
 	 * Store mcastport value to cmap runtime section for KNET
 	 * Store mcastport value to cmap runtime section for KNET
@@ -1981,6 +2020,7 @@ extern int totem_config_read (
 				return -1;
 				return -1;
 			}
 			}
 
 
+#ifdef ENABLE_UDPU
 			if ((totem_config->transport_number == TOTEM_TRANSPORT_UDP ||
 			if ((totem_config->transport_number == TOTEM_TRANSPORT_UDP ||
 			     totem_config->transport_number == TOTEM_TRANSPORT_UDPU) && (!totem_config->node_id)) {
 			     totem_config->transport_number == TOTEM_TRANSPORT_UDPU) && (!totem_config->node_id)) {
 
 
@@ -1999,6 +2039,7 @@ extern int totem_config_read (
 
 
 				free(str);
 				free(str);
 			}
 			}
+#endif
 
 
 			/* Users must not change this */
 			/* Users must not change this */
 			icmap_set_ro_access("nodelist.local_node_pos", 0, 1);
 			icmap_set_ro_access("nodelist.local_node_pos", 0, 1);
@@ -2066,6 +2107,7 @@ int totem_config_validate (
 
 
 		memset (&null_addr, 0, sizeof (struct totem_ip_address));
 		memset (&null_addr, 0, sizeof (struct totem_ip_address));
 
 
+#ifdef ENABLE_UDPU
 		if ((totem_config->transport_number == TOTEM_TRANSPORT_UDP) &&
 		if ((totem_config->transport_number == TOTEM_TRANSPORT_UDP) &&
 			memcmp (&totem_config->interfaces[i].mcast_addr, &null_addr,
 			memcmp (&totem_config->interfaces[i].mcast_addr, &null_addr,
 				sizeof (struct totem_ip_address)) == 0) {
 				sizeof (struct totem_ip_address)) == 0) {
@@ -2073,6 +2115,7 @@ int totem_config_validate (
 					"No multicast address specified for interface %u", i);
 					"No multicast address specified for interface %u", i);
 			goto parse_error;
 			goto parse_error;
 		}
 		}
+#endif
 
 
 		if (totem_config->interfaces[i].ip_port == 0) {
 		if (totem_config->interfaces[i].ip_port == 0) {
 		        snprintf (local_error_reason, sizeof(local_error_reason),
 		        snprintf (local_error_reason, sizeof(local_error_reason),
@@ -2085,8 +2128,12 @@ int totem_config_validate (
 					"Invalid TTL (should be 0..255) for interface %u", i);
 					"Invalid TTL (should be 0..255) for interface %u", i);
 			goto parse_error;
 			goto parse_error;
 		}
 		}
+#ifdef ENABLE_UDPU
 		if (totem_config->transport_number != TOTEM_TRANSPORT_UDP &&
 		if (totem_config->transport_number != TOTEM_TRANSPORT_UDP &&
 		    totem_config->interfaces[i].ttl != 1) {
 		    totem_config->interfaces[i].ttl != 1) {
+#else
+		if (totem_config->interfaces[i].ttl != 1) {
+#endif
 		        snprintf (local_error_reason, sizeof(local_error_reason),
 		        snprintf (local_error_reason, sizeof(local_error_reason),
 					"Can only set ttl on multicast transport types for interface %u", i);
 					"Can only set ttl on multicast transport types for interface %u", i);
 			goto parse_error;
 			goto parse_error;
@@ -2110,6 +2157,7 @@ int totem_config_validate (
 			goto parse_error;
 			goto parse_error;
 		}
 		}
 
 
+#ifdef ENABLE_UDPU
 		if (totem_config->broadcast_use == 0 && totem_config->transport_number == TOTEM_TRANSPORT_UDP) {
 		if (totem_config->broadcast_use == 0 && totem_config->transport_number == TOTEM_TRANSPORT_UDP) {
 			if (totem_config->interfaces[i].mcast_addr.family != totem_config->interfaces[i].bindnet.family) {
 			if (totem_config->interfaces[i].mcast_addr.family != totem_config->interfaces[i].bindnet.family) {
 				snprintf (local_error_reason, sizeof(local_error_reason),
 				snprintf (local_error_reason, sizeof(local_error_reason),
@@ -2123,6 +2171,7 @@ int totem_config_validate (
 				goto parse_error;
 				goto parse_error;
 			}
 			}
 		}
 		}
+#endif
 	}
 	}
 
 
 	if (totem_config->version != 2) {
 	if (totem_config->version != 2) {

+ 11 - 1
exec/totemnet.c

@@ -37,8 +37,10 @@
 
 
 #include <assert.h>
 #include <assert.h>
 
 
+#ifdef ENABLE_UDPU
 #include <totemudp.h>
 #include <totemudp.h>
 #include <totemudpu.h>
 #include <totemudpu.h>
+#endif
 #include <totemknet.h>
 #include <totemknet.h>
 #include <totemnet.h>
 #include <totemnet.h>
 #include <qb/qbloop.h>
 #include <qb/qbloop.h>
@@ -168,6 +170,7 @@ struct transport {
 };
 };
 
 
 struct transport transport_entries[] = {
 struct transport transport_entries[] = {
+#ifdef ENABLE_UDPU
 	{
 	{
 		.name = "UDP/IP Multicast",
 		.name = "UDP/IP Multicast",
 		.initialize = totemudp_initialize,
 		.initialize = totemudp_initialize,
@@ -218,6 +221,14 @@ struct transport transport_entries[] = {
 		.reconfigure = totemudpu_reconfigure,
 		.reconfigure = totemudpu_reconfigure,
 		.crypto_reconfigure_phase = NULL
 		.crypto_reconfigure_phase = NULL
 	},
 	},
+#else
+	{
+		.name = "UDP/IP Multicast (disabled - expect crash)",
+	},
+	{
+		.name = "UDP/IP Unicast (disabled - expect crash)",
+	},
+#endif
 	{
 	{
 		.name = "Kronosnet",
 		.name = "Kronosnet",
 		.initialize = totemknet_initialize,
 		.initialize = totemknet_initialize,
@@ -280,7 +291,6 @@ static void totemnet_instance_initialize (
 	instance->totemnet_log_printf = config->totem_logging_configuration.log_printf;
 	instance->totemnet_log_printf = config->totem_logging_configuration.log_printf;
 	instance->totemnet_subsys_id = config->totem_logging_configuration.log_subsys_id;
 	instance->totemnet_subsys_id = config->totem_logging_configuration.log_subsys_id;
 
 
-
 	transport = config->transport_number;
 	transport = config->transport_number;
 
 
 	log_printf (LOGSYS_LEVEL_NOTICE,
 	log_printf (LOGSYS_LEVEL_NOTICE,

+ 6 - 0
include/corosync/totem/totem.h

@@ -139,6 +139,12 @@ enum {
 
 
 enum { TOTEM_LINK_MODE_BYTES = 64 };
 enum { TOTEM_LINK_MODE_BYTES = 64 };
 
 
+
+/*
+ * Keep compatibility with old applications. For Corosync 4.0, remove
+ * TOTEM_TRANSPORT_UDP/TOTEM_TRANSPORT_UDPU, set TOTEM_TRANSPORT_KNET to 1
+ * and change totemnet.c
+ */
 typedef enum {
 typedef enum {
 	TOTEM_TRANSPORT_UDP = 0,
 	TOTEM_TRANSPORT_UDP = 0,
 	TOTEM_TRANSPORT_UDPU = 1,
 	TOTEM_TRANSPORT_UDPU = 1,

+ 22 - 12
man/corosync.conf.5

@@ -1,6 +1,6 @@
 .\"/*
 .\"/*
 .\" * Copyright (c) 2005 MontaVista Software, Inc.
 .\" * Copyright (c) 2005 MontaVista Software, Inc.
-.\" * Copyright (c) 2006-2025 Red Hat, Inc.
+.\" * Copyright (c) 2006-2026 Red Hat, Inc.
 .\" *
 .\" *
 .\" * All rights reserved.
 .\" * All rights reserved.
 .\" *
 .\" *
@@ -32,7 +32,7 @@
 .\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 .\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 .\" * THE POSSIBILITY OF SUCH DAMAGE.
 .\" * THE POSSIBILITY OF SUCH DAMAGE.
 .\" */
 .\" */
-.TH COROSYNC_CONF 5 2025-06-12 "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+.TH COROSYNC_CONF 5 2026-04-07 "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
 .SH NAME
 .SH NAME
 corosync.conf - corosync executive configuration file
 corosync.conf - corosync executive configuration file
 
 
@@ -68,11 +68,20 @@ nozzle { }
 This top level directive contains configuration options for a libnozzle device.
 This top level directive contains configuration options for a libnozzle device.
 
 
 .PP
 .PP
-Corosync supports multiple types of network transports for communication between the nodes in the cluster. There are three types of transports:
+Corosync uses KNET as the standard network transport for communication
+between nodes in the cluster. Legacy unencrypted transports are strictly
+disabled in standard builds for security reasons.
 .RS
 .RS
 .IP 1.
 .IP 1.
-KNET. This is a default and recommended transport introduced in Corosync 3. It provides several advantages over the UDP and UDPU transports,
-including better performance, link-level redundancy, automatic link recovery, and native IP compression and encryption.
+KNET. This is a default and recommended transport introduced in Corosync 3.
+It provides several advantages over the UDP and UDPU transports,
+including better performance, link-level redundancy, automatic link recovery,
+and native IP compression and encryption.
+.RE
+
+Legacy unencrypted transports (available only for udpu builds; run
+`corosync -v` and check for "udpu" under "Built-in features"):
+.RS
 .IP 2.
 .IP 2.
 UDPU. This is for unicast communication. This transport is deprecated.
 UDPU. This is for unicast communication. This transport is deprecated.
 .IP 3.
 .IP 3.
@@ -241,20 +250,21 @@ The default is nss.
 .TP
 .TP
 crypto_hash
 crypto_hash
 This specifies which HMAC authentication should be used to authenticate all
 This specifies which HMAC authentication should be used to authenticate all
-messages. Valid values are none (no authentication), md5, sha1, sha256,
-sha384 and sha512. Encrypted transmission is only supported for
-the KNET transport.
+messages. Valid values are md5, sha1, sha256, sha384, sha512 and
+(for unencrypted builds only) none (no authentication). Encrypted transmission
+is only supported for the KNET transport.
 
 
-The default is none.
+The default is sha256 (none for unencrypted builds).
 
 
 .TP
 .TP
 crypto_cipher
 crypto_cipher
 This specifies which cipher should be used to encrypt all messages.
 This specifies which cipher should be used to encrypt all messages.
-Valid values are none (no encryption), aes256, aes192 and aes128.
+Valid values are aes256, aes192, aes128 and
+(for unencrypted builds only) also none (no encryption).
 Enabling crypto_cipher, requires also enabling of crypto_hash. Encrypted
 Enabling crypto_cipher, requires also enabling of crypto_hash. Encrypted
 transmission is only supported for the KNET transport.
 transmission is only supported for the KNET transport.
 
 
-The default is none.
+The default is aes256 (none for unencrypted builds).
 
 
 .TP
 .TP
 secauth
 secauth
@@ -262,7 +272,7 @@ This implies crypto_cipher=aes256 and crypto_hash=sha256, unless those options
 are explicitly set. Encrypted transmission is only supported for the KNET
 are explicitly set. Encrypted transmission is only supported for the KNET
 transport.
 transport.
 
 
-The default is off.
+The default is on (off for unencrypted builds).
 
 
 .TP
 .TP
 keyfile
 keyfile