Why are ports below 1024 privileged? [closed]
Asked Answered
S

2

81

I've heard it's meant to be a security feature, but it often seems like a security problem. If I want to write a server that uses a privileged port, not only do I have to worry about how secure my code is, I have to especially worry about whether I'm using setuid right and dropping privileges.

Strangulation answered 16/4, 2012 at 22:49 Comment(4)
Seems more of a Superuser things. Maybe transfer the question?Worst
In linux, if you set a program with CAP_NET_BIND_SERVICE, this program can listen to privilege ports while being another user. man setcapPickup
yaws.hyber.org/privbind.yaws … misfeature found on UN*X … ports below 1024 … workarounds …Giaour
The thing is, we don't have to worry about whether we're using setuid right. We could for example just say "my process will assume that when it is started, file descriptor 3 is the relevant socket you want me to listen on", and then we could have a single simple standard well-verified program which drops privileges and then executes a command, and then another simple standard well-verified program which just listens on a socket and puts that socket on a given file descriptor.Battlement
W
81

True. But it also means that anyone talking to you knows that you must have to root privileges to run that server. When you log in to a server on port 22 (say), you know you're talking to a process that was run by root (security problems aside), so you trust it with your password for that system, or other information you might not trust to anyone with a user account on that system.

Reference: http://www.w3.org/Daemon/User/Installation/PrivilegedPorts.html.

Edit to elaborate on the reasoning: a lot of the most important network services - telnet (yes, it's still used - surprisingly often), SSH, many HTTP services, FTP etc. etc. - involve sending important data like passwords over the wire. In a secure setup some sort of encryption, whether inherent in the protocol (SSH) or wrapped around it (stunnel, IPSec), protects the data from being snooped on the wire, but all these protections end at the server.

In order to protect your data properly, you need to be sure that you're talking to the 'real' server. Today secure certificates are the most important way of doing this on the web (and elsewhere): you assume that only the 'real' server has access to the certificate, so if you verify that the server you're talking to has that certificate you'll trust it.

Privileged ports work in a very similar way: only root has access to privileged ports, so if you're talking to a privileged port you know you're talking to root. This isn't very useful on the modern web: what matters is the identity of the server, not its IP. In other types of networks, this isn't the case: in an academic network, for example, servers are often physically controlled by trusted staff in secure rooms, but students and staff have quite free access as users. In this situation it's often safe to assume you can always trust root, so you can log in and send private data to a privileged port safely. If ordinary users could listen on all ports, you'd need a whole extra layer to verify that a particular program was trusted with certain data.

Whaleback answered 16/4, 2012 at 22:52 Comment(17)
Ick, that seems like such a small reason for such an annoying restriction.Strangulation
On the contrary, it's a very big and important reason - clearly I haven't explained well enough above.=Whaleback
Now I understand, that's more useful than I thought. Thanks.Strangulation
If you know that a server IS running as root, doesn't that make it more prone for someone to attempt hacking? No "client" should ever assume or know you run as root. Initial passwords should always be changed, this is why SSH has the security feature of knowing a server is the same as the one I've connected to before. Just because its root, doesn't make it any more or less secure as that service could have been hacked and now is running as root to steal your passwords anyway. Even servers such as linux allow listening to privileged ports as a non root user (root needs to give access)Pickup
@Rahly: If your machine's root account is compromised or if the root account is managed by an idiot, then you have a bigger issue, as any service running on that machine will be suspect. In short, you should never connect to a machine that you don't trust.Berdichev
Yeah, but my point is that if you know that only root can run on these ports, that has the possibility actually getting root access. If even "privileged" ports can be as any user, even if that service is compromised, it can be as a limited user. Once a service is compromised, it doesn't matter what user it runs as. The impact comes if that service can damage other services on the machine or the machine(OS) itself.Pickup
@Rahly: Your assumption is wrong: It is true that only root can initiate services that listen on privileged ports. But once initiated the service will usually drop root privileges and run as a limited user (e.g. www-data) for exactly the security reasons you mentioned. So services on privileged ports have to be authorized by root, but usually do not run with root privileges.Tuque
@Dreamer: Not an assumption, a fact. Assuming there is no OS bypass like CAP_NET_BIND_SERVICE, user land code HAS to execute as root in order to listen to a privileged port. I believe YOUR assumption is wrong on how services work at least in a *nix environment. Looking at 3 linux distributions, and ALL of them that listen to <1024 are running as root. As for your www-data, I'm guessing you are talking about a web server like apache. These services will usually spawn a child as a different user to handle individual requests, but the process itself still runs as root. They do thisPickup
because to drop the entire process tree down to a different user would lose complete control over the socket, and provide zero recovery to the user process. The process would just have to die. SSHd does this when making login shells. The concept is the same.Pickup
On my Ubuntu, these run as root: nginx master process, smbd, sshd, cupsd, cups-browsed, nmbd, dhclient. These drop privileges: lighttpd, dnsmasq, exim4, mongod, mysqld, avahi-daemon, dictd ntpd. So you are both wrong, I mean right.Microphotograph
does well-known port are just a convention or an enforced rule?Smut
This is a stupid reason. You can't even be sure that the server is running Unix! Even if every server in the world were Unix, the number of Unix servers out there with users that don't have sudo access is completely negligible. Really the reason is "because that's how it was in the 70s and nobody can be bothered to fix it".Encratia
@Encratia It's a great and smart reason, because it means when you SSH from one of your computers to another, you know that only the stuff you set up as root (through sudo or whatever) could have done a middleman attack on it. Do you audit every single binary or library you install as not-root (through npm or pip or gem or whatever language package managers you use) for malicious code that binds port 22, and for any bug in anything running as not-root which is exploitable for local unprivileged arbitrary code execution? Do you want to?Battlement
@Battlement Port numbers are not a security feature. You don't know if your request to port 22 actually ends up on 22 (or on the requested server) unless you know and trust every network device and TCP stack in between. That's why SSH has host keys or TLS has certificates, to verify you actually end up at the right place - the port number is irrelevant for that process. Privileged ports date back to a time when this kind of verification wasn't available and it made sense back then. Nowadays it's useless. And a random package can't start a service on a port you already have something running on.Hoard
@Hoard 1. Race conditions! What exactly do you think ensures that something is already going to be running on that port? A malicious piece of software can race the legitimate service and if it grabs the port first, then the legitimate service is the one that can't start on that port. For a long time, and on many systems to this day, making the port privileged is the only thing making it impossible for unprivileged malicious code to steal ports from legitimate system services by getting to them first.Battlement
@Hoard 2. Defense in depth! Good computer security is about overlapping many protections, so you can lose some and still be logically assured you're getting the right result. If port 22 does not allow unprivileged processes to bind, that adds one more protective requirement to the SSH server being compromised on the computer it's hosted by. This means that even if the the private key of the server is compromised, so long as the network is trustworthy and the port only allows privileged binding , the server cannot be faked. Overlapping protections.Battlement
@Hoard Now if you want to argue that unprivileged processes racing to bind service ports is not enough of a security vulnerability to justify the current privileged port situation, that's fine, but you can't correctly discuss the tradeoffs of a security hole until you recognize and really feel that hole. (Personally, I think privileged ports make for a bad user and developer experience, and we can do better than always rigidly privileging of all ports <1024, without loss of security: the OS could leave it up to its admin to configure what ports, if any, are privileged/reserved.)Battlement
A
14

You don't say what platform you are using, but on Linux at least you can use capabilities (specifically CAP_NET_BIND_SERVICE) to allow a non-root process to listen on a port less than 1024. See, for example, Is there a way for non-root processes to bind to "privileged" ports on Linux?

Another alternative is to set up iptables rules to forward traffic from the privileged port to the non-privileged port (I've used this in production, and it's fairly simple and works well). It's also described in the above link.

Antetype answered 17/4, 2012 at 7:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.