Linux  ·  medium  ·  Access, hardening & packages

SELinux blocks a service on a non-standard port

SELinux labels ports as well as files. A service moved to a port outside its label cannot bind to it, whatever the firewall says.

What you see

nginx or sshd fails to start after a port change, with permission denied on the bind. Running it as root makes no difference, which is the clue.

What is actually wrong

Each port range carries a type label, and a service's domain may only bind to ports of its own type. Changing the port without changing the label is denied.

Codes and articles

bind() to 0.0.0.0:8443 failedPermission denied portsemanage portavc: denied name_bind

The fix

Label the port for the service
Root shell20 minutesmedium riskreversible

A service cannot bind to a port it has been moved to.

  1. Confirm SELinux is the cause rather than something already using the port.

    Shell
    sudo ausearch -m avc -ts recent | grep name_bind | tailsudo ss -tlnp | grep 8443

    Permission denied on a bind as root is almost always SELinux — the kernel is refusing on the label, not the user. Root cannot override a policy denial, which is why running with sudo changes nothing.

  2. See what the port is currently labelled as.

    Shell
    sudo semanage port -l | grep -E '8443|http_port_t|ssh_port_t'
  3. Add the port to the service's type.

    Shell
    sudo semanage port -a -t http_port_t -p tcp 8443
  4. If the port is already assigned to another type, modify rather than add.

    Shell
    sudo semanage port -m -t http_port_t -p tcp 8443
  5. For SSH specifically, both the port label and the firewall need changing, and it is worth keeping the old port open until the new one is proven.

    Shell
    sudo semanage port -a -t ssh_port_t -p tcp 2222sudo firewall-cmd --add-port=2222/tcp --permanentsudo firewall-cmd --reload
  6. Do not set SELinux to permissive as the fix. Use it to confirm a diagnosis and then label the port properly.

    Shell
    getenforce
Confirm it workedThe service starts and binds, with SELinux still enforcing.
Shell
getenforcesudo ss -tlnp | grep 8443sudo semanage port -l | grep 8443
If you need to undo itsudo semanage port -d -t http_port_t -p tcp 8443 removes the label.

Where this stops. This write-up was written and checked by hand. It says what each step changes, how to confirm it worked and how to reverse it, and anything destructive is flagged before you reach it. If it does not match what your machine is doing, search the Support Centre for the exact code or message — and when something needs a person, get in touch.