Ephemeral port range (patch)

Fernando Gont fernando at gont.com.ar
Sat Mar 1 13:39:16 UTC 2008


Folks,

This patch changes the default ephemeral port range from 49152-65535 
to 1024-65535. This makes it harder for an attacker to guess the 
ephemeral ports (as the port number space is larger). Also, it makes 
the chances of port number collisions smaller. 
(http://www.ietf.org/internet-drafts/draft-ietf-tsvwg-port-randomization-01.txt)

This patch also includes my previous patch that eliminated duplicated 
code in in_pcb_bind().


Index: in.h
===================================================================
RCS file: /home/ncvs/src/sys/netinet/in.h,v
retrieving revision 1.100
diff -u -r1.100 in.h
--- in.h        12 Jun 2007 16:24:53 -0000      1.100
+++ in.h        1 Mar 2008 09:00:10 -0000
@@ -293,8 +293,7 @@
   *
   * The value IP_PORTRANGE_HIGH changes the range of candidate port numbers
   * into the "high" range.  These are reserved for client outbound connections
- * which do not want to be filtered by any firewalls.  Note that by default
- * this is the same as IP_PORTRANGE_DEFAULT.
+ * which do not want to be filtered by any firewalls.
   *
   * The value IP_PORTRANGE_LOW changes the range to the "low" are
   * that is (by convention) restricted to privileged processes.  This
@@ -331,8 +330,13 @@
  #define        IPPORT_RESERVED         1024

  /*
- * Default local port range, used by both IP_PORTRANGE_DEFAULT
- * and IP_PORTRANGE_HIGH.
+ * Default local port range, used by IP_PORTRANGE_DEFAULT
+ */
+#define IPPORT_EPHEMERALFIRST  1024
+#define IPPORT_EPHEMERALLAST   65535
+
+/*
+ * Dynamic port range, used by IP_PORTRANGE_HIGH.
   */
  #define        IPPORT_HIFIRSTAUTO      49152
  #define        IPPORT_HILASTAUTO       65535
Index: in_pcb.c
===================================================================
RCS file: /home/ncvs/src/sys/netinet/in_pcb.c,v
retrieving revision 1.198
diff -u -r1.198 in_pcb.c
--- in_pcb.c    22 Dec 2007 10:06:11 -0000      1.198
+++ in_pcb.c    1 Mar 2008 09:00:11 -0000
@@ -89,8 +89,8 @@
   */
  int    ipport_lowfirstauto  = IPPORT_RESERVED - 1;     /* 1023 */
  int    ipport_lowlastauto = IPPORT_RESERVEDSTART;      /* 600 */
-int    ipport_firstauto = IPPORT_HIFIRSTAUTO;          /* 49152 */
-int    ipport_lastauto  = IPPORT_HILASTAUTO;           /* 65535 */
+int    ipport_firstauto = IPPORT_EPHEMERALFIRST;       /* 1024 */
+int    ipport_lastauto  = IPPORT_EPHEMERALLAST;        /* 65535 */
  int    ipport_hifirstauto = IPPORT_HIFIRSTAUTO;        /* 49152 */
  int    ipport_hilastauto  = IPPORT_HILASTAUTO;         /* 65535 */

@@ -393,7 +393,7 @@
         if (*lportp != 0)
                 lport = *lportp;
         if (lport == 0) {
-               u_short first, last;
+               u_short first, last, aux;
                 int count;

                 if (laddr.s_addr != INADDR_ANY)
@@ -440,47 +440,28 @@
                 /*
                  * Simple check to ensure all ports are not used up causing
                  * a deadlock here.
-                *
-                * We split the two cases (up and down) so that the direction
-                * is not being tested on each round of the loop.
                  */
                 if (first > last) {
-                       /*
-                        * counting down
-                        */
-                       if (dorandom)
-                               *lastport = first -
-                                           (arc4random() % (first - last));
-                       count = first - last;
+                       aux = first;
+                       first = last;
+                       last = aux;
+               }

-                       do {
-                               if (count-- < 0)        /* completely used? */
-                                       return (EADDRNOTAVAIL);
-                               --*lastport;
-                               if (*lastport > first || *lastport < last)
-                                       *lastport = first;
-                               lport = htons(*lastport);
-                       } while (in_pcblookup_local(pcbinfo, laddr, lport,
-                           wild));
-               } else {
-                       /*
-                        * counting up
-                        */
-                       if (dorandom)
-                               *lastport = first +
-                                           (arc4random() % (last - first));
-                       count = last - first;
+               if (dorandom)
+                       *lastport = first +
+                                   (arc4random() % (last - first));

-                       do {
-                               if (count-- < 0)        /* completely used? */
-                                       return (EADDRNOTAVAIL);
-                               ++*lastport;
-                               if (*lastport < first || *lastport > last)
-                                       *lastport = first;
-                               lport = htons(*lastport);
-                       } while (in_pcblookup_local(pcbinfo, laddr, lport,
-                           wild));
-               }
+               count = last - first;
+
+               do {
+                       if (count-- < 0)        /* completely used? */
+                               return (EADDRNOTAVAIL);
+                       ++*lastport;
+                       if (*lastport < first || *lastport > last)
+                               *lastport = first;
+                       lport = htons(*lastport);
+               } while (in_pcblookup_local(pcbinfo, laddr, lport,
+                   wild));
         }
         if (prison_ip(cred, 0, &laddr.s_addr))
                 return (EINVAL);



Kind regards,

--
Fernando Gont
e-mail: fernando at gont.com.ar || fgont at acm.org
PGP Fingerprint: 7809 84F5 322E 45C7 F1C9 3945 96EE A9EF D076 FFF1






More information about the freebsd-net mailing list