During a recent deployment, I encountered an odd Nginx behavior where standard ports (80, 8080) worked perfectly, but attempts to use ports like 8090 or 9090 resulted in permission errors:
2023/08/15 14:22:45 [emerg] 30181#0: bind() to 0.0.0.0:8090 failed (13: Permission denied)
The root cause lies in SELinux (Security-Enhanced Linux) which is enabled by default on Fedora/RHEL systems. SELinux implements Mandatory Access Control (MAC) that restricts what ports services can bind to.
Check SELinux status with:
sestatus
# Should show: SELinux status: enabled
To see which ports SELinux permits Nginx to bind to:
semanage port -l | grep http
# Typical output:
http_port_t tcp 80, 81, 443, 488, 8008, 8009, 8443, 9000
Notice 8090 and 9090 are missing from this list.
To permanently allow Nginx to bind to port 8090:
sudo semanage port -a -t http_port_t -p tcp 8090
sudo semanage port -a -t http_port_t -p tcp 9090
Verify the changes:
semanage port -l | grep http_port_t
For testing purposes only, you can temporarily set SELinux to permissive mode:
sudo setenforce 0
# Remember to revert after testing:
sudo setenforce 1
If you prefer to understand the exact denial before making changes:
sudo ausearch -m avc -c nginx | grep denied
sudo grep nginx /var/log/audit/audit.log | audit2allow
After implementing Solution 1, test your Nginx configuration:
sudo nginx -t
sudo systemctl restart nginx
ss -tulnp | grep nginx
For advanced users, consider using systemd socket activation which handles port binding differently:
[Unit]
Description=NGINX Socket Activation
[Socket]
ListenStream=8090
BindIPv6Only=both
Service=nginx.service
[Install]
WantedBy=sockets.target
When working with nginx on Linux systems, you might encounter permission issues when binding to non-standard ports (anything above 1024) while standard ports like 80 or 8080 work fine. This typically manifests with errors like:
2023/02/15 14:30:45 [emerg] 30181#0: bind() to 0.0.0.0:8090 failed (13: Permission denied)
The original poster noted several important details:
- Ports 80 and 8080 work without issues
- Port 8090 fails with permission denied
- Other services (like Python's SimpleHTTPServer) can bind to 8090
- nginx runs as user 'nginx' which belongs to group 'git'
SELinux Context Issues
On Fedora systems (which use SELinux by default), this is often the root cause. Check current settings:
# Check SELinux status
sestatus
# View current port contexts
semanage port -l | grep http
To allow nginx to bind to port 8090:
# Add the port to http_port_t context
semanage port -a -t http_port_t -p tcp 8090
# Verify the change
semanage port -l | grep http_port_t
Firewall Configuration
While this typically wouldn't cause a bind error, it's worth checking:
# Check firewall rules
firewall-cmd --list-all
# Add port 8090 if needed
firewall-cmd --permanent --add-port=8090/tcp
firewall-cmd --reload
Process Capabilities
nginx might need special capabilities to bind to non-standard ports:
# Check current capabilities
getcap /usr/sbin/nginx
# Set required capabilities
setcap 'cap_net_bind_service=+ep' /usr/sbin/nginx
If you can't modify SELinux policies:
# Temporary solution (not recommended for production)
setenforce 0
# Or create custom policy module
audit2allow -a -M nginx_port
semodule -i nginx_port.pp
After making changes:
# Restart nginx
systemctl restart nginx
# Verify port binding
netstat -tulnp | grep nginx
ss -tulnp | grep nginx
Here's a complete working server block for port 8090:
server {
listen 8090;
server_name example.com;
location / {
root /var/www/html;
index index.html;
}
access_log /var/log/nginx/8090_access.log;
error_log /var/log/nginx/8090_error.log;
}
Remember to test your configuration before applying:
nginx -t