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 ]
NOTE:
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.
- 10 things you probably did not know about SELinux.. #8 How to remove a port from a port type?
Well the problem with that is all the kernel is returning is EPERM
2011-10-24 05:31 pm (UTC)