Protecting network ports

Each network daemon that's running on your system has a specific network port or set of network ports assigned to it, on which it will listen. The /etc/services file contains a list of common daemons and their associated network ports, but it doesn't prevent someone from configuring a daemon to listen on some non-standard port. So, without some mechanism to prevent it, some sneaky intruder could potentially plant some sort of malware that would cause a daemon to listen on a non-standard port, possibly listening for commands from its master.

SELinux protects against this sort of malicious activity by only allowing daemons to listen on certain ports. Use semanage to look at the list of allowed ports:

[donnie@localhost ~]$ sudo semanage port -l
SELinux Port Type Proto Port Number

afs3_callback_port_t tcp 7001
afs3_callback_port_t udp 7001
afs_bos_port_t udp 7007
. . .
. . .
zented_port_t udp 1229
zookeeper_client_port_t tcp 2181
zookeeper_election_port_t tcp 3888
zookeeper_leader_port_t tcp 2888
zope_port_t tcp 8021
[donnie@localhost ~]$

This is yet another of those very long lists, so I'm only showing partial output. However, let's narrow things down a bit. Let's say that I only want to look at a list of ports on which the Apache web server can listen. For this, I'll use my good friend grep:

[donnie@localhost ~]$ sudo semanage port -l | grep 'http'
[sudo] password for donnie:
http_cache_port_t tcp 8080, 8118, 8123, 10001-10010
http_cache_port_t udp 3130
http_port_t tcp 80, 81, 443, 488, 8008, 8009, 8443, 9000
pegasus_http_port_t tcp 5988
pegasus_https_port_t tcp 5989
[donnie@localhost ~]$

Several http items come up, but I'm only interested in the http_port_t item because it's the one that affects normal web server operation. We see here that SELinux will allow Apache to listen on ports 80, 81, 443, 488, 8008, 8009, 8443, and 9000. Since the Apache server is one of the few daemons you'd ever have a legitimate reason for adding a non-standard port to, let's demo with it.

First, let's go into the /etc/httpd/conf/httpd.conf file and look at the ports on which Apache is currently listening. Search for Listen, and you'll see the following line:

Listen 80

I don't have the SSL module installed on this machine, but if I did I would have an ssl.conf file in the /etc/httpd/conf.d directory with this line:

Listen 443

So for normal, non-encrypted website connections, the default configuration only has Apache listening on port 80. For secure, encrypted website connections, Apache listens on port 443. Now, let's go into the httpd.conf file and change Listen 80 to a port number that SELinux doesn't allow, for example, port 82:

Listen 82

After saving the file, I'll restart Apache to read in the new configuration:

[donnie@localhost ~]$ sudo systemctl restart httpd
Job for httpd.service failed because the control process exited with error code. See "systemctl status httpd.service" and "journalctl -xe" for details.
[donnie@localhost ~]$

Yes, I have a problem. I'll look in the /var/log/messages file to see if setroubleshoot gives me a clue:

Nov 29 16:39:21 localhost python: SELinux is preventing /usr/sbin/httpd from name_bind access on the tcp_socket port 82.#012#012***** Plugin bind_ports (99.5 confidence) suggests ************************#012#012If you want to allow /usr/sbin/httpd to bind to network port 82#012Then you need to modify the port type.#012Do#012# semanage port -a -t PORT_TYPE -p tcp 82#012 where PORT_TYPE is one of the following: http_cache_port_t, http_port_t, jboss_management_port_t, jboss_messaging_port_t, ntop_port_t, puppet_port_t.#012#012***** Plugin catchall (1.49 confidence) suggests **************************#012#012If you believe that httpd should be allowed name_bind access on the port 82 tcp_socket by default.#012Then you should report this as a bug.#012You can generate a local policy module to allow this access.#012Do#012allow this access for now by executing:#012# ausearch -c 'httpd' --raw | audit2allow -M my-httpd#012# semodule -i my-httpd.pp#012

The problem that details how SELinux is preventing httpd from binding to port 82 is defined in the first line of the message. The first suggestion we see for fixing this is to use semanage to add the port to the list of allowed ports. So, let's do that and look at the list of Apache ports:

[donnie@localhost ~]$ sudo semanage port -a 82 -t http_port_t -p tcp

[donnie@localhost ~]$ sudo semanage port -l | grep 'http_port_t'
http_port_t tcp 82, 80, 81, 443, 488, 8008, 8009, 8443, 9000
pegasus_http_port_t tcp 5988
[donnie@localhost ~]$

It's not clear in the setroubleshoot message, but you need to specify the port number that you want to add after port -a. -t http_port_t specifies the type for which you want to add the port, and -p tcp specifies that you want to use the TCP protocol.

Now for the moment of truth. Will the Apache daemon start this time? Let's see:

[donnie@localhost ~]$ sudo systemctl restart httpd
[sudo] password for donnie:
[donnie@localhost ~]$ sudo systemctl status httpd
● httpd.service - The Apache HTTP Server
Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: disabled)
Active: active (running) since Wed 2017-11-29 20:09:51 EST; 7s ago
Docs: man:httpd(8)
. . .
. . .

It works, and we have achieved coolness. But now, I've decided that I no longer need this oddball port. Deleting it is just as easy as adding it:

[donnie@localhost ~]$ sudo semanage port -d 82 -t http_port_t -p tcp

[donnie@localhost ~]$ sudo semanage port -l | grep 'http_port_t'
http_port_t tcp 80, 81, 443, 488, 8008, 8009, 8443, 9000
pegasus_http_port_t tcp 5988
[donnie@localhost ~]$

All I had to do was to replace port -a with port -d. And of course, I still need to go into the /etc/httpd/conf/httpd.conf file to change Listen 82 back to Listen 80.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.191.223.123