others-how to solve 13 Permission denied problem in nginx?

1. Purpose

In this post, I will show you how to solve 13 Permission denied problem in nginx, when I try to start nginx I got the following error:

2023/08/17 20:05:53 [notice] 4399#4399: signal process started
2023/08/17 20:07:07 [emerg] 4698#4698: bind() to 0.0.0.0:15051 failed (13: Permission denied)

1.1 Enviroment

OS version: centOS 7.9

nginx version:

[root@local ~]# nginx -V
nginx version: nginx/1.20.1
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC)
built with OpenSSL 1.1.1k  FIPS 25 Mar 2021
TLS SNI support enabled
configure arguments: --prefix=/usr/share/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --http-client-body-temp-path=/var/lib/nginx/tmp/client_body --http-proxy-temp-path=/var/lib/nginx/tmp/proxy --http-fastcgi-temp-path=/var/lib/nginx/tmp/fastcgi --http-uwsgi-temp-path=/var/lib/nginx/tmp/uwsgi --http-scgi-temp-path=/var/lib/nginx/tmp/scgi --pid-path=/run/nginx.pid --lock-path=/run/lock/subsys/nginx --user=nginx --group=nginx --with-compat --with-debug --with-file-aio --with-google_perftools_module --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_degradation_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_image_filter_module=dynamic --with-http_mp4_module --with-http_perl_module=dynamic --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-http_xslt_module=dynamic --with-mail=dynamic --with-mail_ssl_module --with-pcre --with-pcre-jit --with-stream=dynamic --with-stream_ssl_module --with-stream_ssl_preread_module --with-threads --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -m64 -mtune=generic' --with-ld-opt='-Wl,-z,relro -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -Wl,-E'

The ngin.conf:

    server {
        listen 15051 http2;
        location / {
                grpc_pass grpc://localhost:50051;
        }
    }

1.2 The problem

You can see that I am just trying to use nginx as the grpc server which listening on 15051, and proxy to localhost:50051, but when I try to visit 15051, the following error occurred:

2023/08/17 20:05:53 [notice] 4399#4399: signal process started
2023/08/17 20:07:07 [emerg] 4698#4698: bind() to 0.0.0.0:15051 failed (13: Permission denied)



2. Solution

2.1 SElinux

My system turned on the SELinux, which stands for Security Enhanced Linux, it is an access control system that is built into the Linux kernel. It is used to enforce the resource policies that define what level of access users, programs, and services have on a system.

To find out the current status of SELinux, issue the sudo sestatus command. Where STATUS is either enabled or disabled. Here, MODE is either disabled, permissive or enforcing. Another way of viewing the status of SELinux is to issue the getenforce command.

Here is an example of checking if SELinux is enabled in my centOS:

[root@local examples]# 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

2.2 Solution

The semanage command is used to configure certain elements of SELinux policy without requiring modification to or recompilation from policy sources. semanage port controls the port number to port type definitions.

You can first check the allowed ports in selinux:

semanage port -l | grep http_port_t

Then if not found , you can just add the port to the selinux:

semanage port -a -t http_port_t  -p tcp 15051

Then restart nginx:

service nginx restart

It works!



3. Summary

In this post, I demonstrated how to solve the permission problem when using nginx, the key point is to check if you have enabled SELinux, which is a security policy enforement on Linux Servers . That’s it, thanks for your reading.