45

I have installed nginx server. I've just checked listening ports and saw the following:

$ sudo lsof -nP -i | grep LISTEN
sshd       614     root    3u  IPv4   7712      0t0  TCP *:22 (LISTEN)
nginx      822     root    7u  IPv4   8745      0t0  TCP *:80 (LISTEN)
nginx      827 www-data    7u  IPv4   8745      0t0  TCP *:80 (LISTEN)
nginx      828 www-data    7u  IPv4   8745      0t0  TCP *:80 (LISTEN)
nginx      829 www-data    7u  IPv4   8745      0t0  TCP *:80 (LISTEN)
nginx      830 www-data    7u  IPv4   8745      0t0  TCP *:80 (LISTEN)
.
.
.

And I'm just interested why there is four nginx processes run as 'www-data' user and one as 'root user'?

Braiam
  • 35,991
Erik
  • 1,737

4 Answers4

60

The process you noticed is the master process, the process that starts all other nginx processes. This process is started by the init script that starts nginx. The reason this process is running as root is simply because you started it as root! You can start it as another user, but you will have to make sure that all resources nginx needs are available to this user. That would typically be at least /var/log/nginx and the pid-file under /var/run/.

Most importantly; Only root processes can listen to ports below 1024. A webserver typically runs at port 80 and/or 443. That means it needs to be started as root.

In conclusion, the master process being run by root is completely normal and in most cases necessary for normal operation.

Edit: Running anything as root carries an implicit security risk. Normally developers of this kind of software have much knowledge about attack vectors and take great care to execute as little as possible as root. In the end you simply have to trust that the software is of good quality.

If you still feel uneasy there is a way to run nginx as another user and still use ports below 1024. You can use iptables to redirect all incoming traffic on port 80 to another port, for example 8080, and have nginx listen on that port.

arnefm
  • 3,172
22

Most servers (Apache, Nginx, etc.) have a parent process that's owned by root which then forks copies of worker nodes up using a less credentialed user. In this case it's www-data.

Example

If you take a look at nginx's config file, /etc/nginx/nginx.conf, you'll notice lines like this:

user nginx;
worker_processes 2; #change to the number of your CPUs/Cores
worker_rlimit_nofile 8192;

Most of the servers have options similar to this which stipulate what user to run the slave nodes as and how many of them.

Security

Exposing services that have root access is often mentioned as a potential insecurity. However you often have to be root to bind to ports that range from 1-1024, so there's really not anything you can do if you want a server to be listening on say ports 80 or 443.

Also if a service is well written and configured properly it in of itself is not necessarily detrimental to your security posture. The applications that run on top of Apache & Nginx are really the true sources of buffer overflow or SQL server injection attacks since the applications are the services that are exposing the entry points for malformed data to be injected into your server stack.

Apache & Nginx by themselves, generally do not accept any input beyond the GET/POST methods that they accept.

slm
  • 369,824
9

It's the way the application is packaged. On most *nix the default setup is a non privileged user can't listen on a port < 1024 and web servers use 80 and 443.

Linux 2.2+, Solaris 10+ and FreeBSD's all allow non root users to listen on ports lower than 1024 though, just not by default. Most have accepted the use of root so it remains in use.

Other than access to bind to the privileged port you need to make sure the user running nginx has access to all the files it needs. You probably don't need to go as far as this but just set correct permission on files/directories. You also need to check that startup scripts don't do anything sneaky like ulimit changes (like mysql always seems to).

Linux capabilities

setcap and getcap let you change or view the cap_net_bind_service capability for an executable. This will be in effect for anyone who executes the binary.

setcap cap_net_bind_service=+ep /usr/sbin/nginx

SELinux provides the ability to configure and control capabilities at a user level.

Freebsd system settings

The reserved port settings are global to the system

sysctl net.inet.ip.portrange.reservedhigh=0
sysctl net.inet.ip.portrange.reservedlow=0

Solaris Privileges

Solaris provides fine grained control of privileges at the user level. These are the privileges for apache but they are likely to work for nginx as well.

/usr/sbin/usermod -K defaultpriv=basic,proc_exec,proc_fork,net_privaddr nginx
Matt
  • 8,991
4

I'd like to add to everybody elses answers. Although nginx is started as root, it is not actually running as root. The user (nginx, www-data, etc) that it is actually running as is usually a restricted/jailed login (you can't login with it, only certain files can be accessed). This is one of the pros of using Linux for web servers as opposed to Windows. This process is called a fork (you can find more details in this Wikipedia article) and it also uses setuid and/or setgid (which is also explained in a Wikipedia article) to change the user and/or group. In a secure setup, a hacker would not be able to access the parent process and utilize the root account. This is not always true as a hacker could utilize some kind of exploit to gain root access (there was a vulnerability in nginx 1.4.0 and below which allowed hackers to gain root access).

SameOldNick
  • 483
  • 2
  • 5
  • 10
  • 2
    > This is one of the pros of using Linux for web servers as opposed to Windows. Sorry, but I don't buy that argument. Windows likewise allows service accounts with interactive logon disabled, and also supports ACLs. That said, there are other reasons Apache httpd and Nginx shouldn't be run on Windows (IIS is preferred) without extenuating circumstances, but that's beside the point here. – Bob Jun 04 '14 at 10:35