By default SELinux policy defines the ports that a particular service is allowed bind to and make use of with port labeling. This increases system security by preventing random services or malicious code from being able to bind to a well known defined port that may otherwise be used by a legitimate service.
In order to change a service to use a non standard port we must change SELinux policy and specify the SELinux port types that are allowed to use specific ports.
We can view a list of currently defined records with the semanage command as shown below.
[[email protected] 7 ~]# semanage port -l
On my test server this output 390 different lines which is quite a lot, you can narrow the results down by piping the output into a grep for the name of the service or port that you’re after.
For instance we can see that the SELinux port type for SSH is allowed to use TCP port 22 by default below but nothing else.
[[email protected] ~]# semanage port -l | grep ssh ssh_port_t tcp 22
We can test this by modifying the /etc/ssh/sshd_config file, by default it specifies “Port 22” which is the port that sshd listens on for connections, I have modified this to “Port 2222” and reloaded the sshd service. After the reload the netstat command showed that sshd was no longer listening on either port 22 or 2222. Using the sealert command from the setroubleshoot-server package, we can get further information from the /var/log/audit/audit.log file as shown below.
[[email protected] ~]# sealert -a /var/log/audit/audit.log 100% done'list' object has no attribute 'split' 100% done found 1 alerts in /var/log/audit/audit.log -------------------------------------------------------------------------------- SELinux is preventing /usr/sbin/sshd from name_bind access on the tcp_socket port 2222. ***** Plugin bind_ports (92.2 confidence) suggests ************************ If you want to allow /usr/sbin/sshd to bind to network port 2222 Then you need to modify the port type. Do # semanage port -a -t PORT_TYPE -p tcp 2222 where PORT_TYPE is one of the following: ssh_port_t, vnc_port_t, xserver_port_t.
The result shows us the “semanage port” command that we need to run in order to allow SSH to use TCP port 2222. The -a flag adds the record, the -t flag specifies the SELinux port type, while -p is the protocol (TCP or UDP) for the specified port.
semanage port -a -t ssh_port_t -p tcp 2222
This command is persistent and the changes will remain even after system reboot.
After running this we can run semanage port -l again and confirm that SSH is now allowed to use either TCP ports 22 or 2222.
[[email protected] ~]# semanage port -l | grep ssh ssh_port_t tcp 2222, 22
It’s important to note that a particular port can only be used by one service at a time, for example if we attempt to assign TCP port 22 or 2222 elsewhere at this point we will get an error.
[[email protected] ~]# semanage port -a -t http_port_t -p tcp 22 ValueError: Port tcp/22 already defined [[email protected] ~]# semanage port -a -t http_port_t -p tcp 2222 ValueError: Port tcp/2222 already defined
Additionally we can use the semanage command with the -C flag, as the full contents of -l are almost 400 lines although we can narrow the results down with grep, -C will only display customizations. In the example below we see our recent port 2222 change which is currently our only customization.
[[email protected] ~]# semanage port -lC SELinux Port Type Proto Port Number ssh_port_t tcp 2222
If we were instead meant to apply TCP port 2222 to Apache we can use semanage with the -m flag to modify the SELinux port type from ssh_port_t to http_port_t as shown below.
[[email protected] ~]# semanage port -m -t http_port_t -p tcp 2222 [[email protected] ~]# semanage port -lC SELinux Port Type Proto Port Number http_port_t tcp 2222
We can also completely delete a record by using the -d flag, afterwards the output of -C confirms there are no longer any customizations in place.
[[email protected] ~]# semanage port -d -t http_port_t -p tcp 2222 [[email protected] ~]# semanage port -lC [[email protected] ~]#
The sepolicy command which comes with the policycoreutils-devel package can also be used to view SELinux port types that have been set on a particular port.
[[email protected] ~]# sepolicy network -p 2222 2222: tcp ssh_port_t 2222 [[email protected] ~]# sepolicy network -p 22 22: tcp ssh_port_t 22 [[email protected] ~]# sepolicy network -t ssh_port_t ssh_port_t: tcp: 2222,22
Alternatively if your Linux system has a GUI installed you can install the policycoreutils-gui package via yum and then run the ‘system-config-selinux’ command to open the GUI. From the Network Port menu on the left you can configure SELinux port types as shown below.
If you have trouble remembering any of this, simply refer to the semanage-port manual page for further information and examples.
By default SELinux only allows known services to bind to known and defined ports. If we want to change a service to make use of a non default port we will need to modify the SELinux port type with either the “semanage port” command or through the GUI as demonstrated.
This post is part of our Red Hat Certified Engineer (RHCE) exam study guide series. For more RHCE related posts and information check out our full RHCE study guide.