Dado que el puerto 80/443 son puertos del sistema, significa que solo pueden ser utilizados por usuarios privilegiados
Creo que te equivocas. Cualquiera puede usar estos puertos. Vincularse a ellos es una operación privilegiada.
La razón aquí es que algún usuario Joe no debería poder escribir un servidor web malicioso y luego crear algún host en el que no tenga ningún derecho administrativo. Por supuesto, este es un modelo bastante débil, generalmente no hay nada que impida a Joe poner su propia computadora en la red, y podría tener derechos administrativos sobre cualquier máquina a la que tenga acceso físico.
Haré una demostración con netcat.
Como usuario normal, no puedo vincularme al puerto 80:
$ nc -l -p 80
Can't grab 0.0.0.0:80 with bind : Permission denied
Me puedo unir al puerto 8080:
$ nc -l -p 8080
Mientras tanto, en otra terminal, puedo conectarme al puerto 80 y enviar algunos datos, y veo que aparece en el extremo del servidor que acabo de comenzar:
$ nc 127.0.0.1 8080 <<<"Hello world"
Si quiero enlazar al puerto 80, necesito ser root:
$ sudo nc -l -p 80
O puedo asignar la CAP_NET_BIND_SERVICE
capacidad al nc
binario:
$ cp `which nc` .
$ sudo setcap 'cap_net_bind_service=+ep' ./nc
$ ./nc -l -p 80
Otra opción es escribir el programa del servidor de modo que después de que se llame listen()
, elimine los privilegios de root. Esta es una solución bastante común, y la verás con la mayoría de los demonios. Apache, por ejemplo, se inicia desde init como root, y luego abandona los privilegios de root y se convierte en el usuario www-data
o algo similar una vez que está vinculado al puerto 80. Intente ejecutarlo /etc/init.d/apache start
como no root y Apache probablemente no se iniciará.