Browse Source

Disable stun backward compatibility

Mészáros Mihály 4 years ago
parent
commit
54ef051844

+ 5 - 1
ChangeLog

@@ -22,7 +22,11 @@ Version 4.5.3 'dan Eider':
 	- merge PR #739 (by hills)
 		* SSL reload has hidden bugs which cause crashes
 	- Fix regression in PR #739
-	- Add option to disable RFC8750
+	- Try to mitigate amplification attatck 
+		* Add option --no-rfc5780
+		  to force disable RFC8750
+		* Add new option --no-stun-backward-compatibility
+		  Disable handling old STUN Binding requests and disable MAPPED-ADDRESS attribute in binding response (use only the XOR-MAPPED-ADDRESS).
 
 10/01/2021 Oleg Moskalenko <[email protected]> Mihály Mészáros <[email protected]>
 Version 4.5.2 'dan Eider':

+ 1 - 0
README.turnserver

@@ -615,6 +615,7 @@ Options with values:
                     This option disables this original behavior, because the NAT behavior discovery
                     adds attributes to response, and this increase the possibility of an amplification attack.
                     Strongly encouraged to use this option to decrease gain factor in STUN binding responses.
+--no-stun-backward-compatibility		Disable handling old STUN Binding requests and disable MAPPED-ADDRESS attribute in binding response (use only the XOR-MAPPED-ADDRESS).
 					
 
 ==================================

+ 8 - 0
examples/etc/turnserver.conf

@@ -773,3 +773,11 @@
 #
 no-rfc5780
 
+# Disable handling old STUN Binding requests and disable MAPPED-ADDRESS
+# attribute in binding response (use only the XOR-MAPPED-ADDRESS).
+#
+# Strongly encouraged to use this option to decrease gain factor in STUN
+# binding responses.
+#
+no-stun-backward-compatibility
+

+ 1 - 1
src/apps/common/stun_buffer.c

@@ -239,7 +239,7 @@ int stun_set_binding_response(stun_buffer* buf, stun_tid* tid,
 			      const ioa_addr *reflexive_addr, int error_code, const uint8_t *reason) {
   return stun_set_binding_response_str(buf->buf, (size_t*)(&(buf->len)), tid, 
 				       reflexive_addr, error_code, reason,
-				       0,0);
+				       0,0,1);
 }
 
 void stun_prepare_binding_request(stun_buffer* buf) {

+ 10 - 2
src/apps/relay/mainrelay.c

@@ -186,7 +186,8 @@ ALLOCATION_DEFAULT_ADDRESS_FAMILY_IPV4,  /* allocation_default_address_family */
 0,  /* no_dynamic_ip_list */
 0,  /* no_dynamic_realms */
 
-0  /* log_binding */
+0,  /* log_binding */
+0,	/* no_stun_backward_compatibility */
 };
 
 //////////////// OpenSSL Init //////////////////////
@@ -696,6 +697,8 @@ static char Usage[] = "Usage: turnserver [options]\n"
 "						This option disables this original behavior, because the NAT behavior discovery\n"
 "						adds attributes to response, and this increase the possibility of an amplification attack.\n"
 "						Strongly encouraged to use this option to decrease gain factor in STUN binding responses.\n"
+" --no-stun-backward-compatibility		Disable handling old STUN Binding requests and disable MAPPED-ADDRESS attribute\n"
+"						in binding response (use only the XOR-MAPPED-ADDRESS).\n"
 " -h						Help\n"
 "\n";
 
@@ -842,7 +845,8 @@ enum EXTRA_OPTS {
 	SECRET_KEY_OPT,
 	ACME_REDIRECT_OPT,
 	LOG_BINDING_OPT,
-	NO_RFC5780
+	NO_RFC5780,
+	NO_STUN_BACKWARD_COMPATIBILITY_OPT
 };
 
 struct myoption {
@@ -980,6 +984,7 @@ static const struct myoption long_options[] = {
 				{ "acme-redirect", required_argument, NULL, ACME_REDIRECT_OPT },
 				{ "log-binding", optional_argument, NULL, LOG_BINDING_OPT },
 				{ "no-rfc5780", optional_argument, NULL, NO_RFC5780 },
+				{ "no-stun-backward-compatibility", optional_argument, NULL, NO_STUN_BACKWARD_COMPATIBILITY_OPT },
 				{ NULL, no_argument, NULL, 0 }
 };
 
@@ -1656,6 +1661,9 @@ static void set_option(int c, char *value)
 	case NO_RFC5780:
 		turn_params.rfc5780 = 0;
 		break;
+	case NO_STUN_BACKWARD_COMPATIBILITY_OPT:
+		turn_params.no_stun_backward_compatibility = get_bool_value(value);
+		break;
 
 	/* these options have been already taken care of before: */
 	case 'l':

+ 1 - 0
src/apps/relay/mainrelay.h

@@ -339,6 +339,7 @@ typedef struct _turn_params_ {
   int no_dynamic_realms;
 
   vint log_binding;
+  vint no_stun_backward_compatibility;
 } turn_params_t;
 
 extern turn_params_t turn_params;

+ 37 - 35
src/apps/relay/netengine.c

@@ -1660,41 +1660,43 @@ static void setup_relay_server(struct relay_server *rs, ioa_engine_handle e, int
 	bufferevent_enable(rs->auth_in_buf, EV_READ);
 
 	init_turn_server(&(rs->server),
-			 rs->id, turn_params.verbose,
-			 rs->ioa_eng, turn_params.ct, 0,
-			 turn_params.fingerprint, DONT_FRAGMENT_SUPPORTED,
-			 start_user_check,
-			 check_new_allocation_quota,
-			 release_allocation_quota,
-			 turn_params.external_ip,
-			 &turn_params.check_origin,
-			 &turn_params.no_tcp_relay,
-			 &turn_params.no_udp_relay,
-			 &turn_params.stale_nonce,
-			 &turn_params.max_allocate_lifetime,
-			 &turn_params.channel_lifetime,
-			 &turn_params.permission_lifetime,
-			 &turn_params.stun_only,
-			 &turn_params.no_stun,
-			 &turn_params.no_software_attribute,
-			 &turn_params.web_admin_listen_on_workers,
-			 &turn_params.alternate_servers_list,
-			 &turn_params.tls_alternate_servers_list,
-			 &turn_params.aux_servers_list,
-			 turn_params.udp_self_balance,
-			 &turn_params.no_multicast_peers, &turn_params.allow_loopback_peers,
-			 &turn_params.ip_whitelist, &turn_params.ip_blacklist,
-			 send_socket_to_relay,
-			 &turn_params.secure_stun, &turn_params.mobility,
-			 turn_params.server_relay,
-			 send_turn_session_info,
-			 send_https_socket,
-			 allocate_bps,
-			 turn_params.oauth,
-			 turn_params.oauth_server_name,
-			 turn_params.acme_redirect,
-			 turn_params.allocation_default_address_family,
-			 &turn_params.log_binding);
+		rs->id, turn_params.verbose,
+		rs->ioa_eng, turn_params.ct, 0,
+		turn_params.fingerprint, DONT_FRAGMENT_SUPPORTED,
+		start_user_check,
+		check_new_allocation_quota,
+		release_allocation_quota,
+		turn_params.external_ip,
+		&turn_params.check_origin,
+		&turn_params.no_tcp_relay,
+		&turn_params.no_udp_relay,
+		&turn_params.stale_nonce,
+		&turn_params.max_allocate_lifetime,
+		&turn_params.channel_lifetime,
+		&turn_params.permission_lifetime,
+		&turn_params.stun_only,
+		&turn_params.no_stun,
+		&turn_params.no_software_attribute,
+		&turn_params.web_admin_listen_on_workers,
+		&turn_params.alternate_servers_list,
+		&turn_params.tls_alternate_servers_list,
+		&turn_params.aux_servers_list,
+		turn_params.udp_self_balance,
+		&turn_params.no_multicast_peers, &turn_params.allow_loopback_peers,
+		&turn_params.ip_whitelist, &turn_params.ip_blacklist,
+		send_socket_to_relay,
+		&turn_params.secure_stun, &turn_params.mobility,
+		turn_params.server_relay,
+		send_turn_session_info,
+		send_https_socket,
+		allocate_bps,
+		turn_params.oauth,
+		turn_params.oauth_server_name,
+		turn_params.acme_redirect,
+		turn_params.allocation_default_address_family,
+		&turn_params.log_binding,
+		&turn_params.no_stun_backward_compatibility
+		);
 	
 	if(to_set_rfc5780) {
 		set_rfc5780(&(rs->server), get_alt_addr, send_message_from_listener_to_client);

+ 1 - 1
src/client++/TurnMsgLib.h

@@ -989,7 +989,7 @@ public:
 
 		stun_set_binding_response_str(_buffer, &_sz, &tid,
 					&reflexive_addr, error_code,
-					reason, 0 , 0);
+					reason, 0 , 0 , 1);
 	}
 
 	bool isBindingResponse() const {

+ 2 - 2
src/client/ns_turn_msg.c

@@ -1140,7 +1140,7 @@ void stun_set_binding_request_str(uint8_t* buf, size_t *len) {
 
 int stun_set_binding_response_str(uint8_t* buf, size_t *len, stun_tid* tid, 
 				  const ioa_addr *reflexive_addr, int error_code, const uint8_t *reason,
-				  uint32_t cookie, int old_stun)
+				  uint32_t cookie, int old_stun, int no_stun_backward_compatibility)
 
 {
 	if (!error_code) {
@@ -1154,7 +1154,7 @@ int stun_set_binding_response_str(uint8_t* buf, size_t *len, stun_tid* tid,
 				return -1;
 		}
 		if(reflexive_addr) {
-			if (stun_attr_add_addr_str(buf, len, STUN_ATTRIBUTE_MAPPED_ADDRESS, reflexive_addr) < 0)
+			if (!no_stun_backward_compatibility && stun_attr_add_addr_str(buf, len, STUN_ATTRIBUTE_MAPPED_ADDRESS, reflexive_addr) < 0)
 				return -1;
 		}
 	} else if (!old_stun) {

+ 1 - 1
src/client/ns_turn_msg.h

@@ -124,7 +124,7 @@ void stun_set_binding_request_str(uint8_t* buf, size_t *len);
 int stun_set_binding_response_str(uint8_t* buf, size_t *len, stun_tid* tid, 
 				  const ioa_addr *reflexive_addr, int error_code,
 				  const uint8_t *reason,
-				  uint32_t cookie, int old_stun);
+				  uint32_t cookie, int old_stun, int no_stun_backward_compatibility);
 int stun_is_binding_request_str(const uint8_t* buf, size_t len, size_t offset);
 int stun_is_binding_response_str(const uint8_t* buf, size_t len);
 

+ 10 - 3
src/server/ns_turn_server.c

@@ -2867,7 +2867,7 @@ static int handle_turn_binding(turn_turnserver *server,
 
 		size_t len = ioa_network_buffer_get_size(nbh);
 		if (stun_set_binding_response_str(ioa_network_buffer_data(nbh), &len, tid,
-					get_remote_addr_from_ioa_socket(ss->client_socket), 0, NULL, cookie, old_stun) >= 0) {
+					get_remote_addr_from_ioa_socket(ss->client_socket), 0, NULL, cookie, old_stun, *server->no_stun_backward_compatibility) >= 0) {
 
 			addr_cpy(response_origin, get_local_addr_from_ioa_socket(ss->client_socket));
 
@@ -4606,7 +4606,11 @@ static int read_client_connection(turn_turnserver *server,
 			return 0;
 		}
 
-	} else if (old_stun_is_command_message_str(ioa_network_buffer_data(in_buffer->nbh), ioa_network_buffer_get_size(in_buffer->nbh), &old_stun_cookie) && !(*(server->no_stun))) {
+	} else if (
+		old_stun_is_command_message_str(ioa_network_buffer_data(in_buffer->nbh), ioa_network_buffer_get_size(in_buffer->nbh), &old_stun_cookie) &&
+		!(*(server->no_stun)) &&
+		!(*(server->no_stun_backward_compatibility))
+	) {
 
 		ioa_network_buffer_handle nbh = ioa_network_buffer_allocate(server->e);
 		int resp_constructed = 0;
@@ -4932,7 +4936,8 @@ void init_turn_server(turn_turnserver* server,
 		const char* oauth_server_name,
 		const char* acme_redirect,
 		ALLOCATION_DEFAULT_ADDRESS_FAMILY allocation_default_address_family,
-		vintp log_binding) {
+		vintp log_binding,
+		vintp no_stun_backward_compatibility) {
 
 	if (!server)
 		return;
@@ -5006,6 +5011,8 @@ void init_turn_server(turn_turnserver* server,
 	set_ioa_timer(server->e, 1, 0, timer_timeout_handler, server, 1, "timer_timeout_handler");
 
 	server->log_binding = log_binding;
+
+	server->no_stun_backward_compatibility = no_stun_backward_compatibility;
 }
 
 ioa_engine_handle turn_server_get_engine(turn_turnserver *s) {

+ 6 - 1
src/server/ns_turn_server.h

@@ -187,6 +187,9 @@ struct _turn_turnserver {
 
 	/* Log Binding Requrest */
 	vintp log_binding;
+
+	/* Disable handling old STUN Binding Requests and disable MAPPED-ADDRESS attribute in response */
+	vintp no_stun_backward_compatibility;
 };
 
 const char * get_version(turn_turnserver *server);
@@ -234,7 +237,9 @@ void init_turn_server(turn_turnserver* server,
 				    const char* oauth_server_name,
 					const char* acme_redirect,
 					ALLOCATION_DEFAULT_ADDRESS_FAMILY allocation_default_address_family,
-					vintp log_binding);
+					vintp log_binding,
+					vintp no_stun_backward_compatibility
+					);
 
 ioa_engine_handle turn_server_get_engine(turn_turnserver *s);