22

I'm reading a book on network programming with Go. One of the chapters deals with the /etc/services file. Something I noticed while exploring this file is that certain popular entries like HTTP and SSH, both of which use TCP at the transport layer, have a second entry for UDP. For example on Ubuntu 14.04:

ubuntu@vm1:~$ grep ssh /etc/services  
ssh             22/tcp         # SSH Remote Login Protocol 
ssh             22/udp

ubuntu@vm1:~$ grep http /etc/services  
http            80/tcp          www             # WorldWideWeb HTTP            
http            80/udp                          # HyperText Transfer Protocol

Anyone know why these have two entries? I don't believe SSH or HTTP ever use UDP (confirmed by this question for SSH).

sixty4bit
  • 343
  • 1
  • 8
  • 7
    `22/udp` was removed in Debian in 2016. [IANA still lists 22/udp](https://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xhtml) and lists both udp and tcp for most protocols that are only usually implemented on either one of them. Could just be that it means 22 is reserved for ssh in case somebody wants to implement ssh over udp some day? – Stéphane Chazelas Sep 25 '19 at 20:58
  • 2
    See also section 7.1 of [rfc6335](https://tools.ietf.org/html/rfc6335) – Stéphane Chazelas Sep 25 '19 at 21:03

1 Answers1

29

Basically, it's because that was the tradition from way back when port numbers started being assigned through until approximately 2011. See, for example, §7.1 “Past Principles” of RFC 6335:

TCP and UDP ports were simultaneously assigned when either was requested

It's possible they will be un-allocated someday, of course, as ports 1023 and below are the "system ports", treated specially by most operating systems, and most of that range is currently assigned.

And, by the way, HTTP/3 runs over UDP. Though it can use any UDP port, not just 80/443. So really those are still unused.

As far as Debian is concerned, its /etc/services already had 22/udp in 1.0 (buzz 1996).

It was however removed in this commit in 2016, first released in version 5.4 of the netbase package.

As of writing, the latest stable version of Debian (buster) has 5.6. And the latest Ubuntu LTS (18.04, bionic) netbase package is based on Debian netbase 5.4 and you can see its changelog also mentions the removal of udp/22.

derobert
  • 107,579
  • 20
  • 231
  • 279
  • I may be mistaken, but also has to do with firewalls often blocking UDP – Sergiy Kolodyazhnyy Sep 25 '19 at 21:28
  • 4
    @SergiyKolodyazhnyy I'd think not, as this practice predates firewalls. – derobert Sep 25 '19 at 23:31
  • "Only 1023" is exaggerating the point - yes, on Linux, only the lowest 1024 (including port 0) can't be bound for listening by non-root users, different Unixen have different thresholds for that, and all 65536 ports could be assigned to protocols. – Toby Speight Sep 26 '19 at 07:28
  • 3
    @TobySpeight That's not just Linux, that's part of the relevant standards. See, e.g., §6 of that RFC. Though the IANA also registers higher ports, they're a different classification (and that matters in practice because of how OSs, not just Linux, treat them). I'll clarify that a bit. Also, 0 isn't a valid port. It's used by the sockets API as a wildcard (to tell the kernel to pick a port for you). – derobert Sep 26 '19 at 07:38
  • @TobySpeight BTW, sort of besides the point, but it's configurable on Linux too. `net.ipv4.ip_unprivileged_port_start` is the key, defaults to 1024. – derobert Sep 26 '19 at 07:45
  • 3
    "0 isn't a valid port" is questionable. It's certainly not a *usable* port on our OS (which is why I called it out specifically, and why it's currently reserved, and unlikely to be assigned to anything), but it's not special at the protocol level. – Toby Speight Sep 26 '19 at 07:52
  • @TobySpeight RFC 793 just says port is a 16-bit number, so in that sense I guess it's valid. But in the sense that you can't actually use it (I bet all kinds of firewalls and other middleware boxes would drop it too, not just most endpoint OSes), it's not valid. We are Unix.SE here, not networking.se. Also, I just avoided the issue when rewording. – derobert Sep 26 '19 at 09:24
  • We're definitely into hair-splitting territory - the important thing is that this a correct and useful answer to the question (which it is: *Because it's assigned by IANA, and that's because it was standard practice at that time*). I agree with your comments; sorry for appearing argumentative! – Toby Speight Sep 26 '19 at 10:29
  • @derobert: If you pass 0 to the kernel (pick a port), couldn't it just pick port 0 for you? Not saying that it will, but POSIX does not use port 0 to mean " failed to find a free port". – MSalters Sep 26 '19 at 14:44
  • @MSalters *somewhat confused* I'm pretty sure you'll find that whichever kernel you look at, it's been programmed not to pick 0. Of course, a lot of kernels are open source, so you could change the programming, maybe even some it'd only require config changes. TCP/UDP is AFAIK not spec'd by POSIX. So I'm not sure what you're asking. – derobert Sep 26 '19 at 14:53
  • 1
    @derobert: Your argument is that port 0 is unusable on Unix machines **because** port 0 means "pick a free port". I'm saying that the argument is wrong. The conclusion does not follow logically from the premise. – MSalters Sep 26 '19 at 15:08
  • @MSalters No, really, it does. You listen on a port by calling `bind` with a `sockaddr_in` structure with the `sin_port` field set to the port you want to listen on, then by calling `listen`. The possible values you can put there are 0 (kernel picks an available port, by default between 32768–60999 on Linux—and it's going to be 1024+ on any sane kernel), 1–1023 (if process is privileged, `CAP_NET_BIND_SERVICE` on Linux), or 1024–65535. There is no value you can pass to actually listen on port 0. This is a tangent at this point, I suggest chat for any further discussion. – derobert Sep 26 '19 at 16:37
  • @derobert There is no such way to do so with the tcp stack on unix/linux systems. IANA lists port 0 "merely" as *reserved* and no special role is mentioned in RFC793. It would still be bad practice to implement a TCP stack that actually uses port 0 – Hagen von Eitzen Sep 26 '19 at 21:28
  • 3
    **Though it can use any UDP port, not just 80/443** That's essentially true of any protocol TCP/UDP protocol, these are just the default ports associated with each. Most applications that use TCP and UDP don't provide a way to specify non-default ports, but HTTP allows them to be specified in URLs so it's more feasible to vary the port. – Barmar Sep 26 '19 at 21:39
  • @Barmar HTTP/3 goes further. It uses the normal 443 to announce what udp port to use for rest of the requests and data transfer. So it really does, in practice, typically, run on other udp ports. – derobert Sep 26 '19 at 22:23
  • @derobert We only need to register the "well known" port used for the initial connection. A number of protocols use random ports afterward, e.g. TFTP and FTP (for the data connection). – Barmar Sep 27 '19 at 16:29
  • @Barmar yep, which is why I say that 80/udp and 443/udp really remain unused; HTTP/3 uses 80/tcp and 443/tcp to advertise the available UDP ports. See, e.g., https://quicwg.org/base-drafts/draft-ietf-quic-http.html#discovery – derobert Sep 27 '19 at 17:17