This is still the header! Main site

TCP ports should be files

2022/03/08

... did I find a thing that not even Plan 9 got right?

This is post no. 90 for Kev Quirk's #100DaysToOffload challenge. The point is to write many things, not to write good ones. Please adjust quality expectations accordingly :)

Motivation

Many services open TCP ports.

Apart from the part where using port numbers is stupid and we could do better even with protocols that already exist... they are a thing. So, given how certain ports have certain important magic numbers, UNIX systems have an excellent and well-thought-out system of giving processes permission to open and listen on them:

everything under 1024 is root only. Everything else is "anyone".

Which... sounds... OK, until you start thinking about how UNIX itself solved similar questions in a way better way.

Device files

/dev/ttyS0 is a serial port. It's owned by the dialout group; if you, as a user, are a member, you can talk and listen to whatever is on the other end of that serial port.

/dev/sg1 is a DVD drive. It's owned by the cdrom group; if you are a member of that one, you can read it.

There are a bunch of examples like this. You can assign device files users and groups with udev rules, for example (... but then you can chown or chmod them on the fly, too.)

Ports

So, why not do the same with TCP ports? Imagine assigning /dev/tcp/80 to your web server user. No more need for trickery like launching it as root so that it can grab the port and then drop privileges (... or not, depending how badly it's configured and how many security holes it has). Then, it could use the already-open "listener socket" file to accept new connections.

This is, actually, different even from Plan 9's approach to ports. There, there was a /net/tcp directory; what it contained was connections though. That is, you'd open /net/tcp/clone, which would give you an endpoint you can open (e.g. at /net/tcp/15); then, you could direct this endpoint to e.g. listen on (or connect to) port 80. Which would leave the "permissions" issue unsolved yet again.

... so why not?

Well, to begin with, UNIX is this archaic OS from the 70s. Device files aren't even actual files; they point to a pair of device numbers, which drivers will interpret somehow. Given this... the 65536 TCP ports would eat up the entire space for devices, leaving nothing for anything else. This is somewhat suboptimal.

Also, there is the question of a directory with 65536 items in it. Which is... fairly ugly. But... this is what you get if you name your ports using integers.

But then... this leaves us to another topic: what TCP ports should have had as addresses! (Another post underway.)

... comments welcome, either in email or on the (eventual) Mastodon post on Fosstodon.