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.
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.
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 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 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 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.
© 2022 - 2024 — McMap. All rights reserved.
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