Issue when trying to bind nginx on CentOS 7.4 to other port than 80

Problem:

I was fighting with a permission related issue with nginx on CentOS 7.4. When I configure nginx to listen to port 80 everything works as expected, but when I use any other port (i.e. 82) it doesn’t.

[root@CentOS7 nginx]# sudo systemctl start nginx
Mai 28 18:32:52 CentOS7 systemd[1]: Starting The nginx HTTP and reverse proxy server…
Mai 28 18:32:52 CentOS7 nginx[22626]: nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
Mai 28 18:32:52 CentOS7 nginx[22626]: nginx: [emerg] bind() to 0.0.0.0:82 failed (13: Permission denied)
Mai 28 18:32:52 CentOS7 nginx[22626]: nginx: configuration file /etc/nginx/nginx.conf test failed
Mai 28 18:32:52 CentOS7 systemd[1]: nginx.service: control process exited, code=exited status=1
Mai 28 18:32:52 CentOS7 systemd[1]: Failed to start The nginx HTTP and reverse proxy server.
Mai 28 18:32:52 CentOS7 systemd[1]: Unit nginx.service entered failed state.
Mai 28 18:32:52 CentOS7 systemd[1]: nginx.service failed.

Solution:

This will most likely be related to SELinux

To check which ports are ports are allowed with SELinux and http use the following command

semanage port -l | grep http_port_t
http_port_t tcp 80, 81, 443, 488, 8008, 8009, 8443, 9000

As you can see from the output above with SELinux in enforcing mode http is only allowed to bind to the listed ports.
The solution is to add the ports you want to bind on to the list

semanage port -a -t http_port_t -p tcp 82

will add port 82 to the list.

Now you can start nginx without any issues.

[root@CentOS7 nginx]# sudo systemctl start nginx
[root@CentOS7 nginx]# sudo systemctl status nginx
nginx.service - The nginx HTTP and reverse proxy server
Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; vendor preset: disabled)
Active: active (running) since Do 2020-05-28 18:38:41 CEST; 6s ago
Process: 22862 ExecStart=/usr/sbin/nginx (code=exited, status=0/SUCCESS)
Process: 22859 ExecStartPre=/usr/sbin/nginx -t (code=exited, status=0/SUCCESS)
Process: 22857 ExecStartPre=/usr/bin/rm -f /run/nginx.pid (code=exited, status=0/SUCCESS)
Main PID: 22864 (nginx)
Tasks: 3
CGroup: /system.slice/nginx.service
├─22864 nginx: master process /usr/sbin/nginx
├─22865 nginx: worker process
└─22866 nginx: worker process
Mai 28 18:38:41 CentOS7 systemd[1]: Starting The nginx HTTP and reverse proxy server…
Mai 28 18:38:41 CentOS7 nginx[22859]: nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
Mai 28 18:38:41 CentOS7 nginx[22859]: nginx: configuration file /etc/nginx/nginx.conf test is successful
Mai 28 18:38:41 CentOS7 systemd[1]: Started The nginx HTTP and reverse proxy server.

nginx + node.js + CentOS 7 = 502 Bad Gateway

I have setup a new Node.js / Express development environment on a CentOS 7 VM. I ‘ll describe the details in another post later.

To test my setp, I created a new Express application “helloworld”. The application listens on port 3000 and I was able to connect to the application using a browser.

Next, I configured NGINX as reverse proxy to use port 80 to access the helloworld application.

But I got an error

I checked the logs

[root@nodejs ~]# cat /var/log/audit/audit.log | grep nginx | grep denied

and got

type=AVC msg=audit(1546783734.750:239): avc:  denied  { name_connect } for  pid=11084 comm="nginx" dest=3000 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:ntop_port_t:s0 tclass=tcp_socket permissive=0

My best guess was SELinux.I checked, if SELinux was enabled.

[root@nodejs ~]# sestatus

SELinux status: enabled
SELinuxfs mount: /sys/fs/selinux
SELinux root directory: /etc/selinux
Loaded policy name: targeted
Current mode: enforcing
Mode from config file: enforcing
Policy MLS status: enabled
Policy deny_unknown status: allowed
Max kernel policy version: 31

Next I checked the settings for httpd.

[root@nodejs ~]# getsebool -a | grep httpd
httpd_anon_write --> off
httpd_builtin_scripting --> on
httpd_can_check_spam --> off
httpd_can_connect_ftp --> off
httpd_can_connect_ldap --> off
httpd_can_connect_mythtv --> off
httpd_can_connect_zabbix --> off
httpd_can_network_connect --> off
httpd_can_network_connect_cobbler --> off
httpd_can_network_connect_db --> off
httpd_can_network_memcache --> off
httpd_can_network_relay --> off
httpd_can_sendmail --> off

So, httpd_can_network_connect was set to “Off”. This blocks the connection from the reverse proxy to the node.js application. As a result, you get the 502 Bad gateway error.

To enable the setting, execute the following command from the shell.

[root@nodejs ~]# setsebool -P httpd_can_network_connect on

You do not need to reboot the machine or SELinux.