Subject: priv/unpriv ports range/exceptions
To: None <tech-kern@NetBSD.org>
From: salo <salo@Xtrmntr.org>
List: tech-kern
Date: 05/28/2001 17:36:29
hi there,

i was solving problem with need to have excluded special ports from
privileged range for daemon running by user. (please do not try to
recommend other method like inetd/port forwarding/switching to user id
after bind(), etc. this was the only way to achieve exactly what i need)

i have experience with doing such a things on solaris with ndd, there is
mechanism which enables me to change priv/unpriv ports policy which will
fits my needs. for example, i need to mark port 700 as unprivileged:

  # ndd -set /dev/tcp tcp_smallest_nonpriv_port 700
  # for port in `gseq 701 1023`; do ndd -set /dev/tcp tcp_extra_priv_ports_add $port; done

this is now in netbsd unpossible to achieve by natural way. this could
be changed manually in sys/netinet/in_pcb.c after line 254 in section:

  #ifndef IPNOPRIVPORTS
      /* GROSS */
      if (ntohs(lport) < IPPORT_RESERVED &&
          (p == 0 || (error = suser(p->p_ucred, &p->p_acflag))))
        return (EACCES);
  #endif

for example i did

  1) in kernel config file:
     options EXTRA_UNPRIVPORT

  2)

  #ifndef IPNOPRIVPORTS
      /* GROSS */
  #ifdef EXTRA_UNPRIVPORT
  #define EXTRA_UNPRIVPORT_NUM   700
      if (ntohs(lport) != EXTRA_UNPRIVPORT_NUM)
  #endif
      if (ntohs(lport) < IPPORT_RESERVED &&
          (p == 0 || (error = suser(p->p_ucred, &p->p_acflag))))
        return (EACCES);
  #endif

this is only hardcoded example but it is relatively easy to implement
robust mechanism which could enable to add/delete privileged or
unprivileged ports with sysctl tool. i think it will be useful to have
better control for some exceptions in priv/unpriv ports areas for some
reasons.

another thing is that all other *BSD systems have better control system
over priv/unpriv low/high port ranges, f.e. (`sysctl -a | grep port`)

NetBSD:
net.inet.ip.anonportmin = 49152
net.inet.ip.anonportmax = 65535
net.inet.ip.lowportmin = 600
net.inet.ip.lowportmax = 1023

FreeBSD:
net.inet.ip.portrange.lowfirst: 1023
net.inet.ip.portrange.lowlast: 600
net.inet.ip.portrange.first: 1024
net.inet.ip.portrange.last: 5000
net.inet.ip.portrange.hifirst: 49152
net.inet.ip.portrange.hilast: 65535

OpenBSD:
net.inet.ip.portfirst = 1024
net.inet.ip.portlast = 49151
net.inet.ip.porthifirst = 49152
net.inet.ip.porthilast = 65535

(i have no access to BSD/OS..)

Solaris (for completness, because i mentioned it above, `ndd /dev/tcp \? |
grep port`)
tcp_smallest_nonpriv_port     (read and write)
tcp_smallest_anon_port        (read and write)
tcp_largest_anon_port         (read and write)
tcp_extra_priv_ports          (read only)
tcp_extra_priv_ports_add      (write only)
tcp_extra_priv_ports_del      (write only)


i think it we could at least discuss this topic and maybe implement some
new features to netbsd kernel. few additional checkings before bind()
are not extremely slow so i do not think speed is relevant argument
against add-ons to this part of kernel code.

bye

-- 
--                                salo <salo@Xtrmntr.org>            --
--                                pgp: http://Xtrmntr.org/salo.pgp   --