RFC 6056

Recommendations for Transport-Protocol Port Randomization

๐Ÿ“… published January 2011, from ietf

Internet Engineering Task Force (IETF) ๐ŸŽ€ RFC 6056: Recommendations for Transport-Protocol Port Randomization โœจ

Okay bestie, let's get into this! ๐Ÿ’– This one is a Best Current Practice (BCP 156), so it's the community's official "here's how to do it well" doc, not a strict must-do-or-else spec. It was written by M. Larsen (Tieto) and F. Gont (UTN/FRH) and published in January 2011. It's on the ISSN 2070-1721 track ๐ŸŒธ. It doesn't obsolete or update any other RFCs, so it's a fresh, standalone vibe ๐Ÿงš.

Part 1 covers the abstract, the boring-but-important legal and status stuff, the table of contents, and the intro. Let's go! ๐Ÿฆ‹


Abstract ๐Ÿ’œ

Okay so, in the last few years, people started noticing a bunch of "blind" attacks that can hit TCP and similar protocols. ๐Ÿ˜ญ These attacks can slow your throughput down, break your connections entirely, or even corrupt your data. Yikes! ๐Ÿ’€

These attacks depend on the attacker being able to guess or know the five-tuple (Protocol, Source Address, Destination Address, Source Port, Destination Port) that identifies the exact transport-protocol instance being attacked. ๐Ÿ”ฅ

So this doc describes some simple, efficient ways for a client to pick its port number, so the attacker has a much harder time guessing the exact value ๐ŸŽฏ. It's not a replacement for crypto protection, to be clear ๐Ÿซถ, but these port selection algorithms give you better security with basically no effort and no key management headaches ๐Ÿ’…. They're local policies you can roll out gradually, and they don't break the specs of the transport protocols that can use them: TCP, UDP, UDP-lite, SCTP, DCCP, and RTP (as long as the RTP app explicitly signals the RTP and RTCP port numbers) โœจ.


Status of This Memo ๐Ÿ“œ

This memo documents an Internet Best Current Practice ๐ŸŒˆ.

This is an IETF product, so it reflects the consensus of the IETF community. It got public review and was approved for publication by the Internet Engineering Steering Group (IESG). If you want more on BCPs, check Section 2 of RFC 5741 ๐Ÿ“.

For the current status of this doc, any errata, and how to give feedback, go to http://www.rfc-editor.org/info/rfc6056 ๐Ÿ’Œ.


Copyright (c) 2011 IETF Trust and the persons identified as the document authors. All rights reserved. ๐Ÿ”’

This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (http://trustee.ietf.org/license-info) as they were in effect on the publication date. Please actually read these, because they spell out your rights and restrictions ๐Ÿ™ˆ. Any Code Components pulled out of this document must include the Simplified BSD License text described in Section 4.e of the Trust Legal Provisions, and they come with no warranty, per the Simplified BSD License ๐Ÿ“.

This document may include material from IETF Documents or IETF Contributions published or made publicly available before November 10, 2008. The people who control the copyright in some of that material may not have given the IETF Trust permission to allow modifications outside the IETF Standards Process. So unless you get an adequate license from those copyright holders, this document may not be modified outside the IETF Standards Process, and derivative works may not be created outside it. The exception is formatting it for RFC publication or translating it into languages other than English ๐ŸŒธ.


Table of Contents ๐Ÿ—บ๏ธ

1.  Introduction . . . . . . . . . . . . . . . . . . . . . . . . .  4
2.  Ephemeral Ports  . . . . . . . . . . . . . . . . . . . . . . .  5
  2.1.  Traditional Ephemeral Port Range . . . . . . . . . . . . .  5
  2.2.  Ephemeral Port Selection . . . . . . . . . . . . . . . . .  6
  2.3.  Collision of instance-ids  . . . . . . . . . . . . . . . .  7
3.  Obfuscating the Ephemeral Port Selection . . . . . . . . . . .  8
  3.1.  Characteristics of a Good Algorithm for the
        Obfuscation of the Ephemeral Port Selection  . . . . . . .  8
  3.2.  Ephemeral Port Number Range  . . . . . . . . . . . . . . . 10
  3.3.  Algorithms for the Obfuscation of the Ephemeral Port
        Selection  . . . . . . . . . . . . . . . . . . . . . . . . 11
    3.3.1.  Algorithm 1: Simple Port Randomization Algorithm . . . 11
    3.3.2.  Algorithm 2: Another Simple Port Randomization
            Algorithm  . . . . . . . . . . . . . . . . . . . . . . 13
    3.3.3.  Algorithm 3: Simple Hash-Based Port Selection
            Algorithm  . . . . . . . . . . . . . . . . . . . . . . 14
    3.3.4.  Algorithm 4: Double-Hash Port Selection Algorithm  . . 16
    3.3.5.  Algorithm 5: Random-Increments Port Selection
            Algorithm  . . . . . . . . . . . . . . . . . . . . . . 18
  3.4.  Secret-Key Considerations for Hash-Based Port
        Selection Algorithms . . . . . . . . . . . . . . . . . . . 19
  3.5.  Choosing an Ephemeral Port Selection Algorithm . . . . . . 20
4.  Interaction with Network Address Port Translation (NAPT) . . . 22
5.  Security Considerations  . . . . . . . . . . . . . . . . . . . 23
6.  Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . 24
7.  References . . . . . . . . . . . . . . . . . . . . . . . . . . 24
  7.1.  Normative References . . . . . . . . . . . . . . . . . . . 24
  7.2.  Informative References . . . . . . . . . . . . . . . . . . 25
Appendix A.  Survey of the Algorithms in Use by Some Popular
             Implementations . . . . . . . . . . . . . . . . . . . 28
  A.1.  FreeBSD  . . . . . . . . . . . . . . . . . . . . . . . . . 28
  A.2.  Linux  . . . . . . . . . . . . . . . . . . . . . . . . . . 28
  A.3.  NetBSD . . . . . . . . . . . . . . . . . . . . . . . . . . 28
  A.4.  OpenBSD  . . . . . . . . . . . . . . . . . . . . . . . . . 28
  A.5.  OpenSolaris  . . . . . . . . . . . . . . . . . . . . . . . 28

1. Introduction ๐ŸŒท

Okay, so recently people have been noticing a bunch of "blind" attacks (meaning attacks that work without sniffing the packets of the transport-protocol instance being targeted) that can hit TCP [RFC0793] and similar protocols ๐Ÿ˜ค. The fallout ranges from throughput reduction to broken connections or data corruption [RFC5927] [RFC4953] [Watson] ๐Ÿ’€.

All of these attacks rely on the attacker guessing or knowing the five-tuple (Protocol, Source Address, Source Port, Destination Address, Destination Port) that identifies the transport-protocol instance being attacked ๐ŸŽฏ.

Services usually live at fixed, "well-known" ports [IANA] on the server host ๐Ÿ . Client apps connecting to one of these services contact the server by specifying its IP address and service port number. The client's own IP address and port are normally left unspecified by the app, so the client's networking stack picks them automatically ๐Ÿงš. Ports picked automatically by the stack are called ephemeral ports [Stevens] ๐Ÿฆ‹.

So the server IP address, the well-known port, and the client IP address may all be known to an attacker, but the client's ephemeral port is usually unknown and has to be guessed ๐Ÿ•ต๏ธโ€โ™€๏ธ.

This document describes a bunch of algorithms for picking ephemeral port numbers, so an off-path attacker is less likely to guess the exact value ๐ŸŽ€. These aren't a replacement for crypto protection like IPsec [RFC4301], the TCP MD5 signature option [RFC2385], or the TCP Authentication Option [RFC5925] ๐Ÿ”. For example, they don't help at all when the attacker can sniff the packets of the instance being attacked. Still, the algorithms give you better resistance to off-path attacks with very little effort and zero key management overhead โœจ.

The mechanisms here are local modifications that can be deployed gradually, and they don't violate the specs of any of the transport protocols that might use them: TCP [RFC0793], UDP [RFC0768], SCTP [RFC4960], DCCP [RFC4340], UDP-lite [RFC3828], and RTP [RFC3550] (as long as the RTP app explicitly signals the RTP and RTCP port numbers with, e.g., [RFC3605]) ๐ŸŒˆ.

Since these are obfuscation techniques, the focus is on finding a reasonable balance between how much obfuscation you get and how easy the thing is to implement ๐Ÿฐ. So the algorithms must be computationally efficient and must not require substantial state ๐Ÿ’….

Quick note ๐Ÿ“: the technique of defending against "blind" attacks by obfuscating ephemeral port selection is commonly called "port randomization". But the goal of the algorithms in this document is to reduce the chances of an attacker guessing the ephemeral ports chosen for new transport-protocol instances. It is not about actually producing mathematically random sequences of ports ๐Ÿ™Œ.

Throughout this doc, "transport-protocol instance" is the general term for an instance of a transport protocol (like a "connection" for connection-oriented protocols). "instance-id" is the short handle for the group of values that identify a transport-protocol instance. For TCP, that's the five-tuple {Protocol, IP Source Address, TCP Source Port, IP Destination Address, TCP Destination Port} ๐Ÿซง.

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 [RFC2119] ๐Ÿ‘‘.


Part 1 of 6. More parts coming, so stay tuned, bestie! ๐Ÿ’–

2.2. Ephemeral Port Selection โœจ

okay so every communication instance is identified by a five-tuple: {protocol, local IP address, local port, remote IP address, remote port} ๐Ÿ’– which means the ephemeral port picks have to result in a unique five-tuple every single time. that's the whole main character goal ๐Ÿ‘‘

some implementations handle this with a per-protocol global "next_ephemeral" variable that equals the previously chosen ephemeral port + 1. it's giving simple and classic, so here's how the selection goes ๐ŸŽ€

    /* Initialization at system boot time. Could be random */
    next_ephemeral = min_ephemeral;

    /* Ephemeral port selection function */
    count = max_ephemeral - min_ephemeral + 1;

    do {
        port = next_ephemeral;
        if (next_ephemeral == max_ephemeral) {
            next_ephemeral = min_ephemeral;
        } else {
            next_ephemeral++;
        }

        if (check_suitable_port(port))
            return port;

        count--;

    } while (count > 0);

    return ERROR;

Traditional BSD Port Selection Algorithm ๐ŸŒธ

Note: check_suitable_port() is a function that checks whether the resulting port number is acceptable as an ephemeral port. Basically it checks whether the resulting port number is unique, and it may also check that the port number isn't in use for a connection in the LISTEN or CLOSED states, and that it isn't in the list of port numbers that should not be allocated as ephemeral ports. In BSD-derived systems, check_suitable_port() would correspond to the in_pcblookup_local() function, where all the necessary checks would be performed. ๐Ÿงš

this algorithm works adequately as long as the number of transport-protocol instances (for each transport protocol) that have a lifetime longer than it takes to exhaust the total ephemeral port range is small, so that collisions of instance-ids are rare ๐Ÿ“

BUT (and this is a big but ๐Ÿ™ˆ) this method has a drawback. the "next_ephemeral" variable, and therefore the ephemeral port range, is shared between ALL transport-protocol instances, and the next ports chosen by the client are easy to predict ๐Ÿ˜ญ if an attacker runs an "innocent" server that the client connects to, it's super easy for them to get a reference point for the current value of the "next_ephemeral" variable. it gets worse too: if an attacker could force a client to periodically establish, e.g., a new TCP connection to an attacker-controlled machine (or through an attacker-observable path), the attacker could subtract consecutive source port values to work out the number of outgoing TCP connections established globally by the target host within that time period. (up to wrap-around issues and instance-id collisions, of course ๐Ÿ’€)

2.3. Collision of instance-ids ๐Ÿ’…

so while the ephemeral port selection algorithm can check that the selected port number gives an instance-id that isn't currently in use by that system, the resulting five-tuple might STILL be in use at a remote system ๐Ÿ˜ค for example, picture a client making a TCP connection with a remote web server, where the web server does the active close on the connection. the state info for this connection disappears on the client side (the connection gets moved to the fictional CLOSED state), but the instance-id stays in the TIME-WAIT state at the web server for 2*MSL (Maximum Segment Lifetime) โณ if that same client tries to make a new incarnation of the previous connection (a connection with the same instance-id as the one sitting in TIME_WAIT at the server), an instance-id "collision" happens. the effects of these collisions range from connection-establishment failures to TIME-WAIT state assassination (with the potential of data corruption) [RFC1337]. ๐Ÿ™ƒ when a specific client keeps establishing TCP connections with a specific service at a server, these problems become super evident. so an ephemeral port selection algorithm should ideally minimize the rate of instance-id collisions ๐Ÿซถ

a simple way to minimize the rate of these collisions would be to choose port numbers incrementally, so a given port number isn't reused until the rest of the port numbers in the ephemeral port range have been used for a transport protocol instance. HOWEVER, if a single global variable tracked the last ephemeral port selected, the ephemeral port numbers would be trivially predictable ๐Ÿ˜ฌ which makes it way easier for an off-path attacker to "guess" the instance-id in use by a target transport-protocol instance. Sections 3.3.3 and 3.3.4 describe algorithms that select port numbers incrementally while still making it difficult for an off-path attacker to predict the ephemeral ports used for future transport-protocol instances ๐Ÿ”

a simple but inefficient approach to minimize the rate of instance-id collisions would be, e.g., for TCP, having both endpoints of a TCP connection keep state about recent connections (e.g., have both endpoints end up in the TIME-WAIT state). ๐Ÿข


3. Obfuscating the Ephemeral Port Selection ๐Ÿฆ‹

3.1. Characteristics of a Good Algorithm for the Obfuscation of the Ephemeral Port Selection ๐Ÿ’œ

there are several factors to think about when designing an algorithm for selecting ephemeral ports, including:

  • Minimizing the predictability of the ephemeral port numbers used for future transport-protocol instances.
  • Minimizing collisions of instance-ids.
  • Avoiding conflict with applications that depend on the use of specific port numbers.

given the goal of improving the transport protocol's resistance to attack by obfuscating the instance-id selection, it's key to minimize how predictable the ephemeral ports are that get selected for new transport-protocol instances โœจ the obvious move would be to just pick a random value within the chosen port number range, but this straightforward policy may lead to instance-id collisions, which can cause the interoperability problems (e.g., delays in establishing new connections, failures in connection establishment, or data corruption) we talked about in Section 2.3. ๐Ÿ˜ฉ as mentioned in Section 1, the technique of mitigating "blind" attacks by obfuscating the ephemeral port selection is well-known as "port randomization." BUT the goal of the algorithms in this document is to reduce the chances that an attacker will guess the ephemeral ports selected for new transport-protocol instances, NOT to actually produce mathematically random ephemeral port numbers ๐ŸŽฒ (so no, it's not the same thing, bestie ๐Ÿ™…โ€โ™€๏ธ)

it's also worth noting that, provided adequate algorithms are in use, the larger the range ephemeral ports are selected from, the smaller the attacker's chances are of guessing the selected port number ๐Ÿ“ˆ

in scenarios where a specific client establishes transport-protocol instances with a specific service at a server, the problems described in Section 2.3 become evident. a good algorithm for minimizing instance-id collisions would consider the time a given five-tuple was last used, and would avoid reusing the least recently used five-tuples ๐Ÿ•ฐ๏ธ a simple approach to minimize the rate of collisions would be to choose port numbers incrementally, so a given port number isn't reused until the rest of the port numbers in the ephemeral port range have been used for a transport-protocol instance. however, if a single global variable were used to track the last ephemeral port selected, the ephemeral port numbers would be trivially predictable. ๐Ÿ™„

it's important to note that a bunch of applications rely on binding specific port numbers that might fall inside the ephemeral port range. if one of those applications ran while its port number was in use, the application would fail ๐Ÿ˜ฑ so ephemeral port selection algorithms avoid using those port numbers. ๐Ÿ›‘

port numbers that are currently in use by a TCP in the LISTEN state should not be allowed for use as ephemeral ports. if this rule isn't followed, an attacker could potentially "steal" an incoming connection to a local server application in at least two different ways ๐Ÿšจ

first, an attacker could send a connection request to the victim client at roughly the same time the client tries to connect to the victim server application [CPNI-TCP] [TCP-SEC]. if the SYN segment for the attacker's connection request and the SYN segment for the victim client "cross each other in the network," and the attacker can know or guess the ephemeral port the client used, a TCP "simultaneous open" scenario happens. the incoming connection request from the client then gets matched with the attacker's socket instead of the victim server application's socket ๐Ÿ˜ˆ

second, an attacker could specify a more specific socket than the "victim" socket (e.g., by specifying both the local IP address and the local TCP port). that way, incoming SYN segments matching the attacker's socket get delivered to the attacker, not the "victim" socket (see Section 10.1 of [CPNI-TCP]). ๐Ÿ•ต๏ธโ€โ™€๏ธ

it should be noted that most applications built on popular implementations of the TCP API (such as the Sockets API) do "passive opens" in three steps. ๐Ÿชœ first, the application gets a file descriptor for inter-process communication (e.g., by issuing a socket() call). second, the application binds the file descriptor to a local TCP port number (e.g., by issuing a bind() call), which creates a TCP in the fictional CLOSED state. third, that TCP is put in the LISTEN state (e.g., by issuing a listen() call).

so with this kind of TCP API implementation, even if port numbers in use by TCPs in the LISTEN state weren't allowed as ephemeral ports, there's a window of time between the second and third steps where an attacker could be allowed to select a port number that would later be used for listening to incoming connections ๐Ÿ˜ต therefore, these TCP API implementations should enforce a stricter requirement for allocating port numbers: port numbers that are in use by a TCP in the LISTEN or CLOSED states should not be allowed for allocation as ephemeral ports [CPNI-TCP] [TCP-SEC]. ๐Ÿ’…

the aforementioned issue doesn't affect SCTP, since most SCTP implementations don't let a socket be bound to the same port number unless a specific socket option (SCTP_REUSE_PORT) is issued on the socket (i.e., this behavior has to be explicitly allowed beforehand) ๐Ÿ™Œ an example of a typical SCTP socket API can be found in [SCTP-SOCKET]. ๐Ÿ“š

DCCP isn't affected by the exploitation of "simultaneous opens" to "steal" incoming connections, because the server and client state machines are different [RFC4340]. ๐Ÿ™†โ€โ™€๏ธ however, it may be affected by the vector involving binding a more specific socket. so those tuples {local IP address, local port, Service Code} that are in use by a local socket should not be allowed for allocation as ephemeral ports. ๐Ÿซง

3.2. Ephemeral Port Number Range โœจ

okay so, as we talked about in Section 2.1, the dynamic ports are the range 49152-65535 ๐Ÿ’– but ephemeral port selection algorithms should use the whole range 1024-65535 ๐ŸŽ€ that's the full glow-up, bestie.

this range includes the IANA Registered Ports ๐ŸŒธ so some of those port numbers might be needed to provide a particular service on the local host, and that could cause the problems we covered in Section 3.1 ๐Ÿ˜ญ which is why port numbers that might be needed for providing a particular service at the local host SHOULD NOT be included in the pool of port numbers available for ephemeral port randomization ๐Ÿ™ˆ if the host doesn't provide a particular service, though, the port can be safely given to ordinary processes ๐Ÿ’…

a possible workaround is to keep a local list of port numbers that should not be allocated as ephemeral ports ๐Ÿ“ before allocating a port number, the ephemeral port selection function checks this list, so it skips ports that specific applications might need ๐Ÿฆ‹ but don't just exclude every registered port, lol, that's lazy ๐Ÿ’€ administrators should figure out which services the local host may offer and SHOULD exclude only the corresponding registered ports ๐Ÿซถ

ephemeral port selection algorithms SHOULD use the largest possible port range, since this reduces the chances of an off-path attacker guessing the selected port numbers ๐Ÿ”ฅ big range, big protection, periodt ๐Ÿ‘‘

3.3. Algorithms for the Obfuscation of the Ephemeral Port Selection ๐Ÿงš

ephemeral port selection algorithms SHOULD obfuscate the selection of their ephemeral ports ๐Ÿ•ต๏ธโ€โ™€๏ธ this helps mitigate a bunch of attacks that depend on the attacker being able to guess or know the five-tuple that identifies the transport-protocol instance being attacked ๐Ÿ˜ฑ main character energy is hiding your port, no cap โœจ

the following subsections describe a few algorithms that could be implemented to obfuscate the selection of ephemeral port numbers ๐ŸŒˆ

3.3.1. Algorithm 1: Simple Port Randomization Algorithm ๐ŸŽฒ

okay so a bunch of systems have implemented simple ephemeral port number randomization to deal with the security issues from Sections 1 and 2.2 ๐Ÿ’œ it looks like this:

    /* Ephemeral port selection function */
    num_ephemeral = max_ephemeral - min_ephemeral + 1;
    next_ephemeral = min_ephemeral + (random() % num_ephemeral);
    count = num_ephemeral;

    do {
        if(check_suitable_port(port))
                return next_ephemeral;

        if (next_ephemeral == max_ephemeral) {
            next_ephemeral = min_ephemeral;
        } else {
            next_ephemeral++;
        }

        count--;
    } while (count > 0);

    return ERROR;

                           Algorithm 1

note: random() is a function that returns a 32-bit pseudo-random unsigned integer number ๐Ÿง  the output needs to be unpredictable, and typical implementations of the POSIX random() function don't necessarily meet that requirement ๐Ÿ™…โ€โ™€๏ธ see [RFC4086] for randomness requirements for security ๐Ÿ”

all the variables (in this and all the algorithms in this document) are unsigned integers ๐Ÿ”ข

so the initially chosen port might already be in use with the same IP addresses and server port that the socket needs ๐Ÿ˜ฌ which means the resulting five-tuple might not be unique ๐Ÿ’” so multiple ports may have to be tried and checked against all existing transport-protocol instances before a port can be chosen ๐Ÿ”

web proxy servers, Network Address Port Translators (NAPTs) [RFC2663], and other middleboxes squish multiple peers into the same port space ๐Ÿซ  that means more used ephemeral ports, and so more chances of instance-id collisions โš ๏ธ but [Allman] has shown that, at least in the network scenarios used to measure collision properties of the algorithms in this document, the collision rate from those middleboxes is still very low ๐Ÿฅนโœจ

since this algorithm picks ports without looking at the ports it picked before, it can reuse port numbers too quickly, which could lead to instance-id collisions ๐Ÿ’€ even if the port selection algorithm checks that an instance-id is unique, it might still be in use at the remote system ๐Ÿ“ก then a connection request could fail ([Silbersack] describes this problem for the TCP case) ๐Ÿ˜ค

but here's the tea ๐Ÿต this algorithm is biased towards the first available port after a run of unavailable port numbers ๐Ÿ‘€ if the local list of registered port numbers that shouldn't be allocated as ephemeral ports (from Section 3.2) is big, an attacker may have a much better shot at guessing a port number ๐Ÿ˜จ

on the bright side, this algorithm picks ephemeral port numbers randomly, so it lowers the chances that an attacker guesses the ephemeral port for a target transport-protocol instance ๐Ÿ›ก๏ธ it also stops attackers from learning how many outgoing transport-protocol instances (e.g., TCP connections) the client has set up in some period of time ๐Ÿ™ˆโœจ

3.3.2. Algorithm 2: Another Simple Port Randomization Algorithm ๐ŸŽ€

the pseudo-code below shows another algorithm for picking a random port number, where if a local instance-id collision is detected, another port number gets picked randomly ๐ŸŽฐ

    /* Ephemeral port selection function */
    num_ephemeral = max_ephemeral - min_ephemeral + 1;
    next_ephemeral = min_ephemeral + (random() % num_ephemeral);
    count = num_ephemeral;

    do {
        if(check_suitable_port(port))
                return next_ephemeral;

        next_ephemeral = min_ephemeral + (random() % num_ephemeral);
        count--;
    } while (count > 0);

    return ERROR;

                           Algorithm 2

when there are a ton of port numbers already in use for the same destination endpoint, this algorithm might not be able to pick an ephemeral port (with a very small remaining probability) ๐Ÿ˜ต it would return "ERROR", even if a few port numbers are still free that would give unique five-tuples ๐Ÿฅบ however, the [Allman] results show that in common scenarios one port choice is enough, and in most cases where more than one choice is needed, two choices suffice ๐Ÿ™Œ so in those scenarios this won't be a problem, iykyk ๐Ÿ’…โœจ

3.3.3. Algorithm 3: Simple Hash-Based Port Selection Algorithm โœจ

okay so the goal here is to get the port-reuse vibes of the old BSD algorithm (see Section 2.2) ๐Ÿ’… but also the unpredictability of Algorithm 1 and Algorithm 2 ๐Ÿ”ฎ like, both at once, no cap ๐Ÿซถ

ideally every combo of (local IP address, remote IP addresses, remote port) gets its own "next_ephemeral" value ๐Ÿฆ‹ so the port-reuse frequency is as low as it can possibly be. each of those should start at a random value inside the ephemeral port range ๐ŸŽฒ and together they separate the ephemeral port space per destination endpoint ๐ŸŒธ (this "separation of the ephemeral port space" just means that transport-protocol instances with different remote endpoints won't walk through the same ephemeral port sequence, unlike the traditional BSD algorithm ๐Ÿ‘€). BUT keeping all those variables in memory is a lot ๐Ÿ’€ so instead we use an offset function F() that can be computed from the local IP address, remote IP address, remote port, and a secret key ๐Ÿ”‘. F() gives you (practically) different values for each set of arguments, like this:

/* Initialization at system boot time. Could be random. */
next_ephemeral = 0;

/* Ephemeral port selection function */
num_ephemeral = max_ephemeral - min_ephemeral + 1;
offset = F(local_IP, remote_IP, remote_port, secret_key);
count = num_ephemeral;

do {
    port = min_ephemeral +
           (next_ephemeral + offset) % num_ephemeral;

    next_ephemeral++;

    if(check_suitable_port(port))
        return port;

    count--;

} while (count > 0);

return ERROR;

Algorithm 3

so basically F() gives a "per-destination endpoint" fixed offset inside the global ephemeral port range ๐Ÿงš both "offset" and "next_ephemeral" can be any value that fits in the storage type, because the resulting port gets restricted in a similar way to Algorithm 1 (see Section 3.3.1) ๐Ÿ’– that means you can just increment "next_ephemeral" and let the unsigned integer wrap around on its own ๐Ÿ™Œ

the F() function should be a cryptographic hash function like MD5 [RFC1321] ๐Ÿ” it should use both IP addresses, the remote port, and the secret key to compute the offset. the remote IP address is the main separator ๐Ÿ‘‘ so it has to be in the offset calculation. the local IP address and remote port might sometimes be constant, which means they won't add much separation, but they should still be included anyway ๐ŸŽ€

stronger crypto than MD5 isn't really needed here, since Algorithm 3 is just a way to obfuscate which ephemeral ports get picked ๐Ÿ™ˆ the secret should be as random as possible (see [RFC4086] for tips on picking secrets) ๐ŸŽฒ

on multiuser systems, F() could also take user-specific info, so you get protection not just host-to-host but user-to-service too ๐Ÿ˜ญ honestly any identifier for the remote entity could work, depending on what's available and how granular you want it. with SCTP, both hostnames and alternative IP addresses can show up in the association negotiation, and either of those could go into F() ๐ŸŒˆ

when you have multiple unique identifiers, any of them can be the input to F(), since they all uniquely identify the remote entity ๐Ÿ’… BUT with SCTP the ephemeral port has to be unique across all IP address combos, so ideally you'd always use the same IP address to get one starting offset for every association with a given remote entity, which keeps collisions down ๐Ÿซถ sorting the IP addresses numerically and always picking the lowest would do it. still, since most protocols report the same IP addresses in the same order every time, the sorting probably isn't needed and you can just use the "first one" โœจ

whether hostnames can uniquely define hosts is up for debate ๐Ÿค” but since SCTP always includes at least one IP address, we recommend using that as the input to F() and ignoring hostname chunks when searching for ephemeral ports ๐Ÿ’œ

now for the sus part ๐Ÿ‘€ this algorithm uses a global counter ("next_ephemeral") to pick ephemeral ports, so if an attacker could force a client to keep making new TCP connections to an attacker-controlled machine (or through a path the attacker can observe), they could subtract consecutive source port values to figure out how many outgoing TCP connections the target host set up globally in that time window ๐Ÿ˜ฑ (ignoring wrap-around issues and five-tuple collisions, of course) ๐Ÿ’€

3.3.4. Algorithm 4: Double-Hash Port Selection Algorithm ๐ŸŒธ

this is a trade-off between keeping one single global "next_ephemeral" variable and keeping 2**N "next_ephemeral" variables (where N is the width of F()'s result) ๐ŸŽ€ the system keeps an array of TABLE_LENGTH short integers, which splits up the increments of "next_ephemeral" ๐Ÿง here's how it fits into Algorithm 3:

/* Initialization at system boot time */
for(i = 0; i < TABLE_LENGTH; i++)
    table[i] = random() % 65536;

/* Ephemeral port selection function */
num_ephemeral = max_ephemeral - min_ephemeral + 1;
offset = F(local_IP, remote_IP, remote_port, secret_key1);
index = G(local_IP, remote_IP, remote_port, secret_key2);
count = num_ephemeral;

do {
    port = min_ephemeral + (offset + table[index]) % num_ephemeral;
    table[index]++;

    if(check_suitable_port(port))
        return port;

   count--;

} while (count > 0);

return ERROR;

Algorithm 4

"table[]" can be initialized with mathematically random values, as the pseudo-code init above shows ๐ŸŽฒ the G() function should be a cryptographic hash function like MD5 [RFC1321] ๐Ÿ” it should use both IP addresses, the remote port, and a secret key to compute a value from 0 to (TABLE_LENGTH-1). alternatively, G() can take "offset" as input and XOR all the bytes in "offset" together ๐Ÿง 

the "table[]" array makes sure that successive transport-protocol instances with the same remote endpoint use increasing ephemeral port numbers ๐Ÿ“ˆ but since the increments are split across TABLE_LENGTH different spaces, the port-reuse frequency is (probabilistically) lower than Algorithm 3's ๐Ÿ™Œ a new instance for one remote endpoint won't necessarily bump the "next_ephemeral" value for other endpoints โœจ

it's kinda iconic that the size of "table[]" doesn't limit how many port sequences you can have ๐Ÿ’… it just splits the increments into TABLE_LENGTH different spaces. the port sequence comes from adding the matching "table[]" entry to "offset", which picks the actual sequence (same as Algorithm 3) ๐Ÿฆ‹ [Allman] found that a TABLE_LENGTH of 10 can beat Algorithm 3 ๐Ÿ† and making TABLE_LENGTH bigger increases how unpredictable the port number is, and might lower the collision rate even more ๐Ÿ“‰

an attacker can do traffic analysis on any "increment space" they have "visibility" into ๐Ÿ‘€ meaning they can force the client to open a transport-protocol instance whose G(offset) lands on the target "increment space". BUT their ability to do traffic analysis is way reduced compared to the traditional BSD algorithm (see Section 2.2) and Algorithm 3 ๐Ÿ™Œ an implementation can also shrink that even more by splitting the increment space further (aka using a bigger TABLE_LENGTH) ๐Ÿ›ก๏ธ

3.3.5. Algorithm 5: Random-Increments Port Selection Algorithm ๐ŸŽข

[Allman] came up with another port selection algorithm that's kind of the middle ground ๐ŸŒˆ between algorithms that pick ephemeral ports totally at random (like Sections 3.3.1 and 3.3.2) and algorithms that get obfuscation with less randomization (like Sections 3.3.3 and 3.3.4) โœจ

/* Initialization code at system boot time. */
next_ephemeral = random() % 65536;   /* Initialization value */
N = 500;                             /* Determines the trade-off */

/* Ephemeral port selection function */
num_ephemeral = max_ephemeral - min_ephemeral + 1;

count = num_ephemeral;

do {
    next_ephemeral = next_ephemeral + (random() % N) + 1;
    port = min_ephemeral + (next_ephemeral % num_ephemeral);

    if(check_suitable_port(port))
            return port;

     count--;
} while (count > 0);

return ERROR;

Algorithm 5

this one is about getting a monotonically increasing sequence so instance-ids don't collide ๐Ÿ“ˆ while skipping fixed increments, which would make the sequences trivially predictable ๐Ÿ™…โ€โ™€๏ธ the value "N" lets you directly control the trade-off between unpredictability and port-reuse frequency ๐ŸŽš๏ธ the smaller N is, the more it acts like the traditional BSD algorithm (see Section 2.2) ๐Ÿฅน the bigger N is, the more it acts like the algorithm in Section 3.3.1 of this document ๐Ÿ’–

when the port numbers wrap around, there's a risk of instance-id collisions ๐Ÿ˜ฌ so "N" should be picked according to these criteria:

  • It should maximize the wrapping time of the ephemeral port space.
  • It should minimize collisions of instance-ids.
  • It should maximize the unpredictability of selected port numbers.

these goals literally compete with each other ๐Ÿ’€ so picking N is a trade-off. that's why N should be configurable, so system administrators can make the call for themselves ๐Ÿซถ

3.4. Secret-Key Considerations for Hash-Based Port Selection Algorithms ๐Ÿ”

okay so every complex manipulation (like MD5) is only as secure as what you feed it, and for ephemeral ports that input is the secret key ๐Ÿ˜ค. if an attacker knows which cryptographic hash function the victim is using (and we should totally expect that), and they can collect enough material, like the ephemeral ports the victim already picked, they can just brute-force the entire secret-key space to find matches. not it ๐Ÿ’€

so to protect against this, the secret key needs to be a reasonable length. 128-bit keys should be adequate ๐Ÿ”‘โœจ

another option is to change the key after some time. if the host platform can make reasonably good random data, the secret key can be changed automatically ๐Ÿฆ‹

BUT here's the tea: changing the secret causes abrupt shifts in the chosen ephemeral ports, so collisions may happen. when the secret changes, the "offset" value (see Sections 3.3.3 and 3.3.4) for each destination endpoint comes out different from what the old secret would've computed, and that can lead to picking a port number that was recently used for connecting to the same endpoint ๐Ÿ˜ญ

so the key change has to be done with some thought, and it could happen whenever one of these events occurs:

  • The system is being bootstrapped. ๐Ÿฅพ
  • Some predefined/random time has expired. โฐ
  • The secret key has been used sufficiently often that it should be regarded as insecure now. ๐Ÿšจ
  • There are few active transport-protocol instances (i.e., possibility of a collision is low). ๐Ÿซง
  • System load is low (i.e., the performance overhead of local collisions is tolerated). ๐Ÿ˜Œ
  • There is enough random data available to change the secret key (pseudo-random changes should not be done). ๐ŸŽฒ

3.5. Choosing an Ephemeral Port Selection Algorithm ๐Ÿ’…

okay so [Allman] is an empirical study of the properties of the algorithms in this document, and it found that all of them offer low collision rates, at most 0.3% ๐Ÿ™Œ. in the network scenarios [Allman] checked, every algorithm here performs well when it comes to instance-id collisions. BUT these results can vary depending on the characteristics of network traffic and the specific network setup, so don't just assume ๐Ÿค”

Section 2.2's algorithm is the traditional one used in BSD-derived systems. it generates a global sequence of ephemeral port numbers, which makes it trivial for an attacker to predict the port that a future transport protocol instance will use ๐Ÿ‘€. it is very simple though, and it leads to a low port-reuse frequency ๐ŸŒธ

Algorithm 1 and Algorithm 2 actually randomize the ephemeral ports, which is the big win ๐ŸŽฒ. the downside is they may increase the chances of port number collisions, and that could make a connection establishment attempt fail. [Allman] found these two show the largest collision rates of all the algorithms here ๐Ÿ˜ฌ

Algorithm 3 gives complete separation in local and remote IP addresses and in the remote port space, and only limited separation in other dimensions (see Section 3.4). the thing to keep in mind is that implementations should consider the performance impact of computing the cryptographic hash used for the offset ๐Ÿงฎ

Algorithm 4 improves on Algorithm 3 and usually leads to a lower port-reuse frequency. the cost is more processor cycles spent computing G(), plus extra kernel memory for storing the array "table[]" ๐Ÿง 

Algorithm 5 is kind of the middle ground between the simple randomization algorithms (Algorithm 1 and Algorithm 2) and the hash-based ones (Algorithm 3 and Algorithm 4) โš–๏ธ. the upper limit on the random increments (the value "N" in the pseudo-code in Section 3.3.5) is what controls the trade-off between randomization and port-reuse frequency ๐Ÿ’–

last but definitely not least, there's a special case that might rule out Algorithm 3 and Algorithm 4, and it needs a look ๐Ÿ‘€. some applications contain this code sequence:

    s = socket();
    bind(s, IP_address, port = *);

on some BSD-derived systems, the call to bind() results in an ephemeral port number being selected. but neither the remote IP address nor the remote port is available to the ephemeral port selection function at that point. so the hash function F() used in Algorithm 3 and Algorithm 4 won't have all the arguments it needs, and the result becomes impossible to compute ๐Ÿ˜ฑ. transport protocols implementing Algorithm 3 or Algorithm 4 should consider using Algorithm 2 in exactly this scenario.

there's an alternative, which is "lazy binding" in response to the bind() call. basically the selection of an ephemeral port gets delayed until something like connect() or send() is called. by then the port really is selected, all the arguments for F() are available, and Algorithm 3 and Algorithm 4 can still be used in this scenario ๐Ÿช„. Linux has implemented this approach [Linux] โœจ


4. Interaction with Network Address Port Translation (NAPT) โœจ

okay so Network Address Port Translation (NAPT) translates both the network address and the transport-protocol port number. this lets the transport identifiers of a bunch of private hosts get multiplexed into the transport identifiers of a single external address [RFC2663] ๐ŸŒ

when a NAPT sits between the two endpoints of a transport-protocol instance, how well the ephemeral port selection is obfuscated (from the point of view of the external network) depends on the ephemeral port selection function at the NAPT ๐Ÿซถ. so NAPTs should consider obfuscating their ephemeral port selection using any of the algorithms discussed in this document ๐Ÿ’œ

A NAPT that does not implement port preservation [RFC4787] [RFC5382] SHOULD obfuscate the selection of the ephemeral port of a packet whenever that port gets changed during translation of the packet ๐Ÿ”ฅ

A NAPT that does implement port preservation SHOULD obfuscate the ephemeral port of a packet only if the port has to be changed because it's already in use for some other session ๐Ÿ™ˆ

A NAPT that performs parity preservation and has to change the ephemeral port during translation of a packet SHOULD obfuscate the ephemeral ports. the algorithms in this document could be easily adapted so parity is preserved (i.e., force the lowest order bit of the resulting port number to 0 or 1 depending on whether even or odd parity is desired) ๐ŸŽ€

some applications allocate contiguous ports and expect to see contiguous ports in use at their peers. ngl that expectation can be hard to meet at a NAPT, since some port numbers might already be in use by other sessions. then an alternative port might need to be selected, which gives a non-contiguous port number sequence (see Section 4.2.3 of [RFC4787]) ๐Ÿ˜ญ. a NAPT that implements a simple port randomization algorithm (such as Algorithm 1, Algorithm 2, or Algorithm 5) is likely to break this assumption, even if the endpoint selecting the ephemeral port does pick contiguous ports. BUT since deployed NAPTs have implemented a bunch of different ephemeral port selection algorithms, any application relying on one specific algorithm at the NAPT is likely to hit interoperability problems when a NAPT is between the two endpoints ๐Ÿฅฒ

the good news is some of the algorithms here (namely Algorithm 3 and Algorithm 4) pick consecutive ephemeral ports so they're contiguous, except when one of the port numbers needed for a contiguous sequence is already in use by some other NAPT session. so a NAPT that wants to produce contiguous port sequences should consider implementing Algorithm 3 or Algorithm 4 ๐Ÿงš Section 3.5 has more guidance on choosing a port selection algorithm.

it's also worth knowing that in some network scenarios, a NAPT may naturally obscure ephemeral port selections, just because of the huge range of services it connects to and the overall rate of the traffic [Allman] ๐ŸŒˆ


5. Security Considerations ๐Ÿ›ก๏ธ

okay this part is SERIOUS bestie ๐Ÿ˜ค obfuscating the ephemeral port selection is NO replacement for cryptographic mechanisms, like IPsec [RFC4301], when it comes to protecting transport-protocol instances against blind attacks ๐Ÿ”

An eavesdropper who can monitor the packets for the transport-protocol instance being attacked can learn the IP addresses and port numbers in use (and also sequence numbers, etc.) and easily perform an attack. obfuscating the ephemeral port selection gives zero extra protection against this kind of attack. in these situations, proper authentication mechanisms like the ones described in [RFC4301] should be used ๐Ÿšจ

this spec recommends including the whole range 1024-65535 for the selection of ephemeral ports, and suggests that an implementation keeps a list of port numbers that should NOT be made available for ephemeral port selection ๐Ÿ“‹. if that list of unavailable ports is significant, Algorithm 1 may be highly biased and generate predictable ports, as noted in Section 3.3.1 ๐Ÿ˜ฌ. in particular, if the list of IANA Registered Ports is accepted as the local list of port numbers that shouldn't be available, certain ports may end up with 500 times the probability of other ports ๐Ÿ’€. systems that support lots of applications (resulting in large lists of unavailable ports), or that use the IANA Registered Ports without modification, MUST NOT use Algorithm 1 ๐Ÿ™…โ€โ™€๏ธ

if the local offset function F() (in Algorithm 3 and Algorithm 4) gives identical offsets for different inputs more often than chance would predict, the port-offset mechanism proposed in this document would have a reduced effect ๐Ÿ“‰

if random numbers are the only source of the secret key, they should be chosen following the recommendations in [RFC4086] ๐ŸŽฒ

if an attacker uses dynamically assigned IP addresses, the current ephemeral port offset (Algorithm 3 and Algorithm 4) for a given five-tuple can be sampled and then used to attack an innocent peer reusing that address ๐Ÿ˜ฑ. BUT this only works until a re-keying happens as described above. also, since ephemeral ports are only used on the client side (e.g., the one initiating the transport-protocol communication), both the attacker and the new peer need to act as servers in the scenario just described. servers using dynamic IP addresses do exist, but they're not very common, and with an appropriate re-keying mechanism the effect of this attack is limited ๐Ÿงฏโœจ

6. Acknowledgements โœจ

The offset function used in Algorithm 3 and Algorithm 4 was inspired by the mechanism Steven Bellovin proposed in [RFC1948] for defending against TCP sequence number attacks. Big thanks to Steven! ๐Ÿซถ

The authors would like to thank (in alphabetical order) Mark Allman, Jari Arkko, Matthias Bethke, Stephane Bortzmeyer, Brian Carpenter, Vincent Deffontaines, Ralph Droms, Lars Eggert, Pasi Eronen, Gorry Fairhurst, Adrian Farrel, Guillermo Gont, David Harrington, Alfred Hoenes, Avshalom Houri, Charlie Kaufman, Amit Klein, Subramanian Moonesamy, Carlos Pignataro, Tim Polk, Kacheong Poon, Pasi Sarolahti, Robert Sparks, Randall Stewart, Joe Touch, Michael Tuexen, Magnus Westerlund, and Dan Wing for their valuable feedback on draft versions of this document. The whole squad showed up ๐Ÿ‘‘๐Ÿ’–

The authors would like to thank Alfred Hoenes for his admirable effort in improving the quality of this document. Alfred really went in on the editing, bestie ๐Ÿงš

The authors would like to thank FreeBSD's Mike Silbersack for a very fruitful discussion about ephemeral port selection techniques. ๐Ÿฆ‹

Fernando Gont's attendance at IETF meetings was supported by ISOC's "Fellowship to the IETF" program. Love that for him ๐ŸŒธ


7. References ๐Ÿ“š

7.1. Normative References

[RFC0768]      Postel, J., "User Datagram Protocol", STD 6, RFC 768,
               August 1980.

[RFC0793]      Postel, J., "Transmission Control Protocol", STD 7,
               RFC 793, September 1981.

[RFC1321]      Rivest, R., "The MD5 Message-Digest Algorithm",
               RFC 1321, April 1992.

[RFC2119]      Bradner, S., "Key words for use in RFCs to Indicate
               Requirement Levels", BCP 14, RFC 2119, March 1997.

[RFC2385]      Heffernan, A., "Protection of BGP Sessions via the TCP
               MD5 Signature Option", RFC 2385, August 1998.

[RFC3550]      Schulzrinne, H., Casner, S., Frederick, R., and V.
               Jacobson, "RTP: A Transport Protocol for Real-Time
               Applications", STD 64, RFC 3550, July 2003.

[RFC3605]      Huitema, C., "Real Time Control Protocol (RTCP)
               attribute in Session Description Protocol (SDP)",
               RFC 3605, October 2003.

[RFC3828]      Larzon, L-A., Degermark, M., Pink, S., Jonsson, L-E.,
               and G. Fairhurst, "The Lightweight User Datagram
               Protocol (UDP-Lite)", RFC 3828, July 2004.

[RFC4086]      Eastlake, D., Schiller, J., and S. Crocker,
               "Randomness Requirements for Security", BCP 106,
               RFC 4086, June 2005.

[RFC4301]      Kent, S. and K. Seo, "Security Architecture for the
               Internet Protocol", RFC 4301, December 2005.

[RFC4340]      Kohler, E., Handley, M., and S. Floyd, "Datagram
               Congestion Control Protocol (DCCP)", RFC 4340,
               March 2006.

[RFC4787]      Audet, F. and C. Jennings, "Network Address
               Translation (NAT) Behavioral Requirements for Unicast
               UDP", BCP 127, RFC 4787, January 2007.

[RFC4960]      Stewart, R., "Stream Control Transmission Protocol",
               RFC 4960, September 2007.

[RFC5382]      Guha, S., Biswas, K., Ford, B., Sivakumar, S., and P.
               Srisuresh, "NAT Behavioral Requirements for TCP",
               BCP 142, RFC 5382, October 2008.

7.2. Informative References

[Allman]       Allman, M., "Comments On Selecting Ephemeral Ports",
                ACM Computer Communication Review, 39(2), 2009.

[CPNI-TCP]     Gont, F., "CPNI Technical Note 3/2009: Security
               Assessment of the Transmission Control Protocol
               (TCP)", 2009, <http://www.cpni.gov.uk/Docs/
               tn-03-09-security-assessment-TCP.pdf>.

[FreeBSD]      The FreeBSD Project, <http://www.freebsd.org>.

[IANA]         "IANA Port Numbers",
               <http://www.iana.org/assignments/port-numbers>.

[Linux]        The Linux Project, <http://www.kernel.org>.

[NetBSD]       The NetBSD Project, <http://www.netbsd.org>.

[OpenBSD]      The OpenBSD Project, <http://www.openbsd.org>.

[OpenSolaris]  OpenSolaris, <http://www.opensolaris.org>.

[RFC1337]      Braden, B., "TIME-WAIT Assassination Hazards in TCP",
               RFC 1337, May 1992.

[RFC1948]      Bellovin, S., "Defending Against Sequence Number
               Attacks", RFC 1948, May 1996.

[RFC2663]      Srisuresh, P. and M. Holdrege, "IP Network Address
               Translator (NAT) Terminology and Considerations",
               RFC 2663, August 1999.

[RFC4953]      Touch, J., "Defending TCP Against Spoofing Attacks",
               RFC 4953, July 2007.

[RFC5925]      Touch, J., Mankin, A., and R. Bonica, "The TCP
               Authentication Option", RFC 5925, June 2010.

[RFC5927]      Gont, F., "ICMP Attacks against TCP", RFC 5927,
               July 2010.

[SCTP-SOCKET]  Stewart, R., Poon, K., Tuexen, M., Lei, P., and V.
               Yasevich, V., "Sockets API Extensions for Stream
               Control Transmission Protocol (SCTP)", Work in
               Progress, January 2011.

[Silbersack]   Silbersack, M., "Improving TCP/IP security through
               randomization without sacrificing interoperability",
               EuroBSDCon 2005 Conference.

[Stevens]      Stevens, W., "Unix Network Programming, Volume 1:
               Networking APIs: Socket and XTI", Prentice Hall, 1998.

[TCP-SEC]      Gont, F., "Security Assessment of the Transmission
               Control Protocol (TCP)", Work in Progress,
               February 2010.

[Watson]       Watson, P., "Slipping in the Window: TCP Reset
               Attacks", CanSecWest 2004 Conference.

A.1. FreeBSD

FreeBSD 8.0 implements Algorithm 1, and in response to this document it now uses a "min_port" of 10000 and a "max_port" of 65535 [FreeBSD]. ๐Ÿก

A.2. Linux

Linux 2.6.15-53-386 implements Algorithm 3, with MD5 as the hash algorithm. If the algorithm is faced with the corner-case scenario described in Section 3.5, Algorithm 1 is used instead [Linux]. ๐Ÿง

A.3. NetBSD

NetBSD 5.0.1 does not obfuscate its ephemeral port numbers. It selects ephemeral port numbers from the range 49152-65535, starting from port 65535, and decreasing the port number for each ephemeral port number selected [NetBSD]. Super straightforward, no hiding ๐Ÿ™ˆ

A.4. OpenBSD

OpenBSD 4.2 implements Algorithm 1, with a "min_port" of 1024 and a "max_port" of 49151. [OpenBSD] ๐Ÿก

A.5. OpenSolaris

OpenSolaris 2009.06 implements Algorithm 1, with a "min_port" of 32768 and a "max_port" of 65535 [OpenSolaris]. โ˜€๏ธ


Authors' Addresses ๐Ÿ’Œ

Michael Vittrup Larsen
Tieto
Skanderborgvej 232
Aarhus  DK-8260
Denmark

Phone: +45 8938 5100
EMail: michael.larsen@tieto.com


Fernando Gont
Universidad Tecnologica Nacional / Facultad Regional Haedo
Evaristo Carriego 2644
Haedo, Provincia de Buenos Aires  1706
Argentina

Phone: +54 11 4650 8472
EMail: fernando@gont.com.ar
๐Ÿ“ฆ where this page comes from