danwalsh (danwalsh) wrote,

10 things you probably did not know about SELinux.. #8 How to remove a port from a port type?

How do you remove a network port from a network port type?

First a little explanation.  Linux contains 65536 network ports for both UDP and TCP.
SELinux uses types to group network ports together.  If you want to see a listing of the port types on the system you can execute:

semanage  port -l
SELinux Port Type              Proto    Port Number

afs_bos_port_t                 udp      7007
afs_client_port_t              udp      7001
afs_fs_port_t                  tcp      2040
afs_fs_port_t                  udp      7000, 7005

Then we write rules in SELinux like

allow httpd_t http_port_t : tcp_socket name_bind ;

This rules says the apache process can execute the bind command using any port that is currently labeled http_port_t.

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

Now a fairly common question that gets asked is, can I remove these ports.   IE I do not want to allow apache to bind to port 8008.

How would I do this?

The simplest thing to do is to redefine port 8008 as a different port type that httpd can not bind to. 

The default port type for all unassigned ports  > 1024 is unreserved_port_t or ephemeral_port_t (Fedora 16)

# semanage  port -l | grep ^unreserved_port_t
unreserved_port_t              tcp      1024-32767, 61001-65535
unreserved_port_t              udp      1024-32767, 61001-65535
# semanage  port -l | grep ^ephemeral_port_t
ephemeral_port_t               tcp      32768-61000
ephemeral_port_t               udp      32768-61000

Note SELinux will use a more specific port type if the port has been defined, for example when the kernel sees tcp port 8008, it will use http_port_t rather then unreserved_port_t. 

But the admin can override this by adding his own port definition.

# semanage port -m -t unreserved_port_t -p tcp 8008

To prove this worked, I tested using apache.

# sed -i 's/Listen 80/Listen 8008/g' /etc/httpd/conf/httpd.conf
# semanage  port -m -t unreserved_port_t -p tcp 8008
# service httpd restart
Restarting httpd (via systemctl):  Job failed. See system logs and 'systemctl status' for details.  [FAILED]
# semanage port -d -p tcp 8008
# service httpd restart
Restarting httpd (via systemctl):                          [  OK  ]


Be careful doing this, because you have just changed the definition of http_port_t for ALL domains, not just the httpd_t domain.   Meaning if you were running firefox with a sandbox_web_t sandbox on the same machine, the firefox would no longer be able to connect to port 8008, because sandbox_web_t is only allowed to connect to http_port_t and 8008 is no longer defined as 8008.
  • Post a new comment


    Anonymous comments are disabled in this journal

    default userpic

    Your reply will be screened