Index: src/wp-admin/includes/network.php
===================================================================
--- src/wp-admin/includes/network.php	(revision 44358)
+++ src/wp-admin/includes/network.php	(working copy)
@@ -133,7 +133,11 @@
 
 	$hostname  = get_clean_basedomain();
 	$has_ports = strstr( $hostname, ':' );
-	if ( ( false !== $has_ports && ! in_array( $has_ports, array( ':80', ':443' ) ) ) ) {
+
+	/** This filter is documented in wp-includes/ms-settings.php */
+	$allowed_ports = apply_filters( 'allowed_multisite_ports', array( ':80', ':443' ) );
+
+	if ( ( false !== $has_ports && ! in_array( $has_ports, $allowed_ports ) ) ) {
 		echo '<div class="error"><p><strong>' . __( 'ERROR:' ) . '</strong> ' . __( 'You cannot install a network of sites with your server address.' ) . '</p></div>';
 		echo '<p>' . sprintf(
 			/* translators: %s: port number */
Index: src/wp-includes/ms-blogs.php
===================================================================
--- src/wp-includes/ms-blogs.php	(revision 44358)
+++ src/wp-includes/ms-blogs.php	(working copy)
@@ -902,6 +902,7 @@
 	// Sanitize domain if passed.
 	if ( array_key_exists( 'domain', $data ) ) {
 		$data['domain'] = trim( $data['domain'] );
+		$data['domain'] = preg_replace( '|:\d+$|', '', $data['domain'] );
 		$data['domain'] = preg_replace( '/\s+/', '', sanitize_user( $data['domain'], true ) );
 		if ( is_subdomain_install() ) {
 			$data['domain'] = str_replace( '@', '', $data['domain'] );
Index: src/wp-includes/ms-settings.php
===================================================================
--- src/wp-includes/ms-settings.php	(revision 44358)
+++ src/wp-includes/ms-settings.php	(working copy)
@@ -55,12 +55,22 @@
 if ( ! isset( $current_site ) || ! isset( $current_blog ) ) {
 
 	$domain = strtolower( stripslashes( $_SERVER['HTTP_HOST'] ) );
-	if ( substr( $domain, -3 ) == ':80' ) {
-		$domain               = substr( $domain, 0, -3 );
-		$_SERVER['HTTP_HOST'] = substr( $_SERVER['HTTP_HOST'], 0, -3 );
-	} elseif ( substr( $domain, -4 ) == ':443' ) {
-		$domain               = substr( $domain, 0, -4 );
-		$_SERVER['HTTP_HOST'] = substr( $_SERVER['HTTP_HOST'], 0, -4 );
+
+	/**
+	 * Filters allowed HTTP ports in Multisite.
+	 *
+	 * @since 5.1.0
+	 *
+	 * @param array $allowed_ports The allowed ports. Default is [ ':80', ':443' ].
+	 */
+	$allowed_ports = apply_filters( 'allowed_multisite_ports', array( ':80', ':443' ) );
+
+	foreach ( $allowed_ports as $allowed_port ) {
+		$str_length = strlen( $allowed_port );
+		if ( substr( $domain, -$str_length ) == $allowed_port ) {
+			$domain               = substr( $domain, 0, -$str_length );
+			$_SERVER['HTTP_HOST'] = substr( $_SERVER['HTTP_HOST'], 0, -$str_length);
+		}
 	}
 
 	$path = stripslashes( $_SERVER['REQUEST_URI'] );
Index: tests/phpunit/tests/multisite/site.php
===================================================================
--- tests/phpunit/tests/multisite/site.php	(revision 44358)
+++ tests/phpunit/tests/multisite/site.php	(working copy)
@@ -1370,6 +1370,25 @@
 						'lang_id'  => 1,
 					),
 				),
+				array(
+					array(
+						'domain'     => 'example.com:443',
+					),
+					array(
+						'domain'     => 'example.com',
+						'path'       => '/',
+					),
+				),
+				array(
+					array(
+						'domain'     => 'example.com:80',
+						'path'       => '/foo',
+					),
+					array(
+						'domain'     => 'example.com',
+						'path'       => '/foo/',
+					),
+				),
 			);
 		}
 
