• Skip to secondary menu
  • Skip to main content
  • Skip to primary sidebar
  • Home
  • Projects
  • Products
  • Themes
  • Tools
  • Request for Quote

Vengala Vinay

Having 12+ Years of Experience in Software Development

  • Home
  • WordPress
  • PHP
    • Codeigniter
  • Django
  • Magento
  • Selenium
  • Server
Home » Tuning SELinux Policies and Firewalld Rules on Rocky Linux 9 to Allow Custom Nginx Reverse Proxy Ports

Tuning SELinux Policies and Firewalld Rules on Rocky Linux 9 to Allow Custom Nginx Reverse Proxy Ports

Understanding the Need for Custom Ports

Rocky Linux 9, like many modern Linux distributions, employs robust security mechanisms such as SELinux and firewalld to protect services. When deploying a custom Nginx reverse proxy that needs to listen on non-standard ports (e.g., ports beyond 80 and 443), these security layers will, by default, block incoming connections. This is a deliberate security feature to prevent unauthorized services from binding to arbitrary ports. To enable your custom Nginx setup, you must explicitly configure both SELinux and firewalld to permit traffic on these specific ports.

SELinux Policy Adjustments for Custom Nginx Ports

SELinux operates on a “least privilege” principle, defining contexts for processes and files. For network services, this includes the ports they are allowed to bind to. We need to inform SELinux that Nginx is permitted to listen on our chosen custom ports.

Identifying the Current SELinux Port Context

Before making changes, it’s useful to see what ports are already allowed for Nginx. The semanage command is your primary tool here.

sudo semanage port -l | grep http_port_t

This command lists all ports associated with the http_port_t SELinux type, which Nginx typically uses. You’ll likely see 80 and 443.

Adding Custom Ports to SELinux Policy

Let’s assume you need Nginx to listen on port 8080 and port 8443 for your reverse proxy setup. You’ll use semanage port again, this time to add new entries. It’s crucial to use the correct SELinux port type. For HTTP/HTTPS traffic, http_port_t is generally appropriate. If you were dealing with a different service type, you’d need to identify the corresponding SELinux type (e.g., https_port_t, smtp_port_t, etc.).

sudo semanage port -a -t http_port_t -p tcp 8080
sudo semanage port -a -t http_port_t -p tcp 8443

The -a flag signifies “add,” -t http_port_t specifies the SELinux type, and -p tcp indicates the protocol. After adding these, verify they are present:

sudo semanage port -l | grep http_port_t

You should now see 8080 and 8443 listed alongside the default ports.

Troubleshooting SELinux Denials

If Nginx still fails to bind or accept connections on the new ports after the semanage commands, SELinux denials might be occurring. The audit log is your best friend here. Use ausearch to filter for AVC (Access Vector Cache) denials related to Nginx.

sudo ausearch -m avc -ts recent | grep nginx

A common denial might look like this:

type=AVC msg=audit(1678886400.123:456): avc: denied { name="bind" objtype="tcp_socket" srcino=12345 ... comm="nginx" ... scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:unreserved_port_t:s0 tport=8080

This indicates that the httpd_t (Nginx process context) tried to bind to a port labeled unreserved_port_t, which is not allowed for http_port_t. The semanage port -a command should have corrected this. If not, you might need to use audit2allow to generate a custom policy module, but this should be a last resort after verifying the port context is correctly set.

Firewalld Configuration for Custom Nginx Ports

Even with SELinux allowing Nginx to bind to the ports, the system’s firewall must also permit incoming traffic on these ports. Rocky Linux 9 uses firewalld, which is a dynamic firewall management tool.

Checking Current Firewall Rules

First, let’s see which services and ports are currently allowed. We’ll focus on the active zone, which is typically public for external-facing services.

sudo firewall-cmd --list-all

This command will show allowed services (like http, https) and ports. You’ll likely only see 80 and 443 if they were added as services.

Adding Custom Ports to Firewalld

We need to add our custom ports (8080 and 8443) to the active zone. It’s good practice to add them as specific ports rather than trying to map them to existing services if they are truly custom.

sudo firewall-cmd --zone=public --add-port=8080/tcp --permanent
sudo firewall-cmd --zone=public --add-port=8443/tcp --permanent

The --permanent flag ensures these rules persist after a reboot. After adding them, you must reload the firewall to apply the changes:

sudo firewall-cmd --reload

Now, verify the changes:

sudo firewall-cmd --zone=public --list-ports

You should see 8080/tcp and 8443/tcp in the output.

Alternative: Using Nginx Service Definitions (Advanced)

For more complex scenarios or to maintain consistency with how standard ports are handled, you can define custom services for firewalld. This involves creating an XML file in /etc/firewalld/services/. For example, to create a service for our custom Nginx ports:

<?xml version="1.0" encoding="utf-8"?>
<service>
  <short>Custom Nginx Proxy</short>
  <description>Allows traffic for custom Nginx reverse proxy ports.</description>
  <port protocol="tcp" port="8080"/>
  <port protocol="tcp" port="8443"/>
</service>

Save this content as custom-nginx.xml in /etc/firewalld/services/. Then, you can add this service to your zone:

sudo firewall-cmd --zone=public --add-service=custom-nginx --permanent
sudo firewall-cmd --reload

This approach is cleaner if you have multiple custom ports or want to group them logically. It also aligns better with SELinux’s concept of service types.

Nginx Configuration Verification

With SELinux and firewalld configured, the final step is to ensure Nginx is correctly listening on the specified ports. Your Nginx configuration file (e.g., /etc/nginx/nginx.conf or files within /etc/nginx/conf.d/) should have listen directives for your custom ports.

server {
    listen 8080;
    listen [::]:8080;
    server_name your_domain.com;

    location / {
        proxy_pass http://backend_server:port;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

server {
    listen 8443 ssl http2;
    listen [::]:8443 ssl http2;
    server_name your_domain.com;

    ssl_certificate /etc/letsencrypt/live/your_domain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/your_domain.com/privkey.pem;
    # ... other SSL configurations
    
    location / {
        proxy_pass https://backend_server:port;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

After modifying your Nginx configuration, always test it for syntax errors and then reload or restart Nginx:

sudo nginx -t
sudo systemctl reload nginx

Finally, use ss or netstat to confirm Nginx is listening on the new ports:

sudo ss -tulnp | grep nginx

You should see lines indicating that the nginx process is listening on 0.0.0.0:8080, [::]:8080, 0.0.0.0:8443, and [::]:8443.

Reader Interactions

Leave a Reply Cancel reply

You must be logged in to post a comment.

Primary Sidebar

A little about the Author

Having 12+ Years of Experience in Software Development, Vinay is a principal software architect, senior systems engineer, and elite technical consultant. He specializes in bespoke PHP/WordPress development, high-performance Magento 2 & Shopify architectures, custom plugin/theme development from scratch, and legacy code modernization (including VB6, VB.NET, PyQt, and Crystal Reports). Known for solving complex database bottlenecks, speed optimization (Core Web Vitals), and advanced security code auditing, Vinay engineers production-ready systems designed to scale under heavy concurrent load conditions.



Chat on WhatsApp

Recent Posts

  • Debugging Guide: Diagnosing PHP-FPM child process pool exhaustion in multi-site network environments with modern tools
  • Debugging and Resolving complex namespace class loading collisions issues during heavy concurrent database traffic
  • Step-by-Step Guide: Offloading high-frequency customer support tickets metadata writes to a Redis KV store
  • How to refactor legacy event ticket registers queries using modern WP_Query and custom Transient caching
  • Step-by-Step Guide: Offloading high-frequency member profile directories metadata writes to a Redis KV store

Categories

  • apache (1)
  • Business & Monetization (390)
  • Centos (4)
  • Comparisons & Decision Making (55)
  • Debian (2)
  • Debugging & Troubleshooting (662)
  • Desktop Applications (14)
  • DevOps (7)
  • DevOps & Cloud Scaling (962)
  • Django (1)
  • Laravel (4)
  • Migration & Architecture (192)
  • Mobile Applications (24)
  • MySQL (1)
  • Performance & Optimization (873)
  • PHP (5)
  • PHP Development (49)
  • Plugins & Themes (244)
  • Programming Languages (9)
  • Python (20)
  • Ruby on Rails (1)
  • Security & Compliance (647)
  • SEO & Growth (492)
  • Server (118)
  • Ubuntu (9)
  • VB6 & VB.NET (8)
  • Web Applications & Frontend (19)
  • Web Assembly (Wasm) (2)
  • WordPress (22)
  • WordPress Plugin Development (726)
  • WordPress Theme Development (357)

Recent Posts

  • Debugging Guide: Diagnosing PHP-FPM child process pool exhaustion in multi-site network environments with modern tools
  • Debugging and Resolving complex namespace class loading collisions issues during heavy concurrent database traffic
  • Step-by-Step Guide: Offloading high-frequency customer support tickets metadata writes to a Redis KV store

Top Categories

  • DevOps & Cloud Scaling (962)
  • Performance & Optimization (873)
  • WordPress Plugin Development (726)
  • Debugging & Troubleshooting (662)
  • Security & Compliance (647)
  • SEO & Growth (492)

Our Products

  • ERP & LMS Systems (4)
  • Directories & Marketplaces (4)
  • Healthcare Portals (3)
  • Point of Sale (POS) (2)
  • E-Commerce Engines (2)

Our Services

  • E-Commerce Development (10)
  • WordPress Development (8)
  • Python & Desktop GUI (7)
  • General Consulting (7)
  • Legacy Modernization (5)
  • Mobile App Development (4)

Copyright © 2026 · Vinay Vengala